From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- gfx/angle/checkout/src/libANGLE/AttributeMap.cpp | 147 + gfx/angle/checkout/src/libANGLE/AttributeMap.h | 100 + gfx/angle/checkout/src/libANGLE/BinaryStream.h | 286 + gfx/angle/checkout/src/libANGLE/BlobCache.cpp | 277 + gfx/angle/checkout/src/libANGLE/BlobCache.h | 182 + gfx/angle/checkout/src/libANGLE/Buffer.cpp | 449 + gfx/angle/checkout/src/libANGLE/Buffer.h | 218 + gfx/angle/checkout/src/libANGLE/Caps.cpp | 1371 +++ gfx/angle/checkout/src/libANGLE/Caps.h | 786 ++ gfx/angle/checkout/src/libANGLE/Compiler.cpp | 422 + gfx/angle/checkout/src/libANGLE/Compiler.h | 78 + gfx/angle/checkout/src/libANGLE/Config.cpp | 416 + gfx/angle/checkout/src/libANGLE/Config.h | 115 + gfx/angle/checkout/src/libANGLE/Constants.h | 125 + gfx/angle/checkout/src/libANGLE/Context.cpp | 10472 +++++++++++++++++++ gfx/angle/checkout/src/libANGLE/Context.h | 901 ++ gfx/angle/checkout/src/libANGLE/Context.inl.h | 176 + gfx/angle/checkout/src/libANGLE/Context_gl.cpp | 3706 +++++++ .../checkout/src/libANGLE/Context_gl_1_autogen.h | 349 + .../checkout/src/libANGLE/Context_gl_2_autogen.h | 44 + .../checkout/src/libANGLE/Context_gl_3_autogen.h | 82 + .../checkout/src/libANGLE/Context_gl_4_autogen.h | 358 + .../checkout/src/libANGLE/Context_gles_1_0.cpp | 746 ++ .../src/libANGLE/Context_gles_1_0_autogen.h | 109 + .../src/libANGLE/Context_gles_2_0_autogen.h | 190 + .../src/libANGLE/Context_gles_3_0_autogen.h | 164 + .../src/libANGLE/Context_gles_3_1_autogen.h | 133 + .../src/libANGLE/Context_gles_3_2_autogen.h | 83 + .../src/libANGLE/Context_gles_ext_autogen.h | 616 ++ gfx/angle/checkout/src/libANGLE/Debug.cpp | 507 + gfx/angle/checkout/src/libANGLE/Debug.h | 180 + gfx/angle/checkout/src/libANGLE/Device.cpp | 133 + gfx/angle/checkout/src/libANGLE/Device.h | 60 + gfx/angle/checkout/src/libANGLE/Display.cpp | 2506 +++++ gfx/angle/checkout/src/libANGLE/Display.h | 427 + gfx/angle/checkout/src/libANGLE/EGLSync.cpp | 114 + gfx/angle/checkout/src/libANGLE/EGLSync.h | 72 + gfx/angle/checkout/src/libANGLE/Error.cpp | 67 + gfx/angle/checkout/src/libANGLE/Error.h | 206 + gfx/angle/checkout/src/libANGLE/Error.inc | 91 + gfx/angle/checkout/src/libANGLE/ErrorStrings.h | 627 ++ gfx/angle/checkout/src/libANGLE/Fence.cpp | 124 + gfx/angle/checkout/src/libANGLE/Fence.h | 88 + gfx/angle/checkout/src/libANGLE/Framebuffer.cpp | 2727 +++++ gfx/angle/checkout/src/libANGLE/Framebuffer.h | 538 + .../src/libANGLE/FramebufferAttachment.cpp | 350 + .../checkout/src/libANGLE/FramebufferAttachment.h | 307 + gfx/angle/checkout/src/libANGLE/GLES1Renderer.cpp | 1197 +++ gfx/angle/checkout/src/libANGLE/GLES1Renderer.h | 340 + gfx/angle/checkout/src/libANGLE/GLES1Shaders.inc | 1218 +++ gfx/angle/checkout/src/libANGLE/GLES1State.cpp | 609 ++ gfx/angle/checkout/src/libANGLE/GLES1State.h | 351 + .../checkout/src/libANGLE/HandleAllocator.cpp | 184 + gfx/angle/checkout/src/libANGLE/HandleAllocator.h | 65 + gfx/angle/checkout/src/libANGLE/Image.cpp | 581 + gfx/angle/checkout/src/libANGLE/Image.h | 216 + gfx/angle/checkout/src/libANGLE/ImageIndex.cpp | 388 + gfx/angle/checkout/src/libANGLE/ImageIndex.h | 133 + .../checkout/src/libANGLE/IndexRangeCache.cpp | 116 + gfx/angle/checkout/src/libANGLE/IndexRangeCache.h | 63 + gfx/angle/checkout/src/libANGLE/InfoLog.h | 90 + .../checkout/src/libANGLE/LoggingAnnotator.cpp | 63 + gfx/angle/checkout/src/libANGLE/LoggingAnnotator.h | 39 + gfx/angle/checkout/src/libANGLE/MemoryObject.cpp | 66 + gfx/angle/checkout/src/libANGLE/MemoryObject.h | 60 + .../checkout/src/libANGLE/MemoryProgramCache.cpp | 283 + .../checkout/src/libANGLE/MemoryProgramCache.h | 87 + .../checkout/src/libANGLE/MemoryShaderCache.cpp | 155 + .../checkout/src/libANGLE/MemoryShaderCache.h | 60 + gfx/angle/checkout/src/libANGLE/Observer.cpp | 113 + gfx/angle/checkout/src/libANGLE/Observer.h | 167 + gfx/angle/checkout/src/libANGLE/Overlay.cpp | 103 + gfx/angle/checkout/src/libANGLE/Overlay.h | 154 + gfx/angle/checkout/src/libANGLE/OverlayWidgets.cpp | 737 ++ gfx/angle/checkout/src/libANGLE/OverlayWidgets.h | 201 + .../checkout/src/libANGLE/Overlay_autogen.cpp | 824 ++ gfx/angle/checkout/src/libANGLE/Overlay_autogen.h | 83 + .../checkout/src/libANGLE/Overlay_font_autogen.cpp | 5078 +++++++++ .../checkout/src/libANGLE/Overlay_font_autogen.h | 27 + .../checkout/src/libANGLE/PixelLocalStorage.cpp | 826 ++ .../checkout/src/libANGLE/PixelLocalStorage.h | 177 + gfx/angle/checkout/src/libANGLE/Platform.cpp | 76 + gfx/angle/checkout/src/libANGLE/Program.cpp | 3810 +++++++ gfx/angle/checkout/src/libANGLE/Program.h | 897 ++ .../checkout/src/libANGLE/ProgramExecutable.cpp | 1785 ++++ .../checkout/src/libANGLE/ProgramExecutable.h | 517 + .../src/libANGLE/ProgramLinkedResources.cpp | 2377 +++++ .../checkout/src/libANGLE/ProgramLinkedResources.h | 333 + .../checkout/src/libANGLE/ProgramPipeline.cpp | 721 ++ gfx/angle/checkout/src/libANGLE/ProgramPipeline.h | 176 + gfx/angle/checkout/src/libANGLE/Query.cpp | 96 + gfx/angle/checkout/src/libANGLE/Query.h | 60 + gfx/angle/checkout/src/libANGLE/RefCountObject.h | 327 + gfx/angle/checkout/src/libANGLE/Renderbuffer.cpp | 423 + gfx/angle/checkout/src/libANGLE/Renderbuffer.h | 181 + .../checkout/src/libANGLE/ResourceManager.cpp | 522 + gfx/angle/checkout/src/libANGLE/ResourceManager.h | 353 + gfx/angle/checkout/src/libANGLE/ResourceMap.h | 346 + gfx/angle/checkout/src/libANGLE/Sampler.cpp | 211 + gfx/angle/checkout/src/libANGLE/Sampler.h | 92 + gfx/angle/checkout/src/libANGLE/Semaphore.cpp | 52 + gfx/angle/checkout/src/libANGLE/Semaphore.h | 57 + gfx/angle/checkout/src/libANGLE/Shader.cpp | 1331 +++ gfx/angle/checkout/src/libANGLE/Shader.h | 305 + gfx/angle/checkout/src/libANGLE/SizedMRUCache.h | 156 + gfx/angle/checkout/src/libANGLE/State.cpp | 3866 +++++++ gfx/angle/checkout/src/libANGLE/State.h | 1258 +++ gfx/angle/checkout/src/libANGLE/Stream.cpp | 282 + gfx/angle/checkout/src/libANGLE/Stream.h | 149 + gfx/angle/checkout/src/libANGLE/Surface.cpp | 941 ++ gfx/angle/checkout/src/libANGLE/Surface.h | 388 + gfx/angle/checkout/src/libANGLE/Texture.cpp | 2494 +++++ gfx/angle/checkout/src/libANGLE/Texture.h | 738 ++ gfx/angle/checkout/src/libANGLE/Thread.cpp | 168 + gfx/angle/checkout/src/libANGLE/Thread.h | 80 + .../checkout/src/libANGLE/TransformFeedback.cpp | 347 + .../checkout/src/libANGLE/TransformFeedback.h | 120 + gfx/angle/checkout/src/libANGLE/Uniform.cpp | 179 + gfx/angle/checkout/src/libANGLE/Uniform.h | 138 + gfx/angle/checkout/src/libANGLE/VaryingPacking.cpp | 1152 ++ gfx/angle/checkout/src/libANGLE/VaryingPacking.h | 329 + gfx/angle/checkout/src/libANGLE/Version.h | 34 + gfx/angle/checkout/src/libANGLE/Version.inc | 59 + gfx/angle/checkout/src/libANGLE/VertexArray.cpp | 906 ++ gfx/angle/checkout/src/libANGLE/VertexArray.h | 436 + .../checkout/src/libANGLE/VertexAttribute.cpp | 170 + gfx/angle/checkout/src/libANGLE/VertexAttribute.h | 139 + .../checkout/src/libANGLE/VertexAttribute.inc | 58 + gfx/angle/checkout/src/libANGLE/WorkerThread.cpp | 356 + gfx/angle/checkout/src/libANGLE/WorkerThread.h | 94 + gfx/angle/checkout/src/libANGLE/angletypes.cpp | 1039 ++ gfx/angle/checkout/src/libANGLE/angletypes.h | 1203 +++ gfx/angle/checkout/src/libANGLE/angletypes.inc | 35 + .../checkout/src/libANGLE/capture/FrameCapture.h | 1208 +++ .../src/libANGLE/capture/FrameCapture_mock.cpp | 55 + .../checkout/src/libANGLE/capture/capture_egl.h | 69 + .../src/libANGLE/capture/capture_gl_1_autogen.h | 2072 ++++ .../src/libANGLE/capture/capture_gl_2_autogen.h | 266 + .../src/libANGLE/capture/capture_gl_3_autogen.h | 609 ++ .../src/libANGLE/capture/capture_gl_4_autogen.h | 2524 +++++ .../libANGLE/capture/capture_gles_1_0_autogen.h | 582 ++ .../libANGLE/capture/capture_gles_2_0_autogen.h | 1195 +++ .../libANGLE/capture/capture_gles_3_0_autogen.h | 1079 ++ .../libANGLE/capture/capture_gles_3_1_autogen.h | 728 ++ .../libANGLE/capture/capture_gles_3_2_autogen.h | 553 + .../libANGLE/capture/capture_gles_ext_autogen.h | 5231 +++++++++ .../src/libANGLE/capture/frame_capture_utils.h | 23 + .../libANGLE/capture/frame_capture_utils_autogen.h | 3257 ++++++ .../libANGLE/capture/frame_capture_utils_mock.cpp | 19 + .../checkout/src/libANGLE/capture/gl_enum_utils.h | 32 + .../src/libANGLE/capture/gl_enum_utils_autogen.h | 419 + .../checkout/src/libANGLE/entry_points_utils.h | 127 + .../libANGLE/es3_copy_conversion_table_autogen.cpp | 171 + gfx/angle/checkout/src/libANGLE/features.h | 56 + .../checkout/src/libANGLE/format_map_autogen.cpp | 1781 ++++ .../checkout/src/libANGLE/format_map_desktop.cpp | 128 + gfx/angle/checkout/src/libANGLE/formatutils.cpp | 3220 ++++++ gfx/angle/checkout/src/libANGLE/formatutils.h | 577 + .../src/libANGLE/gles_extensions_autogen.cpp | 278 + .../src/libANGLE/gles_extensions_autogen.h | 727 ++ gfx/angle/checkout/src/libANGLE/histogram_macros.h | 110 + .../checkout/src/libANGLE/queryconversions.cpp | 315 + gfx/angle/checkout/src/libANGLE/queryconversions.h | 138 + gfx/angle/checkout/src/libANGLE/queryutils.cpp | 4525 ++++++++ gfx/angle/checkout/src/libANGLE/queryutils.h | 293 + .../checkout/src/libANGLE/renderer/BufferImpl.cpp | 39 + .../checkout/src/libANGLE/renderer/BufferImpl.h | 98 + .../checkout/src/libANGLE/renderer/CompilerImpl.h | 32 + .../checkout/src/libANGLE/renderer/ContextImpl.cpp | 88 + .../checkout/src/libANGLE/renderer/ContextImpl.h | 274 + .../checkout/src/libANGLE/renderer/DeviceImpl.cpp | 18 + .../checkout/src/libANGLE/renderer/DeviceImpl.h | 42 + .../checkout/src/libANGLE/renderer/DisplayImpl.cpp | 168 + .../checkout/src/libANGLE/renderer/DisplayImpl.h | 169 + .../src/libANGLE/renderer/EGLImplFactory.h | 104 + .../src/libANGLE/renderer/EGLReusableSync.cpp | 116 + .../src/libANGLE/renderer/EGLReusableSync.h | 54 + .../checkout/src/libANGLE/renderer/EGLSyncImpl.cpp | 37 + .../checkout/src/libANGLE/renderer/EGLSyncImpl.h | 57 + .../checkout/src/libANGLE/renderer/FenceNVImpl.h | 38 + gfx/angle/checkout/src/libANGLE/renderer/Format.h | 238 + .../src/libANGLE/renderer/FormatID_autogen.h | 264 + .../src/libANGLE/renderer/Format_table_autogen.cpp | 762 ++ .../renderer/FramebufferAttachmentObjectImpl.h | 65 + .../src/libANGLE/renderer/FramebufferImpl.cpp | 18 + .../src/libANGLE/renderer/FramebufferImpl.h | 123 + .../checkout/src/libANGLE/renderer/GLImplFactory.h | 116 + .../checkout/src/libANGLE/renderer/ImageImpl.cpp | 30 + .../checkout/src/libANGLE/renderer/ImageImpl.h | 68 + .../src/libANGLE/renderer/MemoryObjectImpl.h | 47 + .../checkout/src/libANGLE/renderer/OverlayImpl.h | 42 + .../checkout/src/libANGLE/renderer/ProgramImpl.cpp | 18 + .../checkout/src/libANGLE/renderer/ProgramImpl.h | 176 + .../src/libANGLE/renderer/ProgramPipelineImpl.cpp | 26 + .../src/libANGLE/renderer/ProgramPipelineImpl.h | 42 + .../checkout/src/libANGLE/renderer/QueryImpl.cpp | 21 + .../checkout/src/libANGLE/renderer/QueryImpl.h | 49 + .../src/libANGLE/renderer/RenderTargetCache.h | 186 + .../src/libANGLE/renderer/RenderbufferImpl.cpp | 19 + .../src/libANGLE/renderer/RenderbufferImpl.h | 164 + .../checkout/src/libANGLE/renderer/SamplerImpl.h | 44 + .../checkout/src/libANGLE/renderer/SemaphoreImpl.h | 50 + .../checkout/src/libANGLE/renderer/ShaderImpl.cpp | 105 + .../checkout/src/libANGLE/renderer/ShaderImpl.h | 77 + .../src/libANGLE/renderer/StreamProducerImpl.h | 40 + .../checkout/src/libANGLE/renderer/SurfaceImpl.cpp | 158 + .../checkout/src/libANGLE/renderer/SurfaceImpl.h | 136 + .../checkout/src/libANGLE/renderer/SyncImpl.h | 45 + .../checkout/src/libANGLE/renderer/TextureImpl.cpp | 200 + .../checkout/src/libANGLE/renderer/TextureImpl.h | 254 + .../libANGLE/renderer/TransformFeedbackImpl.cpp | 19 + .../src/libANGLE/renderer/TransformFeedbackImpl.h | 42 + .../src/libANGLE/renderer/VertexArrayImpl.cpp | 18 + .../src/libANGLE/renderer/VertexArrayImpl.h | 70 + .../checkout/src/libANGLE/renderer/copyvertex.h | 80 + .../src/libANGLE/renderer/copyvertex.inc.h | 635 ++ .../src/libANGLE/renderer/d3d/BufferD3D.cpp | 191 + .../checkout/src/libANGLE/renderer/d3d/BufferD3D.h | 89 + .../src/libANGLE/renderer/d3d/CompilerD3D.cpp | 24 + .../src/libANGLE/renderer/d3d/CompilerD3D.h | 32 + .../src/libANGLE/renderer/d3d/ContextD3D.h | 24 + .../src/libANGLE/renderer/d3d/DeviceD3D.cpp | 84 + .../checkout/src/libANGLE/renderer/d3d/DeviceD3D.h | 39 + .../src/libANGLE/renderer/d3d/DisplayD3D.cpp | 462 + .../src/libANGLE/renderer/d3d/DisplayD3D.h | 179 + .../src/libANGLE/renderer/d3d/DynamicHLSL.cpp | 1537 +++ .../src/libANGLE/renderer/d3d/DynamicHLSL.h | 212 + .../libANGLE/renderer/d3d/DynamicImage2DHLSL.cpp | 919 ++ .../src/libANGLE/renderer/d3d/DynamicImage2DHLSL.h | 28 + .../src/libANGLE/renderer/d3d/EGLImageD3D.cpp | 93 + .../src/libANGLE/renderer/d3d/EGLImageD3D.h | 55 + .../src/libANGLE/renderer/d3d/FramebufferD3D.cpp | 402 + .../src/libANGLE/renderer/d3d/FramebufferD3D.h | 143 + .../src/libANGLE/renderer/d3d/HLSLCompiler.cpp | 387 + .../src/libANGLE/renderer/d3d/HLSLCompiler.h | 74 + .../src/libANGLE/renderer/d3d/ImageD3D.cpp | 56 + .../checkout/src/libANGLE/renderer/d3d/ImageD3D.h | 105 + .../src/libANGLE/renderer/d3d/IndexBuffer.cpp | 183 + .../src/libANGLE/renderer/d3d/IndexBuffer.h | 125 + .../src/libANGLE/renderer/d3d/IndexDataManager.cpp | 318 + .../src/libANGLE/renderer/d3d/IndexDataManager.h | 112 + .../src/libANGLE/renderer/d3d/NativeWindowD3D.cpp | 19 + .../src/libANGLE/renderer/d3d/NativeWindowD3D.h | 38 + .../src/libANGLE/renderer/d3d/ProgramD3D.cpp | 3412 ++++++ .../src/libANGLE/renderer/d3d/ProgramD3D.h | 613 ++ .../src/libANGLE/renderer/d3d/RenderTargetD3D.cpp | 31 + .../src/libANGLE/renderer/d3d/RenderTargetD3D.h | 44 + .../src/libANGLE/renderer/d3d/RenderbufferD3D.cpp | 126 + .../src/libANGLE/renderer/d3d/RenderbufferD3D.h | 63 + .../src/libANGLE/renderer/d3d/RendererD3D.cpp | 247 + .../src/libANGLE/renderer/d3d/RendererD3D.h | 489 + .../src/libANGLE/renderer/d3d/SamplerD3D.h | 33 + .../src/libANGLE/renderer/d3d/ShaderD3D.cpp | 391 + .../checkout/src/libANGLE/renderer/d3d/ShaderD3D.h | 126 + .../libANGLE/renderer/d3d/ShaderExecutableD3D.cpp | 67 + .../libANGLE/renderer/d3d/ShaderExecutableD3D.h | 57 + .../src/libANGLE/renderer/d3d/SurfaceD3D.cpp | 517 + .../src/libANGLE/renderer/d3d/SurfaceD3D.h | 145 + .../src/libANGLE/renderer/d3d/SwapChainD3D.cpp | 34 + .../src/libANGLE/renderer/d3d/SwapChainD3D.h | 83 + .../src/libANGLE/renderer/d3d/TextureD3D.cpp | 4640 ++++++++ .../src/libANGLE/renderer/d3d/TextureD3D.h | 1050 ++ .../src/libANGLE/renderer/d3d/TextureStorage.h | 135 + .../src/libANGLE/renderer/d3d/VertexBuffer.cpp | 308 + .../src/libANGLE/renderer/d3d/VertexBuffer.h | 189 + .../libANGLE/renderer/d3d/VertexDataManager.cpp | 683 ++ .../src/libANGLE/renderer/d3d/VertexDataManager.h | 163 + .../src/libANGLE/renderer/d3d/d3d11/Blit11.cpp | 1943 ++++ .../src/libANGLE/renderer/d3d/d3d11/Blit11.h | 300 + .../renderer/d3d/d3d11/Blit11Helper_autogen.inc | 1575 +++ .../src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp | 1888 ++++ .../src/libANGLE/renderer/d3d/d3d11/Buffer11.h | 234 + .../src/libANGLE/renderer/d3d/d3d11/Clear11.cpp | 813 ++ .../src/libANGLE/renderer/d3d/d3d11/Clear11.h | 102 + .../src/libANGLE/renderer/d3d/d3d11/Context11.cpp | 1048 ++ .../src/libANGLE/renderer/d3d/d3d11/Context11.h | 282 + .../renderer/d3d/d3d11/DebugAnnotator11.cpp | 148 + .../libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h | 60 + .../d3d/d3d11/ExternalImageSiblingImpl11.cpp | 209 + .../d3d/d3d11/ExternalImageSiblingImpl11.h | 70 + .../src/libANGLE/renderer/d3d/d3d11/Fence11.cpp | 234 + .../src/libANGLE/renderer/d3d/d3d11/Fence11.h | 76 + .../libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp | 452 + .../libANGLE/renderer/d3d/d3d11/Framebuffer11.h | 100 + .../src/libANGLE/renderer/d3d/d3d11/Image11.cpp | 676 ++ .../src/libANGLE/renderer/d3d/d3d11/Image11.h | 128 + .../libANGLE/renderer/d3d/d3d11/IndexBuffer11.cpp | 160 + .../libANGLE/renderer/d3d/d3d11/IndexBuffer11.h | 58 + .../renderer/d3d/d3d11/InputLayoutCache.cpp | 313 + .../libANGLE/renderer/d3d/d3d11/InputLayoutCache.h | 123 + .../d3d/d3d11/MappedSubresourceVerifier11.cpp | 119 + .../d3d/d3d11/MappedSubresourceVerifier11.h | 63 + .../libANGLE/renderer/d3d/d3d11/NativeWindow11.h | 38 + .../renderer/d3d/d3d11/PixelTransfer11.cpp | 271 + .../libANGLE/renderer/d3d/d3d11/PixelTransfer11.h | 96 + .../src/libANGLE/renderer/d3d/d3d11/Program11.cpp | 34 + .../src/libANGLE/renderer/d3d/d3d11/Program11.h | 28 + .../renderer/d3d/d3d11/ProgramPipeline11.cpp | 21 + .../renderer/d3d/d3d11/ProgramPipeline11.h | 27 + .../src/libANGLE/renderer/d3d/d3d11/Query11.cpp | 357 + .../src/libANGLE/renderer/d3d/d3d11/Query11.h | 71 + .../renderer/d3d/d3d11/RenderStateCache.cpp | 323 + .../libANGLE/renderer/d3d/d3d11/RenderStateCache.h | 124 + .../libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp | 403 + .../libANGLE/renderer/d3d/d3d11/RenderTarget11.h | 133 + .../src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp | 4454 ++++++++ .../src/libANGLE/renderer/d3d/d3d11/Renderer11.h | 632 ++ .../renderer/d3d/d3d11/ResourceManager11.cpp | 560 + .../renderer/d3d/d3d11/ResourceManager11.h | 411 + .../renderer/d3d/d3d11/ShaderExecutable11.cpp | 116 + .../renderer/d3d/d3d11/ShaderExecutable11.h | 69 + .../libANGLE/renderer/d3d/d3d11/StateManager11.cpp | 4004 +++++++ .../libANGLE/renderer/d3d/d3d11/StateManager11.h | 692 ++ .../d3d/d3d11/StreamProducerD3DTexture.cpp | 166 + .../renderer/d3d/d3d11/StreamProducerD3DTexture.h | 44 + .../libANGLE/renderer/d3d/d3d11/SwapChain11.cpp | 1119 ++ .../src/libANGLE/renderer/d3d/d3d11/SwapChain11.h | 134 + .../renderer/d3d/d3d11/TextureStorage11.cpp | 4352 ++++++++ .../libANGLE/renderer/d3d/d3d11/TextureStorage11.h | 1003 ++ .../renderer/d3d/d3d11/TransformFeedback11.cpp | 131 + .../renderer/d3d/d3d11/TransformFeedback11.h | 61 + .../src/libANGLE/renderer/d3d/d3d11/Trim11.cpp | 103 + .../src/libANGLE/renderer/d3d/d3d11/Trim11.h | 43 + .../libANGLE/renderer/d3d/d3d11/VertexArray11.cpp | 375 + .../libANGLE/renderer/d3d/d3d11/VertexArray11.h | 112 + .../libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp | 167 + .../libANGLE/renderer/d3d/d3d11/VertexBuffer11.h | 65 + .../d3d11/converged/CompositorNativeWindow11.cpp | 457 + .../d3d/d3d11/converged/CompositorNativeWindow11.h | 116 + .../libANGLE/renderer/d3d/d3d11/formatutils11.cpp | 1029 ++ .../libANGLE/renderer/d3d/d3d11/formatutils11.h | 64 + .../renderer/d3d/d3d11/renderer11_utils.cpp | 2751 +++++ .../libANGLE/renderer/d3d/d3d11/renderer11_utils.h | 478 + .../d3d11/shaders/compiled/buffertotexture11_gs.h | 80 + .../shaders/compiled/buffertotexture11_ps_4f.h | 65 + .../shaders/compiled/buffertotexture11_ps_4i.h | 65 + .../shaders/compiled/buffertotexture11_ps_4ui.h | 65 + .../d3d11/shaders/compiled/buffertotexture11_vs.h | 145 + .../d3d/d3d11/shaders/compiled/clear11_fl9vs.h | 71 + .../d3d11/shaders/compiled/clear11multiviewgs.h | 83 + .../d3d11/shaders/compiled/clear11multiviewvs.h | 80 + .../d3d/d3d11/shaders/compiled/clear11vs.h | 69 + .../d3d/d3d11/shaders/compiled/cleardepth11ps.h | 74 + .../d3d11/shaders/compiled/clearfloat11_fl9ps.h | 128 + .../d3d/d3d11/shaders/compiled/clearfloat11ps1.h | 85 + .../d3d/d3d11/shaders/compiled/clearfloat11ps2.h | 91 + .../d3d/d3d11/shaders/compiled/clearfloat11ps3.h | 97 + .../d3d/d3d11/shaders/compiled/clearfloat11ps4.h | 104 + .../d3d/d3d11/shaders/compiled/clearfloat11ps5.h | 110 + .../d3d/d3d11/shaders/compiled/clearfloat11ps6.h | 116 + .../d3d/d3d11/shaders/compiled/clearfloat11ps7.h | 122 + .../d3d/d3d11/shaders/compiled/clearfloat11ps8.h | 128 + .../d3d/d3d11/shaders/compiled/clearsint11ps1.h | 85 + .../d3d/d3d11/shaders/compiled/clearsint11ps2.h | 91 + .../d3d/d3d11/shaders/compiled/clearsint11ps3.h | 97 + .../d3d/d3d11/shaders/compiled/clearsint11ps4.h | 104 + .../d3d/d3d11/shaders/compiled/clearsint11ps5.h | 110 + .../d3d/d3d11/shaders/compiled/clearsint11ps6.h | 116 + .../d3d/d3d11/shaders/compiled/clearsint11ps7.h | 122 + .../d3d/d3d11/shaders/compiled/clearsint11ps8.h | 128 + .../d3d/d3d11/shaders/compiled/clearuint11ps1.h | 85 + .../d3d/d3d11/shaders/compiled/clearuint11ps2.h | 91 + .../d3d/d3d11/shaders/compiled/clearuint11ps3.h | 97 + .../d3d/d3d11/shaders/compiled/clearuint11ps4.h | 104 + .../d3d/d3d11/shaders/compiled/clearuint11ps5.h | 110 + .../d3d/d3d11/shaders/compiled/clearuint11ps6.h | 116 + .../d3d/d3d11/shaders/compiled/clearuint11ps7.h | 122 + .../d3d/d3d11/shaders/compiled/clearuint11ps8.h | 128 + .../compiled/multiplyalpha_ftof_pm_luma_2d_ps.h | 76 + .../multiplyalpha_ftof_pm_luma_2darray_ps.h | 86 + .../compiled/multiplyalpha_ftof_pm_luma_3d_ps.h | 80 + .../multiplyalpha_ftof_pm_lumaalpha_2d_ps.h | 76 + .../multiplyalpha_ftof_pm_lumaalpha_2darray_ps.h | 86 + .../multiplyalpha_ftof_pm_lumaalpha_3d_ps.h | 80 + .../compiled/multiplyalpha_ftof_pm_rgb_2d_ps.h | 76 + .../multiplyalpha_ftof_pm_rgb_2darray_ps.h | 86 + .../compiled/multiplyalpha_ftof_pm_rgb_3d_ps.h | 80 + .../compiled/multiplyalpha_ftof_pm_rgb_565_2d_ps.h | 84 + .../multiplyalpha_ftof_pm_rgb_565_2darray_ps.h | 94 + .../compiled/multiplyalpha_ftof_pm_rgb_565_3d_ps.h | 88 + .../compiled/multiplyalpha_ftof_pm_rgba_2d_ps.h | 76 + .../multiplyalpha_ftof_pm_rgba_2darray_ps.h | 86 + .../compiled/multiplyalpha_ftof_pm_rgba_3d_ps.h | 80 + .../multiplyalpha_ftof_pm_rgba_4444_2d_ps.h | 82 + .../multiplyalpha_ftof_pm_rgba_4444_2darray_ps.h | 92 + .../multiplyalpha_ftof_pm_rgba_4444_3d_ps.h | 86 + .../multiplyalpha_ftof_pm_rgba_5551_2d_ps.h | 82 + .../multiplyalpha_ftof_pm_rgba_5551_2darray_ps.h | 92 + .../multiplyalpha_ftof_pm_rgba_5551_3d_ps.h | 86 + .../compiled/multiplyalpha_ftof_um_luma_2d_ps.h | 82 + .../multiplyalpha_ftof_um_luma_2darray_ps.h | 91 + .../compiled/multiplyalpha_ftof_um_luma_3d_ps.h | 85 + .../multiplyalpha_ftof_um_lumaalpha_2d_ps.h | 82 + .../multiplyalpha_ftof_um_lumaalpha_2darray_ps.h | 91 + .../multiplyalpha_ftof_um_lumaalpha_3d_ps.h | 85 + .../compiled/multiplyalpha_ftof_um_rgb_2d_ps.h | 82 + .../multiplyalpha_ftof_um_rgb_2darray_ps.h | 91 + .../compiled/multiplyalpha_ftof_um_rgb_3d_ps.h | 85 + .../compiled/multiplyalpha_ftof_um_rgb_565_2d_ps.h | 90 + .../multiplyalpha_ftof_um_rgb_565_2darray_ps.h | 100 + .../compiled/multiplyalpha_ftof_um_rgb_565_3d_ps.h | 93 + .../compiled/multiplyalpha_ftof_um_rgba_2d_ps.h | 82 + .../multiplyalpha_ftof_um_rgba_2darray_ps.h | 91 + .../compiled/multiplyalpha_ftof_um_rgba_3d_ps.h | 85 + .../multiplyalpha_ftof_um_rgba_4444_2d_ps.h | 88 + .../multiplyalpha_ftof_um_rgba_4444_2darray_ps.h | 98 + .../multiplyalpha_ftof_um_rgba_4444_3d_ps.h | 91 + .../multiplyalpha_ftof_um_rgba_5551_2d_ps.h | 88 + .../multiplyalpha_ftof_um_rgba_5551_2darray_ps.h | 98 + .../multiplyalpha_ftof_um_rgba_5551_3d_ps.h | 91 + .../multiplyalpha_ftoi_pm_rgb_2darray_ps.h | 96 + .../compiled/multiplyalpha_ftoi_pm_rgb_3d_ps.h | 90 + .../multiplyalpha_ftoi_pm_rgba_2darray_ps.h | 94 + .../compiled/multiplyalpha_ftoi_pm_rgba_3d_ps.h | 88 + .../multiplyalpha_ftoi_pt_rgb_2darray_ps.h | 94 + .../compiled/multiplyalpha_ftoi_pt_rgb_3d_ps.h | 88 + .../multiplyalpha_ftoi_pt_rgba_2darray_ps.h | 92 + .../compiled/multiplyalpha_ftoi_pt_rgba_3d_ps.h | 85 + .../multiplyalpha_ftoi_um_rgb_2darray_ps.h | 102 + .../compiled/multiplyalpha_ftoi_um_rgb_3d_ps.h | 95 + .../multiplyalpha_ftoi_um_rgba_2darray_ps.h | 100 + .../compiled/multiplyalpha_ftoi_um_rgba_3d_ps.h | 93 + .../compiled/multiplyalpha_ftou_pm_rgb_2d_ps.h | 81 + .../multiplyalpha_ftou_pm_rgb_2darray_ps.h | 91 + .../compiled/multiplyalpha_ftou_pm_rgb_3d_ps.h | 85 + .../compiled/multiplyalpha_ftou_pm_rgba_2d_ps.h | 79 + .../multiplyalpha_ftou_pm_rgba_2darray_ps.h | 89 + .../compiled/multiplyalpha_ftou_pm_rgba_3d_ps.h | 83 + .../compiled/multiplyalpha_ftou_pt_rgb_2d_ps.h | 79 + .../multiplyalpha_ftou_pt_rgb_2darray_ps.h | 89 + .../compiled/multiplyalpha_ftou_pt_rgb_3d_ps.h | 80 + .../compiled/multiplyalpha_ftou_pt_rgba_2d_ps.h | 77 + .../multiplyalpha_ftou_pt_rgba_2darray_ps.h | 87 + .../compiled/multiplyalpha_ftou_pt_rgba_3d_ps.h | 80 + .../compiled/multiplyalpha_ftou_um_rgb_2d_ps.h | 87 + .../multiplyalpha_ftou_um_rgb_2darray_ps.h | 97 + .../compiled/multiplyalpha_ftou_um_rgb_3d_ps.h | 90 + .../compiled/multiplyalpha_ftou_um_rgba_2d_ps.h | 85 + .../multiplyalpha_ftou_um_rgba_2darray_ps.h | 95 + .../compiled/multiplyalpha_ftou_um_rgba_3d_ps.h | 88 + .../d3d/d3d11/shaders/compiled/passthrough2d11vs.h | 91 + .../d3d/d3d11/shaders/compiled/passthrough3d11gs.h | 93 + .../d3d/d3d11/shaders/compiled/passthrough3d11vs.h | 75 + .../d3d11/shaders/compiled/passthrougha2d11ps.h | 103 + .../shaders/compiled/passthroughdepth2d11ps.h | 73 + .../d3d11/shaders/compiled/passthroughlum2d11ps.h | 103 + .../shaders/compiled/passthroughlum2darray11ps.h | 85 + .../d3d11/shaders/compiled/passthroughlum3d11ps.h | 79 + .../shaders/compiled/passthroughlumalpha2d11ps.h | 98 + .../compiled/passthroughlumalpha2darray11ps.h | 83 + .../shaders/compiled/passthroughlumalpha3d11ps.h | 77 + .../d3d11/shaders/compiled/passthroughr2d11ps.h | 104 + .../shaders/compiled/passthroughr2darray11ps.h | 86 + .../shaders/compiled/passthroughr2darrayi11ps.h | 90 + .../shaders/compiled/passthroughr2darrayui11ps.h | 90 + .../d3d11/shaders/compiled/passthroughr2di11ps.h | 83 + .../d3d11/shaders/compiled/passthroughr2dui11ps.h | 83 + .../d3d11/shaders/compiled/passthroughr3d11ps.h | 80 + .../d3d11/shaders/compiled/passthroughr3di11ps.h | 86 + .../d3d11/shaders/compiled/passthroughr3dui11ps.h | 86 + .../d3d11/shaders/compiled/passthroughrg2d11ps.h | 104 + .../shaders/compiled/passthroughrg2darray11ps.h | 86 + .../shaders/compiled/passthroughrg2darrayi11ps.h | 90 + .../shaders/compiled/passthroughrg2darrayui11ps.h | 90 + .../d3d11/shaders/compiled/passthroughrg2di11ps.h | 83 + .../d3d11/shaders/compiled/passthroughrg2dui11ps.h | 83 + .../d3d11/shaders/compiled/passthroughrg3d11ps.h | 80 + .../d3d11/shaders/compiled/passthroughrg3di11ps.h | 86 + .../d3d11/shaders/compiled/passthroughrg3dui11ps.h | 86 + .../d3d11/shaders/compiled/passthroughrgb2d11ps.h | 103 + .../shaders/compiled/passthroughrgb2d_565_11ps.h | 118 + .../shaders/compiled/passthroughrgb2darray11ps.h | 85 + .../compiled/passthroughrgb2darray_565_11ps.h | 91 + .../shaders/compiled/passthroughrgb2darrayi11ps.h | 89 + .../shaders/compiled/passthroughrgb2darrayui11ps.h | 89 + .../d3d11/shaders/compiled/passthroughrgb2di11ps.h | 82 + .../shaders/compiled/passthroughrgb2dui11ps.h | 82 + .../d3d11/shaders/compiled/passthroughrgb3d11ps.h | 79 + .../shaders/compiled/passthroughrgb3d_565_11ps.h | 85 + .../d3d11/shaders/compiled/passthroughrgb3di11ps.h | 85 + .../shaders/compiled/passthroughrgb3dui11ps.h | 85 + .../d3d11/shaders/compiled/passthroughrgba2d11ps.h | 93 + .../shaders/compiled/passthroughrgba2d_4444_11ps.h | 112 + .../shaders/compiled/passthroughrgba2d_5551_11ps.h | 112 + .../shaders/compiled/passthroughrgba2darray11ps.h | 81 + .../compiled/passthroughrgba2darray_4444_11ps.h | 89 + .../compiled/passthroughrgba2darray_5551_11ps.h | 89 + .../shaders/compiled/passthroughrgba2darrayi11ps.h | 85 + .../compiled/passthroughrgba2darrayui11ps.h | 85 + .../shaders/compiled/passthroughrgba2di11ps.h | 78 + .../shaders/compiled/passthroughrgba2dms11ps.h | 80 + .../shaders/compiled/passthroughrgba2dui11ps.h | 78 + .../d3d11/shaders/compiled/passthroughrgba3d11ps.h | 74 + .../shaders/compiled/passthroughrgba3d_4444_11ps.h | 83 + .../shaders/compiled/passthroughrgba3d_5551_11ps.h | 83 + .../shaders/compiled/passthroughrgba3di11ps.h | 81 + .../shaders/compiled/passthroughrgba3dui11ps.h | 81 + .../d3d/d3d11/shaders/compiled/resolvecolor2dps.h | 103 + .../d3d/d3d11/shaders/compiled/resolvedepth11_ps.h | 81 + .../shaders/compiled/resolvedepthstencil11_ps.h | 92 + .../shaders/compiled/resolvedepthstencil11_vs.h | 83 + .../d3d11/shaders/compiled/resolvestencil11_ps.h | 84 + .../d3d/d3d11/shaders/compiled/swizzlef2darrayps.h | 135 + .../d3d/d3d11/shaders/compiled/swizzlef2dps.h | 126 + .../d3d/d3d11/shaders/compiled/swizzlef3dps.h | 129 + .../d3d/d3d11/shaders/compiled/swizzlei2darrayps.h | 139 + .../d3d/d3d11/shaders/compiled/swizzlei2dps.h | 132 + .../d3d/d3d11/shaders/compiled/swizzlei3dps.h | 135 + .../d3d11/shaders/compiled/swizzleui2darrayps.h | 139 + .../d3d/d3d11/shaders/compiled/swizzleui2dps.h | 132 + .../d3d/d3d11/shaders/compiled/swizzleui3dps.h | 135 + .../renderer/d3d/d3d11/texture_format_table.cpp | 35 + .../renderer/d3d/d3d11/texture_format_table.h | 118 + .../d3d/d3d11/texture_format_table_autogen.cpp | 3269 ++++++ .../d3d/d3d11/texture_format_table_utils.h | 90 + .../d3d/d3d11/win32/NativeWindow11Win32.cpp | 218 + .../renderer/d3d/d3d11/win32/NativeWindow11Win32.h | 53 + .../src/libANGLE/renderer/d3d/d3d9/Blit9.cpp | 760 ++ .../src/libANGLE/renderer/d3d/d3d9/Blit9.h | 166 + .../src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp | 141 + .../src/libANGLE/renderer/d3d/d3d9/Buffer9.h | 63 + .../src/libANGLE/renderer/d3d/d3d9/Context9.cpp | 529 + .../src/libANGLE/renderer/d3d/d3d9/Context9.h | 265 + .../libANGLE/renderer/d3d/d3d9/DebugAnnotator9.cpp | 48 + .../libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h | 38 + .../src/libANGLE/renderer/d3d/d3d9/Fence9.cpp | 73 + .../src/libANGLE/renderer/d3d/d3d9/Fence9.h | 39 + .../libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp | 416 + .../src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h | 89 + .../src/libANGLE/renderer/d3d/d3d9/Image9.cpp | 907 ++ .../src/libANGLE/renderer/d3d/d3d9/Image9.h | 112 + .../libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp | 161 + .../src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.h | 57 + .../libANGLE/renderer/d3d/d3d9/NativeWindow9.cpp | 37 + .../src/libANGLE/renderer/d3d/d3d9/NativeWindow9.h | 35 + .../src/libANGLE/renderer/d3d/d3d9/Query9.cpp | 176 + .../src/libANGLE/renderer/d3d/d3d9/Query9.h | 50 + .../libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp | 160 + .../src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h | 98 + .../src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp | 3338 ++++++ .../src/libANGLE/renderer/d3d/d3d9/Renderer9.h | 586 ++ .../src/libANGLE/renderer/d3d/d3d9/ShaderCache.h | 110 + .../renderer/d3d/d3d9/ShaderExecutable9.cpp | 51 + .../libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h | 35 + .../libANGLE/renderer/d3d/d3d9/StateManager9.cpp | 888 ++ .../src/libANGLE/renderer/d3d/d3d9/StateManager9.h | 211 + .../src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp | 472 + .../src/libANGLE/renderer/d3d/d3d9/SwapChain9.h | 80 + .../libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp | 575 + .../libANGLE/renderer/d3d/d3d9/TextureStorage9.h | 186 + .../src/libANGLE/renderer/d3d/d3d9/VertexArray9.h | 57 + .../libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp | 153 + .../src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h | 56 + .../renderer/d3d/d3d9/VertexDeclarationCache.cpp | 262 + .../renderer/d3d/d3d9/VertexDeclarationCache.h | 68 + .../libANGLE/renderer/d3d/d3d9/formatutils9.cpp | 695 ++ .../src/libANGLE/renderer/d3d/d3d9/formatutils9.h | 59 + .../libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp | 845 ++ .../libANGLE/renderer/d3d/d3d9/renderer9_utils.h | 105 + .../d3d9/shaders/compiled/componentmaskpremultps.h | 50 + .../d3d/d3d9/shaders/compiled/componentmaskps.h | 48 + .../d3d9/shaders/compiled/componentmaskunmultps.h | 54 + .../d3d/d3d9/shaders/compiled/luminancepremultps.h | 50 + .../d3d/d3d9/shaders/compiled/luminanceps.h | 53 + .../d3d/d3d9/shaders/compiled/luminanceunmultps.h | 54 + .../d3d/d3d9/shaders/compiled/passthroughps.h | 37 + .../d3d/d3d9/shaders/compiled/standardvs.h | 46 + .../libANGLE/renderer/d3d/d3d9/vertexconversion.h | 197 + .../src/libANGLE/renderer/d3d/driver_utils_d3d.cpp | 26 + .../src/libANGLE/renderer/d3d/driver_utils_d3d.h | 21 + .../src/libANGLE/renderer/d3d/formatutilsD3D.h | 24 + .../checkout/src/libANGLE/renderer/d3d_format.cpp | 206 + .../checkout/src/libANGLE/renderer/d3d_format.h | 58 + .../src/libANGLE/renderer/driver_utils.cpp | 438 + .../checkout/src/libANGLE/renderer/driver_utils.h | 278 + .../src/libANGLE/renderer/dxgi_format_map.h | 27 + .../libANGLE/renderer/dxgi_format_map_autogen.cpp | 516 + .../src/libANGLE/renderer/dxgi_support_table.h | 43 + .../renderer/dxgi_support_table_autogen.cpp | 3042 ++++++ .../src/libANGLE/renderer/gl/functionsgl_enums.h | 1376 +++ .../src/libANGLE/renderer/load_functions_table.h | 20 + .../renderer/load_functions_table_autogen.cpp | 5465 ++++++++++ .../src/libANGLE/renderer/renderer_utils.cpp | 1583 +++ .../src/libANGLE/renderer/renderer_utils.h | 499 + .../checkout/src/libANGLE/renderer/serial_utils.h | 126 + gfx/angle/checkout/src/libANGLE/trace.h | 26 + gfx/angle/checkout/src/libANGLE/validationEGL.cpp | 6782 ++++++++++++ gfx/angle/checkout/src/libANGLE/validationEGL.h | 201 + .../checkout/src/libANGLE/validationEGL_autogen.h | 510 + gfx/angle/checkout/src/libANGLE/validationES.cpp | 8666 +++++++++++++++ gfx/angle/checkout/src/libANGLE/validationES.h | 1272 +++ gfx/angle/checkout/src/libANGLE/validationES1.cpp | 2129 ++++ gfx/angle/checkout/src/libANGLE/validationES1.h | 20 + .../checkout/src/libANGLE/validationES1_autogen.h | 395 + gfx/angle/checkout/src/libANGLE/validationES2.cpp | 6544 ++++++++++++ gfx/angle/checkout/src/libANGLE/validationES2.h | 207 + .../checkout/src/libANGLE/validationES2_autogen.h | 666 ++ gfx/angle/checkout/src/libANGLE/validationES3.cpp | 5311 ++++++++++ gfx/angle/checkout/src/libANGLE/validationES3.h | 72 + gfx/angle/checkout/src/libANGLE/validationES31.cpp | 3157 ++++++ gfx/angle/checkout/src/libANGLE/validationES31.h | 300 + .../checkout/src/libANGLE/validationES31_autogen.h | 415 + gfx/angle/checkout/src/libANGLE/validationES32.cpp | 628 ++ gfx/angle/checkout/src/libANGLE/validationES32.h | 20 + .../checkout/src/libANGLE/validationES32_autogen.h | 281 + .../checkout/src/libANGLE/validationES3_autogen.h | 578 + .../checkout/src/libANGLE/validationESEXT.cpp | 3599 +++++++ gfx/angle/checkout/src/libANGLE/validationESEXT.h | 20 + .../src/libANGLE/validationESEXT_autogen.h | 2646 +++++ gfx/angle/checkout/src/libANGLE/validationGL1.cpp | 2421 +++++ .../checkout/src/libANGLE/validationGL1_autogen.h | 1192 +++ gfx/angle/checkout/src/libANGLE/validationGL2.cpp | 262 + .../checkout/src/libANGLE/validationGL2_autogen.h | 158 + gfx/angle/checkout/src/libANGLE/validationGL3.cpp | 634 ++ .../checkout/src/libANGLE/validationGL3_autogen.h | 367 + gfx/angle/checkout/src/libANGLE/validationGL4.cpp | 2223 ++++ .../checkout/src/libANGLE/validationGL4_autogen.h | 1375 +++ 617 files changed, 274826 insertions(+) create mode 100644 gfx/angle/checkout/src/libANGLE/AttributeMap.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/AttributeMap.h create mode 100644 gfx/angle/checkout/src/libANGLE/BinaryStream.h create mode 100644 gfx/angle/checkout/src/libANGLE/BlobCache.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/BlobCache.h create mode 100644 gfx/angle/checkout/src/libANGLE/Buffer.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/Buffer.h create mode 100644 gfx/angle/checkout/src/libANGLE/Caps.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/Caps.h create mode 100644 gfx/angle/checkout/src/libANGLE/Compiler.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/Compiler.h create mode 100644 gfx/angle/checkout/src/libANGLE/Config.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/Config.h create mode 100644 gfx/angle/checkout/src/libANGLE/Constants.h create mode 100644 gfx/angle/checkout/src/libANGLE/Context.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/Context.h create mode 100644 gfx/angle/checkout/src/libANGLE/Context.inl.h create mode 100644 gfx/angle/checkout/src/libANGLE/Context_gl.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/Context_gl_1_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/Context_gl_2_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/Context_gl_3_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/Context_gl_4_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/Context_gles_1_0.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/Context_gles_1_0_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/Context_gles_2_0_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/Context_gles_3_0_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/Context_gles_3_1_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/Context_gles_3_2_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/Context_gles_ext_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/Debug.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/Debug.h create mode 100644 gfx/angle/checkout/src/libANGLE/Device.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/Device.h create mode 100644 gfx/angle/checkout/src/libANGLE/Display.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/Display.h create mode 100644 gfx/angle/checkout/src/libANGLE/EGLSync.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/EGLSync.h create mode 100644 gfx/angle/checkout/src/libANGLE/Error.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/Error.h create mode 100644 gfx/angle/checkout/src/libANGLE/Error.inc create mode 100644 gfx/angle/checkout/src/libANGLE/ErrorStrings.h create mode 100644 gfx/angle/checkout/src/libANGLE/Fence.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/Fence.h create mode 100644 gfx/angle/checkout/src/libANGLE/Framebuffer.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/Framebuffer.h create mode 100644 gfx/angle/checkout/src/libANGLE/FramebufferAttachment.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/FramebufferAttachment.h create mode 100644 gfx/angle/checkout/src/libANGLE/GLES1Renderer.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/GLES1Renderer.h create mode 100644 gfx/angle/checkout/src/libANGLE/GLES1Shaders.inc create mode 100644 gfx/angle/checkout/src/libANGLE/GLES1State.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/GLES1State.h create mode 100644 gfx/angle/checkout/src/libANGLE/HandleAllocator.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/HandleAllocator.h create mode 100644 gfx/angle/checkout/src/libANGLE/Image.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/Image.h create mode 100644 gfx/angle/checkout/src/libANGLE/ImageIndex.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/ImageIndex.h create mode 100644 gfx/angle/checkout/src/libANGLE/IndexRangeCache.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/IndexRangeCache.h create mode 100644 gfx/angle/checkout/src/libANGLE/InfoLog.h create mode 100644 gfx/angle/checkout/src/libANGLE/LoggingAnnotator.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/LoggingAnnotator.h create mode 100644 gfx/angle/checkout/src/libANGLE/MemoryObject.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/MemoryObject.h create mode 100644 gfx/angle/checkout/src/libANGLE/MemoryProgramCache.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/MemoryProgramCache.h create mode 100644 gfx/angle/checkout/src/libANGLE/MemoryShaderCache.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/MemoryShaderCache.h create mode 100644 gfx/angle/checkout/src/libANGLE/Observer.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/Observer.h create mode 100644 gfx/angle/checkout/src/libANGLE/Overlay.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/Overlay.h create mode 100644 gfx/angle/checkout/src/libANGLE/OverlayWidgets.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/OverlayWidgets.h create mode 100644 gfx/angle/checkout/src/libANGLE/Overlay_autogen.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/Overlay_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/Overlay_font_autogen.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/Overlay_font_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/PixelLocalStorage.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/PixelLocalStorage.h create mode 100644 gfx/angle/checkout/src/libANGLE/Platform.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/Program.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/Program.h create mode 100644 gfx/angle/checkout/src/libANGLE/ProgramExecutable.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/ProgramExecutable.h create mode 100644 gfx/angle/checkout/src/libANGLE/ProgramLinkedResources.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/ProgramLinkedResources.h create mode 100644 gfx/angle/checkout/src/libANGLE/ProgramPipeline.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/ProgramPipeline.h create mode 100644 gfx/angle/checkout/src/libANGLE/Query.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/Query.h create mode 100644 gfx/angle/checkout/src/libANGLE/RefCountObject.h create mode 100644 gfx/angle/checkout/src/libANGLE/Renderbuffer.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/Renderbuffer.h create mode 100644 gfx/angle/checkout/src/libANGLE/ResourceManager.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/ResourceManager.h create mode 100644 gfx/angle/checkout/src/libANGLE/ResourceMap.h create mode 100644 gfx/angle/checkout/src/libANGLE/Sampler.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/Sampler.h create mode 100644 gfx/angle/checkout/src/libANGLE/Semaphore.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/Semaphore.h create mode 100644 gfx/angle/checkout/src/libANGLE/Shader.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/Shader.h create mode 100644 gfx/angle/checkout/src/libANGLE/SizedMRUCache.h create mode 100644 gfx/angle/checkout/src/libANGLE/State.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/State.h create mode 100644 gfx/angle/checkout/src/libANGLE/Stream.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/Stream.h create mode 100644 gfx/angle/checkout/src/libANGLE/Surface.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/Surface.h create mode 100644 gfx/angle/checkout/src/libANGLE/Texture.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/Texture.h create mode 100644 gfx/angle/checkout/src/libANGLE/Thread.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/Thread.h create mode 100644 gfx/angle/checkout/src/libANGLE/TransformFeedback.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/TransformFeedback.h create mode 100644 gfx/angle/checkout/src/libANGLE/Uniform.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/Uniform.h create mode 100644 gfx/angle/checkout/src/libANGLE/VaryingPacking.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/VaryingPacking.h create mode 100644 gfx/angle/checkout/src/libANGLE/Version.h create mode 100644 gfx/angle/checkout/src/libANGLE/Version.inc create mode 100644 gfx/angle/checkout/src/libANGLE/VertexArray.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/VertexArray.h create mode 100644 gfx/angle/checkout/src/libANGLE/VertexAttribute.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/VertexAttribute.h create mode 100644 gfx/angle/checkout/src/libANGLE/VertexAttribute.inc create mode 100644 gfx/angle/checkout/src/libANGLE/WorkerThread.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/WorkerThread.h create mode 100644 gfx/angle/checkout/src/libANGLE/angletypes.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/angletypes.h create mode 100644 gfx/angle/checkout/src/libANGLE/angletypes.inc create mode 100644 gfx/angle/checkout/src/libANGLE/capture/FrameCapture.h create mode 100644 gfx/angle/checkout/src/libANGLE/capture/FrameCapture_mock.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/capture/capture_egl.h create mode 100644 gfx/angle/checkout/src/libANGLE/capture/capture_gl_1_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/capture/capture_gl_2_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/capture/capture_gl_3_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/capture/capture_gl_4_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/capture/capture_gles_1_0_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/capture/capture_gles_2_0_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/capture/capture_gles_3_0_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/capture/capture_gles_3_1_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/capture/capture_gles_3_2_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/capture/capture_gles_ext_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/capture/frame_capture_utils.h create mode 100644 gfx/angle/checkout/src/libANGLE/capture/frame_capture_utils_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/capture/frame_capture_utils_mock.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/capture/gl_enum_utils.h create mode 100644 gfx/angle/checkout/src/libANGLE/capture/gl_enum_utils_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/entry_points_utils.h create mode 100644 gfx/angle/checkout/src/libANGLE/es3_copy_conversion_table_autogen.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/features.h create mode 100644 gfx/angle/checkout/src/libANGLE/format_map_autogen.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/format_map_desktop.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/formatutils.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/formatutils.h create mode 100644 gfx/angle/checkout/src/libANGLE/gles_extensions_autogen.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/gles_extensions_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/histogram_macros.h create mode 100644 gfx/angle/checkout/src/libANGLE/queryconversions.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/queryconversions.h create mode 100644 gfx/angle/checkout/src/libANGLE/queryutils.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/queryutils.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/BufferImpl.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/BufferImpl.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/CompilerImpl.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/ContextImpl.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/ContextImpl.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/DeviceImpl.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/DeviceImpl.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/DisplayImpl.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/DisplayImpl.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/EGLImplFactory.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/EGLReusableSync.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/EGLReusableSync.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/EGLSyncImpl.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/EGLSyncImpl.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/FenceNVImpl.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/Format.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/FormatID_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/Format_table_autogen.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/FramebufferAttachmentObjectImpl.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/FramebufferImpl.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/FramebufferImpl.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/GLImplFactory.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/ImageImpl.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/ImageImpl.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/MemoryObjectImpl.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/OverlayImpl.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/ProgramImpl.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/ProgramImpl.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/ProgramPipelineImpl.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/ProgramPipelineImpl.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/QueryImpl.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/QueryImpl.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/RenderTargetCache.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/RenderbufferImpl.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/RenderbufferImpl.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/SamplerImpl.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/SemaphoreImpl.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/ShaderImpl.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/ShaderImpl.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/StreamProducerImpl.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/SurfaceImpl.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/SurfaceImpl.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/SyncImpl.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/TextureImpl.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/TextureImpl.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/TransformFeedbackImpl.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/TransformFeedbackImpl.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/VertexArrayImpl.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/VertexArrayImpl.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/copyvertex.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/copyvertex.inc.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/BufferD3D.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/BufferD3D.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/CompilerD3D.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/CompilerD3D.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/ContextD3D.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/DeviceD3D.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/DeviceD3D.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/DisplayD3D.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/DisplayD3D.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicHLSL.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicHLSL.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicImage2DHLSL.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicImage2DHLSL.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/EGLImageD3D.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/EGLImageD3D.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/FramebufferD3D.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/FramebufferD3D.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/HLSLCompiler.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/HLSLCompiler.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/ImageD3D.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/ImageD3D.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexBuffer.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexBuffer.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexDataManager.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexDataManager.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/NativeWindowD3D.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/NativeWindowD3D.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/ProgramD3D.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/ProgramD3D.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderTargetD3D.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderTargetD3D.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderbufferD3D.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/RendererD3D.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/RendererD3D.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/SamplerD3D.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderD3D.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderD3D.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderExecutableD3D.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderExecutableD3D.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/SurfaceD3D.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/SurfaceD3D.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/SwapChainD3D.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/SwapChainD3D.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureD3D.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureD3D.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureStorage.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexBuffer.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexBuffer.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexDataManager.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexDataManager.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Blit11.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Blit11Helper_autogen.inc create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Buffer11.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Clear11.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Context11.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Context11.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ExternalImageSiblingImpl11.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ExternalImageSiblingImpl11.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Fence11.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Image11.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Image11.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/MappedSubresourceVerifier11.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/MappedSubresourceVerifier11.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/NativeWindow11.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Program11.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Program11.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ProgramPipeline11.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ProgramPipeline11.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Query11.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Query11.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Renderer11.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StateManager11.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Trim11.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Trim11.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexArray11.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/converged/CompositorNativeWindow11.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/converged/CompositorNativeWindow11.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/formatutils11.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_gs.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4f.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4i.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_vs.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11_fl9vs.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11multiviewgs.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11multiviewvs.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11vs.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/cleardepth11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11_fl9ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps1.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps2.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps3.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps4.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps5.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps6.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps7.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps8.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps1.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps2.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps3.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps4.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps5.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps6.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps7.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps8.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps1.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps2.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps3.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps4.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps5.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps6.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps7.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps8.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_2d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_2darray_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_3d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_2d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_2darray_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_3d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_2d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_2darray_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_3d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_565_2d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_565_2darray_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_565_3d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_2d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_2darray_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_3d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_4444_2d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_4444_2darray_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_4444_3d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_5551_2d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_5551_2darray_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_5551_3d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_2d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_2darray_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_3d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_2d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_2darray_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_3d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_2d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_2darray_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_3d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_565_2d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_565_2darray_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_565_3d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_2d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_2darray_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_3d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_4444_2d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_4444_2darray_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_4444_3d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_5551_2d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_5551_2darray_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_5551_3d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgb_2darray_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgb_3d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgba_2darray_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgba_3d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgb_2darray_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgb_3d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgba_2darray_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgba_3d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgb_2darray_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgb_3d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgba_2darray_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgba_3d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_2d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_2darray_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_3d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_2d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_2darray_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_3d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_2d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_2darray_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_3d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_2d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_2darray_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_3d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_2d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_2darray_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_3d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_2d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_2darray_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_3d_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11gs.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11vs.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrougha2d11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2d11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum2d11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum2darray11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum3d11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2darray11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2d11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2darray11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2darrayi11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2darrayui11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2di11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2dui11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3d11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3di11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3dui11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2d11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2darray11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2darrayi11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2darrayui11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2di11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2dui11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3d11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3di11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3dui11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d_565_11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darray11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darray_565_11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darrayi11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darrayui11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2di11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2dui11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d_565_11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3di11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3dui11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d_4444_11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d_5551_11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darray11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darray_4444_11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darray_5551_11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darrayi11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darrayui11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2di11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dms11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dui11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d_4444_11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d_5551_11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3di11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3dui11ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvecolor2dps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepth11_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_vs.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvestencil11_ps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2darrayps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2dps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef3dps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2darrayps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei3dps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2darrayps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2dps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui3dps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table_utils.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Blit9.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Buffer9.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Context9.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Context9.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Fence9.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Fence9.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Image9.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Image9.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Query9.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Query9.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Renderer9.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/ShaderCache.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/StateManager9.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/formatutils9.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskpremultps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskunmultps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminancepremultps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceunmultps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/passthroughps.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/standardvs.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/vertexconversion.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/driver_utils_d3d.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/driver_utils_d3d.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d/formatutilsD3D.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d_format.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/d3d_format.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/driver_utils.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/driver_utils.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/dxgi_format_map.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/dxgi_format_map_autogen.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/dxgi_support_table.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/dxgi_support_table_autogen.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/gl/functionsgl_enums.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/load_functions_table.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/load_functions_table_autogen.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/renderer_utils.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/renderer_utils.h create mode 100644 gfx/angle/checkout/src/libANGLE/renderer/serial_utils.h create mode 100644 gfx/angle/checkout/src/libANGLE/trace.h create mode 100644 gfx/angle/checkout/src/libANGLE/validationEGL.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/validationEGL.h create mode 100644 gfx/angle/checkout/src/libANGLE/validationEGL_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/validationES.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/validationES.h create mode 100644 gfx/angle/checkout/src/libANGLE/validationES1.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/validationES1.h create mode 100644 gfx/angle/checkout/src/libANGLE/validationES1_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/validationES2.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/validationES2.h create mode 100644 gfx/angle/checkout/src/libANGLE/validationES2_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/validationES3.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/validationES3.h create mode 100644 gfx/angle/checkout/src/libANGLE/validationES31.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/validationES31.h create mode 100644 gfx/angle/checkout/src/libANGLE/validationES31_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/validationES32.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/validationES32.h create mode 100644 gfx/angle/checkout/src/libANGLE/validationES32_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/validationES3_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/validationESEXT.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/validationESEXT.h create mode 100644 gfx/angle/checkout/src/libANGLE/validationESEXT_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/validationGL1.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/validationGL1_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/validationGL2.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/validationGL2_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/validationGL3.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/validationGL3_autogen.h create mode 100644 gfx/angle/checkout/src/libANGLE/validationGL4.cpp create mode 100644 gfx/angle/checkout/src/libANGLE/validationGL4_autogen.h (limited to 'gfx/angle/checkout/src/libANGLE') diff --git a/gfx/angle/checkout/src/libANGLE/AttributeMap.cpp b/gfx/angle/checkout/src/libANGLE/AttributeMap.cpp new file mode 100644 index 0000000000..6b56aee142 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/AttributeMap.cpp @@ -0,0 +1,147 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "libANGLE/AttributeMap.h" + +#include "common/debug.h" + +namespace egl +{ + +AttributeMap::AttributeMap() = default; + +AttributeMap::AttributeMap(const AttributeMap &other) = default; + +AttributeMap &AttributeMap::operator=(const AttributeMap &other) = default; + +AttributeMap::~AttributeMap() = default; + +void AttributeMap::insert(EGLAttrib key, EGLAttrib value) +{ + mValidatedAttributes[key] = value; +} + +bool AttributeMap::contains(EGLAttrib key) const +{ + return (attribs().find(key) != attribs().end()); +} + +EGLAttrib AttributeMap::get(EGLAttrib key) const +{ + auto iter = attribs().find(key); + ASSERT(iter != attribs().end()); + return iter->second; +} + +EGLAttrib AttributeMap::get(EGLAttrib key, EGLAttrib defaultValue) const +{ + auto iter = attribs().find(key); + return (iter != attribs().end()) ? iter->second : defaultValue; +} + +EGLint AttributeMap::getAsInt(EGLAttrib key) const +{ + return static_cast(get(key)); +} + +EGLint AttributeMap::getAsInt(EGLAttrib key, EGLint defaultValue) const +{ + return static_cast(get(key, static_cast(defaultValue))); +} + +bool AttributeMap::isEmpty() const +{ + return attribs().empty(); +} + +std::vector AttributeMap::toIntVector() const +{ + std::vector ret; + for (const auto &pair : attribs()) + { + ret.push_back(static_cast(pair.first)); + ret.push_back(static_cast(pair.second)); + } + ret.push_back(EGL_NONE); + + return ret; +} + +AttributeMap::const_iterator AttributeMap::begin() const +{ + return attribs().begin(); +} + +AttributeMap::const_iterator AttributeMap::end() const +{ + return attribs().end(); +} + +bool AttributeMap::validate(const ValidationContext *val, + const egl::Display *display, + AttributeValidationFunc validationFunc) const +{ + if (mIntPointer) + { + for (const EGLint *curAttrib = mIntPointer; curAttrib[0] != EGL_NONE; curAttrib += 2) + { + if (!validationFunc(val, display, curAttrib[0])) + { + return false; + } + + mValidatedAttributes[static_cast(curAttrib[0])] = + static_cast(curAttrib[1]); + } + mIntPointer = nullptr; + } + + if (mAttribPointer) + { + for (const EGLAttrib *curAttrib = mAttribPointer; curAttrib[0] != EGL_NONE; curAttrib += 2) + { + if (!validationFunc(val, display, curAttrib[0])) + { + return false; + } + + mValidatedAttributes[curAttrib[0]] = curAttrib[1]; + } + mAttribPointer = nullptr; + } + + return true; +} + +void AttributeMap::initializeWithoutValidation() const +{ + auto alwaysTrue = [](const ValidationContext *, const egl::Display *, EGLAttrib) { + return true; + }; + (void)validate(nullptr, nullptr, alwaysTrue); +} + +// static +AttributeMap AttributeMap::CreateFromIntArray(const EGLint *attributes) +{ + AttributeMap map; + map.mIntPointer = attributes; + return map; +} + +// static +AttributeMap AttributeMap::CreateFromAttribArray(const EGLAttrib *attributes) +{ + AttributeMap map; + map.mAttribPointer = attributes; + return map; +} + +bool AttributeMap::isValidated() const +{ + return mIntPointer == nullptr && mAttribPointer == nullptr; +} +} // namespace egl diff --git a/gfx/angle/checkout/src/libANGLE/AttributeMap.h b/gfx/angle/checkout/src/libANGLE/AttributeMap.h new file mode 100644 index 0000000000..60ba913fe1 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/AttributeMap.h @@ -0,0 +1,100 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef LIBANGLE_ATTRIBUTEMAP_H_ +#define LIBANGLE_ATTRIBUTEMAP_H_ + +#include "common/FastVector.h" +#include "common/PackedEnums.h" + +#include + +#include +#include + +namespace egl +{ +class Display; +struct ValidationContext; + +// Validates {key, value} for each attribute. Generates an error and returns false on invalid usage. +using AttributeValidationFunc = + std::function; + +class AttributeMap final +{ + public: + static constexpr size_t kMapSize = 2; + using Map = angle::FlatUnorderedMap; + + AttributeMap(); + AttributeMap(const AttributeMap &other); + AttributeMap &operator=(const AttributeMap &other); + ~AttributeMap(); + + void insert(EGLAttrib key, EGLAttrib value); + bool contains(EGLAttrib key) const; + + EGLAttrib get(EGLAttrib key) const; + EGLAttrib get(EGLAttrib key, EGLAttrib defaultValue) const; + EGLint getAsInt(EGLAttrib key) const; + EGLint getAsInt(EGLAttrib key, EGLint defaultValue) const; + + template + PackedEnumT getAsPackedEnum(EGLAttrib key) const + { + return FromEGLenum(static_cast(get(key))); + } + + using const_iterator = Map::const_iterator; + + template + PackedEnumT getAsPackedEnum(EGLAttrib key, PackedEnumT defaultValue) const + { + const_iterator iter = attribs().find(key); + return (attribs().find(key) != attribs().end()) + ? FromEGLenum(static_cast(iter->second)) + : defaultValue; + } + + bool isEmpty() const; + std::vector toIntVector() const; + + const_iterator begin() const; + const_iterator end() const; + + [[nodiscard]] bool validate(const ValidationContext *val, + const egl::Display *display, + AttributeValidationFunc validationFunc) const; + + // TODO: remove this and validate at every call site. http://anglebug.com/6671 + void initializeWithoutValidation() const; + + static AttributeMap CreateFromIntArray(const EGLint *attributes); + static AttributeMap CreateFromAttribArray(const EGLAttrib *attributes); + + private: + bool isValidated() const; + + const Map &attribs() const + { + ASSERT(isValidated()); + return mValidatedAttributes; + } + + Map &attribs() + { + ASSERT(isValidated()); + return mValidatedAttributes; + } + + mutable const EGLint *mIntPointer = nullptr; + mutable const EGLAttrib *mAttribPointer = nullptr; + mutable Map mValidatedAttributes; +}; +} // namespace egl + +#endif // LIBANGLE_ATTRIBUTEMAP_H_ diff --git a/gfx/angle/checkout/src/libANGLE/BinaryStream.h b/gfx/angle/checkout/src/libANGLE/BinaryStream.h new file mode 100644 index 0000000000..35672f62e8 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/BinaryStream.h @@ -0,0 +1,286 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// BinaryStream.h: Provides binary serialization of simple types. + +#ifndef LIBANGLE_BINARYSTREAM_H_ +#define LIBANGLE_BINARYSTREAM_H_ + +#include +#include +#include +#include + +#include "common/angleutils.h" +#include "common/mathutil.h" + +namespace gl +{ +template +struct PromotedIntegerType +{ + using type = typename std::conditional< + std::is_signed::value, + typename std::conditional::type, + typename std::conditional::type>::type; +}; + +class BinaryInputStream : angle::NonCopyable +{ + public: + BinaryInputStream(const void *data, size_t length) + { + mError = false; + mOffset = 0; + mData = static_cast(data); + mLength = length; + } + + // readInt will generate an error for bool types + template + IntT readInt() + { + static_assert(!std::is_same()>(), "Use readBool"); + using PromotedIntT = typename PromotedIntegerType::type; + PromotedIntT value = 0; + read(&value); + ASSERT(angle::IsValueInRangeForNumericType(value)); + return static_cast(value); + } + + template + void readInt(IntT *outValue) + { + *outValue = readInt(); + } + + template + void readIntVector(std::vector *param) + { + size_t size = readInt(); + for (size_t index = 0; index < size; ++index) + { + param->push_back(readInt()); + } + } + + template + EnumT readEnum() + { + using UnderlyingType = typename std::underlying_type::type; + return static_cast(readInt()); + } + + template + void readEnum(EnumT *outValue) + { + *outValue = readEnum(); + } + + bool readBool() + { + int value = 0; + read(&value); + return (value > 0); + } + + void readBool(bool *outValue) { *outValue = readBool(); } + + void readBytes(unsigned char outArray[], size_t count) { read(outArray, count); } + + std::string readString() + { + std::string outString; + readString(&outString); + return outString; + } + + void readString(std::string *v) + { + size_t length; + readInt(&length); + + if (mError) + { + return; + } + + angle::CheckedNumeric checkedOffset(mOffset); + checkedOffset += length; + + if (!checkedOffset.IsValid() || mOffset + length > mLength) + { + mError = true; + return; + } + + v->assign(reinterpret_cast(mData) + mOffset, length); + mOffset = checkedOffset.ValueOrDie(); + } + + float readFloat() + { + float f; + read(&f, 1); + return f; + } + + void skip(size_t length) + { + angle::CheckedNumeric checkedOffset(mOffset); + checkedOffset += length; + + if (!checkedOffset.IsValid() || mOffset + length > mLength) + { + mError = true; + return; + } + + mOffset = checkedOffset.ValueOrDie(); + } + + size_t offset() const { return mOffset; } + size_t remainingSize() const + { + ASSERT(mLength >= mOffset); + return mLength - mOffset; + } + + bool error() const { return mError; } + + bool endOfStream() const { return mOffset == mLength; } + + const uint8_t *data() { return mData; } + + private: + bool mError; + size_t mOffset; + const uint8_t *mData; + size_t mLength; + + template + void read(T *v, size_t num) + { + static_assert(std::is_fundamental::value, "T must be a fundamental type."); + + angle::CheckedNumeric checkedLength(num); + checkedLength *= sizeof(T); + if (!checkedLength.IsValid()) + { + mError = true; + return; + } + + angle::CheckedNumeric checkedOffset(mOffset); + checkedOffset += checkedLength; + + if (!checkedOffset.IsValid() || checkedOffset.ValueOrDie() > mLength) + { + mError = true; + return; + } + + memcpy(v, mData + mOffset, checkedLength.ValueOrDie()); + mOffset = checkedOffset.ValueOrDie(); + } + + template + void read(T *v) + { + read(v, 1); + } +}; + +class BinaryOutputStream : angle::NonCopyable +{ + public: + BinaryOutputStream(); + ~BinaryOutputStream(); + + // writeInt also handles bool types + template + void writeInt(IntT param) + { + static_assert(std::is_integral::value, "Not an integral type"); + static_assert(!std::is_same()>(), "Use writeBool"); + using PromotedIntT = typename PromotedIntegerType::type; + ASSERT(angle::IsValueInRangeForNumericType(param)); + PromotedIntT intValue = static_cast(param); + write(&intValue, 1); + } + + // Specialized writeInt for values that can also be exactly -1. + template + void writeIntOrNegOne(UintT param) + { + if (param == static_cast(-1)) + { + writeInt(-1); + } + else + { + writeInt(param); + } + } + + template + void writeIntVector(const std::vector ¶m) + { + writeInt(param.size()); + for (IntT element : param) + { + writeIntOrNegOne(element); + } + } + + template + void writeEnum(EnumT param) + { + using UnderlyingType = typename std::underlying_type::type; + writeInt(static_cast(param)); + } + + void writeString(const std::string &v) + { + writeInt(v.length()); + write(v.c_str(), v.length()); + } + + void writeBytes(const unsigned char *bytes, size_t count) { write(bytes, count); } + + void writeBool(bool value) + { + int intValue = value ? 1 : 0; + write(&intValue, 1); + } + + void writeFloat(float value) { write(&value, 1); } + + size_t length() const { return mData.size(); } + + const void *data() const { return mData.size() ? &mData[0] : nullptr; } + + const std::vector &getData() const { return mData; } + + private: + template + void write(const T *v, size_t num) + { + static_assert(std::is_fundamental::value, "T must be a fundamental type."); + const char *asBytes = reinterpret_cast(v); + mData.insert(mData.end(), asBytes, asBytes + num * sizeof(T)); + } + + std::vector mData; +}; + +inline BinaryOutputStream::BinaryOutputStream() {} + +inline BinaryOutputStream::~BinaryOutputStream() = default; + +} // namespace gl + +#endif // LIBANGLE_BINARYSTREAM_H_ diff --git a/gfx/angle/checkout/src/libANGLE/BlobCache.cpp b/gfx/angle/checkout/src/libANGLE/BlobCache.cpp new file mode 100644 index 0000000000..6a3e2dcc56 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/BlobCache.cpp @@ -0,0 +1,277 @@ +// +// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// BlobCache: Stores keyed blobs in memory to support EGL_ANDROID_blob_cache. +// Can be used in conjunction with the platform layer to warm up the cache from +// disk. MemoryProgramCache uses this to handle caching of compiled programs. + +#include "libANGLE/BlobCache.h" +#include "common/utilities.h" +#include "libANGLE/Context.h" +#include "libANGLE/Display.h" +#include "libANGLE/histogram_macros.h" +#include "platform/PlatformMethods.h" + +#define USE_SYSTEM_ZLIB +#include "compression_utils_portable.h" + +namespace egl +{ + +namespace +{ +enum CacheResult +{ + kCacheMiss, + kCacheHitMemory, + kCacheHitDisk, + kCacheResultMax, +}; + +} // anonymous namespace + +// In oder to store more cache in blob cache, compress cacheData to compressedData +// before being stored. +bool CompressBlobCacheData(const size_t cacheSize, + const uint8_t *cacheData, + angle::MemoryBuffer *compressedData) +{ + uLong uncompressedSize = static_cast(cacheSize); + uLong expectedCompressedSize = zlib_internal::GzipExpectedCompressedSize(uncompressedSize); + + // Allocate memory. + if (!compressedData->resize(expectedCompressedSize)) + { + ERR() << "Failed to allocate memory for compression"; + return false; + } + + int zResult = zlib_internal::GzipCompressHelper(compressedData->data(), &expectedCompressedSize, + cacheData, uncompressedSize, nullptr, nullptr); + + if (zResult != Z_OK) + { + ERR() << "Failed to compress cache data: " << zResult; + return false; + } + + // Resize it to expected size. + if (!compressedData->resize(expectedCompressedSize)) + { + return false; + } + + return true; +} + +bool DecompressBlobCacheData(const uint8_t *compressedData, + const size_t compressedSize, + angle::MemoryBuffer *uncompressedData) +{ + // Call zlib function to decompress. + uint32_t uncompressedSize = + zlib_internal::GetGzipUncompressedSize(compressedData, compressedSize); + + // Allocate enough memory. + if (!uncompressedData->resize(uncompressedSize)) + { + ERR() << "Failed to allocate memory for decompression"; + return false; + } + + uLong destLen = uncompressedSize; + int zResult = zlib_internal::GzipUncompressHelper( + uncompressedData->data(), &destLen, compressedData, static_cast(compressedSize)); + + if (zResult != Z_OK) + { + ERR() << "Failed to decompress data: " << zResult << "\n"; + return false; + } + + // Resize it to expected size. + if (!uncompressedData->resize(destLen)) + { + return false; + } + + return true; +} + +BlobCache::BlobCache(size_t maxCacheSizeBytes) + : mBlobCache(maxCacheSizeBytes), mSetBlobFunc(nullptr), mGetBlobFunc(nullptr) +{} + +BlobCache::~BlobCache() {} + +void BlobCache::put(const BlobCache::Key &key, angle::MemoryBuffer &&value) +{ + if (areBlobCacheFuncsSet()) + { + std::scoped_lock lock(mBlobCacheMutex); + // Store the result in the application's cache + mSetBlobFunc(key.data(), key.size(), value.data(), value.size()); + } + else + { + populate(key, std::move(value), CacheSource::Memory); + } +} + +bool BlobCache::compressAndPut(const BlobCache::Key &key, + angle::MemoryBuffer &&uncompressedValue, + size_t *compressedSize) +{ + angle::MemoryBuffer compressedValue; + if (!CompressBlobCacheData(uncompressedValue.size(), uncompressedValue.data(), + &compressedValue)) + { + return false; + } + if (compressedSize != nullptr) + *compressedSize = compressedValue.size(); + put(key, std::move(compressedValue)); + return true; +} + +void BlobCache::putApplication(const BlobCache::Key &key, const angle::MemoryBuffer &value) +{ + if (areBlobCacheFuncsSet()) + { + std::scoped_lock lock(mBlobCacheMutex); + mSetBlobFunc(key.data(), key.size(), value.data(), value.size()); + } +} + +void BlobCache::populate(const BlobCache::Key &key, angle::MemoryBuffer &&value, CacheSource source) +{ + std::scoped_lock lock(mBlobCacheMutex); + CacheEntry newEntry; + newEntry.first = std::move(value); + newEntry.second = source; + + // Cache it inside blob cache only if caching inside the application is not possible. + mBlobCache.put(key, std::move(newEntry), newEntry.first.size()); +} + +bool BlobCache::get(angle::ScratchBuffer *scratchBuffer, + const BlobCache::Key &key, + BlobCache::Value *valueOut, + size_t *bufferSizeOut) +{ + // Look into the application's cache, if there is such a cache + if (areBlobCacheFuncsSet()) + { + std::scoped_lock lock(mBlobCacheMutex); + EGLsizeiANDROID valueSize = mGetBlobFunc(key.data(), key.size(), nullptr, 0); + if (valueSize <= 0) + { + return false; + } + + angle::MemoryBuffer *scratchMemory; + bool result = scratchBuffer->get(valueSize, &scratchMemory); + if (!result) + { + ERR() << "Failed to allocate memory for binary blob"; + return false; + } + + EGLsizeiANDROID originalValueSize = valueSize; + valueSize = mGetBlobFunc(key.data(), key.size(), scratchMemory->data(), valueSize); + + // Make sure the key/value pair still exists/is unchanged after the second call + // (modifications to the application cache by another thread are a possibility) + if (valueSize != originalValueSize) + { + // This warning serves to find issues with the application cache, none of which are + // currently known to be thread-safe. If such a use ever arises, this WARN can be + // removed. + WARN() << "Binary blob no longer available in cache (removed by a thread?)"; + return false; + } + + *valueOut = BlobCache::Value(scratchMemory->data(), scratchMemory->size()); + *bufferSizeOut = valueSize; + return true; + } + + std::scoped_lock lock(mBlobCacheMutex); + // Otherwise we are doing caching internally, so try to find it there + const CacheEntry *entry; + bool result = mBlobCache.get(key, &entry); + + if (result) + { + + *valueOut = BlobCache::Value(entry->first.data(), entry->first.size()); + *bufferSizeOut = entry->first.size(); + } + + return result; +} + +bool BlobCache::getAt(size_t index, const BlobCache::Key **keyOut, BlobCache::Value *valueOut) +{ + std::scoped_lock lock(mBlobCacheMutex); + const CacheEntry *valueBuf; + bool result = mBlobCache.getAt(index, keyOut, &valueBuf); + if (result) + { + *valueOut = BlobCache::Value(valueBuf->first.data(), valueBuf->first.size()); + } + return result; +} + +BlobCache::GetAndDecompressResult BlobCache::getAndDecompress( + angle::ScratchBuffer *scratchBuffer, + const BlobCache::Key &key, + angle::MemoryBuffer *uncompressedValueOut) +{ + ASSERT(uncompressedValueOut); + + Value compressedValue; + size_t compressedSize; + if (!get(scratchBuffer, key, &compressedValue, &compressedSize)) + { + return GetAndDecompressResult::NotFound; + } + + { + // This needs to be locked because `DecompressBlobCacheData` is reading shared memory from + // `compressedValue.data()`. + std::scoped_lock lock(mBlobCacheMutex); + if (!DecompressBlobCacheData(compressedValue.data(), compressedSize, uncompressedValueOut)) + { + return GetAndDecompressResult::DecompressFailure; + } + } + + return GetAndDecompressResult::GetSuccess; +} + +void BlobCache::remove(const BlobCache::Key &key) +{ + std::scoped_lock lock(mBlobCacheMutex); + mBlobCache.eraseByKey(key); +} + +void BlobCache::setBlobCacheFuncs(EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get) +{ + std::scoped_lock lock(mBlobCacheMutex); + mSetBlobFunc = set; + mGetBlobFunc = get; +} + +bool BlobCache::areBlobCacheFuncsSet() const +{ + std::scoped_lock lock(mBlobCacheMutex); + // Either none or both of the callbacks should be set. + ASSERT((mSetBlobFunc != nullptr) == (mGetBlobFunc != nullptr)); + + return mSetBlobFunc != nullptr && mGetBlobFunc != nullptr; +} + +} // namespace egl diff --git a/gfx/angle/checkout/src/libANGLE/BlobCache.h b/gfx/angle/checkout/src/libANGLE/BlobCache.h new file mode 100644 index 0000000000..772eee04aa --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/BlobCache.h @@ -0,0 +1,182 @@ +// +// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// BlobCache: Stores compiled and linked programs in memory so they don't +// always have to be re-compiled. Can be used in conjunction with the platform +// layer to warm up the cache from disk. + +#ifndef LIBANGLE_BLOB_CACHE_H_ +#define LIBANGLE_BLOB_CACHE_H_ + +#include +#include + +#include +#include "common/MemoryBuffer.h" +#include "common/hash_utils.h" +#include "libANGLE/Error.h" +#include "libANGLE/SizedMRUCache.h" + +namespace gl +{ +class Context; +} // namespace gl + +namespace egl +{ +// 160-bit SHA-1 hash key used for hasing a program. BlobCache opts in using fixed keys for +// simplicity and efficiency. +static constexpr size_t kBlobCacheKeyLength = angle::base::kSHA1Length; +using BlobCacheKey = std::array; +} // namespace egl + +namespace std +{ +template <> +struct hash +{ + // Simple routine to hash four ints. + size_t operator()(const egl::BlobCacheKey &key) const + { + return angle::ComputeGenericHash(key.data(), key.size()); + } +}; +} // namespace std + +namespace egl +{ + +bool CompressBlobCacheData(const size_t cacheSize, + const uint8_t *cacheData, + angle::MemoryBuffer *compressedData); +bool DecompressBlobCacheData(const uint8_t *compressedData, + const size_t compressedSize, + angle::MemoryBuffer *uncompressedData); + +class BlobCache final : angle::NonCopyable +{ + public: + // 160-bit SHA-1 hash key used for hasing a program. BlobCache opts in using fixed keys for + // simplicity and efficiency. + static constexpr size_t kKeyLength = kBlobCacheKeyLength; + using Key = BlobCacheKey; + class Value + { + public: + Value() : mPtr(nullptr), mSize(0) {} + Value(const uint8_t *ptr, size_t sz) : mPtr(ptr), mSize(sz) {} + + // A very basic struct to hold the pointer and size together. The objects of this class + // don't own the memory. + const uint8_t *data() { return mPtr; } + size_t size() { return mSize; } + + const uint8_t &operator[](size_t pos) const + { + ASSERT(pos < mSize); + return mPtr[pos]; + } + + private: + const uint8_t *mPtr; + size_t mSize; + }; + enum class CacheSource + { + Memory, + Disk, + }; + + explicit BlobCache(size_t maxCacheSizeBytes); + ~BlobCache(); + + // Store a key-blob pair in the cache. If application callbacks are set, the application cache + // will be used. Otherwise the value is cached in this object. + void put(const BlobCache::Key &key, angle::MemoryBuffer &&value); + + // Store a key-blob pair in the cache, but compress the blob before insertion. Returns false if + // compression fails, returns true otherwise. + bool compressAndPut(const BlobCache::Key &key, + angle::MemoryBuffer &&uncompressedValue, + size_t *compressedSize); + + // Store a key-blob pair in the application cache, only if application callbacks are set. + void putApplication(const BlobCache::Key &key, const angle::MemoryBuffer &value); + + // Store a key-blob pair in the cache without making callbacks to the application. This is used + // to repopulate this object's cache on startup without generating callback calls. + void populate(const BlobCache::Key &key, + angle::MemoryBuffer &&value, + CacheSource source = CacheSource::Disk); + + // Check if the cache contains the blob corresponding to this key. If application callbacks are + // set, those will be used. Otherwise they key is looked up in this object's cache. + [[nodiscard]] bool get(angle::ScratchBuffer *scratchBuffer, + const BlobCache::Key &key, + BlobCache::Value *valueOut, + size_t *bufferSizeOut); + + // For querying the contents of the cache. + [[nodiscard]] bool getAt(size_t index, + const BlobCache::Key **keyOut, + BlobCache::Value *valueOut); + + enum class GetAndDecompressResult + { + GetSuccess, + NotFound, + DecompressFailure, + }; + [[nodiscard]] GetAndDecompressResult getAndDecompress( + angle::ScratchBuffer *scratchBuffer, + const BlobCache::Key &key, + angle::MemoryBuffer *uncompressedValueOut); + + // Evict a blob from the binary cache. + void remove(const BlobCache::Key &key); + + // Empty the cache. + void clear() { mBlobCache.clear(); } + + // Resize the cache. Discards current contents. + void resize(size_t maxCacheSizeBytes) { mBlobCache.resize(maxCacheSizeBytes); } + + // Returns the number of entries in the cache. + size_t entryCount() const { return mBlobCache.entryCount(); } + + // Reduces the current cache size and returns the number of bytes freed. + size_t trim(size_t limit) { return mBlobCache.shrinkToSize(limit); } + + // Returns the current cache size in bytes. + size_t size() const { return mBlobCache.size(); } + + // Returns whether the cache is empty + bool empty() const { return mBlobCache.empty(); } + + // Returns the maximum cache size in bytes. + size_t maxSize() const { return mBlobCache.maxSize(); } + + void setBlobCacheFuncs(EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get); + + bool areBlobCacheFuncsSet() const; + + bool isCachingEnabled() const { return areBlobCacheFuncsSet() || maxSize() > 0; } + + std::mutex &getMutex() { return mBlobCacheMutex; } + + private: + // This internal cache is used only if the application is not providing caching callbacks + using CacheEntry = std::pair; + + mutable std::mutex mBlobCacheMutex; + angle::SizedMRUCache mBlobCache; + + EGLSetBlobFuncANDROID mSetBlobFunc; + EGLGetBlobFuncANDROID mGetBlobFunc; +}; + +} // namespace egl + +#endif // LIBANGLE_MEMORY_PROGRAM_CACHE_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Buffer.cpp b/gfx/angle/checkout/src/libANGLE/Buffer.cpp new file mode 100644 index 0000000000..440cfd873a --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Buffer.cpp @@ -0,0 +1,449 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Buffer.cpp: Implements the gl::Buffer class, representing storage of vertex and/or +// index data. Implements GL buffer objects and related functionality. +// [OpenGL ES 2.0.24] section 2.9 page 21. + +#include "libANGLE/Buffer.h" + +#include "libANGLE/Context.h" +#include "libANGLE/renderer/BufferImpl.h" +#include "libANGLE/renderer/GLImplFactory.h" + +namespace gl +{ +namespace +{ +constexpr angle::SubjectIndex kImplementationSubjectIndex = 0; +constexpr size_t kInvalidContentsObserverIndex = std::numeric_limits::max(); +} // anonymous namespace + +BufferState::BufferState() + : mLabel(), + mUsage(BufferUsage::StaticDraw), + mSize(0), + mAccessFlags(0), + mAccess(GL_WRITE_ONLY_OES), + mMapped(GL_FALSE), + mMapPointer(nullptr), + mMapOffset(0), + mMapLength(0), + mBindingCount(0), + mTransformFeedbackIndexedBindingCount(0), + mTransformFeedbackGenericBindingCount(0), + mImmutable(GL_FALSE), + mStorageExtUsageFlags(0), + mExternal(GL_FALSE) +{} + +BufferState::~BufferState() {} + +Buffer::Buffer(rx::GLImplFactory *factory, BufferID id) + : RefCountObject(factory->generateSerial(), id), + mImpl(factory->createBuffer(mState)), + mImplObserver(this, kImplementationSubjectIndex) +{ + mImplObserver.bind(mImpl); +} + +Buffer::~Buffer() +{ + SafeDelete(mImpl); +} + +void Buffer::onDestroy(const Context *context) +{ + // In tests, mImpl might be null. + if (mImpl) + mImpl->destroy(context); +} + +angle::Result Buffer::setLabel(const Context *context, const std::string &label) +{ + mState.mLabel = label; + if (mImpl) + { + return mImpl->onLabelUpdate(context); + } + return angle::Result::Continue; +} + +const std::string &Buffer::getLabel() const +{ + return mState.mLabel; +} + +angle::Result Buffer::bufferStorageExternal(Context *context, + BufferBinding target, + GLsizeiptr size, + GLeglClientBufferEXT clientBuffer, + GLbitfield flags) +{ + return bufferExternalDataImpl(context, target, clientBuffer, size, flags); +} + +angle::Result Buffer::bufferStorage(Context *context, + BufferBinding target, + GLsizeiptr size, + const void *data, + GLbitfield flags) +{ + return bufferDataImpl(context, target, data, size, BufferUsage::InvalidEnum, flags); +} + +angle::Result Buffer::bufferData(Context *context, + BufferBinding target, + const void *data, + GLsizeiptr size, + BufferUsage usage) +{ + GLbitfield flags = (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_DYNAMIC_STORAGE_BIT_EXT); + return bufferDataImpl(context, target, data, size, usage, flags); +} + +angle::Result Buffer::bufferDataImpl(Context *context, + BufferBinding target, + const void *data, + GLsizeiptr size, + BufferUsage usage, + GLbitfield flags) +{ + const void *dataForImpl = data; + + if (mState.isMapped()) + { + // Per the OpenGL ES 3.0 spec, buffers are implicity unmapped when a call to + // BufferData happens on a mapped buffer: + // + // If any portion of the buffer object is mapped in the current context or any context + // current to another thread, it is as though UnmapBuffer (see section 2.10.3) is + // executed in each such context prior to deleting the existing data store. + // + GLboolean dontCare = GL_FALSE; + ANGLE_TRY(unmap(context, &dontCare)); + } + + // If we are using robust resource init, make sure the buffer starts cleared. + // Note: the Context is checked for nullptr because of some testing code. + // TODO(jmadill): Investigate lazier clearing. + if (context && context->isRobustResourceInitEnabled() && !data && size > 0) + { + angle::MemoryBuffer *scratchBuffer = nullptr; + ANGLE_CHECK_GL_ALLOC( + context, context->getZeroFilledBuffer(static_cast(size), &scratchBuffer)); + dataForImpl = scratchBuffer->data(); + } + + if (mImpl->setDataWithUsageFlags(context, target, nullptr, dataForImpl, size, usage, flags) == + angle::Result::Stop) + { + // If setData fails, the buffer contents are undefined. Set a zero size to indicate that. + mIndexRangeCache.clear(); + mState.mSize = 0; + + // Notify when storage changes. + onStateChange(angle::SubjectMessage::SubjectChanged); + + return angle::Result::Stop; + } + + bool wholeBuffer = size == mState.mSize; + + mIndexRangeCache.clear(); + mState.mUsage = usage; + mState.mSize = size; + mState.mImmutable = (usage == BufferUsage::InvalidEnum); + mState.mStorageExtUsageFlags = flags; + + // Notify when storage changes. + if (wholeBuffer) + { + onContentsChange(); + } + else + { + onStateChange(angle::SubjectMessage::SubjectChanged); + } + + return angle::Result::Continue; +} + +angle::Result Buffer::bufferExternalDataImpl(Context *context, + BufferBinding target, + GLeglClientBufferEXT clientBuffer, + GLsizeiptr size, + GLbitfield flags) +{ + if (mState.isMapped()) + { + // Per the OpenGL ES 3.0 spec, buffers are implicitly unmapped when a call to + // BufferData happens on a mapped buffer: + // + // If any portion of the buffer object is mapped in the current context or any context + // current to another thread, it is as though UnmapBuffer (see section 2.10.3) is + // executed in each such context prior to deleting the existing data store. + // + GLboolean dontCare = GL_FALSE; + ANGLE_TRY(unmap(context, &dontCare)); + } + + if (mImpl->setDataWithUsageFlags(context, target, clientBuffer, nullptr, size, + BufferUsage::InvalidEnum, flags) == angle::Result::Stop) + { + // If setData fails, the buffer contents are undefined. Set a zero size to indicate that. + mIndexRangeCache.clear(); + mState.mSize = 0; + + // Notify when storage changes. + onStateChange(angle::SubjectMessage::SubjectChanged); + + return angle::Result::Stop; + } + + mIndexRangeCache.clear(); + mState.mUsage = BufferUsage::InvalidEnum; + mState.mSize = size; + mState.mImmutable = GL_TRUE; + mState.mStorageExtUsageFlags = flags; + mState.mExternal = GL_TRUE; + + // Notify when storage changes. + onStateChange(angle::SubjectMessage::SubjectChanged); + + return angle::Result::Continue; +} + +angle::Result Buffer::bufferSubData(const Context *context, + BufferBinding target, + const void *data, + GLsizeiptr size, + GLintptr offset) +{ + ANGLE_TRY(mImpl->setSubData(context, target, data, size, offset)); + + mIndexRangeCache.invalidateRange(static_cast(offset), + static_cast(size)); + + // Notify when data changes. + onContentsChange(); + + return angle::Result::Continue; +} + +angle::Result Buffer::copyBufferSubData(const Context *context, + Buffer *source, + GLintptr sourceOffset, + GLintptr destOffset, + GLsizeiptr size) +{ + ANGLE_TRY( + mImpl->copySubData(context, source->getImplementation(), sourceOffset, destOffset, size)); + + mIndexRangeCache.invalidateRange(static_cast(destOffset), + static_cast(size)); + + // Notify when data changes. + onContentsChange(); + + return angle::Result::Continue; +} + +angle::Result Buffer::map(const Context *context, GLenum access) +{ + ASSERT(!mState.mMapped); + + mState.mMapPointer = nullptr; + ANGLE_TRY(mImpl->map(context, access, &mState.mMapPointer)); + + ASSERT(access == GL_WRITE_ONLY_OES); + + mState.mMapped = GL_TRUE; + mState.mMapOffset = 0; + mState.mMapLength = mState.mSize; + mState.mAccess = access; + mState.mAccessFlags = GL_MAP_WRITE_BIT; + mIndexRangeCache.clear(); + + // Notify when state changes. + onStateChange(angle::SubjectMessage::SubjectMapped); + + return angle::Result::Continue; +} + +angle::Result Buffer::mapRange(const Context *context, + GLintptr offset, + GLsizeiptr length, + GLbitfield access) +{ + ASSERT(!mState.mMapped); + ASSERT(offset + length <= mState.mSize); + + mState.mMapPointer = nullptr; + ANGLE_TRY(mImpl->mapRange(context, offset, length, access, &mState.mMapPointer)); + + mState.mMapped = GL_TRUE; + mState.mMapOffset = static_cast(offset); + mState.mMapLength = static_cast(length); + mState.mAccess = GL_WRITE_ONLY_OES; + mState.mAccessFlags = access; + + // The OES_mapbuffer extension states that GL_WRITE_ONLY_OES is the only valid + // value for GL_BUFFER_ACCESS_OES because it was written against ES2. Since there is + // no update for ES3 and the GL_READ_ONLY and GL_READ_WRITE enums don't exist for ES, + // we cannot properly set GL_BUFFER_ACCESS_OES when glMapBufferRange is called. + + if ((access & GL_MAP_WRITE_BIT) > 0) + { + mIndexRangeCache.invalidateRange(static_cast(offset), + static_cast(length)); + } + + // Notify when state changes. + onStateChange(angle::SubjectMessage::SubjectMapped); + + return angle::Result::Continue; +} + +angle::Result Buffer::unmap(const Context *context, GLboolean *result) +{ + ASSERT(mState.mMapped); + + *result = GL_FALSE; + ANGLE_TRY(mImpl->unmap(context, result)); + + mState.mMapped = GL_FALSE; + mState.mMapPointer = nullptr; + mState.mMapOffset = 0; + mState.mMapLength = 0; + mState.mAccess = GL_WRITE_ONLY_OES; + mState.mAccessFlags = 0; + + // Notify when data changes. + onStateChange(angle::SubjectMessage::SubjectUnmapped); + + return angle::Result::Continue; +} + +void Buffer::onDataChanged() +{ + mIndexRangeCache.clear(); + + // Notify when data changes. + onContentsChange(); + + mImpl->onDataChanged(); +} + +angle::Result Buffer::getIndexRange(const gl::Context *context, + DrawElementsType type, + size_t offset, + size_t count, + bool primitiveRestartEnabled, + IndexRange *outRange) const +{ + if (mIndexRangeCache.findRange(type, offset, count, primitiveRestartEnabled, outRange)) + { + return angle::Result::Continue; + } + + ANGLE_TRY( + mImpl->getIndexRange(context, type, offset, count, primitiveRestartEnabled, outRange)); + + mIndexRangeCache.addRange(type, offset, count, primitiveRestartEnabled, *outRange); + + return angle::Result::Continue; +} + +GLint64 Buffer::getMemorySize() const +{ + GLint64 implSize = mImpl->getMemorySize(); + return implSize > 0 ? implSize : mState.mSize; +} + +bool Buffer::isDoubleBoundForTransformFeedback() const +{ + return mState.mTransformFeedbackIndexedBindingCount > 1; +} + +void Buffer::onTFBindingChanged(const Context *context, bool bound, bool indexed) +{ + ASSERT(bound || mState.mBindingCount > 0); + mState.mBindingCount += bound ? 1 : -1; + if (indexed) + { + ASSERT(bound || mState.mTransformFeedbackIndexedBindingCount > 0); + mState.mTransformFeedbackIndexedBindingCount += bound ? 1 : -1; + + onStateChange(angle::SubjectMessage::BindingChanged); + } + else + { + mState.mTransformFeedbackGenericBindingCount += bound ? 1 : -1; + } +} + +angle::Result Buffer::getSubData(const gl::Context *context, + GLintptr offset, + GLsizeiptr size, + void *outData) +{ + return mImpl->getSubData(context, offset, size, outData); +} + +void Buffer::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) +{ + // Pass it along! + ASSERT(index == kImplementationSubjectIndex); + ASSERT(message == angle::SubjectMessage::SubjectChanged || + message == angle::SubjectMessage::InternalMemoryAllocationChanged); + onStateChange(message); +} + +size_t Buffer::getContentsObserverIndex(VertexArray *vertexArray, uint32_t bufferIndex) const +{ + for (size_t observerIndex = 0; observerIndex < mContentsObservers.size(); ++observerIndex) + { + const ContentsObserver &observer = mContentsObservers[observerIndex]; + if (observer.vertexArray == vertexArray && observer.bufferIndex == bufferIndex) + { + return observerIndex; + } + } + + return kInvalidContentsObserverIndex; +} + +void Buffer::addContentsObserver(VertexArray *vertexArray, uint32_t bufferIndex) +{ + if (getContentsObserverIndex(vertexArray, bufferIndex) == kInvalidContentsObserverIndex) + { + mContentsObservers.push_back({vertexArray, bufferIndex}); + } +} + +void Buffer::removeContentsObserver(VertexArray *vertexArray, uint32_t bufferIndex) +{ + size_t foundObserver = getContentsObserverIndex(vertexArray, bufferIndex); + if (foundObserver != kInvalidContentsObserverIndex) + { + size_t lastObserverIndex = mContentsObservers.size() - 1; + if (foundObserver != lastObserverIndex) + { + mContentsObservers[foundObserver] = mContentsObservers[lastObserverIndex]; + } + mContentsObservers.pop_back(); + } +} + +void Buffer::onContentsChange() +{ + for (const ContentsObserver &observer : mContentsObservers) + { + observer.vertexArray->onBufferContentsChange(observer.bufferIndex); + } +} +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/Buffer.h b/gfx/angle/checkout/src/libANGLE/Buffer.h new file mode 100644 index 0000000000..b71f6af89b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Buffer.h @@ -0,0 +1,218 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Buffer.h: Defines the gl::Buffer class, representing storage of vertex and/or +// index data. Implements GL buffer objects and related functionality. +// [OpenGL ES 2.0.24] section 2.9 page 21. + +#ifndef LIBANGLE_BUFFER_H_ +#define LIBANGLE_BUFFER_H_ + +#include "common/PackedEnums.h" +#include "common/angleutils.h" +#include "libANGLE/Debug.h" +#include "libANGLE/Error.h" +#include "libANGLE/IndexRangeCache.h" +#include "libANGLE/Observer.h" +#include "libANGLE/RefCountObject.h" +#include "libANGLE/angletypes.h" + +namespace rx +{ +class BufferImpl; +class GLImplFactory; +} // namespace rx + +namespace gl +{ +class Buffer; +class Context; + +class BufferState final : angle::NonCopyable +{ + public: + BufferState(); + ~BufferState(); + + BufferUsage getUsage() const { return mUsage; } + GLbitfield getAccessFlags() const { return mAccessFlags; } + GLenum getAccess() const { return mAccess; } + GLboolean isMapped() const { return mMapped; } + void *getMapPointer() const { return mMapPointer; } + GLint64 getMapOffset() const { return mMapOffset; } + GLint64 getMapLength() const { return mMapLength; } + GLint64 getSize() const { return mSize; } + bool isBoundForTransformFeedback() const { return mTransformFeedbackIndexedBindingCount != 0; } + std::string getLabel() const { return mLabel; } + + private: + friend class Buffer; + + std::string mLabel; + + BufferUsage mUsage; + GLint64 mSize; + GLbitfield mAccessFlags; + GLenum mAccess; + GLboolean mMapped; + void *mMapPointer; + GLint64 mMapOffset; + GLint64 mMapLength; + int mBindingCount; + int mTransformFeedbackIndexedBindingCount; + int mTransformFeedbackGenericBindingCount; + GLboolean mImmutable; + GLbitfield mStorageExtUsageFlags; + GLboolean mExternal; +}; + +// Some Vertex Array Objects track buffer data updates. +struct ContentsObserver +{ + VertexArray *vertexArray = nullptr; + uint32_t bufferIndex = 0; +}; + +ANGLE_INLINE bool operator==(const ContentsObserver &lhs, const ContentsObserver &rhs) +{ + return lhs.vertexArray == rhs.vertexArray && lhs.bufferIndex == rhs.bufferIndex; +} + +class Buffer final : public RefCountObject, + public LabeledObject, + public angle::ObserverInterface, + public angle::Subject +{ + public: + Buffer(rx::GLImplFactory *factory, BufferID id); + ~Buffer() override; + void onDestroy(const Context *context) override; + + angle::Result setLabel(const Context *context, const std::string &label) override; + const std::string &getLabel() const override; + + angle::Result bufferStorageExternal(Context *context, + BufferBinding target, + GLsizeiptr size, + GLeglClientBufferEXT clientBuffer, + GLbitfield flags); + angle::Result bufferStorage(Context *context, + BufferBinding target, + GLsizeiptr size, + const void *data, + GLbitfield flags); + angle::Result bufferData(Context *context, + BufferBinding target, + const void *data, + GLsizeiptr size, + BufferUsage usage); + angle::Result bufferSubData(const Context *context, + BufferBinding target, + const void *data, + GLsizeiptr size, + GLintptr offset); + angle::Result copyBufferSubData(const Context *context, + Buffer *source, + GLintptr sourceOffset, + GLintptr destOffset, + GLsizeiptr size); + angle::Result map(const Context *context, GLenum access); + angle::Result mapRange(const Context *context, + GLintptr offset, + GLsizeiptr length, + GLbitfield access); + angle::Result unmap(const Context *context, GLboolean *result); + + // These are called when another operation changes Buffer data. + void onDataChanged(); + + angle::Result getIndexRange(const gl::Context *context, + DrawElementsType type, + size_t offset, + size_t count, + bool primitiveRestartEnabled, + IndexRange *outRange) const; + const BufferState &getState() const { return mState; } + BufferUsage getUsage() const { return mState.mUsage; } + GLbitfield getAccessFlags() const { return mState.mAccessFlags; } + GLenum getAccess() const { return mState.mAccess; } + GLboolean isMapped() const { return mState.mMapped; } + bool isPersistentlyMapped() const + { + return (mState.mStorageExtUsageFlags & GL_MAP_PERSISTENT_BIT_EXT) != 0; + } + void *getMapPointer() const { return mState.mMapPointer; } + GLint64 getMapOffset() const { return mState.mMapOffset; } + GLint64 getMapLength() const { return mState.mMapLength; } + GLint64 getSize() const { return mState.mSize; } + GLint64 getMemorySize() const; + GLboolean isImmutable() const { return mState.mImmutable; } + GLbitfield getStorageExtUsageFlags() const { return mState.mStorageExtUsageFlags; } + + // Buffers are always initialized immediately when allocated + InitState initState() const { return InitState::Initialized; } + + rx::BufferImpl *getImplementation() const { return mImpl; } + + // Note: we pass "isWebGL" to this function to clarify it's only valid if WebGL is enabled. + // We pass the boolean flag instead of the pointer because this header can't read Context.h. + ANGLE_INLINE bool hasWebGLXFBBindingConflict(bool isWebGL) const + { + if (!isWebGL) + { + return false; + } + + // The transform feedback generic binding point is not an indexed binding point but it also + // does not count as a non-transform-feedback use of the buffer, so we subtract it from the + // binding count when checking if the buffer is bound to a non-transform-feedback location. + // See https://crbug.com/853978 + return mState.mTransformFeedbackIndexedBindingCount > 0 && + mState.mTransformFeedbackIndexedBindingCount != + mState.mBindingCount - mState.mTransformFeedbackGenericBindingCount; + } + + bool isDoubleBoundForTransformFeedback() const; + void onTFBindingChanged(const Context *context, bool bound, bool indexed); + void onNonTFBindingChanged(int incr) { mState.mBindingCount += incr; } + angle::Result getSubData(const gl::Context *context, + GLintptr offset, + GLsizeiptr size, + void *outData); + + // angle::ObserverInterface implementation. + void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; + + void addContentsObserver(VertexArray *vertexArray, uint32_t bufferIndex); + void removeContentsObserver(VertexArray *vertexArray, uint32_t bufferIndex); + + private: + angle::Result bufferDataImpl(Context *context, + BufferBinding target, + const void *data, + GLsizeiptr size, + BufferUsage usage, + GLbitfield flags); + angle::Result bufferExternalDataImpl(Context *context, + BufferBinding target, + GLeglClientBufferEXT clientBuffer, + GLsizeiptr size, + GLbitfield flags); + + void onContentsChange(); + size_t getContentsObserverIndex(VertexArray *vertexArray, uint32_t bufferIndex) const; + + BufferState mState; + rx::BufferImpl *mImpl; + angle::ObserverBinding mImplObserver; + + angle::FastVector mContentsObservers; + mutable IndexRangeCache mIndexRangeCache; +}; + +} // namespace gl + +#endif // LIBANGLE_BUFFER_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Caps.cpp b/gfx/angle/checkout/src/libANGLE/Caps.cpp new file mode 100644 index 0000000000..d0b27ebbc2 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Caps.cpp @@ -0,0 +1,1371 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "libANGLE/Caps.h" + +#include "common/angleutils.h" +#include "common/debug.h" + +#include "libANGLE/formatutils.h" + +#include "angle_gl.h" + +#include +#include + +static void InsertExtensionString(const std::string &extension, + bool supported, + std::vector *extensionVector) +{ + if (supported) + { + extensionVector->push_back(extension); + } +} + +namespace gl +{ + +TextureCaps::TextureCaps() = default; + +TextureCaps::TextureCaps(const TextureCaps &other) = default; + +TextureCaps &TextureCaps::operator=(const TextureCaps &other) = default; + +TextureCaps::~TextureCaps() = default; + +GLuint TextureCaps::getMaxSamples() const +{ + return !sampleCounts.empty() ? *sampleCounts.rbegin() : 0; +} + +GLuint TextureCaps::getNearestSamples(GLuint requestedSamples) const +{ + if (requestedSamples == 0) + { + return 0; + } + + for (SupportedSampleSet::const_iterator i = sampleCounts.begin(); i != sampleCounts.end(); i++) + { + GLuint samples = *i; + if (samples >= requestedSamples) + { + return samples; + } + } + + return 0; +} + +TextureCaps GenerateMinimumTextureCaps(GLenum sizedInternalFormat, + const Version &clientVersion, + const Extensions &extensions) +{ + TextureCaps caps; + + const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(sizedInternalFormat); + caps.texturable = internalFormatInfo.textureSupport(clientVersion, extensions); + caps.filterable = internalFormatInfo.filterSupport(clientVersion, extensions); + caps.textureAttachment = internalFormatInfo.textureAttachmentSupport(clientVersion, extensions); + caps.renderbuffer = internalFormatInfo.renderbufferSupport(clientVersion, extensions); + caps.blendable = internalFormatInfo.blendSupport(clientVersion, extensions); + + caps.sampleCounts.insert(0); + if (internalFormatInfo.isRequiredRenderbufferFormat(clientVersion)) + { + if ((clientVersion.major >= 3 && clientVersion.minor >= 1) || + (clientVersion.major >= 3 && !internalFormatInfo.isInt())) + { + caps.sampleCounts.insert(4); + } + } + + return caps; +} + +TextureCapsMap::TextureCapsMap() {} + +TextureCapsMap::~TextureCapsMap() {} + +void TextureCapsMap::insert(GLenum internalFormat, const TextureCaps &caps) +{ + angle::FormatID formatID = angle::Format::InternalFormatToID(internalFormat); + get(formatID) = caps; +} + +void TextureCapsMap::clear() +{ + mFormatData.fill(TextureCaps()); +} + +const TextureCaps &TextureCapsMap::get(GLenum internalFormat) const +{ + angle::FormatID formatID = angle::Format::InternalFormatToID(internalFormat); + return get(formatID); +} + +const TextureCaps &TextureCapsMap::get(angle::FormatID formatID) const +{ + return mFormatData[formatID]; +} + +TextureCaps &TextureCapsMap::get(angle::FormatID formatID) +{ + return mFormatData[formatID]; +} + +void TextureCapsMap::set(angle::FormatID formatID, const TextureCaps &caps) +{ + get(formatID) = caps; +} + +void InitMinimumTextureCapsMap(const Version &clientVersion, + const Extensions &extensions, + TextureCapsMap *capsMap) +{ + for (GLenum internalFormat : GetAllSizedInternalFormats()) + { + capsMap->insert(internalFormat, + GenerateMinimumTextureCaps(internalFormat, clientVersion, extensions)); + } +} + +Extensions::Extensions() = default; + +Extensions::Extensions(const Extensions &other) = default; + +Extensions &Extensions::operator=(const Extensions &other) = default; + +std::vector Extensions::getStrings() const +{ + std::vector extensionStrings; + + for (const auto &extensionInfo : GetExtensionInfoMap()) + { + if (this->*(extensionInfo.second.ExtensionsMember)) + { + extensionStrings.push_back(extensionInfo.first); + } + } + + return extensionStrings; +} + +Limitations::Limitations() = default; +Limitations::Limitations(const Limitations &other) = default; + +Limitations &Limitations::operator=(const Limitations &other) = default; + +static bool GetFormatSupportBase(const TextureCapsMap &textureCaps, + const GLenum *requiredFormats, + size_t requiredFormatsSize, + bool requiresTexturing, + bool requiresFiltering, + bool requiresAttachingTexture, + bool requiresRenderbufferSupport, + bool requiresBlending) +{ + for (size_t i = 0; i < requiredFormatsSize; i++) + { + const TextureCaps &cap = textureCaps.get(requiredFormats[i]); + if (requiresTexturing && !cap.texturable) + { + return false; + } + + if (requiresFiltering && !cap.filterable) + { + return false; + } + + if (requiresAttachingTexture && !cap.textureAttachment) + { + return false; + } + + if (requiresRenderbufferSupport && !cap.renderbuffer) + { + return false; + } + + if (requiresBlending && !cap.blendable) + { + return false; + } + } + + return true; +} + +template +static bool GetFormatSupport(const TextureCapsMap &textureCaps, + const GLenum (&requiredFormats)[N], + bool requiresTexturing, + bool requiresFiltering, + bool requiresAttachingTexture, + bool requiresRenderbufferSupport, + bool requiresBlending) +{ + return GetFormatSupportBase(textureCaps, requiredFormats, N, requiresTexturing, + requiresFiltering, requiresAttachingTexture, + requiresRenderbufferSupport, requiresBlending); +} + +// Check for GL_OES_packed_depth_stencil support +static bool DeterminePackedDepthStencilSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_DEPTH24_STENCIL8, + }; + + return GetFormatSupport(textureCaps, requiredFormats, false, false, true, true, false); +} + +// Checks for GL_NV_read_depth support +static bool DetermineReadDepthSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_DEPTH_COMPONENT16, + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, false, true, false, false); +} + +// Checks for GL_NV_read_stencil support +static bool DetermineReadStencilSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_STENCIL_INDEX8, + }; + + return GetFormatSupport(textureCaps, requiredFormats, false, false, true, false, false); +} + +// Checks for GL_NV_depth_buffer_float2 support +static bool DetermineDepthBufferFloat2Support(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_DEPTH_COMPONENT32F, + GL_DEPTH32F_STENCIL8, + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, false, true, false, false); +} + +// Checks for GL_OES_rgb8_rgba8 support +static bool DetermineRGB8AndRGBA8TextureSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_RGB8, + GL_RGBA8, + }; + + return GetFormatSupport(textureCaps, requiredFormats, false, false, false, true, false); +} + +// Checks for GL_EXT_texture_format_BGRA8888 support +static bool DetermineBGRA8TextureSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_BGRA8_EXT, + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, true, true, true, false); +} + +// Checks for GL_EXT_read_format_bgra support +static bool DetermineBGRAReadFormatSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_BGRA8_EXT, + // TODO(http://anglebug.com/4302): GL_EXT_read_format_bgra specifies 2 more types, which are + // currently ignored. The equivalent formats would be: GL_BGRA4_ANGLEX, GL_BGR5_A1_ANGLEX + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, false, true, true, false); +} + +// Checks for GL_OES_color_buffer_half_float support +static bool DetermineColorBufferHalfFloatSupport(const TextureCapsMap &textureCaps) +{ + // EXT_color_buffer_half_float issue #2 states that an implementation doesn't need to support + // rendering to any of the formats but is expected to be able to render to at least one. WebGL + // requires that at least RGBA16F is renderable so we make the same requirement. + constexpr GLenum requiredFormats[] = { + GL_RGBA16F, + }; + + return GetFormatSupport(textureCaps, requiredFormats, false, false, true, true, false); +} + +// Checks for GL_OES_texture_half_float support +static bool DetermineHalfFloatTextureSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_RGBA16F, GL_RGB16F, GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE16F_EXT, GL_ALPHA16F_EXT, + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, false, false, false, false); +} + +// Checks for GL_OES_texture_half_float_linear support +static bool DetermineHalfFloatTextureFilteringSupport(const TextureCapsMap &textureCaps, + bool checkLegacyFormats) +{ + constexpr GLenum requiredFormats[] = {GL_RGBA16F, GL_RGB16F}; + // If GL_OES_texture_half_float is present, this extension must also support legacy formats + // introduced by that extension + constexpr GLenum requiredFormatsES2[] = {GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE16F_EXT, + GL_ALPHA16F_EXT}; + + if (checkLegacyFormats && + !GetFormatSupport(textureCaps, requiredFormatsES2, false, true, false, false, false)) + { + return false; + } + + return GetFormatSupport(textureCaps, requiredFormats, false, true, false, false, false); +} + +// Checks for GL_OES_texture_float support +static bool DetermineFloatTextureSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_RGBA32F, GL_RGB32F, GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE32F_EXT, GL_ALPHA32F_EXT, + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, false, false, false, false); +} + +// Checks for GL_OES_texture_float_linear support +static bool DetermineFloatTextureFilteringSupport(const TextureCapsMap &textureCaps, + bool checkLegacyFormats) +{ + constexpr GLenum requiredFormats[] = { + GL_RGBA32F, + GL_RGB32F, + }; + // If GL_OES_texture_float is present, this extension must also support legacy formats + // introduced by that extension + constexpr GLenum requiredFormatsES2[] = { + GL_LUMINANCE_ALPHA32F_EXT, + GL_LUMINANCE32F_EXT, + GL_ALPHA32F_EXT, + }; + + if (checkLegacyFormats && + !GetFormatSupport(textureCaps, requiredFormatsES2, false, true, false, false, false)) + { + return false; + } + + return GetFormatSupport(textureCaps, requiredFormats, false, true, false, false, false); +} + +// Checks for GL_EXT_texture_rg support +static bool DetermineRGTextureSupport(const TextureCapsMap &textureCaps, + bool checkHalfFloatFormats, + bool checkFloatFormats) +{ + constexpr GLenum requiredFormats[] = { + GL_R8, + GL_RG8, + }; + constexpr GLenum requiredHalfFloatFormats[] = { + GL_R16F, + GL_RG16F, + }; + constexpr GLenum requiredFloatFormats[] = { + GL_R32F, + GL_RG32F, + }; + + if (checkHalfFloatFormats && + !GetFormatSupport(textureCaps, requiredHalfFloatFormats, true, false, false, false, false)) + { + return false; + } + + if (checkFloatFormats && + !GetFormatSupport(textureCaps, requiredFloatFormats, true, false, false, false, false)) + { + return false; + } + + return GetFormatSupport(textureCaps, requiredFormats, true, true, true, true, false); +} + +static bool DetermineTextureFormat2101010Support(const TextureCapsMap &textureCaps) +{ + // GL_EXT_texture_type_2_10_10_10_REV specifies both RGBA and RGB support whereas desktop GL + // only specifies RGBA support, so check both RGBA and RGB before marking as supported. + constexpr GLenum requiredFormats[] = { + GL_RGB10_A2, + GL_RGB10_UNORM_ANGLEX, + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); +} + +// Check for GL_EXT_texture_compression_dxt1 support +static bool DetermineDXT1TextureSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_COMPRESSED_RGB_S3TC_DXT1_EXT, + GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); +} + +// Check for GL_ANGLE_texture_compression_dxt3 support +static bool DetermineDXT3TextureSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); +} + +// Check for GL_ANGLE_texture_compression_dxt5 support +static bool DetermineDXT5TextureSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); +} + +// Check for GL_EXT_texture_compression_s3tc_srgb support +static bool DetermineS3TCsRGBTextureSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, + GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, + GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, + GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); +} + +// Check for GL_KHR_texture_compression_astc_ldr support +static bool DetermineASTCLDRTextureSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_COMPRESSED_RGBA_ASTC_4x4_KHR, GL_COMPRESSED_RGBA_ASTC_5x4_KHR, + GL_COMPRESSED_RGBA_ASTC_5x5_KHR, GL_COMPRESSED_RGBA_ASTC_6x5_KHR, + GL_COMPRESSED_RGBA_ASTC_6x6_KHR, GL_COMPRESSED_RGBA_ASTC_8x5_KHR, + GL_COMPRESSED_RGBA_ASTC_8x6_KHR, GL_COMPRESSED_RGBA_ASTC_8x8_KHR, + GL_COMPRESSED_RGBA_ASTC_10x5_KHR, GL_COMPRESSED_RGBA_ASTC_10x6_KHR, + GL_COMPRESSED_RGBA_ASTC_10x8_KHR, GL_COMPRESSED_RGBA_ASTC_10x10_KHR, + GL_COMPRESSED_RGBA_ASTC_12x10_KHR, GL_COMPRESSED_RGBA_ASTC_12x12_KHR, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); +} + +// Check for GL_OES_texture_compression_astc support +static bool DetermineASTCOESTExtureSupport(const TextureCapsMap &textureCaps) +{ + if (!DetermineASTCLDRTextureSupport(textureCaps)) + { + return false; + } + + // The OES version of the extension also requires the 3D ASTC formats + constexpr GLenum requiredFormats[] = { + GL_COMPRESSED_RGBA_ASTC_3x3x3_OES, GL_COMPRESSED_RGBA_ASTC_4x3x3_OES, + GL_COMPRESSED_RGBA_ASTC_4x4x3_OES, GL_COMPRESSED_RGBA_ASTC_4x4x4_OES, + GL_COMPRESSED_RGBA_ASTC_5x4x4_OES, GL_COMPRESSED_RGBA_ASTC_5x5x4_OES, + GL_COMPRESSED_RGBA_ASTC_5x5x5_OES, GL_COMPRESSED_RGBA_ASTC_6x5x5_OES, + GL_COMPRESSED_RGBA_ASTC_6x6x5_OES, GL_COMPRESSED_RGBA_ASTC_6x6x6_OES, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES, + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); +} + +// Check for GL_ETC1_RGB8_OES support +static bool DetermineETC1RGB8TextureSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_ETC1_RGB8_OES, + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); +} + +// Check for OES_compressed_ETC2_RGB8_texture support +static bool DetermineETC2RGB8TextureSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_COMPRESSED_RGB8_ETC2, + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); +} + +// Check for OES_compressed_ETC2_sRGB8_texture support +static bool DetermineETC2sRGB8TextureSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_COMPRESSED_SRGB8_ETC2, + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); +} + +// Check for OES_compressed_ETC2_punchthroughA_RGBA8_texture support +static bool DetermineETC2PunchthroughARGB8TextureSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); +} + +// Check for OES_compressed_ETC2_punchthroughA_sRGB8_alpha_texture support +static bool DetermineETC2PunchthroughAsRGB8AlphaTextureSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); +} + +// Check for OES_compressed_ETC2_RGBA8_texture support +static bool DetermineETC2RGBA8TextureSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_COMPRESSED_RGBA8_ETC2_EAC, + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); +} + +// Check for OES_compressed_ETC2_sRGB8_alpha8_texture support +static bool DetermineETC2sRGB8Alpha8TextureSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); +} + +// Check for OES_compressed_EAC_R11_unsigned_texture support +static bool DetermineEACR11UnsignedTextureSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_COMPRESSED_R11_EAC, + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); +} + +// Check for OES_compressed_EAC_R11_signed_texture support +static bool DetermineEACR11SignedTextureSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_COMPRESSED_SIGNED_R11_EAC, + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); +} + +// Check for OES_compressed_EAC_RG11_unsigned_texture support +static bool DetermineEACRG11UnsignedTextureSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_COMPRESSED_RG11_EAC, + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); +} + +// Check for OES_compressed_EAC_RG11_signed_texture support +static bool DetermineEACRG11SignedTextureSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_COMPRESSED_SIGNED_RG11_EAC, + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); +} + +// Check for GL_EXT_sRGB support +static bool DetermineSRGBTextureSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFilterFormats[] = { + GL_SRGB8, + GL_SRGB8_ALPHA8, + }; + + constexpr GLenum requiredRenderFormats[] = { + GL_SRGB8_ALPHA8, + }; + + return GetFormatSupport(textureCaps, requiredFilterFormats, true, true, false, false, false) && + GetFormatSupport(textureCaps, requiredRenderFormats, true, false, true, true, false); +} + +// Check for GL_EXT_texture_sRGB_R8 support +static bool DetermineSRGBR8TextureSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFilterFormats[] = {GL_SR8_EXT}; + + return GetFormatSupport(textureCaps, requiredFilterFormats, true, true, false, false, false); +} + +// Check for GL_EXT_texture_sRGB_RG8 support +static bool DetermineSRGBRG8TextureSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFilterFormats[] = {GL_SRG8_EXT}; + + return GetFormatSupport(textureCaps, requiredFilterFormats, true, true, false, false, false); +} + +// Check for GL_ANGLE_depth_texture support +static bool DetermineDepthTextureANGLESupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_DEPTH_COMPONENT16, +#if !defined(ANGLE_PLATFORM_IOS) && \ + (!defined(ANGLE_PLATFORM_MACCATALYST) || !defined(ANGLE_CPU_ARM64)) + // anglebug.com/6082 + // TODO(dino): Temporarily Removing the need for GL_DEPTH_COMPONENT32_OES + // because it is not supported on iOS. + // TODO(dino): I think this needs to be a runtime check when running an iOS app on Mac. + GL_DEPTH_COMPONENT32_OES, +#endif + GL_DEPTH24_STENCIL8_OES, + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, false, true, false, false); +} + +// Check for GL_OES_depth_texture support +static bool DetermineDepthTextureOESSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_DEPTH_COMPONENT16, +#if !defined(ANGLE_PLATFORM_IOS) && \ + (!defined(ANGLE_PLATFORM_MACCATALYST) || !defined(ANGLE_CPU_ARM64)) + // anglebug.com/6082 + // TODO(dino): Temporarily Removing the need for GL_DEPTH_COMPONENT32_OES + // because it is not supported on iOS. + // TODO(dino): I think this needs to be a runtime check when running an iOS app on Mac. + GL_DEPTH_COMPONENT32_OES, +#endif + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, false, true, true, false); +} + +// Check for GL_OES_depth24 +static bool DetermineDepth24OESSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_DEPTH_COMPONENT24_OES, + }; + + return GetFormatSupport(textureCaps, requiredFormats, false, false, false, true, false); +} + +// Check for GL_OES_depth32 support +static bool DetermineDepth32Support(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_DEPTH_COMPONENT32_OES, + }; + + return GetFormatSupport(textureCaps, requiredFormats, false, false, true, true, false); +} + +// Check for GL_CHROMIUM_color_buffer_float_rgb support +static bool DetermineColorBufferFloatRGBSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_RGB32F, + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, false, true, false, false); +} + +// Check for GL_CHROMIUM_color_buffer_float_rgba support +static bool DetermineColorBufferFloatRGBASupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_RGBA32F, + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, false, true, true, false); +} + +// Check for GL_EXT_color_buffer_float support +static bool DetermineColorBufferFloatSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum nonBlendableFormats[] = { + GL_R32F, + GL_RG32F, + GL_RGBA32F, + }; + + constexpr GLenum blendableFormats[] = { + GL_R16F, + GL_RG16F, + GL_RGBA16F, + GL_R11F_G11F_B10F, + }; + + return GetFormatSupport(textureCaps, nonBlendableFormats, true, false, true, true, false) && + GetFormatSupport(textureCaps, blendableFormats, true, false, true, true, true); +} + +// Check for GL_EXT_float_blend support +static bool DetermineFloatBlendSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_R32F, + GL_RG32F, + GL_RGBA32F, + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, false, true, true, true); +} + +// Check for GL_EXT_texture_norm16 support +static bool DetermineTextureNorm16Support(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFilterFormats[] = { + GL_R16_EXT, GL_RG16_EXT, GL_RGB16_EXT, GL_RGBA16_EXT, + GL_R16_SNORM_EXT, GL_RG16_SNORM_EXT, GL_RGB16_SNORM_EXT, GL_RGBA16_SNORM_EXT, + }; + + constexpr GLenum requiredRenderFormats[] = { + GL_R16_EXT, + GL_RG16_EXT, + GL_RGBA16_EXT, + }; + + return GetFormatSupport(textureCaps, requiredFilterFormats, true, true, false, false, false) && + GetFormatSupport(textureCaps, requiredRenderFormats, true, false, true, true, false); +} + +// Check for EXT_texture_compression_rgtc support +static bool DetermineRGTCTextureSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_COMPRESSED_RED_RGTC1_EXT, GL_COMPRESSED_SIGNED_RED_RGTC1_EXT, + GL_COMPRESSED_RED_GREEN_RGTC2_EXT, GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT}; + + return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); +} + +// Check for EXT_texture_compression_bptc support +static bool DetermineBPTCTextureSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT, + GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT}; + + return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); +} + +// Check for GL_IMG_texture_compression_pvrtc support +static bool DeterminePVRTCTextureSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG, + GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}; + + return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); +} + +// Check for GL_EXT_pvrtc_sRGB support +static bool DeterminePVRTCsRGBTextureSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT, GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT, + GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT, GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT}; + + return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); +} + +bool DetermineCompressedTextureETCSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = {GL_COMPRESSED_R11_EAC, + GL_COMPRESSED_SIGNED_R11_EAC, + GL_COMPRESSED_RG11_EAC, + GL_COMPRESSED_SIGNED_RG11_EAC, + GL_COMPRESSED_RGB8_ETC2, + GL_COMPRESSED_SRGB8_ETC2, + GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, + GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, + GL_COMPRESSED_RGBA8_ETC2_EAC, + GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC}; + + return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); +} + +// Checks for GL_OES_texture_stencil8 support +static bool DetermineStencilIndex8Support(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_STENCIL_INDEX8, + }; + + return GetFormatSupport(textureCaps, requiredFormats, false, false, true, false, false); +} + +void Extensions::setTextureExtensionSupport(const TextureCapsMap &textureCaps) +{ + // TODO(ynovikov): rgb8Rgba8OES, colorBufferHalfFloatEXT, textureHalfFloatOES, + // textureHalfFloatLinearOES, textureFloatOES, textureFloatLinearOES, textureRgEXT, sRGB, + // colorBufferFloatRgbCHROMIUM, colorBufferFloatRgbaCHROMIUM and colorBufferFloatEXT were + // verified. Verify the rest. + packedDepthStencilOES = DeterminePackedDepthStencilSupport(textureCaps); + rgb8Rgba8OES = DetermineRGB8AndRGBA8TextureSupport(textureCaps); + readDepthNV = DetermineReadDepthSupport(textureCaps); + readStencilNV = DetermineReadStencilSupport(textureCaps); + depthBufferFloat2NV = DetermineDepthBufferFloat2Support(textureCaps); + textureFormatBGRA8888EXT = DetermineBGRA8TextureSupport(textureCaps); + readFormatBgraEXT = DetermineBGRAReadFormatSupport(textureCaps); + textureHalfFloatOES = DetermineHalfFloatTextureSupport(textureCaps); + textureHalfFloatLinearOES = + DetermineHalfFloatTextureFilteringSupport(textureCaps, textureHalfFloatOES); + textureFloatOES = DetermineFloatTextureSupport(textureCaps); + textureFloatLinearOES = DetermineFloatTextureFilteringSupport(textureCaps, textureFloatOES); + textureRgEXT = DetermineRGTextureSupport(textureCaps, textureHalfFloatOES, textureFloatOES); + colorBufferHalfFloatEXT = + textureHalfFloatOES && DetermineColorBufferHalfFloatSupport(textureCaps); + textureType2101010REVEXT = DetermineTextureFormat2101010Support(textureCaps); + textureCompressionDxt1EXT = DetermineDXT1TextureSupport(textureCaps); + textureCompressionDxt3ANGLE = DetermineDXT3TextureSupport(textureCaps); + textureCompressionDxt5ANGLE = DetermineDXT5TextureSupport(textureCaps); + textureCompressionS3tcSrgbEXT = DetermineS3TCsRGBTextureSupport(textureCaps); + textureCompressionAstcLdrKHR = DetermineASTCLDRTextureSupport(textureCaps); + textureCompressionAstcOES = DetermineASTCOESTExtureSupport(textureCaps); + compressedETC1RGB8TextureOES = DetermineETC1RGB8TextureSupport(textureCaps); + compressedETC2RGB8TextureOES = DetermineETC2RGB8TextureSupport(textureCaps); + compressedETC2SRGB8TextureOES = DetermineETC2sRGB8TextureSupport(textureCaps); + compressedETC2PunchthroughARGBA8TextureOES = + DetermineETC2PunchthroughARGB8TextureSupport(textureCaps); + compressedETC2PunchthroughASRGB8AlphaTextureOES = + DetermineETC2PunchthroughAsRGB8AlphaTextureSupport(textureCaps); + compressedETC2RGBA8TextureOES = DetermineETC2RGBA8TextureSupport(textureCaps); + compressedETC2SRGB8Alpha8TextureOES = DetermineETC2sRGB8Alpha8TextureSupport(textureCaps); + compressedEACR11UnsignedTextureOES = DetermineEACR11UnsignedTextureSupport(textureCaps); + compressedEACR11SignedTextureOES = DetermineEACR11SignedTextureSupport(textureCaps); + compressedEACRG11UnsignedTextureOES = DetermineEACRG11UnsignedTextureSupport(textureCaps); + compressedEACRG11SignedTextureOES = DetermineEACRG11SignedTextureSupport(textureCaps); + sRGBEXT = DetermineSRGBTextureSupport(textureCaps); + textureSRGBR8EXT = DetermineSRGBR8TextureSupport(textureCaps); + textureSRGBRG8EXT = DetermineSRGBRG8TextureSupport(textureCaps); + depthTextureANGLE = DetermineDepthTextureANGLESupport(textureCaps); + depthTextureOES = DetermineDepthTextureOESSupport(textureCaps); + depth24OES = DetermineDepth24OESSupport(textureCaps); + depth32OES = DetermineDepth32Support(textureCaps); + colorBufferFloatRgbCHROMIUM = DetermineColorBufferFloatRGBSupport(textureCaps); + colorBufferFloatRgbaCHROMIUM = DetermineColorBufferFloatRGBASupport(textureCaps); + colorBufferFloatEXT = DetermineColorBufferFloatSupport(textureCaps); + floatBlendEXT = DetermineFloatBlendSupport(textureCaps); + textureNorm16EXT = DetermineTextureNorm16Support(textureCaps); + textureCompressionRgtcEXT = DetermineRGTCTextureSupport(textureCaps); + textureCompressionBptcEXT = DetermineBPTCTextureSupport(textureCaps); + textureCompressionPvrtcIMG = DeterminePVRTCTextureSupport(textureCaps); + pvrtcSRGBEXT = DeterminePVRTCsRGBTextureSupport(textureCaps); + textureStencil8OES = DetermineStencilIndex8Support(textureCaps); +} + +TypePrecision::TypePrecision() = default; + +TypePrecision::TypePrecision(const TypePrecision &other) = default; + +TypePrecision &TypePrecision::operator=(const TypePrecision &other) = default; + +void TypePrecision::setIEEEFloat() +{ + range = {{127, 127}}; + precision = 23; +} + +void TypePrecision::setIEEEHalfFloat() +{ + range = {{15, 15}}; + precision = 10; +} + +void TypePrecision::setTwosComplementInt(unsigned int bits) +{ + range = {{static_cast(bits) - 1, static_cast(bits) - 2}}; + precision = 0; +} + +void TypePrecision::setSimulatedFloat(unsigned int r, unsigned int p) +{ + range = {{static_cast(r), static_cast(r)}}; + precision = static_cast(p); +} + +void TypePrecision::setSimulatedInt(unsigned int r) +{ + range = {{static_cast(r), static_cast(r)}}; + precision = 0; +} + +void TypePrecision::get(GLint *returnRange, GLint *returnPrecision) const +{ + std::copy(range.begin(), range.end(), returnRange); + *returnPrecision = precision; +} + +Caps::Caps() = default; +Caps::Caps(const Caps &other) = default; +Caps::~Caps() = default; +Caps &Caps::operator=(const Caps &other) = default; + +Caps GenerateMinimumCaps(const Version &clientVersion, const Extensions &extensions) +{ + Caps caps; + + // GLES1 emulation (Minimums taken from Table 6.20 / 6.22 (ES 1.1 spec)) + if (clientVersion < Version(2, 0)) + { + caps.maxMultitextureUnits = 2; + caps.maxLights = 8; + caps.maxClipPlanes = 1; + + caps.maxModelviewMatrixStackDepth = 16; + caps.maxProjectionMatrixStackDepth = 2; + caps.maxTextureMatrixStackDepth = 2; + + caps.minSmoothPointSize = 1.0f; + caps.maxSmoothPointSize = 1.0f; + } + + if (clientVersion >= Version(2, 0)) + { + // Table 6.18 + caps.max2DTextureSize = 64; + caps.maxCubeMapTextureSize = 16; + caps.maxViewportWidth = caps.max2DTextureSize; + caps.maxViewportHeight = caps.max2DTextureSize; + caps.minAliasedPointSize = 1; + caps.maxAliasedPointSize = 1; + caps.minAliasedLineWidth = 1; + caps.maxAliasedLineWidth = 1; + + // Table 6.19 + caps.vertexHighpFloat.setSimulatedFloat(62, 16); + caps.vertexMediumpFloat.setSimulatedFloat(14, 10); + caps.vertexLowpFloat.setSimulatedFloat(1, 8); + caps.vertexHighpInt.setSimulatedInt(16); + caps.vertexMediumpInt.setSimulatedInt(10); + caps.vertexLowpInt.setSimulatedInt(8); + caps.fragmentHighpFloat.setSimulatedFloat(62, 16); + caps.fragmentMediumpFloat.setSimulatedFloat(14, 10); + caps.fragmentLowpFloat.setSimulatedFloat(1, 8); + caps.fragmentHighpInt.setSimulatedInt(16); + caps.fragmentMediumpInt.setSimulatedInt(10); + caps.fragmentLowpInt.setSimulatedInt(8); + + // Table 6.20 + caps.maxVertexAttributes = 8; + caps.maxVertexUniformVectors = 128; + caps.maxVaryingVectors = 8; + caps.maxCombinedTextureImageUnits = 8; + caps.maxShaderTextureImageUnits[ShaderType::Fragment] = 8; + caps.maxFragmentUniformVectors = 16; + caps.maxRenderbufferSize = 1; + + // Table 3.35 + caps.maxSamples = 4; + } + + if (clientVersion >= Version(3, 0)) + { + // Table 6.28 + caps.maxElementIndex = (1 << 24) - 1; + caps.max3DTextureSize = 256; + caps.max2DTextureSize = 2048; + caps.maxArrayTextureLayers = 256; + caps.maxLODBias = 2.0f; + caps.maxCubeMapTextureSize = 2048; + caps.maxRenderbufferSize = 2048; + caps.maxDrawBuffers = 4; + caps.maxColorAttachments = 4; + caps.maxViewportWidth = caps.max2DTextureSize; + caps.maxViewportHeight = caps.max2DTextureSize; + + // Table 6.29 + caps.compressedTextureFormats.push_back(GL_COMPRESSED_R11_EAC); + caps.compressedTextureFormats.push_back(GL_COMPRESSED_SIGNED_R11_EAC); + caps.compressedTextureFormats.push_back(GL_COMPRESSED_RG11_EAC); + caps.compressedTextureFormats.push_back(GL_COMPRESSED_SIGNED_RG11_EAC); + caps.compressedTextureFormats.push_back(GL_COMPRESSED_RGB8_ETC2); + caps.compressedTextureFormats.push_back(GL_COMPRESSED_SRGB8_ETC2); + caps.compressedTextureFormats.push_back(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2); + caps.compressedTextureFormats.push_back(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2); + caps.compressedTextureFormats.push_back(GL_COMPRESSED_RGBA8_ETC2_EAC); + caps.compressedTextureFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC); + caps.vertexHighpFloat.setIEEEFloat(); + caps.vertexHighpInt.setTwosComplementInt(32); + caps.vertexMediumpInt.setTwosComplementInt(16); + caps.vertexLowpInt.setTwosComplementInt(8); + caps.fragmentHighpFloat.setIEEEFloat(); + caps.fragmentHighpInt.setSimulatedInt(32); + caps.fragmentMediumpInt.setTwosComplementInt(16); + caps.fragmentLowpInt.setTwosComplementInt(8); + caps.maxServerWaitTimeout = 0; + + // Table 6.31 + caps.maxVertexAttributes = 16; + caps.maxShaderUniformComponents[ShaderType::Vertex] = 1024; + caps.maxVertexUniformVectors = 256; + caps.maxShaderUniformBlocks[ShaderType::Vertex] = limits::kMinimumShaderUniformBlocks; + caps.maxVertexOutputComponents = limits::kMinimumVertexOutputComponents; + caps.maxShaderTextureImageUnits[ShaderType::Vertex] = 16; + + // Table 6.32 + caps.maxShaderUniformComponents[ShaderType::Fragment] = 896; + caps.maxFragmentUniformVectors = 224; + caps.maxShaderUniformBlocks[ShaderType::Fragment] = limits::kMinimumShaderUniformBlocks; + caps.maxFragmentInputComponents = 60; + caps.maxShaderTextureImageUnits[ShaderType::Fragment] = 16; + caps.minProgramTexelOffset = -8; + caps.maxProgramTexelOffset = 7; + + // Table 6.33 + caps.maxUniformBufferBindings = 24; + caps.maxUniformBlockSize = 16384; + caps.uniformBufferOffsetAlignment = 256; + caps.maxCombinedUniformBlocks = 24; + caps.maxVaryingComponents = 60; + caps.maxVaryingVectors = 15; + caps.maxCombinedTextureImageUnits = 32; + + // Table 6.34 + caps.maxTransformFeedbackInterleavedComponents = 64; + caps.maxTransformFeedbackSeparateAttributes = 4; + caps.maxTransformFeedbackSeparateComponents = 4; + } + + if (clientVersion >= Version(3, 1)) + { + // Table 20.40 + caps.maxFramebufferWidth = 2048; + caps.maxFramebufferHeight = 2048; + caps.maxFramebufferSamples = 4; + caps.maxSampleMaskWords = 1; + caps.maxColorTextureSamples = 1; + caps.maxDepthTextureSamples = 1; + caps.maxIntegerSamples = 1; + + // Table 20.41 + caps.maxVertexAttribRelativeOffset = 2047; + caps.maxVertexAttribBindings = 16; + caps.maxVertexAttribStride = 2048; + + // Table 20.43 + caps.maxShaderAtomicCounterBuffers[ShaderType::Vertex] = 0; + caps.maxShaderAtomicCounters[ShaderType::Vertex] = 0; + caps.maxShaderImageUniforms[ShaderType::Vertex] = 0; + caps.maxShaderStorageBlocks[ShaderType::Vertex] = 0; + + // Table 20.44 + caps.maxShaderUniformComponents[ShaderType::Fragment] = 1024; + caps.maxFragmentUniformVectors = 256; + caps.maxShaderAtomicCounterBuffers[ShaderType::Fragment] = 0; + caps.maxShaderAtomicCounters[ShaderType::Fragment] = 0; + caps.maxShaderImageUniforms[ShaderType::Fragment] = 0; + caps.maxShaderStorageBlocks[ShaderType::Fragment] = 0; + caps.minProgramTextureGatherOffset = 0; + caps.maxProgramTextureGatherOffset = 0; + + // Table 20.45 + caps.maxComputeWorkGroupCount = {{65535, 65535, 65535}}; + caps.maxComputeWorkGroupSize = {{128, 128, 64}}; + caps.maxComputeWorkGroupInvocations = 12; + caps.maxShaderUniformBlocks[ShaderType::Compute] = limits::kMinimumShaderUniformBlocks; + caps.maxShaderTextureImageUnits[ShaderType::Compute] = 16; + caps.maxComputeSharedMemorySize = 16384; + caps.maxShaderUniformComponents[ShaderType::Compute] = 1024; + caps.maxShaderAtomicCounterBuffers[ShaderType::Compute] = 1; + caps.maxShaderAtomicCounters[ShaderType::Compute] = 8; + caps.maxShaderImageUniforms[ShaderType::Compute] = 4; + caps.maxShaderStorageBlocks[ShaderType::Compute] = 4; + + // Table 20.46 + caps.maxUniformBufferBindings = 36; + caps.maxCombinedTextureImageUnits = 48; + caps.maxCombinedShaderOutputResources = 4; + + // Table 20.47 + caps.maxUniformLocations = 1024; + caps.maxAtomicCounterBufferBindings = 1; + caps.maxAtomicCounterBufferSize = 32; + caps.maxCombinedAtomicCounterBuffers = 1; + caps.maxCombinedAtomicCounters = 8; + caps.maxImageUnits = 4; + caps.maxCombinedImageUniforms = 4; + caps.maxShaderStorageBufferBindings = 4; + caps.maxShaderStorageBlockSize = 1 << 27; + caps.maxCombinedShaderStorageBlocks = 4; + caps.shaderStorageBufferOffsetAlignment = 256; + } + + if (extensions.textureRectangleANGLE) + { + caps.maxRectangleTextureSize = 64; + } + + if (extensions.geometryShaderAny()) + { + // Table 20.40 (GL_EXT_geometry_shader) + caps.maxFramebufferLayers = 256; + caps.layerProvokingVertex = GL_LAST_VERTEX_CONVENTION_EXT; + + // Table 20.43gs (GL_EXT_geometry_shader) + caps.maxShaderUniformComponents[ShaderType::Geometry] = 1024; + caps.maxShaderUniformBlocks[ShaderType::Geometry] = limits::kMinimumShaderUniformBlocks; + caps.maxGeometryInputComponents = 64; + caps.maxGeometryOutputComponents = 64; + caps.maxGeometryOutputVertices = 256; + caps.maxGeometryTotalOutputComponents = 1024; + caps.maxShaderTextureImageUnits[ShaderType::Geometry] = 16; + caps.maxShaderAtomicCounterBuffers[ShaderType::Geometry] = 0; + caps.maxShaderAtomicCounters[ShaderType::Geometry] = 0; + caps.maxShaderStorageBlocks[ShaderType::Geometry] = 0; + caps.maxGeometryShaderInvocations = 32; + + // Table 20.46 (GL_EXT_geometry_shader) + caps.maxShaderImageUniforms[ShaderType::Geometry] = 0; + + // Table 20.46 (GL_EXT_geometry_shader) + caps.maxUniformBufferBindings = 48; + caps.maxCombinedUniformBlocks = 36; + caps.maxCombinedTextureImageUnits = 64; + } + + if (extensions.tessellationShaderEXT) + { + // Table 20.43 "Implementation Dependent Tessellation Shader Limits" + caps.maxTessControlInputComponents = 64; + caps.maxTessControlOutputComponents = 64; + caps.maxShaderTextureImageUnits[ShaderType::TessControl] = 16; + caps.maxShaderUniformComponents[ShaderType::TessControl] = 1024; + caps.maxTessControlTotalOutputComponents = 2048; + caps.maxShaderImageUniforms[ShaderType::TessControl] = 0; + caps.maxShaderAtomicCounters[ShaderType::TessControl] = 0; + caps.maxShaderAtomicCounterBuffers[ShaderType::TessControl] = 0; + + caps.maxTessPatchComponents = 120; + caps.maxPatchVertices = 32; + caps.maxTessGenLevel = 64; + + caps.maxTessEvaluationInputComponents = 64; + caps.maxTessEvaluationOutputComponents = 64; + caps.maxShaderTextureImageUnits[ShaderType::TessEvaluation] = 16; + caps.maxShaderUniformComponents[ShaderType::TessEvaluation] = 1024; + caps.maxShaderImageUniforms[ShaderType::TessEvaluation] = 0; + caps.maxShaderAtomicCounters[ShaderType::TessEvaluation] = 0; + caps.maxShaderAtomicCounterBuffers[ShaderType::TessEvaluation] = 0; + + // Table 20.46 "Implementation Dependent Aggregate Shader Limits" + caps.maxUniformBufferBindings = 72; + caps.maxCombinedUniformBlocks = 60; + caps.maxCombinedTextureImageUnits = 96; + } + + for (ShaderType shaderType : AllShaderTypes()) + { + caps.maxCombinedShaderUniformComponents[shaderType] = + caps.maxShaderUniformBlocks[shaderType] * + static_cast(caps.maxUniformBlockSize / 4) + + caps.maxShaderUniformComponents[shaderType]; + } + + return caps; +} +} // namespace gl + +namespace egl +{ + +Caps::Caps() = default; + +DisplayExtensions::DisplayExtensions() = default; + +std::vector DisplayExtensions::getStrings() const +{ + std::vector extensionStrings; + + // clang-format off + // | Extension name | Supported flag | Output vector | + InsertExtensionString("EGL_EXT_create_context_robustness", createContextRobustness, &extensionStrings); + InsertExtensionString("EGL_ANGLE_d3d_share_handle_client_buffer", d3dShareHandleClientBuffer, &extensionStrings); + InsertExtensionString("EGL_ANGLE_d3d_texture_client_buffer", d3dTextureClientBuffer, &extensionStrings); + InsertExtensionString("EGL_ANGLE_surface_d3d_texture_2d_share_handle", surfaceD3DTexture2DShareHandle, &extensionStrings); + InsertExtensionString("EGL_ANGLE_query_surface_pointer", querySurfacePointer, &extensionStrings); + InsertExtensionString("EGL_ANGLE_window_fixed_size", windowFixedSize, &extensionStrings); + InsertExtensionString("EGL_ANGLE_keyed_mutex", keyedMutex, &extensionStrings); + InsertExtensionString("EGL_ANGLE_surface_orientation", surfaceOrientation, &extensionStrings); + InsertExtensionString("EGL_ANGLE_direct_composition", directComposition, &extensionStrings); + InsertExtensionString("EGL_ANGLE_windows_ui_composition", windowsUIComposition, &extensionStrings); + InsertExtensionString("EGL_NV_post_sub_buffer", postSubBuffer, &extensionStrings); + InsertExtensionString("EGL_KHR_create_context", createContext, &extensionStrings); + InsertExtensionString("EGL_KHR_image", image, &extensionStrings); + InsertExtensionString("EGL_KHR_image_base", imageBase, &extensionStrings); + InsertExtensionString("EGL_KHR_image_pixmap", imagePixmap, &extensionStrings); + InsertExtensionString("EGL_EXT_image_gl_colorspace", imageGlColorspace, &extensionStrings); + InsertExtensionString("EGL_KHR_gl_colorspace", glColorspace, &extensionStrings); + InsertExtensionString("EGL_EXT_gl_colorspace_scrgb", glColorspaceScrgb, &extensionStrings); + InsertExtensionString("EGL_EXT_gl_colorspace_scrgb_linear", glColorspaceScrgbLinear, &extensionStrings); + InsertExtensionString("EGL_EXT_gl_colorspace_display_p3", glColorspaceDisplayP3, &extensionStrings); + InsertExtensionString("EGL_EXT_gl_colorspace_display_p3_linear", glColorspaceDisplayP3Linear, &extensionStrings); + InsertExtensionString("EGL_EXT_gl_colorspace_display_p3_passthrough", glColorspaceDisplayP3Passthrough, &extensionStrings); + InsertExtensionString("EGL_ANGLE_colorspace_attribute_passthrough", eglColorspaceAttributePassthroughANGLE, &extensionStrings); + InsertExtensionString("EGL_KHR_gl_texture_2D_image", glTexture2DImage, &extensionStrings); + InsertExtensionString("EGL_KHR_gl_texture_cubemap_image", glTextureCubemapImage, &extensionStrings); + InsertExtensionString("EGL_KHR_gl_texture_3D_image", glTexture3DImage, &extensionStrings); + InsertExtensionString("EGL_KHR_gl_renderbuffer_image", glRenderbufferImage, &extensionStrings); + InsertExtensionString("EGL_KHR_get_all_proc_addresses", getAllProcAddresses, &extensionStrings); + InsertExtensionString("EGL_KHR_stream", stream, &extensionStrings); + InsertExtensionString("EGL_KHR_stream_consumer_gltexture", streamConsumerGLTexture, &extensionStrings); + InsertExtensionString("EGL_NV_stream_consumer_gltexture_yuv", streamConsumerGLTextureYUV, &extensionStrings); + InsertExtensionString("EGL_KHR_fence_sync", fenceSync, &extensionStrings); + InsertExtensionString("EGL_KHR_wait_sync", waitSync, &extensionStrings); + InsertExtensionString("EGL_ANGLE_stream_producer_d3d_texture", streamProducerD3DTexture, &extensionStrings); + InsertExtensionString("EGL_ANGLE_create_context_webgl_compatibility", createContextWebGLCompatibility, &extensionStrings); + InsertExtensionString("EGL_CHROMIUM_create_context_bind_generates_resource", createContextBindGeneratesResource, &extensionStrings); + InsertExtensionString("EGL_CHROMIUM_sync_control", syncControlCHROMIUM, &extensionStrings); + InsertExtensionString("EGL_ANGLE_sync_control_rate", syncControlRateANGLE, &extensionStrings); + InsertExtensionString("EGL_KHR_swap_buffers_with_damage", swapBuffersWithDamage, &extensionStrings); + InsertExtensionString("EGL_EXT_pixel_format_float", pixelFormatFloat, &extensionStrings); + InsertExtensionString("EGL_KHR_surfaceless_context", surfacelessContext, &extensionStrings); + InsertExtensionString("EGL_ANGLE_display_texture_share_group", displayTextureShareGroup, &extensionStrings); + InsertExtensionString("EGL_ANGLE_display_semaphore_share_group", displaySemaphoreShareGroup, &extensionStrings); + InsertExtensionString("EGL_ANGLE_create_context_client_arrays", createContextClientArrays, &extensionStrings); + InsertExtensionString("EGL_ANGLE_program_cache_control", programCacheControlANGLE, &extensionStrings); + InsertExtensionString("EGL_ANGLE_robust_resource_initialization", robustResourceInitializationANGLE, &extensionStrings); + InsertExtensionString("EGL_ANGLE_iosurface_client_buffer", iosurfaceClientBuffer, &extensionStrings); + InsertExtensionString("EGL_ANGLE_metal_texture_client_buffer", mtlTextureClientBuffer, &extensionStrings); + InsertExtensionString("EGL_ANGLE_create_context_extensions_enabled", createContextExtensionsEnabled, &extensionStrings); + InsertExtensionString("EGL_ANDROID_presentation_time", presentationTime, &extensionStrings); + InsertExtensionString("EGL_ANDROID_blob_cache", blobCache, &extensionStrings); + InsertExtensionString("EGL_ANDROID_framebuffer_target", framebufferTargetANDROID, &extensionStrings); + InsertExtensionString("EGL_ANDROID_image_native_buffer", imageNativeBuffer, &extensionStrings); + InsertExtensionString("EGL_ANDROID_get_frame_timestamps", getFrameTimestamps, &extensionStrings); + InsertExtensionString("EGL_ANGLE_timestamp_surface_attribute", timestampSurfaceAttributeANGLE, &extensionStrings); + InsertExtensionString("EGL_ANDROID_recordable", recordable, &extensionStrings); + InsertExtensionString("EGL_ANGLE_power_preference", powerPreference, &extensionStrings); + InsertExtensionString("EGL_ANGLE_image_d3d11_texture", imageD3D11Texture, &extensionStrings); + InsertExtensionString("EGL_ANDROID_create_native_client_buffer", createNativeClientBufferANDROID, &extensionStrings); + InsertExtensionString("EGL_ANDROID_get_native_client_buffer", getNativeClientBufferANDROID, &extensionStrings); + InsertExtensionString("EGL_ANDROID_native_fence_sync", nativeFenceSyncANDROID, &extensionStrings); + InsertExtensionString("EGL_ANGLE_create_context_backwards_compatible", createContextBackwardsCompatible, &extensionStrings); + InsertExtensionString("EGL_KHR_no_config_context", noConfigContext, &extensionStrings); + InsertExtensionString("EGL_IMG_context_priority", contextPriority, &extensionStrings); + InsertExtensionString("EGL_KHR_create_context_no_error", createContextNoError, &extensionStrings); + InsertExtensionString("EGL_EXT_image_dma_buf_import", imageDmaBufImportEXT, &extensionStrings); + InsertExtensionString("EGL_EXT_image_dma_buf_import_modifiers", imageDmaBufImportModifiersEXT, &extensionStrings); + InsertExtensionString("EGL_NOK_texture_from_pixmap", textureFromPixmapNOK, &extensionStrings); + InsertExtensionString("EGL_NV_robustness_video_memory_purge", robustnessVideoMemoryPurgeNV, &extensionStrings); + InsertExtensionString("EGL_KHR_reusable_sync", reusableSyncKHR, &extensionStrings); + InsertExtensionString("EGL_ANGLE_external_context_and_surface", externalContextAndSurface, &extensionStrings); + InsertExtensionString("EGL_EXT_buffer_age", bufferAgeEXT, &extensionStrings); + InsertExtensionString("EGL_KHR_mutable_render_buffer", mutableRenderBufferKHR, &extensionStrings); + InsertExtensionString("EGL_EXT_protected_content", protectedContentEXT, &extensionStrings); + InsertExtensionString("EGL_ANGLE_create_surface_swap_interval", createSurfaceSwapIntervalANGLE, &extensionStrings); + InsertExtensionString("EGL_ANGLE_context_virtualization", contextVirtualizationANGLE, &extensionStrings); + InsertExtensionString("EGL_KHR_lock_surface3", lockSurface3KHR, &extensionStrings); + InsertExtensionString("EGL_ANGLE_vulkan_image", vulkanImageANGLE, &extensionStrings); + InsertExtensionString("EGL_ANGLE_metal_create_context_ownership_identity", metalCreateContextOwnershipIdentityANGLE, &extensionStrings); + InsertExtensionString("EGL_KHR_partial_update", partialUpdateKHR, &extensionStrings); + InsertExtensionString("EGL_ANGLE_metal_shared_event_sync", mtlSyncSharedEventANGLE, &extensionStrings); + // clang-format on + + return extensionStrings; +} + +DeviceExtensions::DeviceExtensions() = default; + +std::vector DeviceExtensions::getStrings() const +{ + std::vector extensionStrings; + + // clang-format off + // | Extension name | Supported flag | Output vector | + InsertExtensionString("EGL_ANGLE_device_d3d", deviceD3D, &extensionStrings); + InsertExtensionString("EGL_ANGLE_device_cgl", deviceCGL, &extensionStrings); + InsertExtensionString("EGL_ANGLE_device_eagl", deviceEAGL, &extensionStrings); + InsertExtensionString("EGL_ANGLE_device_metal", deviceMetal, &extensionStrings); + InsertExtensionString("EGL_ANGLE_device_vulkan", deviceVulkan, &extensionStrings); + + // clang-format on + + return extensionStrings; +} + +ClientExtensions::ClientExtensions() = default; +ClientExtensions::ClientExtensions(const ClientExtensions &other) = default; + +std::vector ClientExtensions::getStrings() const +{ + std::vector extensionStrings; + + // clang-format off + // | Extension name | Supported flag | Output vector | + InsertExtensionString("EGL_EXT_client_extensions", clientExtensions, &extensionStrings); + InsertExtensionString("EGL_EXT_device_query", deviceQueryEXT, &extensionStrings); + InsertExtensionString("EGL_EXT_platform_base", platformBase, &extensionStrings); + InsertExtensionString("EGL_EXT_platform_device", platformDevice, &extensionStrings); + InsertExtensionString("EGL_KHR_platform_gbm", platformGbmKHR, &extensionStrings); + InsertExtensionString("EGL_EXT_platform_wayland", platformWaylandEXT, &extensionStrings); + InsertExtensionString("EGL_ANGLE_platform_angle", platformANGLE, &extensionStrings); + InsertExtensionString("EGL_ANGLE_platform_angle_d3d", platformANGLED3D, &extensionStrings); + InsertExtensionString("EGL_ANGLE_platform_angle_d3d11on12", platformANGLED3D11ON12, &extensionStrings); + InsertExtensionString("EGL_ANGLE_platform_angle_device_type_egl_angle", platformANGLEDeviceTypeEGLANGLE, &extensionStrings); + InsertExtensionString("EGL_ANGLE_platform_angle_device_type_swiftshader", platformANGLEDeviceTypeSwiftShader, &extensionStrings); + InsertExtensionString("EGL_ANGLE_platform_angle_opengl", platformANGLEOpenGL, &extensionStrings); + InsertExtensionString("EGL_ANGLE_platform_angle_null", platformANGLENULL, &extensionStrings); + InsertExtensionString("EGL_ANGLE_platform_angle_vulkan", platformANGLEVulkan, &extensionStrings); + InsertExtensionString("EGL_ANGLE_platform_angle_metal", platformANGLEMetal, &extensionStrings); + InsertExtensionString("EGL_ANGLE_platform_device_context_volatile_eagl", platformANGLEDeviceContextVolatileEagl, &extensionStrings); + InsertExtensionString("EGL_ANGLE_platform_device_context_volatile_cgl", platformANGLEDeviceContextVolatileCgl, &extensionStrings); + InsertExtensionString("EGL_ANGLE_platform_angle_device_id", platformANGLEDeviceId, &extensionStrings); + InsertExtensionString("EGL_ANGLE_device_creation", deviceCreation, &extensionStrings); + InsertExtensionString("EGL_ANGLE_device_creation_d3d11", deviceCreationD3D11, &extensionStrings); + InsertExtensionString("EGL_ANGLE_x11_visual", x11Visual, &extensionStrings); + InsertExtensionString("EGL_ANGLE_experimental_present_path", experimentalPresentPath, &extensionStrings); + InsertExtensionString("EGL_KHR_client_get_all_proc_addresses", clientGetAllProcAddresses, &extensionStrings); + InsertExtensionString("EGL_KHR_debug", debug, &extensionStrings); + InsertExtensionString("EGL_ANGLE_feature_control", featureControlANGLE, &extensionStrings); + InsertExtensionString("EGL_ANGLE_display_power_preference", displayPowerPreferenceANGLE, &extensionStrings); + // clang-format on + + return extensionStrings; +} + +} // namespace egl diff --git a/gfx/angle/checkout/src/libANGLE/Caps.h b/gfx/angle/checkout/src/libANGLE/Caps.h new file mode 100644 index 0000000000..03b4ef8c9a --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Caps.h @@ -0,0 +1,786 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef LIBANGLE_CAPS_H_ +#define LIBANGLE_CAPS_H_ + +#include "angle_gl.h" +#include "libANGLE/Version.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/gles_extensions_autogen.h" +#include "libANGLE/renderer/Format.h" + +#include +#include +#include +#include +#include + +namespace gl +{ +struct TextureCaps +{ + TextureCaps(); + TextureCaps(const TextureCaps &other); + TextureCaps &operator=(const TextureCaps &other); + + ~TextureCaps(); + + // Supports for basic texturing: glTexImage, glTexSubImage, etc + bool texturable = false; + + // Support for linear or anisotropic filtering + bool filterable = false; + + // Support for being used as a framebuffer attachment, i.e. glFramebufferTexture2D + bool textureAttachment = false; + + // Support for being used as a renderbuffer format, i.e. glFramebufferRenderbuffer + bool renderbuffer = false; + + // Support for blend modes while being used as a framebuffer attachment + bool blendable = false; + + // Set of supported sample counts, only guaranteed to be valid in ES3. + SupportedSampleSet sampleCounts; + + // Get the maximum number of samples supported + GLuint getMaxSamples() const; + + // Get the number of supported samples that is at least as many as requested. Returns 0 if + // there are no sample counts available + GLuint getNearestSamples(GLuint requestedSamples) const; +}; + +TextureCaps GenerateMinimumTextureCaps(GLenum internalFormat, + const Version &clientVersion, + const Extensions &extensions); + +class TextureCapsMap final : angle::NonCopyable +{ + public: + TextureCapsMap(); + ~TextureCapsMap(); + + // These methods are deprecated. Please use angle::Format for new features. + void insert(GLenum internalFormat, const TextureCaps &caps); + const TextureCaps &get(GLenum internalFormat) const; + + void clear(); + + // Prefer using angle::Format methods. + const TextureCaps &get(angle::FormatID formatID) const; + void set(angle::FormatID formatID, const TextureCaps &caps); + + private: + TextureCaps &get(angle::FormatID formatID); + + // Indexed by angle::FormatID + angle::FormatMap mFormatData; +}; + +void InitMinimumTextureCapsMap(const Version &clientVersion, + const Extensions &extensions, + TextureCapsMap *capsMap); + +// Returns true if all the formats required to support GL_ANGLE_compressed_texture_etc are +// present. Does not determine if they are natively supported without decompression. +bool DetermineCompressedTextureETCSupport(const TextureCapsMap &textureCaps); + +// Pointer to a boolean member of the Extensions struct +using ExtensionBool = bool Extensions::*; + +struct ExtensionInfo +{ + // If this extension can be enabled or disabled with glRequestExtension + // (GL_ANGLE_request_extension) + bool Requestable = false; + bool Disablable = false; + + // Pointer to a boolean member of the Extensions struct + ExtensionBool ExtensionsMember = nullptr; +}; + +using ExtensionInfoMap = std::map; +const ExtensionInfoMap &GetExtensionInfoMap(); + +struct Limitations +{ + Limitations(); + Limitations(const Limitations &other); + + Limitations &operator=(const Limitations &other); + + // Renderer doesn't support gl_FrontFacing in fragment shaders + bool noFrontFacingSupport = false; + + // Renderer doesn't support GL_SAMPLE_ALPHA_TO_COVERAGE + bool noSampleAlphaToCoverageSupport = false; + + // In glVertexAttribDivisorANGLE, attribute zero must have a zero divisor + bool attributeZeroRequiresZeroDivisorInEXT = false; + + // Unable to support different values for front and back faces for stencil refs and masks + bool noSeparateStencilRefsAndMasks = false; + + // Renderer doesn't support non-constant indexing loops in fragment shader + bool shadersRequireIndexedLoopValidation = false; + + // Renderer doesn't support Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA + // and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR blend functions. + bool noSimultaneousConstantColorAndAlphaBlendFunc = false; + + // Renderer always clamps constant blend color. + bool noUnclampedBlendColor = false; + + // D3D9 does not support flexible varying register packing. + bool noFlexibleVaryingPacking = false; + + // D3D does not support having multiple transform feedback outputs go to the same buffer. + bool noDoubleBoundTransformFeedbackBuffers = false; + + // D3D does not support vertex attribute aliasing + bool noVertexAttributeAliasing = false; + + // Renderer doesn't support GL_TEXTURE_COMPARE_MODE=GL_NONE on a shadow sampler. + // TODO(http://anglebug.com/5231): add validation code to front-end. + bool noShadowSamplerCompareModeNone = false; + + // PVRTC1 textures must be squares. + bool squarePvrtc1 = false; + + // ETC1 texture support is emulated. + bool emulatedEtc1 = false; + + // ASTC texture support is emulated. + bool emulatedAstc = false; + + // No compressed TEXTURE_3D support. + bool noCompressedTexture3D = false; + + // D3D does not support compressed textures where the base mip level is not a multiple of 4 + bool compressedBaseMipLevelMultipleOfFour = false; + + bool limitWebglMaxTextureSizeTo4096 = false; +}; + +struct TypePrecision +{ + TypePrecision(); + TypePrecision(const TypePrecision &other); + + TypePrecision &operator=(const TypePrecision &other); + + void setIEEEFloat(); + void setIEEEHalfFloat(); + void setTwosComplementInt(unsigned int bits); + void setSimulatedFloat(unsigned int range, unsigned int precision); + void setSimulatedInt(unsigned int range); + + void get(GLint *returnRange, GLint *returnPrecision) const; + + std::array range = {0, 0}; + GLint precision = 0; +}; + +struct Caps +{ + Caps(); + Caps(const Caps &other); + Caps &operator=(const Caps &other); + + ~Caps(); + + // If the values could be got by using GetIntegeri_v, they should + // be GLint instead of GLuint and call LimitToInt() to ensure + // they will not overflow. + + GLfloat minInterpolationOffset = 0; + GLfloat maxInterpolationOffset = 0; + GLint subPixelInterpolationOffsetBits = 0; + + // ES 3.1 (April 29, 2015) 20.39: implementation dependent values + GLint64 maxElementIndex = 0; + GLint max3DTextureSize = 0; + GLint max2DTextureSize = 0; + GLint maxRectangleTextureSize = 0; + GLint maxArrayTextureLayers = 0; + GLfloat maxLODBias = 0.0f; + GLint maxCubeMapTextureSize = 0; + GLint maxRenderbufferSize = 0; + GLfloat minAliasedPointSize = 1.0f; + GLfloat maxAliasedPointSize = 1.0f; + GLfloat minAliasedLineWidth = 0.0f; + GLfloat maxAliasedLineWidth = 0.0f; + + // ES 3.1 (April 29, 2015) 20.40: implementation dependent values (cont.) + GLint maxDrawBuffers = 0; + GLint maxFramebufferWidth = 0; + GLint maxFramebufferHeight = 0; + GLint maxFramebufferSamples = 0; + GLint maxColorAttachments = 0; + GLint maxViewportWidth = 0; + GLint maxViewportHeight = 0; + GLint maxSampleMaskWords = 0; + GLint maxColorTextureSamples = 0; + GLint maxDepthTextureSamples = 0; + GLint maxIntegerSamples = 0; + GLint64 maxServerWaitTimeout = 0; + + // ES 3.1 (April 29, 2015) Table 20.41: Implementation dependent values (cont.) + GLint maxVertexAttribRelativeOffset = 0; + GLint maxVertexAttribBindings = 0; + GLint maxVertexAttribStride = 0; + GLint maxElementsIndices = 0; + GLint maxElementsVertices = 0; + std::vector compressedTextureFormats; + std::vector programBinaryFormats; + std::vector shaderBinaryFormats; + TypePrecision vertexHighpFloat; + TypePrecision vertexMediumpFloat; + TypePrecision vertexLowpFloat; + TypePrecision vertexHighpInt; + TypePrecision vertexMediumpInt; + TypePrecision vertexLowpInt; + TypePrecision fragmentHighpFloat; + TypePrecision fragmentMediumpFloat; + TypePrecision fragmentLowpFloat; + TypePrecision fragmentHighpInt; + TypePrecision fragmentMediumpInt; + TypePrecision fragmentLowpInt; + + // Implementation dependent limits required on all shader types. + // TODO(jiawei.shao@intel.com): organize all such limits into ShaderMap. + // ES 3.1 (April 29, 2015) Table 20.43: Implementation dependent Vertex shader limits + // ES 3.1 (April 29, 2015) Table 20.44: Implementation dependent Fragment shader limits + // ES 3.1 (April 29, 2015) Table 20.45: implementation dependent compute shader limits + // GL_EXT_geometry_shader (May 31, 2016) Table 20.43gs: Implementation dependent geometry shader + // limits + // GL_EXT_geometry_shader (May 31, 2016) Table 20.46: Implementation dependent aggregate shader + // limits + ShaderMap maxShaderUniformBlocks = {}; + ShaderMap maxShaderTextureImageUnits = {}; + ShaderMap maxShaderStorageBlocks = {}; + ShaderMap maxShaderUniformComponents = {}; + ShaderMap maxShaderAtomicCounterBuffers = {}; + ShaderMap maxShaderAtomicCounters = {}; + ShaderMap maxShaderImageUniforms = {}; + // Note that we can query MAX_COMPUTE_UNIFORM_COMPONENTS and MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT + // by GetIntegerv, but we can only use GetInteger64v on MAX_VERTEX_UNIFORM_COMPONENTS and + // MAX_FRAGMENT_UNIFORM_COMPONENTS. Currently we use GLuint64 to store all these values so that + // we can put them together into one ShaderMap. + ShaderMap maxCombinedShaderUniformComponents = {}; + + // ES 3.1 (April 29, 2015) Table 20.43: Implementation dependent Vertex shader limits + GLint maxVertexAttributes = 0; + GLint maxVertexUniformVectors = 0; + GLint maxVertexOutputComponents = 0; + + // ES 3.1 (April 29, 2015) Table 20.44: Implementation dependent Fragment shader limits + GLint maxFragmentUniformVectors = 0; + GLint maxFragmentInputComponents = 0; + GLint minProgramTextureGatherOffset = 0; + GLint maxProgramTextureGatherOffset = 0; + GLint minProgramTexelOffset = 0; + GLint maxProgramTexelOffset = 0; + + // ES 3.1 (April 29, 2015) Table 20.45: implementation dependent compute shader limits + std::array maxComputeWorkGroupCount = {0, 0, 0}; + std::array maxComputeWorkGroupSize = {0, 0, 0}; + GLint maxComputeWorkGroupInvocations = 0; + GLint maxComputeSharedMemorySize = 0; + + // ES 3.1 (April 29, 2015) Table 20.46: implementation dependent aggregate shader limits + GLint maxUniformBufferBindings = 0; + GLint64 maxUniformBlockSize = 0; + GLint uniformBufferOffsetAlignment = 0; + GLint maxCombinedUniformBlocks = 0; + GLint maxVaryingComponents = 0; + GLint maxVaryingVectors = 0; + GLint maxCombinedTextureImageUnits = 0; + GLint maxCombinedShaderOutputResources = 0; + + // ES 3.1 (April 29, 2015) Table 20.47: implementation dependent aggregate shader limits (cont.) + GLint maxUniformLocations = 0; + GLint maxAtomicCounterBufferBindings = 0; + GLint maxAtomicCounterBufferSize = 0; + GLint maxCombinedAtomicCounterBuffers = 0; + GLint maxCombinedAtomicCounters = 0; + GLint maxImageUnits = 0; + GLint maxCombinedImageUniforms = 0; + GLint maxShaderStorageBufferBindings = 0; + GLint64 maxShaderStorageBlockSize = 0; + GLint maxCombinedShaderStorageBlocks = 0; + GLint shaderStorageBufferOffsetAlignment = 0; + + // ES 3.1 (April 29, 2015) Table 20.48: implementation dependent transform feedback limits + GLint maxTransformFeedbackInterleavedComponents = 0; + GLint maxTransformFeedbackSeparateAttributes = 0; + GLint maxTransformFeedbackSeparateComponents = 0; + + // ES 3.1 (April 29, 2015) Table 20.49: Framebuffer Dependent Values + GLint maxSamples = 0; + + // GL_EXT_geometry_shader (May 31, 2016) Table 20.40: Implementation-Dependent Values (cont.) + GLint maxFramebufferLayers = 0; + GLint layerProvokingVertex = 0; + + // GL_EXT_geometry_shader (May 31, 2016) Table 20.43gs: Implementation dependent geometry shader + // limits + GLint maxGeometryInputComponents = 0; + GLint maxGeometryOutputComponents = 0; + GLint maxGeometryOutputVertices = 0; + GLint maxGeometryTotalOutputComponents = 0; + GLint maxGeometryShaderInvocations = 0; + + // GL_EXT_tessellation_shader + GLint maxTessControlInputComponents = 0; + GLint maxTessControlOutputComponents = 0; + GLint maxTessControlTotalOutputComponents = 0; + + GLint maxTessPatchComponents = 0; + GLint maxPatchVertices = 0; + GLint maxTessGenLevel = 0; + + GLint maxTessEvaluationInputComponents = 0; + GLint maxTessEvaluationOutputComponents = 0; + + GLuint subPixelBits = 4; + + // GL_EXT_blend_func_extended + GLuint maxDualSourceDrawBuffers = 0; + + // GL_EXT_texture_filter_anisotropic + GLfloat maxTextureAnisotropy = 0.0f; + + // GL_EXT_disjoint_timer_query + GLuint queryCounterBitsTimeElapsed = 0; + GLuint queryCounterBitsTimestamp = 0; + + // OVR_multiview + GLuint maxViews = 1; + + // GL_KHR_debug + GLuint maxDebugMessageLength = 0; + GLuint maxDebugLoggedMessages = 0; + GLuint maxDebugGroupStackDepth = 0; + GLuint maxLabelLength = 0; + + // GL_APPLE_clip_distance/GL_EXT_clip_cull_distance + GLuint maxClipDistances = 0; + GLuint maxCullDistances = 0; + GLuint maxCombinedClipAndCullDistances = 0; + + // GL_ANGLE_shader_pixel_local_storage + GLuint maxPixelLocalStoragePlanes = 0; + GLuint maxColorAttachmentsWithActivePixelLocalStorage = 0; + GLuint maxCombinedDrawBuffersAndPixelLocalStoragePlanes = 0; + + // GLES1 emulation: Caps for ES 1.1. Taken from Table 6.20 / 6.22 in the OpenGL ES 1.1 spec. + GLuint maxMultitextureUnits = 0; + GLuint maxClipPlanes = 0; + GLuint maxLights = 0; + static constexpr int GlobalMatrixStackDepth = 16; + GLuint maxModelviewMatrixStackDepth = 0; + GLuint maxProjectionMatrixStackDepth = 0; + GLuint maxTextureMatrixStackDepth = 0; + GLfloat minSmoothPointSize = 0.0f; + GLfloat maxSmoothPointSize = 0.0f; + GLfloat minSmoothLineWidth = 0.0f; + GLfloat maxSmoothLineWidth = 0.0f; + + // ES 3.2 Table 20.41: Implementation Dependent Values (cont.) + GLint maxTextureBufferSize = 0; + GLint textureBufferOffsetAlignment = 0; +}; + +Caps GenerateMinimumCaps(const Version &clientVersion, const Extensions &extensions); +} // namespace gl + +namespace egl +{ + +struct Caps +{ + Caps(); + + // Support for NPOT surfaces + bool textureNPOT; + + // Support for Stencil8 configs + bool stencil8; +}; + +struct DisplayExtensions +{ + DisplayExtensions(); + + // Generate a vector of supported extension strings + std::vector getStrings() const; + + // EGL_EXT_create_context_robustness + bool createContextRobustness = false; + + // EGL_ANGLE_d3d_share_handle_client_buffer + bool d3dShareHandleClientBuffer = false; + + // EGL_ANGLE_d3d_texture_client_buffer + bool d3dTextureClientBuffer = false; + + // EGL_ANGLE_surface_d3d_texture_2d_share_handle + bool surfaceD3DTexture2DShareHandle = false; + + // EGL_ANGLE_query_surface_pointer + bool querySurfacePointer = false; + + // EGL_ANGLE_window_fixed_size + bool windowFixedSize = false; + + // EGL_ANGLE_keyed_mutex + bool keyedMutex = false; + + // EGL_ANGLE_surface_orientation + bool surfaceOrientation = false; + + // EGL_NV_post_sub_buffer + bool postSubBuffer = false; + + // EGL_KHR_create_context + bool createContext = false; + + // EGL_KHR_image + bool image = false; + + // EGL_KHR_image_base + bool imageBase = false; + + // EGL_KHR_image_pixmap + bool imagePixmap = false; + + // EGL_KHR_gl_texture_2D_image + bool glTexture2DImage = false; + + // EGL_KHR_gl_texture_cubemap_image + bool glTextureCubemapImage = false; + + // EGL_KHR_gl_texture_3D_image + bool glTexture3DImage = false; + + // EGL_KHR_gl_renderbuffer_image + bool glRenderbufferImage = false; + + // EGL_KHR_get_all_proc_addresses + bool getAllProcAddresses = false; + + // EGL_ANGLE_direct_composition + bool directComposition = false; + + // EGL_ANGLE_windows_ui_composition + bool windowsUIComposition = false; + + // KHR_create_context_no_error + bool createContextNoError = false; + + // EGL_KHR_stream + bool stream = false; + + // EGL_KHR_stream_consumer_gltexture + bool streamConsumerGLTexture = false; + + // EGL_NV_stream_consumer_gltexture_yuv + bool streamConsumerGLTextureYUV = false; + + // EGL_ANGLE_stream_producer_d3d_texture + bool streamProducerD3DTexture = false; + + // EGL_KHR_fence_sync + bool fenceSync = false; + + // EGL_KHR_wait_sync + bool waitSync = false; + + // EGL_ANGLE_create_context_webgl_compatibility + bool createContextWebGLCompatibility = false; + + // EGL_CHROMIUM_create_context_bind_generates_resource + bool createContextBindGeneratesResource = false; + + // EGL_CHROMIUM_sync_control + bool syncControlCHROMIUM = false; + + // EGL_ANGLE_sync_control_rate + bool syncControlRateANGLE = false; + + // EGL_KHR_swap_buffers_with_damage + bool swapBuffersWithDamage = false; + + // EGL_EXT_pixel_format_float + bool pixelFormatFloat = false; + + // EGL_KHR_surfaceless_context + bool surfacelessContext = false; + + // EGL_ANGLE_display_texture_share_group + bool displayTextureShareGroup = false; + + // EGL_ANGLE_display_semaphore_share_group + bool displaySemaphoreShareGroup = false; + + // EGL_ANGLE_create_context_client_arrays + bool createContextClientArrays = false; + + // EGL_ANGLE_program_cache_control + bool programCacheControlANGLE = false; + + // EGL_ANGLE_robust_resource_initialization + bool robustResourceInitializationANGLE = false; + + // EGL_ANGLE_iosurface_client_buffer + bool iosurfaceClientBuffer = false; + + // EGL_ANGLE_metal_texture_client_buffer + bool mtlTextureClientBuffer = false; + + // EGL_ANGLE_create_context_extensions_enabled + bool createContextExtensionsEnabled = false; + + // EGL_ANDROID_presentation_time + bool presentationTime = false; + + // EGL_ANDROID_blob_cache + bool blobCache = false; + + // EGL_ANDROID_image_native_buffer + bool imageNativeBuffer = false; + + // EGL_ANDROID_get_frame_timestamps + bool getFrameTimestamps = false; + + // EGL_ANGLE_timestamp_surface_attribute + bool timestampSurfaceAttributeANGLE = false; + + // EGL_ANDROID_recordable + bool recordable = false; + + // EGL_ANGLE_power_preference + bool powerPreference = false; + + // EGL_ANGLE_image_d3d11_texture + bool imageD3D11Texture = false; + + // EGL_ANDROID_get_native_client_buffer + bool getNativeClientBufferANDROID = false; + + // EGL_ANDROID_create_native_client_buffer + bool createNativeClientBufferANDROID = false; + + // EGL_ANDROID_native_fence_sync + bool nativeFenceSyncANDROID = false; + + // EGL_ANGLE_create_context_backwards_compatible + bool createContextBackwardsCompatible = false; + + // EGL_KHR_no_config_context + bool noConfigContext = false; + + // EGL_IMG_context_priority + bool contextPriority = false; + + // EGL_ANGLE_ggp_stream_descriptor + bool ggpStreamDescriptor = false; + + // EGL_ANGLE_swap_with_frame_token + bool swapWithFrameToken = false; + + // EGL_KHR_gl_colorspace + bool glColorspace = false; + + // EGL_EXT_gl_colorspace_display_p3_linear + bool glColorspaceDisplayP3Linear = false; + + // EGL_EXT_gl_colorspace_display_p3 + bool glColorspaceDisplayP3 = false; + + // EGL_EXT_gl_colorspace_scrgb + bool glColorspaceScrgb = false; + + // EGL_EXT_gl_colorspace_scrgb_linear + bool glColorspaceScrgbLinear = false; + + // EGL_EXT_gl_colorspace_display_p3_passthrough + bool glColorspaceDisplayP3Passthrough = false; + + // EGL_ANGLE_colorspace_attribute_passthrough + bool eglColorspaceAttributePassthroughANGLE = false; + + // EGL_ANDROID_framebuffer_target + bool framebufferTargetANDROID = false; + + // EGL_EXT_image_gl_colorspace + bool imageGlColorspace = false; + + // EGL_EXT_image_dma_buf_import + bool imageDmaBufImportEXT = false; + + // EGL_EXT_image_dma_buf_import_modifiers + bool imageDmaBufImportModifiersEXT = false; + + // EGL_NOK_texture_from_pixmap + bool textureFromPixmapNOK = false; + + // EGL_NV_robustness_video_memory_purge + bool robustnessVideoMemoryPurgeNV = false; + + // EGL_KHR_reusable_sync + bool reusableSyncKHR = false; + + // EGL_ANGLE_external_context_and_surface + bool externalContextAndSurface = false; + + // EGL_EXT_buffer_age + bool bufferAgeEXT = false; + + // EGL_KHR_mutable_render_buffer + bool mutableRenderBufferKHR = false; + + // EGL_EXT_protected_content + bool protectedContentEXT = false; + + // EGL_ANGLE_create_surface_swap_interval + bool createSurfaceSwapIntervalANGLE = false; + + // EGL_ANGLE_context_virtualization + bool contextVirtualizationANGLE = false; + + // EGL_KHR_lock_surface3 + bool lockSurface3KHR = false; + + // EGL_ANGLE_vulkan_image + bool vulkanImageANGLE = false; + + // EGL_ANGLE_metal_create_context_ownership_identity + bool metalCreateContextOwnershipIdentityANGLE = false; + + // EGL_KHR_partial_update + bool partialUpdateKHR = false; + + // EGL_ANGLE_sync_mtl_shared_event + bool mtlSyncSharedEventANGLE = false; +}; + +struct DeviceExtensions +{ + DeviceExtensions(); + + // Generate a vector of supported extension strings + std::vector getStrings() const; + + // EGL_ANGLE_device_d3d + bool deviceD3D = false; + + // EGL_ANGLE_device_cgl + bool deviceCGL = false; + + // EGL_ANGLE_device_eagl + bool deviceEAGL = false; + + // EGL_ANGLE_device_metal + bool deviceMetal = false; + + // EGL_ANGLE_device_vulkan + bool deviceVulkan = false; +}; + +struct ClientExtensions +{ + ClientExtensions(); + ClientExtensions(const ClientExtensions &other); + + // Generate a vector of supported extension strings + std::vector getStrings() const; + + // EGL_EXT_client_extensions + bool clientExtensions = false; + + // EGL_EXT_platform_base + bool platformBase = false; + + // EGL_EXT_platform_device + bool platformDevice = false; + + // EGL_KHR_platform_gbm + bool platformGbmKHR = false; + + // EGL_EXT_platform_wayland + bool platformWaylandEXT = false; + + // EGL_ANGLE_platform_angle + bool platformANGLE = false; + + // EGL_ANGLE_platform_angle_d3d + bool platformANGLED3D = false; + + // EGL_ANGLE_platform_angle_d3d11on12 + bool platformANGLED3D11ON12 = false; + + // EGL_ANGLE_platform_angle_opengl + bool platformANGLEOpenGL = false; + + // EGL_ANGLE_platform_angle_null + bool platformANGLENULL = false; + + // EGL_ANGLE_platform_angle_vulkan + bool platformANGLEVulkan = false; + + // EGL_ANGLE_platform_angle_metal + bool platformANGLEMetal = false; + + // EGL_ANGLE_platform_angle_device_context_volatile_eagl + bool platformANGLEDeviceContextVolatileEagl = false; + + // EGL_ANGLE_platform_angle_device_context_volatile_cgl + bool platformANGLEDeviceContextVolatileCgl = false; + + // EGL_ANGLE_platform_angle_device_id + bool platformANGLEDeviceId = false; + + // EGL_ANGLE_device_creation + bool deviceCreation = false; + + // EGL_ANGLE_device_creation_d3d11 + bool deviceCreationD3D11 = false; + + // EGL_ANGLE_x11_visual + bool x11Visual = false; + + // EGL_ANGLE_experimental_present_path + bool experimentalPresentPath = false; + + // EGL_KHR_client_get_all_proc_addresses + bool clientGetAllProcAddresses = false; + + // EGL_KHR_debug + bool debug = false; + + // EGL_ANGLE_feature_control + bool featureControlANGLE = false; + + // EGL_ANGLE_platform_angle_device_type_swiftshader + bool platformANGLEDeviceTypeSwiftShader = false; + + // EGL_ANGLE_platform_angle_device_type_egl_angle + bool platformANGLEDeviceTypeEGLANGLE = false; + + // EGL_EXT_device_query + bool deviceQueryEXT = false; + + // EGL_ANGLE_display_power_preference + bool displayPowerPreferenceANGLE = false; +}; + +} // namespace egl + +#endif // LIBANGLE_CAPS_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Compiler.cpp b/gfx/angle/checkout/src/libANGLE/Compiler.cpp new file mode 100644 index 0000000000..a838f27ed6 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Compiler.cpp @@ -0,0 +1,422 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Compiler.cpp: implements the gl::Compiler class. + +#include "libANGLE/Compiler.h" + +#include "common/debug.h" +#include "libANGLE/Context.h" +#include "libANGLE/Display.h" +#include "libANGLE/State.h" +#include "libANGLE/renderer/CompilerImpl.h" +#include "libANGLE/renderer/GLImplFactory.h" + +namespace gl +{ + +namespace +{ + +// To know when to call sh::Initialize and sh::Finalize. +size_t gActiveCompilers = 0; + +} // anonymous namespace + +Compiler::Compiler(rx::GLImplFactory *implFactory, const State &state, egl::Display *display) + : mImplementation(implFactory->createCompiler()), + mSpec(SelectShaderSpec(state)), + mOutputType(mImplementation->getTranslatorOutputType()), + mResources() +{ + // TODO(http://anglebug.com/3819): Update for GL version specific validation + ASSERT(state.getClientMajorVersion() == 1 || state.getClientMajorVersion() == 2 || + state.getClientMajorVersion() == 3 || state.getClientMajorVersion() == 4); + + { + std::lock_guard lock(display->getDisplayGlobalMutex()); + if (gActiveCompilers == 0) + { + sh::Initialize(); + } + ++gActiveCompilers; + } + + const Caps &caps = state.getCaps(); + const Extensions &extensions = state.getExtensions(); + + sh::InitBuiltInResources(&mResources); + mResources.MaxVertexAttribs = caps.maxVertexAttributes; + mResources.MaxVertexUniformVectors = caps.maxVertexUniformVectors; + mResources.MaxVaryingVectors = caps.maxVaryingVectors; + mResources.MaxVertexTextureImageUnits = caps.maxShaderTextureImageUnits[ShaderType::Vertex]; + mResources.MaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits; + mResources.MaxTextureImageUnits = caps.maxShaderTextureImageUnits[ShaderType::Fragment]; + mResources.MaxFragmentUniformVectors = caps.maxFragmentUniformVectors; + mResources.MaxDrawBuffers = caps.maxDrawBuffers; + mResources.OES_standard_derivatives = extensions.standardDerivativesOES; + mResources.EXT_draw_buffers = extensions.drawBuffersEXT; + mResources.EXT_shader_texture_lod = extensions.shaderTextureLodEXT; + mResources.EXT_shader_non_constant_global_initializers = + extensions.shaderNonConstantGlobalInitializersEXT; + mResources.OES_EGL_image_external = extensions.EGLImageExternalOES; + mResources.OES_EGL_image_external_essl3 = extensions.EGLImageExternalEssl3OES; + mResources.NV_EGL_stream_consumer_external = extensions.EGLStreamConsumerExternalNV; + mResources.NV_shader_noperspective_interpolation = + extensions.shaderNoperspectiveInterpolationNV; + mResources.ARB_texture_rectangle = extensions.textureRectangleANGLE; + mResources.EXT_gpu_shader5 = extensions.gpuShader5EXT; + mResources.OES_shader_io_blocks = extensions.shaderIoBlocksOES; + mResources.EXT_shader_io_blocks = extensions.shaderIoBlocksEXT; + mResources.OES_texture_storage_multisample_2d_array = + extensions.textureStorageMultisample2dArrayOES; + mResources.OES_texture_3D = extensions.texture3DOES; + mResources.ANGLE_base_vertex_base_instance_shader_builtin = + extensions.baseVertexBaseInstanceShaderBuiltinANGLE; + mResources.ANGLE_multi_draw = extensions.multiDrawANGLE; + mResources.ANGLE_shader_pixel_local_storage = extensions.shaderPixelLocalStorageANGLE; + mResources.ANGLE_texture_multisample = extensions.textureMultisampleANGLE; + mResources.APPLE_clip_distance = extensions.clipDistanceAPPLE; + // OES_shader_multisample_interpolation + mResources.OES_shader_multisample_interpolation = extensions.shaderMultisampleInterpolationOES; + mResources.OES_shader_image_atomic = extensions.shaderImageAtomicOES; + // TODO: use shader precision caps to determine if high precision is supported? + mResources.FragmentPrecisionHigh = 1; + mResources.EXT_frag_depth = extensions.fragDepthEXT; + + // OVR_multiview state + mResources.OVR_multiview = extensions.multiviewOVR; + + // OVR_multiview2 state + mResources.OVR_multiview2 = extensions.multiview2OVR; + mResources.MaxViewsOVR = caps.maxViews; + + // EXT_multisampled_render_to_texture and EXT_multisampled_render_to_texture2 + mResources.EXT_multisampled_render_to_texture = extensions.multisampledRenderToTextureEXT; + mResources.EXT_multisampled_render_to_texture2 = extensions.multisampledRenderToTexture2EXT; + + // WEBGL_video_texture + mResources.WEBGL_video_texture = extensions.videoTextureWEBGL; + + // OES_texture_cube_map_array + mResources.OES_texture_cube_map_array = extensions.textureCubeMapArrayOES; + mResources.EXT_texture_cube_map_array = extensions.textureCubeMapArrayEXT; + + // EXT_shadow_samplers + mResources.EXT_shadow_samplers = extensions.shadowSamplersEXT; + + // OES_texture_buffer + mResources.OES_texture_buffer = extensions.textureBufferOES; + mResources.EXT_texture_buffer = extensions.textureBufferEXT; + + // GL_EXT_YUV_target + mResources.EXT_YUV_target = extensions.YUVTargetEXT; + + mResources.EXT_shader_framebuffer_fetch_non_coherent = + extensions.shaderFramebufferFetchNonCoherentEXT; + + mResources.EXT_shader_framebuffer_fetch = extensions.shaderFramebufferFetchEXT; + + // GL_EXT_clip_cull_distance + mResources.EXT_clip_cull_distance = extensions.clipCullDistanceEXT; + + // GL_EXT_primitive_bounding_box + mResources.EXT_primitive_bounding_box = extensions.primitiveBoundingBoxEXT; + + // GL_OES_primitive_bounding_box + mResources.OES_primitive_bounding_box = extensions.primitiveBoundingBoxOES; + + // GLSL ES 3.0 constants + mResources.MaxVertexOutputVectors = caps.maxVertexOutputComponents / 4; + mResources.MaxFragmentInputVectors = caps.maxFragmentInputComponents / 4; + mResources.MinProgramTexelOffset = caps.minProgramTexelOffset; + mResources.MaxProgramTexelOffset = caps.maxProgramTexelOffset; + + // EXT_blend_func_extended + mResources.EXT_blend_func_extended = extensions.blendFuncExtendedEXT; + mResources.MaxDualSourceDrawBuffers = caps.maxDualSourceDrawBuffers; + + // APPLE_clip_distance/EXT_clip_cull_distance + mResources.MaxClipDistances = caps.maxClipDistances; + mResources.MaxCullDistances = caps.maxCullDistances; + mResources.MaxCombinedClipAndCullDistances = caps.maxCombinedClipAndCullDistances; + + // ANGLE_shader_pixel_local_storage. + mResources.MaxPixelLocalStoragePlanes = caps.maxPixelLocalStoragePlanes; + mResources.MaxColorAttachmentsWithActivePixelLocalStorage = + caps.maxColorAttachmentsWithActivePixelLocalStorage; + mResources.MaxCombinedDrawBuffersAndPixelLocalStoragePlanes = + caps.maxCombinedDrawBuffersAndPixelLocalStoragePlanes; + + // OES_sample_variables + mResources.OES_sample_variables = extensions.sampleVariablesOES; + mResources.MaxSamples = caps.maxSamples; + + // ANDROID_extension_pack_es31a + mResources.ANDROID_extension_pack_es31a = extensions.extensionPackEs31aANDROID; + + // KHR_blend_equation_advanced + mResources.KHR_blend_equation_advanced = extensions.blendEquationAdvancedKHR; + + // GLSL ES 3.1 constants + mResources.MaxProgramTextureGatherOffset = caps.maxProgramTextureGatherOffset; + mResources.MinProgramTextureGatherOffset = caps.minProgramTextureGatherOffset; + mResources.MaxImageUnits = caps.maxImageUnits; + mResources.MaxVertexImageUniforms = caps.maxShaderImageUniforms[ShaderType::Vertex]; + mResources.MaxFragmentImageUniforms = caps.maxShaderImageUniforms[ShaderType::Fragment]; + mResources.MaxComputeImageUniforms = caps.maxShaderImageUniforms[ShaderType::Compute]; + mResources.MaxCombinedImageUniforms = caps.maxCombinedImageUniforms; + mResources.MaxCombinedShaderOutputResources = caps.maxCombinedShaderOutputResources; + mResources.MaxUniformLocations = caps.maxUniformLocations; + + for (size_t index = 0u; index < 3u; ++index) + { + mResources.MaxComputeWorkGroupCount[index] = caps.maxComputeWorkGroupCount[index]; + mResources.MaxComputeWorkGroupSize[index] = caps.maxComputeWorkGroupSize[index]; + } + + mResources.MaxComputeUniformComponents = caps.maxShaderUniformComponents[ShaderType::Compute]; + mResources.MaxComputeTextureImageUnits = caps.maxShaderTextureImageUnits[ShaderType::Compute]; + + mResources.MaxComputeAtomicCounters = caps.maxShaderAtomicCounters[ShaderType::Compute]; + mResources.MaxComputeAtomicCounterBuffers = + caps.maxShaderAtomicCounterBuffers[ShaderType::Compute]; + + mResources.MaxVertexAtomicCounters = caps.maxShaderAtomicCounters[ShaderType::Vertex]; + mResources.MaxFragmentAtomicCounters = caps.maxShaderAtomicCounters[ShaderType::Fragment]; + mResources.MaxCombinedAtomicCounters = caps.maxCombinedAtomicCounters; + mResources.MaxAtomicCounterBindings = caps.maxAtomicCounterBufferBindings; + mResources.MaxVertexAtomicCounterBuffers = + caps.maxShaderAtomicCounterBuffers[ShaderType::Vertex]; + mResources.MaxFragmentAtomicCounterBuffers = + caps.maxShaderAtomicCounterBuffers[ShaderType::Fragment]; + mResources.MaxCombinedAtomicCounterBuffers = caps.maxCombinedAtomicCounterBuffers; + mResources.MaxAtomicCounterBufferSize = caps.maxAtomicCounterBufferSize; + + mResources.MaxUniformBufferBindings = caps.maxUniformBufferBindings; + mResources.MaxShaderStorageBufferBindings = caps.maxShaderStorageBufferBindings; + + // Needed by point size clamping workaround + mResources.MaxPointSize = caps.maxAliasedPointSize; + + if (state.getClientMajorVersion() == 2 && !extensions.drawBuffersEXT) + { + mResources.MaxDrawBuffers = 1; + } + + // Geometry Shader constants + mResources.EXT_geometry_shader = extensions.geometryShaderEXT; + mResources.OES_geometry_shader = extensions.geometryShaderOES; + mResources.MaxGeometryUniformComponents = caps.maxShaderUniformComponents[ShaderType::Geometry]; + mResources.MaxGeometryUniformBlocks = caps.maxShaderUniformBlocks[ShaderType::Geometry]; + mResources.MaxGeometryInputComponents = caps.maxGeometryInputComponents; + mResources.MaxGeometryOutputComponents = caps.maxGeometryOutputComponents; + mResources.MaxGeometryOutputVertices = caps.maxGeometryOutputVertices; + mResources.MaxGeometryTotalOutputComponents = caps.maxGeometryTotalOutputComponents; + mResources.MaxGeometryTextureImageUnits = caps.maxShaderTextureImageUnits[ShaderType::Geometry]; + + mResources.MaxGeometryAtomicCounterBuffers = + caps.maxShaderAtomicCounterBuffers[ShaderType::Geometry]; + mResources.MaxGeometryAtomicCounters = caps.maxShaderAtomicCounters[ShaderType::Geometry]; + mResources.MaxGeometryShaderStorageBlocks = caps.maxShaderStorageBlocks[ShaderType::Geometry]; + mResources.MaxGeometryShaderInvocations = caps.maxGeometryShaderInvocations; + mResources.MaxGeometryImageUniforms = caps.maxShaderImageUniforms[ShaderType::Geometry]; + + // Tessellation Shader constants + mResources.EXT_tessellation_shader = extensions.tessellationShaderEXT; + mResources.MaxTessControlInputComponents = caps.maxTessControlInputComponents; + mResources.MaxTessControlOutputComponents = caps.maxTessControlOutputComponents; + mResources.MaxTessControlTextureImageUnits = + caps.maxShaderTextureImageUnits[ShaderType::TessControl]; + mResources.MaxTessControlUniformComponents = + caps.maxShaderUniformComponents[ShaderType::TessControl]; + mResources.MaxTessControlTotalOutputComponents = caps.maxTessControlTotalOutputComponents; + mResources.MaxTessControlImageUniforms = caps.maxShaderImageUniforms[ShaderType::TessControl]; + mResources.MaxTessControlAtomicCounters = caps.maxShaderAtomicCounters[ShaderType::TessControl]; + mResources.MaxTessControlAtomicCounterBuffers = + caps.maxShaderAtomicCounterBuffers[ShaderType::TessControl]; + + mResources.MaxTessPatchComponents = caps.maxTessPatchComponents; + mResources.MaxPatchVertices = caps.maxPatchVertices; + mResources.MaxTessGenLevel = caps.maxTessGenLevel; + + mResources.MaxTessEvaluationInputComponents = caps.maxTessEvaluationInputComponents; + mResources.MaxTessEvaluationOutputComponents = caps.maxTessEvaluationOutputComponents; + mResources.MaxTessEvaluationTextureImageUnits = + caps.maxShaderTextureImageUnits[ShaderType::TessEvaluation]; + mResources.MaxTessEvaluationUniformComponents = + caps.maxShaderUniformComponents[ShaderType::TessEvaluation]; + mResources.MaxTessEvaluationImageUniforms = + caps.maxShaderImageUniforms[ShaderType::TessEvaluation]; + mResources.MaxTessEvaluationAtomicCounters = + caps.maxShaderAtomicCounters[ShaderType::TessEvaluation]; + mResources.MaxTessEvaluationAtomicCounterBuffers = + caps.maxShaderAtomicCounterBuffers[ShaderType::TessEvaluation]; + + // Subpixel bits. + mResources.SubPixelBits = static_cast(caps.subPixelBits); +} + +Compiler::~Compiler() = default; + +void Compiler::onDestroy(const Context *context) +{ + std::lock_guard lock(context->getDisplay()->getDisplayGlobalMutex()); + for (auto &pool : mPools) + { + for (ShCompilerInstance &instance : pool) + { + instance.destroy(); + } + } + --gActiveCompilers; + if (gActiveCompilers == 0) + { + sh::Finalize(); + } +} + +ShCompilerInstance Compiler::getInstance(ShaderType type) +{ + ASSERT(type != ShaderType::InvalidEnum); + auto &pool = mPools[type]; + if (pool.empty()) + { + ShHandle handle = sh::ConstructCompiler(ToGLenum(type), mSpec, mOutputType, &mResources); + ASSERT(handle); + return ShCompilerInstance(handle, mOutputType, type); + } + else + { + ShCompilerInstance instance = std::move(pool.back()); + pool.pop_back(); + return instance; + } +} + +void Compiler::putInstance(ShCompilerInstance &&instance) +{ + static constexpr size_t kMaxPoolSize = 32; + auto &pool = mPools[instance.getShaderType()]; + if (pool.size() < kMaxPoolSize) + { + pool.push_back(std::move(instance)); + } + else + { + instance.destroy(); + } +} + +ShShaderSpec Compiler::SelectShaderSpec(const State &state) +{ + const EGLenum clientType = state.getClientType(); + const EGLint profileMask = state.getProfileMask(); + const GLint majorVersion = state.getClientMajorVersion(); + const GLint minorVersion = state.getClientMinorVersion(); + bool isWebGL = state.isWebGL(); + + // For Desktop GL + if (clientType == EGL_OPENGL_API) + { + if ((profileMask & EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT) != 0) + { + return SH_GL_CORE_SPEC; + } + else + { + return SH_GL_COMPATIBILITY_SPEC; + } + } + + if (majorVersion >= 3) + { + switch (minorVersion) + { + case 2: + ASSERT(!isWebGL); + return SH_GLES3_2_SPEC; + case 1: + return isWebGL ? SH_WEBGL3_SPEC : SH_GLES3_1_SPEC; + case 0: + return isWebGL ? SH_WEBGL2_SPEC : SH_GLES3_SPEC; + default: + UNREACHABLE(); + } + } + + // GLES1 emulation: Use GLES3 shader spec. + if (!isWebGL && majorVersion == 1) + { + return SH_GLES3_SPEC; + } + + return isWebGL ? SH_WEBGL_SPEC : SH_GLES2_SPEC; +} + +ShCompilerInstance::ShCompilerInstance() : mHandle(nullptr) {} + +ShCompilerInstance::ShCompilerInstance(ShHandle handle, + ShShaderOutput outputType, + ShaderType shaderType) + : mHandle(handle), mOutputType(outputType), mShaderType(shaderType) +{} + +ShCompilerInstance::~ShCompilerInstance() +{ + ASSERT(mHandle == nullptr); +} + +void ShCompilerInstance::destroy() +{ + if (mHandle != nullptr) + { + sh::Destruct(mHandle); + mHandle = nullptr; + } +} + +ShCompilerInstance::ShCompilerInstance(ShCompilerInstance &&other) + : mHandle(other.mHandle), mOutputType(other.mOutputType), mShaderType(other.mShaderType) +{ + other.mHandle = nullptr; +} + +ShCompilerInstance &ShCompilerInstance::operator=(ShCompilerInstance &&other) +{ + mHandle = other.mHandle; + mOutputType = other.mOutputType; + mShaderType = other.mShaderType; + other.mHandle = nullptr; + return *this; +} + +ShHandle ShCompilerInstance::getHandle() +{ + return mHandle; +} + +ShaderType ShCompilerInstance::getShaderType() const +{ + return mShaderType; +} + +ShBuiltInResources ShCompilerInstance::getBuiltInResources() const +{ + return sh::GetBuiltInResources(mHandle); +} + +const std::string &ShCompilerInstance::getBuiltinResourcesString() const +{ + return sh::GetBuiltInResourcesString(mHandle); +} + +ShShaderOutput ShCompilerInstance::getShaderOutputType() const +{ + return mOutputType; +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/Compiler.h b/gfx/angle/checkout/src/libANGLE/Compiler.h new file mode 100644 index 0000000000..01428f36da --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Compiler.h @@ -0,0 +1,78 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Compiler.h: Defines the gl::Compiler class, abstracting the ESSL compiler +// that a GL context holds. + +#ifndef LIBANGLE_COMPILER_H_ +#define LIBANGLE_COMPILER_H_ + +#include + +#include "GLSLANG/ShaderLang.h" +#include "common/PackedEnums.h" +#include "libANGLE/Error.h" +#include "libANGLE/RefCountObject.h" + +namespace rx +{ +class CompilerImpl; +class GLImplFactory; +} // namespace rx + +namespace gl +{ +class ShCompilerInstance; +class State; + +class Compiler final : public RefCountObjectNoID +{ + public: + Compiler(rx::GLImplFactory *implFactory, const State &data, egl::Display *display); + + void onDestroy(const Context *context) override; + + ShCompilerInstance getInstance(ShaderType shaderType); + void putInstance(ShCompilerInstance &&instance); + ShShaderOutput getShaderOutputType() const { return mOutputType; } + + static ShShaderSpec SelectShaderSpec(const State &state); + + private: + ~Compiler() override; + std::unique_ptr mImplementation; + ShShaderSpec mSpec; + ShShaderOutput mOutputType; + ShBuiltInResources mResources; + ShaderMap> mPools; +}; + +class ShCompilerInstance final : public angle::NonCopyable +{ + public: + ShCompilerInstance(); + ShCompilerInstance(ShHandle handle, ShShaderOutput outputType, ShaderType shaderType); + ~ShCompilerInstance(); + void destroy(); + + ShCompilerInstance(ShCompilerInstance &&other); + ShCompilerInstance &operator=(ShCompilerInstance &&other); + + ShHandle getHandle(); + ShaderType getShaderType() const; + ShBuiltInResources getBuiltInResources() const; + const std::string &getBuiltinResourcesString() const; + ShShaderOutput getShaderOutputType() const; + + private: + ShHandle mHandle; + ShShaderOutput mOutputType; + ShaderType mShaderType; +}; + +} // namespace gl + +#endif // LIBANGLE_COMPILER_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Config.cpp b/gfx/angle/checkout/src/libANGLE/Config.cpp new file mode 100644 index 0000000000..127480db1f --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Config.cpp @@ -0,0 +1,416 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Config.cpp: Implements the egl::Config class, describing the format, type +// and size for an egl::Surface. Implements EGLConfig and related functionality. +// [EGL 1.5] section 3.4 page 19. + +#include "libANGLE/Config.h" +#include "libANGLE/AttributeMap.h" + +#include +#include + +#include +#include "angle_gl.h" + +#include "common/debug.h" + +namespace egl +{ + +Config::Config() + : renderTargetFormat(GL_NONE), + depthStencilFormat(GL_NONE), + bufferSize(0), + redSize(0), + greenSize(0), + blueSize(0), + luminanceSize(0), + alphaSize(0), + alphaMaskSize(0), + bindToTextureRGB(EGL_FALSE), + bindToTextureRGBA(EGL_FALSE), + bindToTextureTarget(EGL_TEXTURE_2D), + colorBufferType(EGL_RGB_BUFFER), + configCaveat(EGL_NONE), + configID(0), + conformant(0), + depthSize(0), + level(0), + matchNativePixmap(EGL_FALSE), + maxPBufferWidth(0), + maxPBufferHeight(0), + maxPBufferPixels(0), + maxSwapInterval(0), + minSwapInterval(0), + nativeRenderable(EGL_FALSE), + nativeVisualID(0), + nativeVisualType(0), + renderableType(0), + sampleBuffers(0), + samples(0), + stencilSize(0), + surfaceType(0), + transparentType(EGL_NONE), + transparentRedValue(0), + transparentGreenValue(0), + transparentBlueValue(0), + optimalOrientation(0), + colorComponentType(EGL_COLOR_COMPONENT_TYPE_FIXED_EXT), + recordable(EGL_FALSE), + framebufferTarget(EGL_FALSE), // TODO: http://anglebug.com/4208 + yInverted(EGL_FALSE) +{} + +Config::~Config() {} + +Config::Config(const Config &other) = default; + +Config &Config::operator=(const Config &other) = default; + +ConfigSet::ConfigSet() = default; + +ConfigSet::ConfigSet(const ConfigSet &other) = default; + +ConfigSet &ConfigSet::operator=(const ConfigSet &other) = default; + +ConfigSet::~ConfigSet() = default; + +EGLint ConfigSet::add(const Config &config) +{ + // Set the config's ID to a small number that starts at 1 ([EGL 1.5] section 3.4) + EGLint id = static_cast(mConfigs.size()) + 1; + + Config copyConfig(config); + copyConfig.configID = id; + mConfigs.insert(std::make_pair(id, copyConfig)); + + return id; +} + +const Config &ConfigSet::get(EGLint id) const +{ + ASSERT(mConfigs.find(id) != mConfigs.end()); + return mConfigs.find(id)->second; +} + +void ConfigSet::clear() +{ + mConfigs.clear(); +} + +size_t ConfigSet::size() const +{ + return mConfigs.size(); +} + +bool ConfigSet::contains(const Config *config) const +{ + for (auto i = mConfigs.begin(); i != mConfigs.end(); i++) + { + const Config &item = i->second; + if (config == &item) + { + return true; + } + } + + return false; +} + +// Function object used by STL sorting routines for ordering Configs according to [EGL 1.5] +// section 3.4.1.2 page 28. +class ConfigSorter +{ + public: + explicit ConfigSorter(const AttributeMap &attributeMap) + : mWantRed(false), + mWantGreen(false), + mWantBlue(false), + mWantAlpha(false), + mWantLuminance(false) + { + scanForWantedComponents(attributeMap); + } + + bool operator()(const Config *x, const Config *y) const { return (*this)(*x, *y); } + + bool operator()(const Config &x, const Config &y) const + { +#define SORT(attribute) \ + do \ + { \ + if (x.attribute != y.attribute) \ + return x.attribute < y.attribute; \ + } while (0) + + static_assert(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG, + "Unexpected EGL enum value."); + SORT(configCaveat); + + static_assert(EGL_COLOR_COMPONENT_TYPE_FIXED_EXT < EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT, + "Unexpected order of EGL enums."); + SORT(colorComponentType); + + static_assert(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER, "Unexpected EGL enum value."); + SORT(colorBufferType); + + // By larger total number of color bits, only considering those that are requested to be > + // 0. + EGLint xComponentsSize = wantedComponentsSize(x); + EGLint yComponentsSize = wantedComponentsSize(y); + if (xComponentsSize != yComponentsSize) + { + return xComponentsSize > yComponentsSize; + } + + SORT(bufferSize); + SORT(sampleBuffers); + SORT(samples); + SORT(depthSize); + SORT(stencilSize); + SORT(alphaMaskSize); + SORT(nativeVisualType); + SORT(configID); + +#undef SORT + + return false; + } + + private: + static bool wantsComponent(const AttributeMap &attributeMap, EGLAttrib component) + { + // [EGL 1.5] section 3.4.1.2 page 30 + // Sorting rule #3: by larger total number of color bits, not considering + // components that are 0 or don't-care. + EGLAttrib value = attributeMap.get(component, 0); + return value != 0 && value != EGL_DONT_CARE; + } + + void scanForWantedComponents(const AttributeMap &attributeMap) + { + mWantRed = wantsComponent(attributeMap, EGL_RED_SIZE); + mWantGreen = wantsComponent(attributeMap, EGL_GREEN_SIZE); + mWantBlue = wantsComponent(attributeMap, EGL_BLUE_SIZE); + mWantAlpha = wantsComponent(attributeMap, EGL_ALPHA_SIZE); + mWantLuminance = wantsComponent(attributeMap, EGL_LUMINANCE_SIZE); + } + + EGLint wantedComponentsSize(const Config &config) const + { + EGLint total = 0; + + if (mWantRed) + total += config.redSize; + if (mWantGreen) + total += config.greenSize; + if (mWantBlue) + total += config.blueSize; + if (mWantAlpha) + total += config.alphaSize; + if (mWantLuminance) + total += config.luminanceSize; + + return total; + } + + bool mWantRed; + bool mWantGreen; + bool mWantBlue; + bool mWantAlpha; + bool mWantLuminance; +}; + +std::vector ConfigSet::filter(const AttributeMap &attributeMap) const +{ + std::vector result; + result.reserve(mConfigs.size()); + + for (auto configIter = mConfigs.begin(); configIter != mConfigs.end(); configIter++) + { + const Config &config = configIter->second; + bool match = true; + + for (auto attribIter = attributeMap.begin(); attribIter != attributeMap.end(); attribIter++) + { + EGLAttrib attributeKey = attribIter->first; + EGLAttrib attributeValue = attribIter->second; + + if (attributeValue == EGL_DONT_CARE) + { + continue; + } + + switch (attributeKey) + { + case EGL_BUFFER_SIZE: + match = config.bufferSize >= attributeValue; + break; + case EGL_ALPHA_SIZE: + match = config.alphaSize >= attributeValue; + break; + case EGL_BLUE_SIZE: + match = config.blueSize >= attributeValue; + break; + case EGL_GREEN_SIZE: + match = config.greenSize >= attributeValue; + break; + case EGL_RED_SIZE: + match = config.redSize >= attributeValue; + break; + case EGL_DEPTH_SIZE: + match = config.depthSize >= attributeValue; + break; + case EGL_STENCIL_SIZE: + match = config.stencilSize >= attributeValue; + break; + case EGL_CONFIG_CAVEAT: + match = config.configCaveat == static_cast(attributeValue); + break; + case EGL_CONFIG_ID: + match = config.configID == attributeValue; + break; + case EGL_LEVEL: + match = config.level == attributeValue; + break; + case EGL_NATIVE_RENDERABLE: + match = config.nativeRenderable == static_cast(attributeValue); + break; + case EGL_NATIVE_VISUAL_TYPE: + match = config.nativeVisualType == attributeValue; + break; + case EGL_SAMPLES: + match = config.samples >= attributeValue; + break; + case EGL_SAMPLE_BUFFERS: + match = config.sampleBuffers >= attributeValue; + break; + case EGL_SURFACE_TYPE: + match = (config.surfaceType & attributeValue) == attributeValue; + break; + case EGL_TRANSPARENT_TYPE: + match = config.transparentType == static_cast(attributeValue); + break; + case EGL_TRANSPARENT_BLUE_VALUE: + if (attributeMap.get(EGL_TRANSPARENT_TYPE, EGL_NONE) != EGL_NONE) + { + match = config.transparentBlueValue == attributeValue; + } + break; + case EGL_TRANSPARENT_GREEN_VALUE: + if (attributeMap.get(EGL_TRANSPARENT_TYPE, EGL_NONE) != EGL_NONE) + { + match = config.transparentGreenValue == attributeValue; + } + break; + case EGL_TRANSPARENT_RED_VALUE: + if (attributeMap.get(EGL_TRANSPARENT_TYPE, EGL_NONE) != EGL_NONE) + { + match = config.transparentRedValue == attributeValue; + } + break; + case EGL_BIND_TO_TEXTURE_RGB: + match = config.bindToTextureRGB == static_cast(attributeValue); + break; + case EGL_BIND_TO_TEXTURE_RGBA: + match = config.bindToTextureRGBA == static_cast(attributeValue); + break; + case EGL_BIND_TO_TEXTURE_TARGET_ANGLE: + match = config.bindToTextureTarget == static_cast(attributeValue); + break; + case EGL_MIN_SWAP_INTERVAL: + match = config.minSwapInterval == attributeValue; + break; + case EGL_MAX_SWAP_INTERVAL: + match = config.maxSwapInterval == attributeValue; + break; + case EGL_LUMINANCE_SIZE: + match = config.luminanceSize >= attributeValue; + break; + case EGL_ALPHA_MASK_SIZE: + match = config.alphaMaskSize >= attributeValue; + break; + case EGL_COLOR_BUFFER_TYPE: + match = config.colorBufferType == static_cast(attributeValue); + break; + case EGL_RENDERABLE_TYPE: + match = (config.renderableType & attributeValue) == attributeValue; + break; + case EGL_MATCH_NATIVE_PIXMAP: + match = false; + UNIMPLEMENTED(); + break; + case EGL_CONFORMANT: + match = (config.conformant & attributeValue) == attributeValue; + break; + case EGL_MAX_PBUFFER_WIDTH: + match = config.maxPBufferWidth >= attributeValue; + break; + case EGL_MAX_PBUFFER_HEIGHT: + match = config.maxPBufferHeight >= attributeValue; + break; + case EGL_MAX_PBUFFER_PIXELS: + match = config.maxPBufferPixels >= attributeValue; + break; + case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE: + match = config.optimalOrientation == attributeValue; + break; + case EGL_COLOR_COMPONENT_TYPE_EXT: + match = config.colorComponentType == static_cast(attributeValue); + break; + case EGL_RECORDABLE_ANDROID: + match = config.recordable == static_cast(attributeValue); + break; + case EGL_FRAMEBUFFER_TARGET_ANDROID: + match = config.framebufferTarget == static_cast(attributeValue); + break; + case EGL_Y_INVERTED_NOK: + match = config.yInverted == static_cast(attributeValue); + break; + case EGL_MATCH_FORMAT_KHR: + if (attributeValue == EGL_NONE) + { + match = (config.surfaceType & EGL_LOCK_SURFACE_BIT_KHR) == 0; + } + else + { + match = config.matchFormat == attributeValue; + } + break; + default: + UNREACHABLE(); + } + + if (!match) + { + break; + } + } + + if (match) + { + result.push_back(&config); + } + } + + // Sort the result + std::sort(result.begin(), result.end(), ConfigSorter(attributeMap)); + + return result; +} + +ConfigSet::ConfigMap::iterator ConfigSet::begin() +{ + return mConfigs.begin(); +} + +ConfigSet::ConfigMap::iterator ConfigSet::end() +{ + return mConfigs.end(); +} +} // namespace egl diff --git a/gfx/angle/checkout/src/libANGLE/Config.h b/gfx/angle/checkout/src/libANGLE/Config.h new file mode 100644 index 0000000000..7901c793ee --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Config.h @@ -0,0 +1,115 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Config.h: Defines the egl::Config class, describing the format, type +// and size for an egl::Surface. Implements EGLConfig and related functionality. +// [EGL 1.5] section 3.4 page 19. + +#ifndef INCLUDE_CONFIG_H_ +#define INCLUDE_CONFIG_H_ + +#include "libANGLE/AttributeMap.h" + +#include "common/angleutils.h" + +#include +#include + +#include +#include + +namespace egl +{ + +struct Config +{ + Config(); + ~Config(); + Config(const Config &other); + Config &operator=(const Config &other); + + GLenum renderTargetFormat; // TODO(geofflang): remove this + GLenum depthStencilFormat; // TODO(geofflang): remove this + + EGLint bufferSize; // Depth of the color buffer + EGLint redSize; // Bits of Red in the color buffer + EGLint greenSize; // Bits of Green in the color buffer + EGLint blueSize; // Bits of Blue in the color buffer + EGLint luminanceSize; // Bits of Luminance in the color buffer + EGLint alphaSize; // Bits of Alpha in the color buffer + EGLint alphaMaskSize; // Bits of Alpha Mask in the mask buffer + EGLBoolean bindToTextureRGB; // True if bindable to RGB textures. + EGLBoolean bindToTextureRGBA; // True if bindable to RGBA textures. + EGLenum bindToTextureTarget; // Which texture target should be used for pbuffers + EGLenum colorBufferType; // Color buffer type + EGLenum configCaveat; // Any caveats for the configuration + EGLint configID; // Unique EGLConfig identifier + EGLint conformant; // Whether contexts created with this config are conformant + EGLint depthSize; // Bits of Z in the depth buffer + EGLint level; // Frame buffer level + EGLBoolean matchNativePixmap; // Match the native pixmap format + EGLint maxPBufferWidth; // Maximum width of pbuffer + EGLint maxPBufferHeight; // Maximum height of pbuffer + EGLint maxPBufferPixels; // Maximum size of pbuffer + EGLint maxSwapInterval; // Maximum swap interval + EGLint minSwapInterval; // Minimum swap interval + EGLBoolean nativeRenderable; // EGL_TRUE if native rendering APIs can render to surface + EGLint nativeVisualID; // Handle of corresponding native visual + EGLint nativeVisualType; // Native visual type of the associated visual + EGLint renderableType; // Which client rendering APIs are supported. + EGLint sampleBuffers; // Number of multisample buffers + EGLint samples; // Number of samples per pixel + EGLint stencilSize; // Bits of Stencil in the stencil buffer + EGLint surfaceType; // Which types of EGL surfaces are supported. + EGLenum transparentType; // Type of transparency supported + EGLint transparentRedValue; // Transparent red value + EGLint transparentGreenValue; // Transparent green value + EGLint transparentBlueValue; // Transparent blue value + EGLint optimalOrientation; // Optimal window surface orientation + EGLenum colorComponentType; // Color component type + EGLBoolean recordable; // EGL_TRUE if a surface can support recording on Android + EGLBoolean framebufferTarget; // EGL_TRUE if the config supports rendering to a ANativeWindow + // for which the buffers are passed to the HWComposer HAL as a + // framebuffer target layer. + EGLBoolean yInverted; // True if the drawable's framebuffer is y-inverted. This can be used to + // determine if y-inverted texture coordinates need to be used when + // texturing from this drawable when it is bound to a texture target. + EGLint matchFormat; // LockSurface match format. +}; + +class ConfigSet +{ + private: + typedef std::map ConfigMap; + + public: + ConfigSet(); + ConfigSet(const ConfigSet &other); + ~ConfigSet(); + ConfigSet &operator=(const ConfigSet &other); + + EGLint add(const Config &config); + const Config &get(EGLint id) const; + + void clear(); + + size_t size() const; + + bool contains(const Config *config) const; + + // Filter configurations based on the table in [EGL 1.5] section 3.4.1.2 page 29 + std::vector filter(const AttributeMap &attributeMap) const; + + ConfigMap::iterator begin(); + ConfigMap::iterator end(); + + private: + ConfigMap mConfigs; +}; + +} // namespace egl + +#endif // INCLUDE_CONFIG_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Constants.h b/gfx/angle/checkout/src/libANGLE/Constants.h new file mode 100644 index 0000000000..36152825e4 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Constants.h @@ -0,0 +1,125 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Contants.h: Defines some implementation specific and gl constants + +#ifndef LIBANGLE_CONSTANTS_H_ +#define LIBANGLE_CONSTANTS_H_ + +#include "common/platform.h" + +#include + +namespace gl +{ + +// The binary cache is currently left disable by default, and the application can enable it. +const size_t kDefaultMaxProgramCacheMemoryBytes = 0; + +enum +{ + // Implementation upper limits, real maximums depend on the hardware + + // Only up to 32x MSAA supported. + IMPLEMENTATION_MAX_SAMPLE_MASK_WORDS = 1, + IMPLEMENTATION_MAX_SAMPLES = 32, + + MAX_VERTEX_ATTRIBS = 16, + MAX_VERTEX_ATTRIB_BINDINGS = 16, + + IMPLEMENTATION_MAX_VARYING_VECTORS = 32, + IMPLEMENTATION_MAX_DRAW_BUFFERS = 8, + IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS = + IMPLEMENTATION_MAX_DRAW_BUFFERS + 2, // 2 extra for depth and/or stencil buffers + + // The vast majority of devices support only one dual-source draw buffer + IMPLEMENTATION_MAX_DUAL_SOURCE_DRAW_BUFFERS = 1, + + IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS = 16, + IMPLEMENTATION_MAX_GEOMETRY_SHADER_UNIFORM_BUFFERS = 16, + IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS = 16, + IMPLEMENTATION_MAX_COMPUTE_SHADER_UNIFORM_BUFFERS = 16, + + // GL_EXT_geometry_shader increases the minimum value of GL_MAX_COMBINED_UNIFORM_BLOCKS to 36. + // GL_EXT_tessellation_shader increases the minimum value to 60. + IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS = 60, + + // GL_EXT_geometry_shader increases the minimum value of GL_MAX_UNIFORM_BUFFER_BINDINGS to 48. + // GL_EXT_tessellation_shader increases the minimum value to 72. + IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS = 72, + + // Transform feedback limits set to the minimum required by the spec. + IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS = 128, + IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = 4, + IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS = 4, + IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS = 4, + + // Maximum number of views which are supported by the implementation of ANGLE_multiview. + IMPLEMENTATION_ANGLE_MULTIVIEW_MAX_VIEWS = 4, + + // These are the maximums the implementation can support + // The actual GL caps are limited by the device caps + // and should be queried from the Context + IMPLEMENTATION_MAX_2D_TEXTURE_SIZE = 32768, + IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = 32768, + IMPLEMENTATION_MAX_3D_TEXTURE_SIZE = 16384, + IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS = 2048, + + // 1+log2 of max of MAX_*_TEXTURE_SIZE + IMPLEMENTATION_MAX_TEXTURE_LEVELS = 16, + + IMPLEMENTATION_MAX_SHADER_TEXTURES = 32, + + // In ES 3.1 and below, the limit for active textures is 64. + IMPLEMENTATION_MAX_ES31_ACTIVE_TEXTURES = 64, + + // In ES 3.2 we need to support a minimum of 96 maximum textures. + IMPLEMENTATION_MAX_ACTIVE_TEXTURES = 96, + IMPLEMENTATION_MAX_IMAGE_UNITS = IMPLEMENTATION_MAX_ACTIVE_TEXTURES, + + // Maximum number of slots allocated for atomic counter buffers. + IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS = 8, + + // Implementation upper limits, real maximums depend on the hardware. + IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS = 64, + + // Implementation upper limits of max number of clip distances (minimum required per spec) + IMPLEMENTATION_MAX_CLIP_DISTANCES = 8, + + // Implementation upper limit for layered framebuffer layer count + IMPLEMENTATION_MAX_FRAMEBUFFER_LAYERS = 256, + + // ANGLE_shader_pixel_local_storage: keep the maximum number of supported planes reasonably + // similar on all platforms. + IMPLEMENTATION_MAX_PIXEL_LOCAL_STORAGE_PLANES = 8, +}; + +namespace limits +{ +// Almost all drivers use 2048 (the minimum value) as GL_MAX_VERTEX_ATTRIB_STRIDE. ANGLE advertizes +// the same limit. +constexpr uint32_t kMaxVertexAttribStride = 2048; + +// Some of the minimums required by GL, used to detect if the backend meets the minimum requirement. +// Currently, there's no need to separate these values per spec version. +constexpr uint32_t kMinimumComputeStorageBuffers = 4; + +// OpenGL ES 3.0+ Minimum Values +// Table 6.31 MAX_VERTEX_UNIFORM_BLOCKS minimum value = 12 +// Table 6.32 MAX_FRAGMENT_UNIFORM_BLOCKS minimum value = 12 +constexpr uint32_t kMinimumShaderUniformBlocks = 12; +// Table 6.31 MAX_VERTEX_OUTPUT_COMPONENTS minimum value = 64 +constexpr uint32_t kMinimumVertexOutputComponents = 64; + +// OpenGL ES 3.2+ Minimum Values +// Table 21.42 TEXTURE_BUFFER_OFFSET_ALIGNMENT minimum value = 256 +constexpr uint32_t kMinTextureBufferOffsetAlignment = 256; + +} // namespace limits + +} // namespace gl + +#endif // LIBANGLE_CONSTANTS_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Context.cpp b/gfx/angle/checkout/src/libANGLE/Context.cpp new file mode 100644 index 0000000000..bfd490ab29 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Context.cpp @@ -0,0 +1,10472 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Context.cpp: Implements the gl::Context class, managing all GL state and performing +// rendering operations. It is the GLES2 specific implementation of EGLContext. +#include "libANGLE/Context.inl.h" + +#include +#include +#include + +#include +#include +#include + +#include "common/PackedEnums.h" +#include "common/angle_version_info.h" +#include "common/matrix_utils.h" +#include "common/platform.h" +#include "common/system_utils.h" +#include "common/utilities.h" +#include "libANGLE/Buffer.h" +#include "libANGLE/Compiler.h" +#include "libANGLE/Display.h" +#include "libANGLE/Fence.h" +#include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/MemoryObject.h" +#include "libANGLE/PixelLocalStorage.h" +#include "libANGLE/Program.h" +#include "libANGLE/ProgramPipeline.h" +#include "libANGLE/Query.h" +#include "libANGLE/Renderbuffer.h" +#include "libANGLE/ResourceManager.h" +#include "libANGLE/Sampler.h" +#include "libANGLE/Semaphore.h" +#include "libANGLE/Surface.h" +#include "libANGLE/Texture.h" +#include "libANGLE/TransformFeedback.h" +#include "libANGLE/VertexArray.h" +#include "libANGLE/capture/FrameCapture.h" +#include "libANGLE/capture/frame_capture_utils.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/queryconversions.h" +#include "libANGLE/queryutils.h" +#include "libANGLE/renderer/DisplayImpl.h" +#include "libANGLE/renderer/Format.h" +#include "libANGLE/validationES.h" + +#if defined(ANGLE_PLATFORM_APPLE) +# include +# include "common/tls.h" +#endif + +namespace gl +{ +namespace +{ + +egl::ShareGroup *AllocateOrGetShareGroup(egl::Display *display, const gl::Context *shareContext) +{ + if (shareContext) + { + egl::ShareGroup *shareGroup = shareContext->getState().getShareGroup(); + shareGroup->addRef(); + return shareGroup; + } + else + { + return new egl::ShareGroup(display->getImplementation()); + } +} + +template +angle::Result GetQueryObjectParameter(const Context *context, Query *query, GLenum pname, T *params) +{ + if (!query) + { + // Some applications call into glGetQueryObjectuiv(...) prior to calling glBeginQuery(...) + // This wouldn't be an issue since the validation layer will handle such a usecases but when + // the app enables EGL_KHR_create_context_no_error extension, we skip the validation layer. + switch (pname) + { + case GL_QUERY_RESULT_EXT: + *params = 0; + break; + case GL_QUERY_RESULT_AVAILABLE_EXT: + *params = GL_FALSE; + break; + default: + UNREACHABLE(); + return angle::Result::Stop; + } + return angle::Result::Continue; + } + + switch (pname) + { + case GL_QUERY_RESULT_EXT: + return query->getResult(context, params); + case GL_QUERY_RESULT_AVAILABLE_EXT: + { + bool available = false; + if (context->isContextLost()) + { + available = true; + } + else + { + ANGLE_TRY(query->isResultAvailable(context, &available)); + } + *params = CastFromStateValue(pname, static_cast(available)); + return angle::Result::Continue; + } + default: + UNREACHABLE(); + return angle::Result::Stop; + } +} + +// Attribute map queries. +EGLint GetClientMajorVersion(const egl::AttributeMap &attribs) +{ + return static_cast(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1)); +} + +EGLint GetClientMinorVersion(const egl::AttributeMap &attribs) +{ + return static_cast(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0)); +} + +bool GetBackwardCompatibleContext(const egl::AttributeMap &attribs) +{ + return attribs.get(EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE, EGL_TRUE) == EGL_TRUE; +} + +bool GetWebGLContext(const egl::AttributeMap &attribs) +{ + return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE); +} + +Version GetClientVersion(egl::Display *display, + const egl::AttributeMap &attribs, + const EGLenum clientType) +{ + Version requestedVersion = + Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs)); + if (GetBackwardCompatibleContext(attribs)) + { + if (clientType == EGL_OPENGL_API) + { + Optional maxSupportedDesktopVersion = + display->getImplementation()->getMaxSupportedDesktopVersion(); + if (maxSupportedDesktopVersion.valid()) + return std::max(maxSupportedDesktopVersion.value(), requestedVersion); + else + return requestedVersion; + } + else if (requestedVersion.major == 1) + { + // If the user requests an ES1 context, we cannot return an ES 2+ context. + return Version(1, 1); + } + else + { + // Always up the version to at least the max conformant version this display supports. + // Only return a higher client version if requested. + const Version conformantVersion = std::max( + display->getImplementation()->getMaxConformantESVersion(), requestedVersion); + // Limit the WebGL context to at most version 3.1 + const bool isWebGL = GetWebGLContext(attribs); + return isWebGL ? std::min(conformantVersion, Version(3, 1)) : conformantVersion; + } + } + else + { + return requestedVersion; + } +} + +EGLint GetProfileMask(const egl::AttributeMap &attribs) +{ + return attribs.getAsInt(EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT); +} + +GLenum GetResetStrategy(const egl::AttributeMap &attribs) +{ + EGLAttrib resetStrategyExt = + attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_NO_RESET_NOTIFICATION); + EGLAttrib resetStrategyCore = + attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY, resetStrategyExt); + + switch (resetStrategyCore) + { + case EGL_NO_RESET_NOTIFICATION: + return GL_NO_RESET_NOTIFICATION_EXT; + case EGL_LOSE_CONTEXT_ON_RESET: + return GL_LOSE_CONTEXT_ON_RESET_EXT; + default: + UNREACHABLE(); + return GL_NONE; + } +} + +bool GetRobustAccess(const egl::AttributeMap &attribs) +{ + EGLAttrib robustAccessExt = attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE); + EGLAttrib robustAccessCore = attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS, robustAccessExt); + + bool attribRobustAccess = (robustAccessCore == EGL_TRUE); + bool contextFlagsRobustAccess = + ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) != 0); + + return (attribRobustAccess || contextFlagsRobustAccess); +} + +bool GetDebug(const egl::AttributeMap &attribs) +{ + return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE) || + ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) != 0); +} + +bool GetNoError(const egl::AttributeMap &attribs) +{ + return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE); +} + +bool GetExtensionsEnabled(const egl::AttributeMap &attribs, bool webGLContext) +{ + // If the context is WebGL, extensions are disabled by default + EGLAttrib defaultValue = webGLContext ? EGL_FALSE : EGL_TRUE; + return (attribs.get(EGL_EXTENSIONS_ENABLED_ANGLE, defaultValue) == EGL_TRUE); +} + +bool GetBindGeneratesResource(const egl::AttributeMap &attribs) +{ + return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE); +} + +bool GetClientArraysEnabled(const egl::AttributeMap &attribs) +{ + return (attribs.get(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE) == EGL_TRUE); +} + +bool GetRobustResourceInit(egl::Display *display, const egl::AttributeMap &attribs) +{ + const angle::FrontendFeatures &frontendFeatures = display->getFrontendFeatures(); + return (frontendFeatures.forceRobustResourceInit.enabled || + attribs.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE); +} + +EGLenum GetContextPriority(const egl::AttributeMap &attribs) +{ + return static_cast( + attribs.getAsInt(EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_MEDIUM_IMG)); +} + +bool GetProtectedContent(const egl::AttributeMap &attribs) +{ + return static_cast(attribs.getAsInt(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE)); +} + +std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label) +{ + std::string labelName; + if (label != nullptr) + { + size_t labelLength = length < 0 ? strlen(label) : length; + labelName = std::string(label, labelLength); + } + return labelName; +} + +void GetObjectLabelBase(const std::string &objectLabel, + GLsizei bufSize, + GLsizei *length, + GLchar *label) +{ + size_t writeLength = objectLabel.length(); + if (label != nullptr && bufSize > 0) + { + writeLength = std::min(static_cast(bufSize) - 1, objectLabel.length()); + std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label); + label[writeLength] = '\0'; + } + + if (length != nullptr) + { + *length = static_cast(writeLength); + } +} + +enum SubjectIndexes : angle::SubjectIndex +{ + kTexture0SubjectIndex = 0, + kTextureMaxSubjectIndex = kTexture0SubjectIndex + IMPLEMENTATION_MAX_ACTIVE_TEXTURES, + kImage0SubjectIndex = kTextureMaxSubjectIndex, + kImageMaxSubjectIndex = kImage0SubjectIndex + IMPLEMENTATION_MAX_IMAGE_UNITS, + kUniformBuffer0SubjectIndex = kImageMaxSubjectIndex, + kUniformBufferMaxSubjectIndex = + kUniformBuffer0SubjectIndex + IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS, + kAtomicCounterBuffer0SubjectIndex = kUniformBufferMaxSubjectIndex, + kAtomicCounterBufferMaxSubjectIndex = + kAtomicCounterBuffer0SubjectIndex + IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, + kShaderStorageBuffer0SubjectIndex = kAtomicCounterBufferMaxSubjectIndex, + kShaderStorageBufferMaxSubjectIndex = + kShaderStorageBuffer0SubjectIndex + IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS, + kSampler0SubjectIndex = kShaderStorageBufferMaxSubjectIndex, + kSamplerMaxSubjectIndex = kSampler0SubjectIndex + IMPLEMENTATION_MAX_ACTIVE_TEXTURES, + kVertexArraySubjectIndex = kSamplerMaxSubjectIndex, + kReadFramebufferSubjectIndex, + kDrawFramebufferSubjectIndex, + kProgramPipelineSubjectIndex, +}; + +bool IsClearBufferEnabled(const FramebufferState &fbState, GLenum buffer, GLint drawbuffer) +{ + return buffer != GL_COLOR || fbState.getEnabledDrawBuffers()[drawbuffer]; +} + +bool IsEmptyScissor(const State &glState) +{ + if (!glState.isScissorTestEnabled()) + { + return false; + } + + const Extents &dimensions = glState.getDrawFramebuffer()->getExtents(); + Rectangle framebufferArea(0, 0, dimensions.width, dimensions.height); + return !ClipRectangle(framebufferArea, glState.getScissor(), nullptr); +} + +bool IsColorMaskedOut(const BlendStateExt &blendStateExt, const GLint drawbuffer) +{ + ASSERT(static_cast(drawbuffer) < blendStateExt.getDrawBufferCount()); + return blendStateExt.getColorMaskIndexed(static_cast(drawbuffer)) == 0; +} + +bool GetIsExternal(const egl::AttributeMap &attribs) +{ + return (attribs.get(EGL_EXTERNAL_CONTEXT_ANGLE, EGL_FALSE) == EGL_TRUE); +} + +bool GetSaveAndRestoreState(const egl::AttributeMap &attribs) +{ + return (attribs.get(EGL_EXTERNAL_CONTEXT_SAVE_STATE_ANGLE, EGL_FALSE) == EGL_TRUE); +} + +void GetPerfMonitorString(const std::string &name, + GLsizei bufSize, + GLsizei *length, + GLchar *stringOut) +{ + GLsizei numCharsWritten = std::min(bufSize, static_cast(name.size())); + + if (length) + { + if (bufSize == 0) + { + *length = static_cast(name.size()); + } + else + { + // Excludes null terminator. + ASSERT(numCharsWritten > 0); + *length = numCharsWritten - 1; + } + } + + if (stringOut) + { + memcpy(stringOut, name.c_str(), numCharsWritten); + } +} + +bool CanSupportAEP(const gl::Version &version, const gl::Extensions &extensions) +{ + // From the GL_ANDROID_extension_pack_es31a extension spec: + // OpenGL ES 3.1 and GLSL ES 3.10 are required. + // The following extensions are required: + // * KHR_debug + // * KHR_texture_compression_astc_ldr + // * KHR_blend_equation_advanced + // * OES_sample_shading + // * OES_sample_variables + // * OES_shader_image_atomic + // * OES_shader_multisample_interpolation + // * OES_texture_stencil8 + // * OES_texture_storage_multisample_2d_array + // * EXT_copy_image + // * EXT_draw_buffers_indexed + // * EXT_geometry_shader + // * EXT_gpu_shader5 + // * EXT_primitive_bounding_box + // * EXT_shader_io_blocks + // * EXT_tessellation_shader + // * EXT_texture_border_clamp + // * EXT_texture_buffer + // * EXT_texture_cube_map_array + // * EXT_texture_sRGB_decode + return (version >= ES_3_1 && extensions.debugKHR && extensions.textureCompressionAstcLdrKHR && + extensions.blendEquationAdvancedKHR && extensions.sampleShadingOES && + extensions.sampleVariablesOES && extensions.shaderImageAtomicOES && + extensions.shaderMultisampleInterpolationOES && extensions.textureStencil8OES && + extensions.textureStorageMultisample2dArrayOES && extensions.copyImageEXT && + extensions.drawBuffersIndexedEXT && extensions.geometryShaderEXT && + extensions.gpuShader5EXT && extensions.primitiveBoundingBoxEXT && + extensions.shaderIoBlocksEXT && extensions.tessellationShaderEXT && + extensions.textureBorderClampEXT && extensions.textureBufferEXT && + extensions.textureCubeMapArrayEXT && extensions.textureSRGBDecodeEXT); +} +} // anonymous namespace + +#if defined(ANGLE_PLATFORM_APPLE) +// TODO(angleproject:6479): Due to a bug in Apple's dyld loader, `thread_local` will cause +// excessive memory use. Temporarily avoid it by using pthread's thread +// local storage instead. +static TLSIndex GetCurrentValidContextTLSIndex() +{ + static TLSIndex CurrentValidContextIndex = TLS_INVALID_INDEX; + static dispatch_once_t once; + dispatch_once(&once, ^{ + ASSERT(CurrentValidContextIndex == TLS_INVALID_INDEX); + CurrentValidContextIndex = CreateTLSIndex(nullptr); + }); + return CurrentValidContextIndex; +} +Context *GetCurrentValidContextTLS() +{ + TLSIndex CurrentValidContextIndex = GetCurrentValidContextTLSIndex(); + ASSERT(CurrentValidContextIndex != TLS_INVALID_INDEX); + return static_cast(GetTLSValue(CurrentValidContextIndex)); +} +void SetCurrentValidContextTLS(Context *context) +{ + TLSIndex CurrentValidContextIndex = GetCurrentValidContextTLSIndex(); + ASSERT(CurrentValidContextIndex != TLS_INVALID_INDEX); + SetTLSValue(CurrentValidContextIndex, context); +} +#else +thread_local Context *gCurrentValidContext = nullptr; +#endif + +Context::Context(egl::Display *display, + const egl::Config *config, + const Context *shareContext, + TextureManager *shareTextures, + SemaphoreManager *shareSemaphores, + MemoryProgramCache *memoryProgramCache, + MemoryShaderCache *memoryShaderCache, + const EGLenum clientType, + const egl::AttributeMap &attribs, + const egl::DisplayExtensions &displayExtensions, + const egl::ClientExtensions &clientExtensions) + : mState(shareContext ? &shareContext->mState : nullptr, + AllocateOrGetShareGroup(display, shareContext), + shareTextures, + shareSemaphores, + &mOverlay, + clientType, + GetClientVersion(display, attribs, clientType), + GetProfileMask(attribs), + GetDebug(attribs), + GetBindGeneratesResource(attribs), + GetClientArraysEnabled(attribs), + GetRobustResourceInit(display, attribs), + memoryProgramCache != nullptr, + GetContextPriority(attribs), + GetRobustAccess(attribs), + GetProtectedContent(attribs)), + mShared(shareContext != nullptr || shareTextures != nullptr || shareSemaphores != nullptr), + mSkipValidation(GetNoError(attribs)), + mDisplayTextureShareGroup(shareTextures != nullptr), + mDisplaySemaphoreShareGroup(shareSemaphores != nullptr), + mErrors(this), + mImplementation(display->getImplementation() + ->createContext(mState, &mErrors, config, shareContext, attribs)), + mLabel(nullptr), + mCompiler(), + mConfig(config), + mHasBeenCurrent(false), + mContextLost(false), + mResetStatus(GraphicsResetStatus::NoError), + mContextLostForced(false), + mResetStrategy(GetResetStrategy(attribs)), + mSurfacelessSupported(displayExtensions.surfacelessContext), + mCurrentDrawSurface(static_cast(EGL_NO_SURFACE)), + mCurrentReadSurface(static_cast(EGL_NO_SURFACE)), + mDisplay(display), + mWebGLContext(GetWebGLContext(attribs)), + mBufferAccessValidationEnabled(false), + mExtensionsEnabled(GetExtensionsEnabled(attribs, mWebGLContext)), + mMemoryProgramCache(memoryProgramCache), + mMemoryShaderCache(memoryShaderCache), + mVertexArrayObserverBinding(this, kVertexArraySubjectIndex), + mDrawFramebufferObserverBinding(this, kDrawFramebufferSubjectIndex), + mReadFramebufferObserverBinding(this, kReadFramebufferSubjectIndex), + mProgramPipelineObserverBinding(this, kProgramPipelineSubjectIndex), + mSingleThreadPool(nullptr), + mMultiThreadPool(nullptr), + mFrameCapture(new angle::FrameCapture), + mRefCount(0), + mOverlay(mImplementation.get()), + mIsExternal(GetIsExternal(attribs)), + mSaveAndRestoreState(GetSaveAndRestoreState(attribs)), + mIsDestroyed(false) +{ + for (angle::SubjectIndex uboIndex = kUniformBuffer0SubjectIndex; + uboIndex < kUniformBufferMaxSubjectIndex; ++uboIndex) + { + mUniformBufferObserverBindings.emplace_back(this, uboIndex); + } + + for (angle::SubjectIndex acbIndex = kAtomicCounterBuffer0SubjectIndex; + acbIndex < kAtomicCounterBufferMaxSubjectIndex; ++acbIndex) + { + mAtomicCounterBufferObserverBindings.emplace_back(this, acbIndex); + } + + for (angle::SubjectIndex ssboIndex = kShaderStorageBuffer0SubjectIndex; + ssboIndex < kShaderStorageBufferMaxSubjectIndex; ++ssboIndex) + { + mShaderStorageBufferObserverBindings.emplace_back(this, ssboIndex); + } + + for (angle::SubjectIndex samplerIndex = kSampler0SubjectIndex; + samplerIndex < kSamplerMaxSubjectIndex; ++samplerIndex) + { + mSamplerObserverBindings.emplace_back(this, samplerIndex); + } + + for (angle::SubjectIndex imageIndex = kImage0SubjectIndex; imageIndex < kImageMaxSubjectIndex; + ++imageIndex) + { + mImageObserverBindings.emplace_back(this, imageIndex); + } + + // Implementations now require the display to be set at context creation. + ASSERT(mDisplay); +} + +egl::Error Context::initialize() +{ + if (!mImplementation) + return egl::Error(EGL_NOT_INITIALIZED, "native context creation failed"); + return egl::NoError(); +} + +void Context::initializeDefaultResources() +{ + mImplementation->setMemoryProgramCache(mMemoryProgramCache); + + initCaps(); + + mState.initialize(this); + + mDefaultFramebuffer = std::make_unique(this, mImplementation.get()); + + mFenceNVHandleAllocator.setBaseHandle(0); + + // [OpenGL ES 2.0.24] section 3.7 page 83: + // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have two-dimensional + // and cube map texture state vectors respectively associated with them. + // In order that access to these initial textures not be lost, they are treated as texture + // objects all of whose names are 0. + + Texture *zeroTexture2D = new Texture(mImplementation.get(), {0}, TextureType::_2D); + mZeroTextures[TextureType::_2D].set(this, zeroTexture2D); + + Texture *zeroTextureCube = new Texture(mImplementation.get(), {0}, TextureType::CubeMap); + mZeroTextures[TextureType::CubeMap].set(this, zeroTextureCube); + + if (getClientVersion() >= Version(3, 0) || mSupportedExtensions.texture3DOES) + { + Texture *zeroTexture3D = new Texture(mImplementation.get(), {0}, TextureType::_3D); + mZeroTextures[TextureType::_3D].set(this, zeroTexture3D); + } + if (getClientVersion() >= Version(3, 0)) + { + Texture *zeroTexture2DArray = + new Texture(mImplementation.get(), {0}, TextureType::_2DArray); + mZeroTextures[TextureType::_2DArray].set(this, zeroTexture2DArray); + } + if (getClientVersion() >= Version(3, 1) || mSupportedExtensions.textureMultisampleANGLE) + { + Texture *zeroTexture2DMultisample = + new Texture(mImplementation.get(), {0}, TextureType::_2DMultisample); + mZeroTextures[TextureType::_2DMultisample].set(this, zeroTexture2DMultisample); + } + if (getClientVersion() >= Version(3, 1)) + { + Texture *zeroTexture2DMultisampleArray = + new Texture(mImplementation.get(), {0}, TextureType::_2DMultisampleArray); + mZeroTextures[TextureType::_2DMultisampleArray].set(this, zeroTexture2DMultisampleArray); + + for (int i = 0; i < mState.mCaps.maxAtomicCounterBufferBindings; i++) + { + bindBufferRange(BufferBinding::AtomicCounter, i, {0}, 0, 0); + } + + for (int i = 0; i < mState.mCaps.maxShaderStorageBufferBindings; i++) + { + bindBufferRange(BufferBinding::ShaderStorage, i, {0}, 0, 0); + } + } + + if ((getClientType() != EGL_OPENGL_API && getClientVersion() >= Version(3, 2)) || + mSupportedExtensions.textureCubeMapArrayAny()) + { + Texture *zeroTextureCubeMapArray = + new Texture(mImplementation.get(), {0}, TextureType::CubeMapArray); + mZeroTextures[TextureType::CubeMapArray].set(this, zeroTextureCubeMapArray); + } + + if ((getClientType() != EGL_OPENGL_API && getClientVersion() >= Version(3, 2)) || + mSupportedExtensions.textureBufferAny()) + { + Texture *zeroTextureBuffer = new Texture(mImplementation.get(), {0}, TextureType::Buffer); + mZeroTextures[TextureType::Buffer].set(this, zeroTextureBuffer); + } + + if (mSupportedExtensions.textureRectangleANGLE) + { + Texture *zeroTextureRectangle = + new Texture(mImplementation.get(), {0}, TextureType::Rectangle); + mZeroTextures[TextureType::Rectangle].set(this, zeroTextureRectangle); + } + + if (mSupportedExtensions.EGLImageExternalOES || + mSupportedExtensions.EGLStreamConsumerExternalNV) + { + Texture *zeroTextureExternal = + new Texture(mImplementation.get(), {0}, TextureType::External); + mZeroTextures[TextureType::External].set(this, zeroTextureExternal); + } + + // This may change native TEXTURE_2D, TEXTURE_EXTERNAL_OES and TEXTURE_RECTANGLE, + // binding states. Ensure state manager is aware of this when binding + // this texture type. + if (mSupportedExtensions.videoTextureWEBGL) + { + Texture *zeroTextureVideoImage = + new Texture(mImplementation.get(), {0}, TextureType::VideoImage); + mZeroTextures[TextureType::VideoImage].set(this, zeroTextureVideoImage); + } + + mState.initializeZeroTextures(this, mZeroTextures); + + ANGLE_CONTEXT_TRY(mImplementation->initialize()); + + // Add context into the share group + mState.getShareGroup()->addSharedContext(this); + + bindVertexArray({0}); + + if (getClientVersion() >= Version(3, 0)) + { + // [OpenGL ES 3.0.2] section 2.14.1 pg 85: + // In the initial state, a default transform feedback object is bound and treated as + // a transform feedback object with a name of zero. That object is bound any time + // BindTransformFeedback is called with id of zero + bindTransformFeedback(GL_TRANSFORM_FEEDBACK, {0}); + } + + for (auto type : angle::AllEnums()) + { + bindBuffer(type, {0}); + } + + bindRenderbuffer(GL_RENDERBUFFER, {0}); + + for (int i = 0; i < mState.mCaps.maxUniformBufferBindings; i++) + { + bindBufferRange(BufferBinding::Uniform, i, {0}, 0, -1); + } + + // Initialize GLES1 renderer if appropriate. + if (getClientVersion() < Version(2, 0)) + { + mGLES1Renderer.reset(new GLES1Renderer()); + } + + // Initialize dirty bit masks + mAllDirtyBits.set(); + + mDrawDirtyObjects.set(State::DIRTY_OBJECT_ACTIVE_TEXTURES); + mDrawDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER); + mDrawDirtyObjects.set(State::DIRTY_OBJECT_VERTEX_ARRAY); + mDrawDirtyObjects.set(State::DIRTY_OBJECT_TEXTURES); + mDrawDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM); + mDrawDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM_PIPELINE_OBJECT); + mDrawDirtyObjects.set(State::DIRTY_OBJECT_SAMPLERS); + mDrawDirtyObjects.set(State::DIRTY_OBJECT_IMAGES); + + mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_STATE); + mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING); + mTexImageDirtyBits.set(State::DIRTY_BIT_EXTENDED); + // No dirty objects. + + // Readpixels uses the pack state and read FBO + mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_STATE); + mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING); + mReadPixelsDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING); + mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER); + + mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED); + mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED); + mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR); + mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT); + mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR); + mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH); + mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL); + mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK); + mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK); + mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT); + mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK); + mClearDirtyBits.set(State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING); + mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER); + + // We sync the draw Framebuffer manually in prepareForClear to allow the clear calls to do + // more custom handling for robust resource init. + + mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED); + mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR); + mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE); + mBlitDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING); + mBlitDirtyBits.set(State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING); + mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER); + mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER); + + mComputeDirtyBits.set(State::DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING); + mComputeDirtyBits.set(State::DIRTY_BIT_UNIFORM_BUFFER_BINDINGS); + mComputeDirtyBits.set(State::DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING); + mComputeDirtyBits.set(State::DIRTY_BIT_PROGRAM_BINDING); + mComputeDirtyBits.set(State::DIRTY_BIT_PROGRAM_EXECUTABLE); + mComputeDirtyBits.set(State::DIRTY_BIT_TEXTURE_BINDINGS); + mComputeDirtyBits.set(State::DIRTY_BIT_SAMPLER_BINDINGS); + mComputeDirtyBits.set(State::DIRTY_BIT_IMAGE_BINDINGS); + mComputeDirtyBits.set(State::DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING); + mComputeDirtyObjects.set(State::DIRTY_OBJECT_ACTIVE_TEXTURES); + mComputeDirtyObjects.set(State::DIRTY_OBJECT_TEXTURES); + mComputeDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM); + mComputeDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM_PIPELINE_OBJECT); + mComputeDirtyObjects.set(State::DIRTY_OBJECT_IMAGES); + mComputeDirtyObjects.set(State::DIRTY_OBJECT_SAMPLERS); + + mCopyImageDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING); + mCopyImageDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER); + + mReadInvalidateDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING); + mDrawInvalidateDirtyBits.set(State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING); + + mOverlay.init(); +} + +egl::Error Context::onDestroy(const egl::Display *display) +{ + if (!mHasBeenCurrent) + { + // The context is never current, so default resources are not allocated. + return egl::NoError(); + } + + // eglDestoryContext() must have been called for this Context and there must not be any Threads + // that still have it current. + ASSERT(mIsDestroyed == true && mRefCount == 0); + + // Dump frame capture if enabled. + getShareGroup()->getFrameCaptureShared()->onDestroyContext(this); + + // Remove context from the capture share group + getShareGroup()->removeSharedContext(this); + + if (mGLES1Renderer) + { + mGLES1Renderer->onDestroy(this, &mState); + } + + ANGLE_TRY(unMakeCurrent(display)); + + mDefaultFramebuffer->onDestroy(this); + mDefaultFramebuffer.reset(); + + for (auto fence : mFenceNVMap) + { + if (fence.second) + { + fence.second->onDestroy(this); + } + SafeDelete(fence.second); + } + mFenceNVMap.clear(); + + for (auto query : mQueryMap) + { + if (query.second != nullptr) + { + query.second->release(this); + } + } + mQueryMap.clear(); + + for (auto vertexArray : mVertexArrayMap) + { + if (vertexArray.second) + { + vertexArray.second->onDestroy(this); + } + } + mVertexArrayMap.clear(); + + for (auto transformFeedback : mTransformFeedbackMap) + { + if (transformFeedback.second != nullptr) + { + transformFeedback.second->release(this); + } + } + mTransformFeedbackMap.clear(); + + for (BindingPointer &zeroTexture : mZeroTextures) + { + if (zeroTexture.get() != nullptr) + { + zeroTexture.set(this, nullptr); + } + } + + releaseShaderCompiler(); + + mState.reset(this); + + mState.mBufferManager->release(this); + // mProgramPipelineManager must be before mShaderProgramManager to give each + // PPO the chance to release any references they have to the Programs that + // are bound to them before the Programs are released()'ed. + mState.mProgramPipelineManager->release(this); + mState.mShaderProgramManager->release(this); + mState.mTextureManager->release(this); + mState.mRenderbufferManager->release(this); + mState.mSamplerManager->release(this); + mState.mSyncManager->release(this); + mState.mFramebufferManager->release(this); + mState.mMemoryObjectManager->release(this); + mState.mSemaphoreManager->release(this); + + mSingleThreadPool.reset(); + mMultiThreadPool.reset(); + + mImplementation->onDestroy(this); + + // Backend requires implementation to be destroyed first to close down all the objects + mState.mShareGroup->release(display); + + mOverlay.destroy(this); + + return egl::NoError(); +} + +Context::~Context() {} + +void Context::setLabel(EGLLabelKHR label) +{ + mLabel = label; +} + +EGLLabelKHR Context::getLabel() const +{ + return mLabel; +} + +egl::Error Context::makeCurrent(egl::Display *display, + egl::Surface *drawSurface, + egl::Surface *readSurface) +{ + mDisplay = display; + + if (!mHasBeenCurrent) + { + initializeDefaultResources(); + initRendererString(); + initVersionStrings(); + initExtensionStrings(); + + int width = 0; + int height = 0; + if (drawSurface != nullptr) + { + width = drawSurface->getWidth(); + height = drawSurface->getHeight(); + } + + mState.setViewportParams(0, 0, width, height); + mState.setScissorParams(0, 0, width, height); + + mHasBeenCurrent = true; + } + + ANGLE_TRY(unsetDefaultFramebuffer()); + + getShareGroup()->getFrameCaptureShared()->onMakeCurrent(this, drawSurface); + + // TODO(jmadill): Rework this when we support ContextImpl + mState.setAllDirtyBits(); + mState.setAllDirtyObjects(); + + ANGLE_TRY(setDefaultFramebuffer(drawSurface, readSurface)); + + // Notify the renderer of a context switch. + angle::Result implResult = mImplementation->onMakeCurrent(this); + + // If the implementation fails onMakeCurrent, unset the default framebuffer. + if (implResult != angle::Result::Continue) + { + ANGLE_TRY(unsetDefaultFramebuffer()); + return angle::ResultToEGL(implResult); + } + + return egl::NoError(); +} + +egl::Error Context::unMakeCurrent(const egl::Display *display) +{ + ANGLE_TRY(angle::ResultToEGL(mImplementation->onUnMakeCurrent(this))); + + ANGLE_TRY(unsetDefaultFramebuffer()); + + // Return the scratch buffers to the display so they can be shared with other contexts while + // this one is not current. + if (mScratchBuffer.valid()) + { + mDisplay->returnScratchBuffer(mScratchBuffer.release()); + } + if (mZeroFilledBuffer.valid()) + { + mDisplay->returnZeroFilledBuffer(mZeroFilledBuffer.release()); + } + + return egl::NoError(); +} + +BufferID Context::createBuffer() +{ + return mState.mBufferManager->createBuffer(); +} + +GLuint Context::createProgram() +{ + return mState.mShaderProgramManager->createProgram(mImplementation.get()).value; +} + +GLuint Context::createShader(ShaderType type) +{ + return mState.mShaderProgramManager + ->createShader(mImplementation.get(), mState.mLimitations, type) + .value; +} + +TextureID Context::createTexture() +{ + return mState.mTextureManager->createTexture(); +} + +RenderbufferID Context::createRenderbuffer() +{ + return mState.mRenderbufferManager->createRenderbuffer(); +} + +// Returns an unused framebuffer name +FramebufferID Context::createFramebuffer() +{ + return mState.mFramebufferManager->createFramebuffer(); +} + +void Context::genFencesNV(GLsizei n, FenceNVID *fences) +{ + for (int i = 0; i < n; i++) + { + GLuint handle = mFenceNVHandleAllocator.allocate(); + mFenceNVMap.assign({handle}, new FenceNV(mImplementation.get())); + fences[i] = {handle}; + } +} + +ProgramPipelineID Context::createProgramPipeline() +{ + return mState.mProgramPipelineManager->createProgramPipeline(); +} + +GLuint Context::createShaderProgramv(ShaderType type, GLsizei count, const GLchar *const *strings) +{ + const ShaderProgramID shaderID = PackParam(createShader(type)); + if (shaderID.value) + { + Shader *shaderObject = getShader(shaderID); + ASSERT(shaderObject); + shaderObject->setSource(count, strings, nullptr); + shaderObject->compile(this); + const ShaderProgramID programID = PackParam(createProgram()); + if (programID.value) + { + gl::Program *programObject = getProgramNoResolveLink(programID); + ASSERT(programObject); + + if (shaderObject->isCompiled(this)) + { + // As per Khronos issue 2261: + // https://gitlab.khronos.org/Tracker/vk-gl-cts/issues/2261 + // We must wait to mark the program separable until it's successfully compiled. + programObject->setSeparable(true); + + programObject->attachShader(shaderObject); + + if (programObject->link(this) != angle::Result::Continue) + { + deleteShader(shaderID); + deleteProgram(programID); + return 0u; + } + if (onProgramLink(programObject) != angle::Result::Continue) + { + deleteShader(shaderID); + deleteProgram(programID); + return 0u; + } + + programObject->detachShader(this, shaderObject); + } + + InfoLog &programInfoLog = programObject->getExecutable().getInfoLog(); + programInfoLog << shaderObject->getInfoLogString(); + } + + deleteShader(shaderID); + + return programID.value; + } + + return 0u; +} + +MemoryObjectID Context::createMemoryObject() +{ + return mState.mMemoryObjectManager->createMemoryObject(mImplementation.get()); +} + +SemaphoreID Context::createSemaphore() +{ + return mState.mSemaphoreManager->createSemaphore(mImplementation.get()); +} + +void Context::deleteBuffer(BufferID bufferName) +{ + Buffer *buffer = mState.mBufferManager->getBuffer(bufferName); + if (buffer) + { + detachBuffer(buffer); + } + + mState.mBufferManager->deleteObject(this, bufferName); +} + +void Context::deleteShader(ShaderProgramID shader) +{ + mState.mShaderProgramManager->deleteShader(this, shader); +} + +void Context::deleteProgram(ShaderProgramID program) +{ + mState.mShaderProgramManager->deleteProgram(this, program); +} + +void Context::deleteTexture(TextureID texture) +{ + if (mState.mTextureManager->getTexture(texture)) + { + detachTexture(texture); + } + + mState.mTextureManager->deleteObject(this, texture); +} + +void Context::deleteRenderbuffer(RenderbufferID renderbuffer) +{ + if (mState.mRenderbufferManager->getRenderbuffer(renderbuffer)) + { + detachRenderbuffer(renderbuffer); + } + + mState.mRenderbufferManager->deleteObject(this, renderbuffer); +} + +void Context::deleteSync(GLsync sync) +{ + // The spec specifies the underlying Fence object is not deleted until all current + // wait commands finish. However, since the name becomes invalid, we cannot query the fence, + // and since our API is currently designed for being called from a single thread, we can delete + // the fence immediately. + mState.mSyncManager->deleteObject(this, static_cast(reinterpret_cast(sync))); +} + +void Context::deleteProgramPipeline(ProgramPipelineID pipelineID) +{ + ProgramPipeline *pipeline = mState.mProgramPipelineManager->getProgramPipeline(pipelineID); + if (pipeline) + { + detachProgramPipeline(pipelineID); + } + + mState.mProgramPipelineManager->deleteObject(this, pipelineID); +} + +void Context::deleteMemoryObject(MemoryObjectID memoryObject) +{ + mState.mMemoryObjectManager->deleteMemoryObject(this, memoryObject); +} + +void Context::deleteSemaphore(SemaphoreID semaphore) +{ + mState.mSemaphoreManager->deleteSemaphore(this, semaphore); +} + +// GL_CHROMIUM_lose_context +void Context::loseContext(GraphicsResetStatus current, GraphicsResetStatus other) +{ + // TODO(geofflang): mark the rest of the share group lost. Requires access to the entire share + // group from a context. http://anglebug.com/3379 + markContextLost(current); +} + +void Context::deleteFramebuffer(FramebufferID framebufferID) +{ + // We are responsible for deleting the GL objects from the Framebuffer's pixel local storage. + std::unique_ptr plsToDelete; + + Framebuffer *framebuffer = mState.mFramebufferManager->getFramebuffer(framebufferID); + if (framebuffer) + { + plsToDelete = framebuffer->detachPixelLocalStorage(); + detachFramebuffer(framebufferID); + } + + mState.mFramebufferManager->deleteObject(this, framebufferID); + + // Delete the pixel local storage GL objects after the framebuffer, in order to avoid any + // potential trickyness with orphaning. + if (plsToDelete) + { + plsToDelete->deleteContextObjects(this); + } +} + +void Context::deleteFencesNV(GLsizei n, const FenceNVID *fences) +{ + for (int i = 0; i < n; i++) + { + FenceNVID fence = fences[i]; + + FenceNV *fenceObject = nullptr; + if (mFenceNVMap.erase(fence, &fenceObject)) + { + mFenceNVHandleAllocator.release(fence.value); + if (fenceObject) + { + fenceObject->onDestroy(this); + } + delete fenceObject; + } + } +} + +Buffer *Context::getBuffer(BufferID handle) const +{ + return mState.mBufferManager->getBuffer(handle); +} + +Renderbuffer *Context::getRenderbuffer(RenderbufferID handle) const +{ + return mState.mRenderbufferManager->getRenderbuffer(handle); +} + +EGLenum Context::getContextPriority() const +{ + return egl::ToEGLenum(mImplementation->getContextPriority()); +} + +Sync *Context::getSync(GLsync handle) const +{ + return mState.mSyncManager->getSync(static_cast(reinterpret_cast(handle))); +} + +VertexArray *Context::getVertexArray(VertexArrayID handle) const +{ + return mVertexArrayMap.query(handle); +} + +Sampler *Context::getSampler(SamplerID handle) const +{ + return mState.mSamplerManager->getSampler(handle); +} + +TransformFeedback *Context::getTransformFeedback(TransformFeedbackID handle) const +{ + return mTransformFeedbackMap.query(handle); +} + +ProgramPipeline *Context::getProgramPipeline(ProgramPipelineID handle) const +{ + return mState.mProgramPipelineManager->getProgramPipeline(handle); +} + +gl::LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const +{ + switch (identifier) + { + case GL_BUFFER: + case GL_BUFFER_OBJECT_EXT: + return getBuffer({name}); + case GL_SHADER: + case GL_SHADER_OBJECT_EXT: + return getShader({name}); + case GL_PROGRAM: + case GL_PROGRAM_OBJECT_EXT: + return getProgramNoResolveLink({name}); + case GL_VERTEX_ARRAY: + case GL_VERTEX_ARRAY_OBJECT_EXT: + return getVertexArray({name}); + case GL_QUERY: + case GL_QUERY_OBJECT_EXT: + return getQuery({name}); + case GL_TRANSFORM_FEEDBACK: + return getTransformFeedback({name}); + case GL_SAMPLER: + return getSampler({name}); + case GL_TEXTURE: + return getTexture({name}); + case GL_RENDERBUFFER: + return getRenderbuffer({name}); + case GL_FRAMEBUFFER: + return getFramebuffer({name}); + case GL_PROGRAM_PIPELINE: + case GL_PROGRAM_PIPELINE_OBJECT_EXT: + return getProgramPipeline({name}); + default: + UNREACHABLE(); + return nullptr; + } +} + +gl::LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const +{ + return getSync(reinterpret_cast(const_cast(ptr))); +} + +void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label) +{ + gl::LabeledObject *object = getLabeledObject(identifier, name); + ASSERT(object != nullptr); + + std::string labelName = GetObjectLabelFromPointer(length, label); + ANGLE_CONTEXT_TRY(object->setLabel(this, labelName)); + + // TODO(jmadill): Determine if the object is dirty based on 'name'. Conservatively assume the + // specified object is active until we do this. + mState.setObjectDirty(identifier); +} + +void Context::labelObject(GLenum type, GLuint object, GLsizei length, const GLchar *label) +{ + gl::LabeledObject *obj = getLabeledObject(type, object); + ASSERT(obj != nullptr); + + std::string labelName = ""; + if (label != nullptr) + { + size_t labelLength = length == 0 ? strlen(label) : length; + labelName = std::string(label, labelLength); + } + ANGLE_CONTEXT_TRY(obj->setLabel(this, labelName)); + mState.setObjectDirty(type); +} + +void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label) +{ + gl::LabeledObject *object = getLabeledObjectFromPtr(ptr); + ASSERT(object != nullptr); + + std::string labelName = GetObjectLabelFromPointer(length, label); + ANGLE_CONTEXT_TRY(object->setLabel(this, labelName)); +} + +void Context::getObjectLabel(GLenum identifier, + GLuint name, + GLsizei bufSize, + GLsizei *length, + GLchar *label) +{ + gl::LabeledObject *object = getLabeledObject(identifier, name); + ASSERT(object != nullptr); + + const std::string &objectLabel = object->getLabel(); + GetObjectLabelBase(objectLabel, bufSize, length, label); +} + +void Context::getObjectPtrLabel(const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label) +{ + gl::LabeledObject *object = getLabeledObjectFromPtr(ptr); + ASSERT(object != nullptr); + + const std::string &objectLabel = object->getLabel(); + GetObjectLabelBase(objectLabel, bufSize, length, label); +} + +GLboolean Context::isSampler(SamplerID samplerName) const +{ + return mState.mSamplerManager->isSampler(samplerName); +} + +void Context::bindTexture(TextureType target, TextureID handle) +{ + // Some apps enable KHR_create_context_no_error but pass in an invalid texture type. + // Workaround this by silently returning in such situations. + if (target == TextureType::InvalidEnum) + { + return; + } + + Texture *texture = nullptr; + if (handle.value == 0) + { + texture = mZeroTextures[target].get(); + } + else + { + texture = + mState.mTextureManager->checkTextureAllocation(mImplementation.get(), handle, target); + } + + ASSERT(texture); + // Early return if rebinding the same texture + if (texture == mState.getTargetTexture(target)) + { + return; + } + + mState.setSamplerTexture(this, target, texture); + mStateCache.onActiveTextureChange(this); +} + +void Context::bindReadFramebuffer(FramebufferID framebufferHandle) +{ + Framebuffer *framebuffer = mState.mFramebufferManager->checkFramebufferAllocation( + mImplementation.get(), this, framebufferHandle); + mState.setReadFramebufferBinding(framebuffer); + mReadFramebufferObserverBinding.bind(framebuffer); +} + +void Context::bindDrawFramebuffer(FramebufferID framebufferHandle) +{ + Framebuffer *framebuffer = mState.mFramebufferManager->checkFramebufferAllocation( + mImplementation.get(), this, framebufferHandle); + mState.setDrawFramebufferBinding(framebuffer); + mDrawFramebufferObserverBinding.bind(framebuffer); + mStateCache.onDrawFramebufferChange(this); +} + +void Context::bindVertexArray(VertexArrayID vertexArrayHandle) +{ + VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle); + mState.setVertexArrayBinding(this, vertexArray); + mVertexArrayObserverBinding.bind(vertexArray); + mStateCache.onVertexArrayBindingChange(this); +} + +void Context::bindVertexBuffer(GLuint bindingIndex, + BufferID bufferHandle, + GLintptr offset, + GLsizei stride) +{ + Buffer *buffer = + mState.mBufferManager->checkBufferAllocation(mImplementation.get(), bufferHandle); + mState.bindVertexBuffer(this, bindingIndex, buffer, offset, stride); + mStateCache.onVertexArrayStateChange(this); +} + +void Context::bindSampler(GLuint textureUnit, SamplerID samplerHandle) +{ + ASSERT(textureUnit < static_cast(mState.mCaps.maxCombinedTextureImageUnits)); + Sampler *sampler = + mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), samplerHandle); + + // Early return if rebinding the same sampler + if (sampler == mState.getSampler(textureUnit)) + { + return; + } + + mState.setSamplerBinding(this, textureUnit, sampler); + mSamplerObserverBindings[textureUnit].bind(sampler); + mStateCache.onActiveTextureChange(this); +} + +void Context::bindImageTexture(GLuint unit, + TextureID texture, + GLint level, + GLboolean layered, + GLint layer, + GLenum access, + GLenum format) +{ + Texture *tex = mState.mTextureManager->getTexture(texture); + mState.setImageUnit(this, unit, tex, level, layered, layer, access, format); + mImageObserverBindings[unit].bind(tex); +} + +void Context::useProgram(ShaderProgramID program) +{ + ANGLE_CONTEXT_TRY(mState.setProgram(this, getProgramResolveLink(program))); + mStateCache.onProgramExecutableChange(this); +} + +void Context::useProgramStages(ProgramPipelineID pipeline, + GLbitfield stages, + ShaderProgramID program) +{ + Program *shaderProgram = getProgramNoResolveLink(program); + ProgramPipeline *programPipeline = + mState.mProgramPipelineManager->checkProgramPipelineAllocation(mImplementation.get(), + pipeline); + + ASSERT(programPipeline); + ANGLE_CONTEXT_TRY(programPipeline->useProgramStages(this, stages, shaderProgram)); +} + +void Context::bindTransformFeedback(GLenum target, TransformFeedbackID transformFeedbackHandle) +{ + ASSERT(target == GL_TRANSFORM_FEEDBACK); + TransformFeedback *transformFeedback = + checkTransformFeedbackAllocation(transformFeedbackHandle); + mState.setTransformFeedbackBinding(this, transformFeedback); + mStateCache.onActiveTransformFeedbackChange(this); +} + +void Context::bindProgramPipeline(ProgramPipelineID pipelineHandle) +{ + ProgramPipeline *pipeline = mState.mProgramPipelineManager->checkProgramPipelineAllocation( + mImplementation.get(), pipelineHandle); + ANGLE_CONTEXT_TRY(mState.setProgramPipelineBinding(this, pipeline)); + mStateCache.onProgramExecutableChange(this); + mProgramPipelineObserverBinding.bind(pipeline); +} + +void Context::beginQuery(QueryType target, QueryID query) +{ + Query *queryObject = getOrCreateQuery(query, target); + ASSERT(queryObject); + + // begin query + ANGLE_CONTEXT_TRY(queryObject->begin(this)); + + // set query as active for specified target only if begin succeeded + mState.setActiveQuery(this, target, queryObject); + mStateCache.onQueryChange(this); +} + +void Context::endQuery(QueryType target) +{ + Query *queryObject = mState.getActiveQuery(target); + ASSERT(queryObject); + + // Intentionally don't call try here. We don't want an early return. + (void)(queryObject->end(this)); + + // Always unbind the query, even if there was an error. This may delete the query object. + mState.setActiveQuery(this, target, nullptr); + mStateCache.onQueryChange(this); +} + +void Context::queryCounter(QueryID id, QueryType target) +{ + ASSERT(target == QueryType::Timestamp); + + Query *queryObject = getOrCreateQuery(id, target); + ASSERT(queryObject); + + ANGLE_CONTEXT_TRY(queryObject->queryCounter(this)); +} + +void Context::getQueryiv(QueryType target, GLenum pname, GLint *params) +{ + switch (pname) + { + case GL_CURRENT_QUERY_EXT: + params[0] = mState.getActiveQueryId(target).value; + break; + case GL_QUERY_COUNTER_BITS_EXT: + switch (target) + { + case QueryType::TimeElapsed: + params[0] = getCaps().queryCounterBitsTimeElapsed; + break; + case QueryType::Timestamp: + params[0] = getCaps().queryCounterBitsTimestamp; + break; + default: + UNREACHABLE(); + params[0] = 0; + break; + } + break; + default: + UNREACHABLE(); + return; + } +} + +void Context::getQueryivRobust(QueryType target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + getQueryiv(target, pname, params); +} + +void Context::getUnsignedBytev(GLenum pname, GLubyte *data) +{ + UNIMPLEMENTED(); +} + +void Context::getUnsignedBytei_v(GLenum target, GLuint index, GLubyte *data) +{ + UNIMPLEMENTED(); +} + +void Context::getQueryObjectiv(QueryID id, GLenum pname, GLint *params) +{ + ANGLE_CONTEXT_TRY(GetQueryObjectParameter(this, getQuery(id), pname, params)); +} + +void Context::getQueryObjectivRobust(QueryID id, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + getQueryObjectiv(id, pname, params); +} + +void Context::getQueryObjectuiv(QueryID id, GLenum pname, GLuint *params) +{ + ANGLE_CONTEXT_TRY(GetQueryObjectParameter(this, getQuery(id), pname, params)); +} + +void Context::getQueryObjectuivRobust(QueryID id, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params) +{ + getQueryObjectuiv(id, pname, params); +} + +void Context::getQueryObjecti64v(QueryID id, GLenum pname, GLint64 *params) +{ + ANGLE_CONTEXT_TRY(GetQueryObjectParameter(this, getQuery(id), pname, params)); +} + +void Context::getQueryObjecti64vRobust(QueryID id, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint64 *params) +{ + getQueryObjecti64v(id, pname, params); +} + +void Context::getQueryObjectui64v(QueryID id, GLenum pname, GLuint64 *params) +{ + ANGLE_CONTEXT_TRY(GetQueryObjectParameter(this, getQuery(id), pname, params)); +} + +void Context::getQueryObjectui64vRobust(QueryID id, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint64 *params) +{ + getQueryObjectui64v(id, pname, params); +} + +Framebuffer *Context::getFramebuffer(FramebufferID handle) const +{ + return mState.mFramebufferManager->getFramebuffer(handle); +} + +FenceNV *Context::getFenceNV(FenceNVID handle) const +{ + return mFenceNVMap.query(handle); +} + +Query *Context::getOrCreateQuery(QueryID handle, QueryType type) +{ + if (!mQueryMap.contains(handle)) + { + return nullptr; + } + + Query *query = mQueryMap.query(handle); + if (!query) + { + ASSERT(type != QueryType::InvalidEnum); + query = new Query(mImplementation.get(), type, handle); + query->addRef(); + mQueryMap.assign(handle, query); + } + return query; +} + +Query *Context::getQuery(QueryID handle) const +{ + return mQueryMap.query(handle); +} + +Texture *Context::getTextureByType(TextureType type) const +{ + ASSERT(ValidTextureTarget(this, type) || ValidTextureExternalTarget(this, type)); + return mState.getTargetTexture(type); +} + +Texture *Context::getTextureByTarget(TextureTarget target) const +{ + return getTextureByType(TextureTargetToType(target)); +} + +Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) const +{ + return mState.getSamplerTexture(sampler, type); +} + +Compiler *Context::getCompiler() const +{ + if (mCompiler.get() == nullptr) + { + mCompiler.set(this, new Compiler(mImplementation.get(), mState, mDisplay)); + } + return mCompiler.get(); +} + +void Context::getBooleanvImpl(GLenum pname, GLboolean *params) const +{ + switch (pname) + { + case GL_SHADER_COMPILER: + *params = GL_TRUE; + break; + case GL_CONTEXT_ROBUST_ACCESS_EXT: + *params = ConvertToGLBoolean(mState.hasRobustAccess()); + break; + + default: + mState.getBooleanv(pname, params); + break; + } +} + +void Context::getFloatvImpl(GLenum pname, GLfloat *params) const +{ + // Queries about context capabilities and maximums are answered by Context. + // Queries about current GL state values are answered by State. + switch (pname) + { + case GL_ALIASED_LINE_WIDTH_RANGE: + params[0] = mState.mCaps.minAliasedLineWidth; + params[1] = mState.mCaps.maxAliasedLineWidth; + break; + case GL_ALIASED_POINT_SIZE_RANGE: + params[0] = mState.mCaps.minAliasedPointSize; + params[1] = mState.mCaps.maxAliasedPointSize; + break; + case GL_SMOOTH_POINT_SIZE_RANGE: + params[0] = mState.mCaps.minSmoothPointSize; + params[1] = mState.mCaps.maxSmoothPointSize; + break; + case GL_SMOOTH_LINE_WIDTH_RANGE: + params[0] = mState.mCaps.minSmoothLineWidth; + params[1] = mState.mCaps.maxSmoothLineWidth; + break; + case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: + ASSERT(mState.mExtensions.textureFilterAnisotropicEXT); + *params = mState.mCaps.maxTextureAnisotropy; + break; + case GL_MAX_TEXTURE_LOD_BIAS: + *params = mState.mCaps.maxLODBias; + break; + case GL_MIN_FRAGMENT_INTERPOLATION_OFFSET: + *params = mState.mCaps.minInterpolationOffset; + break; + case GL_MAX_FRAGMENT_INTERPOLATION_OFFSET: + *params = mState.mCaps.maxInterpolationOffset; + break; + case GL_PRIMITIVE_BOUNDING_BOX: + params[0] = mState.mBoundingBoxMinX; + params[1] = mState.mBoundingBoxMinY; + params[2] = mState.mBoundingBoxMinZ; + params[3] = mState.mBoundingBoxMinW; + params[4] = mState.mBoundingBoxMaxX; + params[5] = mState.mBoundingBoxMaxY; + params[6] = mState.mBoundingBoxMaxZ; + params[7] = mState.mBoundingBoxMaxW; + break; + default: + mState.getFloatv(pname, params); + break; + } +} + +void Context::getIntegervImpl(GLenum pname, GLint *params) const +{ + // Queries about context capabilities and maximums are answered by Context. + // Queries about current GL state values are answered by State. + + switch (pname) + { + case GL_MAX_VERTEX_ATTRIBS: + *params = mState.mCaps.maxVertexAttributes; + break; + case GL_MAX_VERTEX_UNIFORM_VECTORS: + *params = mState.mCaps.maxVertexUniformVectors; + break; + case GL_MAX_VERTEX_UNIFORM_COMPONENTS: + *params = mState.mCaps.maxShaderUniformComponents[ShaderType::Vertex]; + break; + case GL_MAX_VARYING_VECTORS: + *params = mState.mCaps.maxVaryingVectors; + break; + case GL_MAX_VARYING_COMPONENTS: + *params = mState.mCaps.maxVaryingVectors * 4; + break; + case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: + *params = mState.mCaps.maxCombinedTextureImageUnits; + break; + case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: + *params = mState.mCaps.maxShaderTextureImageUnits[ShaderType::Vertex]; + break; + case GL_MAX_TEXTURE_IMAGE_UNITS: + *params = mState.mCaps.maxShaderTextureImageUnits[ShaderType::Fragment]; + break; + case GL_MAX_FRAGMENT_UNIFORM_VECTORS: + *params = mState.mCaps.maxFragmentUniformVectors; + break; + case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: + *params = mState.mCaps.maxShaderUniformComponents[ShaderType::Fragment]; + break; + case GL_MAX_RENDERBUFFER_SIZE: + *params = mState.mCaps.maxRenderbufferSize; + break; + case GL_MAX_COLOR_ATTACHMENTS_EXT: + *params = mState.mCaps.maxColorAttachments; + break; + case GL_MAX_DRAW_BUFFERS_EXT: + *params = mState.mCaps.maxDrawBuffers; + break; + case GL_SUBPIXEL_BITS: + *params = mState.mCaps.subPixelBits; + break; + case GL_MAX_TEXTURE_SIZE: + *params = mState.mCaps.max2DTextureSize; + break; + case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE: + *params = mState.mCaps.maxRectangleTextureSize; + break; + case GL_MAX_CUBE_MAP_TEXTURE_SIZE: + *params = mState.mCaps.maxCubeMapTextureSize; + break; + case GL_MAX_3D_TEXTURE_SIZE: + *params = mState.mCaps.max3DTextureSize; + break; + case GL_MAX_ARRAY_TEXTURE_LAYERS: + *params = mState.mCaps.maxArrayTextureLayers; + break; + case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: + *params = mState.mCaps.uniformBufferOffsetAlignment; + break; + case GL_MAX_UNIFORM_BUFFER_BINDINGS: + *params = mState.mCaps.maxUniformBufferBindings; + break; + case GL_MAX_VERTEX_UNIFORM_BLOCKS: + *params = mState.mCaps.maxShaderUniformBlocks[ShaderType::Vertex]; + break; + case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: + *params = mState.mCaps.maxShaderUniformBlocks[ShaderType::Fragment]; + break; + case GL_MAX_COMBINED_UNIFORM_BLOCKS: + *params = mState.mCaps.maxCombinedUniformBlocks; + break; + case GL_MAX_VERTEX_OUTPUT_COMPONENTS: + *params = mState.mCaps.maxVertexOutputComponents; + break; + case GL_MAX_FRAGMENT_INPUT_COMPONENTS: + *params = mState.mCaps.maxFragmentInputComponents; + break; + case GL_MIN_PROGRAM_TEXEL_OFFSET: + *params = mState.mCaps.minProgramTexelOffset; + break; + case GL_MAX_PROGRAM_TEXEL_OFFSET: + *params = mState.mCaps.maxProgramTexelOffset; + break; + case GL_MAJOR_VERSION: + *params = getClientVersion().major; + break; + case GL_MINOR_VERSION: + *params = getClientVersion().minor; + break; + case GL_MAX_ELEMENTS_INDICES: + *params = mState.mCaps.maxElementsIndices; + break; + case GL_MAX_ELEMENTS_VERTICES: + *params = mState.mCaps.maxElementsVertices; + break; + case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: + *params = mState.mCaps.maxTransformFeedbackInterleavedComponents; + break; + case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: + *params = mState.mCaps.maxTransformFeedbackSeparateAttributes; + break; + case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: + *params = mState.mCaps.maxTransformFeedbackSeparateComponents; + break; + case GL_NUM_COMPRESSED_TEXTURE_FORMATS: + *params = static_cast(mState.mCaps.compressedTextureFormats.size()); + break; + case GL_MAX_SAMPLES_ANGLE: + *params = mState.mCaps.maxSamples; + break; + case GL_MAX_VIEWPORT_DIMS: + { + params[0] = mState.mCaps.maxViewportWidth; + params[1] = mState.mCaps.maxViewportHeight; + } + break; + case GL_COMPRESSED_TEXTURE_FORMATS: + std::copy(mState.mCaps.compressedTextureFormats.begin(), + mState.mCaps.compressedTextureFormats.end(), params); + break; + case GL_RESET_NOTIFICATION_STRATEGY_EXT: + *params = mResetStrategy; + break; + case GL_NUM_SHADER_BINARY_FORMATS: + *params = static_cast(mState.mCaps.shaderBinaryFormats.size()); + break; + case GL_SHADER_BINARY_FORMATS: + std::copy(mState.mCaps.shaderBinaryFormats.begin(), + mState.mCaps.shaderBinaryFormats.end(), params); + break; + case GL_NUM_PROGRAM_BINARY_FORMATS: + *params = static_cast(mState.mCaps.programBinaryFormats.size()); + break; + case GL_PROGRAM_BINARY_FORMATS: + std::copy(mState.mCaps.programBinaryFormats.begin(), + mState.mCaps.programBinaryFormats.end(), params); + break; + case GL_NUM_EXTENSIONS: + *params = static_cast(mExtensionStrings.size()); + break; + + // Desktop client flags + case GL_CONTEXT_FLAGS: + { + GLint contextFlags = 0; + if (mState.hasProtectedContent()) + { + contextFlags |= GL_CONTEXT_FLAG_PROTECTED_CONTENT_BIT_EXT; + } + + if (mState.isDebugContext()) + { + contextFlags |= GL_CONTEXT_FLAG_DEBUG_BIT_KHR; + } + + if (mState.hasRobustAccess()) + { + contextFlags |= GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT; + } + *params = contextFlags; + } + break; + case GL_CONTEXT_PROFILE_MASK: + ASSERT(getClientType() == EGL_OPENGL_API); + *params = mState.getProfileMask(); + break; + + // GL_ANGLE_request_extension + case GL_NUM_REQUESTABLE_EXTENSIONS_ANGLE: + *params = static_cast(mRequestableExtensionStrings.size()); + break; + + // GL_KHR_debug + case GL_MAX_DEBUG_MESSAGE_LENGTH: + *params = mState.mCaps.maxDebugMessageLength; + break; + case GL_MAX_DEBUG_LOGGED_MESSAGES: + *params = mState.mCaps.maxDebugLoggedMessages; + break; + case GL_MAX_DEBUG_GROUP_STACK_DEPTH: + *params = mState.mCaps.maxDebugGroupStackDepth; + break; + case GL_MAX_LABEL_LENGTH: + *params = mState.mCaps.maxLabelLength; + break; + + // GL_OVR_multiview2 + case GL_MAX_VIEWS_OVR: + *params = mState.mCaps.maxViews; + break; + + // GL_EXT_disjoint_timer_query + case GL_GPU_DISJOINT_EXT: + *params = mImplementation->getGPUDisjoint(); + break; + case GL_MAX_FRAMEBUFFER_WIDTH: + *params = mState.mCaps.maxFramebufferWidth; + break; + case GL_MAX_FRAMEBUFFER_HEIGHT: + *params = mState.mCaps.maxFramebufferHeight; + break; + case GL_MAX_FRAMEBUFFER_SAMPLES: + *params = mState.mCaps.maxFramebufferSamples; + break; + case GL_MAX_SAMPLE_MASK_WORDS: + *params = mState.mCaps.maxSampleMaskWords; + break; + case GL_MAX_COLOR_TEXTURE_SAMPLES: + *params = mState.mCaps.maxColorTextureSamples; + break; + case GL_MAX_DEPTH_TEXTURE_SAMPLES: + *params = mState.mCaps.maxDepthTextureSamples; + break; + case GL_MAX_INTEGER_SAMPLES: + *params = mState.mCaps.maxIntegerSamples; + break; + case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET: + *params = mState.mCaps.maxVertexAttribRelativeOffset; + break; + case GL_MAX_VERTEX_ATTRIB_BINDINGS: + *params = mState.mCaps.maxVertexAttribBindings; + break; + case GL_MAX_VERTEX_ATTRIB_STRIDE: + *params = mState.mCaps.maxVertexAttribStride; + break; + case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS: + *params = mState.mCaps.maxShaderAtomicCounterBuffers[ShaderType::Vertex]; + break; + case GL_MAX_VERTEX_ATOMIC_COUNTERS: + *params = mState.mCaps.maxShaderAtomicCounters[ShaderType::Vertex]; + break; + case GL_MAX_VERTEX_IMAGE_UNIFORMS: + *params = mState.mCaps.maxShaderImageUniforms[ShaderType::Vertex]; + break; + case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS: + *params = mState.mCaps.maxShaderStorageBlocks[ShaderType::Vertex]; + break; + case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS: + *params = mState.mCaps.maxShaderAtomicCounterBuffers[ShaderType::Fragment]; + break; + case GL_MAX_FRAGMENT_ATOMIC_COUNTERS: + *params = mState.mCaps.maxShaderAtomicCounters[ShaderType::Fragment]; + break; + case GL_MAX_FRAGMENT_IMAGE_UNIFORMS: + *params = mState.mCaps.maxShaderImageUniforms[ShaderType::Fragment]; + break; + case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS: + *params = mState.mCaps.maxShaderStorageBlocks[ShaderType::Fragment]; + break; + case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET: + *params = mState.mCaps.minProgramTextureGatherOffset; + break; + case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET: + *params = mState.mCaps.maxProgramTextureGatherOffset; + break; + case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS: + *params = mState.mCaps.maxComputeWorkGroupInvocations; + break; + case GL_MAX_COMPUTE_UNIFORM_BLOCKS: + *params = mState.mCaps.maxShaderUniformBlocks[ShaderType::Compute]; + break; + case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS: + *params = mState.mCaps.maxShaderTextureImageUnits[ShaderType::Compute]; + break; + case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE: + *params = mState.mCaps.maxComputeSharedMemorySize; + break; + case GL_MAX_COMPUTE_UNIFORM_COMPONENTS: + *params = mState.mCaps.maxShaderUniformComponents[ShaderType::Compute]; + break; + case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS: + *params = mState.mCaps.maxShaderAtomicCounterBuffers[ShaderType::Compute]; + break; + case GL_MAX_COMPUTE_ATOMIC_COUNTERS: + *params = mState.mCaps.maxShaderAtomicCounters[ShaderType::Compute]; + break; + case GL_MAX_COMPUTE_IMAGE_UNIFORMS: + *params = mState.mCaps.maxShaderImageUniforms[ShaderType::Compute]; + break; + case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS: + *params = static_cast( + mState.mCaps.maxCombinedShaderUniformComponents[ShaderType::Compute]); + break; + case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS: + *params = mState.mCaps.maxShaderStorageBlocks[ShaderType::Compute]; + break; + case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES: + *params = mState.mCaps.maxCombinedShaderOutputResources; + break; + case GL_MAX_UNIFORM_LOCATIONS: + *params = mState.mCaps.maxUniformLocations; + break; + case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS: + *params = mState.mCaps.maxAtomicCounterBufferBindings; + break; + case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE: + *params = mState.mCaps.maxAtomicCounterBufferSize; + break; + case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS: + *params = mState.mCaps.maxCombinedAtomicCounterBuffers; + break; + case GL_MAX_COMBINED_ATOMIC_COUNTERS: + *params = mState.mCaps.maxCombinedAtomicCounters; + break; + case GL_MAX_IMAGE_UNITS: + *params = mState.mCaps.maxImageUnits; + break; + case GL_MAX_COMBINED_IMAGE_UNIFORMS: + *params = mState.mCaps.maxCombinedImageUniforms; + break; + case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS: + *params = mState.mCaps.maxShaderStorageBufferBindings; + break; + case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS: + *params = mState.mCaps.maxCombinedShaderStorageBlocks; + break; + case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT: + *params = mState.mCaps.shaderStorageBufferOffsetAlignment; + break; + + // GL_EXT_geometry_shader + case GL_MAX_FRAMEBUFFER_LAYERS_EXT: + *params = mState.mCaps.maxFramebufferLayers; + break; + case GL_LAYER_PROVOKING_VERTEX_EXT: + *params = mState.mCaps.layerProvokingVertex; + break; + case GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT: + *params = mState.mCaps.maxShaderUniformComponents[ShaderType::Geometry]; + break; + case GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT: + *params = mState.mCaps.maxShaderUniformBlocks[ShaderType::Geometry]; + break; + case GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT: + *params = static_cast( + mState.mCaps.maxCombinedShaderUniformComponents[ShaderType::Geometry]); + break; + case GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT: + *params = mState.mCaps.maxGeometryInputComponents; + break; + case GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT: + *params = mState.mCaps.maxGeometryOutputComponents; + break; + case GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT: + *params = mState.mCaps.maxGeometryOutputVertices; + break; + case GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT: + *params = mState.mCaps.maxGeometryTotalOutputComponents; + break; + case GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT: + *params = mState.mCaps.maxGeometryShaderInvocations; + break; + case GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT: + *params = mState.mCaps.maxShaderTextureImageUnits[ShaderType::Geometry]; + break; + case GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT: + *params = mState.mCaps.maxShaderAtomicCounterBuffers[ShaderType::Geometry]; + break; + case GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT: + *params = mState.mCaps.maxShaderAtomicCounters[ShaderType::Geometry]; + break; + case GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT: + *params = mState.mCaps.maxShaderImageUniforms[ShaderType::Geometry]; + break; + case GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT: + *params = mState.mCaps.maxShaderStorageBlocks[ShaderType::Geometry]; + break; + // GL_EXT_tessellation_shader + case GL_MAX_PATCH_VERTICES_EXT: + *params = mState.mCaps.maxPatchVertices; + break; + case GL_MAX_TESS_GEN_LEVEL_EXT: + *params = mState.mCaps.maxTessGenLevel; + break; + case GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_EXT: + *params = mState.mCaps.maxShaderUniformComponents[ShaderType::TessControl]; + break; + case GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT: + *params = mState.mCaps.maxShaderUniformComponents[ShaderType::TessEvaluation]; + break; + case GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_EXT: + *params = mState.mCaps.maxShaderTextureImageUnits[ShaderType::TessControl]; + break; + case GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_EXT: + *params = mState.mCaps.maxShaderTextureImageUnits[ShaderType::TessEvaluation]; + break; + case GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT: + *params = mState.mCaps.maxTessControlOutputComponents; + break; + case GL_MAX_TESS_PATCH_COMPONENTS_EXT: + *params = mState.mCaps.maxTessPatchComponents; + break; + case GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_EXT: + *params = mState.mCaps.maxTessControlTotalOutputComponents; + break; + case GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_EXT: + *params = mState.mCaps.maxTessEvaluationOutputComponents; + break; + case GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_EXT: + *params = mState.mCaps.maxShaderUniformBlocks[ShaderType::TessControl]; + break; + case GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_EXT: + *params = mState.mCaps.maxShaderUniformBlocks[ShaderType::TessEvaluation]; + break; + case GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT: + *params = mState.mCaps.maxTessControlInputComponents; + break; + case GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT: + *params = mState.mCaps.maxTessEvaluationInputComponents; + break; + case GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_EXT: + *params = static_cast( + mState.mCaps.maxCombinedShaderUniformComponents[ShaderType::TessControl]); + break; + case GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT: + *params = static_cast( + mState.mCaps.maxCombinedShaderUniformComponents[ShaderType::TessEvaluation]); + break; + case GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_EXT: + *params = mState.mCaps.maxShaderAtomicCounterBuffers[ShaderType::TessControl]; + break; + case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_EXT: + *params = mState.mCaps.maxShaderAtomicCounterBuffers[ShaderType::TessEvaluation]; + break; + case GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_EXT: + *params = mState.mCaps.maxShaderAtomicCounters[ShaderType::TessControl]; + break; + case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_EXT: + *params = mState.mCaps.maxShaderAtomicCounters[ShaderType::TessEvaluation]; + break; + case GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_EXT: + *params = mState.mCaps.maxShaderImageUniforms[ShaderType::TessControl]; + break; + case GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_EXT: + *params = mState.mCaps.maxShaderImageUniforms[ShaderType::TessEvaluation]; + break; + case GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_EXT: + *params = mState.mCaps.maxShaderStorageBlocks[ShaderType::TessControl]; + break; + case GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_EXT: + *params = mState.mCaps.maxShaderStorageBlocks[ShaderType::TessEvaluation]; + break; + // GLES1 emulation: Caps queries + case GL_MAX_TEXTURE_UNITS: + *params = mState.mCaps.maxMultitextureUnits; + break; + case GL_MAX_MODELVIEW_STACK_DEPTH: + *params = mState.mCaps.maxModelviewMatrixStackDepth; + break; + case GL_MAX_PROJECTION_STACK_DEPTH: + *params = mState.mCaps.maxProjectionMatrixStackDepth; + break; + case GL_MAX_TEXTURE_STACK_DEPTH: + *params = mState.mCaps.maxTextureMatrixStackDepth; + break; + case GL_MAX_LIGHTS: + *params = mState.mCaps.maxLights; + break; + + // case GL_MAX_CLIP_DISTANCES_EXT: Conflict enum value + case GL_MAX_CLIP_PLANES: + if (getClientVersion().major >= 2) + { + // GL_APPLE_clip_distance/GL_EXT_clip_cull_distance + *params = mState.mCaps.maxClipDistances; + } + else + { + *params = mState.mCaps.maxClipPlanes; + } + break; + case GL_MAX_CULL_DISTANCES_EXT: + *params = mState.mCaps.maxCullDistances; + break; + case GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT: + *params = mState.mCaps.maxCombinedClipAndCullDistances; + break; + // GLES1 emulation: Vertex attribute queries + case GL_VERTEX_ARRAY_BUFFER_BINDING: + case GL_NORMAL_ARRAY_BUFFER_BINDING: + case GL_COLOR_ARRAY_BUFFER_BINDING: + case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES: + case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING: + getIntegerVertexAttribImpl(pname, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, params); + break; + case GL_VERTEX_ARRAY_STRIDE: + case GL_NORMAL_ARRAY_STRIDE: + case GL_COLOR_ARRAY_STRIDE: + case GL_POINT_SIZE_ARRAY_STRIDE_OES: + case GL_TEXTURE_COORD_ARRAY_STRIDE: + getIntegerVertexAttribImpl(pname, GL_VERTEX_ATTRIB_ARRAY_STRIDE, params); + break; + case GL_VERTEX_ARRAY_SIZE: + case GL_COLOR_ARRAY_SIZE: + case GL_TEXTURE_COORD_ARRAY_SIZE: + getIntegerVertexAttribImpl(pname, GL_VERTEX_ATTRIB_ARRAY_SIZE, params); + break; + case GL_VERTEX_ARRAY_TYPE: + case GL_COLOR_ARRAY_TYPE: + case GL_NORMAL_ARRAY_TYPE: + case GL_POINT_SIZE_ARRAY_TYPE_OES: + case GL_TEXTURE_COORD_ARRAY_TYPE: + getIntegerVertexAttribImpl(pname, GL_VERTEX_ATTRIB_ARRAY_TYPE, params); + break; + + // GL_KHR_parallel_shader_compile + case GL_MAX_SHADER_COMPILER_THREADS_KHR: + *params = mState.getMaxShaderCompilerThreads(); + break; + + // GL_EXT_blend_func_extended + case GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT: + *params = mState.mCaps.maxDualSourceDrawBuffers; + break; + + // OES_shader_multisample_interpolation + case GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES: + *params = mState.mCaps.subPixelInterpolationOffsetBits; + break; + + // GL_OES_texture_buffer + case GL_MAX_TEXTURE_BUFFER_SIZE: + *params = mState.mCaps.maxTextureBufferSize; + break; + case GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT: + *params = mState.mCaps.textureBufferOffsetAlignment; + break; + + // GL_EXT_clip_control + case GL_CLIP_ORIGIN_EXT: + *params = mState.mClipControlOrigin; + break; + case GL_CLIP_DEPTH_MODE_EXT: + *params = mState.mClipControlDepth; + break; + + // ANGLE_shader_pixel_local_storage + case GL_MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE: + *params = mState.mCaps.maxPixelLocalStoragePlanes; + break; + case GL_MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE_ANGLE: + *params = mState.mCaps.maxColorAttachmentsWithActivePixelLocalStorage; + break; + case GL_MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES_ANGLE: + *params = mState.mCaps.maxCombinedDrawBuffersAndPixelLocalStoragePlanes; + break; + + default: + ANGLE_CONTEXT_TRY(mState.getIntegerv(this, pname, params)); + break; + } +} + +void Context::getIntegerVertexAttribImpl(GLenum pname, GLenum attribpname, GLint *params) const +{ + getVertexAttribivImpl(static_cast(vertexArrayIndex(ParamToVertexArrayType(pname))), + attribpname, params); +} + +void Context::getInteger64vImpl(GLenum pname, GLint64 *params) const +{ + // Queries about context capabilities and maximums are answered by Context. + // Queries about current GL state values are answered by State. + switch (pname) + { + case GL_MAX_ELEMENT_INDEX: + *params = mState.mCaps.maxElementIndex; + break; + case GL_MAX_UNIFORM_BLOCK_SIZE: + *params = mState.mCaps.maxUniformBlockSize; + break; + case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: + *params = mState.mCaps.maxCombinedShaderUniformComponents[ShaderType::Vertex]; + break; + case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: + *params = mState.mCaps.maxCombinedShaderUniformComponents[ShaderType::Fragment]; + break; + case GL_MAX_SERVER_WAIT_TIMEOUT: + *params = mState.mCaps.maxServerWaitTimeout; + break; + + // GL_EXT_disjoint_timer_query + case GL_TIMESTAMP_EXT: + *params = mImplementation->getTimestamp(); + break; + + case GL_MAX_SHADER_STORAGE_BLOCK_SIZE: + *params = mState.mCaps.maxShaderStorageBlockSize; + break; + default: + UNREACHABLE(); + break; + } +} + +void Context::getPointerv(GLenum pname, void **params) +{ + mState.getPointerv(this, pname, params); +} + +void Context::getPointervRobustANGLERobust(GLenum pname, + GLsizei bufSize, + GLsizei *length, + void **params) +{ + UNIMPLEMENTED(); +} + +void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data) +{ + // Queries about context capabilities and maximums are answered by Context. + // Queries about current GL state values are answered by State. + + GLenum nativeType; + unsigned int numParams; + bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams); + ASSERT(queryStatus); + + if (nativeType == GL_INT) + { + switch (target) + { + case GL_MAX_COMPUTE_WORK_GROUP_COUNT: + ASSERT(index < 3u); + *data = mState.mCaps.maxComputeWorkGroupCount[index]; + break; + case GL_MAX_COMPUTE_WORK_GROUP_SIZE: + ASSERT(index < 3u); + *data = mState.mCaps.maxComputeWorkGroupSize[index]; + break; + default: + mState.getIntegeri_v(this, target, index, data); + } + } + else + { + CastIndexedStateValues(this, nativeType, target, index, numParams, data); + } +} + +void Context::getIntegeri_vRobust(GLenum target, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint *data) +{ + getIntegeri_v(target, index, data); +} + +void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data) +{ + // Queries about context capabilities and maximums are answered by Context. + // Queries about current GL state values are answered by State. + + GLenum nativeType; + unsigned int numParams; + bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams); + ASSERT(queryStatus); + + if (nativeType == GL_INT_64_ANGLEX) + { + mState.getInteger64i_v(target, index, data); + } + else + { + CastIndexedStateValues(this, nativeType, target, index, numParams, data); + } +} + +void Context::getInteger64i_vRobust(GLenum target, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint64 *data) +{ + getInteger64i_v(target, index, data); +} + +void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data) +{ + // Queries about context capabilities and maximums are answered by Context. + // Queries about current GL state values are answered by State. + + GLenum nativeType; + unsigned int numParams; + bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams); + ASSERT(queryStatus); + + if (nativeType == GL_BOOL) + { + mState.getBooleani_v(target, index, data); + } + else + { + CastIndexedStateValues(this, nativeType, target, index, numParams, data); + } +} + +void Context::getBooleani_vRobust(GLenum target, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLboolean *data) +{ + getBooleani_v(target, index, data); +} + +void Context::getBufferParameteriv(BufferBinding target, GLenum pname, GLint *params) +{ + Buffer *buffer = mState.getTargetBuffer(target); + QueryBufferParameteriv(buffer, pname, params); +} + +void Context::getBufferParameterivRobust(BufferBinding target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + getBufferParameteriv(target, pname, params); +} + +void Context::getFramebufferAttachmentParameteriv(GLenum target, + GLenum attachment, + GLenum pname, + GLint *params) +{ + const Framebuffer *framebuffer = mState.getTargetFramebuffer(target); + QueryFramebufferAttachmentParameteriv(this, framebuffer, attachment, pname, params); +} + +void Context::getFramebufferAttachmentParameterivRobust(GLenum target, + GLenum attachment, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + getFramebufferAttachmentParameteriv(target, attachment, pname, params); +} + +void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params) +{ + Renderbuffer *renderbuffer = mState.getCurrentRenderbuffer(); + QueryRenderbufferiv(this, renderbuffer, pname, params); +} + +void Context::getRenderbufferParameterivRobust(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + getRenderbufferParameteriv(target, pname, params); +} + +void Context::texBuffer(TextureType target, GLenum internalformat, BufferID buffer) +{ + ASSERT(target == TextureType::Buffer); + + Texture *texture = getTextureByType(target); + Buffer *bufferObj = mState.mBufferManager->getBuffer(buffer); + ANGLE_CONTEXT_TRY(texture->setBuffer(this, bufferObj, internalformat)); +} + +void Context::texBufferRange(TextureType target, + GLenum internalformat, + BufferID buffer, + GLintptr offset, + GLsizeiptr size) +{ + ASSERT(target == TextureType::Buffer); + + Texture *texture = getTextureByType(target); + Buffer *bufferObj = mState.mBufferManager->getBuffer(buffer); + ANGLE_CONTEXT_TRY(texture->setBufferRange(this, bufferObj, internalformat, offset, size)); +} + +void Context::getTexParameterfv(TextureType target, GLenum pname, GLfloat *params) +{ + const Texture *const texture = getTextureByType(target); + QueryTexParameterfv(this, texture, pname, params); +} + +void Context::getTexParameterfvRobust(TextureType target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params) +{ + getTexParameterfv(target, pname, params); +} + +void Context::getTexParameteriv(TextureType target, GLenum pname, GLint *params) +{ + const Texture *const texture = getTextureByType(target); + QueryTexParameteriv(this, texture, pname, params); +} + +void Context::getTexParameterIiv(TextureType target, GLenum pname, GLint *params) +{ + const Texture *const texture = getTextureByType(target); + QueryTexParameterIiv(this, texture, pname, params); +} + +void Context::getTexParameterIuiv(TextureType target, GLenum pname, GLuint *params) +{ + const Texture *const texture = getTextureByType(target); + QueryTexParameterIuiv(this, texture, pname, params); +} + +void Context::getTexParameterivRobust(TextureType target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + getTexParameteriv(target, pname, params); +} + +void Context::getTexParameterIivRobust(TextureType target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + UNIMPLEMENTED(); +} + +void Context::getTexParameterIuivRobust(TextureType target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params) +{ + UNIMPLEMENTED(); +} + +void Context::getTexLevelParameteriv(TextureTarget target, GLint level, GLenum pname, GLint *params) +{ + Texture *texture = getTextureByTarget(target); + QueryTexLevelParameteriv(texture, target, level, pname, params); +} + +void Context::getTexLevelParameterivRobust(TextureTarget target, + GLint level, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + UNIMPLEMENTED(); +} + +void Context::getTexLevelParameterfv(TextureTarget target, + GLint level, + GLenum pname, + GLfloat *params) +{ + Texture *texture = getTextureByTarget(target); + QueryTexLevelParameterfv(texture, target, level, pname, params); +} + +void Context::getTexLevelParameterfvRobust(TextureTarget target, + GLint level, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params) +{ + UNIMPLEMENTED(); +} + +void Context::texParameterf(TextureType target, GLenum pname, GLfloat param) +{ + Texture *const texture = getTextureByType(target); + SetTexParameterf(this, texture, pname, param); +} + +void Context::texParameterfv(TextureType target, GLenum pname, const GLfloat *params) +{ + Texture *const texture = getTextureByType(target); + SetTexParameterfv(this, texture, pname, params); +} + +void Context::texParameterfvRobust(TextureType target, + GLenum pname, + GLsizei bufSize, + const GLfloat *params) +{ + texParameterfv(target, pname, params); +} + +void Context::texParameteri(TextureType target, GLenum pname, GLint param) +{ + // Some apps enable KHR_create_context_no_error but pass in an invalid texture type. + // Workaround this by silently returning in such situations. + if (target == TextureType::InvalidEnum) + { + return; + } + + Texture *const texture = getTextureByType(target); + SetTexParameteri(this, texture, pname, param); +} + +void Context::texParameteriv(TextureType target, GLenum pname, const GLint *params) +{ + Texture *const texture = getTextureByType(target); + SetTexParameteriv(this, texture, pname, params); +} + +void Context::texParameterIiv(TextureType target, GLenum pname, const GLint *params) +{ + Texture *const texture = getTextureByType(target); + SetTexParameterIiv(this, texture, pname, params); +} + +void Context::texParameterIuiv(TextureType target, GLenum pname, const GLuint *params) +{ + Texture *const texture = getTextureByType(target); + SetTexParameterIuiv(this, texture, pname, params); +} + +void Context::texParameterivRobust(TextureType target, + GLenum pname, + GLsizei bufSize, + const GLint *params) +{ + texParameteriv(target, pname, params); +} + +void Context::texParameterIivRobust(TextureType target, + GLenum pname, + GLsizei bufSize, + const GLint *params) +{ + UNIMPLEMENTED(); +} + +void Context::texParameterIuivRobust(TextureType target, + GLenum pname, + GLsizei bufSize, + const GLuint *params) +{ + UNIMPLEMENTED(); +} + +void Context::drawArraysInstanced(PrimitiveMode mode, + GLint first, + GLsizei count, + GLsizei instanceCount) +{ + // No-op if count draws no primitives for given mode + if (noopDrawInstanced(mode, count, instanceCount)) + { + ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent()); + return; + } + + ANGLE_CONTEXT_TRY(prepareForDraw(mode)); + ANGLE_CONTEXT_TRY( + mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount)); + MarkTransformFeedbackBufferUsage(this, count, instanceCount); + MarkShaderStorageUsage(this); +} + +void Context::drawElementsInstanced(PrimitiveMode mode, + GLsizei count, + DrawElementsType type, + const void *indices, + GLsizei instances) +{ + // No-op if count draws no primitives for given mode + if (noopDrawInstanced(mode, count, instances)) + { + ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent()); + return; + } + + ANGLE_CONTEXT_TRY(prepareForDraw(mode)); + ANGLE_CONTEXT_TRY( + mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances)); + MarkShaderStorageUsage(this); +} + +void Context::drawElementsBaseVertex(PrimitiveMode mode, + GLsizei count, + DrawElementsType type, + const void *indices, + GLint basevertex) +{ + // No-op if count draws no primitives for given mode + if (noopDraw(mode, count)) + { + ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent()); + return; + } + + ANGLE_CONTEXT_TRY(prepareForDraw(mode)); + ANGLE_CONTEXT_TRY( + mImplementation->drawElementsBaseVertex(this, mode, count, type, indices, basevertex)); + MarkShaderStorageUsage(this); +} + +void Context::drawElementsInstancedBaseVertex(PrimitiveMode mode, + GLsizei count, + DrawElementsType type, + const void *indices, + GLsizei instancecount, + GLint basevertex) +{ + // No-op if count draws no primitives for given mode + if (noopDrawInstanced(mode, count, instancecount)) + { + ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent()); + return; + } + + ANGLE_CONTEXT_TRY(prepareForDraw(mode)); + ANGLE_CONTEXT_TRY(mImplementation->drawElementsInstancedBaseVertex( + this, mode, count, type, indices, instancecount, basevertex)); + MarkShaderStorageUsage(this); +} + +void Context::drawRangeElements(PrimitiveMode mode, + GLuint start, + GLuint end, + GLsizei count, + DrawElementsType type, + const void *indices) +{ + // No-op if count draws no primitives for given mode + if (noopDraw(mode, count)) + { + ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent()); + return; + } + + ANGLE_CONTEXT_TRY(prepareForDraw(mode)); + ANGLE_CONTEXT_TRY( + mImplementation->drawRangeElements(this, mode, start, end, count, type, indices)); + MarkShaderStorageUsage(this); +} + +void Context::drawRangeElementsBaseVertex(PrimitiveMode mode, + GLuint start, + GLuint end, + GLsizei count, + DrawElementsType type, + const void *indices, + GLint basevertex) +{ + // No-op if count draws no primitives for given mode + if (noopDraw(mode, count)) + { + ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent()); + return; + } + + ANGLE_CONTEXT_TRY(prepareForDraw(mode)); + ANGLE_CONTEXT_TRY(mImplementation->drawRangeElementsBaseVertex(this, mode, start, end, count, + type, indices, basevertex)); + MarkShaderStorageUsage(this); +} + +void Context::drawArraysIndirect(PrimitiveMode mode, const void *indirect) +{ + ANGLE_CONTEXT_TRY(prepareForDraw(mode)); + ANGLE_CONTEXT_TRY(mImplementation->drawArraysIndirect(this, mode, indirect)); + MarkShaderStorageUsage(this); +} + +void Context::drawElementsIndirect(PrimitiveMode mode, DrawElementsType type, const void *indirect) +{ + ANGLE_CONTEXT_TRY(prepareForDraw(mode)); + ANGLE_CONTEXT_TRY(mImplementation->drawElementsIndirect(this, mode, type, indirect)); + MarkShaderStorageUsage(this); +} + +void Context::flush() +{ + ANGLE_CONTEXT_TRY(mImplementation->flush(this)); +} + +void Context::finish() +{ + ANGLE_CONTEXT_TRY(mImplementation->finish(this)); +} + +void Context::insertEventMarker(GLsizei length, const char *marker) +{ + ASSERT(mImplementation); + ANGLE_CONTEXT_TRY(mImplementation->insertEventMarker(length, marker)); +} + +void Context::pushGroupMarker(GLsizei length, const char *marker) +{ + ASSERT(mImplementation); + + if (marker == nullptr) + { + // From the EXT_debug_marker spec, + // "If is null then an empty string is pushed on the stack." + ANGLE_CONTEXT_TRY(mImplementation->pushGroupMarker(length, "")); + } + else + { + ANGLE_CONTEXT_TRY(mImplementation->pushGroupMarker(length, marker)); + } +} + +void Context::popGroupMarker() +{ + ASSERT(mImplementation); + ANGLE_CONTEXT_TRY(mImplementation->popGroupMarker()); +} + +void Context::bindUniformLocation(ShaderProgramID program, + UniformLocation location, + const GLchar *name) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + + programObject->bindUniformLocation(location, name); +} + +void Context::coverageModulation(GLenum components) +{ + mState.setCoverageModulation(components); +} + +GLuint Context::getProgramResourceIndex(ShaderProgramID program, + GLenum programInterface, + const GLchar *name) +{ + const Program *programObject = getProgramResolveLink(program); + return QueryProgramResourceIndex(programObject, programInterface, name); +} + +void Context::getProgramResourceName(ShaderProgramID program, + GLenum programInterface, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name) +{ + const Program *programObject = getProgramResolveLink(program); + QueryProgramResourceName(this, programObject, programInterface, index, bufSize, length, name); +} + +GLint Context::getProgramResourceLocation(ShaderProgramID program, + GLenum programInterface, + const GLchar *name) +{ + const Program *programObject = getProgramResolveLink(program); + return QueryProgramResourceLocation(programObject, programInterface, name); +} + +void Context::getProgramResourceiv(ShaderProgramID program, + GLenum programInterface, + GLuint index, + GLsizei propCount, + const GLenum *props, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + const Program *programObject = getProgramResolveLink(program); + QueryProgramResourceiv(programObject, programInterface, {index}, propCount, props, bufSize, + length, params); +} + +void Context::getProgramInterfaceiv(ShaderProgramID program, + GLenum programInterface, + GLenum pname, + GLint *params) +{ + const Program *programObject = getProgramResolveLink(program); + QueryProgramInterfaceiv(programObject, programInterface, pname, params); +} + +void Context::getProgramInterfaceivRobust(ShaderProgramID program, + GLenum programInterface, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + UNIMPLEMENTED(); +} + +void Context::handleError(GLenum errorCode, + const char *message, + const char *file, + const char *function, + unsigned int line) +{ + mErrors.handleError(errorCode, message, file, function, line); +} + +void Context::validationError(angle::EntryPoint entryPoint, + GLenum errorCode, + const char *message) const +{ + const_cast(this)->mErrors.validationError(entryPoint, errorCode, message); +} + +void Context::validationErrorF(angle::EntryPoint entryPoint, + GLenum errorCode, + const char *format, + ...) const +{ + va_list vargs; + va_start(vargs, format); + constexpr size_t kMessageSize = 256; + char message[kMessageSize]; + int r = vsnprintf(message, kMessageSize, format, vargs); + va_end(vargs); + + if (r > 0) + { + validationError(entryPoint, errorCode, message); + } + else + { + validationError(entryPoint, errorCode, format); + } +} + +// Get one of the recorded errors and clear its flag, if any. +// [OpenGL ES 2.0.24] section 2.5 page 13. +GLenum Context::getError() +{ + if (mErrors.empty()) + { + return GL_NO_ERROR; + } + else + { + return mErrors.popError(); + } +} + +// NOTE: this function should not assume that this context is current! +void Context::markContextLost(GraphicsResetStatus status) +{ + ASSERT(status != GraphicsResetStatus::NoError); + if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT) + { + mResetStatus = status; + mContextLostForced = true; + } + setContextLost(); +} + +void Context::setContextLost() +{ + mContextLost = true; + + // Stop skipping validation, since many implementation entrypoint assume they can't + // be called when lost, or with null object arguments, etc. + mSkipValidation = false; + + // Make sure we update TLS. +#if defined(ANGLE_PLATFORM_APPLE) + SetCurrentValidContextTLS(nullptr); +#else + gCurrentValidContext = nullptr; +#endif +} + +GLenum Context::getGraphicsResetStatus() +{ + // Even if the application doesn't want to know about resets, we want to know + // as it will allow us to skip all the calls. + if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT) + { + if (!isContextLost() && mImplementation->getResetStatus() != GraphicsResetStatus::NoError) + { + setContextLost(); + } + + // EXT_robustness, section 2.6: If the reset notification behavior is + // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of + // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR. + return GL_NO_ERROR; + } + + // The GL_EXT_robustness spec says that if a reset is encountered, a reset + // status should be returned at least once, and GL_NO_ERROR should be returned + // once the device has finished resetting. + if (!isContextLost()) + { + ASSERT(mResetStatus == GraphicsResetStatus::NoError); + mResetStatus = mImplementation->getResetStatus(); + + if (mResetStatus != GraphicsResetStatus::NoError) + { + setContextLost(); + } + } + else if (!mContextLostForced && mResetStatus != GraphicsResetStatus::NoError) + { + // If markContextLost was used to mark the context lost then + // assume that is not recoverable, and continue to report the + // lost reset status for the lifetime of this context. + mResetStatus = mImplementation->getResetStatus(); + } + + return ToGLenum(mResetStatus); +} + +bool Context::isResetNotificationEnabled() const +{ + return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT); +} + +bool Context::isRobustnessEnabled() const +{ + return mState.hasRobustAccess(); +} + +const egl::Config *Context::getConfig() const +{ + return mConfig; +} + +EGLenum Context::getClientType() const +{ + return mState.getClientType(); +} + +EGLenum Context::getRenderBuffer() const +{ + const Framebuffer *framebuffer = + mState.mFramebufferManager->getFramebuffer(Framebuffer::kDefaultDrawFramebufferHandle); + if (framebuffer == nullptr) + { + return EGL_NONE; + } + + const FramebufferAttachment *backAttachment = framebuffer->getAttachment(this, GL_BACK); + ASSERT(backAttachment != nullptr); + return backAttachment->getSurface()->getRenderBuffer(); +} + +VertexArray *Context::checkVertexArrayAllocation(VertexArrayID vertexArrayHandle) +{ + // Only called after a prior call to Gen. + VertexArray *vertexArray = getVertexArray(vertexArrayHandle); + if (!vertexArray) + { + vertexArray = + new VertexArray(mImplementation.get(), vertexArrayHandle, + mState.mCaps.maxVertexAttributes, mState.mCaps.maxVertexAttribBindings); + vertexArray->setBufferAccessValidationEnabled(mBufferAccessValidationEnabled); + + mVertexArrayMap.assign(vertexArrayHandle, vertexArray); + } + + return vertexArray; +} + +TransformFeedback *Context::checkTransformFeedbackAllocation( + TransformFeedbackID transformFeedbackHandle) +{ + // Only called after a prior call to Gen. + TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle); + if (!transformFeedback) + { + transformFeedback = + new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mState.mCaps); + transformFeedback->addRef(); + mTransformFeedbackMap.assign(transformFeedbackHandle, transformFeedback); + } + + return transformFeedback; +} + +bool Context::isVertexArrayGenerated(VertexArrayID vertexArray) const +{ + ASSERT(mVertexArrayMap.contains({0})); + return mVertexArrayMap.contains(vertexArray); +} + +bool Context::isTransformFeedbackGenerated(TransformFeedbackID transformFeedback) const +{ + ASSERT(mTransformFeedbackMap.contains({0})); + return mTransformFeedbackMap.contains(transformFeedback); +} + +void Context::detachTexture(TextureID texture) +{ + // The State cannot unbind image observers itself, they are owned by the Context + Texture *tex = mState.mTextureManager->getTexture(texture); + for (auto &imageBinding : mImageObserverBindings) + { + if (imageBinding.getSubject() == tex) + { + imageBinding.reset(); + } + } + + // Simple pass-through to State's detachTexture method, as textures do not require + // allocation map management either here or in the resource manager at detach time. + // Zero textures are held by the Context, and we don't attempt to request them from + // the State. + mState.detachTexture(this, mZeroTextures, texture); +} + +void Context::detachBuffer(Buffer *buffer) +{ + // Simple pass-through to State's detachBuffer method, since + // only buffer attachments to container objects that are bound to the current context + // should be detached. And all those are available in State. + + // [OpenGL ES 3.2] section 5.1.2 page 45: + // Attachments to unbound container objects, such as + // deletion of a buffer attached to a vertex array object which is not bound to the context, + // are not affected and continue to act as references on the deleted object + ANGLE_CONTEXT_TRY(mState.detachBuffer(this, buffer)); +} + +void Context::detachFramebuffer(FramebufferID framebuffer) +{ + // Framebuffer detachment is handled by Context, because 0 is a valid + // Framebuffer object, and a pointer to it must be passed from Context + // to State at binding time. + + // [OpenGL ES 2.0.24] section 4.4 page 107: + // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as + // though BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of + // zero. + + if (mState.removeReadFramebufferBinding(framebuffer) && framebuffer.value != 0) + { + bindReadFramebuffer({0}); + } + + if (mState.removeDrawFramebufferBinding(framebuffer) && framebuffer.value != 0) + { + bindDrawFramebuffer({0}); + } +} + +void Context::detachRenderbuffer(RenderbufferID renderbuffer) +{ + mState.detachRenderbuffer(this, renderbuffer); +} + +void Context::detachVertexArray(VertexArrayID vertexArray) +{ + // Vertex array detachment is handled by Context, because 0 is a valid + // VAO, and a pointer to it must be passed from Context to State at + // binding time. + + // [OpenGL ES 3.0.2] section 2.10 page 43: + // If a vertex array object that is currently bound is deleted, the binding + // for that object reverts to zero and the default vertex array becomes current. + if (mState.removeVertexArrayBinding(this, vertexArray)) + { + bindVertexArray({0}); + } +} + +void Context::detachTransformFeedback(TransformFeedbackID transformFeedback) +{ + // Transform feedback detachment is handled by Context, because 0 is a valid + // transform feedback, and a pointer to it must be passed from Context to State at + // binding time. + + // The OpenGL specification doesn't mention what should happen when the currently bound + // transform feedback object is deleted. Since it is a container object, we treat it like + // VAOs and FBOs and set the current bound transform feedback back to 0. + if (mState.removeTransformFeedbackBinding(this, transformFeedback)) + { + bindTransformFeedback(GL_TRANSFORM_FEEDBACK, {0}); + mStateCache.onActiveTransformFeedbackChange(this); + } +} + +void Context::detachSampler(SamplerID sampler) +{ + mState.detachSampler(this, sampler); +} + +void Context::detachProgramPipeline(ProgramPipelineID pipeline) +{ + mState.detachProgramPipeline(this, pipeline); +} + +void Context::vertexAttribDivisor(GLuint index, GLuint divisor) +{ + mState.setVertexAttribDivisor(this, index, divisor); + mStateCache.onVertexArrayStateChange(this); +} + +void Context::samplerParameteri(SamplerID sampler, GLenum pname, GLint param) +{ + Sampler *const samplerObject = + mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler); + SetSamplerParameteri(this, samplerObject, pname, param); +} + +void Context::samplerParameteriv(SamplerID sampler, GLenum pname, const GLint *param) +{ + Sampler *const samplerObject = + mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler); + SetSamplerParameteriv(this, samplerObject, pname, param); +} + +void Context::samplerParameterIiv(SamplerID sampler, GLenum pname, const GLint *param) +{ + Sampler *const samplerObject = + mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler); + SetSamplerParameterIiv(this, samplerObject, pname, param); +} + +void Context::samplerParameterIuiv(SamplerID sampler, GLenum pname, const GLuint *param) +{ + Sampler *const samplerObject = + mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler); + SetSamplerParameterIuiv(this, samplerObject, pname, param); +} + +void Context::samplerParameterivRobust(SamplerID sampler, + GLenum pname, + GLsizei bufSize, + const GLint *param) +{ + samplerParameteriv(sampler, pname, param); +} + +void Context::samplerParameterIivRobust(SamplerID sampler, + GLenum pname, + GLsizei bufSize, + const GLint *param) +{ + UNIMPLEMENTED(); +} + +void Context::samplerParameterIuivRobust(SamplerID sampler, + GLenum pname, + GLsizei bufSize, + const GLuint *param) +{ + UNIMPLEMENTED(); +} + +void Context::samplerParameterf(SamplerID sampler, GLenum pname, GLfloat param) +{ + Sampler *const samplerObject = + mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler); + SetSamplerParameterf(this, samplerObject, pname, param); +} + +void Context::samplerParameterfv(SamplerID sampler, GLenum pname, const GLfloat *param) +{ + Sampler *const samplerObject = + mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler); + SetSamplerParameterfv(this, samplerObject, pname, param); +} + +void Context::samplerParameterfvRobust(SamplerID sampler, + GLenum pname, + GLsizei bufSize, + const GLfloat *param) +{ + samplerParameterfv(sampler, pname, param); +} + +void Context::getSamplerParameteriv(SamplerID sampler, GLenum pname, GLint *params) +{ + const Sampler *const samplerObject = + mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler); + QuerySamplerParameteriv(samplerObject, pname, params); +} + +void Context::getSamplerParameterIiv(SamplerID sampler, GLenum pname, GLint *params) +{ + const Sampler *const samplerObject = + mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler); + QuerySamplerParameterIiv(samplerObject, pname, params); +} + +void Context::getSamplerParameterIuiv(SamplerID sampler, GLenum pname, GLuint *params) +{ + const Sampler *const samplerObject = + mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler); + QuerySamplerParameterIuiv(samplerObject, pname, params); +} + +void Context::getSamplerParameterivRobust(SamplerID sampler, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + getSamplerParameteriv(sampler, pname, params); +} + +void Context::getSamplerParameterIivRobust(SamplerID sampler, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + UNIMPLEMENTED(); +} + +void Context::getSamplerParameterIuivRobust(SamplerID sampler, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params) +{ + UNIMPLEMENTED(); +} + +void Context::getSamplerParameterfv(SamplerID sampler, GLenum pname, GLfloat *params) +{ + const Sampler *const samplerObject = + mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler); + QuerySamplerParameterfv(samplerObject, pname, params); +} + +void Context::getSamplerParameterfvRobust(SamplerID sampler, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params) +{ + getSamplerParameterfv(sampler, pname, params); +} + +void Context::programParameteri(ShaderProgramID program, GLenum pname, GLint value) +{ + gl::Program *programObject = getProgramResolveLink(program); + SetProgramParameteri(programObject, pname, value); +} + +void Context::initRendererString() +{ + std::ostringstream frontendRendererString; + std::string vendorString(mDisplay->getBackendVendorString()); + std::string rendererString(mDisplay->getBackendRendererDescription()); + std::string versionString(mDisplay->getBackendVersionString(!isWebGL())); + // Commas are used as a separator in ANGLE's renderer string, so remove commas from each + // element. + vendorString.erase(std::remove(vendorString.begin(), vendorString.end(), ','), + vendorString.end()); + rendererString.erase(std::remove(rendererString.begin(), rendererString.end(), ','), + rendererString.end()); + versionString.erase(std::remove(versionString.begin(), versionString.end(), ','), + versionString.end()); + frontendRendererString << "ANGLE ("; + frontendRendererString << vendorString; + frontendRendererString << ", "; + frontendRendererString << rendererString; + frontendRendererString << ", "; + frontendRendererString << versionString; + frontendRendererString << ")"; + + mRendererString = MakeStaticString(frontendRendererString.str()); +} + +void Context::initVersionStrings() +{ + const Version &clientVersion = getClientVersion(); + + std::ostringstream versionString; + if (getClientType() == EGL_OPENGL_ES_API) + { + versionString << "OpenGL ES "; + } + versionString << clientVersion.major << "." << clientVersion.minor << ".0 (ANGLE " + << angle::GetANGLEVersionString() << ")"; + mVersionString = MakeStaticString(versionString.str()); + + std::ostringstream shadingLanguageVersionString; + if (getClientType() == EGL_OPENGL_ES_API) + { + shadingLanguageVersionString << "OpenGL ES GLSL ES "; + } + else + { + ASSERT(getClientType() == EGL_OPENGL_API); + shadingLanguageVersionString << "OpenGL GLSL "; + } + shadingLanguageVersionString << (clientVersion.major == 2 ? 1 : clientVersion.major) << "." + << clientVersion.minor << "0 (ANGLE " + << angle::GetANGLEVersionString() << ")"; + mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str()); +} + +void Context::initExtensionStrings() +{ + auto mergeExtensionStrings = [](const std::vector &strings) { + std::ostringstream combinedStringStream; + std::copy(strings.begin(), strings.end(), + std::ostream_iterator(combinedStringStream, " ")); + return MakeStaticString(combinedStringStream.str()); + }; + + mExtensionStrings.clear(); + for (const auto &extensionString : mState.mExtensions.getStrings()) + { + mExtensionStrings.push_back(MakeStaticString(extensionString)); + } + mExtensionString = mergeExtensionStrings(mExtensionStrings); + + mRequestableExtensionStrings.clear(); + for (const auto &extensionInfo : GetExtensionInfoMap()) + { + if (extensionInfo.second.Requestable && + !(mState.mExtensions.*(extensionInfo.second.ExtensionsMember)) && + mSupportedExtensions.*(extensionInfo.second.ExtensionsMember)) + { + mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first)); + } + } + mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings); +} + +const GLubyte *Context::getString(GLenum name) +{ + return static_cast(this)->getString(name); +} + +const GLubyte *Context::getStringi(GLenum name, GLuint index) +{ + return static_cast(this)->getStringi(name, index); +} + +const GLubyte *Context::getString(GLenum name) const +{ + switch (name) + { + case GL_VENDOR: + return reinterpret_cast(mDisplay->getVendorString().c_str()); + + case GL_RENDERER: + return reinterpret_cast(mRendererString); + + case GL_VERSION: + return reinterpret_cast(mVersionString); + + case GL_SHADING_LANGUAGE_VERSION: + return reinterpret_cast(mShadingLanguageString); + + case GL_EXTENSIONS: + return reinterpret_cast(mExtensionString); + + case GL_REQUESTABLE_EXTENSIONS_ANGLE: + return reinterpret_cast(mRequestableExtensionString); + + case GL_SERIALIZED_CONTEXT_STRING_ANGLE: + if (angle::SerializeContextToString(this, &mCachedSerializedStateString) == + angle::Result::Continue) + { + return reinterpret_cast(mCachedSerializedStateString.c_str()); + } + else + { + return nullptr; + } + + default: + UNREACHABLE(); + return nullptr; + } +} + +const GLubyte *Context::getStringi(GLenum name, GLuint index) const +{ + switch (name) + { + case GL_EXTENSIONS: + return reinterpret_cast(mExtensionStrings[index]); + + case GL_REQUESTABLE_EXTENSIONS_ANGLE: + return reinterpret_cast(mRequestableExtensionStrings[index]); + + default: + UNREACHABLE(); + return nullptr; + } +} + +size_t Context::getExtensionStringCount() const +{ + return mExtensionStrings.size(); +} + +bool Context::isExtensionRequestable(const char *name) const +{ + const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap(); + auto extension = extensionInfos.find(name); + + return extension != extensionInfos.end() && extension->second.Requestable && + mSupportedExtensions.*(extension->second.ExtensionsMember); +} + +bool Context::isExtensionDisablable(const char *name) const +{ + const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap(); + auto extension = extensionInfos.find(name); + + return extension != extensionInfos.end() && extension->second.Disablable && + mSupportedExtensions.*(extension->second.ExtensionsMember); +} + +void Context::requestExtension(const char *name) +{ + setExtensionEnabled(name, true); +} +void Context::disableExtension(const char *name) +{ + setExtensionEnabled(name, false); +} + +void Context::setExtensionEnabled(const char *name, bool enabled) +{ + // OVR_multiview is implicitly enabled when OVR_multiview2 is enabled + if (strcmp(name, "GL_OVR_multiview2") == 0) + { + setExtensionEnabled("GL_OVR_multiview", enabled); + } + const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap(); + ASSERT(extensionInfos.find(name) != extensionInfos.end()); + const auto &extension = extensionInfos.at(name); + ASSERT(extension.Requestable); + ASSERT(isExtensionRequestable(name)); + + if (mState.mExtensions.*(extension.ExtensionsMember) == enabled) + { + // No change + return; + } + + mState.mExtensions.*(extension.ExtensionsMember) = enabled; + + reinitializeAfterExtensionsChanged(); +} + +void Context::reinitializeAfterExtensionsChanged() +{ + updateCaps(); + initExtensionStrings(); + + // Release the shader compiler so it will be re-created with the requested extensions enabled. + releaseShaderCompiler(); + + // Invalidate all textures and framebuffer. Some extensions make new formats renderable or + // sampleable. + mState.mTextureManager->signalAllTexturesDirty(); + for (auto &zeroTexture : mZeroTextures) + { + if (zeroTexture.get() != nullptr) + { + zeroTexture->signalDirtyStorage(InitState::Initialized); + } + } + + mState.mFramebufferManager->invalidateFramebufferCompletenessCache(); +} + +size_t Context::getRequestableExtensionStringCount() const +{ + return mRequestableExtensionStrings.size(); +} + +void Context::beginTransformFeedback(PrimitiveMode primitiveMode) +{ + TransformFeedback *transformFeedback = mState.getCurrentTransformFeedback(); + ASSERT(transformFeedback != nullptr); + ASSERT(!transformFeedback->isPaused()); + + // TODO: http://anglebug.com/7232: Handle PPOs + ANGLE_CONTEXT_TRY(transformFeedback->begin(this, primitiveMode, mState.getProgram())); + mStateCache.onActiveTransformFeedbackChange(this); +} + +bool Context::hasActiveTransformFeedback(ShaderProgramID program) const +{ + for (auto pair : mTransformFeedbackMap) + { + if (pair.second != nullptr && pair.second->hasBoundProgram(program)) + { + return true; + } + } + return false; +} + +Extensions Context::generateSupportedExtensions() const +{ + Extensions supportedExtensions = mImplementation->getNativeExtensions(); + + if (getClientVersion() < ES_2_0) + { + // Default extensions for GLES1 + supportedExtensions.pointSizeArrayOES = true; + supportedExtensions.textureCubeMapOES = true; + supportedExtensions.pointSpriteOES = true; + supportedExtensions.drawTextureOES = true; + supportedExtensions.framebufferObjectOES = true; + supportedExtensions.parallelShaderCompileKHR = false; + supportedExtensions.texture3DOES = false; + supportedExtensions.clipDistanceAPPLE = false; + } + + if (getClientVersion() < ES_3_0) + { + // Disable ES3+ extensions + supportedExtensions.colorBufferFloatEXT = false; + supportedExtensions.EGLImageExternalEssl3OES = false; + supportedExtensions.multiviewOVR = false; + supportedExtensions.multiview2OVR = false; + supportedExtensions.multiviewMultisampleANGLE = false; + supportedExtensions.copyTexture3dANGLE = false; + supportedExtensions.textureMultisampleANGLE = false; + supportedExtensions.drawBuffersIndexedEXT = false; + supportedExtensions.drawBuffersIndexedOES = false; + supportedExtensions.EGLImageArrayEXT = false; + supportedExtensions.textureFormatSRGBOverrideEXT = false; + + // Support GL_EXT_texture_norm16 on non-WebGL ES2 contexts. This is needed for R16/RG16 + // texturing for HDR video playback in Chromium which uses ES2 for compositor contexts. + // Remove this workaround after Chromium migrates to ES3 for compositor contexts. + if (mWebGLContext || getClientVersion() < ES_2_0) + { + supportedExtensions.textureNorm16EXT = false; + } + + // Requires immutable textures + supportedExtensions.yuvInternalFormatANGLE = false; + + // Require ESSL 3.0 + supportedExtensions.shaderMultisampleInterpolationOES = false; + supportedExtensions.shaderNoperspectiveInterpolationNV = false; + supportedExtensions.sampleVariablesOES = false; + + // Require ES 3.1 but could likely be exposed on 3.0 + supportedExtensions.textureCubeMapArrayEXT = false; + supportedExtensions.textureCubeMapArrayOES = false; + + // Require RED and RG formats + supportedExtensions.textureSRGBR8EXT = false; + supportedExtensions.textureSRGBRG8EXT = false; + + // Requires glCompressedTexImage3D + supportedExtensions.textureCompressionAstcOES = false; + + // Don't expose GL_EXT_texture_sRGB_decode without sRGB texture support + if (!supportedExtensions.sRGBEXT) + { + supportedExtensions.textureSRGBDecodeEXT = false; + } + + // Don't expose GL_OES_texture_float_linear without full legacy float texture support + // The renderer may report OES_texture_float_linear without OES_texture_float + // This is valid in a GLES 3.0 context, but not in a GLES 2.0 context + if (!(supportedExtensions.textureFloatOES && supportedExtensions.textureHalfFloatOES)) + { + supportedExtensions.textureFloatLinearOES = false; + supportedExtensions.textureHalfFloatLinearOES = false; + } + + // Because of the difference in the SNORM to FLOAT conversion formula + // between GLES 2.0 and 3.0, vertex type 10_10_10_2 is disabled + // when the context version is lower than 3.0 + supportedExtensions.vertexType1010102OES = false; + + // GL_EXT_EGL_image_storage requires ESSL3 + supportedExtensions.EGLImageStorageEXT = false; + + // GL_EXT_YUV_target requires ESSL3 + supportedExtensions.YUVTargetEXT = false; + + // GL_EXT_clip_cull_distance requires ESSL3 + supportedExtensions.clipCullDistanceEXT = false; + + // ANGLE_shader_pixel_local_storage requires ES3 + supportedExtensions.shaderPixelLocalStorageANGLE = false; + supportedExtensions.shaderPixelLocalStorageCoherentANGLE = false; + } + + if (getClientVersion() < ES_3_1) + { + // Disable ES3.1+ extensions + supportedExtensions.geometryShaderEXT = false; + supportedExtensions.geometryShaderOES = false; + supportedExtensions.gpuShader5EXT = false; + supportedExtensions.primitiveBoundingBoxEXT = false; + supportedExtensions.shaderImageAtomicOES = false; + supportedExtensions.shaderIoBlocksEXT = false; + supportedExtensions.shaderIoBlocksOES = false; + supportedExtensions.tessellationShaderEXT = false; + supportedExtensions.textureBufferEXT = false; + supportedExtensions.textureBufferOES = false; + + // TODO(http://anglebug.com/2775): Multisample arrays could be supported on ES 3.0 as well + // once 2D multisample texture extension is exposed there. + supportedExtensions.textureStorageMultisample2dArrayOES = false; + } + + if (getClientVersion() > ES_2_0) + { + // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts + // supportedExtensions.sRGB = false; + + // If colorBufferFloatEXT is disabled but colorBufferHalfFloatEXT is enabled, then we will + // expose some floating-point formats as color buffer targets but reject blits between + // fixed-point and floating-point formats (this behavior is only enabled in + // colorBufferFloatEXT, and must be rejected if only colorBufferHalfFloatEXT is enabled). + // dEQP does not check for this, and will assume that floating-point and fixed-point formats + // can be blit onto each other if the format is available. + // We require colorBufferFloatEXT to be present in order to enable colorBufferHalfFloatEXT, + // so that blitting is always allowed if the requested formats are exposed and have the + // correct feature capabilities. WebGL 2 wants to support colorBufferHalfFloatEXT without + // colorBufferFloatEXT. + if (!supportedExtensions.colorBufferFloatEXT && !mWebGLContext) + { + supportedExtensions.colorBufferHalfFloatEXT = false; + } + + // Disable support for CHROMIUM_color_buffer_float_rgb[a] in ES 3.0+, these extensions are + // non-conformant in ES 3.0 and superseded by EXT_color_buffer_float. + supportedExtensions.colorBufferFloatRgbCHROMIUM = false; + supportedExtensions.colorBufferFloatRgbaCHROMIUM = false; + } + + if (getFrontendFeatures().disableDrawBuffersIndexed.enabled) + { + supportedExtensions.drawBuffersIndexedEXT = false; + supportedExtensions.drawBuffersIndexedOES = false; + } + + if (getFrontendFeatures().disableAnisotropicFiltering.enabled) + { + supportedExtensions.textureFilterAnisotropicEXT = false; + } + + if (!getFrontendFeatures().emulatePixelLocalStorage.enabled) + { + supportedExtensions.shaderPixelLocalStorageANGLE = false; + supportedExtensions.shaderPixelLocalStorageCoherentANGLE = false; + } + + // Some extensions are always available because they are implemented in the GL layer. + supportedExtensions.bindUniformLocationCHROMIUM = true; + supportedExtensions.vertexArrayObjectOES = true; + supportedExtensions.bindGeneratesResourceCHROMIUM = true; + supportedExtensions.clientArraysANGLE = true; + supportedExtensions.requestExtensionANGLE = true; + supportedExtensions.multiDrawANGLE = true; + + // Enable the no error extension if the context was created with the flag. + supportedExtensions.noErrorKHR = mSkipValidation; + + // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO + supportedExtensions.surfacelessContextOES = mSurfacelessSupported; + + // Explicitly enable GL_KHR_debug + supportedExtensions.debugKHR = true; + + // Explicitly enable GL_EXT_debug_label + supportedExtensions.debugLabelEXT = true; + + // Explicitly enable GL_ANGLE_robust_client_memory if the context supports validation. + supportedExtensions.robustClientMemoryANGLE = !mSkipValidation; + + // Determine robust resource init availability from EGL. + supportedExtensions.robustResourceInitializationANGLE = mState.isRobustResourceInitEnabled(); + + // mState.mExtensions.robustBufferAccessBehaviorKHR is true only if robust access is true and + // the backend supports it. + supportedExtensions.robustBufferAccessBehaviorKHR = + mState.hasRobustAccess() && supportedExtensions.robustBufferAccessBehaviorKHR; + + // Enable the cache control query unconditionally. + supportedExtensions.programCacheControlANGLE = true; + + // If EGL_KHR_fence_sync is not enabled, don't expose GL_OES_EGL_sync. + ASSERT(mDisplay); + if (!mDisplay->getExtensions().fenceSync) + { + supportedExtensions.EGLSyncOES = false; + } + + if (mDisplay->getExtensions().robustnessVideoMemoryPurgeNV) + { + supportedExtensions.robustnessVideoMemoryPurgeNV = true; + } + + supportedExtensions.memorySizeANGLE = true; + + // GL_CHROMIUM_lose_context is implemented in the frontend + supportedExtensions.loseContextCHROMIUM = true; + + // The ASTC texture extensions have dependency requirements. + if (supportedExtensions.textureCompressionAstcHdrKHR || + supportedExtensions.textureCompressionAstcSliced3dKHR) + { + // GL_KHR_texture_compression_astc_hdr cannot be exposed without also exposing + // GL_KHR_texture_compression_astc_ldr + ASSERT(supportedExtensions.textureCompressionAstcLdrKHR); + } + + if (supportedExtensions.textureCompressionAstcOES) + { + // GL_OES_texture_compression_astc cannot be exposed without also exposing + // GL_KHR_texture_compression_astc_ldr and GL_KHR_texture_compression_astc_hdr + ASSERT(supportedExtensions.textureCompressionAstcLdrKHR); + ASSERT(supportedExtensions.textureCompressionAstcHdrKHR); + } + + // GL_KHR_protected_textures + // If EGL_KHR_protected_content is not supported then GL_EXT_protected_texture + // can not be supported. + if (!mDisplay->getExtensions().protectedContentEXT) + { + supportedExtensions.protectedTexturesEXT = false; + } + + // GL_ANGLE_get_tex_level_parameter is implemented in the front-end + supportedExtensions.getTexLevelParameterANGLE = true; + + // Always enabled. Will return a default string if capture is not enabled. + supportedExtensions.getSerializedContextStringANGLE = true; + + // Performance counter queries are always supported. Different groups exist on each back-end. + supportedExtensions.performanceMonitorAMD = true; + + // GL_ANDROID_extension_pack_es31a + supportedExtensions.extensionPackEs31aANDROID = + CanSupportAEP(getClientVersion(), supportedExtensions); + + return supportedExtensions; +} + +void Context::initCaps() +{ + mState.mCaps = mImplementation->getNativeCaps(); + + // TODO (http://anglebug.com/6010): mSupportedExtensions should not be modified here + mSupportedExtensions = generateSupportedExtensions(); + + if (!mDisplay->getFrontendFeatures().allowCompressedFormats.enabled) + { + INFO() << "Limiting compressed format support.\n"; + + mSupportedExtensions.compressedEACR11SignedTextureOES = false; + mSupportedExtensions.compressedEACR11UnsignedTextureOES = false; + mSupportedExtensions.compressedEACRG11SignedTextureOES = false; + mSupportedExtensions.compressedEACRG11UnsignedTextureOES = false; + mSupportedExtensions.compressedETC1RGB8SubTextureEXT = false; + mSupportedExtensions.compressedETC1RGB8TextureOES = false; + mSupportedExtensions.compressedETC2PunchthroughARGBA8TextureOES = false; + mSupportedExtensions.compressedETC2PunchthroughASRGB8AlphaTextureOES = false; + mSupportedExtensions.compressedETC2RGB8TextureOES = false; + mSupportedExtensions.compressedETC2RGBA8TextureOES = false; + mSupportedExtensions.compressedETC2SRGB8Alpha8TextureOES = false; + mSupportedExtensions.compressedETC2SRGB8TextureOES = false; + mSupportedExtensions.compressedTextureEtcANGLE = false; + mSupportedExtensions.textureCompressionPvrtcIMG = false; + mSupportedExtensions.pvrtcSRGBEXT = false; + mSupportedExtensions.copyCompressedTextureCHROMIUM = false; + mSupportedExtensions.textureCompressionAstcHdrKHR = false; + mSupportedExtensions.textureCompressionAstcLdrKHR = false; + mSupportedExtensions.textureCompressionAstcOES = false; + mSupportedExtensions.textureCompressionBptcEXT = false; + mSupportedExtensions.textureCompressionDxt1EXT = false; + mSupportedExtensions.textureCompressionDxt3ANGLE = false; + mSupportedExtensions.textureCompressionDxt5ANGLE = false; + mSupportedExtensions.textureCompressionRgtcEXT = false; + mSupportedExtensions.textureCompressionS3tcSrgbEXT = false; + mSupportedExtensions.textureCompressionAstcSliced3dKHR = false; + mSupportedExtensions.textureFilteringHintCHROMIUM = false; + + mState.mCaps.compressedTextureFormats.clear(); + } + + mState.mExtensions = mSupportedExtensions; + + mState.mLimitations = mImplementation->getNativeLimitations(); + + // GLES1 emulation: Initialize caps (Table 6.20 / 6.22 in the ES 1.1 spec) + if (getClientType() == EGL_OPENGL_API || getClientVersion() < Version(2, 0)) + { + mState.mCaps.maxMultitextureUnits = 4; + mState.mCaps.maxClipPlanes = 6; + mState.mCaps.maxLights = 8; + mState.mCaps.maxModelviewMatrixStackDepth = Caps::GlobalMatrixStackDepth; + mState.mCaps.maxProjectionMatrixStackDepth = Caps::GlobalMatrixStackDepth; + mState.mCaps.maxTextureMatrixStackDepth = Caps::GlobalMatrixStackDepth; + mState.mCaps.minSmoothPointSize = 1.0f; + mState.mCaps.maxSmoothPointSize = 1.0f; + mState.mCaps.minSmoothLineWidth = 1.0f; + mState.mCaps.maxSmoothLineWidth = 1.0f; + } + + mState.mCaps.maxDebugMessageLength = 1024; + mState.mCaps.maxDebugLoggedMessages = 1024; + mState.mCaps.maxDebugGroupStackDepth = 1024; + mState.mCaps.maxLabelLength = 1024; + + if (getClientVersion() < Version(3, 0)) + { + mState.mCaps.maxViews = 1u; + } + +#if 0 +// This logging can generate a lot of spam in test suites that create many contexts +# define ANGLE_LOG_LIMITED_CAP(cap, limit) \ + INFO() << "Limiting " << #cap << " to implementation limit " << (limit) << " (was " \ + << (cap) << ")." +#else +# define ANGLE_LOG_LIMITED_CAP(cap, limit) +#endif + +#define ANGLE_LIMIT_CAP(cap, limit) \ + do \ + { \ + if ((cap) > (limit)) \ + { \ + ANGLE_LOG_LIMITED_CAP(cap, limit); \ + (cap) = (limit); \ + } \ + } while (0) + + // Apply/Verify implementation limits + ANGLE_LIMIT_CAP(mState.mCaps.maxDrawBuffers, IMPLEMENTATION_MAX_DRAW_BUFFERS); + ANGLE_LIMIT_CAP(mState.mCaps.maxColorAttachments, IMPLEMENTATION_MAX_DRAW_BUFFERS); + ANGLE_LIMIT_CAP(mState.mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS); + ANGLE_LIMIT_CAP(mState.mCaps.maxVertexAttribStride, + static_cast(limits::kMaxVertexAttribStride)); + + ASSERT(mState.mCaps.minAliasedPointSize >= 1.0f); + + if (getClientVersion() < ES_3_1) + { + mState.mCaps.maxVertexAttribBindings = mState.mCaps.maxVertexAttributes; + } + else + { + ANGLE_LIMIT_CAP(mState.mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS); + } + + if (mWebGLContext && getLimitations().limitWebglMaxTextureSizeTo4096) + { + constexpr GLint kMaxTextureSize = 4096; + ANGLE_LIMIT_CAP(mState.mCaps.max2DTextureSize, kMaxTextureSize); + ANGLE_LIMIT_CAP(mState.mCaps.max3DTextureSize, kMaxTextureSize); + ANGLE_LIMIT_CAP(mState.mCaps.maxCubeMapTextureSize, kMaxTextureSize); + ANGLE_LIMIT_CAP(mState.mCaps.maxArrayTextureLayers, kMaxTextureSize); + ANGLE_LIMIT_CAP(mState.mCaps.maxRectangleTextureSize, kMaxTextureSize); + } + + ANGLE_LIMIT_CAP(mState.mCaps.max2DTextureSize, IMPLEMENTATION_MAX_2D_TEXTURE_SIZE); + ANGLE_LIMIT_CAP(mState.mCaps.maxCubeMapTextureSize, IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE); + ANGLE_LIMIT_CAP(mState.mCaps.max3DTextureSize, IMPLEMENTATION_MAX_3D_TEXTURE_SIZE); + ANGLE_LIMIT_CAP(mState.mCaps.maxArrayTextureLayers, IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS); + ANGLE_LIMIT_CAP(mState.mCaps.maxRectangleTextureSize, IMPLEMENTATION_MAX_2D_TEXTURE_SIZE); + + ANGLE_LIMIT_CAP(mState.mCaps.maxShaderUniformBlocks[ShaderType::Vertex], + IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS); + ANGLE_LIMIT_CAP(mState.mCaps.maxShaderUniformBlocks[ShaderType::Geometry], + IMPLEMENTATION_MAX_GEOMETRY_SHADER_UNIFORM_BUFFERS); + ANGLE_LIMIT_CAP(mState.mCaps.maxShaderUniformBlocks[ShaderType::Fragment], + IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS); + ANGLE_LIMIT_CAP(mState.mCaps.maxShaderUniformBlocks[ShaderType::Compute], + IMPLEMENTATION_MAX_COMPUTE_SHADER_UNIFORM_BUFFERS); + ANGLE_LIMIT_CAP(mState.mCaps.maxCombinedUniformBlocks, + IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS); + ANGLE_LIMIT_CAP(mState.mCaps.maxUniformBufferBindings, + IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS); + + ANGLE_LIMIT_CAP(mState.mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4); + ANGLE_LIMIT_CAP(mState.mCaps.maxFragmentInputComponents, + IMPLEMENTATION_MAX_VARYING_VECTORS * 4); + + ANGLE_LIMIT_CAP(mState.mCaps.maxTransformFeedbackInterleavedComponents, + IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS); + ANGLE_LIMIT_CAP(mState.mCaps.maxTransformFeedbackSeparateAttributes, + IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS); + ANGLE_LIMIT_CAP(mState.mCaps.maxTransformFeedbackSeparateComponents, + IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS); + + if (getClientVersion() < ES_3_2 && !mState.mExtensions.tessellationShaderEXT) + { + ANGLE_LIMIT_CAP(mState.mCaps.maxCombinedTextureImageUnits, + IMPLEMENTATION_MAX_ES31_ACTIVE_TEXTURES); + } + else + { + ANGLE_LIMIT_CAP(mState.mCaps.maxCombinedTextureImageUnits, + IMPLEMENTATION_MAX_ACTIVE_TEXTURES); + } + + for (ShaderType shaderType : AllShaderTypes()) + { + ANGLE_LIMIT_CAP(mState.mCaps.maxShaderTextureImageUnits[shaderType], + IMPLEMENTATION_MAX_SHADER_TEXTURES); + } + + ANGLE_LIMIT_CAP(mState.mCaps.maxImageUnits, IMPLEMENTATION_MAX_IMAGE_UNITS); + ANGLE_LIMIT_CAP(mState.mCaps.maxCombinedImageUniforms, IMPLEMENTATION_MAX_IMAGE_UNITS); + for (ShaderType shaderType : AllShaderTypes()) + { + ANGLE_LIMIT_CAP(mState.mCaps.maxShaderImageUniforms[shaderType], + IMPLEMENTATION_MAX_IMAGE_UNITS); + } + + for (ShaderType shaderType : AllShaderTypes()) + { + ANGLE_LIMIT_CAP(mState.mCaps.maxShaderAtomicCounterBuffers[shaderType], + IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS); + } + ANGLE_LIMIT_CAP(mState.mCaps.maxAtomicCounterBufferBindings, + IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS); + ANGLE_LIMIT_CAP(mState.mCaps.maxCombinedAtomicCounterBuffers, + IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS); + + for (ShaderType shaderType : AllShaderTypes()) + { + ANGLE_LIMIT_CAP(mState.mCaps.maxShaderStorageBlocks[shaderType], + IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS); + } + ANGLE_LIMIT_CAP(mState.mCaps.maxShaderStorageBufferBindings, + IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS); + ANGLE_LIMIT_CAP(mState.mCaps.maxCombinedShaderStorageBlocks, + IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS); + + ANGLE_LIMIT_CAP(mState.mCaps.maxClipDistances, IMPLEMENTATION_MAX_CLIP_DISTANCES); + + ANGLE_LIMIT_CAP(mState.mCaps.maxFramebufferLayers, IMPLEMENTATION_MAX_FRAMEBUFFER_LAYERS); + + ANGLE_LIMIT_CAP(mState.mCaps.maxSampleMaskWords, IMPLEMENTATION_MAX_SAMPLE_MASK_WORDS); + ANGLE_LIMIT_CAP(mState.mCaps.maxSamples, IMPLEMENTATION_MAX_SAMPLES); + ANGLE_LIMIT_CAP(mState.mCaps.maxFramebufferSamples, IMPLEMENTATION_MAX_SAMPLES); + ANGLE_LIMIT_CAP(mState.mCaps.maxColorTextureSamples, IMPLEMENTATION_MAX_SAMPLES); + ANGLE_LIMIT_CAP(mState.mCaps.maxDepthTextureSamples, IMPLEMENTATION_MAX_SAMPLES); + ANGLE_LIMIT_CAP(mState.mCaps.maxIntegerSamples, IMPLEMENTATION_MAX_SAMPLES); + + ANGLE_LIMIT_CAP(mState.mCaps.maxViews, IMPLEMENTATION_ANGLE_MULTIVIEW_MAX_VIEWS); + + ANGLE_LIMIT_CAP(mState.mCaps.maxDualSourceDrawBuffers, + IMPLEMENTATION_MAX_DUAL_SOURCE_DRAW_BUFFERS); + + // WebGL compatibility + mState.mExtensions.webglCompatibilityANGLE = mWebGLContext; + for (const auto &extensionInfo : GetExtensionInfoMap()) + { + // If the user has requested that extensions start disabled and they are requestable, + // disable them. + if (!mExtensionsEnabled && extensionInfo.second.Requestable) + { + mState.mExtensions.*(extensionInfo.second.ExtensionsMember) = false; + } + } + + // Hide emulated ETC1 extension from WebGL contexts. + if (mWebGLContext && getLimitations().emulatedEtc1) + { + mSupportedExtensions.compressedETC1RGB8SubTextureEXT = false; + mSupportedExtensions.compressedETC1RGB8TextureOES = false; + } + + if (getLimitations().emulatedAstc) + { + // Hide emulated ASTC extension from WebGL contexts. + if (mWebGLContext) + { + mSupportedExtensions.textureCompressionAstcLdrKHR = false; + mState.mExtensions.textureCompressionAstcLdrKHR = false; + } +#if !defined(ANGLE_HAS_ASTCENC) + // Don't expose emulated ASTC when it's not built. + mSupportedExtensions.textureCompressionAstcLdrKHR = false; + mState.mExtensions.textureCompressionAstcLdrKHR = false; +#endif + } + + // If we're capturing application calls for replay, apply some feature limits to increase + // portability of the trace. + if (getShareGroup()->getFrameCaptureShared()->enabled() || + getFrontendFeatures().enableCaptureLimits.enabled) + { + INFO() << "Limit some features because " + << (getShareGroup()->getFrameCaptureShared()->enabled() + ? "FrameCapture is enabled" + : "FrameCapture limits were forced") + << std::endl; + + if (!getFrontendFeatures().enableProgramBinaryForCapture.enabled) + { + // Some apps insist on being able to use glProgramBinary. For those, we'll allow the + // extension to remain on. Otherwise, force the extension off. + INFO() << "Disabling GL_OES_get_program_binary for trace portability"; + mDisplay->overrideFrontendFeatures({"disable_program_binary"}, true); + } + + // Set to the most common limit per gpuinfo.org. Required for several platforms we test. + constexpr GLint maxImageUnits = 8; + INFO() << "Limiting image unit count to " << maxImageUnits; + ANGLE_LIMIT_CAP(mState.mCaps.maxImageUnits, maxImageUnits); + for (ShaderType shaderType : AllShaderTypes()) + { + ANGLE_LIMIT_CAP(mState.mCaps.maxShaderImageUniforms[shaderType], maxImageUnits); + } + + // Set a large uniform buffer offset alignment that works on multiple platforms. + // The offset used by the trace needs to be divisible by the device's actual value. + // Values seen during development: ARM (16), Intel (32), Qualcomm (128), Nvidia (256) + constexpr GLint uniformBufferOffsetAlignment = 256; + ASSERT(uniformBufferOffsetAlignment % mState.mCaps.uniformBufferOffsetAlignment == 0); + INFO() << "Setting uniform buffer offset alignment to " << uniformBufferOffsetAlignment; + mState.mCaps.uniformBufferOffsetAlignment = uniformBufferOffsetAlignment; + + // Also limit texture buffer offset alignment, if enabled + if (mState.mExtensions.textureBufferAny()) + { + constexpr GLint textureBufferOffsetAlignment = + gl::limits::kMinTextureBufferOffsetAlignment; + ASSERT(textureBufferOffsetAlignment % mState.mCaps.textureBufferOffsetAlignment == 0); + INFO() << "Setting texture buffer offset alignment to " << textureBufferOffsetAlignment; + mState.mCaps.textureBufferOffsetAlignment = textureBufferOffsetAlignment; + } + + INFO() << "Disabling GL_EXT_map_buffer_range and GL_OES_mapbuffer during capture, which " + "are not supported on some native drivers"; + mState.mExtensions.mapBufferRangeEXT = false; + mState.mExtensions.mapbufferOES = false; + + INFO() << "Disabling GL_CHROMIUM_bind_uniform_location during capture, which is not " + "supported on native drivers"; + mState.mExtensions.bindUniformLocationCHROMIUM = false; + + INFO() << "Disabling GL_NV_shader_noperspective_interpolation during capture, which is not " + "supported on some native drivers"; + mState.mExtensions.shaderNoperspectiveInterpolationNV = false; + + INFO() << "Disabling GL_NV_framebuffer_blit during capture, which is not " + "supported on some native drivers"; + mState.mExtensions.framebufferBlitNV = false; + + // NVIDIA's Vulkan driver only supports 4 draw buffers + constexpr GLint maxDrawBuffers = 4; + INFO() << "Limiting draw buffer count to " << maxDrawBuffers; + ANGLE_LIMIT_CAP(mState.mCaps.maxDrawBuffers, maxDrawBuffers); + + // Unity based applications are sending down GL streams with undefined behavior. + // Disabling EGL_KHR_create_context_no_error (which enables a new EGL attrib) prevents that, + // but we don't have the infrastructure for disabling EGL extensions yet. + // Instead, disable GL_KHR_no_error (which disables exposing the GL extension), which + // prevents writing invalid calls to the capture. + INFO() << "Enabling validation to prevent invalid calls from being captured. This " + "effectively disables GL_KHR_no_error and enables GL_ANGLE_robust_client_memory."; + mSkipValidation = false; + mState.mExtensions.noErrorKHR = mSkipValidation; + mState.mExtensions.robustClientMemoryANGLE = !mSkipValidation; + + INFO() << "Disabling GL_OES_depth32 during capture, which is not widely supported on " + "mobile"; + mState.mExtensions.depth32OES = false; + + // Pixel 4 (Qualcomm) only supports 6 atomic counter buffer bindings. + constexpr GLint maxAtomicCounterBufferBindings = 6; + INFO() << "Limiting max atomic counter buffer bindings to " + << maxAtomicCounterBufferBindings; + ANGLE_LIMIT_CAP(mState.mCaps.maxAtomicCounterBufferBindings, + maxAtomicCounterBufferBindings); + for (gl::ShaderType shaderType : gl::AllShaderTypes()) + { + ANGLE_LIMIT_CAP(mState.mCaps.maxShaderAtomicCounterBuffers[shaderType], + maxAtomicCounterBufferBindings); + } + + // SwiftShader only supports 12 shader storage buffer bindings. + constexpr GLint maxShaderStorageBufferBindings = 12; + INFO() << "Limiting max shader storage buffer bindings to " + << maxShaderStorageBufferBindings; + ANGLE_LIMIT_CAP(mState.mCaps.maxShaderStorageBufferBindings, + maxShaderStorageBufferBindings); + for (gl::ShaderType shaderType : gl::AllShaderTypes()) + { + ANGLE_LIMIT_CAP(mState.mCaps.maxShaderStorageBlocks[shaderType], + maxShaderStorageBufferBindings); + } + + // Pixel 4 only supports GL_MAX_SAMPLES of 4 + constexpr GLint maxSamples = 4; + INFO() << "Limiting GL_MAX_SAMPLES to " << maxSamples; + ANGLE_LIMIT_CAP(mState.mCaps.maxSamples, maxSamples); + } + + // Disable support for OES_get_program_binary + if (mDisplay->getFrontendFeatures().disableProgramBinary.enabled) + { + mState.mExtensions.getProgramBinaryOES = false; + mState.mCaps.shaderBinaryFormats.clear(); + mState.mCaps.programBinaryFormats.clear(); + mMemoryProgramCache = nullptr; + } + + if (mSupportedExtensions.shaderPixelLocalStorageANGLE) + { + int maxDrawableAttachments = + std::min(mState.mCaps.maxDrawBuffers, mState.mCaps.maxColorAttachments); + ShPixelLocalStorageType plsType = mImplementation->getNativePixelLocalStorageType(); + if (ShPixelLocalStorageTypeUsesImages(plsType)) + { + mState.mCaps.maxPixelLocalStoragePlanes = + mState.mCaps.maxShaderImageUniforms[ShaderType::Fragment]; + ANGLE_LIMIT_CAP(mState.mCaps.maxPixelLocalStoragePlanes, + IMPLEMENTATION_MAX_PIXEL_LOCAL_STORAGE_PLANES); + mState.mCaps.maxColorAttachmentsWithActivePixelLocalStorage = + mState.mCaps.maxColorAttachments; + mState.mCaps.maxCombinedDrawBuffersAndPixelLocalStoragePlanes = std::min( + mState.mCaps.maxPixelLocalStoragePlanes + + std::min(mState.mCaps.maxDrawBuffers, mState.mCaps.maxColorAttachments), + mState.mCaps.maxCombinedShaderOutputResources); + } + else + { + ASSERT(plsType == ShPixelLocalStorageType::FramebufferFetch); + mState.mCaps.maxPixelLocalStoragePlanes = maxDrawableAttachments; + ANGLE_LIMIT_CAP(mState.mCaps.maxPixelLocalStoragePlanes, + IMPLEMENTATION_MAX_PIXEL_LOCAL_STORAGE_PLANES); + if (!mSupportedExtensions.drawBuffersIndexedAny()) + { + // When pixel local storage is implemented as framebuffer attachments, we need to + // disable color masks and blending to its attachments. If the backend context + // doesn't have indexed blend and color mask support, then we will have have to + // disable them globally. This also means the application can't have its own draw + // buffers while PLS is active. + mState.mCaps.maxColorAttachmentsWithActivePixelLocalStorage = 0; + } + else + { + mState.mCaps.maxColorAttachmentsWithActivePixelLocalStorage = + maxDrawableAttachments - 1; + } + mState.mCaps.maxCombinedDrawBuffersAndPixelLocalStoragePlanes = maxDrawableAttachments; + } + } + +#undef ANGLE_LIMIT_CAP +#undef ANGLE_LOG_CAP_LIMIT + + // Generate texture caps + updateCaps(); +} + +void Context::updateCaps() +{ + mState.mCaps.compressedTextureFormats.clear(); + mState.mTextureCaps.clear(); + + for (GLenum sizedInternalFormat : GetAllSizedInternalFormats()) + { + TextureCaps formatCaps = mImplementation->getNativeTextureCaps().get(sizedInternalFormat); + const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat); + + // Update the format caps based on the client version and extensions. + // Caps are AND'd with the renderer caps because some core formats are still unsupported in + // ES3. + formatCaps.texturable = formatCaps.texturable && + formatInfo.textureSupport(getClientVersion(), mState.mExtensions); + formatCaps.filterable = formatCaps.filterable && + formatInfo.filterSupport(getClientVersion(), mState.mExtensions); + formatCaps.textureAttachment = + formatCaps.textureAttachment && + formatInfo.textureAttachmentSupport(getClientVersion(), mState.mExtensions); + formatCaps.renderbuffer = + formatCaps.renderbuffer && + formatInfo.renderbufferSupport(getClientVersion(), mState.mExtensions); + formatCaps.blendable = + formatCaps.blendable && formatInfo.blendSupport(getClientVersion(), mState.mExtensions); + + // OpenGL ES does not support multisampling with non-rendererable formats + // OpenGL ES 3.0 or prior does not support multisampling with integer formats + if (!formatCaps.renderbuffer || + (getClientVersion() < ES_3_1 && !mState.mExtensions.textureMultisampleANGLE && + formatInfo.isInt())) + { + formatCaps.sampleCounts.clear(); + } + else + { + // We may have limited the max samples for some required renderbuffer formats due to + // non-conformant formats. In this case MAX_SAMPLES needs to be lowered accordingly. + GLuint formatMaxSamples = formatCaps.getMaxSamples(); + + // GLES 3.0.5 section 4.4.2.2: "Implementations must support creation of renderbuffers + // in these required formats with up to the value of MAX_SAMPLES multisamples, with the + // exception of signed and unsigned integer formats." + if (!formatInfo.isInt() && formatInfo.isRequiredRenderbufferFormat(getClientVersion())) + { + ASSERT(getClientVersion() < ES_3_0 || formatMaxSamples >= 4); + mState.mCaps.maxSamples = + std::min(static_cast(mState.mCaps.maxSamples), formatMaxSamples); + } + + // Handle GLES 3.1 MAX_*_SAMPLES values similarly to MAX_SAMPLES. + if (getClientVersion() >= ES_3_1 || mState.mExtensions.textureMultisampleANGLE) + { + // GLES 3.1 section 9.2.5: "Implementations must support creation of renderbuffers + // in these required formats with up to the value of MAX_SAMPLES multisamples, with + // the exception that the signed and unsigned integer formats are required only to + // support creation of renderbuffers with up to the value of MAX_INTEGER_SAMPLES + // multisamples, which must be at least one." + if (formatInfo.isInt()) + { + mState.mCaps.maxIntegerSamples = std::min( + static_cast(mState.mCaps.maxIntegerSamples), formatMaxSamples); + } + + // GLES 3.1 section 19.3.1. + if (formatCaps.texturable) + { + if (formatInfo.depthBits > 0) + { + mState.mCaps.maxDepthTextureSamples = + std::min(static_cast(mState.mCaps.maxDepthTextureSamples), + formatMaxSamples); + } + else if (formatInfo.redBits > 0) + { + mState.mCaps.maxColorTextureSamples = + std::min(static_cast(mState.mCaps.maxColorTextureSamples), + formatMaxSamples); + } + } + } + } + + if (formatCaps.texturable && (formatInfo.compressed || formatInfo.paletted)) + { + mState.mCaps.compressedTextureFormats.push_back(sizedInternalFormat); + } + + mState.mTextureCaps.insert(sizedInternalFormat, formatCaps); + } + + // If program binary is disabled, blank out the memory cache pointer. + if (!mSupportedExtensions.getProgramBinaryOES) + { + mMemoryProgramCache = nullptr; + } + + // Compute which buffer types are allowed + mValidBufferBindings.reset(); + mValidBufferBindings.set(BufferBinding::ElementArray); + mValidBufferBindings.set(BufferBinding::Array); + + if (mState.mExtensions.pixelBufferObjectNV || getClientVersion() >= ES_3_0) + { + mValidBufferBindings.set(BufferBinding::PixelPack); + mValidBufferBindings.set(BufferBinding::PixelUnpack); + } + + if (getClientVersion() >= ES_3_0) + { + mValidBufferBindings.set(BufferBinding::CopyRead); + mValidBufferBindings.set(BufferBinding::CopyWrite); + mValidBufferBindings.set(BufferBinding::TransformFeedback); + mValidBufferBindings.set(BufferBinding::Uniform); + } + + if (getClientVersion() >= ES_3_1) + { + mValidBufferBindings.set(BufferBinding::AtomicCounter); + mValidBufferBindings.set(BufferBinding::ShaderStorage); + mValidBufferBindings.set(BufferBinding::DrawIndirect); + mValidBufferBindings.set(BufferBinding::DispatchIndirect); + } + + if (getClientVersion() >= ES_3_2 || mState.mExtensions.textureBufferAny()) + { + mValidBufferBindings.set(BufferBinding::Texture); + } + + if (!mState.mExtensions.parallelShaderCompileKHR) + { + mSingleThreadPool = angle::WorkerThreadPool::Create(false); + } + mMultiThreadPool = angle::WorkerThreadPool::Create( + mState.mExtensions.parallelShaderCompileKHR || + getFrontendFeatures().enableCompressingPipelineCacheInThreadPool.enabled); + + // Reinitialize some dirty bits that depend on extensions. + if (mState.isRobustResourceInitEnabled()) + { + mDrawDirtyObjects.set(State::DIRTY_OBJECT_DRAW_ATTACHMENTS); + mDrawDirtyObjects.set(State::DIRTY_OBJECT_TEXTURES_INIT); + mDrawDirtyObjects.set(State::DIRTY_OBJECT_IMAGES_INIT); + mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_ATTACHMENTS); + mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_ATTACHMENTS); + mComputeDirtyObjects.set(State::DIRTY_OBJECT_TEXTURES_INIT); + mComputeDirtyObjects.set(State::DIRTY_OBJECT_IMAGES_INIT); + mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_ATTACHMENTS); + mCopyImageDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING); + mCopyImageDirtyObjects.set(State::DIRTY_OBJECT_READ_ATTACHMENTS); + } + + // We need to validate buffer bounds if we are in a WebGL or robust access context and the + // back-end does not support robust buffer access behaviour. + mBufferAccessValidationEnabled = (!mSupportedExtensions.robustBufferAccessBehaviorKHR && + (mState.isWebGL() || mState.hasRobustAccess())); + + // Cache this in the VertexArrays. They need to check it in state change notifications. + for (auto vaoIter : mVertexArrayMap) + { + VertexArray *vao = vaoIter.second; + vao->setBufferAccessValidationEnabled(mBufferAccessValidationEnabled); + } + + // Reinitialize state cache after extension changes. + mStateCache.initialize(this); +} + +bool Context::noopDrawInstanced(PrimitiveMode mode, GLsizei count, GLsizei instanceCount) const +{ + return (instanceCount == 0) || noopDraw(mode, count); +} + +angle::Result Context::prepareForClear(GLbitfield mask) +{ + // Sync the draw framebuffer manually after the clear attachments. + ANGLE_TRY(mState.getDrawFramebuffer()->ensureClearAttachmentsInitialized(this, mask)); + return syncStateForClear(); +} + +angle::Result Context::prepareForClearBuffer(GLenum buffer, GLint drawbuffer) +{ + // Sync the draw framebuffer manually after the clear attachments. + ANGLE_TRY(mState.getDrawFramebuffer()->ensureClearBufferAttachmentsInitialized(this, buffer, + drawbuffer)); + return syncStateForClear(); +} + +ANGLE_INLINE angle::Result Context::prepareForCopyImage() +{ + ANGLE_TRY(syncDirtyObjects(mCopyImageDirtyObjects, Command::CopyImage)); + return syncDirtyBits(mCopyImageDirtyBits, Command::CopyImage); +} + +ANGLE_INLINE angle::Result Context::prepareForDispatch() +{ + // Converting a PPO from graphics to compute requires re-linking it. + // The compute shader must have successfully linked before being included in the PPO, so no link + // errors that would have been caught during validation should be possible when re-linking the + // PPO with the compute shader. + Program *program = mState.getProgram(); + ProgramPipeline *pipeline = mState.getProgramPipeline(); + if (!program && pipeline) + { + // Linking the PPO can't fail due to a validation error within the compute program, + // since it successfully linked already in order to become part of the PPO in the first + // place. + pipeline->resolveLink(this); + ANGLE_CHECK(this, pipeline->isLinked(), "Program pipeline link failed", + GL_INVALID_OPERATION); + } + + ANGLE_TRY(syncDirtyObjects(mComputeDirtyObjects, Command::Dispatch)); + return syncDirtyBits(mComputeDirtyBits, Command::Dispatch); +} + +angle::Result Context::prepareForInvalidate(GLenum target) +{ + // Only sync the FBO that's being invalidated. Per the GLES3 spec, GL_FRAMEBUFFER is equivalent + // to GL_DRAW_FRAMEBUFFER for the purposes of invalidation. + GLenum effectiveTarget = target; + if (effectiveTarget == GL_FRAMEBUFFER) + { + effectiveTarget = GL_DRAW_FRAMEBUFFER; + } + ANGLE_TRY(mState.syncDirtyObject(this, effectiveTarget)); + return syncDirtyBits(effectiveTarget == GL_READ_FRAMEBUFFER ? mReadInvalidateDirtyBits + : mDrawInvalidateDirtyBits, + Command::Invalidate); +} + +angle::Result Context::syncState(const State::DirtyBits &bitMask, + const State::DirtyObjects &objectMask, + Command command) +{ + ANGLE_TRY(syncDirtyObjects(objectMask, command)); + ANGLE_TRY(syncDirtyBits(bitMask, command)); + return angle::Result::Continue; +} + +void Context::blitFramebuffer(GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter) +{ + if (mask == 0) + { + // ES3.0 spec, section 4.3.2 specifies that a mask of zero is valid and no + // buffers are copied. + return; + } + + Framebuffer *drawFramebuffer = mState.getDrawFramebuffer(); + ASSERT(drawFramebuffer); + + // Note that blitting is called against draw framebuffer. + // See the code in gl::Context::blitFramebuffer. + if ((mask & GL_COLOR_BUFFER_BIT) && !drawFramebuffer->hasEnabledDrawBuffer()) + { + mask &= ~GL_COLOR_BUFFER_BIT; + } + + if ((mask & GL_STENCIL_BUFFER_BIT) && + drawFramebuffer->getState().getStencilAttachment() == nullptr) + { + mask &= ~GL_STENCIL_BUFFER_BIT; + } + + if ((mask & GL_DEPTH_BUFFER_BIT) && drawFramebuffer->getState().getDepthAttachment() == nullptr) + { + mask &= ~GL_DEPTH_BUFFER_BIT; + } + + // Early out if none of the specified attachments exist or are enabled. + if (mask == 0) + { + ANGLE_PERF_WARNING(mState.getDebug(), GL_DEBUG_SEVERITY_LOW, + "BlitFramebuffer called for non-existing buffers"); + return; + } + + Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0); + Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0); + + if (dstArea.width == 0 || dstArea.height == 0) + { + return; + } + + ANGLE_CONTEXT_TRY(syncStateForBlit(mask)); + ANGLE_CONTEXT_TRY(drawFramebuffer->blit(this, srcArea, dstArea, mask, filter)); +} + +void Context::blitFramebufferNV(GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter) +{ + blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); +} + +void Context::clear(GLbitfield mask) +{ + if (mState.isRasterizerDiscardEnabled()) + { + return; + } + + // Noop empty scissors. + if (IsEmptyScissor(mState)) + { + return; + } + + // Remove clear bits that are ineffective. An effective clear changes at least one fragment. If + // color/depth/stencil masks make the clear ineffective we skip it altogether. + + // If all color channels in all draw buffers are masked, don't attempt to clear color. + if (mState.allActiveDrawBufferChannelsMasked()) + { + mask &= ~GL_COLOR_BUFFER_BIT; + } + + // If depth write is disabled, don't attempt to clear depth. + if (mState.getDrawFramebuffer()->getDepthAttachment() == nullptr || + !mState.getDepthStencilState().depthMask) + { + mask &= ~GL_DEPTH_BUFFER_BIT; + } + + // If all stencil bits are masked, don't attempt to clear stencil. + if (mState.getDrawFramebuffer()->getStencilAttachment() == nullptr || + (angle::BitMask( + mState.getDrawFramebuffer()->getStencilAttachment()->getStencilSize()) & + mState.getDepthStencilState().stencilWritemask) == 0) + { + mask &= ~GL_STENCIL_BUFFER_BIT; + } + + if (mask == 0) + { + ANGLE_PERF_WARNING(mState.getDebug(), GL_DEBUG_SEVERITY_LOW, + "Clear called for non-existing buffers"); + return; + } + + ANGLE_CONTEXT_TRY(prepareForClear(mask)); + ANGLE_CONTEXT_TRY(mState.getDrawFramebuffer()->clear(this, mask)); +} + +bool Context::isClearBufferMaskedOut(GLenum buffer, GLint drawbuffer) const +{ + switch (buffer) + { + case GL_COLOR: + return IsColorMaskedOut(mState.getBlendStateExt(), drawbuffer); + case GL_DEPTH: + return mState.getDepthStencilState().isDepthMaskedOut(); + case GL_STENCIL: + return mState.getDepthStencilState().isStencilMaskedOut(); + case GL_DEPTH_STENCIL: + return mState.getDepthStencilState().isDepthMaskedOut() && + mState.getDepthStencilState().isStencilMaskedOut(); + default: + UNREACHABLE(); + return true; + } +} + +bool Context::noopClearBuffer(GLenum buffer, GLint drawbuffer) const +{ + Framebuffer *framebufferObject = mState.getDrawFramebuffer(); + + return !IsClearBufferEnabled(framebufferObject->getState(), buffer, drawbuffer) || + mState.isRasterizerDiscardEnabled() || isClearBufferMaskedOut(buffer, drawbuffer) || + IsEmptyScissor(mState); +} + +void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values) +{ + if (noopClearBuffer(buffer, drawbuffer)) + { + return; + } + + Framebuffer *framebufferObject = mState.getDrawFramebuffer(); + const FramebufferAttachment *attachment = nullptr; + if (buffer == GL_DEPTH) + { + attachment = framebufferObject->getDepthAttachment(); + } + else if (buffer == GL_COLOR && + static_cast(drawbuffer) < framebufferObject->getNumColorAttachments()) + { + attachment = framebufferObject->getColorAttachment(drawbuffer); + } + // It's not an error to try to clear a non-existent buffer, but it's a no-op. We early out so + // that the backend doesn't need to take this case into account. + if (!attachment) + { + return; + } + ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer)); + ANGLE_CONTEXT_TRY(framebufferObject->clearBufferfv(this, buffer, drawbuffer, values)); +} + +void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values) +{ + if (noopClearBuffer(buffer, drawbuffer)) + { + return; + } + + Framebuffer *framebufferObject = mState.getDrawFramebuffer(); + const FramebufferAttachment *attachment = nullptr; + if (buffer == GL_COLOR && + static_cast(drawbuffer) < framebufferObject->getNumColorAttachments()) + { + attachment = framebufferObject->getColorAttachment(drawbuffer); + } + // It's not an error to try to clear a non-existent buffer, but it's a no-op. We early out so + // that the backend doesn't need to take this case into account. + if (!attachment) + { + return; + } + ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer)); + ANGLE_CONTEXT_TRY(framebufferObject->clearBufferuiv(this, buffer, drawbuffer, values)); +} + +void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values) +{ + if (noopClearBuffer(buffer, drawbuffer)) + { + return; + } + + Framebuffer *framebufferObject = mState.getDrawFramebuffer(); + const FramebufferAttachment *attachment = nullptr; + if (buffer == GL_STENCIL) + { + attachment = framebufferObject->getStencilAttachment(); + } + else if (buffer == GL_COLOR && + static_cast(drawbuffer) < framebufferObject->getNumColorAttachments()) + { + attachment = framebufferObject->getColorAttachment(drawbuffer); + } + // It's not an error to try to clear a non-existent buffer, but it's a no-op. We early out so + // that the backend doesn't need to take this case into account. + if (!attachment) + { + return; + } + ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer)); + ANGLE_CONTEXT_TRY(framebufferObject->clearBufferiv(this, buffer, drawbuffer, values)); +} + +void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) +{ + if (noopClearBuffer(buffer, drawbuffer)) + { + return; + } + + Framebuffer *framebufferObject = mState.getDrawFramebuffer(); + ASSERT(framebufferObject); + + // If a buffer is not present, the clear has no effect + if (framebufferObject->getDepthAttachment() == nullptr && + framebufferObject->getStencilAttachment() == nullptr) + { + return; + } + + ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer)); + ANGLE_CONTEXT_TRY(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil)); +} + +void Context::readPixels(GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + void *pixels) +{ + if (width == 0 || height == 0) + { + return; + } + + ANGLE_CONTEXT_TRY(syncStateForReadPixels()); + + Framebuffer *readFBO = mState.getReadFramebuffer(); + ASSERT(readFBO); + + Rectangle area(x, y, width, height); + PixelPackState packState = mState.getPackState(); + Buffer *packBuffer = mState.getTargetBuffer(gl::BufferBinding::PixelPack); + ANGLE_CONTEXT_TRY(readFBO->readPixels(this, area, format, type, packState, packBuffer, pixels)); +} + +void Context::readPixelsRobust(GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + GLsizei *length, + GLsizei *columns, + GLsizei *rows, + void *pixels) +{ + readPixels(x, y, width, height, format, type, pixels); +} + +void Context::readnPixelsRobust(GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + GLsizei *length, + GLsizei *columns, + GLsizei *rows, + void *data) +{ + readPixels(x, y, width, height, format, type, data); +} + +void Context::copyTexImage2D(TextureTarget target, + GLint level, + GLenum internalformat, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border) +{ + ANGLE_CONTEXT_TRY(prepareForCopyImage()); + + Rectangle sourceArea(x, y, width, height); + + Framebuffer *framebuffer = mState.getReadFramebuffer(); + Texture *texture = getTextureByTarget(target); + ANGLE_CONTEXT_TRY( + texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer)); +} + +void Context::copyTexSubImage2D(TextureTarget target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) +{ + if (width == 0 || height == 0) + { + return; + } + + ANGLE_CONTEXT_TRY(prepareForCopyImage()); + + Offset destOffset(xoffset, yoffset, 0); + Rectangle sourceArea(x, y, width, height); + + ImageIndex index = ImageIndex::MakeFromTarget(target, level, 1); + + Framebuffer *framebuffer = mState.getReadFramebuffer(); + Texture *texture = getTextureByTarget(target); + ANGLE_CONTEXT_TRY(texture->copySubImage(this, index, destOffset, sourceArea, framebuffer)); +} + +void Context::copyTexSubImage3D(TextureTarget target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) +{ + if (width == 0 || height == 0) + { + return; + } + + ANGLE_CONTEXT_TRY(prepareForCopyImage()); + + Offset destOffset(xoffset, yoffset, zoffset); + Rectangle sourceArea(x, y, width, height); + + ImageIndex index = ImageIndex::MakeFromType(TextureTargetToType(target), level, zoffset); + + Framebuffer *framebuffer = mState.getReadFramebuffer(); + Texture *texture = getTextureByTarget(target); + ANGLE_CONTEXT_TRY(texture->copySubImage(this, index, destOffset, sourceArea, framebuffer)); +} + +void Context::copyImageSubData(GLuint srcName, + GLenum srcTarget, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLuint dstName, + GLenum dstTarget, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth) +{ + // if copy region is zero, the copy is a successful no-op + if ((srcWidth == 0) || (srcHeight == 0) || (srcDepth == 0)) + { + return; + } + + if (srcTarget == GL_RENDERBUFFER) + { + // Source target is a Renderbuffer + Renderbuffer *readBuffer = getRenderbuffer(PackParam(srcName)); + if (dstTarget == GL_RENDERBUFFER) + { + // Destination target is a Renderbuffer + Renderbuffer *writeBuffer = getRenderbuffer(PackParam(dstName)); + + // Copy Renderbuffer to Renderbuffer + ANGLE_CONTEXT_TRY(writeBuffer->copyRenderbufferSubData( + this, readBuffer, srcLevel, srcX, srcY, srcZ, dstLevel, dstX, dstY, dstZ, srcWidth, + srcHeight, srcDepth)); + } + else + { + // Destination target is a Texture + ASSERT(dstTarget == GL_TEXTURE_2D || dstTarget == GL_TEXTURE_2D_ARRAY || + dstTarget == GL_TEXTURE_3D || dstTarget == GL_TEXTURE_CUBE_MAP); + + Texture *writeTexture = getTexture(PackParam(dstName)); + ANGLE_CONTEXT_TRY(syncTextureForCopy(writeTexture)); + + // Copy Renderbuffer to Texture + ANGLE_CONTEXT_TRY(writeTexture->copyRenderbufferSubData( + this, readBuffer, srcLevel, srcX, srcY, srcZ, dstLevel, dstX, dstY, dstZ, srcWidth, + srcHeight, srcDepth)); + } + } + else + { + // Source target is a Texture + ASSERT(srcTarget == GL_TEXTURE_2D || srcTarget == GL_TEXTURE_2D_ARRAY || + srcTarget == GL_TEXTURE_3D || srcTarget == GL_TEXTURE_CUBE_MAP); + + Texture *readTexture = getTexture(PackParam(srcName)); + ANGLE_CONTEXT_TRY(syncTextureForCopy(readTexture)); + + if (dstTarget == GL_RENDERBUFFER) + { + // Destination target is a Renderbuffer + Renderbuffer *writeBuffer = getRenderbuffer(PackParam(dstName)); + + // Copy Texture to Renderbuffer + ANGLE_CONTEXT_TRY(writeBuffer->copyTextureSubData(this, readTexture, srcLevel, srcX, + srcY, srcZ, dstLevel, dstX, dstY, + dstZ, srcWidth, srcHeight, srcDepth)); + } + else + { + // Destination target is a Texture + ASSERT(dstTarget == GL_TEXTURE_2D || dstTarget == GL_TEXTURE_2D_ARRAY || + dstTarget == GL_TEXTURE_3D || dstTarget == GL_TEXTURE_CUBE_MAP); + + Texture *writeTexture = getTexture(PackParam(dstName)); + ANGLE_CONTEXT_TRY(syncTextureForCopy(writeTexture)); + + // Copy Texture to Texture + ANGLE_CONTEXT_TRY(writeTexture->copyTextureSubData( + this, readTexture, srcLevel, srcX, srcY, srcZ, dstLevel, dstX, dstY, dstZ, srcWidth, + srcHeight, srcDepth)); + } + } +} + +void Context::framebufferTexture2D(GLenum target, + GLenum attachment, + TextureTarget textarget, + TextureID texture, + GLint level) +{ + Framebuffer *framebuffer = mState.getTargetFramebuffer(target); + ASSERT(framebuffer); + + if (texture.value != 0) + { + Texture *textureObj = getTexture(texture); + ImageIndex index = ImageIndex::MakeFromTarget(textarget, level, 1); + framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj); + } + else + { + framebuffer->resetAttachment(this, attachment); + } + + mState.setObjectDirty(target); +} + +void Context::framebufferTexture3D(GLenum target, + GLenum attachment, + TextureTarget textargetPacked, + TextureID texture, + GLint level, + GLint zoffset) +{ + Framebuffer *framebuffer = mState.getTargetFramebuffer(target); + ASSERT(framebuffer); + + if (texture.value != 0) + { + Texture *textureObj = getTexture(texture); + ImageIndex index = ImageIndex::Make3D(level, zoffset); + framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj); + } + else + { + framebuffer->resetAttachment(this, attachment); + } + + mState.setObjectDirty(target); +} + +void Context::framebufferRenderbuffer(GLenum target, + GLenum attachment, + GLenum renderbuffertarget, + RenderbufferID renderbuffer) +{ + Framebuffer *framebuffer = mState.getTargetFramebuffer(target); + ASSERT(framebuffer); + + if (renderbuffer.value != 0) + { + Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer); + GLsizei rbSamples = renderbufferObject->getState().getSamples(); + + framebuffer->setAttachmentMultisample(this, GL_RENDERBUFFER, attachment, gl::ImageIndex(), + renderbufferObject, rbSamples); + } + else + { + framebuffer->resetAttachment(this, attachment); + } + + mState.setObjectDirty(target); +} + +void Context::framebufferTextureLayer(GLenum target, + GLenum attachment, + TextureID texture, + GLint level, + GLint layer) +{ + Framebuffer *framebuffer = mState.getTargetFramebuffer(target); + ASSERT(framebuffer); + + if (texture.value != 0) + { + Texture *textureObject = getTexture(texture); + ImageIndex index = ImageIndex::MakeFromType(textureObject->getType(), level, layer); + framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject); + } + else + { + framebuffer->resetAttachment(this, attachment); + } + + mState.setObjectDirty(target); +} + +void Context::framebufferTextureMultiview(GLenum target, + GLenum attachment, + TextureID texture, + GLint level, + GLint baseViewIndex, + GLsizei numViews) +{ + Framebuffer *framebuffer = mState.getTargetFramebuffer(target); + ASSERT(framebuffer); + + if (texture.value != 0) + { + Texture *textureObj = getTexture(texture); + + ImageIndex index; + if (textureObj->getType() == TextureType::_2DArray) + { + index = ImageIndex::Make2DArrayRange(level, baseViewIndex, numViews); + } + else + { + ASSERT(textureObj->getType() == TextureType::_2DMultisampleArray); + ASSERT(level == 0); + index = ImageIndex::Make2DMultisampleArrayRange(baseViewIndex, numViews); + } + framebuffer->setAttachmentMultiview(this, GL_TEXTURE, attachment, index, textureObj, + numViews, baseViewIndex); + } + else + { + framebuffer->resetAttachment(this, attachment); + } + + mState.setObjectDirty(target); +} + +void Context::framebufferTexture(GLenum target, GLenum attachment, TextureID texture, GLint level) +{ + Framebuffer *framebuffer = mState.getTargetFramebuffer(target); + ASSERT(framebuffer); + + if (texture.value != 0) + { + Texture *textureObj = getTexture(texture); + + ImageIndex index = ImageIndex::MakeFromType( + textureObj->getType(), level, ImageIndex::kEntireLevel, ImageIndex::kEntireLevel); + framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj); + } + else + { + framebuffer->resetAttachment(this, attachment); + } + + mState.setObjectDirty(target); +} + +void Context::drawBuffers(GLsizei n, const GLenum *bufs) +{ + Framebuffer *framebuffer = mState.getDrawFramebuffer(); + ASSERT(framebuffer); + framebuffer->setDrawBuffers(n, bufs); + mState.setDrawFramebufferDirty(); + mStateCache.onDrawFramebufferChange(this); +} + +void Context::readBuffer(GLenum mode) +{ + Framebuffer *readFBO = mState.getReadFramebuffer(); + readFBO->setReadBuffer(mode); + mState.setObjectDirty(GL_READ_FRAMEBUFFER); +} + +void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments) +{ + // The specification isn't clear what should be done when the framebuffer isn't complete. + // We threat it the same way as GLES3 glInvalidateFramebuffer. + invalidateFramebuffer(target, numAttachments, attachments); +} + +void Context::invalidateFramebuffer(GLenum target, + GLsizei numAttachments, + const GLenum *attachments) +{ + Framebuffer *framebuffer = mState.getTargetFramebuffer(target); + ASSERT(framebuffer); + + // No-op incomplete FBOs. + if (!framebuffer->isComplete(this)) + { + return; + } + + ANGLE_CONTEXT_TRY(prepareForInvalidate(target)); + ANGLE_CONTEXT_TRY(framebuffer->invalidate(this, numAttachments, attachments)); +} + +void Context::invalidateSubFramebuffer(GLenum target, + GLsizei numAttachments, + const GLenum *attachments, + GLint x, + GLint y, + GLsizei width, + GLsizei height) +{ + Framebuffer *framebuffer = mState.getTargetFramebuffer(target); + ASSERT(framebuffer); + + if (!framebuffer->isComplete(this)) + { + return; + } + + Rectangle area(x, y, width, height); + ANGLE_CONTEXT_TRY(prepareForInvalidate(target)); + ANGLE_CONTEXT_TRY(framebuffer->invalidateSub(this, numAttachments, attachments, area)); +} + +void Context::texImage2D(TextureTarget target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + const void *pixels) +{ + ANGLE_CONTEXT_TRY(syncStateForTexImage()); + + gl::Buffer *unpackBuffer = mState.getTargetBuffer(gl::BufferBinding::PixelUnpack); + + Extents size(width, height, 1); + Texture *texture = getTextureByTarget(target); + ANGLE_CONTEXT_TRY(texture->setImage(this, mState.getUnpackState(), unpackBuffer, target, level, + internalformat, size, format, type, + static_cast(pixels))); +} + +void Context::texImage2DRobust(TextureTarget target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels) +{ + texImage2D(target, level, internalformat, width, height, border, format, type, pixels); +} + +void Context::texImage3D(TextureTarget target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const void *pixels) +{ + ANGLE_CONTEXT_TRY(syncStateForTexImage()); + + gl::Buffer *unpackBuffer = mState.getTargetBuffer(gl::BufferBinding::PixelUnpack); + + Extents size(width, height, depth); + Texture *texture = getTextureByTarget(target); + ANGLE_CONTEXT_TRY(texture->setImage(this, mState.getUnpackState(), unpackBuffer, target, level, + internalformat, size, format, type, + static_cast(pixels))); +} + +void Context::texImage3DRobust(TextureTarget target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels) +{ + texImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels); +} + +void Context::texSubImage2D(TextureTarget target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void *pixels) +{ + // Zero sized uploads are valid but no-ops + if (width == 0 || height == 0) + { + return; + } + + ANGLE_CONTEXT_TRY(syncStateForTexImage()); + + Box area(xoffset, yoffset, 0, width, height, 1); + Texture *texture = getTextureByTarget(target); + + gl::Buffer *unpackBuffer = mState.getTargetBuffer(gl::BufferBinding::PixelUnpack); + + ANGLE_CONTEXT_TRY(texture->setSubImage(this, mState.getUnpackState(), unpackBuffer, target, + level, area, format, type, + static_cast(pixels))); +} + +void Context::texSubImage2DRobust(TextureTarget target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels) +{ + texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); +} + +void Context::texSubImage3D(TextureTarget target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *pixels) +{ + // Zero sized uploads are valid but no-ops + if (width == 0 || height == 0 || depth == 0) + { + return; + } + + ANGLE_CONTEXT_TRY(syncStateForTexImage()); + + Box area(xoffset, yoffset, zoffset, width, height, depth); + Texture *texture = getTextureByTarget(target); + + gl::Buffer *unpackBuffer = mState.getTargetBuffer(gl::BufferBinding::PixelUnpack); + + ANGLE_CONTEXT_TRY(texture->setSubImage(this, mState.getUnpackState(), unpackBuffer, target, + level, area, format, type, + static_cast(pixels))); +} + +void Context::texSubImage3DRobust(TextureTarget target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels) +{ + texSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, + pixels); +} + +void Context::compressedTexImage2D(TextureTarget target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + const void *data) +{ + ANGLE_CONTEXT_TRY(syncStateForTexImage()); + + Extents size(width, height, 1); + Texture *texture = getTextureByTarget(target); + // From OpenGL ES 3 spec: All pixel storage modes are ignored when decoding a compressed texture + // image. So we use an empty PixelUnpackState. + ANGLE_CONTEXT_TRY(texture->setCompressedImage(this, PixelUnpackState(), target, level, + internalformat, size, imageSize, + static_cast(data))); +} + +void Context::compressedTexImage2DRobust(TextureTarget target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + GLsizei dataSize, + const GLvoid *data) +{ + compressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data); +} + +void Context::compressedTexImage3D(TextureTarget target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + const void *data) +{ + ANGLE_CONTEXT_TRY(syncStateForTexImage()); + + Extents size(width, height, depth); + Texture *texture = getTextureByTarget(target); + // From OpenGL ES 3 spec: All pixel storage modes are ignored when decoding a compressed texture + // image. So we use an empty PixelUnpackState. + ANGLE_CONTEXT_TRY(texture->setCompressedImage(this, PixelUnpackState(), target, level, + internalformat, size, imageSize, + static_cast(data))); +} + +void Context::compressedTexImage3DRobust(TextureTarget target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + GLsizei dataSize, + const GLvoid *data) +{ + compressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize, + data); +} + +void Context::compressedTexSubImage2D(TextureTarget target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + const void *data) +{ + ANGLE_CONTEXT_TRY(syncStateForTexImage()); + + Box area(xoffset, yoffset, 0, width, height, 1); + Texture *texture = getTextureByTarget(target); + // From OpenGL ES 3 spec: All pixel storage modes are ignored when decoding a compressed texture + // image. So we use an empty PixelUnpackState. + ANGLE_CONTEXT_TRY(texture->setCompressedSubImage(this, PixelUnpackState(), target, level, area, + format, imageSize, + static_cast(data))); +} + +void Context::compressedTexSubImage2DRobust(TextureTarget target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + GLsizei dataSize, + const GLvoid *data) +{ + compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, + data); +} + +void Context::compressedTexSubImage3D(TextureTarget target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const void *data) +{ + // Zero sized uploads are valid but no-ops + if (width == 0 || height == 0) + { + return; + } + + ANGLE_CONTEXT_TRY(syncStateForTexImage()); + + Box area(xoffset, yoffset, zoffset, width, height, depth); + Texture *texture = getTextureByTarget(target); + // From OpenGL ES 3 spec: All pixel storage modes are ignored when decoding a compressed texture + // image. So we use an empty PixelUnpackState. + ANGLE_CONTEXT_TRY(texture->setCompressedSubImage(this, PixelUnpackState(), target, level, area, + format, imageSize, + static_cast(data))); +} + +void Context::compressedTexSubImage3DRobust(TextureTarget target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + GLsizei dataSize, + const GLvoid *data) +{ + compressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, + imageSize, data); +} + +void Context::generateMipmap(TextureType target) +{ + Texture *texture = getTextureByType(target); + ANGLE_CONTEXT_TRY(texture->generateMipmap(this)); +} + +void Context::copyTexture(TextureID sourceId, + GLint sourceLevel, + TextureTarget destTarget, + TextureID destId, + GLint destLevel, + GLint internalFormat, + GLenum destType, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha) +{ + ANGLE_CONTEXT_TRY(syncStateForTexImage()); + + gl::Texture *sourceTexture = getTexture(sourceId); + gl::Texture *destTexture = getTexture(destId); + ANGLE_CONTEXT_TRY( + destTexture->copyTexture(this, destTarget, destLevel, internalFormat, destType, sourceLevel, + ConvertToBool(unpackFlipY), ConvertToBool(unpackPremultiplyAlpha), + ConvertToBool(unpackUnmultiplyAlpha), sourceTexture)); +} + +void Context::copySubTexture(TextureID sourceId, + GLint sourceLevel, + TextureTarget destTarget, + TextureID destId, + GLint destLevel, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha) +{ + // Zero sized copies are valid but no-ops + if (width == 0 || height == 0) + { + return; + } + + ANGLE_CONTEXT_TRY(syncStateForTexImage()); + + gl::Texture *sourceTexture = getTexture(sourceId); + gl::Texture *destTexture = getTexture(destId); + Offset offset(xoffset, yoffset, 0); + Box box(x, y, 0, width, height, 1); + ANGLE_CONTEXT_TRY(destTexture->copySubTexture( + this, destTarget, destLevel, offset, sourceLevel, box, ConvertToBool(unpackFlipY), + ConvertToBool(unpackPremultiplyAlpha), ConvertToBool(unpackUnmultiplyAlpha), + sourceTexture)); +} + +void Context::copyTexture3D(TextureID sourceId, + GLint sourceLevel, + TextureTarget destTarget, + TextureID destId, + GLint destLevel, + GLint internalFormat, + GLenum destType, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha) +{ + ANGLE_CONTEXT_TRY(syncStateForTexImage()); + + Texture *sourceTexture = getTexture(sourceId); + Texture *destTexture = getTexture(destId); + ANGLE_CONTEXT_TRY( + destTexture->copyTexture(this, destTarget, destLevel, internalFormat, destType, sourceLevel, + ConvertToBool(unpackFlipY), ConvertToBool(unpackPremultiplyAlpha), + ConvertToBool(unpackUnmultiplyAlpha), sourceTexture)); +} + +void Context::copySubTexture3D(TextureID sourceId, + GLint sourceLevel, + TextureTarget destTarget, + TextureID destId, + GLint destLevel, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLint z, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha) +{ + // Zero sized copies are valid but no-ops + if (width == 0 || height == 0 || depth == 0) + { + return; + } + + ANGLE_CONTEXT_TRY(syncStateForTexImage()); + + Texture *sourceTexture = getTexture(sourceId); + Texture *destTexture = getTexture(destId); + Offset offset(xoffset, yoffset, zoffset); + Box box(x, y, z, width, height, depth); + ANGLE_CONTEXT_TRY(destTexture->copySubTexture( + this, destTarget, destLevel, offset, sourceLevel, box, ConvertToBool(unpackFlipY), + ConvertToBool(unpackPremultiplyAlpha), ConvertToBool(unpackUnmultiplyAlpha), + sourceTexture)); +} + +void Context::compressedCopyTexture(TextureID sourceId, TextureID destId) +{ + ANGLE_CONTEXT_TRY(syncStateForTexImage()); + + gl::Texture *sourceTexture = getTexture(sourceId); + gl::Texture *destTexture = getTexture(destId); + ANGLE_CONTEXT_TRY(destTexture->copyCompressedTexture(this, sourceTexture)); +} + +void Context::getBufferPointerv(BufferBinding target, GLenum pname, void **params) +{ + Buffer *buffer = mState.getTargetBuffer(target); + ASSERT(buffer); + + QueryBufferPointerv(buffer, pname, params); +} + +void Context::getBufferPointervRobust(BufferBinding target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + void **params) +{ + getBufferPointerv(target, pname, params); +} + +void *Context::mapBuffer(BufferBinding target, GLenum access) +{ + Buffer *buffer = mState.getTargetBuffer(target); + ASSERT(buffer); + + if (buffer->map(this, access) == angle::Result::Stop) + { + return nullptr; + } + + return buffer->getMapPointer(); +} + +GLboolean Context::unmapBuffer(BufferBinding target) +{ + Buffer *buffer = mState.getTargetBuffer(target); + ASSERT(buffer); + + GLboolean result; + if (buffer->unmap(this, &result) == angle::Result::Stop) + { + return GL_FALSE; + } + + return result; +} + +void *Context::mapBufferRange(BufferBinding target, + GLintptr offset, + GLsizeiptr length, + GLbitfield access) +{ + Buffer *buffer = mState.getTargetBuffer(target); + ASSERT(buffer); + + if (buffer->mapRange(this, offset, length, access) == angle::Result::Stop) + { + return nullptr; + } + + return buffer->getMapPointer(); +} + +void Context::flushMappedBufferRange(BufferBinding /*target*/, + GLintptr /*offset*/, + GLsizeiptr /*length*/) +{ + // We do not currently support a non-trivial implementation of FlushMappedBufferRange +} + +angle::Result Context::syncStateForReadPixels() +{ + return syncState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects, Command::ReadPixels); +} + +angle::Result Context::syncStateForTexImage() +{ + return syncState(mTexImageDirtyBits, mTexImageDirtyObjects, Command::TexImage); +} + +angle::Result Context::syncStateForBlit(GLbitfield mask) +{ + uint32_t commandMask = 0; + if ((mask & GL_COLOR_BUFFER_BIT) != 0) + { + commandMask |= CommandBlitBufferColor; + } + if ((mask & GL_DEPTH_BUFFER_BIT) != 0) + { + commandMask |= CommandBlitBufferDepth; + } + if ((mask & GL_STENCIL_BUFFER_BIT) != 0) + { + commandMask |= CommandBlitBufferStencil; + } + + Command command = static_cast(static_cast(Command::Blit) + commandMask); + + return syncState(mBlitDirtyBits, mBlitDirtyObjects, command); +} + +angle::Result Context::syncStateForClear() +{ + return syncState(mClearDirtyBits, mClearDirtyObjects, Command::Clear); +} + +angle::Result Context::syncTextureForCopy(Texture *texture) +{ + ASSERT(texture); + // Sync texture not active but scheduled for a copy + if (texture->hasAnyDirtyBit()) + { + return texture->syncState(this, Command::Other); + } + + return angle::Result::Continue; +} + +void Context::activeShaderProgram(ProgramPipelineID pipeline, ShaderProgramID program) +{ + Program *shaderProgram = getProgramNoResolveLink(program); + ProgramPipeline *programPipeline = + mState.mProgramPipelineManager->checkProgramPipelineAllocation(mImplementation.get(), + pipeline); + ASSERT(programPipeline); + + programPipeline->activeShaderProgram(shaderProgram); +} + +void Context::activeTexture(GLenum texture) +{ + mState.setActiveSampler(texture - GL_TEXTURE0); +} + +void Context::blendBarrier() +{ + mImplementation->blendBarrier(); +} + +void Context::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) +{ + mState.setBlendColor(red, green, blue, alpha); +} + +void Context::blendEquation(GLenum mode) +{ + mState.setBlendEquation(mode, mode); + + mStateCache.onBlendEquationChange(this); +} + +void Context::blendEquationi(GLuint buf, GLenum mode) +{ + mState.setBlendEquationIndexed(mode, mode, buf); + + mStateCache.onBlendEquationChange(this); +} + +void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) +{ + mState.setBlendEquation(modeRGB, modeAlpha); +} + +void Context::blendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeAlpha) +{ + mState.setBlendEquationIndexed(modeRGB, modeAlpha, buf); +} + +void Context::blendFunc(GLenum sfactor, GLenum dfactor) +{ + mState.setBlendFactors(sfactor, dfactor, sfactor, dfactor); +} + +void Context::blendFunci(GLuint buf, GLenum src, GLenum dst) +{ + mState.setBlendFactorsIndexed(src, dst, src, dst, buf); + + if (mState.noSimultaneousConstantColorAndAlphaBlendFunc()) + { + mStateCache.onBlendFuncIndexedChange(this); + } +} + +void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) +{ + mState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha); +} + +void Context::blendFuncSeparatei(GLuint buf, + GLenum srcRGB, + GLenum dstRGB, + GLenum srcAlpha, + GLenum dstAlpha) +{ + mState.setBlendFactorsIndexed(srcRGB, dstRGB, srcAlpha, dstAlpha, buf); + + if (mState.noSimultaneousConstantColorAndAlphaBlendFunc()) + { + mStateCache.onBlendFuncIndexedChange(this); + } +} + +void Context::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) +{ + mState.setColorClearValue(red, green, blue, alpha); +} + +void Context::clearDepthf(GLfloat depth) +{ + mState.setDepthClearValue(clamp01(depth)); +} + +void Context::clearStencil(GLint s) +{ + mState.setStencilClearValue(s); +} + +void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) +{ + mState.setColorMask(ConvertToBool(red), ConvertToBool(green), ConvertToBool(blue), + ConvertToBool(alpha)); + mStateCache.onColorMaskChange(this); +} + +void Context::colorMaski(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a) +{ + mState.setColorMaskIndexed(ConvertToBool(r), ConvertToBool(g), ConvertToBool(b), + ConvertToBool(a), index); + mStateCache.onColorMaskChange(this); +} + +void Context::cullFace(CullFaceMode mode) +{ + mState.setCullMode(mode); +} + +void Context::depthFunc(GLenum func) +{ + mState.setDepthFunc(func); +} + +void Context::depthMask(GLboolean flag) +{ + mState.setDepthMask(ConvertToBool(flag)); +} + +void Context::depthRangef(GLfloat zNear, GLfloat zFar) +{ + mState.setDepthRange(clamp01(zNear), clamp01(zFar)); +} + +void Context::clipControl(GLenum origin, GLenum depth) +{ + mState.setClipControl(origin, depth); +} + +void Context::disable(GLenum cap) +{ + mState.setEnableFeature(cap, false); + mStateCache.onContextCapChange(this); +} + +void Context::disablei(GLenum target, GLuint index) +{ + mState.setEnableFeatureIndexed(target, false, index); + mStateCache.onContextCapChange(this); +} + +void Context::disableVertexAttribArray(GLuint index) +{ + mState.setEnableVertexAttribArray(index, false); + mStateCache.onVertexArrayStateChange(this); +} + +void Context::enable(GLenum cap) +{ + mState.setEnableFeature(cap, true); + mStateCache.onContextCapChange(this); +} + +void Context::enablei(GLenum target, GLuint index) +{ + mState.setEnableFeatureIndexed(target, true, index); + mStateCache.onContextCapChange(this); +} + +void Context::enableVertexAttribArray(GLuint index) +{ + mState.setEnableVertexAttribArray(index, true); + mStateCache.onVertexArrayStateChange(this); +} + +void Context::frontFace(GLenum mode) +{ + mState.setFrontFace(mode); +} + +void Context::hint(GLenum target, GLenum mode) +{ + switch (target) + { + case GL_GENERATE_MIPMAP_HINT: + mState.setGenerateMipmapHint(mode); + break; + + case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: + mState.setFragmentShaderDerivativeHint(mode); + break; + + case GL_PERSPECTIVE_CORRECTION_HINT: + case GL_POINT_SMOOTH_HINT: + case GL_LINE_SMOOTH_HINT: + case GL_FOG_HINT: + mState.gles1().setHint(target, mode); + break; + case GL_TEXTURE_FILTERING_HINT_CHROMIUM: + mState.setTextureFilteringHint(mode); + break; + default: + UNREACHABLE(); + return; + } +} + +void Context::lineWidth(GLfloat width) +{ + mState.setLineWidth(width); +} + +void Context::pixelStorei(GLenum pname, GLint param) +{ + switch (pname) + { + case GL_UNPACK_ALIGNMENT: + mState.setUnpackAlignment(param); + break; + + case GL_PACK_ALIGNMENT: + mState.setPackAlignment(param); + break; + + case GL_PACK_REVERSE_ROW_ORDER_ANGLE: + mState.setPackReverseRowOrder(param != 0); + break; + + case GL_UNPACK_ROW_LENGTH: + ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimageEXT); + mState.setUnpackRowLength(param); + break; + + case GL_UNPACK_IMAGE_HEIGHT: + ASSERT(getClientMajorVersion() >= 3); + mState.setUnpackImageHeight(param); + break; + + case GL_UNPACK_SKIP_IMAGES: + ASSERT(getClientMajorVersion() >= 3); + mState.setUnpackSkipImages(param); + break; + + case GL_UNPACK_SKIP_ROWS: + ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimageEXT); + mState.setUnpackSkipRows(param); + break; + + case GL_UNPACK_SKIP_PIXELS: + ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimageEXT); + mState.setUnpackSkipPixels(param); + break; + + case GL_PACK_ROW_LENGTH: + ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimageNV); + mState.setPackRowLength(param); + break; + + case GL_PACK_SKIP_ROWS: + ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimageNV); + mState.setPackSkipRows(param); + break; + + case GL_PACK_SKIP_PIXELS: + ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimageNV); + mState.setPackSkipPixels(param); + break; + + default: + UNREACHABLE(); + return; + } +} + +void Context::polygonOffset(GLfloat factor, GLfloat units) +{ + mState.setPolygonOffsetParams(factor, units); +} + +void Context::sampleCoverage(GLfloat value, GLboolean invert) +{ + mState.setSampleCoverageParams(clamp01(value), ConvertToBool(invert)); +} + +void Context::sampleMaski(GLuint maskNumber, GLbitfield mask) +{ + mState.setSampleMaskParams(maskNumber, mask); +} + +void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height) +{ + mState.setScissorParams(x, y, width, height); +} + +void Context::shadingRateQCOM(GLenum rate) +{ + mState.setShadingRate(rate); +} + +void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) +{ + GLint clampedRef = gl::clamp(ref, 0, std::numeric_limits::max()); + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) + { + mState.setStencilParams(func, clampedRef, mask); + } + + if (face == GL_BACK || face == GL_FRONT_AND_BACK) + { + mState.setStencilBackParams(func, clampedRef, mask); + } + + mStateCache.onStencilStateChange(this); +} + +void Context::stencilMaskSeparate(GLenum face, GLuint mask) +{ + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) + { + mState.setStencilWritemask(mask); + } + + if (face == GL_BACK || face == GL_FRONT_AND_BACK) + { + mState.setStencilBackWritemask(mask); + } + + mStateCache.onStencilStateChange(this); +} + +void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) +{ + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) + { + mState.setStencilOperations(fail, zfail, zpass); + } + + if (face == GL_BACK || face == GL_FRONT_AND_BACK) + { + mState.setStencilBackOperations(fail, zfail, zpass); + } +} + +void Context::vertexAttrib1f(GLuint index, GLfloat x) +{ + GLfloat vals[4] = {x, 0, 0, 1}; + mState.setVertexAttribf(index, vals); + mStateCache.onDefaultVertexAttributeChange(this); +} + +void Context::vertexAttrib1fv(GLuint index, const GLfloat *values) +{ + GLfloat vals[4] = {values[0], 0, 0, 1}; + mState.setVertexAttribf(index, vals); + mStateCache.onDefaultVertexAttributeChange(this); +} + +void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y) +{ + GLfloat vals[4] = {x, y, 0, 1}; + mState.setVertexAttribf(index, vals); + mStateCache.onDefaultVertexAttributeChange(this); +} + +void Context::vertexAttrib2fv(GLuint index, const GLfloat *values) +{ + GLfloat vals[4] = {values[0], values[1], 0, 1}; + mState.setVertexAttribf(index, vals); + mStateCache.onDefaultVertexAttributeChange(this); +} + +void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) +{ + GLfloat vals[4] = {x, y, z, 1}; + mState.setVertexAttribf(index, vals); + mStateCache.onDefaultVertexAttributeChange(this); +} + +void Context::vertexAttrib3fv(GLuint index, const GLfloat *values) +{ + GLfloat vals[4] = {values[0], values[1], values[2], 1}; + mState.setVertexAttribf(index, vals); + mStateCache.onDefaultVertexAttributeChange(this); +} + +void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ + GLfloat vals[4] = {x, y, z, w}; + mState.setVertexAttribf(index, vals); + mStateCache.onDefaultVertexAttributeChange(this); +} + +void Context::vertexAttrib4fv(GLuint index, const GLfloat *values) +{ + mState.setVertexAttribf(index, values); + mStateCache.onDefaultVertexAttributeChange(this); +} + +void Context::vertexAttribPointer(GLuint index, + GLint size, + VertexAttribType type, + GLboolean normalized, + GLsizei stride, + const void *ptr) +{ + mState.setVertexAttribPointer(this, index, mState.getTargetBuffer(BufferBinding::Array), size, + type, ConvertToBool(normalized), stride, ptr); + mStateCache.onVertexArrayStateChange(this); +} + +void Context::vertexAttribFormat(GLuint attribIndex, + GLint size, + VertexAttribType type, + GLboolean normalized, + GLuint relativeOffset) +{ + mState.setVertexAttribFormat(attribIndex, size, type, ConvertToBool(normalized), false, + relativeOffset); + mStateCache.onVertexArrayFormatChange(this); +} + +void Context::vertexAttribIFormat(GLuint attribIndex, + GLint size, + VertexAttribType type, + GLuint relativeOffset) +{ + mState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset); + mStateCache.onVertexArrayFormatChange(this); +} + +void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex) +{ + mState.setVertexAttribBinding(this, attribIndex, bindingIndex); + mStateCache.onVertexArrayStateChange(this); +} + +void Context::vertexBindingDivisor(GLuint bindingIndex, GLuint divisor) +{ + mState.setVertexBindingDivisor(this, bindingIndex, divisor); + mStateCache.onVertexArrayFormatChange(this); +} + +void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height) +{ + mState.setViewportParams(x, y, width, height); +} + +void Context::vertexAttribIPointer(GLuint index, + GLint size, + VertexAttribType type, + GLsizei stride, + const void *pointer) +{ + mState.setVertexAttribIPointer(this, index, mState.getTargetBuffer(BufferBinding::Array), size, + type, stride, pointer); + mStateCache.onVertexArrayStateChange(this); +} + +void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w) +{ + GLint vals[4] = {x, y, z, w}; + mState.setVertexAttribi(index, vals); + mStateCache.onDefaultVertexAttributeChange(this); +} + +void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) +{ + GLuint vals[4] = {x, y, z, w}; + mState.setVertexAttribu(index, vals); + mStateCache.onDefaultVertexAttributeChange(this); +} + +void Context::vertexAttribI4iv(GLuint index, const GLint *v) +{ + mState.setVertexAttribi(index, v); + mStateCache.onDefaultVertexAttributeChange(this); +} + +void Context::vertexAttribI4uiv(GLuint index, const GLuint *v) +{ + mState.setVertexAttribu(index, v); + mStateCache.onDefaultVertexAttributeChange(this); +} + +void Context::getVertexAttribivImpl(GLuint index, GLenum pname, GLint *params) const +{ + const VertexAttribCurrentValueData ¤tValues = + getState().getVertexAttribCurrentValue(index); + const VertexArray *vao = getState().getVertexArray(); + QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index), + currentValues, pname, params); +} + +void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params) +{ + return getVertexAttribivImpl(index, pname, params); +} + +void Context::getVertexAttribivRobust(GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + getVertexAttribiv(index, pname, params); +} + +void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params) +{ + const VertexAttribCurrentValueData ¤tValues = + getState().getVertexAttribCurrentValue(index); + const VertexArray *vao = getState().getVertexArray(); + QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index), + currentValues, pname, params); +} + +void Context::getVertexAttribfvRobust(GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params) +{ + getVertexAttribfv(index, pname, params); +} + +void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params) +{ + const VertexAttribCurrentValueData ¤tValues = + getState().getVertexAttribCurrentValue(index); + const VertexArray *vao = getState().getVertexArray(); + QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index), + currentValues, pname, params); +} + +void Context::getVertexAttribIivRobust(GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + getVertexAttribIiv(index, pname, params); +} + +void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params) +{ + const VertexAttribCurrentValueData ¤tValues = + getState().getVertexAttribCurrentValue(index); + const VertexArray *vao = getState().getVertexArray(); + QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index), + currentValues, pname, params); +} + +void Context::getVertexAttribIuivRobust(GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params) +{ + getVertexAttribIuiv(index, pname, params); +} + +void Context::getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer) +{ + const VertexAttribute &attrib = getState().getVertexArray()->getVertexAttribute(index); + QueryVertexAttribPointerv(attrib, pname, pointer); +} + +void Context::getVertexAttribPointervRobust(GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + void **pointer) +{ + getVertexAttribPointerv(index, pname, pointer); +} + +void Context::debugMessageControl(GLenum source, + GLenum type, + GLenum severity, + GLsizei count, + const GLuint *ids, + GLboolean enabled) +{ + std::vector idVector(ids, ids + count); + mState.getDebug().setMessageControl(source, type, severity, std::move(idVector), + ConvertToBool(enabled)); +} + +void Context::debugMessageInsert(GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar *buf) +{ + std::string msg(buf, (length > 0) ? static_cast(length) : strlen(buf)); + mState.getDebug().insertMessage(source, type, id, severity, std::move(msg), gl::LOG_INFO, + angle::EntryPoint::GLDebugMessageInsert); +} + +void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam) +{ + mState.getDebug().setCallback(callback, userParam); +} + +GLuint Context::getDebugMessageLog(GLuint count, + GLsizei bufSize, + GLenum *sources, + GLenum *types, + GLuint *ids, + GLenum *severities, + GLsizei *lengths, + GLchar *messageLog) +{ + return static_cast(mState.getDebug().getMessages(count, bufSize, sources, types, ids, + severities, lengths, messageLog)); +} + +void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message) +{ + std::string msg(message, (length > 0) ? static_cast(length) : strlen(message)); + ANGLE_CONTEXT_TRY(mImplementation->pushDebugGroup(this, source, id, msg)); + mState.getDebug().pushGroup(source, id, std::move(msg)); +} + +angle::Result Context::handleNoopDrawEvent() +{ + return (mImplementation->handleNoopDrawEvent()); +} + +void Context::popDebugGroup() +{ + mState.getDebug().popGroup(); + ANGLE_CONTEXT_TRY(mImplementation->popDebugGroup(this)); +} + +void Context::primitiveBoundingBox(GLfloat minX, + GLfloat minY, + GLfloat minZ, + GLfloat minW, + GLfloat maxX, + GLfloat maxY, + GLfloat maxZ, + GLfloat maxW) +{ + mState.mBoundingBoxMinX = minX; + mState.mBoundingBoxMinY = minY; + mState.mBoundingBoxMinZ = minZ; + mState.mBoundingBoxMinW = minW; + mState.mBoundingBoxMaxX = maxX; + mState.mBoundingBoxMaxY = maxY; + mState.mBoundingBoxMaxZ = maxZ; + mState.mBoundingBoxMaxW = maxW; +} + +void Context::bufferStorage(BufferBinding target, + GLsizeiptr size, + const void *data, + GLbitfield flags) +{ + Buffer *buffer = mState.getTargetBuffer(target); + ASSERT(buffer); + ANGLE_CONTEXT_TRY(buffer->bufferStorage(this, target, size, data, flags)); +} + +void Context::bufferStorageExternal(BufferBinding target, + GLintptr offset, + GLsizeiptr size, + GLeglClientBufferEXT clientBuffer, + GLbitfield flags) +{ + Buffer *buffer = mState.getTargetBuffer(target); + ASSERT(buffer); + + ANGLE_CONTEXT_TRY(buffer->bufferStorageExternal(this, target, size, clientBuffer, flags)); +} + +void Context::namedBufferStorageExternal(GLuint buffer, + GLintptr offset, + GLsizeiptr size, + GLeglClientBufferEXT clientBuffer, + GLbitfield flags) +{ + UNIMPLEMENTED(); +} + +void Context::bufferData(BufferBinding target, GLsizeiptr size, const void *data, BufferUsage usage) +{ + Buffer *buffer = mState.getTargetBuffer(target); + ASSERT(buffer); + ANGLE_CONTEXT_TRY(buffer->bufferData(this, target, data, size, usage)); +} + +void Context::bufferSubData(BufferBinding target, + GLintptr offset, + GLsizeiptr size, + const void *data) +{ + if (data == nullptr || size == 0) + { + return; + } + + Buffer *buffer = mState.getTargetBuffer(target); + ASSERT(buffer); + ANGLE_CONTEXT_TRY(buffer->bufferSubData(this, target, data, size, offset)); +} + +void Context::attachShader(ShaderProgramID program, ShaderProgramID shader) +{ + Program *programObject = mState.mShaderProgramManager->getProgram(program); + Shader *shaderObject = mState.mShaderProgramManager->getShader(shader); + ASSERT(programObject && shaderObject); + programObject->attachShader(shaderObject); +} + +void Context::copyBufferSubData(BufferBinding readTarget, + BufferBinding writeTarget, + GLintptr readOffset, + GLintptr writeOffset, + GLsizeiptr size) +{ + // if size is zero, the copy is a successful no-op + if (size == 0) + { + return; + } + + // TODO(jmadill): cache these. + Buffer *readBuffer = mState.getTargetBuffer(readTarget); + Buffer *writeBuffer = mState.getTargetBuffer(writeTarget); + + ANGLE_CONTEXT_TRY( + writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size)); +} + +void Context::bindAttribLocation(ShaderProgramID program, GLuint index, const GLchar *name) +{ + // Ideally we could share the program query with the validation layer if possible. + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + programObject->bindAttributeLocation(index, name); +} + +void Context::bindBufferBase(BufferBinding target, GLuint index, BufferID buffer) +{ + bindBufferRange(target, index, buffer, 0, 0); +} + +void Context::bindBufferRange(BufferBinding target, + GLuint index, + BufferID buffer, + GLintptr offset, + GLsizeiptr size) +{ + Buffer *object = mState.mBufferManager->checkBufferAllocation(mImplementation.get(), buffer); + ANGLE_CONTEXT_TRY(mState.setIndexedBufferBinding(this, target, index, object, offset, size)); + if (target == BufferBinding::Uniform) + { + mUniformBufferObserverBindings[index].bind(object); + mStateCache.onUniformBufferStateChange(this); + } + else if (target == BufferBinding::AtomicCounter) + { + mAtomicCounterBufferObserverBindings[index].bind(object); + mStateCache.onAtomicCounterBufferStateChange(this); + } + else if (target == BufferBinding::ShaderStorage) + { + mShaderStorageBufferObserverBindings[index].bind(object); + mStateCache.onShaderStorageBufferStateChange(this); + } + else + { + mStateCache.onBufferBindingChange(this); + } +} + +void Context::bindFramebuffer(GLenum target, FramebufferID framebuffer) +{ + if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER) + { + bindReadFramebuffer(framebuffer); + } + + if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER) + { + bindDrawFramebuffer(framebuffer); + } +} + +void Context::bindRenderbuffer(GLenum target, RenderbufferID renderbuffer) +{ + ASSERT(target == GL_RENDERBUFFER); + Renderbuffer *object = mState.mRenderbufferManager->checkRenderbufferAllocation( + mImplementation.get(), renderbuffer); + mState.setRenderbufferBinding(this, object); +} + +void Context::texStorage2DMultisample(TextureType target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations) +{ + Extents size(width, height, 1); + Texture *texture = getTextureByType(target); + ANGLE_CONTEXT_TRY(texture->setStorageMultisample(this, target, samples, internalformat, size, + ConvertToBool(fixedsamplelocations))); +} + +void Context::texStorage3DMultisample(TextureType target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedsamplelocations) +{ + Extents size(width, height, depth); + Texture *texture = getTextureByType(target); + ANGLE_CONTEXT_TRY(texture->setStorageMultisample(this, target, samples, internalformat, size, + ConvertToBool(fixedsamplelocations))); +} + +void Context::texImage2DExternal(TextureTarget target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type) +{ + Extents size(width, height, 1); + Texture *texture = getTextureByTarget(target); + ANGLE_CONTEXT_TRY( + texture->setImageExternal(this, target, level, internalformat, size, format, type)); +} + +void Context::invalidateTexture(TextureType target) +{ + mImplementation->invalidateTexture(target); + mState.invalidateTextureBindings(target); +} + +void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val) +{ + // According to spec 3.1 Table 20.49: Framebuffer Dependent Values, + // the sample position should be queried by DRAW_FRAMEBUFFER. + ANGLE_CONTEXT_TRY(mState.syncDirtyObject(this, GL_DRAW_FRAMEBUFFER)); + const Framebuffer *framebuffer = mState.getDrawFramebuffer(); + + switch (pname) + { + case GL_SAMPLE_POSITION: + ANGLE_CONTEXT_TRY(framebuffer->getSamplePosition(this, index, val)); + break; + default: + UNREACHABLE(); + } +} + +void Context::getMultisamplefvRobust(GLenum pname, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLfloat *val) +{ + UNIMPLEMENTED(); +} + +void Context::renderbufferStorage(GLenum target, + GLenum internalformat, + GLsizei width, + GLsizei height) +{ + // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format. + GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat); + + Renderbuffer *renderbuffer = mState.getCurrentRenderbuffer(); + ANGLE_CONTEXT_TRY(renderbuffer->setStorage(this, convertedInternalFormat, width, height)); +} + +void Context::renderbufferStorageMultisample(GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height) +{ + renderbufferStorageMultisampleImpl(target, samples, internalformat, width, height, + MultisamplingMode::Regular); +} + +void Context::renderbufferStorageMultisampleEXT(GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height) +{ + renderbufferStorageMultisampleImpl(target, samples, internalformat, width, height, + MultisamplingMode::MultisampledRenderToTexture); +} + +void Context::renderbufferStorageMultisampleImpl(GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + MultisamplingMode mode) +{ + // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format. + GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat); + + Renderbuffer *renderbuffer = mState.getCurrentRenderbuffer(); + ANGLE_CONTEXT_TRY(renderbuffer->setStorageMultisample(this, samples, convertedInternalFormat, + width, height, mode)); +} + +void Context::framebufferTexture2DMultisample(GLenum target, + GLenum attachment, + TextureTarget textarget, + TextureID texture, + GLint level, + GLsizei samples) +{ + Framebuffer *framebuffer = mState.getTargetFramebuffer(target); + ASSERT(framebuffer); + + if (texture.value != 0) + { + Texture *textureObj = getTexture(texture); + ImageIndex index = ImageIndex::MakeFromTarget(textarget, level, 1); + framebuffer->setAttachmentMultisample(this, GL_TEXTURE, attachment, index, textureObj, + samples); + } + else + { + framebuffer->resetAttachment(this, attachment); + } + + mState.setObjectDirty(target); +} + +void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values) +{ + const Sync *syncObject = nullptr; + if (!isContextLost()) + { + syncObject = getSync(sync); + } + ANGLE_CONTEXT_TRY(QuerySynciv(this, syncObject, pname, bufSize, length, values)); +} + +void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params) +{ + Framebuffer *framebuffer = mState.getTargetFramebuffer(target); + QueryFramebufferParameteriv(framebuffer, pname, params); +} + +void Context::getFramebufferParameterivRobust(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + UNIMPLEMENTED(); +} + +void Context::framebufferParameteri(GLenum target, GLenum pname, GLint param) +{ + Framebuffer *framebuffer = mState.getTargetFramebuffer(target); + SetFramebufferParameteri(this, framebuffer, pname, param); +} + +bool Context::getScratchBuffer(size_t requstedSizeBytes, + angle::MemoryBuffer **scratchBufferOut) const +{ + if (!mScratchBuffer.valid()) + { + mScratchBuffer = mDisplay->requestScratchBuffer(); + } + + ASSERT(mScratchBuffer.valid()); + return mScratchBuffer.value().get(requstedSizeBytes, scratchBufferOut); +} + +angle::ScratchBuffer *Context::getScratchBuffer() const +{ + if (!mScratchBuffer.valid()) + { + mScratchBuffer = mDisplay->requestScratchBuffer(); + } + + ASSERT(mScratchBuffer.valid()); + return &mScratchBuffer.value(); +} + +bool Context::getZeroFilledBuffer(size_t requstedSizeBytes, + angle::MemoryBuffer **zeroBufferOut) const +{ + if (!mZeroFilledBuffer.valid()) + { + mZeroFilledBuffer = mDisplay->requestZeroFilledBuffer(); + } + + ASSERT(mZeroFilledBuffer.valid()); + return mZeroFilledBuffer.value().getInitialized(requstedSizeBytes, zeroBufferOut, 0); +} + +void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ) +{ + if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u) + { + return; + } + + ANGLE_CONTEXT_TRY(prepareForDispatch()); + + angle::Result result = + mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ); + + // This must be called before convertPpoToComputeOrDraw() so it uses the PPO's compute values + // before convertPpoToComputeOrDraw() reverts the PPO back to graphics. + MarkShaderStorageUsage(this); + + if (ANGLE_UNLIKELY(IsError(result))) + { + return; + } +} + +void Context::dispatchComputeIndirect(GLintptr indirect) +{ + ANGLE_CONTEXT_TRY(prepareForDispatch()); + ANGLE_CONTEXT_TRY(mImplementation->dispatchComputeIndirect(this, indirect)); + + MarkShaderStorageUsage(this); +} + +void Context::texStorage2D(TextureType target, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height) +{ + Extents size(width, height, 1); + Texture *texture = getTextureByType(target); + ANGLE_CONTEXT_TRY(texture->setStorage(this, target, levels, internalFormat, size)); +} + +void Context::texStorage3D(TextureType target, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth) +{ + Extents size(width, height, depth); + Texture *texture = getTextureByType(target); + ANGLE_CONTEXT_TRY(texture->setStorage(this, target, levels, internalFormat, size)); +} + +void Context::memoryBarrier(GLbitfield barriers) +{ + ANGLE_CONTEXT_TRY(mImplementation->memoryBarrier(this, barriers)); +} + +void Context::memoryBarrierByRegion(GLbitfield barriers) +{ + ANGLE_CONTEXT_TRY(mImplementation->memoryBarrierByRegion(this, barriers)); +} + +void Context::multiDrawArrays(PrimitiveMode mode, + const GLint *firsts, + const GLsizei *counts, + GLsizei drawcount) +{ + ANGLE_CONTEXT_TRY(prepareForDraw(mode)); + ANGLE_CONTEXT_TRY(mImplementation->multiDrawArrays(this, mode, firsts, counts, drawcount)); +} + +void Context::multiDrawArraysInstanced(PrimitiveMode mode, + const GLint *firsts, + const GLsizei *counts, + const GLsizei *instanceCounts, + GLsizei drawcount) +{ + ANGLE_CONTEXT_TRY(prepareForDraw(mode)); + ANGLE_CONTEXT_TRY(mImplementation->multiDrawArraysInstanced(this, mode, firsts, counts, + instanceCounts, drawcount)); +} + +void Context::multiDrawArraysIndirect(PrimitiveMode mode, + const void *indirect, + GLsizei drawcount, + GLsizei stride) +{ + ANGLE_CONTEXT_TRY(prepareForDraw(mode)); + ANGLE_CONTEXT_TRY( + mImplementation->multiDrawArraysIndirect(this, mode, indirect, drawcount, stride)); + MarkShaderStorageUsage(this); +} + +void Context::multiDrawElements(PrimitiveMode mode, + const GLsizei *counts, + DrawElementsType type, + const GLvoid *const *indices, + GLsizei drawcount) +{ + ANGLE_CONTEXT_TRY(prepareForDraw(mode)); + ANGLE_CONTEXT_TRY( + mImplementation->multiDrawElements(this, mode, counts, type, indices, drawcount)); +} + +void Context::multiDrawElementsInstanced(PrimitiveMode mode, + const GLsizei *counts, + DrawElementsType type, + const GLvoid *const *indices, + const GLsizei *instanceCounts, + GLsizei drawcount) +{ + ANGLE_CONTEXT_TRY(prepareForDraw(mode)); + ANGLE_CONTEXT_TRY(mImplementation->multiDrawElementsInstanced(this, mode, counts, type, indices, + instanceCounts, drawcount)); +} + +void Context::multiDrawElementsIndirect(PrimitiveMode mode, + DrawElementsType type, + const void *indirect, + GLsizei drawcount, + GLsizei stride) +{ + ANGLE_CONTEXT_TRY(prepareForDraw(mode)); + ANGLE_CONTEXT_TRY( + mImplementation->multiDrawElementsIndirect(this, mode, type, indirect, drawcount, stride)); + MarkShaderStorageUsage(this); +} + +void Context::drawArraysInstancedBaseInstance(PrimitiveMode mode, + GLint first, + GLsizei count, + GLsizei instanceCount, + GLuint baseInstance) +{ + if (noopDrawInstanced(mode, count, instanceCount)) + { + ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent()); + return; + } + + ANGLE_CONTEXT_TRY(prepareForDraw(mode)); + Program *programObject = mState.getLinkedProgram(this); + + const bool hasBaseInstance = programObject && programObject->hasBaseInstanceUniform(); + if (hasBaseInstance) + { + programObject->setBaseInstanceUniform(baseInstance); + } + + rx::ResetBaseVertexBaseInstance resetUniforms(programObject, false, hasBaseInstance); + + // The input gl_InstanceID does not follow the baseinstance. gl_InstanceID always falls on + // the half-open range [0, instancecount). No need to set other stuff. Except for Vulkan. + + ANGLE_CONTEXT_TRY(mImplementation->drawArraysInstancedBaseInstance( + this, mode, first, count, instanceCount, baseInstance)); + MarkTransformFeedbackBufferUsage(this, count, 1); +} + +void Context::drawArraysInstancedBaseInstanceANGLE(PrimitiveMode mode, + GLint first, + GLsizei count, + GLsizei instanceCount, + GLuint baseInstance) +{ + drawArraysInstancedBaseInstance(mode, first, count, instanceCount, baseInstance); +} + +void Context::drawElementsInstancedBaseInstance(PrimitiveMode mode, + GLsizei count, + DrawElementsType type, + const void *indices, + GLsizei instanceCount, + GLuint baseInstance) +{ + drawElementsInstancedBaseVertexBaseInstance(mode, count, type, indices, instanceCount, 0, + baseInstance); +} + +void Context::drawElementsInstancedBaseVertexBaseInstance(PrimitiveMode mode, + GLsizei count, + DrawElementsType type, + const GLvoid *indices, + GLsizei instanceCount, + GLint baseVertex, + GLuint baseInstance) +{ + if (noopDrawInstanced(mode, count, instanceCount)) + { + ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent()); + return; + } + + ANGLE_CONTEXT_TRY(prepareForDraw(mode)); + Program *programObject = mState.getLinkedProgram(this); + + const bool hasBaseVertex = programObject && programObject->hasBaseVertexUniform(); + if (hasBaseVertex) + { + programObject->setBaseVertexUniform(baseVertex); + } + + const bool hasBaseInstance = programObject && programObject->hasBaseInstanceUniform(); + if (hasBaseInstance) + { + programObject->setBaseInstanceUniform(baseInstance); + } + + rx::ResetBaseVertexBaseInstance resetUniforms(programObject, hasBaseVertex, hasBaseInstance); + + ANGLE_CONTEXT_TRY(mImplementation->drawElementsInstancedBaseVertexBaseInstance( + this, mode, count, type, indices, instanceCount, baseVertex, baseInstance)); +} + +void Context::drawElementsInstancedBaseVertexBaseInstanceANGLE(PrimitiveMode mode, + GLsizei count, + DrawElementsType type, + const GLvoid *indices, + GLsizei instanceCount, + GLint baseVertex, + GLuint baseInstance) +{ + drawElementsInstancedBaseVertexBaseInstance(mode, count, type, indices, instanceCount, + baseVertex, baseInstance); +} + +void Context::multiDrawArraysInstancedBaseInstance(PrimitiveMode mode, + const GLint *firsts, + const GLsizei *counts, + const GLsizei *instanceCounts, + const GLuint *baseInstances, + GLsizei drawcount) +{ + ANGLE_CONTEXT_TRY(prepareForDraw(mode)); + ANGLE_CONTEXT_TRY(mImplementation->multiDrawArraysInstancedBaseInstance( + this, mode, firsts, counts, instanceCounts, baseInstances, drawcount)); +} + +void Context::multiDrawElementsInstancedBaseVertexBaseInstance(PrimitiveMode mode, + const GLsizei *counts, + DrawElementsType type, + const GLvoid *const *indices, + const GLsizei *instanceCounts, + const GLint *baseVertices, + const GLuint *baseInstances, + GLsizei drawcount) +{ + ANGLE_CONTEXT_TRY(prepareForDraw(mode)); + ANGLE_CONTEXT_TRY(mImplementation->multiDrawElementsInstancedBaseVertexBaseInstance( + this, mode, counts, type, indices, instanceCounts, baseVertices, baseInstances, drawcount)); +} + +void Context::provokingVertex(ProvokingVertexConvention provokeMode) +{ + mState.setProvokingVertex(provokeMode); +} + +GLenum Context::checkFramebufferStatus(GLenum target) +{ + Framebuffer *framebuffer = mState.getTargetFramebuffer(target); + ASSERT(framebuffer); + return framebuffer->checkStatus(this).status; +} + +void Context::compileShader(ShaderProgramID shader) +{ + Shader *shaderObject = GetValidShader(this, angle::EntryPoint::GLCompileShader, shader); + if (!shaderObject) + { + return; + } + shaderObject->compile(this); +} + +void Context::deleteBuffers(GLsizei n, const BufferID *buffers) +{ + for (int i = 0; i < n; i++) + { + deleteBuffer(buffers[i]); + } +} + +void Context::deleteFramebuffers(GLsizei n, const FramebufferID *framebuffers) +{ + for (int i = 0; i < n; i++) + { + if (framebuffers[i].value != 0) + { + deleteFramebuffer(framebuffers[i]); + } + } +} + +void Context::deleteRenderbuffers(GLsizei n, const RenderbufferID *renderbuffers) +{ + for (int i = 0; i < n; i++) + { + deleteRenderbuffer(renderbuffers[i]); + } +} + +void Context::deleteTextures(GLsizei n, const TextureID *textures) +{ + for (int i = 0; i < n; i++) + { + if (textures[i].value != 0) + { + deleteTexture(textures[i]); + } + } +} + +void Context::detachShader(ShaderProgramID program, ShaderProgramID shader) +{ + Program *programObject = getProgramNoResolveLink(program); + ASSERT(programObject); + + Shader *shaderObject = getShader(shader); + ASSERT(shaderObject); + + programObject->detachShader(this, shaderObject); +} + +void Context::genBuffers(GLsizei n, BufferID *buffers) +{ + for (int i = 0; i < n; i++) + { + buffers[i] = createBuffer(); + } +} + +void Context::genFramebuffers(GLsizei n, FramebufferID *framebuffers) +{ + for (int i = 0; i < n; i++) + { + framebuffers[i] = createFramebuffer(); + } +} + +void Context::genRenderbuffers(GLsizei n, RenderbufferID *renderbuffers) +{ + for (int i = 0; i < n; i++) + { + renderbuffers[i] = createRenderbuffer(); + } +} + +void Context::genTextures(GLsizei n, TextureID *textures) +{ + for (int i = 0; i < n; i++) + { + textures[i] = createTexture(); + } +} + +void Context::getActiveAttrib(ShaderProgramID program, + GLuint index, + GLsizei bufsize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + programObject->getActiveAttribute(index, bufsize, length, size, type, name); +} + +void Context::getActiveUniform(ShaderProgramID program, + GLuint index, + GLsizei bufsize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + programObject->getActiveUniform(index, bufsize, length, size, type, name); +} + +void Context::getAttachedShaders(ShaderProgramID program, + GLsizei maxcount, + GLsizei *count, + ShaderProgramID *shaders) +{ + Program *programObject = getProgramNoResolveLink(program); + ASSERT(programObject); + programObject->getAttachedShaders(maxcount, count, shaders); +} + +GLint Context::getAttribLocation(ShaderProgramID program, const GLchar *name) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + return programObject->getAttributeLocation(name); +} + +void Context::getBooleanv(GLenum pname, GLboolean *params) +{ + GLenum nativeType; + unsigned int numParams = 0; + getQueryParameterInfo(pname, &nativeType, &numParams); + + if (nativeType == GL_BOOL) + { + getBooleanvImpl(pname, params); + } + else + { + CastStateValues(this, nativeType, pname, numParams, params); + } +} + +void Context::getBooleanvRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLboolean *params) +{ + getBooleanv(pname, params); +} + +void Context::getFloatv(GLenum pname, GLfloat *params) +{ + GLenum nativeType; + unsigned int numParams = 0; + getQueryParameterInfo(pname, &nativeType, &numParams); + + if (nativeType == GL_FLOAT) + { + getFloatvImpl(pname, params); + } + else + { + CastStateValues(this, nativeType, pname, numParams, params); + } +} + +void Context::getFloatvRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params) +{ + getFloatv(pname, params); +} + +void Context::getIntegerv(GLenum pname, GLint *params) +{ + GLenum nativeType = GL_NONE; + unsigned int numParams = 0; + getQueryParameterInfo(pname, &nativeType, &numParams); + + if (nativeType == GL_INT) + { + getIntegervImpl(pname, params); + } + else + { + CastStateValues(this, nativeType, pname, numParams, params); + } +} + +void Context::getIntegervRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLint *data) +{ + getIntegerv(pname, data); +} + +void Context::getProgramiv(ShaderProgramID program, GLenum pname, GLint *params) +{ + // Don't resolve link if checking the link completion status. + Program *programObject = getProgramNoResolveLink(program); + if (!isContextLost() && pname != GL_COMPLETION_STATUS_KHR) + { + programObject = getProgramResolveLink(program); + } + ASSERT(programObject); + QueryProgramiv(this, programObject, pname, params); +} + +void Context::getProgramivRobust(ShaderProgramID program, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + getProgramiv(program, pname, params); +} + +void Context::getProgramPipelineiv(ProgramPipelineID pipeline, GLenum pname, GLint *params) +{ + ProgramPipeline *programPipeline = nullptr; + if (!mContextLost) + { + programPipeline = getProgramPipeline(pipeline); + } + QueryProgramPipelineiv(this, programPipeline, pname, params); +} + +MemoryObject *Context::getMemoryObject(MemoryObjectID handle) const +{ + return mState.mMemoryObjectManager->getMemoryObject(handle); +} + +Semaphore *Context::getSemaphore(SemaphoreID handle) const +{ + return mState.mSemaphoreManager->getSemaphore(handle); +} + +void Context::getProgramInfoLog(ShaderProgramID program, + GLsizei bufsize, + GLsizei *length, + GLchar *infolog) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + programObject->getExecutable().getInfoLog(bufsize, length, infolog); +} + +void Context::getProgramPipelineInfoLog(ProgramPipelineID pipeline, + GLsizei bufSize, + GLsizei *length, + GLchar *infoLog) +{ + ProgramPipeline *programPipeline = getProgramPipeline(pipeline); + if (programPipeline) + { + programPipeline->getExecutable().getInfoLog(bufSize, length, infoLog); + } + else + { + *length = 0; + *infoLog = '\0'; + } +} + +void Context::getShaderiv(ShaderProgramID shader, GLenum pname, GLint *params) +{ + Shader *shaderObject = nullptr; + if (!isContextLost()) + { + shaderObject = getShader(shader); + ASSERT(shaderObject); + } + QueryShaderiv(this, shaderObject, pname, params); +} + +void Context::getShaderivRobust(ShaderProgramID shader, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + getShaderiv(shader, pname, params); +} + +void Context::getShaderInfoLog(ShaderProgramID shader, + GLsizei bufsize, + GLsizei *length, + GLchar *infolog) +{ + Shader *shaderObject = getShader(shader); + ASSERT(shaderObject); + shaderObject->getInfoLog(this, bufsize, length, infolog); +} + +void Context::getShaderPrecisionFormat(GLenum shadertype, + GLenum precisiontype, + GLint *range, + GLint *precision) +{ + // TODO(jmadill): Compute shaders. + + switch (shadertype) + { + case GL_VERTEX_SHADER: + switch (precisiontype) + { + case GL_LOW_FLOAT: + mState.mCaps.vertexLowpFloat.get(range, precision); + break; + case GL_MEDIUM_FLOAT: + mState.mCaps.vertexMediumpFloat.get(range, precision); + break; + case GL_HIGH_FLOAT: + mState.mCaps.vertexHighpFloat.get(range, precision); + break; + + case GL_LOW_INT: + mState.mCaps.vertexLowpInt.get(range, precision); + break; + case GL_MEDIUM_INT: + mState.mCaps.vertexMediumpInt.get(range, precision); + break; + case GL_HIGH_INT: + mState.mCaps.vertexHighpInt.get(range, precision); + break; + + default: + UNREACHABLE(); + return; + } + break; + + case GL_FRAGMENT_SHADER: + switch (precisiontype) + { + case GL_LOW_FLOAT: + mState.mCaps.fragmentLowpFloat.get(range, precision); + break; + case GL_MEDIUM_FLOAT: + mState.mCaps.fragmentMediumpFloat.get(range, precision); + break; + case GL_HIGH_FLOAT: + mState.mCaps.fragmentHighpFloat.get(range, precision); + break; + + case GL_LOW_INT: + mState.mCaps.fragmentLowpInt.get(range, precision); + break; + case GL_MEDIUM_INT: + mState.mCaps.fragmentMediumpInt.get(range, precision); + break; + case GL_HIGH_INT: + mState.mCaps.fragmentHighpInt.get(range, precision); + break; + + default: + UNREACHABLE(); + return; + } + break; + + default: + UNREACHABLE(); + return; + } +} + +void Context::getShaderSource(ShaderProgramID shader, + GLsizei bufsize, + GLsizei *length, + GLchar *source) +{ + Shader *shaderObject = getShader(shader); + ASSERT(shaderObject); + shaderObject->getSource(bufsize, length, source); +} + +void Context::getUniformfv(ShaderProgramID program, UniformLocation location, GLfloat *params) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + programObject->getUniformfv(this, location, params); +} + +void Context::getUniformfvRobust(ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + GLsizei *length, + GLfloat *params) +{ + getUniformfv(program, location, params); +} + +void Context::getUniformiv(ShaderProgramID program, UniformLocation location, GLint *params) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + programObject->getUniformiv(this, location, params); +} + +void Context::getUniformivRobust(ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + getUniformiv(program, location, params); +} + +GLint Context::getUniformLocation(ShaderProgramID program, const GLchar *name) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + return programObject->getUniformLocation(name).value; +} + +GLboolean Context::isBuffer(BufferID buffer) const +{ + if (buffer.value == 0) + { + return GL_FALSE; + } + + return ConvertToGLBoolean(getBuffer(buffer)); +} + +GLboolean Context::isEnabled(GLenum cap) const +{ + return mState.getEnableFeature(cap); +} + +GLboolean Context::isEnabledi(GLenum target, GLuint index) const +{ + return mState.getEnableFeatureIndexed(target, index); +} + +GLboolean Context::isFramebuffer(FramebufferID framebuffer) const +{ + if (framebuffer.value == 0) + { + return GL_FALSE; + } + + return ConvertToGLBoolean(getFramebuffer(framebuffer)); +} + +GLboolean Context::isProgram(ShaderProgramID program) const +{ + if (program.value == 0) + { + return GL_FALSE; + } + + return ConvertToGLBoolean(getProgramNoResolveLink(program)); +} + +GLboolean Context::isRenderbuffer(RenderbufferID renderbuffer) const +{ + if (renderbuffer.value == 0) + { + return GL_FALSE; + } + + return ConvertToGLBoolean(getRenderbuffer(renderbuffer)); +} + +GLboolean Context::isShader(ShaderProgramID shader) const +{ + if (shader.value == 0) + { + return GL_FALSE; + } + + return ConvertToGLBoolean(getShader(shader)); +} + +GLboolean Context::isTexture(TextureID texture) const +{ + if (texture.value == 0) + { + return GL_FALSE; + } + + return ConvertToGLBoolean(getTexture(texture)); +} + +void Context::linkProgram(ShaderProgramID program) +{ + Program *programObject = getProgramNoResolveLink(program); + ASSERT(programObject); + ANGLE_CONTEXT_TRY(programObject->link(this)); + ANGLE_CONTEXT_TRY(onProgramLink(programObject)); +} + +void Context::releaseShaderCompiler() +{ + mCompiler.set(this, nullptr); +} + +void Context::shaderBinary(GLsizei n, + const ShaderProgramID *shaders, + GLenum binaryformat, + const void *binary, + GLsizei length) +{ + // No binary shader formats are supported. + UNIMPLEMENTED(); +} + +void Context::bindFragDataLocationIndexed(ShaderProgramID program, + GLuint colorNumber, + GLuint index, + const char *name) +{ + Program *programObject = getProgramNoResolveLink(program); + programObject->bindFragmentOutputLocation(colorNumber, name); + programObject->bindFragmentOutputIndex(index, name); +} + +void Context::bindFragDataLocation(ShaderProgramID program, GLuint colorNumber, const char *name) +{ + bindFragDataLocationIndexed(program, colorNumber, 0u, name); +} + +int Context::getFragDataIndex(ShaderProgramID program, const char *name) +{ + Program *programObject = getProgramResolveLink(program); + return programObject->getFragDataIndex(name); +} + +int Context::getProgramResourceLocationIndex(ShaderProgramID program, + GLenum programInterface, + const char *name) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programInterface == GL_PROGRAM_OUTPUT); + return programObject->getFragDataIndex(name); +} + +void Context::shaderSource(ShaderProgramID shader, + GLsizei count, + const GLchar *const *string, + const GLint *length) +{ + Shader *shaderObject = getShader(shader); + ASSERT(shaderObject); + shaderObject->setSource(count, string, length); +} + +void Context::stencilFunc(GLenum func, GLint ref, GLuint mask) +{ + stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask); +} + +void Context::stencilMask(GLuint mask) +{ + stencilMaskSeparate(GL_FRONT_AND_BACK, mask); +} + +void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass) +{ + stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass); +} + +void Context::patchParameteri(GLenum pname, GLint value) +{ + switch (pname) + { + case GL_PATCH_VERTICES: + mState.setPatchVertices(value); + break; + default: + break; + } +} + +Program *Context::getActiveLinkedProgram() const +{ + Program *program = mState.getLinkedProgram(this); + if (!program) + { + ProgramPipeline *programPipelineObject = mState.getProgramPipeline(); + if (programPipelineObject) + { + program = programPipelineObject->getLinkedActiveShaderProgram(this); + } + } + + return program; +} + +void Context::uniform1f(UniformLocation location, GLfloat x) +{ + Program *program = getActiveLinkedProgram(); + program->setUniform1fv(location, 1, &x); +} + +void Context::uniform1fv(UniformLocation location, GLsizei count, const GLfloat *v) +{ + Program *program = getActiveLinkedProgram(); + program->setUniform1fv(location, count, v); +} + +void Context::setUniform1iImpl(Program *program, + UniformLocation location, + GLsizei count, + const GLint *v) +{ + program->setUniform1iv(this, location, count, v); +} + +void Context::onSamplerUniformChange(size_t textureUnitIndex) +{ + mState.onActiveTextureChange(this, textureUnitIndex); + mStateCache.onActiveTextureChange(this); +} + +void Context::uniform1i(UniformLocation location, GLint x) +{ + Program *program = getActiveLinkedProgram(); + setUniform1iImpl(program, location, 1, &x); +} + +void Context::uniform1iv(UniformLocation location, GLsizei count, const GLint *v) +{ + Program *program = getActiveLinkedProgram(); + setUniform1iImpl(program, location, count, v); +} + +void Context::uniform2f(UniformLocation location, GLfloat x, GLfloat y) +{ + GLfloat xy[2] = {x, y}; + Program *program = getActiveLinkedProgram(); + program->setUniform2fv(location, 1, xy); +} + +void Context::uniform2fv(UniformLocation location, GLsizei count, const GLfloat *v) +{ + Program *program = getActiveLinkedProgram(); + program->setUniform2fv(location, count, v); +} + +void Context::uniform2i(UniformLocation location, GLint x, GLint y) +{ + GLint xy[2] = {x, y}; + Program *program = getActiveLinkedProgram(); + program->setUniform2iv(location, 1, xy); +} + +void Context::uniform2iv(UniformLocation location, GLsizei count, const GLint *v) +{ + Program *program = getActiveLinkedProgram(); + program->setUniform2iv(location, count, v); +} + +void Context::uniform3f(UniformLocation location, GLfloat x, GLfloat y, GLfloat z) +{ + GLfloat xyz[3] = {x, y, z}; + Program *program = getActiveLinkedProgram(); + program->setUniform3fv(location, 1, xyz); +} + +void Context::uniform3fv(UniformLocation location, GLsizei count, const GLfloat *v) +{ + Program *program = getActiveLinkedProgram(); + program->setUniform3fv(location, count, v); +} + +void Context::uniform3i(UniformLocation location, GLint x, GLint y, GLint z) +{ + GLint xyz[3] = {x, y, z}; + Program *program = getActiveLinkedProgram(); + program->setUniform3iv(location, 1, xyz); +} + +void Context::uniform3iv(UniformLocation location, GLsizei count, const GLint *v) +{ + Program *program = getActiveLinkedProgram(); + program->setUniform3iv(location, count, v); +} + +void Context::uniform4f(UniformLocation location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ + GLfloat xyzw[4] = {x, y, z, w}; + Program *program = getActiveLinkedProgram(); + program->setUniform4fv(location, 1, xyzw); +} + +void Context::uniform4fv(UniformLocation location, GLsizei count, const GLfloat *v) +{ + Program *program = getActiveLinkedProgram(); + program->setUniform4fv(location, count, v); +} + +void Context::uniform4i(UniformLocation location, GLint x, GLint y, GLint z, GLint w) +{ + GLint xyzw[4] = {x, y, z, w}; + Program *program = getActiveLinkedProgram(); + program->setUniform4iv(location, 1, xyzw); +} + +void Context::uniform4iv(UniformLocation location, GLsizei count, const GLint *v) +{ + Program *program = getActiveLinkedProgram(); + program->setUniform4iv(location, count, v); +} + +void Context::uniformMatrix2fv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *program = getActiveLinkedProgram(); + program->setUniformMatrix2fv(location, count, transpose, value); +} + +void Context::uniformMatrix3fv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *program = getActiveLinkedProgram(); + program->setUniformMatrix3fv(location, count, transpose, value); +} + +void Context::uniformMatrix4fv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *program = getActiveLinkedProgram(); + program->setUniformMatrix4fv(location, count, transpose, value); +} + +void Context::validateProgram(ShaderProgramID program) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + programObject->validate(mState.mCaps); +} + +void Context::validateProgramPipeline(ProgramPipelineID pipeline) +{ + // GLES spec 3.2, Section 7.4 "Program Pipeline Objects" + // If pipeline is a name that has been generated (without subsequent deletion) by + // GenProgramPipelines, but refers to a program pipeline object that has not been + // previously bound, the GL first creates a new state vector in the same manner as + // when BindProgramPipeline creates a new program pipeline object. + // + // void BindProgramPipeline( uint pipeline ); + // pipeline is the program pipeline object name. The resulting program pipeline + // object is a new state vector, comprising all the state and with the same initial values + // listed in table 21.20. + // + // If we do not have a pipeline object that's been created with glBindProgramPipeline, we leave + // VALIDATE_STATUS at it's default false value without generating a pipeline object. + if (!getProgramPipeline(pipeline)) + { + return; + } + + ProgramPipeline *programPipeline = + mState.mProgramPipelineManager->checkProgramPipelineAllocation(mImplementation.get(), + pipeline); + ASSERT(programPipeline); + + programPipeline->validate(this); +} + +void Context::getProgramBinary(ShaderProgramID program, + GLsizei bufSize, + GLsizei *length, + GLenum *binaryFormat, + void *binary) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject != nullptr); + + ANGLE_CONTEXT_TRY(programObject->saveBinary(this, binaryFormat, binary, bufSize, length)); +} + +void Context::programBinary(ShaderProgramID program, + GLenum binaryFormat, + const void *binary, + GLsizei length) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject != nullptr); + + ANGLE_CONTEXT_TRY(programObject->loadBinary(this, binaryFormat, binary, length)); + ANGLE_CONTEXT_TRY(onProgramLink(programObject)); +} + +void Context::uniform1ui(UniformLocation location, GLuint v0) +{ + Program *program = getActiveLinkedProgram(); + program->setUniform1uiv(location, 1, &v0); +} + +void Context::uniform2ui(UniformLocation location, GLuint v0, GLuint v1) +{ + Program *program = getActiveLinkedProgram(); + const GLuint xy[] = {v0, v1}; + program->setUniform2uiv(location, 1, xy); +} + +void Context::uniform3ui(UniformLocation location, GLuint v0, GLuint v1, GLuint v2) +{ + Program *program = getActiveLinkedProgram(); + const GLuint xyz[] = {v0, v1, v2}; + program->setUniform3uiv(location, 1, xyz); +} + +void Context::uniform4ui(UniformLocation location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) +{ + Program *program = getActiveLinkedProgram(); + const GLuint xyzw[] = {v0, v1, v2, v3}; + program->setUniform4uiv(location, 1, xyzw); +} + +void Context::uniform1uiv(UniformLocation location, GLsizei count, const GLuint *value) +{ + Program *program = getActiveLinkedProgram(); + program->setUniform1uiv(location, count, value); +} +void Context::uniform2uiv(UniformLocation location, GLsizei count, const GLuint *value) +{ + Program *program = getActiveLinkedProgram(); + program->setUniform2uiv(location, count, value); +} + +void Context::uniform3uiv(UniformLocation location, GLsizei count, const GLuint *value) +{ + Program *program = getActiveLinkedProgram(); + program->setUniform3uiv(location, count, value); +} + +void Context::uniform4uiv(UniformLocation location, GLsizei count, const GLuint *value) +{ + Program *program = getActiveLinkedProgram(); + program->setUniform4uiv(location, count, value); +} + +void Context::genQueries(GLsizei n, QueryID *ids) +{ + for (GLsizei i = 0; i < n; i++) + { + QueryID handle = QueryID{mQueryHandleAllocator.allocate()}; + mQueryMap.assign(handle, nullptr); + ids[i] = handle; + } +} + +void Context::deleteQueries(GLsizei n, const QueryID *ids) +{ + for (int i = 0; i < n; i++) + { + QueryID query = ids[i]; + + Query *queryObject = nullptr; + if (mQueryMap.erase(query, &queryObject)) + { + mQueryHandleAllocator.release(query.value); + if (queryObject) + { + queryObject->release(this); + } + } + } +} + +bool Context::isQueryGenerated(QueryID query) const +{ + return mQueryMap.contains(query); +} + +GLboolean Context::isQuery(QueryID id) const +{ + return ConvertToGLBoolean(getQuery(id) != nullptr); +} + +void Context::uniformMatrix2x3fv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *program = getActiveLinkedProgram(); + program->setUniformMatrix2x3fv(location, count, transpose, value); +} + +void Context::uniformMatrix3x2fv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *program = getActiveLinkedProgram(); + program->setUniformMatrix3x2fv(location, count, transpose, value); +} + +void Context::uniformMatrix2x4fv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *program = getActiveLinkedProgram(); + program->setUniformMatrix2x4fv(location, count, transpose, value); +} + +void Context::uniformMatrix4x2fv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *program = getActiveLinkedProgram(); + program->setUniformMatrix4x2fv(location, count, transpose, value); +} + +void Context::uniformMatrix3x4fv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *program = getActiveLinkedProgram(); + program->setUniformMatrix3x4fv(location, count, transpose, value); +} + +void Context::uniformMatrix4x3fv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *program = getActiveLinkedProgram(); + program->setUniformMatrix4x3fv(location, count, transpose, value); +} + +void Context::deleteVertexArrays(GLsizei n, const VertexArrayID *arrays) +{ + for (int arrayIndex = 0; arrayIndex < n; arrayIndex++) + { + VertexArrayID vertexArray = arrays[arrayIndex]; + + if (arrays[arrayIndex].value != 0) + { + VertexArray *vertexArrayObject = nullptr; + if (mVertexArrayMap.erase(vertexArray, &vertexArrayObject)) + { + if (vertexArrayObject != nullptr) + { + detachVertexArray(vertexArray); + vertexArrayObject->onDestroy(this); + } + + mVertexArrayHandleAllocator.release(vertexArray.value); + } + } + } +} + +void Context::genVertexArrays(GLsizei n, VertexArrayID *arrays) +{ + for (int arrayIndex = 0; arrayIndex < n; arrayIndex++) + { + VertexArrayID vertexArray = {mVertexArrayHandleAllocator.allocate()}; + mVertexArrayMap.assign(vertexArray, nullptr); + arrays[arrayIndex] = vertexArray; + } +} + +GLboolean Context::isVertexArray(VertexArrayID array) const +{ + if (array.value == 0) + { + return GL_FALSE; + } + + VertexArray *vao = getVertexArray(array); + return ConvertToGLBoolean(vao != nullptr); +} + +void Context::endTransformFeedback() +{ + TransformFeedback *transformFeedback = mState.getCurrentTransformFeedback(); + ANGLE_CONTEXT_TRY(transformFeedback->end(this)); + mStateCache.onActiveTransformFeedbackChange(this); +} + +void Context::transformFeedbackVaryings(ShaderProgramID program, + GLsizei count, + const GLchar *const *varyings, + GLenum bufferMode) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + programObject->setTransformFeedbackVaryings(count, varyings, bufferMode); +} + +void Context::getTransformFeedbackVarying(ShaderProgramID program, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLsizei *size, + GLenum *type, + GLchar *name) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name); +} + +void Context::deleteTransformFeedbacks(GLsizei n, const TransformFeedbackID *ids) +{ + for (int i = 0; i < n; i++) + { + TransformFeedbackID transformFeedback = ids[i]; + if (transformFeedback.value == 0) + { + continue; + } + + TransformFeedback *transformFeedbackObject = nullptr; + if (mTransformFeedbackMap.erase(transformFeedback, &transformFeedbackObject)) + { + if (transformFeedbackObject != nullptr) + { + detachTransformFeedback(transformFeedback); + transformFeedbackObject->release(this); + } + + mTransformFeedbackHandleAllocator.release(transformFeedback.value); + } + } +} + +void Context::genTransformFeedbacks(GLsizei n, TransformFeedbackID *ids) +{ + for (int i = 0; i < n; i++) + { + TransformFeedbackID transformFeedback = {mTransformFeedbackHandleAllocator.allocate()}; + mTransformFeedbackMap.assign(transformFeedback, nullptr); + ids[i] = transformFeedback; + } +} + +GLboolean Context::isTransformFeedback(TransformFeedbackID id) const +{ + if (id.value == 0) + { + // The 3.0.4 spec [section 6.1.11] states that if ID is zero, IsTransformFeedback + // returns FALSE + return GL_FALSE; + } + + const TransformFeedback *transformFeedback = getTransformFeedback(id); + return ConvertToGLBoolean(transformFeedback != nullptr); +} + +void Context::pauseTransformFeedback() +{ + TransformFeedback *transformFeedback = mState.getCurrentTransformFeedback(); + ANGLE_CONTEXT_TRY(transformFeedback->pause(this)); + mStateCache.onActiveTransformFeedbackChange(this); +} + +void Context::resumeTransformFeedback() +{ + TransformFeedback *transformFeedback = mState.getCurrentTransformFeedback(); + ANGLE_CONTEXT_TRY(transformFeedback->resume(this)); + mStateCache.onActiveTransformFeedbackChange(this); +} + +void Context::getUniformuiv(ShaderProgramID program, UniformLocation location, GLuint *params) +{ + const Program *programObject = getProgramResolveLink(program); + programObject->getUniformuiv(this, location, params); +} + +void Context::getUniformuivRobust(ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + GLsizei *length, + GLuint *params) +{ + getUniformuiv(program, location, params); +} + +GLint Context::getFragDataLocation(ShaderProgramID program, const GLchar *name) +{ + const Program *programObject = getProgramResolveLink(program); + return programObject->getFragDataLocation(name); +} + +void Context::getUniformIndices(ShaderProgramID program, + GLsizei uniformCount, + const GLchar *const *uniformNames, + GLuint *uniformIndices) +{ + const Program *programObject = getProgramResolveLink(program); + if (!programObject->isLinked()) + { + for (int uniformId = 0; uniformId < uniformCount; uniformId++) + { + uniformIndices[uniformId] = GL_INVALID_INDEX; + } + } + else + { + for (int uniformId = 0; uniformId < uniformCount; uniformId++) + { + uniformIndices[uniformId] = programObject->getUniformIndex(uniformNames[uniformId]); + } + } +} + +void Context::getActiveUniformsiv(ShaderProgramID program, + GLsizei uniformCount, + const GLuint *uniformIndices, + GLenum pname, + GLint *params) +{ + const Program *programObject = getProgramResolveLink(program); + for (int uniformId = 0; uniformId < uniformCount; uniformId++) + { + const GLuint index = uniformIndices[uniformId]; + params[uniformId] = GetUniformResourceProperty(programObject, index, pname); + } +} + +GLuint Context::getUniformBlockIndex(ShaderProgramID program, const GLchar *uniformBlockName) +{ + const Program *programObject = getProgramResolveLink(program); + return programObject->getUniformBlockIndex(uniformBlockName); +} + +void Context::getActiveUniformBlockiv(ShaderProgramID program, + UniformBlockIndex uniformBlockIndex, + GLenum pname, + GLint *params) +{ + const Program *programObject = getProgramResolveLink(program); + QueryActiveUniformBlockiv(programObject, uniformBlockIndex, pname, params); +} + +void Context::getActiveUniformBlockivRobust(ShaderProgramID program, + UniformBlockIndex uniformBlockIndex, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + getActiveUniformBlockiv(program, uniformBlockIndex, pname, params); +} + +void Context::getActiveUniformBlockName(ShaderProgramID program, + UniformBlockIndex uniformBlockIndex, + GLsizei bufSize, + GLsizei *length, + GLchar *uniformBlockName) +{ + const Program *programObject = getProgramResolveLink(program); + programObject->getActiveUniformBlockName(this, uniformBlockIndex, bufSize, length, + uniformBlockName); +} + +void Context::uniformBlockBinding(ShaderProgramID program, + UniformBlockIndex uniformBlockIndex, + GLuint uniformBlockBinding) +{ + Program *programObject = getProgramResolveLink(program); + programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding); + + // Note: If the Program is shared between Contexts we would be better using Observer/Subject. + if (programObject->isInUse()) + { + mState.setObjectDirty(GL_PROGRAM); + mStateCache.onUniformBufferStateChange(this); + } +} + +GLsync Context::fenceSync(GLenum condition, GLbitfield flags) +{ + GLuint handle = mState.mSyncManager->createSync(mImplementation.get()); + GLsync syncHandle = reinterpret_cast(static_cast(handle)); + + Sync *syncObject = getSync(syncHandle); + if (syncObject->set(this, condition, flags) == angle::Result::Stop) + { + deleteSync(syncHandle); + return nullptr; + } + + return syncHandle; +} + +GLboolean Context::isSync(GLsync sync) const +{ + return (getSync(sync) != nullptr); +} + +GLenum Context::clientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) +{ + Sync *syncObject = getSync(sync); + + GLenum result = GL_WAIT_FAILED; + if (syncObject->clientWait(this, flags, timeout, &result) == angle::Result::Stop) + { + return GL_WAIT_FAILED; + } + return result; +} + +void Context::waitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) +{ + Sync *syncObject = getSync(sync); + ANGLE_CONTEXT_TRY(syncObject->serverWait(this, flags, timeout)); +} + +void Context::getInteger64v(GLenum pname, GLint64 *params) +{ + GLenum nativeType = GL_NONE; + unsigned int numParams = 0; + getQueryParameterInfo(pname, &nativeType, &numParams); + + if (nativeType == GL_INT_64_ANGLEX) + { + getInteger64vImpl(pname, params); + } + else + { + CastStateValues(this, nativeType, pname, numParams, params); + } +} + +void Context::getInteger64vRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *data) +{ + getInteger64v(pname, data); +} + +void Context::getBufferParameteri64v(BufferBinding target, GLenum pname, GLint64 *params) +{ + Buffer *buffer = mState.getTargetBuffer(target); + QueryBufferParameteri64v(buffer, pname, params); +} + +void Context::getBufferParameteri64vRobust(BufferBinding target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint64 *params) +{ + getBufferParameteri64v(target, pname, params); +} + +void Context::genSamplers(GLsizei count, SamplerID *samplers) +{ + for (int i = 0; i < count; i++) + { + samplers[i] = mState.mSamplerManager->createSampler(); + } +} + +void Context::deleteSamplers(GLsizei count, const SamplerID *samplers) +{ + for (int i = 0; i < count; i++) + { + SamplerID sampler = samplers[i]; + + if (mState.mSamplerManager->getSampler(sampler)) + { + detachSampler(sampler); + } + + mState.mSamplerManager->deleteObject(this, sampler); + } +} + +void Context::minSampleShading(GLfloat value) +{ + mState.setMinSampleShading(value); +} + +void Context::getInternalformativ(GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei bufSize, + GLint *params) +{ + const TextureCaps &formatCaps = mState.mTextureCaps.get(internalformat); + QueryInternalFormativ(formatCaps, pname, bufSize, params); +} + +void Context::getInternalformativRobust(GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + getInternalformativ(target, internalformat, pname, bufSize, params); +} + +void Context::programUniform1i(ShaderProgramID program, UniformLocation location, GLint v0) +{ + programUniform1iv(program, location, 1, &v0); +} + +void Context::programUniform2i(ShaderProgramID program, + UniformLocation location, + GLint v0, + GLint v1) +{ + GLint xy[2] = {v0, v1}; + programUniform2iv(program, location, 1, xy); +} + +void Context::programUniform3i(ShaderProgramID program, + UniformLocation location, + GLint v0, + GLint v1, + GLint v2) +{ + GLint xyz[3] = {v0, v1, v2}; + programUniform3iv(program, location, 1, xyz); +} + +void Context::programUniform4i(ShaderProgramID program, + UniformLocation location, + GLint v0, + GLint v1, + GLint v2, + GLint v3) +{ + GLint xyzw[4] = {v0, v1, v2, v3}; + programUniform4iv(program, location, 1, xyzw); +} + +void Context::programUniform1ui(ShaderProgramID program, UniformLocation location, GLuint v0) +{ + programUniform1uiv(program, location, 1, &v0); +} + +void Context::programUniform2ui(ShaderProgramID program, + UniformLocation location, + GLuint v0, + GLuint v1) +{ + GLuint xy[2] = {v0, v1}; + programUniform2uiv(program, location, 1, xy); +} + +void Context::programUniform3ui(ShaderProgramID program, + UniformLocation location, + GLuint v0, + GLuint v1, + GLuint v2) +{ + GLuint xyz[3] = {v0, v1, v2}; + programUniform3uiv(program, location, 1, xyz); +} + +void Context::programUniform4ui(ShaderProgramID program, + UniformLocation location, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3) +{ + GLuint xyzw[4] = {v0, v1, v2, v3}; + programUniform4uiv(program, location, 1, xyzw); +} + +void Context::programUniform1f(ShaderProgramID program, UniformLocation location, GLfloat v0) +{ + programUniform1fv(program, location, 1, &v0); +} + +void Context::programUniform2f(ShaderProgramID program, + UniformLocation location, + GLfloat v0, + GLfloat v1) +{ + GLfloat xy[2] = {v0, v1}; + programUniform2fv(program, location, 1, xy); +} + +void Context::programUniform3f(ShaderProgramID program, + UniformLocation location, + GLfloat v0, + GLfloat v1, + GLfloat v2) +{ + GLfloat xyz[3] = {v0, v1, v2}; + programUniform3fv(program, location, 1, xyz); +} + +void Context::programUniform4f(ShaderProgramID program, + UniformLocation location, + GLfloat v0, + GLfloat v1, + GLfloat v2, + GLfloat v3) +{ + GLfloat xyzw[4] = {v0, v1, v2, v3}; + programUniform4fv(program, location, 1, xyzw); +} + +void Context::programUniform1iv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLint *value) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + setUniform1iImpl(programObject, location, count, value); +} + +void Context::programUniform2iv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLint *value) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + programObject->setUniform2iv(location, count, value); +} + +void Context::programUniform3iv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLint *value) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + programObject->setUniform3iv(location, count, value); +} + +void Context::programUniform4iv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLint *value) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + programObject->setUniform4iv(location, count, value); +} + +void Context::programUniform1uiv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLuint *value) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + programObject->setUniform1uiv(location, count, value); +} + +void Context::programUniform2uiv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLuint *value) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + programObject->setUniform2uiv(location, count, value); +} + +void Context::programUniform3uiv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLuint *value) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + programObject->setUniform3uiv(location, count, value); +} + +void Context::programUniform4uiv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLuint *value) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + programObject->setUniform4uiv(location, count, value); +} + +void Context::programUniform1fv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLfloat *value) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + programObject->setUniform1fv(location, count, value); +} + +void Context::programUniform2fv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLfloat *value) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + programObject->setUniform2fv(location, count, value); +} + +void Context::programUniform3fv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLfloat *value) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + programObject->setUniform3fv(location, count, value); +} + +void Context::programUniform4fv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLfloat *value) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + programObject->setUniform4fv(location, count, value); +} + +void Context::programUniformMatrix2fv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + programObject->setUniformMatrix2fv(location, count, transpose, value); +} + +void Context::programUniformMatrix3fv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + programObject->setUniformMatrix3fv(location, count, transpose, value); +} + +void Context::programUniformMatrix4fv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + programObject->setUniformMatrix4fv(location, count, transpose, value); +} + +void Context::programUniformMatrix2x3fv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + programObject->setUniformMatrix2x3fv(location, count, transpose, value); +} + +void Context::programUniformMatrix3x2fv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + programObject->setUniformMatrix3x2fv(location, count, transpose, value); +} + +void Context::programUniformMatrix2x4fv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + programObject->setUniformMatrix2x4fv(location, count, transpose, value); +} + +void Context::programUniformMatrix4x2fv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + programObject->setUniformMatrix4x2fv(location, count, transpose, value); +} + +void Context::programUniformMatrix3x4fv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + programObject->setUniformMatrix3x4fv(location, count, transpose, value); +} + +void Context::programUniformMatrix4x3fv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + programObject->setUniformMatrix4x3fv(location, count, transpose, value); +} + +bool Context::isCurrentTransformFeedback(const TransformFeedback *tf) const +{ + return mState.isCurrentTransformFeedback(tf); +} + +void Context::genProgramPipelines(GLsizei count, ProgramPipelineID *pipelines) +{ + for (int i = 0; i < count; i++) + { + pipelines[i] = createProgramPipeline(); + } +} + +void Context::deleteProgramPipelines(GLsizei count, const ProgramPipelineID *pipelines) +{ + for (int i = 0; i < count; i++) + { + if (pipelines[i].value != 0) + { + deleteProgramPipeline(pipelines[i]); + } + } +} + +GLboolean Context::isProgramPipeline(ProgramPipelineID pipeline) const +{ + if (pipeline.value == 0) + { + return GL_FALSE; + } + + if (getProgramPipeline(pipeline)) + { + return GL_TRUE; + } + + return GL_FALSE; +} + +void Context::finishFenceNV(FenceNVID fence) +{ + FenceNV *fenceObject = getFenceNV(fence); + + ASSERT(fenceObject && fenceObject->isSet()); + ANGLE_CONTEXT_TRY(fenceObject->finish(this)); +} + +void Context::getFenceivNV(FenceNVID fence, GLenum pname, GLint *params) +{ + FenceNV *fenceObject = getFenceNV(fence); + + ASSERT(fenceObject && fenceObject->isSet()); + + switch (pname) + { + case GL_FENCE_STATUS_NV: + { + // GL_NV_fence spec: + // Once the status of a fence has been finished (via FinishFenceNV) or tested and + // the returned status is TRUE (via either TestFenceNV or GetFenceivNV querying the + // FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence. + GLboolean status = GL_TRUE; + if (fenceObject->getStatus() != GL_TRUE) + { + ANGLE_CONTEXT_TRY(fenceObject->test(this, &status)); + } + *params = status; + break; + } + + case GL_FENCE_CONDITION_NV: + { + *params = static_cast(fenceObject->getCondition()); + break; + } + + default: + UNREACHABLE(); + } +} + +void Context::getTranslatedShaderSource(ShaderProgramID shader, + GLsizei bufsize, + GLsizei *length, + GLchar *source) +{ + Shader *shaderObject = getShader(shader); + ASSERT(shaderObject); + shaderObject->getTranslatedSourceWithDebugInfo(this, bufsize, length, source); +} + +void Context::getnUniformfv(ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + GLfloat *params) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + + programObject->getUniformfv(this, location, params); +} + +void Context::getnUniformfvRobust(ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + GLsizei *length, + GLfloat *params) +{ + UNIMPLEMENTED(); +} + +void Context::getnUniformiv(ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + GLint *params) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + + programObject->getUniformiv(this, location, params); +} + +void Context::getnUniformuiv(ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + GLuint *params) +{ + Program *programObject = getProgramResolveLink(program); + ASSERT(programObject); + + programObject->getUniformuiv(this, location, params); +} + +void Context::getnUniformivRobust(ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + UNIMPLEMENTED(); +} + +void Context::getnUniformuivRobust(ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + GLsizei *length, + GLuint *params) +{ + UNIMPLEMENTED(); +} + +GLboolean Context::isFenceNV(FenceNVID fence) const +{ + FenceNV *fenceObject = getFenceNV(fence); + + if (fenceObject == nullptr) + { + return GL_FALSE; + } + + // GL_NV_fence spec: + // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an + // existing fence. + return fenceObject->isSet(); +} + +void Context::readnPixels(GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + void *data) +{ + return readPixels(x, y, width, height, format, type, data); +} + +void Context::setFenceNV(FenceNVID fence, GLenum condition) +{ + ASSERT(condition == GL_ALL_COMPLETED_NV); + + FenceNV *fenceObject = getFenceNV(fence); + ASSERT(fenceObject != nullptr); + ANGLE_CONTEXT_TRY(fenceObject->set(this, condition)); +} + +GLboolean Context::testFenceNV(FenceNVID fence) +{ + FenceNV *fenceObject = getFenceNV(fence); + + ASSERT(fenceObject != nullptr); + ASSERT(fenceObject->isSet() == GL_TRUE); + + GLboolean result = GL_TRUE; + if (fenceObject->test(this, &result) == angle::Result::Stop) + { + return GL_TRUE; + } + + return result; +} + +void Context::deleteMemoryObjects(GLsizei n, const MemoryObjectID *memoryObjects) +{ + for (int i = 0; i < n; i++) + { + deleteMemoryObject(memoryObjects[i]); + } +} + +GLboolean Context::isMemoryObject(MemoryObjectID memoryObject) const +{ + if (memoryObject.value == 0) + { + return GL_FALSE; + } + + return ConvertToGLBoolean(getMemoryObject(memoryObject)); +} + +void Context::createMemoryObjects(GLsizei n, MemoryObjectID *memoryObjects) +{ + for (int i = 0; i < n; i++) + { + memoryObjects[i] = createMemoryObject(); + } +} + +void Context::memoryObjectParameteriv(MemoryObjectID memory, GLenum pname, const GLint *params) +{ + MemoryObject *memoryObject = getMemoryObject(memory); + ASSERT(memoryObject); + ANGLE_CONTEXT_TRY(SetMemoryObjectParameteriv(this, memoryObject, pname, params)); +} + +void Context::getMemoryObjectParameteriv(MemoryObjectID memory, GLenum pname, GLint *params) +{ + const MemoryObject *memoryObject = getMemoryObject(memory); + ASSERT(memoryObject); + QueryMemoryObjectParameteriv(memoryObject, pname, params); +} + +void Context::texStorageMem2D(TextureType target, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height, + MemoryObjectID memory, + GLuint64 offset) +{ + texStorageMemFlags2D(target, levels, internalFormat, width, height, memory, offset, 0, + std::numeric_limits::max(), nullptr); +} + +void Context::texStorageMem2DMultisample(TextureType target, + GLsizei samples, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLboolean fixedSampleLocations, + MemoryObjectID memory, + GLuint64 offset) +{ + UNIMPLEMENTED(); +} + +void Context::texStorageMem3D(TextureType target, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth, + MemoryObjectID memory, + GLuint64 offset) +{ + UNIMPLEMENTED(); +} + +void Context::texStorageMem3DMultisample(TextureType target, + GLsizei samples, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedSampleLocations, + MemoryObjectID memory, + GLuint64 offset) +{ + UNIMPLEMENTED(); +} + +void Context::bufferStorageMem(TextureType target, + GLsizeiptr size, + MemoryObjectID memory, + GLuint64 offset) +{ + UNIMPLEMENTED(); +} + +void Context::importMemoryFd(MemoryObjectID memory, GLuint64 size, HandleType handleType, GLint fd) +{ + MemoryObject *memoryObject = getMemoryObject(memory); + ASSERT(memoryObject != nullptr); + ANGLE_CONTEXT_TRY(memoryObject->importFd(this, size, handleType, fd)); +} + +void Context::texStorageMemFlags2D(TextureType target, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height, + MemoryObjectID memory, + GLuint64 offset, + GLbitfield createFlags, + GLbitfield usageFlags, + const void *imageCreateInfoPNext) +{ + MemoryObject *memoryObject = getMemoryObject(memory); + ASSERT(memoryObject); + Extents size(width, height, 1); + Texture *texture = getTextureByType(target); + ANGLE_CONTEXT_TRY(texture->setStorageExternalMemory(this, target, levels, internalFormat, size, + memoryObject, offset, createFlags, + usageFlags, imageCreateInfoPNext)); +} + +void Context::texStorageMemFlags2DMultisample(TextureType target, + GLsizei samples, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLboolean fixedSampleLocations, + MemoryObjectID memory, + GLuint64 offset, + GLbitfield createFlags, + GLbitfield usageFlags, + const void *imageCreateInfoPNext) +{ + UNIMPLEMENTED(); +} + +void Context::texStorageMemFlags3D(TextureType target, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth, + MemoryObjectID memory, + GLuint64 offset, + GLbitfield createFlags, + GLbitfield usageFlags, + const void *imageCreateInfoPNext) +{ + UNIMPLEMENTED(); +} + +void Context::texStorageMemFlags3DMultisample(TextureType target, + GLsizei samples, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedSampleLocations, + MemoryObjectID memory, + GLuint64 offset, + GLbitfield createFlags, + GLbitfield usageFlags, + const void *imageCreateInfoPNext) +{ + UNIMPLEMENTED(); +} + +void Context::importMemoryZirconHandle(MemoryObjectID memory, + GLuint64 size, + HandleType handleType, + GLuint handle) +{ + MemoryObject *memoryObject = getMemoryObject(memory); + ASSERT(memoryObject != nullptr); + ANGLE_CONTEXT_TRY(memoryObject->importZirconHandle(this, size, handleType, handle)); +} + +void Context::genSemaphores(GLsizei n, SemaphoreID *semaphores) +{ + for (int i = 0; i < n; i++) + { + semaphores[i] = createSemaphore(); + } +} + +void Context::deleteSemaphores(GLsizei n, const SemaphoreID *semaphores) +{ + for (int i = 0; i < n; i++) + { + deleteSemaphore(semaphores[i]); + } +} + +GLboolean Context::isSemaphore(SemaphoreID semaphore) const +{ + if (semaphore.value == 0) + { + return GL_FALSE; + } + + return ConvertToGLBoolean(getSemaphore(semaphore)); +} + +void Context::semaphoreParameterui64v(SemaphoreID semaphore, GLenum pname, const GLuint64 *params) +{ + UNIMPLEMENTED(); +} + +void Context::getSemaphoreParameterui64v(SemaphoreID semaphore, GLenum pname, GLuint64 *params) +{ + UNIMPLEMENTED(); +} + +void Context::acquireTextures(GLuint numTextures, + const TextureID *textureIds, + const GLenum *layouts) +{ + TextureBarrierVector textureBarriers(numTextures); + for (size_t i = 0; i < numTextures; i++) + { + textureBarriers[i].texture = getTexture(textureIds[i]); + textureBarriers[i].layout = layouts[i]; + } + ANGLE_CONTEXT_TRY(mImplementation->acquireTextures(this, textureBarriers)); +} + +void Context::releaseTextures(GLuint numTextures, const TextureID *textureIds, GLenum *layouts) +{ + TextureBarrierVector textureBarriers(numTextures); + for (size_t i = 0; i < numTextures; i++) + { + textureBarriers[i].texture = getTexture(textureIds[i]); + } + ANGLE_CONTEXT_TRY(mImplementation->releaseTextures(this, &textureBarriers)); + for (size_t i = 0; i < numTextures; i++) + { + layouts[i] = textureBarriers[i].layout; + } +} + +void Context::waitSemaphore(SemaphoreID semaphoreHandle, + GLuint numBufferBarriers, + const BufferID *buffers, + GLuint numTextureBarriers, + const TextureID *textures, + const GLenum *srcLayouts) +{ + Semaphore *semaphore = getSemaphore(semaphoreHandle); + ASSERT(semaphore); + + BufferBarrierVector bufferBarriers(numBufferBarriers); + for (GLuint bufferBarrierIdx = 0; bufferBarrierIdx < numBufferBarriers; bufferBarrierIdx++) + { + bufferBarriers[bufferBarrierIdx] = getBuffer(buffers[bufferBarrierIdx]); + } + + TextureBarrierVector textureBarriers(numTextureBarriers); + for (GLuint textureBarrierIdx = 0; textureBarrierIdx < numTextureBarriers; textureBarrierIdx++) + { + textureBarriers[textureBarrierIdx].texture = getTexture(textures[textureBarrierIdx]); + textureBarriers[textureBarrierIdx].layout = srcLayouts[textureBarrierIdx]; + } + + ANGLE_CONTEXT_TRY(semaphore->wait(this, bufferBarriers, textureBarriers)); +} + +void Context::signalSemaphore(SemaphoreID semaphoreHandle, + GLuint numBufferBarriers, + const BufferID *buffers, + GLuint numTextureBarriers, + const TextureID *textures, + const GLenum *dstLayouts) +{ + Semaphore *semaphore = getSemaphore(semaphoreHandle); + ASSERT(semaphore); + + BufferBarrierVector bufferBarriers(numBufferBarriers); + for (GLuint bufferBarrierIdx = 0; bufferBarrierIdx < numBufferBarriers; bufferBarrierIdx++) + { + bufferBarriers[bufferBarrierIdx] = getBuffer(buffers[bufferBarrierIdx]); + } + + TextureBarrierVector textureBarriers(numTextureBarriers); + for (GLuint textureBarrierIdx = 0; textureBarrierIdx < numTextureBarriers; textureBarrierIdx++) + { + textureBarriers[textureBarrierIdx].texture = getTexture(textures[textureBarrierIdx]); + textureBarriers[textureBarrierIdx].layout = dstLayouts[textureBarrierIdx]; + } + + ANGLE_CONTEXT_TRY(semaphore->signal(this, bufferBarriers, textureBarriers)); +} + +void Context::importSemaphoreFd(SemaphoreID semaphore, HandleType handleType, GLint fd) +{ + Semaphore *semaphoreObject = getSemaphore(semaphore); + ASSERT(semaphoreObject != nullptr); + ANGLE_CONTEXT_TRY(semaphoreObject->importFd(this, handleType, fd)); +} + +void Context::importSemaphoreZirconHandle(SemaphoreID semaphore, + HandleType handleType, + GLuint handle) +{ + Semaphore *semaphoreObject = getSemaphore(semaphore); + ASSERT(semaphoreObject != nullptr); + ANGLE_CONTEXT_TRY(semaphoreObject->importZirconHandle(this, handleType, handle)); +} + +void Context::framebufferMemorylessPixelLocalStorage(GLint plane, GLenum internalformat) +{ + Framebuffer *framebuffer = mState.getDrawFramebuffer(); + ASSERT(framebuffer); + PixelLocalStorage &pls = framebuffer->getPixelLocalStorage(this); + + if (internalformat == GL_NONE) + { + pls.deinitialize(this, plane); + } + else + { + pls.setMemoryless(this, plane, internalformat); + } +} + +void Context::framebufferTexturePixelLocalStorage(GLint plane, + TextureID backingtexture, + GLint level, + GLint layer) +{ + Framebuffer *framebuffer = mState.getDrawFramebuffer(); + ASSERT(framebuffer); + PixelLocalStorage &pls = framebuffer->getPixelLocalStorage(this); + + if (backingtexture.value == 0) + { + pls.deinitialize(this, plane); + } + else + { + Texture *tex = getTexture(backingtexture); + ASSERT(tex); // Validation guarantees this. + pls.setTextureBacked(this, plane, tex, level, layer); + } +} + +void Context::beginPixelLocalStorage(GLsizei planes, const GLenum loadops[], const void *cleardata) +{ + Framebuffer *framebuffer = mState.getDrawFramebuffer(); + ASSERT(framebuffer); + PixelLocalStorage &pls = framebuffer->getPixelLocalStorage(this); + + pls.begin(this, planes, loadops, cleardata); + mState.setPixelLocalStorageActive(true); +} + +void Context::endPixelLocalStorage() +{ + Framebuffer *framebuffer = mState.getDrawFramebuffer(); + ASSERT(framebuffer); + PixelLocalStorage &pls = framebuffer->getPixelLocalStorage(this); + + pls.end(this); + mState.setPixelLocalStorageActive(false); +} + +void Context::pixelLocalStorageBarrier() +{ + if (getExtensions().shaderPixelLocalStorageCoherentANGLE) + { + return; + } + + Framebuffer *framebuffer = mState.getDrawFramebuffer(); + ASSERT(framebuffer); + PixelLocalStorage &pls = framebuffer->getPixelLocalStorage(this); + + pls.barrier(this); +} + +void Context::eGLImageTargetTexStorage(GLenum target, GLeglImageOES image, const GLint *attrib_list) +{ + Texture *texture = getTextureByType(FromGLenum(target)); + egl::Image *imageObject = static_cast(image); + ANGLE_CONTEXT_TRY(texture->setStorageEGLImageTarget(this, FromGLenum(target), + imageObject, attrib_list)); +} + +void Context::eGLImageTargetTextureStorage(GLuint texture, + GLeglImageOES image, + const GLint *attrib_list) +{ + return; +} + +void Context::eGLImageTargetTexture2D(TextureType target, GLeglImageOES image) +{ + Texture *texture = getTextureByType(target); + egl::Image *imageObject = static_cast(image); + ANGLE_CONTEXT_TRY(texture->setEGLImageTarget(this, target, imageObject)); +} + +void Context::eGLImageTargetRenderbufferStorage(GLenum target, GLeglImageOES image) +{ + Renderbuffer *renderbuffer = mState.getCurrentRenderbuffer(); + egl::Image *imageObject = static_cast(image); + ANGLE_CONTEXT_TRY(renderbuffer->setStorageEGLImageTarget(this, imageObject)); +} + +void Context::framebufferFetchBarrier() +{ + mImplementation->framebufferFetchBarrier(); +} + +void Context::texStorage1D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width) +{ + UNIMPLEMENTED(); +} + +bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) const +{ + return GetQueryParameterInfo(mState, pname, type, numParams); +} + +bool Context::getIndexedQueryParameterInfo(GLenum target, + GLenum *type, + unsigned int *numParams) const +{ + if (getClientVersion() < Version(3, 0)) + { + return false; + } + + switch (target) + { + case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: + case GL_UNIFORM_BUFFER_BINDING: + { + *type = GL_INT; + *numParams = 1; + return true; + } + case GL_TRANSFORM_FEEDBACK_BUFFER_START: + case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: + case GL_UNIFORM_BUFFER_START: + case GL_UNIFORM_BUFFER_SIZE: + { + *type = GL_INT_64_ANGLEX; + *numParams = 1; + return true; + } + } + + if (mSupportedExtensions.drawBuffersIndexedAny()) + { + switch (target) + { + case GL_BLEND_SRC_RGB: + case GL_BLEND_SRC_ALPHA: + case GL_BLEND_DST_RGB: + case GL_BLEND_DST_ALPHA: + case GL_BLEND_EQUATION_RGB: + case GL_BLEND_EQUATION_ALPHA: + { + *type = GL_INT; + *numParams = 1; + return true; + } + case GL_COLOR_WRITEMASK: + { + *type = GL_BOOL; + *numParams = 4; + return true; + } + } + } + + if (mSupportedExtensions.shaderPixelLocalStorageANGLE) + { + switch (target) + { + case GL_PIXEL_LOCAL_FORMAT_ANGLE: + case GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE: + case GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE: + case GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE: + *type = GL_INT; + *numParams = 1; + return true; + } + } + + if (getClientVersion() < Version(3, 1)) + { + return false; + } + + switch (target) + { + case GL_IMAGE_BINDING_LAYERED: + { + *type = GL_BOOL; + *numParams = 1; + return true; + } + case GL_MAX_COMPUTE_WORK_GROUP_COUNT: + case GL_MAX_COMPUTE_WORK_GROUP_SIZE: + case GL_ATOMIC_COUNTER_BUFFER_BINDING: + case GL_SHADER_STORAGE_BUFFER_BINDING: + case GL_VERTEX_BINDING_BUFFER: + case GL_VERTEX_BINDING_DIVISOR: + case GL_VERTEX_BINDING_OFFSET: + case GL_VERTEX_BINDING_STRIDE: + case GL_SAMPLE_MASK_VALUE: + case GL_IMAGE_BINDING_NAME: + case GL_IMAGE_BINDING_LEVEL: + case GL_IMAGE_BINDING_LAYER: + case GL_IMAGE_BINDING_ACCESS: + case GL_IMAGE_BINDING_FORMAT: + { + *type = GL_INT; + *numParams = 1; + return true; + } + case GL_ATOMIC_COUNTER_BUFFER_START: + case GL_ATOMIC_COUNTER_BUFFER_SIZE: + case GL_SHADER_STORAGE_BUFFER_START: + case GL_SHADER_STORAGE_BUFFER_SIZE: + { + *type = GL_INT_64_ANGLEX; + *numParams = 1; + return true; + } + } + + return false; +} + +Program *Context::getProgramNoResolveLink(ShaderProgramID handle) const +{ + return mState.mShaderProgramManager->getProgram(handle); +} + +Shader *Context::getShader(ShaderProgramID handle) const +{ + return mState.mShaderProgramManager->getShader(handle); +} + +const angle::FrontendFeatures &Context::getFrontendFeatures() const +{ + return mDisplay->getFrontendFeatures(); +} + +bool Context::isRenderbufferGenerated(RenderbufferID renderbuffer) const +{ + return mState.mRenderbufferManager->isHandleGenerated(renderbuffer); +} + +bool Context::isFramebufferGenerated(FramebufferID framebuffer) const +{ + return mState.mFramebufferManager->isHandleGenerated(framebuffer); +} + +bool Context::isProgramPipelineGenerated(ProgramPipelineID pipeline) const +{ + return mState.mProgramPipelineManager->isHandleGenerated(pipeline); +} + +bool Context::usingDisplayTextureShareGroup() const +{ + return mDisplayTextureShareGroup; +} + +bool Context::usingDisplaySemaphoreShareGroup() const +{ + return mDisplaySemaphoreShareGroup; +} + +GLenum Context::getConvertedRenderbufferFormat(GLenum internalformat) const +{ + if (isWebGL() && mState.mClientVersion.major == 2 && internalformat == GL_DEPTH_STENCIL) + { + return GL_DEPTH24_STENCIL8; + } + if (getClientType() == EGL_OPENGL_API && internalformat == GL_DEPTH_COMPONENT) + { + return GL_DEPTH_COMPONENT24; + } + return internalformat; +} + +void Context::maxShaderCompilerThreads(GLuint count) +{ + GLuint oldCount = mState.getMaxShaderCompilerThreads(); + mState.setMaxShaderCompilerThreads(count); + // A count of zero specifies a request for no parallel compiling or linking. + if ((oldCount == 0 || count == 0) && (oldCount != 0 || count != 0)) + { + mMultiThreadPool = angle::WorkerThreadPool::Create(count > 0); + } + mMultiThreadPool->setMaxThreads(count); + mImplementation->setMaxShaderCompilerThreads(count); +} + +void Context::framebufferParameteriMESA(GLenum target, GLenum pname, GLint param) +{ + framebufferParameteri(target, pname, param); +} + +void Context::getFramebufferParameterivMESA(GLenum target, GLenum pname, GLint *params) +{ + getFramebufferParameteriv(target, pname, params); +} + +bool Context::isGLES1() const +{ + return mState.isGLES1(); +} + +void Context::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) +{ + switch (index) + { + case kVertexArraySubjectIndex: + switch (message) + { + case angle::SubjectMessage::ContentsChanged: + mState.setObjectDirty(GL_VERTEX_ARRAY); + mStateCache.onVertexArrayBufferContentsChange(this); + break; + case angle::SubjectMessage::SubjectMapped: + case angle::SubjectMessage::SubjectUnmapped: + case angle::SubjectMessage::BindingChanged: + mStateCache.onVertexArrayBufferStateChange(this); + break; + default: + break; + } + break; + + case kReadFramebufferSubjectIndex: + switch (message) + { + case angle::SubjectMessage::DirtyBitsFlagged: + mState.setReadFramebufferDirty(); + break; + case angle::SubjectMessage::SurfaceChanged: + mState.setReadFramebufferBindingDirty(); + break; + default: + UNREACHABLE(); + break; + } + break; + + case kDrawFramebufferSubjectIndex: + switch (message) + { + case angle::SubjectMessage::DirtyBitsFlagged: + mState.setDrawFramebufferDirty(); + mStateCache.onDrawFramebufferChange(this); + break; + case angle::SubjectMessage::SurfaceChanged: + mState.setDrawFramebufferBindingDirty(); + break; + default: + UNREACHABLE(); + break; + } + break; + + case kProgramPipelineSubjectIndex: + switch (message) + { + case angle::SubjectMessage::SubjectChanged: + ANGLE_CONTEXT_TRY(mState.onProgramPipelineExecutableChange(this)); + mStateCache.onProgramExecutableChange(this); + break; + case angle::SubjectMessage::ProgramRelinked: + ANGLE_CONTEXT_TRY(mState.mProgramPipeline->link(this)); + break; + default: + UNREACHABLE(); + break; + } + break; + + default: + if (index < kTextureMaxSubjectIndex) + { + if (message != angle::SubjectMessage::ContentsChanged && + message != angle::SubjectMessage::BindingChanged) + { + mState.onActiveTextureStateChange(this, index); + mStateCache.onActiveTextureChange(this); + } + } + else if (index < kImageMaxSubjectIndex) + { + mState.onImageStateChange(this, index - kImage0SubjectIndex); + if (message == angle::SubjectMessage::ContentsChanged) + { + mState.mDirtyBits.set(State::DirtyBitType::DIRTY_BIT_IMAGE_BINDINGS); + } + } + else if (index < kUniformBufferMaxSubjectIndex) + { + mState.onUniformBufferStateChange(index - kUniformBuffer0SubjectIndex); + mStateCache.onUniformBufferStateChange(this); + } + else if (index < kAtomicCounterBufferMaxSubjectIndex) + { + mState.onAtomicCounterBufferStateChange(index - kAtomicCounterBuffer0SubjectIndex); + mStateCache.onAtomicCounterBufferStateChange(this); + } + else if (index < kShaderStorageBufferMaxSubjectIndex) + { + mState.onShaderStorageBufferStateChange(index - kShaderStorageBuffer0SubjectIndex); + mStateCache.onShaderStorageBufferStateChange(this); + } + else + { + ASSERT(index < kSamplerMaxSubjectIndex); + mState.setSamplerDirty(index - kSampler0SubjectIndex); + mState.onActiveTextureStateChange(this, index - kSampler0SubjectIndex); + } + break; + } +} + +angle::Result Context::onProgramLink(Program *programObject) +{ + // Don't parallel link a program which is active in any GL contexts. With this assumption, we + // don't need to worry that: + // 1. Draw calls after link use the new executable code or the old one depending on the link + // result. + // 2. When a backend program, e.g., ProgramD3D is linking, other backend classes like + // StateManager11, Renderer11, etc., may have a chance to make unexpected calls to + // ProgramD3D. + if (programObject->isInUse()) + { + programObject->resolveLink(this); + if (programObject->isLinked()) + { + ANGLE_TRY(mState.onProgramExecutableChange(this, programObject)); + programObject->onStateChange(angle::SubjectMessage::ProgramRelinked); + } + mStateCache.onProgramExecutableChange(this); + } + + return angle::Result::Continue; +} + +egl::Error Context::setDefaultFramebuffer(egl::Surface *drawSurface, egl::Surface *readSurface) +{ + ASSERT(mCurrentDrawSurface == nullptr); + ASSERT(mCurrentReadSurface == nullptr); + + mCurrentDrawSurface = drawSurface; + mCurrentReadSurface = readSurface; + + if (drawSurface != nullptr) + { + ANGLE_TRY(drawSurface->makeCurrent(this)); + } + + ANGLE_TRY(mDefaultFramebuffer->setSurfaces(this, drawSurface, readSurface)); + + if (readSurface && (drawSurface != readSurface)) + { + ANGLE_TRY(readSurface->makeCurrent(this)); + } + + // Update default framebuffer, the binding of the previous default + // framebuffer (or lack of) will have a nullptr. + mState.mFramebufferManager->setDefaultFramebuffer(mDefaultFramebuffer.get()); + if (mState.getDrawFramebuffer() == nullptr) + { + bindDrawFramebuffer(mDefaultFramebuffer->id()); + } + if (mState.getReadFramebuffer() == nullptr) + { + bindReadFramebuffer(mDefaultFramebuffer->id()); + } + + return egl::NoError(); +} + +egl::Error Context::unsetDefaultFramebuffer() +{ + Framebuffer *defaultFramebuffer = + mState.mFramebufferManager->getFramebuffer(Framebuffer::kDefaultDrawFramebufferHandle); + + if (defaultFramebuffer) + { + // Remove the default framebuffer + if (defaultFramebuffer == mState.getReadFramebuffer()) + { + mState.setReadFramebufferBinding(nullptr); + mReadFramebufferObserverBinding.bind(nullptr); + } + + if (defaultFramebuffer == mState.getDrawFramebuffer()) + { + mState.setDrawFramebufferBinding(nullptr); + mDrawFramebufferObserverBinding.bind(nullptr); + } + + ANGLE_TRY(defaultFramebuffer->unsetSurfaces(this)); + mState.mFramebufferManager->setDefaultFramebuffer(nullptr); + } + + // Always unset the current surface, even if setIsCurrent fails. + egl::Surface *drawSurface = mCurrentDrawSurface; + egl::Surface *readSurface = mCurrentReadSurface; + mCurrentDrawSurface = nullptr; + mCurrentReadSurface = nullptr; + if (drawSurface) + { + ANGLE_TRY(drawSurface->unMakeCurrent(this)); + } + if (drawSurface != readSurface) + { + ANGLE_TRY(readSurface->unMakeCurrent(this)); + } + + return egl::NoError(); +} + +void Context::onPreSwap() const +{ + // Dump frame capture if enabled. + getShareGroup()->getFrameCaptureShared()->onEndFrame(this); +} + +void Context::getTexImage(TextureTarget target, + GLint level, + GLenum format, + GLenum type, + void *pixels) +{ + Texture *texture = getTextureByTarget(target); + Buffer *packBuffer = mState.getTargetBuffer(BufferBinding::PixelPack); + ANGLE_CONTEXT_TRY(texture->getTexImage(this, mState.getPackState(), packBuffer, target, level, + format, type, pixels)); +} + +void Context::getCompressedTexImage(TextureTarget target, GLint level, void *pixels) +{ + Texture *texture = getTextureByTarget(target); + Buffer *packBuffer = mState.getTargetBuffer(BufferBinding::PixelPack); + ANGLE_CONTEXT_TRY(texture->getCompressedTexImage(this, mState.getPackState(), packBuffer, + target, level, pixels)); +} + +void Context::getRenderbufferImage(GLenum target, GLenum format, GLenum type, void *pixels) +{ + Renderbuffer *renderbuffer = mState.getCurrentRenderbuffer(); + Buffer *packBuffer = mState.getTargetBuffer(BufferBinding::PixelPack); + ANGLE_CONTEXT_TRY(renderbuffer->getRenderbufferImage(this, mState.getPackState(), packBuffer, + format, type, pixels)); +} + +void Context::logicOpANGLE(LogicalOperation opcodePacked) +{ + mState.setLogicOp(opcodePacked); +} + +egl::Error Context::releaseHighPowerGPU() +{ + return mImplementation->releaseHighPowerGPU(this); +} + +egl::Error Context::reacquireHighPowerGPU() +{ + return mImplementation->reacquireHighPowerGPU(this); +} + +void Context::onGPUSwitch() +{ + // Re-initialize the renderer string, which just changed, and + // which must be visible to applications. + initRendererString(); +} + +std::mutex &Context::getProgramCacheMutex() const +{ + return mDisplay->getProgramCacheMutex(); +} + +bool Context::supportsGeometryOrTesselation() const +{ + return mState.getClientVersion() == ES_3_2 || mState.getExtensions().geometryShaderAny() || + mState.getExtensions().tessellationShaderEXT; +} + +void Context::dirtyAllState() +{ + mState.setAllDirtyBits(); + mState.setAllDirtyObjects(); + mState.gles1().setAllDirty(); +} + +void Context::finishImmutable() const +{ + ANGLE_CONTEXT_TRY(mImplementation->finish(this)); +} + +void Context::beginPerfMonitor(GLuint monitor) {} + +void Context::deletePerfMonitors(GLsizei n, GLuint *monitors) {} + +void Context::endPerfMonitor(GLuint monitor) {} + +void Context::genPerfMonitors(GLsizei n, GLuint *monitors) +{ + for (GLsizei monitorIndex = 0; monitorIndex < n; ++monitorIndex) + { + monitors[n] = static_cast(monitorIndex); + } +} + +void Context::getPerfMonitorCounterData(GLuint monitor, + GLenum pname, + GLsizei dataSize, + GLuint *data, + GLint *bytesWritten) +{ + using namespace angle; + const PerfMonitorCounterGroups &perfMonitorGroups = mImplementation->getPerfMonitorCounters(); + GLint byteCount = 0; + switch (pname) + { + case GL_PERFMON_RESULT_AVAILABLE_AMD: + { + *data = GL_TRUE; + byteCount += sizeof(GLuint); + break; + } + case GL_PERFMON_RESULT_SIZE_AMD: + { + GLuint resultSize = 0; + for (const PerfMonitorCounterGroup &group : perfMonitorGroups) + { + resultSize += sizeof(PerfMonitorTriplet) * group.counters.size(); + } + *data = resultSize; + byteCount += sizeof(GLuint); + break; + } + case GL_PERFMON_RESULT_AMD: + { + PerfMonitorTriplet *resultsOut = reinterpret_cast(data); + GLsizei maxResults = dataSize / (3 * sizeof(GLuint)); + GLsizei resultCount = 0; + for (size_t groupIndex = 0; + groupIndex < perfMonitorGroups.size() && resultCount < maxResults; ++groupIndex) + { + const PerfMonitorCounterGroup &group = perfMonitorGroups[groupIndex]; + for (size_t counterIndex = 0; + counterIndex < group.counters.size() && resultCount < maxResults; + ++counterIndex) + { + const PerfMonitorCounter &counter = group.counters[counterIndex]; + PerfMonitorTriplet &triplet = resultsOut[resultCount++]; + triplet.counter = static_cast(counterIndex); + triplet.group = static_cast(groupIndex); + triplet.value = counter.value; + } + } + byteCount += sizeof(PerfMonitorTriplet) * resultCount; + break; + } + default: + UNREACHABLE(); + } + + if (bytesWritten) + { + *bytesWritten = byteCount; + } +} + +void Context::getPerfMonitorCounterInfo(GLuint group, GLuint counter, GLenum pname, void *data) +{ + using namespace angle; + const PerfMonitorCounterGroups &perfMonitorGroups = mImplementation->getPerfMonitorCounters(); + ASSERT(group < perfMonitorGroups.size()); + const PerfMonitorCounters &counters = perfMonitorGroups[group].counters; + ASSERT(counter < counters.size()); + + switch (pname) + { + case GL_COUNTER_TYPE_AMD: + { + GLenum *dataOut = reinterpret_cast(data); + *dataOut = GL_UNSIGNED_INT; + break; + } + case GL_COUNTER_RANGE_AMD: + { + GLuint *dataOut = reinterpret_cast(data); + dataOut[0] = 0; + dataOut[1] = std::numeric_limits::max(); + break; + } + default: + UNREACHABLE(); + } +} + +void Context::getPerfMonitorCounterString(GLuint group, + GLuint counter, + GLsizei bufSize, + GLsizei *length, + GLchar *counterString) +{ + using namespace angle; + const PerfMonitorCounterGroups &perfMonitorGroups = mImplementation->getPerfMonitorCounters(); + ASSERT(group < perfMonitorGroups.size()); + const PerfMonitorCounters &counters = perfMonitorGroups[group].counters; + ASSERT(counter < counters.size()); + GetPerfMonitorString(counters[counter].name, bufSize, length, counterString); +} + +void Context::getPerfMonitorCounters(GLuint group, + GLint *numCounters, + GLint *maxActiveCounters, + GLsizei counterSize, + GLuint *counters) +{ + using namespace angle; + const PerfMonitorCounterGroups &perfMonitorGroups = mImplementation->getPerfMonitorCounters(); + ASSERT(group < perfMonitorGroups.size()); + const PerfMonitorCounters &groupCounters = perfMonitorGroups[group].counters; + + if (numCounters) + { + *numCounters = static_cast(groupCounters.size()); + } + + if (maxActiveCounters) + { + *maxActiveCounters = static_cast(groupCounters.size()); + } + + if (counters) + { + GLsizei maxCounterIndex = std::min(counterSize, static_cast(groupCounters.size())); + for (GLsizei counterIndex = 0; counterIndex < maxCounterIndex; ++counterIndex) + { + counters[counterIndex] = static_cast(counterIndex); + } + } +} + +void Context::getPerfMonitorGroupString(GLuint group, + GLsizei bufSize, + GLsizei *length, + GLchar *groupString) +{ + using namespace angle; + const PerfMonitorCounterGroups &perfMonitorGroups = mImplementation->getPerfMonitorCounters(); + ASSERT(group < perfMonitorGroups.size()); + GetPerfMonitorString(perfMonitorGroups[group].name, bufSize, length, groupString); +} + +void Context::getPerfMonitorGroups(GLint *numGroups, GLsizei groupsSize, GLuint *groups) +{ + using namespace angle; + const PerfMonitorCounterGroups &perfMonitorGroups = mImplementation->getPerfMonitorCounters(); + + if (numGroups) + { + *numGroups = static_cast(perfMonitorGroups.size()); + } + + GLuint maxGroupIndex = + std::min(groupsSize, static_cast(perfMonitorGroups.size())); + for (GLuint groupIndex = 0; groupIndex < maxGroupIndex; ++groupIndex) + { + groups[groupIndex] = groupIndex; + } +} + +void Context::selectPerfMonitorCounters(GLuint monitor, + GLboolean enable, + GLuint group, + GLint numCounters, + GLuint *counterList) +{} + +const angle::PerfMonitorCounterGroups &Context::getPerfMonitorCounterGroups() const +{ + return mImplementation->getPerfMonitorCounters(); +} + +// ErrorSet implementation. +ErrorSet::ErrorSet(Context *context) : mContext(context) {} + +ErrorSet::~ErrorSet() = default; + +void ErrorSet::handleError(GLenum errorCode, + const char *message, + const char *file, + const char *function, + unsigned int line) +{ + if (errorCode == GL_OUT_OF_MEMORY && + mContext->getGraphicsResetStrategy() == GL_LOSE_CONTEXT_ON_RESET_EXT && + mContext->getDisplay()->getFrontendFeatures().loseContextOnOutOfMemory.enabled) + { + mContext->markContextLost(GraphicsResetStatus::UnknownContextReset); + } + + std::stringstream errorStream; + errorStream << "Error: " << gl::FmtHex(errorCode) << ", in " << file << ", " << function << ":" + << line << ". " << message; + + std::string formattedMessage = errorStream.str(); + + // Process the error, but log it with WARN severity so it shows up in logs. + ASSERT(errorCode != GL_NO_ERROR); + mErrors.insert(errorCode); + + mContext->getState().getDebug().insertMessage( + GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, errorCode, GL_DEBUG_SEVERITY_HIGH, + std::move(formattedMessage), gl::LOG_WARN, angle::EntryPoint::GLInvalid); +} + +void ErrorSet::validationError(angle::EntryPoint entryPoint, GLenum errorCode, const char *message) +{ + ASSERT(errorCode != GL_NO_ERROR); + mErrors.insert(errorCode); + + mContext->getState().getDebug().insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, + errorCode, GL_DEBUG_SEVERITY_HIGH, message, + gl::LOG_INFO, entryPoint); +} + +bool ErrorSet::empty() const +{ + return mErrors.empty(); +} + +GLenum ErrorSet::popError() +{ + ASSERT(!empty()); + GLenum error = *mErrors.begin(); + mErrors.erase(mErrors.begin()); + return error; +} + +// StateCache implementation. +StateCache::StateCache() + : mCachedHasAnyEnabledClientAttrib(false), + mCachedNonInstancedVertexElementLimit(0), + mCachedInstancedVertexElementLimit(0), + mCachedBasicDrawStatesError(kInvalidPointer), + mCachedBasicDrawElementsError(kInvalidPointer), + mCachedProgramPipelineError(kInvalidPointer), + mCachedTransformFeedbackActiveUnpaused(false), + mCachedCanDraw(false) +{ + mCachedValidDrawModes.fill(false); +} + +StateCache::~StateCache() = default; + +ANGLE_INLINE void StateCache::updateVertexElementLimits(Context *context) +{ + if (context->isBufferAccessValidationEnabled()) + { + updateVertexElementLimitsImpl(context); + } +} + +void StateCache::initialize(Context *context) +{ + updateValidDrawModes(context); + updateValidBindTextureTypes(context); + updateValidDrawElementsTypes(context); + updateBasicDrawStatesError(); + updateBasicDrawElementsError(); + updateVertexAttribTypesValidation(context); + updateCanDraw(context); +} + +void StateCache::updateActiveAttribsMask(Context *context) +{ + bool isGLES1 = context->isGLES1(); + const State &glState = context->getState(); + + if (!isGLES1 && !glState.getProgramExecutable()) + { + mCachedActiveBufferedAttribsMask = AttributesMask(); + mCachedActiveClientAttribsMask = AttributesMask(); + mCachedActiveDefaultAttribsMask = AttributesMask(); + return; + } + + AttributesMask activeAttribs = + isGLES1 ? glState.gles1().getActiveAttributesMask() + : glState.getProgramExecutable()->getActiveAttribLocationsMask(); + + const VertexArray *vao = glState.getVertexArray(); + ASSERT(vao); + + const AttributesMask &clientAttribs = vao->getClientAttribsMask(); + const AttributesMask &enabledAttribs = vao->getEnabledAttributesMask(); + const AttributesMask &activeEnabled = activeAttribs & enabledAttribs; + + mCachedActiveClientAttribsMask = activeEnabled & clientAttribs; + mCachedActiveBufferedAttribsMask = activeEnabled & ~clientAttribs; + mCachedActiveDefaultAttribsMask = activeAttribs & ~enabledAttribs; + mCachedHasAnyEnabledClientAttrib = (clientAttribs & enabledAttribs).any(); +} + +void StateCache::updateVertexElementLimitsImpl(Context *context) +{ + ASSERT(context->isBufferAccessValidationEnabled()); + + const VertexArray *vao = context->getState().getVertexArray(); + + mCachedNonInstancedVertexElementLimit = std::numeric_limits::max(); + mCachedInstancedVertexElementLimit = std::numeric_limits::max(); + + // VAO can be null on Context startup. If we make this computation lazier we could ASSERT. + // If there are no buffered attributes then we should not limit the draw call count. + if (!vao || !mCachedActiveBufferedAttribsMask.any()) + { + return; + } + + const auto &vertexAttribs = vao->getVertexAttributes(); + const auto &vertexBindings = vao->getVertexBindings(); + + for (size_t attributeIndex : mCachedActiveBufferedAttribsMask) + { + const VertexAttribute &attrib = vertexAttribs[attributeIndex]; + + const VertexBinding &binding = vertexBindings[attrib.bindingIndex]; + ASSERT(context->isGLES1() || + context->getState().getProgramExecutable()->isAttribLocationActive(attributeIndex)); + + GLint64 limit = attrib.getCachedElementLimit(); + if (binding.getDivisor() > 0) + { + mCachedInstancedVertexElementLimit = + std::min(mCachedInstancedVertexElementLimit, limit); + } + else + { + mCachedNonInstancedVertexElementLimit = + std::min(mCachedNonInstancedVertexElementLimit, limit); + } + } +} + +void StateCache::updateBasicDrawStatesError() +{ + mCachedBasicDrawStatesError = kInvalidPointer; +} + +void StateCache::updateProgramPipelineError() +{ + mCachedProgramPipelineError = kInvalidPointer; +} + +void StateCache::updateBasicDrawElementsError() +{ + mCachedBasicDrawElementsError = kInvalidPointer; +} + +intptr_t StateCache::getBasicDrawStatesErrorImpl(const Context *context) const +{ + ASSERT(mCachedBasicDrawStatesError == kInvalidPointer); + mCachedBasicDrawStatesError = reinterpret_cast(ValidateDrawStates(context)); + return mCachedBasicDrawStatesError; +} + +intptr_t StateCache::getProgramPipelineErrorImpl(const Context *context) const +{ + ASSERT(mCachedProgramPipelineError == kInvalidPointer); + mCachedProgramPipelineError = reinterpret_cast(ValidateProgramPipeline(context)); + return mCachedProgramPipelineError; +} + +intptr_t StateCache::getBasicDrawElementsErrorImpl(const Context *context) const +{ + ASSERT(mCachedBasicDrawElementsError == kInvalidPointer); + mCachedBasicDrawElementsError = reinterpret_cast(ValidateDrawElementsStates(context)); + return mCachedBasicDrawElementsError; +} + +void StateCache::onVertexArrayBindingChange(Context *context) +{ + updateActiveAttribsMask(context); + updateVertexElementLimits(context); + updateBasicDrawStatesError(); + updateBasicDrawElementsError(); +} + +void StateCache::onProgramExecutableChange(Context *context) +{ + updateActiveAttribsMask(context); + updateVertexElementLimits(context); + updateBasicDrawStatesError(); + updateProgramPipelineError(); + updateValidDrawModes(context); + updateActiveShaderStorageBufferIndices(context); + updateActiveImageUnitIndices(context); + updateCanDraw(context); +} + +void StateCache::onVertexArrayFormatChange(Context *context) +{ + updateVertexElementLimits(context); +} + +void StateCache::onVertexArrayBufferContentsChange(Context *context) +{ + updateVertexElementLimits(context); + updateBasicDrawStatesError(); +} + +void StateCache::onVertexArrayStateChange(Context *context) +{ + updateActiveAttribsMask(context); + updateVertexElementLimits(context); + updateBasicDrawStatesError(); + updateBasicDrawElementsError(); +} + +void StateCache::onVertexArrayBufferStateChange(Context *context) +{ + updateBasicDrawStatesError(); + updateBasicDrawElementsError(); +} + +void StateCache::onGLES1ClientStateChange(Context *context) +{ + updateActiveAttribsMask(context); +} + +void StateCache::onDrawFramebufferChange(Context *context) +{ + updateBasicDrawStatesError(); +} + +void StateCache::onContextCapChange(Context *context) +{ + updateBasicDrawStatesError(); +} + +void StateCache::onStencilStateChange(Context *context) +{ + updateBasicDrawStatesError(); +} + +void StateCache::onDefaultVertexAttributeChange(Context *context) +{ + updateBasicDrawStatesError(); +} + +void StateCache::onActiveTextureChange(Context *context) +{ + updateBasicDrawStatesError(); +} + +void StateCache::onQueryChange(Context *context) +{ + updateBasicDrawStatesError(); +} + +void StateCache::onActiveTransformFeedbackChange(Context *context) +{ + updateTransformFeedbackActiveUnpaused(context); + updateBasicDrawStatesError(); + updateBasicDrawElementsError(); + updateValidDrawModes(context); +} + +void StateCache::onUniformBufferStateChange(Context *context) +{ + updateBasicDrawStatesError(); +} + +void StateCache::onAtomicCounterBufferStateChange(Context *context) +{ + updateBasicDrawStatesError(); +} + +void StateCache::onShaderStorageBufferStateChange(Context *context) +{ + updateBasicDrawStatesError(); +} + +void StateCache::onColorMaskChange(Context *context) +{ + updateBasicDrawStatesError(); +} + +void StateCache::onBlendFuncIndexedChange(Context *context) +{ + updateBasicDrawStatesError(); +} + +void StateCache::onBlendEquationChange(Context *context) +{ + updateBasicDrawStatesError(); +} + +void StateCache::setValidDrawModes(bool pointsOK, + bool linesOK, + bool trisOK, + bool lineAdjOK, + bool triAdjOK, + bool patchOK) +{ + mCachedValidDrawModes[PrimitiveMode::Points] = pointsOK; + mCachedValidDrawModes[PrimitiveMode::Lines] = linesOK; + mCachedValidDrawModes[PrimitiveMode::LineLoop] = linesOK; + mCachedValidDrawModes[PrimitiveMode::LineStrip] = linesOK; + mCachedValidDrawModes[PrimitiveMode::Triangles] = trisOK; + mCachedValidDrawModes[PrimitiveMode::TriangleStrip] = trisOK; + mCachedValidDrawModes[PrimitiveMode::TriangleFan] = trisOK; + mCachedValidDrawModes[PrimitiveMode::LinesAdjacency] = lineAdjOK; + mCachedValidDrawModes[PrimitiveMode::LineStripAdjacency] = lineAdjOK; + mCachedValidDrawModes[PrimitiveMode::TrianglesAdjacency] = triAdjOK; + mCachedValidDrawModes[PrimitiveMode::TriangleStripAdjacency] = triAdjOK; + mCachedValidDrawModes[PrimitiveMode::Patches] = patchOK; +} + +void StateCache::updateValidDrawModes(Context *context) +{ + const State &state = context->getState(); + + const ProgramExecutable *programExecutable = context->getState().getProgramExecutable(); + + // If tessellation is active primitive mode must be GL_PATCHES. + if (programExecutable && programExecutable->hasLinkedTessellationShader()) + { + setValidDrawModes(false, false, false, false, false, true); + return; + } + + if (mCachedTransformFeedbackActiveUnpaused) + { + TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback(); + + // ES Spec 3.0 validation text: + // When transform feedback is active and not paused, all geometric primitives generated must + // match the value of primitiveMode passed to BeginTransformFeedback. The error + // INVALID_OPERATION is generated by DrawArrays and DrawArraysInstanced if mode is not + // identical to primitiveMode. The error INVALID_OPERATION is also generated by + // DrawElements, DrawElementsInstanced, and DrawRangeElements while transform feedback is + // active and not paused, regardless of mode. Any primitive type may be used while transform + // feedback is paused. + if (!context->getExtensions().geometryShaderAny() && + !context->getExtensions().tessellationShaderEXT && context->getClientVersion() < ES_3_2) + { + mCachedValidDrawModes.fill(false); + mCachedValidDrawModes[curTransformFeedback->getPrimitiveMode()] = true; + return; + } + } + + if (!programExecutable || !programExecutable->hasLinkedShaderStage(ShaderType::Geometry)) + { + // All draw modes are valid, since drawing without a program does not generate an error and + // and operations requiring a GS will trigger other validation errors. + // `patchOK = false` due to checking above already enabling it if a TS is present. + setValidDrawModes(true, true, true, true, true, false); + return; + } + + PrimitiveMode gsMode = programExecutable->getGeometryShaderInputPrimitiveType(); + bool pointsOK = gsMode == PrimitiveMode::Points; + bool linesOK = gsMode == PrimitiveMode::Lines; + bool trisOK = gsMode == PrimitiveMode::Triangles; + bool lineAdjOK = gsMode == PrimitiveMode::LinesAdjacency; + bool triAdjOK = gsMode == PrimitiveMode::TrianglesAdjacency; + + setValidDrawModes(pointsOK, linesOK, trisOK, lineAdjOK, triAdjOK, false); +} + +void StateCache::updateValidBindTextureTypes(Context *context) +{ + const Extensions &exts = context->getExtensions(); + bool isGLES3 = context->getClientMajorVersion() >= 3; + bool isGLES31 = context->getClientVersion() >= Version(3, 1); + + mCachedValidBindTextureTypes = {{ + {TextureType::_2D, true}, + {TextureType::_2DArray, isGLES3}, + {TextureType::_2DMultisample, isGLES31 || exts.textureMultisampleANGLE}, + {TextureType::_2DMultisampleArray, exts.textureStorageMultisample2dArrayOES}, + {TextureType::_3D, isGLES3 || exts.texture3DOES}, + {TextureType::External, exts.EGLImageExternalOES || exts.EGLStreamConsumerExternalNV}, + {TextureType::Rectangle, exts.textureRectangleANGLE}, + {TextureType::CubeMap, true}, + {TextureType::CubeMapArray, exts.textureCubeMapArrayAny()}, + {TextureType::VideoImage, exts.videoTextureWEBGL}, + {TextureType::Buffer, exts.textureBufferAny()}, + }}; +} + +void StateCache::updateValidDrawElementsTypes(Context *context) +{ + bool supportsUint = + (context->getClientMajorVersion() >= 3 || context->getExtensions().elementIndexUintOES); + + mCachedValidDrawElementsTypes = {{ + {DrawElementsType::UnsignedByte, true}, + {DrawElementsType::UnsignedShort, true}, + {DrawElementsType::UnsignedInt, supportsUint}, + }}; +} + +void StateCache::updateTransformFeedbackActiveUnpaused(Context *context) +{ + TransformFeedback *xfb = context->getState().getCurrentTransformFeedback(); + mCachedTransformFeedbackActiveUnpaused = xfb && xfb->isActive() && !xfb->isPaused(); +} + +void StateCache::updateVertexAttribTypesValidation(Context *context) +{ + VertexAttribTypeCase halfFloatValidity = (context->getExtensions().vertexHalfFloatOES) + ? VertexAttribTypeCase::Valid + : VertexAttribTypeCase::Invalid; + + VertexAttribTypeCase vertexType1010102Validity = (context->getExtensions().vertexType1010102OES) + ? VertexAttribTypeCase::ValidSize3or4 + : VertexAttribTypeCase::Invalid; + + if (context->getClientMajorVersion() <= 2) + { + mCachedVertexAttribTypesValidation = {{ + {VertexAttribType::Byte, VertexAttribTypeCase::Valid}, + {VertexAttribType::Short, VertexAttribTypeCase::Valid}, + {VertexAttribType::UnsignedByte, VertexAttribTypeCase::Valid}, + {VertexAttribType::UnsignedShort, VertexAttribTypeCase::Valid}, + {VertexAttribType::Float, VertexAttribTypeCase::Valid}, + {VertexAttribType::Fixed, VertexAttribTypeCase::Valid}, + {VertexAttribType::HalfFloatOES, halfFloatValidity}, + }}; + } + else + { + mCachedVertexAttribTypesValidation = {{ + {VertexAttribType::Byte, VertexAttribTypeCase::Valid}, + {VertexAttribType::Short, VertexAttribTypeCase::Valid}, + {VertexAttribType::Int, VertexAttribTypeCase::Valid}, + {VertexAttribType::UnsignedByte, VertexAttribTypeCase::Valid}, + {VertexAttribType::UnsignedShort, VertexAttribTypeCase::Valid}, + {VertexAttribType::UnsignedInt, VertexAttribTypeCase::Valid}, + {VertexAttribType::Float, VertexAttribTypeCase::Valid}, + {VertexAttribType::HalfFloat, VertexAttribTypeCase::Valid}, + {VertexAttribType::Fixed, VertexAttribTypeCase::Valid}, + {VertexAttribType::Int2101010, VertexAttribTypeCase::ValidSize4Only}, + {VertexAttribType::HalfFloatOES, halfFloatValidity}, + {VertexAttribType::UnsignedInt2101010, VertexAttribTypeCase::ValidSize4Only}, + {VertexAttribType::Int1010102, vertexType1010102Validity}, + {VertexAttribType::UnsignedInt1010102, vertexType1010102Validity}, + }}; + + mCachedIntegerVertexAttribTypesValidation = {{ + {VertexAttribType::Byte, VertexAttribTypeCase::Valid}, + {VertexAttribType::Short, VertexAttribTypeCase::Valid}, + {VertexAttribType::Int, VertexAttribTypeCase::Valid}, + {VertexAttribType::UnsignedByte, VertexAttribTypeCase::Valid}, + {VertexAttribType::UnsignedShort, VertexAttribTypeCase::Valid}, + {VertexAttribType::UnsignedInt, VertexAttribTypeCase::Valid}, + }}; + } +} + +void StateCache::updateActiveShaderStorageBufferIndices(Context *context) +{ + mCachedActiveShaderStorageBufferIndices.reset(); + const ProgramExecutable *executable = context->getState().getProgramExecutable(); + if (executable) + { + for (const InterfaceBlock &block : executable->getShaderStorageBlocks()) + { + mCachedActiveShaderStorageBufferIndices.set(block.binding); + } + } +} + +void StateCache::updateActiveImageUnitIndices(Context *context) +{ + mCachedActiveImageUnitIndices.reset(); + const ProgramExecutable *executable = context->getState().getProgramExecutable(); + if (executable) + { + for (const ImageBinding &imageBinding : executable->getImageBindings()) + { + for (GLuint binding : imageBinding.boundImageUnits) + { + mCachedActiveImageUnitIndices.set(binding); + } + } + } +} + +void StateCache::updateCanDraw(Context *context) +{ + mCachedCanDraw = + (context->isGLES1() || (context->getState().getProgramExecutable() && + context->getState().getProgramExecutable()->hasVertexShader())); +} +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/Context.h b/gfx/angle/checkout/src/libANGLE/Context.h new file mode 100644 index 0000000000..fec6a6653c --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Context.h @@ -0,0 +1,901 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Context.h: Defines the gl::Context class, managing all GL state and performing +// rendering operations. It is the GLES2 specific implementation of EGLContext. + +#ifndef LIBANGLE_CONTEXT_H_ +#define LIBANGLE_CONTEXT_H_ + +#include +#include +#include + +#include "angle_gl.h" +#include "common/MemoryBuffer.h" +#include "common/PackedEnums.h" +#include "common/angleutils.h" +#include "libANGLE/Caps.h" +#include "libANGLE/Constants.h" +#include "libANGLE/Context_gl_1_autogen.h" +#include "libANGLE/Context_gl_2_autogen.h" +#include "libANGLE/Context_gl_3_autogen.h" +#include "libANGLE/Context_gl_4_autogen.h" +#include "libANGLE/Context_gles_1_0_autogen.h" +#include "libANGLE/Context_gles_2_0_autogen.h" +#include "libANGLE/Context_gles_3_0_autogen.h" +#include "libANGLE/Context_gles_3_1_autogen.h" +#include "libANGLE/Context_gles_3_2_autogen.h" +#include "libANGLE/Context_gles_ext_autogen.h" +#include "libANGLE/Error.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/HandleAllocator.h" +#include "libANGLE/RefCountObject.h" +#include "libANGLE/ResourceManager.h" +#include "libANGLE/ResourceMap.h" +#include "libANGLE/State.h" +#include "libANGLE/VertexAttribute.h" +#include "libANGLE/WorkerThread.h" +#include "libANGLE/angletypes.h" + +namespace angle +{ +class FrameCapture; +class FrameCaptureShared; +struct FrontendFeatures; +} // namespace angle + +namespace rx +{ +class ContextImpl; +class EGLImplFactory; +} // namespace rx + +namespace egl +{ +class AttributeMap; +class Surface; +struct Config; +class Thread; +} // namespace egl + +namespace gl +{ +class Buffer; +class Compiler; +class FenceNV; +class GLES1Renderer; +class MemoryProgramCache; +class MemoryShaderCache; +class MemoryObject; +class Program; +class ProgramPipeline; +class Query; +class Renderbuffer; +class Sampler; +class Semaphore; +class Shader; +class Sync; +class Texture; +class TransformFeedback; +class VertexArray; +struct VertexAttribute; + +class ErrorSet : angle::NonCopyable +{ + public: + explicit ErrorSet(Context *context); + ~ErrorSet(); + + bool empty() const; + GLenum popError(); + + void handleError(GLenum errorCode, + const char *message, + const char *file, + const char *function, + unsigned int line); + + void validationError(angle::EntryPoint entryPoint, GLenum errorCode, const char *message); + + private: + Context *mContext; + std::set mErrors; +}; + +enum class VertexAttribTypeCase +{ + Invalid = 0, + Valid = 1, + ValidSize4Only = 2, + ValidSize3or4 = 3, +}; + +// Helper class for managing cache variables and state changes. +class StateCache final : angle::NonCopyable +{ + public: + StateCache(); + ~StateCache(); + + void initialize(Context *context); + + // Places that can trigger updateActiveAttribsMask: + // 1. onVertexArrayBindingChange. + // 2. onProgramExecutableChange. + // 3. onVertexArrayStateChange. + // 4. onGLES1ClientStateChange. + AttributesMask getActiveBufferedAttribsMask() const { return mCachedActiveBufferedAttribsMask; } + AttributesMask getActiveClientAttribsMask() const { return mCachedActiveClientAttribsMask; } + AttributesMask getActiveDefaultAttribsMask() const { return mCachedActiveDefaultAttribsMask; } + bool hasAnyEnabledClientAttrib() const { return mCachedHasAnyEnabledClientAttrib; } + bool hasAnyActiveClientAttrib() const { return mCachedActiveClientAttribsMask.any(); } + + // Places that can trigger updateVertexElementLimits: + // 1. onVertexArrayBindingChange. + // 2. onProgramExecutableChange. + // 3. onVertexArrayFormatChange. + // 4. onVertexArrayBufferChange. + // 5. onVertexArrayStateChange. + GLint64 getNonInstancedVertexElementLimit() const + { + return mCachedNonInstancedVertexElementLimit; + } + GLint64 getInstancedVertexElementLimit() const { return mCachedInstancedVertexElementLimit; } + + // Places that can trigger updateBasicDrawStatesError: + // 1. onVertexArrayBindingChange. + // 2. onProgramExecutableChange. + // 3. onVertexArrayBufferContentsChange. + // 4. onVertexArrayStateChange. + // 5. onVertexArrayBufferStateChange. + // 6. onDrawFramebufferChange. + // 7. onContextCapChange. + // 8. onStencilStateChange. + // 9. onDefaultVertexAttributeChange. + // 10. onActiveTextureChange. + // 11. onQueryChange. + // 12. onActiveTransformFeedbackChange. + // 13. onUniformBufferStateChange. + // 14. onColorMaskChange. + // 15. onBufferBindingChange. + // 16. onBlendFuncIndexedChange. + bool hasBasicDrawStatesError(Context *context) const + { + if (mCachedBasicDrawStatesError == 0) + { + return false; + } + if (mCachedBasicDrawStatesError != kInvalidPointer) + { + return true; + } + return getBasicDrawStatesErrorImpl(context) != 0; + } + + intptr_t getBasicDrawStatesError(const Context *context) const + { + if (mCachedBasicDrawStatesError != kInvalidPointer) + { + return mCachedBasicDrawStatesError; + } + + return getBasicDrawStatesErrorImpl(context); + } + + // Places that can trigger updateProgramPipelineError: + // 1. onProgramExecutableChange. + intptr_t getProgramPipelineError(const Context *context) const + { + if (mCachedProgramPipelineError != kInvalidPointer) + { + return mCachedProgramPipelineError; + } + + return getProgramPipelineErrorImpl(context); + } + + // Places that can trigger updateBasicDrawElementsError: + // 1. onActiveTransformFeedbackChange. + // 2. onVertexArrayBufferStateChange. + // 3. onBufferBindingChange. + // 4. onVertexArrayStateChange. + // 5. onVertexArrayBindingStateChange. + intptr_t getBasicDrawElementsError(const Context *context) const + { + if (mCachedBasicDrawElementsError != kInvalidPointer) + { + return mCachedBasicDrawElementsError; + } + + return getBasicDrawElementsErrorImpl(context); + } + + // Places that can trigger updateValidDrawModes: + // 1. onProgramExecutableChange. + // 2. onActiveTransformFeedbackChange. + bool isValidDrawMode(PrimitiveMode primitiveMode) const + { + return mCachedValidDrawModes[primitiveMode]; + } + + // Cannot change except on Context/Extension init. + bool isValidBindTextureType(TextureType type) const + { + return mCachedValidBindTextureTypes[type]; + } + + // Cannot change except on Context/Extension init. + bool isValidDrawElementsType(DrawElementsType type) const + { + return mCachedValidDrawElementsTypes[type]; + } + + // Places that can trigger updateTransformFeedbackActiveUnpaused: + // 1. onActiveTransformFeedbackChange. + bool isTransformFeedbackActiveUnpaused() const + { + return mCachedTransformFeedbackActiveUnpaused; + } + + // Cannot change except on Context/Extension init. + VertexAttribTypeCase getVertexAttribTypeValidation(VertexAttribType type) const + { + return mCachedVertexAttribTypesValidation[type]; + } + + VertexAttribTypeCase getIntegerVertexAttribTypeValidation(VertexAttribType type) const + { + return mCachedIntegerVertexAttribTypesValidation[type]; + } + + // Places that can trigger updateActiveShaderStorageBufferIndices: + // 1. onProgramExecutableChange. + StorageBuffersMask getActiveShaderStorageBufferIndices() const + { + return mCachedActiveShaderStorageBufferIndices; + } + + // Places that can trigger updateActiveImageUnitIndices: + // 1. onProgramExecutableChange. + const ImageUnitMask &getActiveImageUnitIndices() const { return mCachedActiveImageUnitIndices; } + + // Places that can trigger updateCanDraw: + // 1. onProgramExecutableChange. + bool getCanDraw() const { return mCachedCanDraw; } + + // State change notifications. + void onVertexArrayBindingChange(Context *context); + void onProgramExecutableChange(Context *context); + void onVertexArrayFormatChange(Context *context); + void onVertexArrayBufferContentsChange(Context *context); + void onVertexArrayStateChange(Context *context); + void onVertexArrayBufferStateChange(Context *context); + void onGLES1ClientStateChange(Context *context); + void onDrawFramebufferChange(Context *context); + void onContextCapChange(Context *context); + void onStencilStateChange(Context *context); + void onDefaultVertexAttributeChange(Context *context); + void onActiveTextureChange(Context *context); + void onQueryChange(Context *context); + void onActiveTransformFeedbackChange(Context *context); + void onUniformBufferStateChange(Context *context); + void onAtomicCounterBufferStateChange(Context *context); + void onShaderStorageBufferStateChange(Context *context); + void onColorMaskChange(Context *context); + void onBufferBindingChange(Context *context); + void onBlendFuncIndexedChange(Context *context); + void onBlendEquationChange(Context *context); + + private: + // Cache update functions. + void updateActiveAttribsMask(Context *context); + void updateVertexElementLimits(Context *context); + void updateVertexElementLimitsImpl(Context *context); + void updateValidDrawModes(Context *context); + void updateValidBindTextureTypes(Context *context); + void updateValidDrawElementsTypes(Context *context); + void updateBasicDrawStatesError(); + void updateProgramPipelineError(); + void updateBasicDrawElementsError(); + void updateTransformFeedbackActiveUnpaused(Context *context); + void updateVertexAttribTypesValidation(Context *context); + void updateActiveShaderStorageBufferIndices(Context *context); + void updateActiveImageUnitIndices(Context *context); + void updateCanDraw(Context *context); + + void setValidDrawModes(bool pointsOK, + bool linesOK, + bool trisOK, + bool lineAdjOK, + bool triAdjOK, + bool patchOK); + + intptr_t getBasicDrawStatesErrorImpl(const Context *context) const; + intptr_t getProgramPipelineErrorImpl(const Context *context) const; + intptr_t getBasicDrawElementsErrorImpl(const Context *context) const; + + static constexpr intptr_t kInvalidPointer = 1; + + AttributesMask mCachedActiveBufferedAttribsMask; + AttributesMask mCachedActiveClientAttribsMask; + AttributesMask mCachedActiveDefaultAttribsMask; + bool mCachedHasAnyEnabledClientAttrib; + GLint64 mCachedNonInstancedVertexElementLimit; + GLint64 mCachedInstancedVertexElementLimit; + mutable intptr_t mCachedBasicDrawStatesError; + mutable intptr_t mCachedBasicDrawElementsError; + // mCachedProgramPipelineError checks only the + // current-program-exists subset of mCachedBasicDrawStatesError. + // Therefore, mCachedProgramPipelineError follows + // mCachedBasicDrawStatesError in that if mCachedBasicDrawStatesError is + // no-error, so is mCachedProgramPipelineError. Otherwise, if + // mCachedBasicDrawStatesError is in error, the state of + // mCachedProgramPipelineError can be no-error or also in error, or + // unknown due to early exiting. + mutable intptr_t mCachedProgramPipelineError; + bool mCachedTransformFeedbackActiveUnpaused; + StorageBuffersMask mCachedActiveShaderStorageBufferIndices; + ImageUnitMask mCachedActiveImageUnitIndices; + + // Reserve an extra slot at the end of these maps for invalid enum. + angle::PackedEnumMap() + 1> + mCachedValidDrawModes; + angle::PackedEnumMap() + 1> + mCachedValidBindTextureTypes; + angle::PackedEnumMap() + 1> + mCachedValidDrawElementsTypes; + angle::PackedEnumMap() + 1> + mCachedVertexAttribTypesValidation; + angle::PackedEnumMap() + 1> + mCachedIntegerVertexAttribTypesValidation; + + bool mCachedCanDraw; +}; + +using VertexArrayMap = ResourceMap; +using QueryMap = ResourceMap; +using TransformFeedbackMap = ResourceMap; + +class Context final : public egl::LabeledObject, angle::NonCopyable, public angle::ObserverInterface +{ + public: + Context(egl::Display *display, + const egl::Config *config, + const Context *shareContext, + TextureManager *shareTextures, + SemaphoreManager *shareSemaphores, + MemoryProgramCache *memoryProgramCache, + MemoryShaderCache *memoryShaderCache, + const EGLenum clientType, + const egl::AttributeMap &attribs, + const egl::DisplayExtensions &displayExtensions, + const egl::ClientExtensions &clientExtensions); + + // Use for debugging. + ContextID id() const { return mState.getContextID(); } + + egl::Error initialize(); + + egl::Error onDestroy(const egl::Display *display); + ~Context() override; + + void setLabel(EGLLabelKHR label) override; + EGLLabelKHR getLabel() const override; + + egl::Error makeCurrent(egl::Display *display, + egl::Surface *drawSurface, + egl::Surface *readSurface); + egl::Error unMakeCurrent(const egl::Display *display); + + // These create and destroy methods pass through to ResourceManager, which owns these objects. + BufferID createBuffer(); + TextureID createTexture(); + RenderbufferID createRenderbuffer(); + ProgramPipelineID createProgramPipeline(); + MemoryObjectID createMemoryObject(); + SemaphoreID createSemaphore(); + + void deleteBuffer(BufferID buffer); + void deleteTexture(TextureID texture); + void deleteRenderbuffer(RenderbufferID renderbuffer); + void deleteProgramPipeline(ProgramPipelineID pipeline); + void deleteMemoryObject(MemoryObjectID memoryObject); + void deleteSemaphore(SemaphoreID semaphore); + + void bindReadFramebuffer(FramebufferID framebufferHandle); + void bindDrawFramebuffer(FramebufferID framebufferHandle); + + Buffer *getBuffer(BufferID handle) const; + FenceNV *getFenceNV(FenceNVID handle) const; + Sync *getSync(GLsync handle) const; + ANGLE_INLINE Texture *getTexture(TextureID handle) const + { + return mState.mTextureManager->getTexture(handle); + } + + Framebuffer *getFramebuffer(FramebufferID handle) const; + Renderbuffer *getRenderbuffer(RenderbufferID handle) const; + VertexArray *getVertexArray(VertexArrayID handle) const; + Sampler *getSampler(SamplerID handle) const; + Query *getOrCreateQuery(QueryID handle, QueryType type); + Query *getQuery(QueryID handle) const; + TransformFeedback *getTransformFeedback(TransformFeedbackID handle) const; + ProgramPipeline *getProgramPipeline(ProgramPipelineID handle) const; + MemoryObject *getMemoryObject(MemoryObjectID handle) const; + Semaphore *getSemaphore(SemaphoreID handle) const; + + Texture *getTextureByType(TextureType type) const; + Texture *getTextureByTarget(TextureTarget target) const; + Texture *getSamplerTexture(unsigned int sampler, TextureType type) const; + + Compiler *getCompiler() const; + + bool isVertexArrayGenerated(VertexArrayID vertexArray) const; + bool isTransformFeedbackGenerated(TransformFeedbackID transformFeedback) const; + + bool isExternal() const { return mIsExternal; } + bool saveAndRestoreState() const { return mSaveAndRestoreState; } + + void getBooleanvImpl(GLenum pname, GLboolean *params) const; + void getFloatvImpl(GLenum pname, GLfloat *params) const; + void getIntegervImpl(GLenum pname, GLint *params) const; + void getInteger64vImpl(GLenum pname, GLint64 *params) const; + void getIntegerVertexAttribImpl(GLenum pname, GLenum attribpname, GLint *params) const; + void getVertexAttribivImpl(GLuint index, GLenum pname, GLint *params) const; + + // Framebuffers are owned by the Context, so these methods do not pass through + FramebufferID createFramebuffer(); + void deleteFramebuffer(FramebufferID framebuffer); + + bool hasActiveTransformFeedback(ShaderProgramID program) const; + + // Desktop GL entry point interface + ANGLE_GL_1_CONTEXT_API + ANGLE_GL_2_CONTEXT_API + ANGLE_GL_3_CONTEXT_API + ANGLE_GL_4_CONTEXT_API + + // GLES entry point interface + ANGLE_GLES_1_0_CONTEXT_API + ANGLE_GLES_2_0_CONTEXT_API + ANGLE_GLES_3_0_CONTEXT_API + ANGLE_GLES_3_1_CONTEXT_API + ANGLE_GLES_3_2_CONTEXT_API + ANGLE_GLES_EXT_CONTEXT_API + + angle::Result handleNoopDrawEvent(); + + // Consumes an error. + void handleError(GLenum errorCode, + const char *message, + const char *file, + const char *function, + unsigned int line); + + void validationError(angle::EntryPoint entryPoint, GLenum errorCode, const char *message) const; + ANGLE_FORMAT_PRINTF(4, 5) + void validationErrorF(angle::EntryPoint entryPoint, + GLenum errorCode, + const char *format, + ...) const; + + void markContextLost(GraphicsResetStatus status); + + bool isContextLost() const { return mContextLost; } + void setContextLost(); + + GLenum getGraphicsResetStrategy() const { return mResetStrategy; } + bool isResetNotificationEnabled() const; + + bool isRobustnessEnabled() const; + + const egl::Config *getConfig() const; + EGLenum getClientType() const; + EGLenum getRenderBuffer() const; + EGLenum getContextPriority() const; + + const GLubyte *getString(GLenum name) const; + const GLubyte *getStringi(GLenum name, GLuint index) const; + + size_t getExtensionStringCount() const; + + bool isExtensionRequestable(const char *name) const; + bool isExtensionDisablable(const char *name) const; + size_t getRequestableExtensionStringCount() const; + void setExtensionEnabled(const char *name, bool enabled); + void reinitializeAfterExtensionsChanged(); + + rx::ContextImpl *getImplementation() const { return mImplementation.get(); } + + [[nodiscard]] bool getScratchBuffer(size_t requestedSizeBytes, + angle::MemoryBuffer **scratchBufferOut) const; + [[nodiscard]] bool getZeroFilledBuffer(size_t requstedSizeBytes, + angle::MemoryBuffer **zeroBufferOut) const; + angle::ScratchBuffer *getScratchBuffer() const; + + angle::Result prepareForCopyImage(); + angle::Result prepareForDispatch(); + angle::Result prepareForInvalidate(GLenum target); + + MemoryProgramCache *getMemoryProgramCache() const { return mMemoryProgramCache; } + MemoryShaderCache *getMemoryShaderCache() const { return mMemoryShaderCache; } + + std::mutex &getProgramCacheMutex() const; + + bool hasBeenCurrent() const { return mHasBeenCurrent; } + egl::Display *getDisplay() const { return mDisplay; } + egl::Surface *getCurrentDrawSurface() const { return mCurrentDrawSurface; } + egl::Surface *getCurrentReadSurface() const { return mCurrentReadSurface; } + + bool isRobustResourceInitEnabled() const { return mState.isRobustResourceInitEnabled(); } + + bool isCurrentTransformFeedback(const TransformFeedback *tf) const; + + bool isCurrentVertexArray(const VertexArray *va) const + { + return mState.isCurrentVertexArray(va); + } + + ANGLE_INLINE bool isShared() const { return mShared; } + // Once a context is setShared() it cannot be undone + void setShared() { mShared = true; } + + const State &getState() const { return mState; } + GLint getClientMajorVersion() const { return mState.getClientMajorVersion(); } + GLint getClientMinorVersion() const { return mState.getClientMinorVersion(); } + const Version &getClientVersion() const { return mState.getClientVersion(); } + const Caps &getCaps() const { return mState.getCaps(); } + const TextureCapsMap &getTextureCaps() const { return mState.getTextureCaps(); } + const Extensions &getExtensions() const { return mState.getExtensions(); } + const Limitations &getLimitations() const { return mState.getLimitations(); } + bool isGLES1() const; + + bool skipValidation() const + { + // Ensure we don't skip validation when context becomes lost, since implementations + // generally assume a non-lost context, non-null objects, etc. + ASSERT(!isContextLost() || !mSkipValidation); + return mSkipValidation; + } + + // Specific methods needed for validation. + bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) const; + bool getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams) const; + + ANGLE_INLINE Program *getProgramResolveLink(ShaderProgramID handle) const + { + Program *program = mState.mShaderProgramManager->getProgram(handle); + if (program) + { + program->resolveLink(this); + } + return program; + } + + Program *getProgramNoResolveLink(ShaderProgramID handle) const; + Shader *getShader(ShaderProgramID handle) const; + + ANGLE_INLINE bool isTextureGenerated(TextureID texture) const + { + return mState.mTextureManager->isHandleGenerated(texture); + } + + ANGLE_INLINE bool isBufferGenerated(BufferID buffer) const + { + return mState.mBufferManager->isHandleGenerated(buffer); + } + + bool isRenderbufferGenerated(RenderbufferID renderbuffer) const; + bool isFramebufferGenerated(FramebufferID framebuffer) const; + bool isProgramPipelineGenerated(ProgramPipelineID pipeline) const; + bool isQueryGenerated(QueryID query) const; + + bool usingDisplayTextureShareGroup() const; + bool usingDisplaySemaphoreShareGroup() const; + + // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format. + GLenum getConvertedRenderbufferFormat(GLenum internalformat) const; + + bool isWebGL() const { return mState.isWebGL(); } + bool isWebGL1() const { return mState.isWebGL1(); } + + bool isValidBufferBinding(BufferBinding binding) const { return mValidBufferBindings[binding]; } + + // GLES1 emulation: Renderer level (for validation) + int vertexArrayIndex(ClientVertexArrayType type) const; + static int TexCoordArrayIndex(unsigned int unit); + + // GL_KHR_parallel_shader_compile + std::shared_ptr getShaderCompileThreadPool() const + { + if (mState.mExtensions.parallelShaderCompileKHR) + { + return mMultiThreadPool; + } + return mSingleThreadPool; + } + + // Generic multithread pool. + std::shared_ptr getWorkerThreadPool() const + { + return mMultiThreadPool; + } + + const StateCache &getStateCache() const { return mStateCache; } + StateCache &getStateCache() { return mStateCache; } + + void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; + + void onSamplerUniformChange(size_t textureUnitIndex); + + bool isBufferAccessValidationEnabled() const { return mBufferAccessValidationEnabled; } + + const angle::FrontendFeatures &getFrontendFeatures() const; + + angle::FrameCapture *getFrameCapture() const { return mFrameCapture.get(); } + + const VertexArrayMap &getVertexArraysForCapture() const { return mVertexArrayMap; } + const QueryMap &getQueriesForCapture() const { return mQueryMap; } + const TransformFeedbackMap &getTransformFeedbacksForCapture() const + { + return mTransformFeedbackMap; + } + + void onPreSwap() const; + + Program *getActiveLinkedProgram() const; + + // EGL_ANGLE_power_preference implementation. + egl::Error releaseHighPowerGPU(); + egl::Error reacquireHighPowerGPU(); + void onGPUSwitch(); + + bool noopDraw(PrimitiveMode mode, GLsizei count) const; + bool noopDrawInstanced(PrimitiveMode mode, GLsizei count, GLsizei instanceCount) const; + + bool isClearBufferMaskedOut(GLenum buffer, GLint drawbuffer) const; + bool noopClearBuffer(GLenum buffer, GLint drawbuffer) const; + + void addRef() const { mRefCount++; } + void release() const { mRefCount--; } + size_t getRefCount() const { return mRefCount; } + + egl::ShareGroup *getShareGroup() const { return mState.getShareGroup(); } + + bool supportsGeometryOrTesselation() const; + void dirtyAllState(); + + bool isDestroyed() const { return mIsDestroyed; } + void setIsDestroyed() { mIsDestroyed = true; } + + void setLogicOpEnabled(bool enabled) { mState.setLogicOpEnabled(enabled); } + void setLogicOp(LogicalOperation opcode) { mState.setLogicOp(opcode); } + + // Needed by capture serialization logic that works with a "const" Context pointer. + void finishImmutable() const; + + const angle::PerfMonitorCounterGroups &getPerfMonitorCounterGroups() const; + + private: + void initializeDefaultResources(); + + angle::Result prepareForDraw(PrimitiveMode mode); + angle::Result prepareForClear(GLbitfield mask); + angle::Result prepareForClearBuffer(GLenum buffer, GLint drawbuffer); + angle::Result syncState(const State::DirtyBits &bitMask, + const State::DirtyObjects &objectMask, + Command command); + angle::Result syncDirtyBits(Command command); + angle::Result syncDirtyBits(const State::DirtyBits &bitMask, Command command); + angle::Result syncDirtyObjects(const State::DirtyObjects &objectMask, Command command); + angle::Result syncStateForReadPixels(); + angle::Result syncStateForTexImage(); + angle::Result syncStateForBlit(GLbitfield mask); + angle::Result syncStateForClear(); + angle::Result syncTextureForCopy(Texture *texture); + + VertexArray *checkVertexArrayAllocation(VertexArrayID vertexArrayHandle); + TransformFeedback *checkTransformFeedbackAllocation(TransformFeedbackID transformFeedback); + + angle::Result onProgramLink(Program *programObject); + + void detachBuffer(Buffer *buffer); + void detachTexture(TextureID texture); + void detachFramebuffer(FramebufferID framebuffer); + void detachRenderbuffer(RenderbufferID renderbuffer); + void detachVertexArray(VertexArrayID vertexArray); + void detachTransformFeedback(TransformFeedbackID transformFeedback); + void detachSampler(SamplerID sampler); + void detachProgramPipeline(ProgramPipelineID pipeline); + + egl::Error setDefaultFramebuffer(egl::Surface *drawSurface, egl::Surface *readSurface); + egl::Error unsetDefaultFramebuffer(); + + void initRendererString(); + void initVersionStrings(); + void initExtensionStrings(); + + Extensions generateSupportedExtensions() const; + void initCaps(); + void updateCaps(); + + gl::LabeledObject *getLabeledObject(GLenum identifier, GLuint name) const; + gl::LabeledObject *getLabeledObjectFromPtr(const void *ptr) const; + + void setUniform1iImpl(Program *program, + UniformLocation location, + GLsizei count, + const GLint *v); + void renderbufferStorageMultisampleImpl(GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + MultisamplingMode mode); + + State mState; + bool mShared; + bool mSkipValidation; + bool mDisplayTextureShareGroup; + bool mDisplaySemaphoreShareGroup; + + // Recorded errors + ErrorSet mErrors; + + // Stores for each buffer binding type whether is it allowed to be used in this context. + angle::PackedEnumBitSet mValidBufferBindings; + + std::unique_ptr mImplementation; + + EGLLabelKHR mLabel; + + // Extensions supported by the implementation plus extensions that are implemented entirely + // within the frontend. + Extensions mSupportedExtensions; + + // Shader compiler. Lazily initialized hence the mutable value. + mutable BindingPointer mCompiler; + + const egl::Config *mConfig; + + TextureMap mZeroTextures; + + ResourceMap mFenceNVMap; + HandleAllocator mFenceNVHandleAllocator; + + QueryMap mQueryMap; + HandleAllocator mQueryHandleAllocator; + + VertexArrayMap mVertexArrayMap; + HandleAllocator mVertexArrayHandleAllocator; + + TransformFeedbackMap mTransformFeedbackMap; + HandleAllocator mTransformFeedbackHandleAllocator; + + const char *mVersionString; + const char *mShadingLanguageString; + const char *mRendererString; + const char *mExtensionString; + std::vector mExtensionStrings; + const char *mRequestableExtensionString; + std::vector mRequestableExtensionStrings; + + // GLES1 renderer state + std::unique_ptr mGLES1Renderer; + + // Current/lost context flags + bool mHasBeenCurrent; + bool mContextLost; // Set with setContextLost so that we also set mSkipValidation=false. + GraphicsResetStatus mResetStatus; + bool mContextLostForced; + GLenum mResetStrategy; + const bool mSurfacelessSupported; + egl::Surface *mCurrentDrawSurface; + egl::Surface *mCurrentReadSurface; + egl::Display *mDisplay; + const bool mWebGLContext; + bool mBufferAccessValidationEnabled; + const bool mExtensionsEnabled; + MemoryProgramCache *mMemoryProgramCache; + MemoryShaderCache *mMemoryShaderCache; + + State::DirtyObjects mDrawDirtyObjects; + + StateCache mStateCache; + + State::DirtyBits mAllDirtyBits; + State::DirtyBits mTexImageDirtyBits; + State::DirtyObjects mTexImageDirtyObjects; + State::DirtyBits mReadPixelsDirtyBits; + State::DirtyObjects mReadPixelsDirtyObjects; + State::DirtyBits mClearDirtyBits; + State::DirtyObjects mClearDirtyObjects; + State::DirtyBits mBlitDirtyBits; + State::DirtyObjects mBlitDirtyObjects; + State::DirtyBits mComputeDirtyBits; + State::DirtyObjects mComputeDirtyObjects; + State::DirtyBits mCopyImageDirtyBits; + State::DirtyObjects mCopyImageDirtyObjects; + State::DirtyBits mReadInvalidateDirtyBits; + State::DirtyBits mDrawInvalidateDirtyBits; + + // Binding to container objects that use dependent state updates. + angle::ObserverBinding mVertexArrayObserverBinding; + angle::ObserverBinding mDrawFramebufferObserverBinding; + angle::ObserverBinding mReadFramebufferObserverBinding; + angle::ObserverBinding mProgramPipelineObserverBinding; + std::vector mUniformBufferObserverBindings; + std::vector mAtomicCounterBufferObserverBindings; + std::vector mShaderStorageBufferObserverBindings; + std::vector mSamplerObserverBindings; + std::vector mImageObserverBindings; + + // Not really a property of context state. The size and contexts change per-api-call. + mutable Optional mScratchBuffer; + mutable Optional mZeroFilledBuffer; + + // Single-threaded pool may not always be initialized. It currently depends on the extension + // GL_KHR_parallel_shader_compile being disabled. + std::shared_ptr mSingleThreadPool; + // Multithreaded pool will always be initialized so it can be used for more generic work. + std::shared_ptr mMultiThreadPool; + + // Note: we use a raw pointer here so we can exclude frame capture sources from the build. + std::unique_ptr mFrameCapture; + + // Cache representation of the serialized context string. + mutable std::string mCachedSerializedStateString; + + mutable size_t mRefCount; + + OverlayType mOverlay; + + const bool mIsExternal; + const bool mSaveAndRestoreState; + + bool mIsDestroyed; + + std::unique_ptr mDefaultFramebuffer; +}; + +class [[nodiscard]] ScopedContextRef +{ + public: + ScopedContextRef(Context *context) : mContext(context) + { + if (mContext) + { + mContext->addRef(); + } + } + ~ScopedContextRef() + { + if (mContext) + { + mContext->release(); + } + } + + private: + Context *const mContext; +}; + +// Thread-local current valid context bound to the thread. +#if defined(ANGLE_PLATFORM_APPLE) +extern Context *GetCurrentValidContextTLS(); +extern void SetCurrentValidContextTLS(Context *context); +#else +extern thread_local Context *gCurrentValidContext; +#endif + +} // namespace gl + +#endif // LIBANGLE_CONTEXT_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Context.inl.h b/gfx/angle/checkout/src/libANGLE/Context.inl.h new file mode 100644 index 0000000000..3a0573d307 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Context.inl.h @@ -0,0 +1,176 @@ +// +// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Context.inl.h: Defines inline functions of gl::Context class +// Has to be included after libANGLE/Context.h when using one +// of the defined functions + +#ifndef LIBANGLE_CONTEXT_INL_H_ +#define LIBANGLE_CONTEXT_INL_H_ + +#include "libANGLE/Context.h" +#include "libANGLE/GLES1Renderer.h" +#include "libANGLE/renderer/ContextImpl.h" + +#define ANGLE_HANDLE_ERR(X) \ + (void)(X); \ + return; +#define ANGLE_CONTEXT_TRY(EXPR) ANGLE_TRY_TEMPLATE(EXPR, ANGLE_HANDLE_ERR) + +namespace gl +{ +constexpr angle::PackedEnumMap kMinimumPrimitiveCounts = {{ + {PrimitiveMode::Points, 1}, + {PrimitiveMode::Lines, 2}, + {PrimitiveMode::LineLoop, 2}, + {PrimitiveMode::LineStrip, 2}, + {PrimitiveMode::Triangles, 3}, + {PrimitiveMode::TriangleStrip, 3}, + {PrimitiveMode::TriangleFan, 3}, + {PrimitiveMode::LinesAdjacency, 2}, + {PrimitiveMode::LineStripAdjacency, 2}, + {PrimitiveMode::TrianglesAdjacency, 3}, + {PrimitiveMode::TriangleStripAdjacency, 3}, +}}; + +ANGLE_INLINE void MarkTransformFeedbackBufferUsage(const Context *context, + GLsizei count, + GLsizei instanceCount) +{ + if (context->getStateCache().isTransformFeedbackActiveUnpaused()) + { + TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback(); + transformFeedback->onVerticesDrawn(context, count, instanceCount); + } +} + +ANGLE_INLINE void MarkShaderStorageUsage(const Context *context) +{ + for (size_t index : context->getStateCache().getActiveShaderStorageBufferIndices()) + { + Buffer *buffer = context->getState().getIndexedShaderStorageBuffer(index).get(); + if (buffer) + { + buffer->onDataChanged(); + } + } + + for (size_t index : context->getStateCache().getActiveImageUnitIndices()) + { + const ImageUnit &imageUnit = context->getState().getImageUnit(index); + const Texture *texture = imageUnit.texture.get(); + if (texture) + { + texture->onStateChange(angle::SubjectMessage::ContentsChanged); + } + } +} + +// Return true if the draw is a no-op, else return false. +// If there is no active program for the vertex or fragment shader stages, the results of vertex +// and fragment shader execution will respectively be undefined. However, this is not +// an error. ANGLE will treat this as a no-op. +// A no-op draw occurs if the count of vertices is less than the minimum required to +// have a valid primitive for this mode (0 for points, 0-1 for lines, 0-2 for tris). +ANGLE_INLINE bool Context::noopDraw(PrimitiveMode mode, GLsizei count) const +{ + if (!mStateCache.getCanDraw()) + { + return true; + } + + return count < kMinimumPrimitiveCounts[mode]; +} + +ANGLE_INLINE angle::Result Context::syncDirtyBits(Command command) +{ + const State::DirtyBits &dirtyBits = mState.getDirtyBits(); + ANGLE_TRY(mImplementation->syncState(this, dirtyBits, mAllDirtyBits, command)); + mState.clearDirtyBits(); + return angle::Result::Continue; +} + +ANGLE_INLINE angle::Result Context::syncDirtyBits(const State::DirtyBits &bitMask, Command command) +{ + const State::DirtyBits &dirtyBits = (mState.getDirtyBits() & bitMask); + ANGLE_TRY(mImplementation->syncState(this, dirtyBits, bitMask, command)); + mState.clearDirtyBits(dirtyBits); + return angle::Result::Continue; +} + +ANGLE_INLINE angle::Result Context::syncDirtyObjects(const State::DirtyObjects &objectMask, + Command command) +{ + return mState.syncDirtyObjects(this, objectMask, command); +} + +ANGLE_INLINE angle::Result Context::prepareForDraw(PrimitiveMode mode) +{ + if (mGLES1Renderer) + { + ANGLE_TRY(mGLES1Renderer->prepareForDraw(mode, this, &mState)); + } + + ANGLE_TRY(syncDirtyObjects(mDrawDirtyObjects, Command::Draw)); + ASSERT(!isRobustResourceInitEnabled() || + !mState.getDrawFramebuffer()->hasResourceThatNeedsInit()); + return syncDirtyBits(Command::Draw); +} + +ANGLE_INLINE void Context::drawArrays(PrimitiveMode mode, GLint first, GLsizei count) +{ + // No-op if count draws no primitives for given mode + if (noopDraw(mode, count)) + { + ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent()); + return; + } + + ANGLE_CONTEXT_TRY(prepareForDraw(mode)); + ANGLE_CONTEXT_TRY(mImplementation->drawArrays(this, mode, first, count)); + MarkTransformFeedbackBufferUsage(this, count, 1); +} + +ANGLE_INLINE void Context::drawElements(PrimitiveMode mode, + GLsizei count, + DrawElementsType type, + const void *indices) +{ + // No-op if count draws no primitives for given mode + if (noopDraw(mode, count)) + { + ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent()); + return; + } + + ANGLE_CONTEXT_TRY(prepareForDraw(mode)); + ANGLE_CONTEXT_TRY(mImplementation->drawElements(this, mode, count, type, indices)); +} + +ANGLE_INLINE void StateCache::onBufferBindingChange(Context *context) +{ + updateBasicDrawStatesError(); + updateBasicDrawElementsError(); +} + +ANGLE_INLINE void Context::bindBuffer(BufferBinding target, BufferID buffer) +{ + Buffer *bufferObject = + mState.mBufferManager->checkBufferAllocation(mImplementation.get(), buffer); + + // Early return if rebinding the same buffer + if (bufferObject == mState.getTargetBuffer(target)) + { + return; + } + + mState.setBufferBinding(this, target, bufferObject); + mStateCache.onBufferBindingChange(this); +} + +} // namespace gl + +#endif // LIBANGLE_CONTEXT_INL_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Context_gl.cpp b/gfx/angle/checkout/src/libANGLE/Context_gl.cpp new file mode 100644 index 0000000000..28f3685a20 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Context_gl.cpp @@ -0,0 +1,3706 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml. +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Context_gl.cpp: Implements the GL specific parts of Context. + +#include "Context.h" +#include "common/debug.h" + +namespace gl +{ + +void Context::compressedTexImage1D(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLint border, + GLsizei imageSize, + const void *data) +{ + UNIMPLEMENTED(); +} + +void Context::compressedTexSubImage1D(GLenum target, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, + GLsizei imageSize, + const void *data) +{ + UNIMPLEMENTED(); +} + +void Context::loadTransposeMatrixd(const GLdouble *m) +{ + UNIMPLEMENTED(); +} + +void Context::loadTransposeMatrixf(const GLfloat *m) +{ + UNIMPLEMENTED(); +} + +void Context::multTransposeMatrixd(const GLdouble *m) +{ + UNIMPLEMENTED(); +} + +void Context::multTransposeMatrixf(const GLfloat *m) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoord1d(GLenum target, GLdouble s) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoord1dv(GLenum target, const GLdouble *v) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoord1f(GLenum target, GLfloat s) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoord1fv(GLenum target, const GLfloat *v) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoord1i(GLenum target, GLint s) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoord1iv(GLenum target, const GLint *v) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoord1s(GLenum target, GLshort s) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoord1sv(GLenum target, const GLshort *v) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoord2d(GLenum target, GLdouble s, GLdouble t) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoord2dv(GLenum target, const GLdouble *v) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoord2f(GLenum target, GLfloat s, GLfloat t) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoord2fv(GLenum target, const GLfloat *v) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoord2i(GLenum target, GLint s, GLint t) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoord2iv(GLenum target, const GLint *v) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoord2s(GLenum target, GLshort s, GLshort t) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoord2sv(GLenum target, const GLshort *v) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoord3d(GLenum target, GLdouble s, GLdouble t, GLdouble r) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoord3dv(GLenum target, const GLdouble *v) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoord3f(GLenum target, GLfloat s, GLfloat t, GLfloat r) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoord3fv(GLenum target, const GLfloat *v) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoord3i(GLenum target, GLint s, GLint t, GLint r) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoord3iv(GLenum target, const GLint *v) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoord3s(GLenum target, GLshort s, GLshort t, GLshort r) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoord3sv(GLenum target, const GLshort *v) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoord4d(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoord4dv(GLenum target, const GLdouble *v) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoord4fv(GLenum target, const GLfloat *v) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoord4i(GLenum target, GLint s, GLint t, GLint r, GLint q) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoord4iv(GLenum target, const GLint *v) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoord4s(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoord4sv(GLenum target, const GLshort *v) +{ + UNIMPLEMENTED(); +} + +void Context::getVertexAttribdv(GLuint index, GLenum pname, GLdouble *params) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttrib1d(GLuint index, GLdouble x) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttrib1dv(GLuint index, const GLdouble *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttrib1s(GLuint index, GLshort x) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttrib1sv(GLuint index, const GLshort *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttrib2d(GLuint index, GLdouble x, GLdouble y) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttrib2dv(GLuint index, const GLdouble *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttrib2s(GLuint index, GLshort x, GLshort y) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttrib2sv(GLuint index, const GLshort *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttrib3d(GLuint index, GLdouble x, GLdouble y, GLdouble z) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttrib3dv(GLuint index, const GLdouble *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttrib3s(GLuint index, GLshort x, GLshort y, GLshort z) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttrib3sv(GLuint index, const GLshort *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttrib4Nbv(GLuint index, const GLbyte *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttrib4Niv(GLuint index, const GLint *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttrib4Nsv(GLuint index, const GLshort *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttrib4Nub(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttrib4Nubv(GLuint index, const GLubyte *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttrib4Nuiv(GLuint index, const GLuint *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttrib4Nusv(GLuint index, const GLushort *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttrib4bv(GLuint index, const GLbyte *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttrib4d(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttrib4dv(GLuint index, const GLdouble *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttrib4iv(GLuint index, const GLint *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttrib4s(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttrib4sv(GLuint index, const GLshort *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttrib4ubv(GLuint index, const GLubyte *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttrib4uiv(GLuint index, const GLuint *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttrib4usv(GLuint index, const GLushort *v) +{ + UNIMPLEMENTED(); +} + +void Context::beginConditionalRender(GLuint id, GLenum mode) +{ + UNIMPLEMENTED(); +} + +void Context::clampColor(GLenum target, GLenum clamp) +{ + UNIMPLEMENTED(); +} + +void Context::endConditionalRender() +{ + UNIMPLEMENTED(); +} + +void Context::framebufferTexture1D(GLenum target, + GLenum attachment, + TextureTarget textarget, + TextureID texture, + GLint level) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribI1i(GLuint index, GLint x) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribI1iv(GLuint index, const GLint *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribI1ui(GLuint index, GLuint x) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribI1uiv(GLuint index, const GLuint *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribI2i(GLuint index, GLint x, GLint y) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribI2iv(GLuint index, const GLint *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribI2ui(GLuint index, GLuint x, GLuint y) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribI2uiv(GLuint index, const GLuint *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribI3i(GLuint index, GLint x, GLint y, GLint z) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribI3iv(GLuint index, const GLint *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribI3ui(GLuint index, GLuint x, GLuint y, GLuint z) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribI3uiv(GLuint index, const GLuint *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribI4bv(GLuint index, const GLbyte *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribI4sv(GLuint index, const GLshort *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribI4ubv(GLuint index, const GLubyte *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribI4usv(GLuint index, const GLushort *v) +{ + UNIMPLEMENTED(); +} + +void Context::getActiveUniformName(ShaderProgramID program, + GLuint uniformIndex, + GLsizei bufSize, + GLsizei *length, + GLchar *uniformName) +{ + UNIMPLEMENTED(); +} + +void Context::primitiveRestartIndex(GLuint index) +{ + UNIMPLEMENTED(); +} + +void Context::fogCoordPointer(GLenum type, GLsizei stride, const void *pointer) +{ + UNIMPLEMENTED(); +} + +void Context::fogCoordd(GLdouble coord) +{ + UNIMPLEMENTED(); +} + +void Context::fogCoorddv(const GLdouble *coord) +{ + UNIMPLEMENTED(); +} + +void Context::fogCoordf(GLfloat coord) +{ + UNIMPLEMENTED(); +} + +void Context::fogCoordfv(const GLfloat *coord) +{ + UNIMPLEMENTED(); +} + +void Context::pointParameteri(GLenum pname, GLint param) +{ + UNIMPLEMENTED(); +} + +void Context::pointParameteriv(GLenum pname, const GLint *params) +{ + UNIMPLEMENTED(); +} + +void Context::secondaryColor3b(GLbyte red, GLbyte green, GLbyte blue) +{ + UNIMPLEMENTED(); +} + +void Context::secondaryColor3bv(const GLbyte *v) +{ + UNIMPLEMENTED(); +} + +void Context::secondaryColor3d(GLdouble red, GLdouble green, GLdouble blue) +{ + UNIMPLEMENTED(); +} + +void Context::secondaryColor3dv(const GLdouble *v) +{ + UNIMPLEMENTED(); +} + +void Context::secondaryColor3f(GLfloat red, GLfloat green, GLfloat blue) +{ + UNIMPLEMENTED(); +} + +void Context::secondaryColor3fv(const GLfloat *v) +{ + UNIMPLEMENTED(); +} + +void Context::secondaryColor3i(GLint red, GLint green, GLint blue) +{ + UNIMPLEMENTED(); +} + +void Context::secondaryColor3iv(const GLint *v) +{ + UNIMPLEMENTED(); +} + +void Context::secondaryColor3s(GLshort red, GLshort green, GLshort blue) +{ + UNIMPLEMENTED(); +} + +void Context::secondaryColor3sv(const GLshort *v) +{ + UNIMPLEMENTED(); +} + +void Context::secondaryColor3ub(GLubyte red, GLubyte green, GLubyte blue) +{ + UNIMPLEMENTED(); +} + +void Context::secondaryColor3ubv(const GLubyte *v) +{ + UNIMPLEMENTED(); +} + +void Context::secondaryColor3ui(GLuint red, GLuint green, GLuint blue) +{ + UNIMPLEMENTED(); +} + +void Context::secondaryColor3uiv(const GLuint *v) +{ + UNIMPLEMENTED(); +} + +void Context::secondaryColor3us(GLushort red, GLushort green, GLushort blue) +{ + UNIMPLEMENTED(); +} + +void Context::secondaryColor3usv(const GLushort *v) +{ + UNIMPLEMENTED(); +} + +void Context::secondaryColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) +{ + UNIMPLEMENTED(); +} + +void Context::windowPos2d(GLdouble x, GLdouble y) +{ + UNIMPLEMENTED(); +} + +void Context::windowPos2dv(const GLdouble *v) +{ + UNIMPLEMENTED(); +} + +void Context::windowPos2f(GLfloat x, GLfloat y) +{ + UNIMPLEMENTED(); +} + +void Context::windowPos2fv(const GLfloat *v) +{ + UNIMPLEMENTED(); +} + +void Context::windowPos2i(GLint x, GLint y) +{ + UNIMPLEMENTED(); +} + +void Context::windowPos2iv(const GLint *v) +{ + UNIMPLEMENTED(); +} + +void Context::windowPos2s(GLshort x, GLshort y) +{ + UNIMPLEMENTED(); +} + +void Context::windowPos2sv(const GLshort *v) +{ + UNIMPLEMENTED(); +} + +void Context::windowPos3d(GLdouble x, GLdouble y, GLdouble z) +{ + UNIMPLEMENTED(); +} + +void Context::windowPos3dv(const GLdouble *v) +{ + UNIMPLEMENTED(); +} + +void Context::windowPos3f(GLfloat x, GLfloat y, GLfloat z) +{ + UNIMPLEMENTED(); +} + +void Context::windowPos3fv(const GLfloat *v) +{ + UNIMPLEMENTED(); +} + +void Context::windowPos3i(GLint x, GLint y, GLint z) +{ + UNIMPLEMENTED(); +} + +void Context::windowPos3iv(const GLint *v) +{ + UNIMPLEMENTED(); +} + +void Context::windowPos3s(GLshort x, GLshort y, GLshort z) +{ + UNIMPLEMENTED(); +} + +void Context::windowPos3sv(const GLshort *v) +{ + UNIMPLEMENTED(); +} + +void Context::getBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, void *data) +{ + UNIMPLEMENTED(); +} + +void Context::accum(GLenum op, GLfloat value) +{ + UNIMPLEMENTED(); +} + +void Context::begin(GLenum mode) +{ + UNIMPLEMENTED(); +} + +void Context::bitmap(GLsizei width, + GLsizei height, + GLfloat xorig, + GLfloat yorig, + GLfloat xmove, + GLfloat ymove, + const GLubyte *bitmap) +{ + UNIMPLEMENTED(); +} + +void Context::callList(GLuint list) +{ + UNIMPLEMENTED(); +} + +void Context::callLists(GLsizei n, GLenum type, const void *lists) +{ + UNIMPLEMENTED(); +} + +void Context::clearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) +{ + UNIMPLEMENTED(); +} + +void Context::clearDepth(GLdouble depth) +{ + UNIMPLEMENTED(); +} + +void Context::clearIndex(GLfloat c) +{ + UNIMPLEMENTED(); +} + +void Context::clipPlane(GLenum plane, const GLdouble *equation) +{ + UNIMPLEMENTED(); +} + +void Context::color3b(GLbyte red, GLbyte green, GLbyte blue) +{ + UNIMPLEMENTED(); +} + +void Context::color3bv(const GLbyte *v) +{ + UNIMPLEMENTED(); +} + +void Context::color3d(GLdouble red, GLdouble green, GLdouble blue) +{ + UNIMPLEMENTED(); +} + +void Context::color3dv(const GLdouble *v) +{ + UNIMPLEMENTED(); +} + +void Context::color3f(GLfloat red, GLfloat green, GLfloat blue) +{ + UNIMPLEMENTED(); +} + +void Context::color3fv(const GLfloat *v) +{ + UNIMPLEMENTED(); +} + +void Context::color3i(GLint red, GLint green, GLint blue) +{ + UNIMPLEMENTED(); +} + +void Context::color3iv(const GLint *v) +{ + UNIMPLEMENTED(); +} + +void Context::color3s(GLshort red, GLshort green, GLshort blue) +{ + UNIMPLEMENTED(); +} + +void Context::color3sv(const GLshort *v) +{ + UNIMPLEMENTED(); +} + +void Context::color3ub(GLubyte red, GLubyte green, GLubyte blue) +{ + UNIMPLEMENTED(); +} + +void Context::color3ubv(const GLubyte *v) +{ + UNIMPLEMENTED(); +} + +void Context::color3ui(GLuint red, GLuint green, GLuint blue) +{ + UNIMPLEMENTED(); +} + +void Context::color3uiv(const GLuint *v) +{ + UNIMPLEMENTED(); +} + +void Context::color3us(GLushort red, GLushort green, GLushort blue) +{ + UNIMPLEMENTED(); +} + +void Context::color3usv(const GLushort *v) +{ + UNIMPLEMENTED(); +} + +void Context::color4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha) +{ + UNIMPLEMENTED(); +} + +void Context::color4bv(const GLbyte *v) +{ + UNIMPLEMENTED(); +} + +void Context::color4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha) +{ + UNIMPLEMENTED(); +} + +void Context::color4dv(const GLdouble *v) +{ + UNIMPLEMENTED(); +} + +void Context::color4fv(const GLfloat *v) +{ + UNIMPLEMENTED(); +} + +void Context::color4i(GLint red, GLint green, GLint blue, GLint alpha) +{ + UNIMPLEMENTED(); +} + +void Context::color4iv(const GLint *v) +{ + UNIMPLEMENTED(); +} + +void Context::color4s(GLshort red, GLshort green, GLshort blue, GLshort alpha) +{ + UNIMPLEMENTED(); +} + +void Context::color4sv(const GLshort *v) +{ + UNIMPLEMENTED(); +} + +void Context::color4ubv(const GLubyte *v) +{ + UNIMPLEMENTED(); +} + +void Context::color4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha) +{ + UNIMPLEMENTED(); +} + +void Context::color4uiv(const GLuint *v) +{ + UNIMPLEMENTED(); +} + +void Context::color4us(GLushort red, GLushort green, GLushort blue, GLushort alpha) +{ + UNIMPLEMENTED(); +} + +void Context::color4usv(const GLushort *v) +{ + UNIMPLEMENTED(); +} + +void Context::colorMaterial(GLenum face, GLenum mode) +{ + UNIMPLEMENTED(); +} + +void Context::copyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type) +{ + UNIMPLEMENTED(); +} + +void Context::deleteLists(GLuint list, GLsizei range) +{ + UNIMPLEMENTED(); +} + +void Context::depthRange(GLdouble n, GLdouble f) +{ + UNIMPLEMENTED(); +} + +void Context::drawBuffer(GLenum buf) +{ + UNIMPLEMENTED(); +} + +void Context::drawPixels(GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void *pixels) +{ + UNIMPLEMENTED(); +} + +void Context::edgeFlag(GLboolean flag) +{ + UNIMPLEMENTED(); +} + +void Context::edgeFlagv(const GLboolean *flag) +{ + UNIMPLEMENTED(); +} + +void Context::end() +{ + UNIMPLEMENTED(); +} + +void Context::endList() +{ + UNIMPLEMENTED(); +} + +void Context::evalCoord1d(GLdouble u) +{ + UNIMPLEMENTED(); +} + +void Context::evalCoord1dv(const GLdouble *u) +{ + UNIMPLEMENTED(); +} + +void Context::evalCoord1f(GLfloat u) +{ + UNIMPLEMENTED(); +} + +void Context::evalCoord1fv(const GLfloat *u) +{ + UNIMPLEMENTED(); +} + +void Context::evalCoord2d(GLdouble u, GLdouble v) +{ + UNIMPLEMENTED(); +} + +void Context::evalCoord2dv(const GLdouble *u) +{ + UNIMPLEMENTED(); +} + +void Context::evalCoord2f(GLfloat u, GLfloat v) +{ + UNIMPLEMENTED(); +} + +void Context::evalCoord2fv(const GLfloat *u) +{ + UNIMPLEMENTED(); +} + +void Context::evalMesh1(GLenum mode, GLint i1, GLint i2) +{ + UNIMPLEMENTED(); +} + +void Context::evalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) +{ + UNIMPLEMENTED(); +} + +void Context::evalPoint1(GLint i) +{ + UNIMPLEMENTED(); +} + +void Context::evalPoint2(GLint i, GLint j) +{ + UNIMPLEMENTED(); +} + +void Context::feedbackBuffer(GLsizei size, GLenum type, GLfloat *buffer) +{ + UNIMPLEMENTED(); +} + +void Context::fogi(GLenum pname, GLint param) +{ + UNIMPLEMENTED(); +} + +void Context::fogiv(GLenum pname, const GLint *params) +{ + UNIMPLEMENTED(); +} + +void Context::frustum(GLdouble left, + GLdouble right, + GLdouble bottom, + GLdouble top, + GLdouble zNear, + GLdouble zFar) +{ + UNIMPLEMENTED(); +} + +GLuint Context::genLists(GLsizei range) +{ + UNIMPLEMENTED(); + return 0; +} + +void Context::getClipPlane(GLenum plane, GLdouble *equation) +{ + UNIMPLEMENTED(); +} + +void Context::getDoublev(GLenum pname, GLdouble *data) +{ + UNIMPLEMENTED(); +} + +void Context::getLightiv(GLenum light, GLenum pname, GLint *params) +{ + UNIMPLEMENTED(); +} + +void Context::getMapdv(GLenum target, GLenum query, GLdouble *v) +{ + UNIMPLEMENTED(); +} + +void Context::getMapfv(GLenum target, GLenum query, GLfloat *v) +{ + UNIMPLEMENTED(); +} + +void Context::getMapiv(GLenum target, GLenum query, GLint *v) +{ + UNIMPLEMENTED(); +} + +void Context::getMaterialiv(GLenum face, GLenum pname, GLint *params) +{ + UNIMPLEMENTED(); +} + +void Context::getPixelMapfv(GLenum map, GLfloat *values) +{ + UNIMPLEMENTED(); +} + +void Context::getPixelMapuiv(GLenum map, GLuint *values) +{ + UNIMPLEMENTED(); +} + +void Context::getPixelMapusv(GLenum map, GLushort *values) +{ + UNIMPLEMENTED(); +} + +void Context::getPolygonStipple(GLubyte *mask) +{ + UNIMPLEMENTED(); +} + +void Context::getTexGendv(GLenum coord, GLenum pname, GLdouble *params) +{ + UNIMPLEMENTED(); +} + +void Context::indexMask(GLuint mask) +{ + UNIMPLEMENTED(); +} + +void Context::indexd(GLdouble c) +{ + UNIMPLEMENTED(); +} + +void Context::indexdv(const GLdouble *c) +{ + UNIMPLEMENTED(); +} + +void Context::indexf(GLfloat c) +{ + UNIMPLEMENTED(); +} + +void Context::indexfv(const GLfloat *c) +{ + UNIMPLEMENTED(); +} + +void Context::indexi(GLint c) +{ + UNIMPLEMENTED(); +} + +void Context::indexiv(const GLint *c) +{ + UNIMPLEMENTED(); +} + +void Context::indexs(GLshort c) +{ + UNIMPLEMENTED(); +} + +void Context::indexsv(const GLshort *c) +{ + UNIMPLEMENTED(); +} + +void Context::initNames() +{ + UNIMPLEMENTED(); +} + +GLboolean Context::isList(GLuint list) const +{ + UNIMPLEMENTED(); + return false; +} + +void Context::lightModeli(GLenum pname, GLint param) +{ + UNIMPLEMENTED(); +} + +void Context::lightModeliv(GLenum pname, const GLint *params) +{ + UNIMPLEMENTED(); +} + +void Context::lighti(GLenum light, GLenum pname, GLint param) +{ + UNIMPLEMENTED(); +} + +void Context::lightiv(GLenum light, GLenum pname, const GLint *params) +{ + UNIMPLEMENTED(); +} + +void Context::lineStipple(GLint factor, GLushort pattern) +{ + UNIMPLEMENTED(); +} + +void Context::listBase(GLuint base) +{ + UNIMPLEMENTED(); +} + +void Context::loadMatrixd(const GLdouble *m) +{ + UNIMPLEMENTED(); +} + +void Context::loadName(GLuint name) +{ + UNIMPLEMENTED(); +} + +void Context::map1d(GLenum target, + GLdouble u1, + GLdouble u2, + GLint stride, + GLint order, + const GLdouble *points) +{ + UNIMPLEMENTED(); +} + +void Context::map1f(GLenum target, + GLfloat u1, + GLfloat u2, + GLint stride, + GLint order, + const GLfloat *points) +{ + UNIMPLEMENTED(); +} + +void Context::map2d(GLenum target, + GLdouble u1, + GLdouble u2, + GLint ustride, + GLint uorder, + GLdouble v1, + GLdouble v2, + GLint vstride, + GLint vorder, + const GLdouble *points) +{ + UNIMPLEMENTED(); +} + +void Context::map2f(GLenum target, + GLfloat u1, + GLfloat u2, + GLint ustride, + GLint uorder, + GLfloat v1, + GLfloat v2, + GLint vstride, + GLint vorder, + const GLfloat *points) +{ + UNIMPLEMENTED(); +} + +void Context::mapGrid1d(GLint un, GLdouble u1, GLdouble u2) +{ + UNIMPLEMENTED(); +} + +void Context::mapGrid1f(GLint un, GLfloat u1, GLfloat u2) +{ + UNIMPLEMENTED(); +} + +void Context::mapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2) +{ + UNIMPLEMENTED(); +} + +void Context::mapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2) +{ + UNIMPLEMENTED(); +} + +void Context::materiali(GLenum face, GLenum pname, GLint param) +{ + UNIMPLEMENTED(); +} + +void Context::materialiv(GLenum face, GLenum pname, const GLint *params) +{ + UNIMPLEMENTED(); +} + +void Context::multMatrixd(const GLdouble *m) +{ + UNIMPLEMENTED(); +} + +void Context::newList(GLuint list, GLenum mode) +{ + UNIMPLEMENTED(); +} + +void Context::normal3b(GLbyte nx, GLbyte ny, GLbyte nz) +{ + UNIMPLEMENTED(); +} + +void Context::normal3bv(const GLbyte *v) +{ + UNIMPLEMENTED(); +} + +void Context::normal3d(GLdouble nx, GLdouble ny, GLdouble nz) +{ + UNIMPLEMENTED(); +} + +void Context::normal3dv(const GLdouble *v) +{ + UNIMPLEMENTED(); +} + +void Context::normal3fv(const GLfloat *v) +{ + UNIMPLEMENTED(); +} + +void Context::normal3i(GLint nx, GLint ny, GLint nz) +{ + UNIMPLEMENTED(); +} + +void Context::normal3iv(const GLint *v) +{ + UNIMPLEMENTED(); +} + +void Context::normal3s(GLshort nx, GLshort ny, GLshort nz) +{ + UNIMPLEMENTED(); +} + +void Context::normal3sv(const GLshort *v) +{ + UNIMPLEMENTED(); +} + +void Context::ortho(GLdouble left, + GLdouble right, + GLdouble bottom, + GLdouble top, + GLdouble zNear, + GLdouble zFar) +{ + UNIMPLEMENTED(); +} + +void Context::passThrough(GLfloat token) +{ + UNIMPLEMENTED(); +} + +void Context::pixelMapfv(GLenum map, GLsizei mapsize, const GLfloat *values) +{ + UNIMPLEMENTED(); +} + +void Context::pixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values) +{ + UNIMPLEMENTED(); +} + +void Context::pixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values) +{ + UNIMPLEMENTED(); +} + +void Context::pixelStoref(GLenum pname, GLfloat param) +{ + UNIMPLEMENTED(); +} + +void Context::pixelTransferf(GLenum pname, GLfloat param) +{ + UNIMPLEMENTED(); +} + +void Context::pixelTransferi(GLenum pname, GLint param) +{ + UNIMPLEMENTED(); +} + +void Context::pixelZoom(GLfloat xfactor, GLfloat yfactor) +{ + UNIMPLEMENTED(); +} + +void Context::polygonMode(GLenum face, GLenum mode) +{ + UNIMPLEMENTED(); +} + +void Context::polygonStipple(const GLubyte *mask) +{ + UNIMPLEMENTED(); +} + +void Context::popAttrib() +{ + UNIMPLEMENTED(); +} + +void Context::popName() +{ + UNIMPLEMENTED(); +} + +void Context::pushAttrib(GLbitfield mask) +{ + UNIMPLEMENTED(); +} + +void Context::pushName(GLuint name) +{ + UNIMPLEMENTED(); +} + +void Context::rasterPos2d(GLdouble x, GLdouble y) +{ + UNIMPLEMENTED(); +} + +void Context::rasterPos2dv(const GLdouble *v) +{ + UNIMPLEMENTED(); +} + +void Context::rasterPos2f(GLfloat x, GLfloat y) +{ + UNIMPLEMENTED(); +} + +void Context::rasterPos2fv(const GLfloat *v) +{ + UNIMPLEMENTED(); +} + +void Context::rasterPos2i(GLint x, GLint y) +{ + UNIMPLEMENTED(); +} + +void Context::rasterPos2iv(const GLint *v) +{ + UNIMPLEMENTED(); +} + +void Context::rasterPos2s(GLshort x, GLshort y) +{ + UNIMPLEMENTED(); +} + +void Context::rasterPos2sv(const GLshort *v) +{ + UNIMPLEMENTED(); +} + +void Context::rasterPos3d(GLdouble x, GLdouble y, GLdouble z) +{ + UNIMPLEMENTED(); +} + +void Context::rasterPos3dv(const GLdouble *v) +{ + UNIMPLEMENTED(); +} + +void Context::rasterPos3f(GLfloat x, GLfloat y, GLfloat z) +{ + UNIMPLEMENTED(); +} + +void Context::rasterPos3fv(const GLfloat *v) +{ + UNIMPLEMENTED(); +} + +void Context::rasterPos3i(GLint x, GLint y, GLint z) +{ + UNIMPLEMENTED(); +} + +void Context::rasterPos3iv(const GLint *v) +{ + UNIMPLEMENTED(); +} + +void Context::rasterPos3s(GLshort x, GLshort y, GLshort z) +{ + UNIMPLEMENTED(); +} + +void Context::rasterPos3sv(const GLshort *v) +{ + UNIMPLEMENTED(); +} + +void Context::rasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w) +{ + UNIMPLEMENTED(); +} + +void Context::rasterPos4dv(const GLdouble *v) +{ + UNIMPLEMENTED(); +} + +void Context::rasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ + UNIMPLEMENTED(); +} + +void Context::rasterPos4fv(const GLfloat *v) +{ + UNIMPLEMENTED(); +} + +void Context::rasterPos4i(GLint x, GLint y, GLint z, GLint w) +{ + UNIMPLEMENTED(); +} + +void Context::rasterPos4iv(const GLint *v) +{ + UNIMPLEMENTED(); +} + +void Context::rasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w) +{ + UNIMPLEMENTED(); +} + +void Context::rasterPos4sv(const GLshort *v) +{ + UNIMPLEMENTED(); +} + +void Context::rectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2) +{ + UNIMPLEMENTED(); +} + +void Context::rectdv(const GLdouble *v1, const GLdouble *v2) +{ + UNIMPLEMENTED(); +} + +void Context::rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) +{ + UNIMPLEMENTED(); +} + +void Context::rectfv(const GLfloat *v1, const GLfloat *v2) +{ + UNIMPLEMENTED(); +} + +void Context::recti(GLint x1, GLint y1, GLint x2, GLint y2) +{ + UNIMPLEMENTED(); +} + +void Context::rectiv(const GLint *v1, const GLint *v2) +{ + UNIMPLEMENTED(); +} + +void Context::rects(GLshort x1, GLshort y1, GLshort x2, GLshort y2) +{ + UNIMPLEMENTED(); +} + +void Context::rectsv(const GLshort *v1, const GLshort *v2) +{ + UNIMPLEMENTED(); +} + +GLint Context::renderMode(GLenum mode) +{ + UNIMPLEMENTED(); + return 0; +} + +void Context::rotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z) +{ + UNIMPLEMENTED(); +} + +void Context::scaled(GLdouble x, GLdouble y, GLdouble z) +{ + UNIMPLEMENTED(); +} + +void Context::selectBuffer(GLsizei size, GLuint *buffer) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord1d(GLdouble s) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord1dv(const GLdouble *v) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord1f(GLfloat s) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord1fv(const GLfloat *v) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord1i(GLint s) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord1iv(const GLint *v) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord1s(GLshort s) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord1sv(const GLshort *v) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord2d(GLdouble s, GLdouble t) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord2dv(const GLdouble *v) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord2f(GLfloat s, GLfloat t) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord2fv(const GLfloat *v) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord2i(GLint s, GLint t) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord2iv(const GLint *v) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord2s(GLshort s, GLshort t) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord2sv(const GLshort *v) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord3d(GLdouble s, GLdouble t, GLdouble r) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord3dv(const GLdouble *v) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord3f(GLfloat s, GLfloat t, GLfloat r) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord3fv(const GLfloat *v) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord3i(GLint s, GLint t, GLint r) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord3iv(const GLint *v) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord3s(GLshort s, GLshort t, GLshort r) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord3sv(const GLshort *v) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord4dv(const GLdouble *v) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord4fv(const GLfloat *v) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord4i(GLint s, GLint t, GLint r, GLint q) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord4iv(const GLint *v) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord4s(GLshort s, GLshort t, GLshort r, GLshort q) +{ + UNIMPLEMENTED(); +} + +void Context::texCoord4sv(const GLshort *v) +{ + UNIMPLEMENTED(); +} + +void Context::texGend(GLenum coord, GLenum pname, GLdouble param) +{ + UNIMPLEMENTED(); +} + +void Context::texGendv(GLenum coord, GLenum pname, const GLdouble *params) +{ + UNIMPLEMENTED(); +} + +void Context::texImage1D(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLint border, + GLenum format, + GLenum type, + const void *pixels) +{ + UNIMPLEMENTED(); +} + +void Context::translated(GLdouble x, GLdouble y, GLdouble z) +{ + UNIMPLEMENTED(); +} + +void Context::vertex2d(GLdouble x, GLdouble y) +{ + UNIMPLEMENTED(); +} + +void Context::vertex2dv(const GLdouble *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertex2f(GLfloat x, GLfloat y) +{ + UNIMPLEMENTED(); +} + +void Context::vertex2fv(const GLfloat *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertex2i(GLint x, GLint y) +{ + UNIMPLEMENTED(); +} + +void Context::vertex2iv(const GLint *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertex2s(GLshort x, GLshort y) +{ + UNIMPLEMENTED(); +} + +void Context::vertex2sv(const GLshort *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertex3d(GLdouble x, GLdouble y, GLdouble z) +{ + UNIMPLEMENTED(); +} + +void Context::vertex3dv(const GLdouble *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertex3f(GLfloat x, GLfloat y, GLfloat z) +{ + UNIMPLEMENTED(); +} + +void Context::vertex3fv(const GLfloat *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertex3i(GLint x, GLint y, GLint z) +{ + UNIMPLEMENTED(); +} + +void Context::vertex3iv(const GLint *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertex3s(GLshort x, GLshort y, GLshort z) +{ + UNIMPLEMENTED(); +} + +void Context::vertex3sv(const GLshort *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w) +{ + UNIMPLEMENTED(); +} + +void Context::vertex4dv(const GLdouble *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ + UNIMPLEMENTED(); +} + +void Context::vertex4fv(const GLfloat *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertex4i(GLint x, GLint y, GLint z, GLint w) +{ + UNIMPLEMENTED(); +} + +void Context::vertex4iv(const GLint *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertex4s(GLshort x, GLshort y, GLshort z, GLshort w) +{ + UNIMPLEMENTED(); +} + +void Context::vertex4sv(const GLshort *v) +{ + UNIMPLEMENTED(); +} + +GLboolean Context::areTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences) +{ + UNIMPLEMENTED(); + return false; +} + +void Context::arrayElement(GLint i) +{ + UNIMPLEMENTED(); +} + +void Context::copyTexImage1D(GLenum target, + GLint level, + GLenum internalformat, + GLint x, + GLint y, + GLsizei width, + GLint border) +{ + UNIMPLEMENTED(); +} + +void Context::copyTexSubImage1D(GLenum target, + GLint level, + GLint xoffset, + GLint x, + GLint y, + GLsizei width) +{ + UNIMPLEMENTED(); +} + +void Context::edgeFlagPointer(GLsizei stride, const void *pointer) +{ + UNIMPLEMENTED(); +} + +void Context::indexPointer(GLenum type, GLsizei stride, const void *pointer) +{ + UNIMPLEMENTED(); +} + +void Context::indexub(GLubyte c) +{ + UNIMPLEMENTED(); +} + +void Context::indexubv(const GLubyte *c) +{ + UNIMPLEMENTED(); +} + +void Context::interleavedArrays(GLenum format, GLsizei stride, const void *pointer) +{ + UNIMPLEMENTED(); +} + +void Context::popClientAttrib() +{ + UNIMPLEMENTED(); +} + +void Context::prioritizeTextures(GLsizei n, const GLuint *textures, const GLfloat *priorities) +{ + UNIMPLEMENTED(); +} + +void Context::pushClientAttrib(GLbitfield mask) +{ + UNIMPLEMENTED(); +} + +void Context::texSubImage1D(GLenum target, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, + GLenum type, + const void *pixels) +{ + UNIMPLEMENTED(); +} + +void Context::multiDrawElementsBaseVertex(PrimitiveMode mode, + const GLsizei *count, + DrawElementsType type, + const void *const *indices, + GLsizei drawcount, + const GLint *basevertex) +{ + UNIMPLEMENTED(); +} + +void Context::texImage2DMultisample(GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations) +{ + UNIMPLEMENTED(); +} + +void Context::texImage3DMultisample(GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedsamplelocations) +{ + UNIMPLEMENTED(); +} + +void Context::colorP3ui(GLenum type, GLuint color) +{ + UNIMPLEMENTED(); +} + +void Context::colorP3uiv(GLenum type, const GLuint *color) +{ + UNIMPLEMENTED(); +} + +void Context::colorP4ui(GLenum type, GLuint color) +{ + UNIMPLEMENTED(); +} + +void Context::colorP4uiv(GLenum type, const GLuint *color) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoordP1ui(GLenum texture, GLenum type, GLuint coords) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoordP1uiv(GLenum texture, GLenum type, const GLuint *coords) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoordP2ui(GLenum texture, GLenum type, GLuint coords) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoordP2uiv(GLenum texture, GLenum type, const GLuint *coords) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoordP3ui(GLenum texture, GLenum type, GLuint coords) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoordP3uiv(GLenum texture, GLenum type, const GLuint *coords) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoordP4ui(GLenum texture, GLenum type, GLuint coords) +{ + UNIMPLEMENTED(); +} + +void Context::multiTexCoordP4uiv(GLenum texture, GLenum type, const GLuint *coords) +{ + UNIMPLEMENTED(); +} + +void Context::normalP3ui(GLenum type, GLuint coords) +{ + UNIMPLEMENTED(); +} + +void Context::normalP3uiv(GLenum type, const GLuint *coords) +{ + UNIMPLEMENTED(); +} + +void Context::secondaryColorP3ui(GLenum type, GLuint color) +{ + UNIMPLEMENTED(); +} + +void Context::secondaryColorP3uiv(GLenum type, const GLuint *color) +{ + UNIMPLEMENTED(); +} + +void Context::texCoordP1ui(GLenum type, GLuint coords) +{ + UNIMPLEMENTED(); +} + +void Context::texCoordP1uiv(GLenum type, const GLuint *coords) +{ + UNIMPLEMENTED(); +} + +void Context::texCoordP2ui(GLenum type, GLuint coords) +{ + UNIMPLEMENTED(); +} + +void Context::texCoordP2uiv(GLenum type, const GLuint *coords) +{ + UNIMPLEMENTED(); +} + +void Context::texCoordP3ui(GLenum type, GLuint coords) +{ + UNIMPLEMENTED(); +} + +void Context::texCoordP3uiv(GLenum type, const GLuint *coords) +{ + UNIMPLEMENTED(); +} + +void Context::texCoordP4ui(GLenum type, GLuint coords) +{ + UNIMPLEMENTED(); +} + +void Context::texCoordP4uiv(GLenum type, const GLuint *coords) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribP1ui(GLuint index, GLenum type, GLboolean normalized, GLuint value) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribP1uiv(GLuint index, + GLenum type, + GLboolean normalized, + const GLuint *value) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribP2ui(GLuint index, GLenum type, GLboolean normalized, GLuint value) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribP2uiv(GLuint index, + GLenum type, + GLboolean normalized, + const GLuint *value) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribP3ui(GLuint index, GLenum type, GLboolean normalized, GLuint value) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribP3uiv(GLuint index, + GLenum type, + GLboolean normalized, + const GLuint *value) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribP4ui(GLuint index, GLenum type, GLboolean normalized, GLuint value) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribP4uiv(GLuint index, + GLenum type, + GLboolean normalized, + const GLuint *value) +{ + UNIMPLEMENTED(); +} + +void Context::vertexP2ui(GLenum type, GLuint value) +{ + UNIMPLEMENTED(); +} + +void Context::vertexP2uiv(GLenum type, const GLuint *value) +{ + UNIMPLEMENTED(); +} + +void Context::vertexP3ui(GLenum type, GLuint value) +{ + UNIMPLEMENTED(); +} + +void Context::vertexP3uiv(GLenum type, const GLuint *value) +{ + UNIMPLEMENTED(); +} + +void Context::vertexP4ui(GLenum type, GLuint value) +{ + UNIMPLEMENTED(); +} + +void Context::vertexP4uiv(GLenum type, const GLuint *value) +{ + UNIMPLEMENTED(); +} + +void Context::beginQueryIndexed(GLenum target, GLuint index, QueryID id) +{ + UNIMPLEMENTED(); +} + +void Context::drawTransformFeedback(GLenum mode, TransformFeedbackID id) +{ + UNIMPLEMENTED(); +} + +void Context::drawTransformFeedbackStream(GLenum mode, TransformFeedbackID id, GLuint stream) +{ + UNIMPLEMENTED(); +} + +void Context::endQueryIndexed(GLenum target, GLuint index) +{ + UNIMPLEMENTED(); +} + +void Context::getActiveSubroutineName(ShaderProgramID program, + GLenum shadertype, + GLuint index, + GLsizei bufsize, + GLsizei *length, + GLchar *name) +{ + UNIMPLEMENTED(); +} + +void Context::getActiveSubroutineUniformName(ShaderProgramID program, + GLenum shadertype, + GLuint index, + GLsizei bufsize, + GLsizei *length, + GLchar *name) +{ + UNIMPLEMENTED(); +} + +void Context::getActiveSubroutineUniformiv(ShaderProgramID program, + GLenum shadertype, + GLuint index, + GLenum pname, + GLint *values) +{ + UNIMPLEMENTED(); +} + +void Context::getProgramStageiv(ShaderProgramID program, + GLenum shadertype, + GLenum pname, + GLint *values) +{ + UNIMPLEMENTED(); +} + +void Context::getQueryIndexediv(GLenum target, GLuint index, GLenum pname, GLint *params) +{ + UNIMPLEMENTED(); +} + +GLuint Context::getSubroutineIndex(ShaderProgramID program, GLenum shadertype, const GLchar *name) +{ + UNIMPLEMENTED(); + return 0; +} + +GLint Context::getSubroutineUniformLocation(ShaderProgramID program, + GLenum shadertype, + const GLchar *name) +{ + UNIMPLEMENTED(); + return 0; +} + +void Context::getUniformSubroutineuiv(GLenum shadertype, GLint location, GLuint *params) +{ + UNIMPLEMENTED(); +} + +void Context::getUniformdv(ShaderProgramID program, UniformLocation location, GLdouble *params) +{ + UNIMPLEMENTED(); +} + +void Context::patchParameterfv(GLenum pname, const GLfloat *values) +{ + UNIMPLEMENTED(); +} + +void Context::uniform1d(UniformLocation location, GLdouble x) +{ + UNIMPLEMENTED(); +} + +void Context::uniform1dv(UniformLocation location, GLsizei count, const GLdouble *value) +{ + UNIMPLEMENTED(); +} + +void Context::uniform2d(UniformLocation location, GLdouble x, GLdouble y) +{ + UNIMPLEMENTED(); +} + +void Context::uniform2dv(UniformLocation location, GLsizei count, const GLdouble *value) +{ + UNIMPLEMENTED(); +} + +void Context::uniform3d(UniformLocation location, GLdouble x, GLdouble y, GLdouble z) +{ + UNIMPLEMENTED(); +} + +void Context::uniform3dv(UniformLocation location, GLsizei count, const GLdouble *value) +{ + UNIMPLEMENTED(); +} + +void Context::uniform4d(UniformLocation location, GLdouble x, GLdouble y, GLdouble z, GLdouble w) +{ + UNIMPLEMENTED(); +} + +void Context::uniform4dv(UniformLocation location, GLsizei count, const GLdouble *value) +{ + UNIMPLEMENTED(); +} + +void Context::uniformMatrix2dv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + UNIMPLEMENTED(); +} + +void Context::uniformMatrix2x3dv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + UNIMPLEMENTED(); +} + +void Context::uniformMatrix2x4dv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + UNIMPLEMENTED(); +} + +void Context::uniformMatrix3dv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + UNIMPLEMENTED(); +} + +void Context::uniformMatrix3x2dv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + UNIMPLEMENTED(); +} + +void Context::uniformMatrix3x4dv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + UNIMPLEMENTED(); +} + +void Context::uniformMatrix4dv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + UNIMPLEMENTED(); +} + +void Context::uniformMatrix4x2dv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + UNIMPLEMENTED(); +} + +void Context::uniformMatrix4x3dv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + UNIMPLEMENTED(); +} + +void Context::uniformSubroutinesuiv(GLenum shadertype, GLsizei count, const GLuint *indices) +{ + UNIMPLEMENTED(); +} + +void Context::depthRangeArrayv(GLuint first, GLsizei count, const GLdouble *v) +{ + UNIMPLEMENTED(); +} + +void Context::depthRangeIndexed(GLuint index, GLdouble n, GLdouble f) +{ + UNIMPLEMENTED(); +} + +void Context::getDoublei_v(GLenum target, GLuint index, GLdouble *data) +{ + UNIMPLEMENTED(); +} + +void Context::getFloati_v(GLenum target, GLuint index, GLfloat *data) +{ + UNIMPLEMENTED(); +} + +void Context::getVertexAttribLdv(GLuint index, GLenum pname, GLdouble *params) +{ + UNIMPLEMENTED(); +} + +void Context::programUniform1d(ShaderProgramID program, UniformLocation location, GLdouble v0) +{ + UNIMPLEMENTED(); +} + +void Context::programUniform1dv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLdouble *value) +{ + UNIMPLEMENTED(); +} + +void Context::programUniform2d(ShaderProgramID program, + UniformLocation location, + GLdouble v0, + GLdouble v1) +{ + UNIMPLEMENTED(); +} + +void Context::programUniform2dv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLdouble *value) +{ + UNIMPLEMENTED(); +} + +void Context::programUniform3d(ShaderProgramID program, + UniformLocation location, + GLdouble v0, + GLdouble v1, + GLdouble v2) +{ + UNIMPLEMENTED(); +} + +void Context::programUniform3dv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLdouble *value) +{ + UNIMPLEMENTED(); +} + +void Context::programUniform4d(ShaderProgramID program, + UniformLocation location, + GLdouble v0, + GLdouble v1, + GLdouble v2, + GLdouble v3) +{ + UNIMPLEMENTED(); +} + +void Context::programUniform4dv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLdouble *value) +{ + UNIMPLEMENTED(); +} + +void Context::programUniformMatrix2dv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + UNIMPLEMENTED(); +} + +void Context::programUniformMatrix2x3dv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + UNIMPLEMENTED(); +} + +void Context::programUniformMatrix2x4dv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + UNIMPLEMENTED(); +} + +void Context::programUniformMatrix3dv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + UNIMPLEMENTED(); +} + +void Context::programUniformMatrix3x2dv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + UNIMPLEMENTED(); +} + +void Context::programUniformMatrix3x4dv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + UNIMPLEMENTED(); +} + +void Context::programUniformMatrix4dv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + UNIMPLEMENTED(); +} + +void Context::programUniformMatrix4x2dv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + UNIMPLEMENTED(); +} + +void Context::programUniformMatrix4x3dv(ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + UNIMPLEMENTED(); +} + +void Context::scissorArrayv(GLuint first, GLsizei count, const GLint *v) +{ + UNIMPLEMENTED(); +} + +void Context::scissorIndexed(GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height) +{ + UNIMPLEMENTED(); +} + +void Context::scissorIndexedv(GLuint index, const GLint *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribL1d(GLuint index, GLdouble x) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribL1dv(GLuint index, const GLdouble *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribL2d(GLuint index, GLdouble x, GLdouble y) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribL2dv(GLuint index, const GLdouble *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribL3d(GLuint index, GLdouble x, GLdouble y, GLdouble z) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribL3dv(GLuint index, const GLdouble *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribL4d(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribL4dv(GLuint index, const GLdouble *v) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribLPointer(GLuint index, + GLint size, + GLenum type, + GLsizei stride, + const void *pointer) +{ + UNIMPLEMENTED(); +} + +void Context::viewportArrayv(GLuint first, GLsizei count, const GLfloat *v) +{ + UNIMPLEMENTED(); +} + +void Context::viewportIndexedf(GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h) +{ + UNIMPLEMENTED(); +} + +void Context::viewportIndexedfv(GLuint index, const GLfloat *v) +{ + UNIMPLEMENTED(); +} + +void Context::drawTransformFeedbackInstanced(GLenum mode, + TransformFeedbackID id, + GLsizei instancecount) +{ + UNIMPLEMENTED(); +} + +void Context::drawTransformFeedbackStreamInstanced(GLenum mode, + TransformFeedbackID id, + GLuint stream, + GLsizei instancecount) +{ + UNIMPLEMENTED(); +} + +void Context::getActiveAtomicCounterBufferiv(ShaderProgramID program, + GLuint bufferIndex, + GLenum pname, + GLint *params) +{ + UNIMPLEMENTED(); +} + +void Context::clearBufferData(GLenum target, + GLenum internalformat, + GLenum format, + GLenum type, + const void *data) +{ + UNIMPLEMENTED(); +} + +void Context::clearBufferSubData(GLenum target, + GLenum internalformat, + GLintptr offset, + GLsizeiptr size, + GLenum format, + GLenum type, + const void *data) +{ + UNIMPLEMENTED(); +} + +void Context::getInternalformati64v(GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei bufSize, + GLint64 *params) +{ + UNIMPLEMENTED(); +} + +void Context::invalidateBufferData(BufferID buffer) +{ + UNIMPLEMENTED(); +} + +void Context::invalidateBufferSubData(BufferID buffer, GLintptr offset, GLsizeiptr length) +{ + UNIMPLEMENTED(); +} + +void Context::invalidateTexImage(TextureID texture, GLint level) +{ + UNIMPLEMENTED(); +} + +void Context::invalidateTexSubImage(TextureID texture, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth) +{ + UNIMPLEMENTED(); +} + +void Context::shaderStorageBlockBinding(ShaderProgramID program, + GLuint storageBlockIndex, + GLuint storageBlockBinding) +{ + UNIMPLEMENTED(); +} + +void Context::textureView(TextureID texture, + GLenum target, + GLuint origtexture, + GLenum internalformat, + GLuint minlevel, + GLuint numlevels, + GLuint minlayer, + GLuint numlayers) +{ + UNIMPLEMENTED(); +} + +void Context::vertexAttribLFormat(GLuint attribindex, + GLint size, + GLenum type, + GLuint relativeoffset) +{ + UNIMPLEMENTED(); +} + +void Context::bindBuffersBase(GLenum target, GLuint first, GLsizei count, const BufferID *buffers) +{ + UNIMPLEMENTED(); +} + +void Context::bindBuffersRange(GLenum target, + GLuint first, + GLsizei count, + const BufferID *buffers, + const GLintptr *offsets, + const GLsizeiptr *sizes) +{ + UNIMPLEMENTED(); +} + +void Context::bindImageTextures(GLuint first, GLsizei count, const GLuint *textures) +{ + UNIMPLEMENTED(); +} + +void Context::bindSamplers(GLuint first, GLsizei count, const GLuint *samplers) +{ + UNIMPLEMENTED(); +} + +void Context::bindTextures(GLuint first, GLsizei count, const GLuint *textures) +{ + UNIMPLEMENTED(); +} + +void Context::bindVertexBuffers(GLuint first, + GLsizei count, + const BufferID *buffers, + const GLintptr *offsets, + const GLsizei *strides) +{ + UNIMPLEMENTED(); +} + +void Context::clearTexImage(TextureID texture, + GLint level, + GLenum format, + GLenum type, + const void *data) +{ + UNIMPLEMENTED(); +} + +void Context::clearTexSubImage(TextureID texture, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *data) +{ + UNIMPLEMENTED(); +} + +void Context::bindTextureUnit(GLuint unit, TextureID texture) +{ + UNIMPLEMENTED(); +} + +void Context::blitNamedFramebuffer(GLuint readFramebuffer, + GLuint drawFramebuffer, + GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter) +{ + UNIMPLEMENTED(); +} + +GLenum Context::checkNamedFramebufferStatus(FramebufferID framebuffer, GLenum target) +{ + UNIMPLEMENTED(); + return 0; +} + +void Context::clearNamedBufferData(BufferID buffer, + GLenum internalformat, + GLenum format, + GLenum type, + const void *data) +{ + UNIMPLEMENTED(); +} + +void Context::clearNamedBufferSubData(BufferID buffer, + GLenum internalformat, + GLintptr offset, + GLsizeiptr size, + GLenum format, + GLenum type, + const void *data) +{ + UNIMPLEMENTED(); +} + +void Context::clearNamedFramebufferfi(FramebufferID framebuffer, + GLenum buffer, + GLint drawbuffer, + GLfloat depth, + GLint stencil) +{ + UNIMPLEMENTED(); +} + +void Context::clearNamedFramebufferfv(FramebufferID framebuffer, + GLenum buffer, + GLint drawbuffer, + const GLfloat *value) +{ + UNIMPLEMENTED(); +} + +void Context::clearNamedFramebufferiv(FramebufferID framebuffer, + GLenum buffer, + GLint drawbuffer, + const GLint *value) +{ + UNIMPLEMENTED(); +} + +void Context::clearNamedFramebufferuiv(FramebufferID framebuffer, + GLenum buffer, + GLint drawbuffer, + const GLuint *value) +{ + UNIMPLEMENTED(); +} + +void Context::compressedTextureSubImage1D(TextureID texture, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, + GLsizei imageSize, + const void *data) +{ + UNIMPLEMENTED(); +} + +void Context::compressedTextureSubImage2D(TextureID texture, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + const void *data) +{ + UNIMPLEMENTED(); +} + +void Context::compressedTextureSubImage3D(TextureID texture, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const void *data) +{ + UNIMPLEMENTED(); +} + +void Context::copyNamedBufferSubData(GLuint readBuffer, + GLuint writeBuffer, + GLintptr readOffset, + GLintptr writeOffset, + GLsizeiptr size) +{ + UNIMPLEMENTED(); +} + +void Context::copyTextureSubImage1D(TextureID texture, + GLint level, + GLint xoffset, + GLint x, + GLint y, + GLsizei width) +{ + UNIMPLEMENTED(); +} + +void Context::copyTextureSubImage2D(TextureID texture, + GLint level, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) +{ + UNIMPLEMENTED(); +} + +void Context::copyTextureSubImage3D(TextureID texture, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) +{ + UNIMPLEMENTED(); +} + +void Context::createBuffers(GLsizei n, BufferID *buffers) +{ + UNIMPLEMENTED(); +} + +void Context::createFramebuffers(GLsizei n, GLuint *framebuffers) +{ + UNIMPLEMENTED(); +} + +void Context::createProgramPipelines(GLsizei n, GLuint *pipelines) +{ + UNIMPLEMENTED(); +} + +void Context::createQueries(GLenum target, GLsizei n, GLuint *ids) +{ + UNIMPLEMENTED(); +} + +void Context::createRenderbuffers(GLsizei n, RenderbufferID *renderbuffers) +{ + UNIMPLEMENTED(); +} + +void Context::createSamplers(GLsizei n, GLuint *samplers) +{ + UNIMPLEMENTED(); +} + +void Context::createTextures(GLenum target, GLsizei n, GLuint *textures) +{ + UNIMPLEMENTED(); +} + +void Context::createTransformFeedbacks(GLsizei n, GLuint *ids) +{ + UNIMPLEMENTED(); +} + +void Context::createVertexArrays(GLsizei n, VertexArrayID *arrays) +{ + UNIMPLEMENTED(); +} + +void Context::disableVertexArrayAttrib(VertexArrayID vaobj, GLuint index) +{ + UNIMPLEMENTED(); +} + +void Context::enableVertexArrayAttrib(VertexArrayID vaobj, GLuint index) +{ + UNIMPLEMENTED(); +} + +void Context::flushMappedNamedBufferRange(BufferID buffer, GLintptr offset, GLsizeiptr length) +{ + UNIMPLEMENTED(); +} + +void Context::generateTextureMipmap(TextureID texture) +{ + UNIMPLEMENTED(); +} + +void Context::getCompressedTextureImage(TextureID texture, + GLint level, + GLsizei bufSize, + void *pixels) +{ + UNIMPLEMENTED(); +} + +void Context::getCompressedTextureSubImage(TextureID texture, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLsizei bufSize, + void *pixels) +{ + UNIMPLEMENTED(); +} + +void Context::getNamedBufferParameteri64v(BufferID buffer, GLenum pname, GLint64 *params) +{ + UNIMPLEMENTED(); +} + +void Context::getNamedBufferParameteriv(BufferID buffer, GLenum pname, GLint *params) +{ + UNIMPLEMENTED(); +} + +void Context::getNamedBufferPointerv(BufferID buffer, GLenum pname, void **params) +{ + UNIMPLEMENTED(); +} + +void Context::getNamedBufferSubData(BufferID buffer, GLintptr offset, GLsizeiptr size, void *data) +{ + UNIMPLEMENTED(); +} + +void Context::getNamedFramebufferAttachmentParameteriv(FramebufferID framebuffer, + GLenum attachment, + GLenum pname, + GLint *params) +{ + UNIMPLEMENTED(); +} + +void Context::getNamedFramebufferParameteriv(FramebufferID framebuffer, GLenum pname, GLint *param) +{ + UNIMPLEMENTED(); +} + +void Context::getNamedRenderbufferParameteriv(RenderbufferID renderbuffer, + GLenum pname, + GLint *params) +{ + UNIMPLEMENTED(); +} + +void Context::getQueryBufferObjecti64v(GLuint id, BufferID buffer, GLenum pname, GLintptr offset) +{ + UNIMPLEMENTED(); +} + +void Context::getQueryBufferObjectiv(GLuint id, BufferID buffer, GLenum pname, GLintptr offset) +{ + UNIMPLEMENTED(); +} + +void Context::getQueryBufferObjectui64v(GLuint id, BufferID buffer, GLenum pname, GLintptr offset) +{ + UNIMPLEMENTED(); +} + +void Context::getQueryBufferObjectuiv(GLuint id, BufferID buffer, GLenum pname, GLintptr offset) +{ + UNIMPLEMENTED(); +} + +void Context::getTextureImage(TextureID texture, + GLint level, + GLenum format, + GLenum type, + GLsizei bufSize, + void *pixels) +{ + UNIMPLEMENTED(); +} + +void Context::getTextureLevelParameterfv(TextureID texture, + GLint level, + GLenum pname, + GLfloat *params) +{ + UNIMPLEMENTED(); +} + +void Context::getTextureLevelParameteriv(TextureID texture, + GLint level, + GLenum pname, + GLint *params) +{ + UNIMPLEMENTED(); +} + +void Context::getTextureParameterIiv(TextureID texture, GLenum pname, GLint *params) +{ + UNIMPLEMENTED(); +} + +void Context::getTextureParameterIuiv(TextureID texture, GLenum pname, GLuint *params) +{ + UNIMPLEMENTED(); +} + +void Context::getTextureParameterfv(TextureID texture, GLenum pname, GLfloat *params) +{ + UNIMPLEMENTED(); +} + +void Context::getTextureParameteriv(TextureID texture, GLenum pname, GLint *params) +{ + UNIMPLEMENTED(); +} + +void Context::getTextureSubImage(TextureID texture, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + GLsizei bufSize, + void *pixels) +{ + UNIMPLEMENTED(); +} + +void Context::getTransformFeedbacki64_v(GLuint xfb, GLenum pname, GLuint index, GLint64 *param) +{ + UNIMPLEMENTED(); +} + +void Context::getTransformFeedbacki_v(GLuint xfb, GLenum pname, GLuint index, GLint *param) +{ + UNIMPLEMENTED(); +} + +void Context::getTransformFeedbackiv(GLuint xfb, GLenum pname, GLint *param) +{ + UNIMPLEMENTED(); +} + +void Context::getVertexArrayIndexed64iv(VertexArrayID vaobj, + GLuint index, + GLenum pname, + GLint64 *param) +{ + UNIMPLEMENTED(); +} + +void Context::getVertexArrayIndexediv(VertexArrayID vaobj, GLuint index, GLenum pname, GLint *param) +{ + UNIMPLEMENTED(); +} + +void Context::getVertexArrayiv(VertexArrayID vaobj, GLenum pname, GLint *param) +{ + UNIMPLEMENTED(); +} + +void Context::getnColorTable(GLenum target, + GLenum format, + GLenum type, + GLsizei bufSize, + void *table) +{ + UNIMPLEMENTED(); +} + +void Context::getnCompressedTexImage(GLenum target, GLint lod, GLsizei bufSize, void *pixels) +{ + UNIMPLEMENTED(); +} + +void Context::getnConvolutionFilter(GLenum target, + GLenum format, + GLenum type, + GLsizei bufSize, + void *image) +{ + UNIMPLEMENTED(); +} + +void Context::getnHistogram(GLenum target, + GLboolean reset, + GLenum format, + GLenum type, + GLsizei bufSize, + void *values) +{ + UNIMPLEMENTED(); +} + +void Context::getnMapdv(GLenum target, GLenum query, GLsizei bufSize, GLdouble *v) +{ + UNIMPLEMENTED(); +} + +void Context::getnMapfv(GLenum target, GLenum query, GLsizei bufSize, GLfloat *v) +{ + UNIMPLEMENTED(); +} + +void Context::getnMapiv(GLenum target, GLenum query, GLsizei bufSize, GLint *v) +{ + UNIMPLEMENTED(); +} + +void Context::getnMinmax(GLenum target, + GLboolean reset, + GLenum format, + GLenum type, + GLsizei bufSize, + void *values) +{ + UNIMPLEMENTED(); +} + +void Context::getnPixelMapfv(GLenum map, GLsizei bufSize, GLfloat *values) +{ + UNIMPLEMENTED(); +} + +void Context::getnPixelMapuiv(GLenum map, GLsizei bufSize, GLuint *values) +{ + UNIMPLEMENTED(); +} + +void Context::getnPixelMapusv(GLenum map, GLsizei bufSize, GLushort *values) +{ + UNIMPLEMENTED(); +} + +void Context::getnPolygonStipple(GLsizei bufSize, GLubyte *pattern) +{ + UNIMPLEMENTED(); +} + +void Context::getnSeparableFilter(GLenum target, + GLenum format, + GLenum type, + GLsizei rowBufSize, + void *row, + GLsizei columnBufSize, + void *column, + void *span) +{ + UNIMPLEMENTED(); +} + +void Context::getnTexImage(GLenum target, + GLint level, + GLenum format, + GLenum type, + GLsizei bufSize, + void *pixels) +{ + UNIMPLEMENTED(); +} + +void Context::getnUniformdv(ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + GLdouble *params) +{ + UNIMPLEMENTED(); +} + +void Context::invalidateNamedFramebufferData(FramebufferID framebuffer, + GLsizei numAttachments, + const GLenum *attachments) +{ + UNIMPLEMENTED(); +} + +void Context::invalidateNamedFramebufferSubData(FramebufferID framebuffer, + GLsizei numAttachments, + const GLenum *attachments, + GLint x, + GLint y, + GLsizei width, + GLsizei height) +{ + UNIMPLEMENTED(); +} + +void *Context::mapNamedBuffer(BufferID buffer, GLenum access) +{ + UNIMPLEMENTED(); + return nullptr; +} + +void *Context::mapNamedBufferRange(BufferID buffer, + GLintptr offset, + GLsizeiptr length, + GLbitfield access) +{ + UNIMPLEMENTED(); + return nullptr; +} + +void Context::namedBufferData(BufferID buffer, GLsizeiptr size, const void *data, GLenum usage) +{ + UNIMPLEMENTED(); +} + +void Context::namedBufferStorage(BufferID buffer, + GLsizeiptr size, + const void *data, + GLbitfield flags) +{ + UNIMPLEMENTED(); +} + +void Context::namedBufferSubData(BufferID buffer, + GLintptr offset, + GLsizeiptr size, + const void *data) +{ + UNIMPLEMENTED(); +} + +void Context::namedFramebufferDrawBuffer(FramebufferID framebuffer, GLenum buf) +{ + UNIMPLEMENTED(); +} + +void Context::namedFramebufferDrawBuffers(FramebufferID framebuffer, GLsizei n, const GLenum *bufs) +{ + UNIMPLEMENTED(); +} + +void Context::namedFramebufferParameteri(FramebufferID framebuffer, GLenum pname, GLint param) +{ + UNIMPLEMENTED(); +} + +void Context::namedFramebufferReadBuffer(FramebufferID framebuffer, GLenum src) +{ + UNIMPLEMENTED(); +} + +void Context::namedFramebufferRenderbuffer(FramebufferID framebuffer, + GLenum attachment, + GLenum renderbuffertarget, + RenderbufferID renderbuffer) +{ + UNIMPLEMENTED(); +} + +void Context::namedFramebufferTexture(FramebufferID framebuffer, + GLenum attachment, + TextureID texture, + GLint level) +{ + UNIMPLEMENTED(); +} + +void Context::namedFramebufferTextureLayer(FramebufferID framebuffer, + GLenum attachment, + TextureID texture, + GLint level, + GLint layer) +{ + UNIMPLEMENTED(); +} + +void Context::namedRenderbufferStorage(RenderbufferID renderbuffer, + GLenum internalformat, + GLsizei width, + GLsizei height) +{ + UNIMPLEMENTED(); +} + +void Context::namedRenderbufferStorageMultisample(RenderbufferID renderbuffer, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height) +{ + UNIMPLEMENTED(); +} + +void Context::textureBarrier() +{ + UNIMPLEMENTED(); +} + +void Context::textureBuffer(TextureID texture, GLenum internalformat, BufferID buffer) +{ + UNIMPLEMENTED(); +} + +void Context::textureBufferRange(TextureID texture, + GLenum internalformat, + BufferID buffer, + GLintptr offset, + GLsizeiptr size) +{ + UNIMPLEMENTED(); +} + +void Context::textureParameterIiv(TextureID texture, GLenum pname, const GLint *params) +{ + UNIMPLEMENTED(); +} + +void Context::textureParameterIuiv(TextureID texture, GLenum pname, const GLuint *params) +{ + UNIMPLEMENTED(); +} + +void Context::textureParameterf(TextureID texture, GLenum pname, GLfloat param) +{ + UNIMPLEMENTED(); +} + +void Context::textureParameterfv(TextureID texture, GLenum pname, const GLfloat *param) +{ + UNIMPLEMENTED(); +} + +void Context::textureParameteri(TextureID texture, GLenum pname, GLint param) +{ + UNIMPLEMENTED(); +} + +void Context::textureParameteriv(TextureID texture, GLenum pname, const GLint *param) +{ + UNIMPLEMENTED(); +} + +void Context::textureStorage1D(TextureID texture, + GLsizei levels, + GLenum internalformat, + GLsizei width) +{ + UNIMPLEMENTED(); +} + +void Context::textureStorage2D(TextureID texture, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height) +{ + UNIMPLEMENTED(); +} + +void Context::textureStorage2DMultisample(TextureID texture, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations) +{ + UNIMPLEMENTED(); +} + +void Context::textureStorage3D(TextureID texture, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth) +{ + UNIMPLEMENTED(); +} + +void Context::textureStorage3DMultisample(TextureID texture, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedsamplelocations) +{ + UNIMPLEMENTED(); +} + +void Context::textureSubImage1D(TextureID texture, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, + GLenum type, + const void *pixels) +{ + UNIMPLEMENTED(); +} + +void Context::textureSubImage2D(TextureID texture, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void *pixels) +{ + UNIMPLEMENTED(); +} + +void Context::textureSubImage3D(TextureID texture, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *pixels) +{ + UNIMPLEMENTED(); +} + +void Context::transformFeedbackBufferBase(GLuint xfb, GLuint index, BufferID buffer) +{ + UNIMPLEMENTED(); +} + +void Context::transformFeedbackBufferRange(GLuint xfb, + GLuint index, + BufferID buffer, + GLintptr offset, + GLsizeiptr size) +{ + UNIMPLEMENTED(); +} + +GLboolean Context::unmapNamedBuffer(BufferID buffer) +{ + UNIMPLEMENTED(); + return false; +} + +void Context::vertexArrayAttribBinding(VertexArrayID vaobj, GLuint attribindex, GLuint bindingindex) +{ + UNIMPLEMENTED(); +} + +void Context::vertexArrayAttribFormat(VertexArrayID vaobj, + GLuint attribindex, + GLint size, + GLenum type, + GLboolean normalized, + GLuint relativeoffset) +{ + UNIMPLEMENTED(); +} + +void Context::vertexArrayAttribIFormat(VertexArrayID vaobj, + GLuint attribindex, + GLint size, + GLenum type, + GLuint relativeoffset) +{ + UNIMPLEMENTED(); +} + +void Context::vertexArrayAttribLFormat(VertexArrayID vaobj, + GLuint attribindex, + GLint size, + GLenum type, + GLuint relativeoffset) +{ + UNIMPLEMENTED(); +} + +void Context::vertexArrayBindingDivisor(VertexArrayID vaobj, GLuint bindingindex, GLuint divisor) +{ + UNIMPLEMENTED(); +} + +void Context::vertexArrayElementBuffer(VertexArrayID vaobj, BufferID buffer) +{ + UNIMPLEMENTED(); +} + +void Context::vertexArrayVertexBuffer(VertexArrayID vaobj, + GLuint bindingindex, + BufferID buffer, + GLintptr offset, + GLsizei stride) +{ + UNIMPLEMENTED(); +} + +void Context::vertexArrayVertexBuffers(VertexArrayID vaobj, + GLuint first, + GLsizei count, + const BufferID *buffers, + const GLintptr *offsets, + const GLsizei *strides) +{ + UNIMPLEMENTED(); +} + +void Context::multiDrawArraysIndirectCount(GLenum mode, + const void *indirect, + GLintptr drawcount, + GLsizei maxdrawcount, + GLsizei stride) +{ + UNIMPLEMENTED(); +} + +void Context::multiDrawElementsIndirectCount(GLenum mode, + GLenum type, + const void *indirect, + GLintptr drawcount, + GLsizei maxdrawcount, + GLsizei stride) +{ + UNIMPLEMENTED(); +} + +void Context::polygonOffsetClamp(GLfloat factor, GLfloat units, GLfloat clamp) +{ + UNIMPLEMENTED(); +} + +void Context::specializeShader(GLuint shader, + const GLchar *pEntryPoint, + GLuint numSpecializationConstants, + const GLuint *pConstantIndex, + const GLuint *pConstantValue) +{ + UNIMPLEMENTED(); +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/Context_gl_1_autogen.h b/gfx/angle/checkout/src/libANGLE/Context_gl_1_autogen.h new file mode 100644 index 0000000000..7bddff4c34 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Context_gl_1_autogen.h @@ -0,0 +1,349 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Context_gl_1_autogen.h: Creates a macro for interfaces in Context. + +#ifndef ANGLE_CONTEXT_GL_1_AUTOGEN_H_ +#define ANGLE_CONTEXT_GL_1_AUTOGEN_H_ + +#define ANGLE_GL_1_CONTEXT_API \ + void accum(GLenum op, GLfloat value); \ + void begin(GLenum mode); \ + void bitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, \ + GLfloat ymove, const GLubyte *bitmap); \ + void callList(GLuint list); \ + void callLists(GLsizei n, GLenum type, const void *lists); \ + void clearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); \ + void clearDepth(GLdouble depth); \ + void clearIndex(GLfloat c); \ + void clipPlane(GLenum plane, const GLdouble *equation); \ + void color3b(GLbyte red, GLbyte green, GLbyte blue); \ + void color3bv(const GLbyte *v); \ + void color3d(GLdouble red, GLdouble green, GLdouble blue); \ + void color3dv(const GLdouble *v); \ + void color3f(GLfloat red, GLfloat green, GLfloat blue); \ + void color3fv(const GLfloat *v); \ + void color3i(GLint red, GLint green, GLint blue); \ + void color3iv(const GLint *v); \ + void color3s(GLshort red, GLshort green, GLshort blue); \ + void color3sv(const GLshort *v); \ + void color3ub(GLubyte red, GLubyte green, GLubyte blue); \ + void color3ubv(const GLubyte *v); \ + void color3ui(GLuint red, GLuint green, GLuint blue); \ + void color3uiv(const GLuint *v); \ + void color3us(GLushort red, GLushort green, GLushort blue); \ + void color3usv(const GLushort *v); \ + void color4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); \ + void color4bv(const GLbyte *v); \ + void color4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); \ + void color4dv(const GLdouble *v); \ + void color4fv(const GLfloat *v); \ + void color4i(GLint red, GLint green, GLint blue, GLint alpha); \ + void color4iv(const GLint *v); \ + void color4s(GLshort red, GLshort green, GLshort blue, GLshort alpha); \ + void color4sv(const GLshort *v); \ + void color4ubv(const GLubyte *v); \ + void color4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha); \ + void color4uiv(const GLuint *v); \ + void color4us(GLushort red, GLushort green, GLushort blue, GLushort alpha); \ + void color4usv(const GLushort *v); \ + void colorMaterial(GLenum face, GLenum mode); \ + void copyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); \ + void deleteLists(GLuint list, GLsizei range); \ + void depthRange(GLdouble n, GLdouble f); \ + void drawBuffer(GLenum buf); \ + void drawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, \ + const void *pixels); \ + void edgeFlag(GLboolean flag); \ + void edgeFlagv(const GLboolean *flag); \ + void end(); \ + void endList(); \ + void evalCoord1d(GLdouble u); \ + void evalCoord1dv(const GLdouble *u); \ + void evalCoord1f(GLfloat u); \ + void evalCoord1fv(const GLfloat *u); \ + void evalCoord2d(GLdouble u, GLdouble v); \ + void evalCoord2dv(const GLdouble *u); \ + void evalCoord2f(GLfloat u, GLfloat v); \ + void evalCoord2fv(const GLfloat *u); \ + void evalMesh1(GLenum mode, GLint i1, GLint i2); \ + void evalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); \ + void evalPoint1(GLint i); \ + void evalPoint2(GLint i, GLint j); \ + void feedbackBuffer(GLsizei size, GLenum type, GLfloat *buffer); \ + void fogi(GLenum pname, GLint param); \ + void fogiv(GLenum pname, const GLint *params); \ + void frustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, \ + GLdouble zFar); \ + GLuint genLists(GLsizei range); \ + void getClipPlane(GLenum plane, GLdouble *equation); \ + void getDoublev(GLenum pname, GLdouble *data); \ + void getLightiv(GLenum light, GLenum pname, GLint *params); \ + void getMapdv(GLenum target, GLenum query, GLdouble *v); \ + void getMapfv(GLenum target, GLenum query, GLfloat *v); \ + void getMapiv(GLenum target, GLenum query, GLint *v); \ + void getMaterialiv(GLenum face, GLenum pname, GLint *params); \ + void getPixelMapfv(GLenum map, GLfloat *values); \ + void getPixelMapuiv(GLenum map, GLuint *values); \ + void getPixelMapusv(GLenum map, GLushort *values); \ + void getPolygonStipple(GLubyte *mask); \ + void getTexGendv(GLenum coord, GLenum pname, GLdouble *params); \ + void indexMask(GLuint mask); \ + void indexd(GLdouble c); \ + void indexdv(const GLdouble *c); \ + void indexf(GLfloat c); \ + void indexfv(const GLfloat *c); \ + void indexi(GLint c); \ + void indexiv(const GLint *c); \ + void indexs(GLshort c); \ + void indexsv(const GLshort *c); \ + void initNames(); \ + GLboolean isList(GLuint list) const; \ + void lightModeli(GLenum pname, GLint param); \ + void lightModeliv(GLenum pname, const GLint *params); \ + void lighti(GLenum light, GLenum pname, GLint param); \ + void lightiv(GLenum light, GLenum pname, const GLint *params); \ + void lineStipple(GLint factor, GLushort pattern); \ + void listBase(GLuint base); \ + void loadMatrixd(const GLdouble *m); \ + void loadName(GLuint name); \ + void map1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, \ + const GLdouble *points); \ + void map1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, \ + const GLfloat *points); \ + void map2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, \ + GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); \ + void map2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, \ + GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); \ + void mapGrid1d(GLint un, GLdouble u1, GLdouble u2); \ + void mapGrid1f(GLint un, GLfloat u1, GLfloat u2); \ + void mapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); \ + void mapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); \ + void materiali(GLenum face, GLenum pname, GLint param); \ + void materialiv(GLenum face, GLenum pname, const GLint *params); \ + void multMatrixd(const GLdouble *m); \ + void newList(GLuint list, GLenum mode); \ + void normal3b(GLbyte nx, GLbyte ny, GLbyte nz); \ + void normal3bv(const GLbyte *v); \ + void normal3d(GLdouble nx, GLdouble ny, GLdouble nz); \ + void normal3dv(const GLdouble *v); \ + void normal3fv(const GLfloat *v); \ + void normal3i(GLint nx, GLint ny, GLint nz); \ + void normal3iv(const GLint *v); \ + void normal3s(GLshort nx, GLshort ny, GLshort nz); \ + void normal3sv(const GLshort *v); \ + void ortho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, \ + GLdouble zFar); \ + void passThrough(GLfloat token); \ + void pixelMapfv(GLenum map, GLsizei mapsize, const GLfloat *values); \ + void pixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values); \ + void pixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values); \ + void pixelStoref(GLenum pname, GLfloat param); \ + void pixelTransferf(GLenum pname, GLfloat param); \ + void pixelTransferi(GLenum pname, GLint param); \ + void pixelZoom(GLfloat xfactor, GLfloat yfactor); \ + void polygonMode(GLenum face, GLenum mode); \ + void polygonStipple(const GLubyte *mask); \ + void popAttrib(); \ + void popName(); \ + void pushAttrib(GLbitfield mask); \ + void pushName(GLuint name); \ + void rasterPos2d(GLdouble x, GLdouble y); \ + void rasterPos2dv(const GLdouble *v); \ + void rasterPos2f(GLfloat x, GLfloat y); \ + void rasterPos2fv(const GLfloat *v); \ + void rasterPos2i(GLint x, GLint y); \ + void rasterPos2iv(const GLint *v); \ + void rasterPos2s(GLshort x, GLshort y); \ + void rasterPos2sv(const GLshort *v); \ + void rasterPos3d(GLdouble x, GLdouble y, GLdouble z); \ + void rasterPos3dv(const GLdouble *v); \ + void rasterPos3f(GLfloat x, GLfloat y, GLfloat z); \ + void rasterPos3fv(const GLfloat *v); \ + void rasterPos3i(GLint x, GLint y, GLint z); \ + void rasterPos3iv(const GLint *v); \ + void rasterPos3s(GLshort x, GLshort y, GLshort z); \ + void rasterPos3sv(const GLshort *v); \ + void rasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w); \ + void rasterPos4dv(const GLdouble *v); \ + void rasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w); \ + void rasterPos4fv(const GLfloat *v); \ + void rasterPos4i(GLint x, GLint y, GLint z, GLint w); \ + void rasterPos4iv(const GLint *v); \ + void rasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w); \ + void rasterPos4sv(const GLshort *v); \ + void rectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); \ + void rectdv(const GLdouble *v1, const GLdouble *v2); \ + void rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); \ + void rectfv(const GLfloat *v1, const GLfloat *v2); \ + void recti(GLint x1, GLint y1, GLint x2, GLint y2); \ + void rectiv(const GLint *v1, const GLint *v2); \ + void rects(GLshort x1, GLshort y1, GLshort x2, GLshort y2); \ + void rectsv(const GLshort *v1, const GLshort *v2); \ + GLint renderMode(GLenum mode); \ + void rotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); \ + void scaled(GLdouble x, GLdouble y, GLdouble z); \ + void selectBuffer(GLsizei size, GLuint *buffer); \ + void texCoord1d(GLdouble s); \ + void texCoord1dv(const GLdouble *v); \ + void texCoord1f(GLfloat s); \ + void texCoord1fv(const GLfloat *v); \ + void texCoord1i(GLint s); \ + void texCoord1iv(const GLint *v); \ + void texCoord1s(GLshort s); \ + void texCoord1sv(const GLshort *v); \ + void texCoord2d(GLdouble s, GLdouble t); \ + void texCoord2dv(const GLdouble *v); \ + void texCoord2f(GLfloat s, GLfloat t); \ + void texCoord2fv(const GLfloat *v); \ + void texCoord2i(GLint s, GLint t); \ + void texCoord2iv(const GLint *v); \ + void texCoord2s(GLshort s, GLshort t); \ + void texCoord2sv(const GLshort *v); \ + void texCoord3d(GLdouble s, GLdouble t, GLdouble r); \ + void texCoord3dv(const GLdouble *v); \ + void texCoord3f(GLfloat s, GLfloat t, GLfloat r); \ + void texCoord3fv(const GLfloat *v); \ + void texCoord3i(GLint s, GLint t, GLint r); \ + void texCoord3iv(const GLint *v); \ + void texCoord3s(GLshort s, GLshort t, GLshort r); \ + void texCoord3sv(const GLshort *v); \ + void texCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q); \ + void texCoord4dv(const GLdouble *v); \ + void texCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q); \ + void texCoord4fv(const GLfloat *v); \ + void texCoord4i(GLint s, GLint t, GLint r, GLint q); \ + void texCoord4iv(const GLint *v); \ + void texCoord4s(GLshort s, GLshort t, GLshort r, GLshort q); \ + void texCoord4sv(const GLshort *v); \ + void texGend(GLenum coord, GLenum pname, GLdouble param); \ + void texGendv(GLenum coord, GLenum pname, const GLdouble *params); \ + void texImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, \ + GLenum format, GLenum type, const void *pixels); \ + void translated(GLdouble x, GLdouble y, GLdouble z); \ + void vertex2d(GLdouble x, GLdouble y); \ + void vertex2dv(const GLdouble *v); \ + void vertex2f(GLfloat x, GLfloat y); \ + void vertex2fv(const GLfloat *v); \ + void vertex2i(GLint x, GLint y); \ + void vertex2iv(const GLint *v); \ + void vertex2s(GLshort x, GLshort y); \ + void vertex2sv(const GLshort *v); \ + void vertex3d(GLdouble x, GLdouble y, GLdouble z); \ + void vertex3dv(const GLdouble *v); \ + void vertex3f(GLfloat x, GLfloat y, GLfloat z); \ + void vertex3fv(const GLfloat *v); \ + void vertex3i(GLint x, GLint y, GLint z); \ + void vertex3iv(const GLint *v); \ + void vertex3s(GLshort x, GLshort y, GLshort z); \ + void vertex3sv(const GLshort *v); \ + void vertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w); \ + void vertex4dv(const GLdouble *v); \ + void vertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w); \ + void vertex4fv(const GLfloat *v); \ + void vertex4i(GLint x, GLint y, GLint z, GLint w); \ + void vertex4iv(const GLint *v); \ + void vertex4s(GLshort x, GLshort y, GLshort z, GLshort w); \ + void vertex4sv(const GLshort *v); \ + GLboolean areTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences); \ + void arrayElement(GLint i); \ + void copyTexImage1D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, \ + GLsizei width, GLint border); \ + void copyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, \ + GLsizei width); \ + void edgeFlagPointer(GLsizei stride, const void *pointer); \ + void indexPointer(GLenum type, GLsizei stride, const void *pointer); \ + void indexub(GLubyte c); \ + void indexubv(const GLubyte *c); \ + void interleavedArrays(GLenum format, GLsizei stride, const void *pointer); \ + void popClientAttrib(); \ + void prioritizeTextures(GLsizei n, const GLuint *textures, const GLfloat *priorities); \ + void pushClientAttrib(GLbitfield mask); \ + void texSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, \ + GLenum type, const void *pixels); \ + void compressedTexImage1D(GLenum target, GLint level, GLenum internalformat, GLsizei width, \ + GLint border, GLsizei imageSize, const void *data); \ + void compressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, \ + GLenum format, GLsizei imageSize, const void *data); \ + void loadTransposeMatrixd(const GLdouble *m); \ + void loadTransposeMatrixf(const GLfloat *m); \ + void multTransposeMatrixd(const GLdouble *m); \ + void multTransposeMatrixf(const GLfloat *m); \ + void multiTexCoord1d(GLenum target, GLdouble s); \ + void multiTexCoord1dv(GLenum target, const GLdouble *v); \ + void multiTexCoord1f(GLenum target, GLfloat s); \ + void multiTexCoord1fv(GLenum target, const GLfloat *v); \ + void multiTexCoord1i(GLenum target, GLint s); \ + void multiTexCoord1iv(GLenum target, const GLint *v); \ + void multiTexCoord1s(GLenum target, GLshort s); \ + void multiTexCoord1sv(GLenum target, const GLshort *v); \ + void multiTexCoord2d(GLenum target, GLdouble s, GLdouble t); \ + void multiTexCoord2dv(GLenum target, const GLdouble *v); \ + void multiTexCoord2f(GLenum target, GLfloat s, GLfloat t); \ + void multiTexCoord2fv(GLenum target, const GLfloat *v); \ + void multiTexCoord2i(GLenum target, GLint s, GLint t); \ + void multiTexCoord2iv(GLenum target, const GLint *v); \ + void multiTexCoord2s(GLenum target, GLshort s, GLshort t); \ + void multiTexCoord2sv(GLenum target, const GLshort *v); \ + void multiTexCoord3d(GLenum target, GLdouble s, GLdouble t, GLdouble r); \ + void multiTexCoord3dv(GLenum target, const GLdouble *v); \ + void multiTexCoord3f(GLenum target, GLfloat s, GLfloat t, GLfloat r); \ + void multiTexCoord3fv(GLenum target, const GLfloat *v); \ + void multiTexCoord3i(GLenum target, GLint s, GLint t, GLint r); \ + void multiTexCoord3iv(GLenum target, const GLint *v); \ + void multiTexCoord3s(GLenum target, GLshort s, GLshort t, GLshort r); \ + void multiTexCoord3sv(GLenum target, const GLshort *v); \ + void multiTexCoord4d(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); \ + void multiTexCoord4dv(GLenum target, const GLdouble *v); \ + void multiTexCoord4fv(GLenum target, const GLfloat *v); \ + void multiTexCoord4i(GLenum target, GLint s, GLint t, GLint r, GLint q); \ + void multiTexCoord4iv(GLenum target, const GLint *v); \ + void multiTexCoord4s(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); \ + void multiTexCoord4sv(GLenum target, const GLshort *v); \ + void fogCoordPointer(GLenum type, GLsizei stride, const void *pointer); \ + void fogCoordd(GLdouble coord); \ + void fogCoorddv(const GLdouble *coord); \ + void fogCoordf(GLfloat coord); \ + void fogCoordfv(const GLfloat *coord); \ + void pointParameteri(GLenum pname, GLint param); \ + void pointParameteriv(GLenum pname, const GLint *params); \ + void secondaryColor3b(GLbyte red, GLbyte green, GLbyte blue); \ + void secondaryColor3bv(const GLbyte *v); \ + void secondaryColor3d(GLdouble red, GLdouble green, GLdouble blue); \ + void secondaryColor3dv(const GLdouble *v); \ + void secondaryColor3f(GLfloat red, GLfloat green, GLfloat blue); \ + void secondaryColor3fv(const GLfloat *v); \ + void secondaryColor3i(GLint red, GLint green, GLint blue); \ + void secondaryColor3iv(const GLint *v); \ + void secondaryColor3s(GLshort red, GLshort green, GLshort blue); \ + void secondaryColor3sv(const GLshort *v); \ + void secondaryColor3ub(GLubyte red, GLubyte green, GLubyte blue); \ + void secondaryColor3ubv(const GLubyte *v); \ + void secondaryColor3ui(GLuint red, GLuint green, GLuint blue); \ + void secondaryColor3uiv(const GLuint *v); \ + void secondaryColor3us(GLushort red, GLushort green, GLushort blue); \ + void secondaryColor3usv(const GLushort *v); \ + void secondaryColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer); \ + void windowPos2d(GLdouble x, GLdouble y); \ + void windowPos2dv(const GLdouble *v); \ + void windowPos2f(GLfloat x, GLfloat y); \ + void windowPos2fv(const GLfloat *v); \ + void windowPos2i(GLint x, GLint y); \ + void windowPos2iv(const GLint *v); \ + void windowPos2s(GLshort x, GLshort y); \ + void windowPos2sv(const GLshort *v); \ + void windowPos3d(GLdouble x, GLdouble y, GLdouble z); \ + void windowPos3dv(const GLdouble *v); \ + void windowPos3f(GLfloat x, GLfloat y, GLfloat z); \ + void windowPos3fv(const GLfloat *v); \ + void windowPos3i(GLint x, GLint y, GLint z); \ + void windowPos3iv(const GLint *v); \ + void windowPos3s(GLshort x, GLshort y, GLshort z); \ + void windowPos3sv(const GLshort *v); \ + void getBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, void *data); + +#endif // ANGLE_CONTEXT_API_1_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Context_gl_2_autogen.h b/gfx/angle/checkout/src/libANGLE/Context_gl_2_autogen.h new file mode 100644 index 0000000000..92e17d1d6e --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Context_gl_2_autogen.h @@ -0,0 +1,44 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Context_gl_2_autogen.h: Creates a macro for interfaces in Context. + +#ifndef ANGLE_CONTEXT_GL_2_AUTOGEN_H_ +#define ANGLE_CONTEXT_GL_2_AUTOGEN_H_ + +#define ANGLE_GL_2_CONTEXT_API \ + void getVertexAttribdv(GLuint index, GLenum pname, GLdouble *params); \ + void vertexAttrib1d(GLuint index, GLdouble x); \ + void vertexAttrib1dv(GLuint index, const GLdouble *v); \ + void vertexAttrib1s(GLuint index, GLshort x); \ + void vertexAttrib1sv(GLuint index, const GLshort *v); \ + void vertexAttrib2d(GLuint index, GLdouble x, GLdouble y); \ + void vertexAttrib2dv(GLuint index, const GLdouble *v); \ + void vertexAttrib2s(GLuint index, GLshort x, GLshort y); \ + void vertexAttrib2sv(GLuint index, const GLshort *v); \ + void vertexAttrib3d(GLuint index, GLdouble x, GLdouble y, GLdouble z); \ + void vertexAttrib3dv(GLuint index, const GLdouble *v); \ + void vertexAttrib3s(GLuint index, GLshort x, GLshort y, GLshort z); \ + void vertexAttrib3sv(GLuint index, const GLshort *v); \ + void vertexAttrib4Nbv(GLuint index, const GLbyte *v); \ + void vertexAttrib4Niv(GLuint index, const GLint *v); \ + void vertexAttrib4Nsv(GLuint index, const GLshort *v); \ + void vertexAttrib4Nub(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); \ + void vertexAttrib4Nubv(GLuint index, const GLubyte *v); \ + void vertexAttrib4Nuiv(GLuint index, const GLuint *v); \ + void vertexAttrib4Nusv(GLuint index, const GLushort *v); \ + void vertexAttrib4bv(GLuint index, const GLbyte *v); \ + void vertexAttrib4d(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); \ + void vertexAttrib4dv(GLuint index, const GLdouble *v); \ + void vertexAttrib4iv(GLuint index, const GLint *v); \ + void vertexAttrib4s(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); \ + void vertexAttrib4sv(GLuint index, const GLshort *v); \ + void vertexAttrib4ubv(GLuint index, const GLubyte *v); \ + void vertexAttrib4uiv(GLuint index, const GLuint *v); \ + void vertexAttrib4usv(GLuint index, const GLushort *v); + +#endif // ANGLE_CONTEXT_API_2_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Context_gl_3_autogen.h b/gfx/angle/checkout/src/libANGLE/Context_gl_3_autogen.h new file mode 100644 index 0000000000..598a9055ef --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Context_gl_3_autogen.h @@ -0,0 +1,82 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Context_gl_3_autogen.h: Creates a macro for interfaces in Context. + +#ifndef ANGLE_CONTEXT_GL_3_AUTOGEN_H_ +#define ANGLE_CONTEXT_GL_3_AUTOGEN_H_ + +#define ANGLE_GL_3_CONTEXT_API \ + void beginConditionalRender(GLuint id, GLenum mode); \ + void clampColor(GLenum target, GLenum clamp); \ + void endConditionalRender(); \ + void framebufferTexture1D(GLenum target, GLenum attachment, TextureTarget textargetPacked, \ + TextureID texturePacked, GLint level); \ + void vertexAttribI1i(GLuint index, GLint x); \ + void vertexAttribI1iv(GLuint index, const GLint *v); \ + void vertexAttribI1ui(GLuint index, GLuint x); \ + void vertexAttribI1uiv(GLuint index, const GLuint *v); \ + void vertexAttribI2i(GLuint index, GLint x, GLint y); \ + void vertexAttribI2iv(GLuint index, const GLint *v); \ + void vertexAttribI2ui(GLuint index, GLuint x, GLuint y); \ + void vertexAttribI2uiv(GLuint index, const GLuint *v); \ + void vertexAttribI3i(GLuint index, GLint x, GLint y, GLint z); \ + void vertexAttribI3iv(GLuint index, const GLint *v); \ + void vertexAttribI3ui(GLuint index, GLuint x, GLuint y, GLuint z); \ + void vertexAttribI3uiv(GLuint index, const GLuint *v); \ + void vertexAttribI4bv(GLuint index, const GLbyte *v); \ + void vertexAttribI4sv(GLuint index, const GLshort *v); \ + void vertexAttribI4ubv(GLuint index, const GLubyte *v); \ + void vertexAttribI4usv(GLuint index, const GLushort *v); \ + void getActiveUniformName(ShaderProgramID programPacked, GLuint uniformIndex, GLsizei bufSize, \ + GLsizei *length, GLchar *uniformName); \ + void primitiveRestartIndex(GLuint index); \ + void texImage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, \ + GLsizei width, GLsizei height, GLboolean fixedsamplelocations); \ + void texImage3DMultisample(GLenum target, GLsizei samples, GLenum internalformat, \ + GLsizei width, GLsizei height, GLsizei depth, \ + GLboolean fixedsamplelocations); \ + void colorP3ui(GLenum type, GLuint color); \ + void colorP3uiv(GLenum type, const GLuint *color); \ + void colorP4ui(GLenum type, GLuint color); \ + void colorP4uiv(GLenum type, const GLuint *color); \ + void multiTexCoordP1ui(GLenum texture, GLenum type, GLuint coords); \ + void multiTexCoordP1uiv(GLenum texture, GLenum type, const GLuint *coords); \ + void multiTexCoordP2ui(GLenum texture, GLenum type, GLuint coords); \ + void multiTexCoordP2uiv(GLenum texture, GLenum type, const GLuint *coords); \ + void multiTexCoordP3ui(GLenum texture, GLenum type, GLuint coords); \ + void multiTexCoordP3uiv(GLenum texture, GLenum type, const GLuint *coords); \ + void multiTexCoordP4ui(GLenum texture, GLenum type, GLuint coords); \ + void multiTexCoordP4uiv(GLenum texture, GLenum type, const GLuint *coords); \ + void normalP3ui(GLenum type, GLuint coords); \ + void normalP3uiv(GLenum type, const GLuint *coords); \ + void secondaryColorP3ui(GLenum type, GLuint color); \ + void secondaryColorP3uiv(GLenum type, const GLuint *color); \ + void texCoordP1ui(GLenum type, GLuint coords); \ + void texCoordP1uiv(GLenum type, const GLuint *coords); \ + void texCoordP2ui(GLenum type, GLuint coords); \ + void texCoordP2uiv(GLenum type, const GLuint *coords); \ + void texCoordP3ui(GLenum type, GLuint coords); \ + void texCoordP3uiv(GLenum type, const GLuint *coords); \ + void texCoordP4ui(GLenum type, GLuint coords); \ + void texCoordP4uiv(GLenum type, const GLuint *coords); \ + void vertexAttribP1ui(GLuint index, GLenum type, GLboolean normalized, GLuint value); \ + void vertexAttribP1uiv(GLuint index, GLenum type, GLboolean normalized, const GLuint *value); \ + void vertexAttribP2ui(GLuint index, GLenum type, GLboolean normalized, GLuint value); \ + void vertexAttribP2uiv(GLuint index, GLenum type, GLboolean normalized, const GLuint *value); \ + void vertexAttribP3ui(GLuint index, GLenum type, GLboolean normalized, GLuint value); \ + void vertexAttribP3uiv(GLuint index, GLenum type, GLboolean normalized, const GLuint *value); \ + void vertexAttribP4ui(GLuint index, GLenum type, GLboolean normalized, GLuint value); \ + void vertexAttribP4uiv(GLuint index, GLenum type, GLboolean normalized, const GLuint *value); \ + void vertexP2ui(GLenum type, GLuint value); \ + void vertexP2uiv(GLenum type, const GLuint *value); \ + void vertexP3ui(GLenum type, GLuint value); \ + void vertexP3uiv(GLenum type, const GLuint *value); \ + void vertexP4ui(GLenum type, GLuint value); \ + void vertexP4uiv(GLenum type, const GLuint *value); + +#endif // ANGLE_CONTEXT_API_3_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Context_gl_4_autogen.h b/gfx/angle/checkout/src/libANGLE/Context_gl_4_autogen.h new file mode 100644 index 0000000000..2c5570149e --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Context_gl_4_autogen.h @@ -0,0 +1,358 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Context_gl_4_autogen.h: Creates a macro for interfaces in Context. + +#ifndef ANGLE_CONTEXT_GL_4_AUTOGEN_H_ +#define ANGLE_CONTEXT_GL_4_AUTOGEN_H_ + +#define ANGLE_GL_4_CONTEXT_API \ + void beginQueryIndexed(GLenum target, GLuint index, QueryID idPacked); \ + void drawTransformFeedback(GLenum mode, TransformFeedbackID idPacked); \ + void drawTransformFeedbackStream(GLenum mode, TransformFeedbackID idPacked, GLuint stream); \ + void endQueryIndexed(GLenum target, GLuint index); \ + void getActiveSubroutineName(ShaderProgramID programPacked, GLenum shadertype, GLuint index, \ + GLsizei bufSize, GLsizei *length, GLchar *name); \ + void getActiveSubroutineUniformName(ShaderProgramID programPacked, GLenum shadertype, \ + GLuint index, GLsizei bufSize, GLsizei *length, \ + GLchar *name); \ + void getActiveSubroutineUniformiv(ShaderProgramID programPacked, GLenum shadertype, \ + GLuint index, GLenum pname, GLint *values); \ + void getProgramStageiv(ShaderProgramID programPacked, GLenum shadertype, GLenum pname, \ + GLint *values); \ + void getQueryIndexediv(GLenum target, GLuint index, GLenum pname, GLint *params); \ + GLuint getSubroutineIndex(ShaderProgramID programPacked, GLenum shadertype, \ + const GLchar *name); \ + GLint getSubroutineUniformLocation(ShaderProgramID programPacked, GLenum shadertype, \ + const GLchar *name); \ + void getUniformSubroutineuiv(GLenum shadertype, GLint location, GLuint *params); \ + void getUniformdv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLdouble *params); \ + void patchParameterfv(GLenum pname, const GLfloat *values); \ + void uniform1d(UniformLocation locationPacked, GLdouble x); \ + void uniform1dv(UniformLocation locationPacked, GLsizei count, const GLdouble *value); \ + void uniform2d(UniformLocation locationPacked, GLdouble x, GLdouble y); \ + void uniform2dv(UniformLocation locationPacked, GLsizei count, const GLdouble *value); \ + void uniform3d(UniformLocation locationPacked, GLdouble x, GLdouble y, GLdouble z); \ + void uniform3dv(UniformLocation locationPacked, GLsizei count, const GLdouble *value); \ + void uniform4d(UniformLocation locationPacked, GLdouble x, GLdouble y, GLdouble z, \ + GLdouble w); \ + void uniform4dv(UniformLocation locationPacked, GLsizei count, const GLdouble *value); \ + void uniformMatrix2dv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \ + const GLdouble *value); \ + void uniformMatrix2x3dv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \ + const GLdouble *value); \ + void uniformMatrix2x4dv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \ + const GLdouble *value); \ + void uniformMatrix3dv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \ + const GLdouble *value); \ + void uniformMatrix3x2dv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \ + const GLdouble *value); \ + void uniformMatrix3x4dv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \ + const GLdouble *value); \ + void uniformMatrix4dv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \ + const GLdouble *value); \ + void uniformMatrix4x2dv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \ + const GLdouble *value); \ + void uniformMatrix4x3dv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \ + const GLdouble *value); \ + void uniformSubroutinesuiv(GLenum shadertype, GLsizei count, const GLuint *indices); \ + void depthRangeArrayv(GLuint first, GLsizei count, const GLdouble *v); \ + void depthRangeIndexed(GLuint index, GLdouble n, GLdouble f); \ + void getDoublei_v(GLenum target, GLuint index, GLdouble *data); \ + void getFloati_v(GLenum target, GLuint index, GLfloat *data); \ + void getVertexAttribLdv(GLuint index, GLenum pname, GLdouble *params); \ + void programUniform1d(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLdouble v0); \ + void programUniform1dv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, const GLdouble *value); \ + void programUniform2d(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLdouble v0, GLdouble v1); \ + void programUniform2dv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, const GLdouble *value); \ + void programUniform3d(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLdouble v0, GLdouble v1, GLdouble v2); \ + void programUniform3dv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, const GLdouble *value); \ + void programUniform4d(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3); \ + void programUniform4dv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, const GLdouble *value); \ + void programUniformMatrix2dv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, GLboolean transpose, const GLdouble *value); \ + void programUniformMatrix2x3dv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, GLboolean transpose, const GLdouble *value); \ + void programUniformMatrix2x4dv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, GLboolean transpose, const GLdouble *value); \ + void programUniformMatrix3dv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, GLboolean transpose, const GLdouble *value); \ + void programUniformMatrix3x2dv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, GLboolean transpose, const GLdouble *value); \ + void programUniformMatrix3x4dv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, GLboolean transpose, const GLdouble *value); \ + void programUniformMatrix4dv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, GLboolean transpose, const GLdouble *value); \ + void programUniformMatrix4x2dv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, GLboolean transpose, const GLdouble *value); \ + void programUniformMatrix4x3dv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, GLboolean transpose, const GLdouble *value); \ + void scissorArrayv(GLuint first, GLsizei count, const GLint *v); \ + void scissorIndexed(GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); \ + void scissorIndexedv(GLuint index, const GLint *v); \ + void vertexAttribL1d(GLuint index, GLdouble x); \ + void vertexAttribL1dv(GLuint index, const GLdouble *v); \ + void vertexAttribL2d(GLuint index, GLdouble x, GLdouble y); \ + void vertexAttribL2dv(GLuint index, const GLdouble *v); \ + void vertexAttribL3d(GLuint index, GLdouble x, GLdouble y, GLdouble z); \ + void vertexAttribL3dv(GLuint index, const GLdouble *v); \ + void vertexAttribL4d(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); \ + void vertexAttribL4dv(GLuint index, const GLdouble *v); \ + void vertexAttribLPointer(GLuint index, GLint size, GLenum type, GLsizei stride, \ + const void *pointer); \ + void viewportArrayv(GLuint first, GLsizei count, const GLfloat *v); \ + void viewportIndexedf(GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); \ + void viewportIndexedfv(GLuint index, const GLfloat *v); \ + void drawTransformFeedbackInstanced(GLenum mode, TransformFeedbackID idPacked, \ + GLsizei instancecount); \ + void drawTransformFeedbackStreamInstanced(GLenum mode, TransformFeedbackID idPacked, \ + GLuint stream, GLsizei instancecount); \ + void getActiveAtomicCounterBufferiv(ShaderProgramID programPacked, GLuint bufferIndex, \ + GLenum pname, GLint *params); \ + void clearBufferData(GLenum target, GLenum internalformat, GLenum format, GLenum type, \ + const void *data); \ + void clearBufferSubData(GLenum target, GLenum internalformat, GLintptr offset, \ + GLsizeiptr size, GLenum format, GLenum type, const void *data); \ + void getInternalformati64v(GLenum target, GLenum internalformat, GLenum pname, GLsizei count, \ + GLint64 *params); \ + void invalidateBufferData(BufferID bufferPacked); \ + void invalidateBufferSubData(BufferID bufferPacked, GLintptr offset, GLsizeiptr length); \ + void invalidateTexImage(TextureID texturePacked, GLint level); \ + void invalidateTexSubImage(TextureID texturePacked, GLint level, GLint xoffset, GLint yoffset, \ + GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); \ + void shaderStorageBlockBinding(ShaderProgramID programPacked, GLuint storageBlockIndex, \ + GLuint storageBlockBinding); \ + void textureView(TextureID texturePacked, GLenum target, GLuint origtexture, \ + GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, \ + GLuint numlayers); \ + void vertexAttribLFormat(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); \ + void bindBuffersBase(GLenum target, GLuint first, GLsizei count, \ + const BufferID *buffersPacked); \ + void bindBuffersRange(GLenum target, GLuint first, GLsizei count, \ + const BufferID *buffersPacked, const GLintptr *offsets, \ + const GLsizeiptr *sizes); \ + void bindImageTextures(GLuint first, GLsizei count, const GLuint *textures); \ + void bindSamplers(GLuint first, GLsizei count, const GLuint *samplers); \ + void bindTextures(GLuint first, GLsizei count, const GLuint *textures); \ + void bindVertexBuffers(GLuint first, GLsizei count, const BufferID *buffersPacked, \ + const GLintptr *offsets, const GLsizei *strides); \ + void clearTexImage(TextureID texturePacked, GLint level, GLenum format, GLenum type, \ + const void *data); \ + void clearTexSubImage(TextureID texturePacked, GLint level, GLint xoffset, GLint yoffset, \ + GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, \ + GLenum format, GLenum type, const void *data); \ + void bindTextureUnit(GLuint unit, TextureID texturePacked); \ + void blitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, \ + GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, \ + GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); \ + GLenum checkNamedFramebufferStatus(FramebufferID framebufferPacked, GLenum target); \ + void clearNamedBufferData(BufferID bufferPacked, GLenum internalformat, GLenum format, \ + GLenum type, const void *data); \ + void clearNamedBufferSubData(BufferID bufferPacked, GLenum internalformat, GLintptr offset, \ + GLsizeiptr size, GLenum format, GLenum type, const void *data); \ + void clearNamedFramebufferfi(FramebufferID framebufferPacked, GLenum buffer, GLint drawbuffer, \ + GLfloat depth, GLint stencil); \ + void clearNamedFramebufferfv(FramebufferID framebufferPacked, GLenum buffer, GLint drawbuffer, \ + const GLfloat *value); \ + void clearNamedFramebufferiv(FramebufferID framebufferPacked, GLenum buffer, GLint drawbuffer, \ + const GLint *value); \ + void clearNamedFramebufferuiv(FramebufferID framebufferPacked, GLenum buffer, \ + GLint drawbuffer, const GLuint *value); \ + void compressedTextureSubImage1D(TextureID texturePacked, GLint level, GLint xoffset, \ + GLsizei width, GLenum format, GLsizei imageSize, \ + const void *data); \ + void compressedTextureSubImage2D(TextureID texturePacked, GLint level, GLint xoffset, \ + GLint yoffset, GLsizei width, GLsizei height, GLenum format, \ + GLsizei imageSize, const void *data); \ + void compressedTextureSubImage3D(TextureID texturePacked, GLint level, GLint xoffset, \ + GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, \ + GLsizei depth, GLenum format, GLsizei imageSize, \ + const void *data); \ + void copyNamedBufferSubData(GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, \ + GLintptr writeOffset, GLsizeiptr size); \ + void copyTextureSubImage1D(TextureID texturePacked, GLint level, GLint xoffset, GLint x, \ + GLint y, GLsizei width); \ + void copyTextureSubImage2D(TextureID texturePacked, GLint level, GLint xoffset, GLint yoffset, \ + GLint x, GLint y, GLsizei width, GLsizei height); \ + void copyTextureSubImage3D(TextureID texturePacked, GLint level, GLint xoffset, GLint yoffset, \ + GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); \ + void createBuffers(GLsizei n, BufferID *buffersPacked); \ + void createFramebuffers(GLsizei n, GLuint *framebuffers); \ + void createProgramPipelines(GLsizei n, GLuint *pipelines); \ + void createQueries(GLenum target, GLsizei n, GLuint *ids); \ + void createRenderbuffers(GLsizei n, RenderbufferID *renderbuffersPacked); \ + void createSamplers(GLsizei n, GLuint *samplers); \ + void createTextures(GLenum target, GLsizei n, GLuint *textures); \ + void createTransformFeedbacks(GLsizei n, GLuint *ids); \ + void createVertexArrays(GLsizei n, VertexArrayID *arraysPacked); \ + void disableVertexArrayAttrib(VertexArrayID vaobjPacked, GLuint index); \ + void enableVertexArrayAttrib(VertexArrayID vaobjPacked, GLuint index); \ + void flushMappedNamedBufferRange(BufferID bufferPacked, GLintptr offset, GLsizeiptr length); \ + void generateTextureMipmap(TextureID texturePacked); \ + void getCompressedTextureImage(TextureID texturePacked, GLint level, GLsizei bufSize, \ + void *pixels); \ + void getCompressedTextureSubImage(TextureID texturePacked, GLint level, GLint xoffset, \ + GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, \ + GLsizei depth, GLsizei bufSize, void *pixels); \ + void getNamedBufferParameteri64v(BufferID bufferPacked, GLenum pname, GLint64 *params); \ + void getNamedBufferParameteriv(BufferID bufferPacked, GLenum pname, GLint *params); \ + void getNamedBufferPointerv(BufferID bufferPacked, GLenum pname, void **params); \ + void getNamedBufferSubData(BufferID bufferPacked, GLintptr offset, GLsizeiptr size, \ + void *data); \ + void getNamedFramebufferAttachmentParameteriv(FramebufferID framebufferPacked, \ + GLenum attachment, GLenum pname, GLint *params); \ + void getNamedFramebufferParameteriv(FramebufferID framebufferPacked, GLenum pname, \ + GLint *param); \ + void getNamedRenderbufferParameteriv(RenderbufferID renderbufferPacked, GLenum pname, \ + GLint *params); \ + void getQueryBufferObjecti64v(GLuint id, BufferID bufferPacked, GLenum pname, \ + GLintptr offset); \ + void getQueryBufferObjectiv(GLuint id, BufferID bufferPacked, GLenum pname, GLintptr offset); \ + void getQueryBufferObjectui64v(GLuint id, BufferID bufferPacked, GLenum pname, \ + GLintptr offset); \ + void getQueryBufferObjectuiv(GLuint id, BufferID bufferPacked, GLenum pname, GLintptr offset); \ + void getTextureImage(TextureID texturePacked, GLint level, GLenum format, GLenum type, \ + GLsizei bufSize, void *pixels); \ + void getTextureLevelParameterfv(TextureID texturePacked, GLint level, GLenum pname, \ + GLfloat *params); \ + void getTextureLevelParameteriv(TextureID texturePacked, GLint level, GLenum pname, \ + GLint *params); \ + void getTextureParameterIiv(TextureID texturePacked, GLenum pname, GLint *params); \ + void getTextureParameterIuiv(TextureID texturePacked, GLenum pname, GLuint *params); \ + void getTextureParameterfv(TextureID texturePacked, GLenum pname, GLfloat *params); \ + void getTextureParameteriv(TextureID texturePacked, GLenum pname, GLint *params); \ + void getTextureSubImage(TextureID texturePacked, GLint level, GLint xoffset, GLint yoffset, \ + GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, \ + GLenum format, GLenum type, GLsizei bufSize, void *pixels); \ + void getTransformFeedbacki64_v(GLuint xfb, GLenum pname, GLuint index, GLint64 *param); \ + void getTransformFeedbacki_v(GLuint xfb, GLenum pname, GLuint index, GLint *param); \ + void getTransformFeedbackiv(GLuint xfb, GLenum pname, GLint *param); \ + void getVertexArrayIndexed64iv(VertexArrayID vaobjPacked, GLuint index, GLenum pname, \ + GLint64 *param); \ + void getVertexArrayIndexediv(VertexArrayID vaobjPacked, GLuint index, GLenum pname, \ + GLint *param); \ + void getVertexArrayiv(VertexArrayID vaobjPacked, GLenum pname, GLint *param); \ + void getnColorTable(GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *table); \ + void getnCompressedTexImage(GLenum target, GLint lod, GLsizei bufSize, void *pixels); \ + void getnConvolutionFilter(GLenum target, GLenum format, GLenum type, GLsizei bufSize, \ + void *image); \ + void getnHistogram(GLenum target, GLboolean reset, GLenum format, GLenum type, \ + GLsizei bufSize, void *values); \ + void getnMapdv(GLenum target, GLenum query, GLsizei bufSize, GLdouble *v); \ + void getnMapfv(GLenum target, GLenum query, GLsizei bufSize, GLfloat *v); \ + void getnMapiv(GLenum target, GLenum query, GLsizei bufSize, GLint *v); \ + void getnMinmax(GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, \ + void *values); \ + void getnPixelMapfv(GLenum map, GLsizei bufSize, GLfloat *values); \ + void getnPixelMapuiv(GLenum map, GLsizei bufSize, GLuint *values); \ + void getnPixelMapusv(GLenum map, GLsizei bufSize, GLushort *values); \ + void getnPolygonStipple(GLsizei bufSize, GLubyte *pattern); \ + void getnSeparableFilter(GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, \ + void *row, GLsizei columnBufSize, void *column, void *span); \ + void getnTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, \ + void *pixels); \ + void getnUniformdv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei bufSize, GLdouble *params); \ + void invalidateNamedFramebufferData(FramebufferID framebufferPacked, GLsizei numAttachments, \ + const GLenum *attachments); \ + void invalidateNamedFramebufferSubData(FramebufferID framebufferPacked, \ + GLsizei numAttachments, const GLenum *attachments, \ + GLint x, GLint y, GLsizei width, GLsizei height); \ + void *mapNamedBuffer(BufferID bufferPacked, GLenum access); \ + void *mapNamedBufferRange(BufferID bufferPacked, GLintptr offset, GLsizeiptr length, \ + GLbitfield access); \ + void namedBufferData(BufferID bufferPacked, GLsizeiptr size, const void *data, GLenum usage); \ + void namedBufferStorage(BufferID bufferPacked, GLsizeiptr size, const void *data, \ + GLbitfield flags); \ + void namedBufferSubData(BufferID bufferPacked, GLintptr offset, GLsizeiptr size, \ + const void *data); \ + void namedFramebufferDrawBuffer(FramebufferID framebufferPacked, GLenum buf); \ + void namedFramebufferDrawBuffers(FramebufferID framebufferPacked, GLsizei n, \ + const GLenum *bufs); \ + void namedFramebufferParameteri(FramebufferID framebufferPacked, GLenum pname, GLint param); \ + void namedFramebufferReadBuffer(FramebufferID framebufferPacked, GLenum src); \ + void namedFramebufferRenderbuffer(FramebufferID framebufferPacked, GLenum attachment, \ + GLenum renderbuffertarget, \ + RenderbufferID renderbufferPacked); \ + void namedFramebufferTexture(FramebufferID framebufferPacked, GLenum attachment, \ + TextureID texturePacked, GLint level); \ + void namedFramebufferTextureLayer(FramebufferID framebufferPacked, GLenum attachment, \ + TextureID texturePacked, GLint level, GLint layer); \ + void namedRenderbufferStorage(RenderbufferID renderbufferPacked, GLenum internalformat, \ + GLsizei width, GLsizei height); \ + void namedRenderbufferStorageMultisample(RenderbufferID renderbufferPacked, GLsizei samples, \ + GLenum internalformat, GLsizei width, \ + GLsizei height); \ + void textureBarrier(); \ + void textureBuffer(TextureID texturePacked, GLenum internalformat, BufferID bufferPacked); \ + void textureBufferRange(TextureID texturePacked, GLenum internalformat, BufferID bufferPacked, \ + GLintptr offset, GLsizeiptr size); \ + void textureParameterIiv(TextureID texturePacked, GLenum pname, const GLint *params); \ + void textureParameterIuiv(TextureID texturePacked, GLenum pname, const GLuint *params); \ + void textureParameterf(TextureID texturePacked, GLenum pname, GLfloat param); \ + void textureParameterfv(TextureID texturePacked, GLenum pname, const GLfloat *param); \ + void textureParameteri(TextureID texturePacked, GLenum pname, GLint param); \ + void textureParameteriv(TextureID texturePacked, GLenum pname, const GLint *param); \ + void textureStorage1D(TextureID texturePacked, GLsizei levels, GLenum internalformat, \ + GLsizei width); \ + void textureStorage2D(TextureID texturePacked, GLsizei levels, GLenum internalformat, \ + GLsizei width, GLsizei height); \ + void textureStorage2DMultisample(TextureID texturePacked, GLsizei samples, \ + GLenum internalformat, GLsizei width, GLsizei height, \ + GLboolean fixedsamplelocations); \ + void textureStorage3D(TextureID texturePacked, GLsizei levels, GLenum internalformat, \ + GLsizei width, GLsizei height, GLsizei depth); \ + void textureStorage3DMultisample(TextureID texturePacked, GLsizei samples, \ + GLenum internalformat, GLsizei width, GLsizei height, \ + GLsizei depth, GLboolean fixedsamplelocations); \ + void textureSubImage1D(TextureID texturePacked, GLint level, GLint xoffset, GLsizei width, \ + GLenum format, GLenum type, const void *pixels); \ + void textureSubImage2D(TextureID texturePacked, GLint level, GLint xoffset, GLint yoffset, \ + GLsizei width, GLsizei height, GLenum format, GLenum type, \ + const void *pixels); \ + void textureSubImage3D(TextureID texturePacked, GLint level, GLint xoffset, GLint yoffset, \ + GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, \ + GLenum format, GLenum type, const void *pixels); \ + void transformFeedbackBufferBase(GLuint xfb, GLuint index, BufferID bufferPacked); \ + void transformFeedbackBufferRange(GLuint xfb, GLuint index, BufferID bufferPacked, \ + GLintptr offset, GLsizeiptr size); \ + GLboolean unmapNamedBuffer(BufferID bufferPacked); \ + void vertexArrayAttribBinding(VertexArrayID vaobjPacked, GLuint attribindex, \ + GLuint bindingindex); \ + void vertexArrayAttribFormat(VertexArrayID vaobjPacked, GLuint attribindex, GLint size, \ + GLenum type, GLboolean normalized, GLuint relativeoffset); \ + void vertexArrayAttribIFormat(VertexArrayID vaobjPacked, GLuint attribindex, GLint size, \ + GLenum type, GLuint relativeoffset); \ + void vertexArrayAttribLFormat(VertexArrayID vaobjPacked, GLuint attribindex, GLint size, \ + GLenum type, GLuint relativeoffset); \ + void vertexArrayBindingDivisor(VertexArrayID vaobjPacked, GLuint bindingindex, \ + GLuint divisor); \ + void vertexArrayElementBuffer(VertexArrayID vaobjPacked, BufferID bufferPacked); \ + void vertexArrayVertexBuffer(VertexArrayID vaobjPacked, GLuint bindingindex, \ + BufferID bufferPacked, GLintptr offset, GLsizei stride); \ + void vertexArrayVertexBuffers(VertexArrayID vaobjPacked, GLuint first, GLsizei count, \ + const BufferID *buffersPacked, const GLintptr *offsets, \ + const GLsizei *strides); \ + void multiDrawArraysIndirectCount(GLenum mode, const void *indirect, GLintptr drawcount, \ + GLsizei maxdrawcount, GLsizei stride); \ + void multiDrawElementsIndirectCount(GLenum mode, GLenum type, const void *indirect, \ + GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); \ + void polygonOffsetClamp(GLfloat factor, GLfloat units, GLfloat clamp); \ + void specializeShader(GLuint shader, const GLchar *pEntryPoint, \ + GLuint numSpecializationConstants, const GLuint *pConstantIndex, \ + const GLuint *pConstantValue); + +#endif // ANGLE_CONTEXT_API_4_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Context_gles_1_0.cpp b/gfx/angle/checkout/src/libANGLE/Context_gles_1_0.cpp new file mode 100644 index 0000000000..611085cfae --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Context_gles_1_0.cpp @@ -0,0 +1,746 @@ +// +// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Context_gles_1_0.cpp: Implements the GLES1-specific parts of Context. + +#include "libANGLE/Context.h" + +#include "common/mathutil.h" +#include "common/utilities.h" + +#include "libANGLE/GLES1Renderer.h" +#include "libANGLE/queryconversions.h" +#include "libANGLE/queryutils.h" + +namespace +{ + +angle::Mat4 FixedMatrixToMat4(const GLfixed *m) +{ + angle::Mat4 matrixAsFloat; + GLfloat *floatData = matrixAsFloat.data(); + + for (int i = 0; i < 16; i++) + { + floatData[i] = gl::ConvertFixedToFloat(m[i]); + } + + return matrixAsFloat; +} + +} // namespace + +namespace gl +{ + +void Context::alphaFunc(AlphaTestFunc func, GLfloat ref) +{ + mState.gles1().setAlphaFunc(func, ref); +} + +void Context::alphaFuncx(AlphaTestFunc func, GLfixed ref) +{ + mState.gles1().setAlphaFunc(func, ConvertFixedToFloat(ref)); +} + +void Context::clearColorx(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha) +{ + mState.setColorClearValue(ConvertFixedToFloat(red), ConvertFixedToFloat(green), + ConvertFixedToFloat(blue), ConvertFixedToFloat(alpha)); +} + +void Context::clearDepthx(GLfixed depth) +{ + mState.setDepthClearValue(clamp01(ConvertFixedToFloat(depth))); +} + +void Context::clientActiveTexture(GLenum texture) +{ + mState.gles1().setClientTextureUnit(texture - GL_TEXTURE0); + mStateCache.onGLES1ClientStateChange(this); +} + +void Context::clipPlanef(GLenum p, const GLfloat *eqn) +{ + mState.gles1().setClipPlane(p - GL_CLIP_PLANE0, eqn); +} + +void Context::clipPlanex(GLenum plane, const GLfixed *equation) +{ + const GLfloat equationf[4] = { + ConvertFixedToFloat(equation[0]), + ConvertFixedToFloat(equation[1]), + ConvertFixedToFloat(equation[2]), + ConvertFixedToFloat(equation[3]), + }; + + mState.gles1().setClipPlane(plane - GL_CLIP_PLANE0, equationf); +} + +void Context::color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) +{ + mState.gles1().setCurrentColor({red, green, blue, alpha}); +} + +void Context::color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) +{ + mState.gles1().setCurrentColor( + {normalizedToFloat(red), normalizedToFloat(green), + normalizedToFloat(blue), normalizedToFloat(alpha)}); +} + +void Context::color4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha) +{ + mState.gles1().setCurrentColor({ConvertFixedToFloat(red), ConvertFixedToFloat(green), + ConvertFixedToFloat(blue), ConvertFixedToFloat(alpha)}); +} + +void Context::colorPointer(GLint size, VertexAttribType type, GLsizei stride, const void *ptr) +{ + // Note that we normalize data for UnsignedByte types. This is to match the behavior + // of current native GLES drivers. + vertexAttribPointer(vertexArrayIndex(ClientVertexArrayType::Color), size, type, + type == VertexAttribType::UnsignedByte, stride, ptr); +} + +void Context::depthRangex(GLfixed n, GLfixed f) +{ + mState.setDepthRange(clamp01(ConvertFixedToFloat(n)), clamp01(ConvertFixedToFloat(f))); +} + +void Context::disableClientState(ClientVertexArrayType clientState) +{ + mState.gles1().setClientStateEnabled(clientState, false); + disableVertexAttribArray(vertexArrayIndex(clientState)); + mStateCache.onGLES1ClientStateChange(this); +} + +void Context::enableClientState(ClientVertexArrayType clientState) +{ + mState.gles1().setClientStateEnabled(clientState, true); + enableVertexAttribArray(vertexArrayIndex(clientState)); + mStateCache.onGLES1ClientStateChange(this); +} + +void Context::fogf(GLenum pname, GLfloat param) +{ + SetFogParameters(&mState.gles1(), pname, ¶m); +} + +void Context::fogfv(GLenum pname, const GLfloat *params) +{ + SetFogParameters(&mState.gles1(), pname, params); +} + +void Context::fogx(GLenum pname, GLfixed param) +{ + if (GetFogParameterCount(pname) == 1) + { + GLfloat paramf = pname == GL_FOG_MODE ? ConvertToGLenum(param) : ConvertFixedToFloat(param); + fogf(pname, paramf); + } + else + { + UNREACHABLE(); + } +} + +void Context::fogxv(GLenum pname, const GLfixed *params) +{ + int paramCount = GetFogParameterCount(pname); + + if (paramCount > 0) + { + GLfloat paramsf[4]; + for (int i = 0; i < paramCount; i++) + { + paramsf[i] = + pname == GL_FOG_MODE ? ConvertToGLenum(params[i]) : ConvertFixedToFloat(params[i]); + } + fogfv(pname, paramsf); + } + else + { + UNREACHABLE(); + } +} + +void Context::frustumf(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f) +{ + mState.gles1().multMatrix(angle::Mat4::Frustum(l, r, b, t, n, f)); +} + +void Context::frustumx(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f) +{ + mState.gles1().multMatrix(angle::Mat4::Frustum(ConvertFixedToFloat(l), ConvertFixedToFloat(r), + ConvertFixedToFloat(b), ConvertFixedToFloat(t), + ConvertFixedToFloat(n), ConvertFixedToFloat(f))); +} + +void Context::getClipPlanef(GLenum plane, GLfloat *equation) +{ + mState.gles1().getClipPlane(plane - GL_CLIP_PLANE0, equation); +} + +void Context::getClipPlanex(GLenum plane, GLfixed *equation) +{ + GLfloat equationf[4] = {}; + + mState.gles1().getClipPlane(plane - GL_CLIP_PLANE0, equationf); + + for (int i = 0; i < 4; i++) + { + equation[i] = ConvertFloatToFixed(equationf[i]); + } +} + +void Context::getFixedv(GLenum pname, GLfixed *params) +{ + GLenum nativeType; + unsigned int numParams = 0; + + getQueryParameterInfo(pname, &nativeType, &numParams); + + std::vector paramsf(numParams, 0); + CastStateValues(this, nativeType, pname, numParams, paramsf.data()); + + for (unsigned int i = 0; i < numParams; i++) + { + params[i] = ConvertFloatToFixed(paramsf[i]); + } +} + +void Context::getLightfv(GLenum light, LightParameter pname, GLfloat *params) +{ + GetLightParameters(&mState.gles1(), light, pname, params); +} + +void Context::getLightxv(GLenum light, LightParameter pname, GLfixed *params) +{ + GLfloat paramsf[4]; + getLightfv(light, pname, paramsf); + + for (unsigned int i = 0; i < GetLightParameterCount(pname); i++) + { + params[i] = ConvertFloatToFixed(paramsf[i]); + } +} + +void Context::getMaterialfv(GLenum face, MaterialParameter pname, GLfloat *params) +{ + GetMaterialParameters(&mState.gles1(), face, pname, params); +} + +void Context::getMaterialxv(GLenum face, MaterialParameter pname, GLfixed *params) +{ + GLfloat paramsf[4]; + getMaterialfv(face, pname, paramsf); + + for (unsigned int i = 0; i < GetMaterialParameterCount(pname); i++) + { + params[i] = ConvertFloatToFixed(paramsf[i]); + } +} + +void Context::getTexEnvfv(TextureEnvTarget target, TextureEnvParameter pname, GLfloat *params) +{ + GetTextureEnv(mState.getActiveSampler(), &mState.gles1(), target, pname, params); +} + +void Context::getTexEnviv(TextureEnvTarget target, TextureEnvParameter pname, GLint *params) +{ + GLfloat paramsf[4]; + GetTextureEnv(mState.getActiveSampler(), &mState.gles1(), target, pname, paramsf); + ConvertTextureEnvToInt(pname, paramsf, params); +} + +void Context::getTexEnvxv(TextureEnvTarget target, TextureEnvParameter pname, GLfixed *params) +{ + GLfloat paramsf[4]; + GetTextureEnv(mState.getActiveSampler(), &mState.gles1(), target, pname, paramsf); + ConvertTextureEnvToFixed(pname, paramsf, params); +} + +void Context::getTexParameterxv(TextureType target, GLenum pname, GLfixed *params) +{ + const Texture *const texture = getTextureByType(target); + QueryTexParameterxv(this, texture, pname, params); +} + +void Context::lightModelf(GLenum pname, GLfloat param) +{ + SetLightModelParameters(&mState.gles1(), pname, ¶m); +} + +void Context::lightModelfv(GLenum pname, const GLfloat *params) +{ + SetLightModelParameters(&mState.gles1(), pname, params); +} + +void Context::lightModelx(GLenum pname, GLfixed param) +{ + lightModelf(pname, ConvertFixedToFloat(param)); +} + +void Context::lightModelxv(GLenum pname, const GLfixed *param) +{ + GLfloat paramsf[4]; + + for (unsigned int i = 0; i < GetLightModelParameterCount(pname); i++) + { + paramsf[i] = ConvertFixedToFloat(param[i]); + } + + lightModelfv(pname, paramsf); +} + +void Context::lightf(GLenum light, LightParameter pname, GLfloat param) +{ + SetLightParameters(&mState.gles1(), light, pname, ¶m); +} + +void Context::lightfv(GLenum light, LightParameter pname, const GLfloat *params) +{ + SetLightParameters(&mState.gles1(), light, pname, params); +} + +void Context::lightx(GLenum light, LightParameter pname, GLfixed param) +{ + lightf(light, pname, ConvertFixedToFloat(param)); +} + +void Context::lightxv(GLenum light, LightParameter pname, const GLfixed *params) +{ + GLfloat paramsf[4]; + + for (unsigned int i = 0; i < GetLightParameterCount(pname); i++) + { + paramsf[i] = ConvertFixedToFloat(params[i]); + } + + lightfv(light, pname, paramsf); +} + +void Context::lineWidthx(GLfixed width) +{ + mState.setLineWidth(ConvertFixedToFloat(width)); +} + +void Context::loadIdentity() +{ + mState.gles1().loadMatrix(angle::Mat4()); +} + +void Context::loadMatrixf(const GLfloat *m) +{ + mState.gles1().loadMatrix(angle::Mat4(m)); +} + +void Context::loadMatrixx(const GLfixed *m) +{ + mState.gles1().loadMatrix(FixedMatrixToMat4(m)); +} + +void Context::logicOp(LogicalOperation opcodePacked) +{ + mState.gles1().setLogicOp(opcodePacked); +} + +void Context::materialf(GLenum face, MaterialParameter pname, GLfloat param) +{ + SetMaterialParameters(&mState.gles1(), face, pname, ¶m); +} + +void Context::materialfv(GLenum face, MaterialParameter pname, const GLfloat *params) +{ + SetMaterialParameters(&mState.gles1(), face, pname, params); +} + +void Context::materialx(GLenum face, MaterialParameter pname, GLfixed param) +{ + materialf(face, pname, ConvertFixedToFloat(param)); +} + +void Context::materialxv(GLenum face, MaterialParameter pname, const GLfixed *param) +{ + GLfloat paramsf[4]; + + for (unsigned int i = 0; i < GetMaterialParameterCount(pname); i++) + { + paramsf[i] = ConvertFixedToFloat(param[i]); + } + + materialfv(face, pname, paramsf); +} + +void Context::matrixMode(MatrixType mode) +{ + mState.gles1().setMatrixMode(mode); +} + +void Context::multMatrixf(const GLfloat *m) +{ + mState.gles1().multMatrix(angle::Mat4(m)); +} + +void Context::multMatrixx(const GLfixed *m) +{ + mState.gles1().multMatrix(FixedMatrixToMat4(m)); +} + +void Context::multiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) +{ + unsigned int unit = target - GL_TEXTURE0; + ASSERT(target >= GL_TEXTURE0 && unit < getCaps().maxMultitextureUnits); + mState.gles1().setCurrentTextureCoords(unit, {s, t, r, q}); +} + +void Context::multiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q) +{ + unsigned int unit = target - GL_TEXTURE0; + ASSERT(target >= GL_TEXTURE0 && unit < getCaps().maxMultitextureUnits); + mState.gles1().setCurrentTextureCoords(unit, {ConvertFixedToFloat(s), ConvertFixedToFloat(t), + ConvertFixedToFloat(r), ConvertFixedToFloat(q)}); +} + +void Context::normal3f(GLfloat nx, GLfloat ny, GLfloat nz) +{ + mState.gles1().setCurrentNormal({nx, ny, nz}); +} + +void Context::normal3x(GLfixed nx, GLfixed ny, GLfixed nz) +{ + mState.gles1().setCurrentNormal( + {ConvertFixedToFloat(nx), ConvertFixedToFloat(ny), ConvertFixedToFloat(nz)}); +} + +void Context::normalPointer(VertexAttribType type, GLsizei stride, const void *ptr) +{ + vertexAttribPointer(vertexArrayIndex(ClientVertexArrayType::Normal), 3, type, GL_FALSE, stride, + ptr); +} + +void Context::orthof(GLfloat left, + GLfloat right, + GLfloat bottom, + GLfloat top, + GLfloat zNear, + GLfloat zFar) +{ + mState.gles1().multMatrix(angle::Mat4::Ortho(left, right, bottom, top, zNear, zFar)); +} + +void Context::orthox(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f) +{ + mState.gles1().multMatrix(angle::Mat4::Ortho(ConvertFixedToFloat(l), ConvertFixedToFloat(r), + ConvertFixedToFloat(b), ConvertFixedToFloat(t), + ConvertFixedToFloat(n), ConvertFixedToFloat(f))); +} + +void Context::pointParameterf(PointParameter pname, GLfloat param) +{ + SetPointParameter(&mState.gles1(), pname, ¶m); +} + +void Context::pointParameterfv(PointParameter pname, const GLfloat *params) +{ + SetPointParameter(&mState.gles1(), pname, params); +} + +void Context::pointParameterx(PointParameter pname, GLfixed param) +{ + GLfloat paramf = ConvertFixedToFloat(param); + SetPointParameter(&mState.gles1(), pname, ¶mf); +} + +void Context::pointParameterxv(PointParameter pname, const GLfixed *params) +{ + GLfloat paramsf[4] = {}; + for (unsigned int i = 0; i < GetPointParameterCount(pname); i++) + { + paramsf[i] = ConvertFixedToFloat(params[i]); + } + SetPointParameter(&mState.gles1(), pname, paramsf); +} + +void Context::pointSize(GLfloat size) +{ + SetPointSize(&mState.gles1(), size); +} + +void Context::pointSizex(GLfixed size) +{ + SetPointSize(&mState.gles1(), ConvertFixedToFloat(size)); +} + +void Context::polygonOffsetx(GLfixed factor, GLfixed units) +{ + mState.setPolygonOffsetParams(ConvertFixedToFloat(factor), ConvertFixedToFloat(units)); +} + +void Context::popMatrix() +{ + mState.gles1().popMatrix(); +} + +void Context::pushMatrix() +{ + mState.gles1().pushMatrix(); +} + +void Context::rotatef(float angle, float x, float y, float z) +{ + mState.gles1().multMatrix(angle::Mat4::Rotate(angle, angle::Vector3(x, y, z))); +} + +void Context::rotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z) +{ + mState.gles1().multMatrix(angle::Mat4::Rotate( + ConvertFixedToFloat(angle), + angle::Vector3(ConvertFixedToFloat(x), ConvertFixedToFloat(y), ConvertFixedToFloat(z)))); +} + +void Context::sampleCoveragex(GLclampx value, GLboolean invert) +{ + GLclampf valuef = ConvertFixedToFloat(value); + mState.setSampleCoverageParams(clamp01(valuef), ConvertToBool(invert)); +} + +void Context::scalef(float x, float y, float z) +{ + mState.gles1().multMatrix(angle::Mat4::Scale(angle::Vector3(x, y, z))); +} + +void Context::scalex(GLfixed x, GLfixed y, GLfixed z) +{ + mState.gles1().multMatrix(angle::Mat4::Scale( + angle::Vector3(ConvertFixedToFloat(x), ConvertFixedToFloat(y), ConvertFixedToFloat(z)))); +} + +void Context::shadeModel(ShadingModel model) +{ + mState.gles1().setShadeModel(model); +} + +void Context::texCoordPointer(GLint size, VertexAttribType type, GLsizei stride, const void *ptr) +{ + vertexAttribPointer(vertexArrayIndex(ClientVertexArrayType::TextureCoord), size, type, GL_FALSE, + stride, ptr); +} + +void Context::texEnvf(TextureEnvTarget target, TextureEnvParameter pname, GLfloat param) +{ + SetTextureEnv(mState.getActiveSampler(), &mState.gles1(), target, pname, ¶m); +} + +void Context::texEnvfv(TextureEnvTarget target, TextureEnvParameter pname, const GLfloat *params) +{ + SetTextureEnv(mState.getActiveSampler(), &mState.gles1(), target, pname, params); +} + +void Context::texEnvi(TextureEnvTarget target, TextureEnvParameter pname, GLint param) +{ + GLfloat paramsf[4] = {}; + ConvertTextureEnvFromInt(pname, ¶m, paramsf); + SetTextureEnv(mState.getActiveSampler(), &mState.gles1(), target, pname, paramsf); +} + +void Context::texEnviv(TextureEnvTarget target, TextureEnvParameter pname, const GLint *params) +{ + GLfloat paramsf[4] = {}; + ConvertTextureEnvFromInt(pname, params, paramsf); + SetTextureEnv(mState.getActiveSampler(), &mState.gles1(), target, pname, paramsf); +} + +void Context::texEnvx(TextureEnvTarget target, TextureEnvParameter pname, GLfixed param) +{ + GLfloat paramsf[4] = {}; + ConvertTextureEnvFromFixed(pname, ¶m, paramsf); + SetTextureEnv(mState.getActiveSampler(), &mState.gles1(), target, pname, paramsf); +} + +void Context::texEnvxv(TextureEnvTarget target, TextureEnvParameter pname, const GLfixed *params) +{ + GLfloat paramsf[4] = {}; + ConvertTextureEnvFromFixed(pname, params, paramsf); + SetTextureEnv(mState.getActiveSampler(), &mState.gles1(), target, pname, paramsf); +} + +void Context::texParameterx(TextureType target, GLenum pname, GLfixed param) +{ + Texture *const texture = getTextureByType(target); + SetTexParameterx(this, texture, pname, param); +} + +void Context::texParameterxv(TextureType target, GLenum pname, const GLfixed *params) +{ + Texture *const texture = getTextureByType(target); + SetTexParameterxv(this, texture, pname, params); +} + +void Context::translatef(float x, float y, float z) +{ + mState.gles1().multMatrix(angle::Mat4::Translate(angle::Vector3(x, y, z))); +} + +void Context::translatex(GLfixed x, GLfixed y, GLfixed z) +{ + mState.gles1().multMatrix(angle::Mat4::Translate( + angle::Vector3(ConvertFixedToFloat(x), ConvertFixedToFloat(y), ConvertFixedToFloat(z)))); +} + +void Context::vertexPointer(GLint size, VertexAttribType type, GLsizei stride, const void *ptr) +{ + vertexAttribPointer(vertexArrayIndex(ClientVertexArrayType::Vertex), size, type, GL_FALSE, + stride, ptr); +} + +// GL_OES_draw_texture +void Context::drawTexf(float x, float y, float z, float width, float height) +{ + mGLES1Renderer->drawTexture(this, &mState, x, y, z, width, height); +} + +void Context::drawTexfv(const GLfloat *coords) +{ + mGLES1Renderer->drawTexture(this, &mState, coords[0], coords[1], coords[2], coords[3], + coords[4]); +} + +void Context::drawTexi(GLint x, GLint y, GLint z, GLint width, GLint height) +{ + mGLES1Renderer->drawTexture(this, &mState, static_cast(x), static_cast(y), + static_cast(z), static_cast(width), + static_cast(height)); +} + +void Context::drawTexiv(const GLint *coords) +{ + mGLES1Renderer->drawTexture(this, &mState, static_cast(coords[0]), + static_cast(coords[1]), static_cast(coords[2]), + static_cast(coords[3]), static_cast(coords[4])); +} + +void Context::drawTexs(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height) +{ + mGLES1Renderer->drawTexture(this, &mState, static_cast(x), static_cast(y), + static_cast(z), static_cast(width), + static_cast(height)); +} + +void Context::drawTexsv(const GLshort *coords) +{ + mGLES1Renderer->drawTexture(this, &mState, static_cast(coords[0]), + static_cast(coords[1]), static_cast(coords[2]), + static_cast(coords[3]), static_cast(coords[4])); +} + +void Context::drawTexx(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height) +{ + mGLES1Renderer->drawTexture(this, &mState, ConvertFixedToFloat(x), ConvertFixedToFloat(y), + ConvertFixedToFloat(z), ConvertFixedToFloat(width), + ConvertFixedToFloat(height)); +} + +void Context::drawTexxv(const GLfixed *coords) +{ + mGLES1Renderer->drawTexture(this, &mState, ConvertFixedToFloat(coords[0]), + ConvertFixedToFloat(coords[1]), ConvertFixedToFloat(coords[2]), + ConvertFixedToFloat(coords[3]), ConvertFixedToFloat(coords[4])); +} + +// GL_OES_matrix_palette +void Context::currentPaletteMatrix(GLuint matrixpaletteindex) +{ + UNIMPLEMENTED(); +} + +void Context::loadPaletteFromModelViewMatrix() +{ + UNIMPLEMENTED(); +} + +void Context::matrixIndexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) +{ + UNIMPLEMENTED(); +} + +void Context::weightPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) +{ + UNIMPLEMENTED(); +} + +// GL_OES_point_size_array +void Context::pointSizePointer(VertexAttribType type, GLsizei stride, const void *ptr) +{ + vertexAttribPointer(vertexArrayIndex(ClientVertexArrayType::PointSize), 1, type, GL_FALSE, + stride, ptr); +} + +// GL_OES_query_matrix +GLbitfield Context::queryMatrixx(GLfixed *mantissa, GLint *exponent) +{ + UNIMPLEMENTED(); + return 0; +} + +// GL_OES_texture_cube_map +void Context::getTexGenfv(GLenum coord, GLenum pname, GLfloat *params) +{ + UNIMPLEMENTED(); +} + +void Context::getTexGeniv(GLenum coord, GLenum pname, GLint *params) +{ + UNIMPLEMENTED(); +} + +void Context::getTexGenxv(GLenum coord, GLenum pname, GLfixed *params) +{ + UNIMPLEMENTED(); +} + +void Context::texGenf(GLenum coord, GLenum pname, GLfloat param) +{ + UNIMPLEMENTED(); +} + +void Context::texGenfv(GLenum coord, GLenum pname, const GLfloat *params) +{ + UNIMPLEMENTED(); +} + +void Context::texGeni(GLenum coord, GLenum pname, GLint param) +{ + UNIMPLEMENTED(); +} + +void Context::texGeniv(GLenum coord, GLenum pname, const GLint *params) +{ + UNIMPLEMENTED(); +} + +void Context::texGenx(GLenum coord, GLenum pname, GLfixed param) +{ + UNIMPLEMENTED(); +} + +void Context::texGenxv(GLenum coord, GLenum pname, const GLint *params) +{ + UNIMPLEMENTED(); +} + +int Context::vertexArrayIndex(ClientVertexArrayType type) const +{ + return GLES1Renderer::VertexArrayIndex(type, mState.gles1()); +} + +// static +int Context::TexCoordArrayIndex(unsigned int unit) +{ + return GLES1Renderer::TexCoordArrayIndex(unit); +} +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/Context_gles_1_0_autogen.h b/gfx/angle/checkout/src/libANGLE/Context_gles_1_0_autogen.h new file mode 100644 index 0000000000..77f1a9afce --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Context_gles_1_0_autogen.h @@ -0,0 +1,109 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Context_gles_1_0_autogen.h: Creates a macro for interfaces in Context. + +#ifndef ANGLE_CONTEXT_GLES_1_0_AUTOGEN_H_ +#define ANGLE_CONTEXT_GLES_1_0_AUTOGEN_H_ + +#define ANGLE_GLES_1_0_CONTEXT_API \ + void alphaFunc(AlphaTestFunc funcPacked, GLfloat ref); \ + void alphaFuncx(AlphaTestFunc funcPacked, GLfixed ref); \ + void clearColorx(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); \ + void clearDepthx(GLfixed depth); \ + void clientActiveTexture(GLenum texture); \ + void clipPlanef(GLenum p, const GLfloat *eqn); \ + void clipPlanex(GLenum plane, const GLfixed *equation); \ + void color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); \ + void color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); \ + void color4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); \ + void colorPointer(GLint size, VertexAttribType typePacked, GLsizei stride, \ + const void *pointer); \ + void depthRangex(GLfixed n, GLfixed f); \ + void disableClientState(ClientVertexArrayType arrayPacked); \ + void enableClientState(ClientVertexArrayType arrayPacked); \ + void fogf(GLenum pname, GLfloat param); \ + void fogfv(GLenum pname, const GLfloat *params); \ + void fogx(GLenum pname, GLfixed param); \ + void fogxv(GLenum pname, const GLfixed *param); \ + void frustumf(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); \ + void frustumx(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); \ + void getClipPlanef(GLenum plane, GLfloat *equation); \ + void getClipPlanex(GLenum plane, GLfixed *equation); \ + void getFixedv(GLenum pname, GLfixed *params); \ + void getLightfv(GLenum light, LightParameter pnamePacked, GLfloat *params); \ + void getLightxv(GLenum light, LightParameter pnamePacked, GLfixed *params); \ + void getMaterialfv(GLenum face, MaterialParameter pnamePacked, GLfloat *params); \ + void getMaterialxv(GLenum face, MaterialParameter pnamePacked, GLfixed *params); \ + void getTexEnvfv(TextureEnvTarget targetPacked, TextureEnvParameter pnamePacked, \ + GLfloat *params); \ + void getTexEnviv(TextureEnvTarget targetPacked, TextureEnvParameter pnamePacked, \ + GLint *params); \ + void getTexEnvxv(TextureEnvTarget targetPacked, TextureEnvParameter pnamePacked, \ + GLfixed *params); \ + void getTexParameterxv(TextureType targetPacked, GLenum pname, GLfixed *params); \ + void lightModelf(GLenum pname, GLfloat param); \ + void lightModelfv(GLenum pname, const GLfloat *params); \ + void lightModelx(GLenum pname, GLfixed param); \ + void lightModelxv(GLenum pname, const GLfixed *param); \ + void lightf(GLenum light, LightParameter pnamePacked, GLfloat param); \ + void lightfv(GLenum light, LightParameter pnamePacked, const GLfloat *params); \ + void lightx(GLenum light, LightParameter pnamePacked, GLfixed param); \ + void lightxv(GLenum light, LightParameter pnamePacked, const GLfixed *params); \ + void lineWidthx(GLfixed width); \ + void loadIdentity(); \ + void loadMatrixf(const GLfloat *m); \ + void loadMatrixx(const GLfixed *m); \ + void logicOp(LogicalOperation opcodePacked); \ + void materialf(GLenum face, MaterialParameter pnamePacked, GLfloat param); \ + void materialfv(GLenum face, MaterialParameter pnamePacked, const GLfloat *params); \ + void materialx(GLenum face, MaterialParameter pnamePacked, GLfixed param); \ + void materialxv(GLenum face, MaterialParameter pnamePacked, const GLfixed *param); \ + void matrixMode(MatrixType modePacked); \ + void multMatrixf(const GLfloat *m); \ + void multMatrixx(const GLfixed *m); \ + void multiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); \ + void multiTexCoord4x(GLenum texture, GLfixed s, GLfixed t, GLfixed r, GLfixed q); \ + void normal3f(GLfloat nx, GLfloat ny, GLfloat nz); \ + void normal3x(GLfixed nx, GLfixed ny, GLfixed nz); \ + void normalPointer(VertexAttribType typePacked, GLsizei stride, const void *pointer); \ + void orthof(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); \ + void orthox(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); \ + void pointParameterf(PointParameter pnamePacked, GLfloat param); \ + void pointParameterfv(PointParameter pnamePacked, const GLfloat *params); \ + void pointParameterx(PointParameter pnamePacked, GLfixed param); \ + void pointParameterxv(PointParameter pnamePacked, const GLfixed *params); \ + void pointSize(GLfloat size); \ + void pointSizex(GLfixed size); \ + void polygonOffsetx(GLfixed factor, GLfixed units); \ + void popMatrix(); \ + void pushMatrix(); \ + void rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); \ + void rotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z); \ + void sampleCoveragex(GLclampx value, GLboolean invert); \ + void scalef(GLfloat x, GLfloat y, GLfloat z); \ + void scalex(GLfixed x, GLfixed y, GLfixed z); \ + void shadeModel(ShadingModel modePacked); \ + void texCoordPointer(GLint size, VertexAttribType typePacked, GLsizei stride, \ + const void *pointer); \ + void texEnvf(TextureEnvTarget targetPacked, TextureEnvParameter pnamePacked, GLfloat param); \ + void texEnvfv(TextureEnvTarget targetPacked, TextureEnvParameter pnamePacked, \ + const GLfloat *params); \ + void texEnvi(TextureEnvTarget targetPacked, TextureEnvParameter pnamePacked, GLint param); \ + void texEnviv(TextureEnvTarget targetPacked, TextureEnvParameter pnamePacked, \ + const GLint *params); \ + void texEnvx(TextureEnvTarget targetPacked, TextureEnvParameter pnamePacked, GLfixed param); \ + void texEnvxv(TextureEnvTarget targetPacked, TextureEnvParameter pnamePacked, \ + const GLfixed *params); \ + void texParameterx(TextureType targetPacked, GLenum pname, GLfixed param); \ + void texParameterxv(TextureType targetPacked, GLenum pname, const GLfixed *params); \ + void translatef(GLfloat x, GLfloat y, GLfloat z); \ + void translatex(GLfixed x, GLfixed y, GLfixed z); \ + void vertexPointer(GLint size, VertexAttribType typePacked, GLsizei stride, \ + const void *pointer); + +#endif // ANGLE_CONTEXT_API_1_0_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Context_gles_2_0_autogen.h b/gfx/angle/checkout/src/libANGLE/Context_gles_2_0_autogen.h new file mode 100644 index 0000000000..1c0501eaf3 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Context_gles_2_0_autogen.h @@ -0,0 +1,190 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Context_gles_2_0_autogen.h: Creates a macro for interfaces in Context. + +#ifndef ANGLE_CONTEXT_GLES_2_0_AUTOGEN_H_ +#define ANGLE_CONTEXT_GLES_2_0_AUTOGEN_H_ + +#define ANGLE_GLES_2_0_CONTEXT_API \ + void activeTexture(GLenum texture); \ + void attachShader(ShaderProgramID programPacked, ShaderProgramID shaderPacked); \ + void bindAttribLocation(ShaderProgramID programPacked, GLuint index, const GLchar *name); \ + void bindBuffer(BufferBinding targetPacked, BufferID bufferPacked); \ + void bindFramebuffer(GLenum target, FramebufferID framebufferPacked); \ + void bindRenderbuffer(GLenum target, RenderbufferID renderbufferPacked); \ + void bindTexture(TextureType targetPacked, TextureID texturePacked); \ + void blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); \ + void blendEquation(GLenum mode); \ + void blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha); \ + void blendFunc(GLenum sfactor, GLenum dfactor); \ + void blendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, \ + GLenum dfactorAlpha); \ + void bufferData(BufferBinding targetPacked, GLsizeiptr size, const void *data, \ + BufferUsage usagePacked); \ + void bufferSubData(BufferBinding targetPacked, GLintptr offset, GLsizeiptr size, \ + const void *data); \ + GLenum checkFramebufferStatus(GLenum target); \ + void clear(GLbitfield mask); \ + void clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); \ + void clearDepthf(GLfloat d); \ + void clearStencil(GLint s); \ + void colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); \ + void compileShader(ShaderProgramID shaderPacked); \ + void compressedTexImage2D(TextureTarget targetPacked, GLint level, GLenum internalformat, \ + GLsizei width, GLsizei height, GLint border, GLsizei imageSize, \ + const void *data); \ + void compressedTexSubImage2D(TextureTarget targetPacked, GLint level, GLint xoffset, \ + GLint yoffset, GLsizei width, GLsizei height, GLenum format, \ + GLsizei imageSize, const void *data); \ + void copyTexImage2D(TextureTarget targetPacked, GLint level, GLenum internalformat, GLint x, \ + GLint y, GLsizei width, GLsizei height, GLint border); \ + void copyTexSubImage2D(TextureTarget targetPacked, GLint level, GLint xoffset, GLint yoffset, \ + GLint x, GLint y, GLsizei width, GLsizei height); \ + GLuint createProgram(); \ + GLuint createShader(ShaderType typePacked); \ + void cullFace(CullFaceMode modePacked); \ + void deleteBuffers(GLsizei n, const BufferID *buffersPacked); \ + void deleteFramebuffers(GLsizei n, const FramebufferID *framebuffersPacked); \ + void deleteProgram(ShaderProgramID programPacked); \ + void deleteRenderbuffers(GLsizei n, const RenderbufferID *renderbuffersPacked); \ + void deleteShader(ShaderProgramID shaderPacked); \ + void deleteTextures(GLsizei n, const TextureID *texturesPacked); \ + void depthFunc(GLenum func); \ + void depthMask(GLboolean flag); \ + void depthRangef(GLfloat n, GLfloat f); \ + void detachShader(ShaderProgramID programPacked, ShaderProgramID shaderPacked); \ + void disable(GLenum cap); \ + void disableVertexAttribArray(GLuint index); \ + void drawArrays(PrimitiveMode modePacked, GLint first, GLsizei count); \ + void drawElements(PrimitiveMode modePacked, GLsizei count, DrawElementsType typePacked, \ + const void *indices); \ + void enable(GLenum cap); \ + void enableVertexAttribArray(GLuint index); \ + void finish(); \ + void flush(); \ + void framebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, \ + RenderbufferID renderbufferPacked); \ + void framebufferTexture2D(GLenum target, GLenum attachment, TextureTarget textargetPacked, \ + TextureID texturePacked, GLint level); \ + void frontFace(GLenum mode); \ + void genBuffers(GLsizei n, BufferID *buffersPacked); \ + void genFramebuffers(GLsizei n, FramebufferID *framebuffersPacked); \ + void genRenderbuffers(GLsizei n, RenderbufferID *renderbuffersPacked); \ + void genTextures(GLsizei n, TextureID *texturesPacked); \ + void generateMipmap(TextureType targetPacked); \ + void getActiveAttrib(ShaderProgramID programPacked, GLuint index, GLsizei bufSize, \ + GLsizei *length, GLint *size, GLenum *type, GLchar *name); \ + void getActiveUniform(ShaderProgramID programPacked, GLuint index, GLsizei bufSize, \ + GLsizei *length, GLint *size, GLenum *type, GLchar *name); \ + void getAttachedShaders(ShaderProgramID programPacked, GLsizei maxCount, GLsizei *count, \ + ShaderProgramID *shadersPacked); \ + GLint getAttribLocation(ShaderProgramID programPacked, const GLchar *name); \ + void getBooleanv(GLenum pname, GLboolean *data); \ + void getBufferParameteriv(BufferBinding targetPacked, GLenum pname, GLint *params); \ + GLenum getError(); \ + void getFloatv(GLenum pname, GLfloat *data); \ + void getFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, \ + GLint *params); \ + void getIntegerv(GLenum pname, GLint *data); \ + void getProgramInfoLog(ShaderProgramID programPacked, GLsizei bufSize, GLsizei *length, \ + GLchar *infoLog); \ + void getProgramiv(ShaderProgramID programPacked, GLenum pname, GLint *params); \ + void getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params); \ + void getShaderInfoLog(ShaderProgramID shaderPacked, GLsizei bufSize, GLsizei *length, \ + GLchar *infoLog); \ + void getShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint *range, \ + GLint *precision); \ + void getShaderSource(ShaderProgramID shaderPacked, GLsizei bufSize, GLsizei *length, \ + GLchar *source); \ + void getShaderiv(ShaderProgramID shaderPacked, GLenum pname, GLint *params); \ + const GLubyte *getString(GLenum name); \ + void getTexParameterfv(TextureType targetPacked, GLenum pname, GLfloat *params); \ + void getTexParameteriv(TextureType targetPacked, GLenum pname, GLint *params); \ + GLint getUniformLocation(ShaderProgramID programPacked, const GLchar *name); \ + void getUniformfv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLfloat *params); \ + void getUniformiv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLint *params); \ + void getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer); \ + void getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params); \ + void getVertexAttribiv(GLuint index, GLenum pname, GLint *params); \ + void hint(GLenum target, GLenum mode); \ + GLboolean isBuffer(BufferID bufferPacked) const; \ + GLboolean isEnabled(GLenum cap) const; \ + GLboolean isFramebuffer(FramebufferID framebufferPacked) const; \ + GLboolean isProgram(ShaderProgramID programPacked) const; \ + GLboolean isRenderbuffer(RenderbufferID renderbufferPacked) const; \ + GLboolean isShader(ShaderProgramID shaderPacked) const; \ + GLboolean isTexture(TextureID texturePacked) const; \ + void lineWidth(GLfloat width); \ + void linkProgram(ShaderProgramID programPacked); \ + void pixelStorei(GLenum pname, GLint param); \ + void polygonOffset(GLfloat factor, GLfloat units); \ + void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, \ + void *pixels); \ + void releaseShaderCompiler(); \ + void renderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); \ + void sampleCoverage(GLfloat value, GLboolean invert); \ + void scissor(GLint x, GLint y, GLsizei width, GLsizei height); \ + void shaderBinary(GLsizei count, const ShaderProgramID *shadersPacked, GLenum binaryFormat, \ + const void *binary, GLsizei length); \ + void shaderSource(ShaderProgramID shaderPacked, GLsizei count, const GLchar *const *string, \ + const GLint *length); \ + void stencilFunc(GLenum func, GLint ref, GLuint mask); \ + void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask); \ + void stencilMask(GLuint mask); \ + void stencilMaskSeparate(GLenum face, GLuint mask); \ + void stencilOp(GLenum fail, GLenum zfail, GLenum zpass); \ + void stencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); \ + void texImage2D(TextureTarget targetPacked, GLint level, GLint internalformat, GLsizei width, \ + GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); \ + void texParameterf(TextureType targetPacked, GLenum pname, GLfloat param); \ + void texParameterfv(TextureType targetPacked, GLenum pname, const GLfloat *params); \ + void texParameteri(TextureType targetPacked, GLenum pname, GLint param); \ + void texParameteriv(TextureType targetPacked, GLenum pname, const GLint *params); \ + void texSubImage2D(TextureTarget targetPacked, GLint level, GLint xoffset, GLint yoffset, \ + GLsizei width, GLsizei height, GLenum format, GLenum type, \ + const void *pixels); \ + void uniform1f(UniformLocation locationPacked, GLfloat v0); \ + void uniform1fv(UniformLocation locationPacked, GLsizei count, const GLfloat *value); \ + void uniform1i(UniformLocation locationPacked, GLint v0); \ + void uniform1iv(UniformLocation locationPacked, GLsizei count, const GLint *value); \ + void uniform2f(UniformLocation locationPacked, GLfloat v0, GLfloat v1); \ + void uniform2fv(UniformLocation locationPacked, GLsizei count, const GLfloat *value); \ + void uniform2i(UniformLocation locationPacked, GLint v0, GLint v1); \ + void uniform2iv(UniformLocation locationPacked, GLsizei count, const GLint *value); \ + void uniform3f(UniformLocation locationPacked, GLfloat v0, GLfloat v1, GLfloat v2); \ + void uniform3fv(UniformLocation locationPacked, GLsizei count, const GLfloat *value); \ + void uniform3i(UniformLocation locationPacked, GLint v0, GLint v1, GLint v2); \ + void uniform3iv(UniformLocation locationPacked, GLsizei count, const GLint *value); \ + void uniform4f(UniformLocation locationPacked, GLfloat v0, GLfloat v1, GLfloat v2, \ + GLfloat v3); \ + void uniform4fv(UniformLocation locationPacked, GLsizei count, const GLfloat *value); \ + void uniform4i(UniformLocation locationPacked, GLint v0, GLint v1, GLint v2, GLint v3); \ + void uniform4iv(UniformLocation locationPacked, GLsizei count, const GLint *value); \ + void uniformMatrix2fv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \ + const GLfloat *value); \ + void uniformMatrix3fv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \ + const GLfloat *value); \ + void uniformMatrix4fv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \ + const GLfloat *value); \ + void useProgram(ShaderProgramID programPacked); \ + void validateProgram(ShaderProgramID programPacked); \ + void vertexAttrib1f(GLuint index, GLfloat x); \ + void vertexAttrib1fv(GLuint index, const GLfloat *v); \ + void vertexAttrib2f(GLuint index, GLfloat x, GLfloat y); \ + void vertexAttrib2fv(GLuint index, const GLfloat *v); \ + void vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z); \ + void vertexAttrib3fv(GLuint index, const GLfloat *v); \ + void vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); \ + void vertexAttrib4fv(GLuint index, const GLfloat *v); \ + void vertexAttribPointer(GLuint index, GLint size, VertexAttribType typePacked, \ + GLboolean normalized, GLsizei stride, const void *pointer); \ + void viewport(GLint x, GLint y, GLsizei width, GLsizei height); + +#endif // ANGLE_CONTEXT_API_2_0_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Context_gles_3_0_autogen.h b/gfx/angle/checkout/src/libANGLE/Context_gles_3_0_autogen.h new file mode 100644 index 0000000000..f87f49f43d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Context_gles_3_0_autogen.h @@ -0,0 +1,164 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Context_gles_3_0_autogen.h: Creates a macro for interfaces in Context. + +#ifndef ANGLE_CONTEXT_GLES_3_0_AUTOGEN_H_ +#define ANGLE_CONTEXT_GLES_3_0_AUTOGEN_H_ + +#define ANGLE_GLES_3_0_CONTEXT_API \ + void beginQuery(QueryType targetPacked, QueryID idPacked); \ + void beginTransformFeedback(PrimitiveMode primitiveModePacked); \ + void bindBufferBase(BufferBinding targetPacked, GLuint index, BufferID bufferPacked); \ + void bindBufferRange(BufferBinding targetPacked, GLuint index, BufferID bufferPacked, \ + GLintptr offset, GLsizeiptr size); \ + void bindSampler(GLuint unit, SamplerID samplerPacked); \ + void bindTransformFeedback(GLenum target, TransformFeedbackID idPacked); \ + void bindVertexArray(VertexArrayID arrayPacked); \ + void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, \ + GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); \ + void clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); \ + void clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value); \ + void clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value); \ + void clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value); \ + GLenum clientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout); \ + void compressedTexImage3D(TextureTarget targetPacked, GLint level, GLenum internalformat, \ + GLsizei width, GLsizei height, GLsizei depth, GLint border, \ + GLsizei imageSize, const void *data); \ + void compressedTexSubImage3D(TextureTarget targetPacked, GLint level, GLint xoffset, \ + GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, \ + GLsizei depth, GLenum format, GLsizei imageSize, \ + const void *data); \ + void copyBufferSubData(BufferBinding readTargetPacked, BufferBinding writeTargetPacked, \ + GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); \ + void copyTexSubImage3D(TextureTarget targetPacked, GLint level, GLint xoffset, GLint yoffset, \ + GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); \ + void deleteQueries(GLsizei n, const QueryID *idsPacked); \ + void deleteSamplers(GLsizei count, const SamplerID *samplersPacked); \ + void deleteSync(GLsync sync); \ + void deleteTransformFeedbacks(GLsizei n, const TransformFeedbackID *idsPacked); \ + void deleteVertexArrays(GLsizei n, const VertexArrayID *arraysPacked); \ + void drawArraysInstanced(PrimitiveMode modePacked, GLint first, GLsizei count, \ + GLsizei instancecount); \ + void drawBuffers(GLsizei n, const GLenum *bufs); \ + void drawElementsInstanced(PrimitiveMode modePacked, GLsizei count, \ + DrawElementsType typePacked, const void *indices, \ + GLsizei instancecount); \ + void drawRangeElements(PrimitiveMode modePacked, GLuint start, GLuint end, GLsizei count, \ + DrawElementsType typePacked, const void *indices); \ + void endQuery(QueryType targetPacked); \ + void endTransformFeedback(); \ + GLsync fenceSync(GLenum condition, GLbitfield flags); \ + void flushMappedBufferRange(BufferBinding targetPacked, GLintptr offset, GLsizeiptr length); \ + void framebufferTextureLayer(GLenum target, GLenum attachment, TextureID texturePacked, \ + GLint level, GLint layer); \ + void genQueries(GLsizei n, QueryID *idsPacked); \ + void genSamplers(GLsizei count, SamplerID *samplersPacked); \ + void genTransformFeedbacks(GLsizei n, TransformFeedbackID *idsPacked); \ + void genVertexArrays(GLsizei n, VertexArrayID *arraysPacked); \ + void getActiveUniformBlockName(ShaderProgramID programPacked, \ + UniformBlockIndex uniformBlockIndexPacked, GLsizei bufSize, \ + GLsizei *length, GLchar *uniformBlockName); \ + void getActiveUniformBlockiv(ShaderProgramID programPacked, \ + UniformBlockIndex uniformBlockIndexPacked, GLenum pname, \ + GLint *params); \ + void getActiveUniformsiv(ShaderProgramID programPacked, GLsizei uniformCount, \ + const GLuint *uniformIndices, GLenum pname, GLint *params); \ + void getBufferParameteri64v(BufferBinding targetPacked, GLenum pname, GLint64 *params); \ + void getBufferPointerv(BufferBinding targetPacked, GLenum pname, void **params); \ + GLint getFragDataLocation(ShaderProgramID programPacked, const GLchar *name); \ + void getInteger64i_v(GLenum target, GLuint index, GLint64 *data); \ + void getInteger64v(GLenum pname, GLint64 *data); \ + void getIntegeri_v(GLenum target, GLuint index, GLint *data); \ + void getInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei count, \ + GLint *params); \ + void getProgramBinary(ShaderProgramID programPacked, GLsizei bufSize, GLsizei *length, \ + GLenum *binaryFormat, void *binary); \ + void getQueryObjectuiv(QueryID idPacked, GLenum pname, GLuint *params); \ + void getQueryiv(QueryType targetPacked, GLenum pname, GLint *params); \ + void getSamplerParameterfv(SamplerID samplerPacked, GLenum pname, GLfloat *params); \ + void getSamplerParameteriv(SamplerID samplerPacked, GLenum pname, GLint *params); \ + const GLubyte *getStringi(GLenum name, GLuint index); \ + void getSynciv(GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values); \ + void getTransformFeedbackVarying(ShaderProgramID programPacked, GLuint index, GLsizei bufSize, \ + GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); \ + GLuint getUniformBlockIndex(ShaderProgramID programPacked, const GLchar *uniformBlockName); \ + void getUniformIndices(ShaderProgramID programPacked, GLsizei uniformCount, \ + const GLchar *const *uniformNames, GLuint *uniformIndices); \ + void getUniformuiv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLuint *params); \ + void getVertexAttribIiv(GLuint index, GLenum pname, GLint *params); \ + void getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params); \ + void invalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments); \ + void invalidateSubFramebuffer(GLenum target, GLsizei numAttachments, \ + const GLenum *attachments, GLint x, GLint y, GLsizei width, \ + GLsizei height); \ + GLboolean isQuery(QueryID idPacked) const; \ + GLboolean isSampler(SamplerID samplerPacked) const; \ + GLboolean isSync(GLsync sync) const; \ + GLboolean isTransformFeedback(TransformFeedbackID idPacked) const; \ + GLboolean isVertexArray(VertexArrayID arrayPacked) const; \ + void *mapBufferRange(BufferBinding targetPacked, GLintptr offset, GLsizeiptr length, \ + GLbitfield access); \ + void pauseTransformFeedback(); \ + void programBinary(ShaderProgramID programPacked, GLenum binaryFormat, const void *binary, \ + GLsizei length); \ + void programParameteri(ShaderProgramID programPacked, GLenum pname, GLint value); \ + void readBuffer(GLenum src); \ + void renderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, \ + GLsizei width, GLsizei height); \ + void resumeTransformFeedback(); \ + void samplerParameterf(SamplerID samplerPacked, GLenum pname, GLfloat param); \ + void samplerParameterfv(SamplerID samplerPacked, GLenum pname, const GLfloat *param); \ + void samplerParameteri(SamplerID samplerPacked, GLenum pname, GLint param); \ + void samplerParameteriv(SamplerID samplerPacked, GLenum pname, const GLint *param); \ + void texImage3D(TextureTarget targetPacked, GLint level, GLint internalformat, GLsizei width, \ + GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, \ + const void *pixels); \ + void texStorage2D(TextureType targetPacked, GLsizei levels, GLenum internalformat, \ + GLsizei width, GLsizei height); \ + void texStorage3D(TextureType targetPacked, GLsizei levels, GLenum internalformat, \ + GLsizei width, GLsizei height, GLsizei depth); \ + void texSubImage3D(TextureTarget targetPacked, GLint level, GLint xoffset, GLint yoffset, \ + GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, \ + GLenum type, const void *pixels); \ + void transformFeedbackVaryings(ShaderProgramID programPacked, GLsizei count, \ + const GLchar *const *varyings, GLenum bufferMode); \ + void uniform1ui(UniformLocation locationPacked, GLuint v0); \ + void uniform1uiv(UniformLocation locationPacked, GLsizei count, const GLuint *value); \ + void uniform2ui(UniformLocation locationPacked, GLuint v0, GLuint v1); \ + void uniform2uiv(UniformLocation locationPacked, GLsizei count, const GLuint *value); \ + void uniform3ui(UniformLocation locationPacked, GLuint v0, GLuint v1, GLuint v2); \ + void uniform3uiv(UniformLocation locationPacked, GLsizei count, const GLuint *value); \ + void uniform4ui(UniformLocation locationPacked, GLuint v0, GLuint v1, GLuint v2, GLuint v3); \ + void uniform4uiv(UniformLocation locationPacked, GLsizei count, const GLuint *value); \ + void uniformBlockBinding(ShaderProgramID programPacked, \ + UniformBlockIndex uniformBlockIndexPacked, \ + GLuint uniformBlockBinding); \ + void uniformMatrix2x3fv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \ + const GLfloat *value); \ + void uniformMatrix2x4fv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \ + const GLfloat *value); \ + void uniformMatrix3x2fv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \ + const GLfloat *value); \ + void uniformMatrix3x4fv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \ + const GLfloat *value); \ + void uniformMatrix4x2fv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \ + const GLfloat *value); \ + void uniformMatrix4x3fv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \ + const GLfloat *value); \ + GLboolean unmapBuffer(BufferBinding targetPacked); \ + void vertexAttribDivisor(GLuint index, GLuint divisor); \ + void vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w); \ + void vertexAttribI4iv(GLuint index, const GLint *v); \ + void vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); \ + void vertexAttribI4uiv(GLuint index, const GLuint *v); \ + void vertexAttribIPointer(GLuint index, GLint size, VertexAttribType typePacked, \ + GLsizei stride, const void *pointer); \ + void waitSync(GLsync sync, GLbitfield flags, GLuint64 timeout); + +#endif // ANGLE_CONTEXT_API_3_0_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Context_gles_3_1_autogen.h b/gfx/angle/checkout/src/libANGLE/Context_gles_3_1_autogen.h new file mode 100644 index 0000000000..0d8c5dcabd --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Context_gles_3_1_autogen.h @@ -0,0 +1,133 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Context_gles_3_1_autogen.h: Creates a macro for interfaces in Context. + +#ifndef ANGLE_CONTEXT_GLES_3_1_AUTOGEN_H_ +#define ANGLE_CONTEXT_GLES_3_1_AUTOGEN_H_ + +#define ANGLE_GLES_3_1_CONTEXT_API \ + void activeShaderProgram(ProgramPipelineID pipelinePacked, ShaderProgramID programPacked); \ + void bindImageTexture(GLuint unit, TextureID texturePacked, GLint level, GLboolean layered, \ + GLint layer, GLenum access, GLenum format); \ + void bindProgramPipeline(ProgramPipelineID pipelinePacked); \ + void bindVertexBuffer(GLuint bindingindex, BufferID bufferPacked, GLintptr offset, \ + GLsizei stride); \ + GLuint createShaderProgramv(ShaderType typePacked, GLsizei count, \ + const GLchar *const *strings); \ + void deleteProgramPipelines(GLsizei n, const ProgramPipelineID *pipelinesPacked); \ + void dispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); \ + void dispatchComputeIndirect(GLintptr indirect); \ + void drawArraysIndirect(PrimitiveMode modePacked, const void *indirect); \ + void drawElementsIndirect(PrimitiveMode modePacked, DrawElementsType typePacked, \ + const void *indirect); \ + void framebufferParameteri(GLenum target, GLenum pname, GLint param); \ + void genProgramPipelines(GLsizei n, ProgramPipelineID *pipelinesPacked); \ + void getBooleani_v(GLenum target, GLuint index, GLboolean *data); \ + void getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params); \ + void getMultisamplefv(GLenum pname, GLuint index, GLfloat *val); \ + void getProgramInterfaceiv(ShaderProgramID programPacked, GLenum programInterface, \ + GLenum pname, GLint *params); \ + void getProgramPipelineInfoLog(ProgramPipelineID pipelinePacked, GLsizei bufSize, \ + GLsizei *length, GLchar *infoLog); \ + void getProgramPipelineiv(ProgramPipelineID pipelinePacked, GLenum pname, GLint *params); \ + GLuint getProgramResourceIndex(ShaderProgramID programPacked, GLenum programInterface, \ + const GLchar *name); \ + GLint getProgramResourceLocation(ShaderProgramID programPacked, GLenum programInterface, \ + const GLchar *name); \ + void getProgramResourceName(ShaderProgramID programPacked, GLenum programInterface, \ + GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); \ + void getProgramResourceiv(ShaderProgramID programPacked, GLenum programInterface, \ + GLuint index, GLsizei propCount, const GLenum *props, GLsizei count, \ + GLsizei *length, GLint *params); \ + void getTexLevelParameterfv(TextureTarget targetPacked, GLint level, GLenum pname, \ + GLfloat *params); \ + void getTexLevelParameteriv(TextureTarget targetPacked, GLint level, GLenum pname, \ + GLint *params); \ + GLboolean isProgramPipeline(ProgramPipelineID pipelinePacked) const; \ + void memoryBarrier(GLbitfield barriers); \ + void memoryBarrierByRegion(GLbitfield barriers); \ + void programUniform1f(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLfloat v0); \ + void programUniform1fv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, const GLfloat *value); \ + void programUniform1i(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLint v0); \ + void programUniform1iv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, const GLint *value); \ + void programUniform1ui(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLuint v0); \ + void programUniform1uiv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, const GLuint *value); \ + void programUniform2f(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLfloat v0, GLfloat v1); \ + void programUniform2fv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, const GLfloat *value); \ + void programUniform2i(ShaderProgramID programPacked, UniformLocation locationPacked, GLint v0, \ + GLint v1); \ + void programUniform2iv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, const GLint *value); \ + void programUniform2ui(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLuint v0, GLuint v1); \ + void programUniform2uiv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, const GLuint *value); \ + void programUniform3f(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLfloat v0, GLfloat v1, GLfloat v2); \ + void programUniform3fv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, const GLfloat *value); \ + void programUniform3i(ShaderProgramID programPacked, UniformLocation locationPacked, GLint v0, \ + GLint v1, GLint v2); \ + void programUniform3iv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, const GLint *value); \ + void programUniform3ui(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLuint v0, GLuint v1, GLuint v2); \ + void programUniform3uiv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, const GLuint *value); \ + void programUniform4f(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); \ + void programUniform4fv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, const GLfloat *value); \ + void programUniform4i(ShaderProgramID programPacked, UniformLocation locationPacked, GLint v0, \ + GLint v1, GLint v2, GLint v3); \ + void programUniform4iv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, const GLint *value); \ + void programUniform4ui(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLuint v0, GLuint v1, GLuint v2, GLuint v3); \ + void programUniform4uiv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, const GLuint *value); \ + void programUniformMatrix2fv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, GLboolean transpose, const GLfloat *value); \ + void programUniformMatrix2x3fv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, GLboolean transpose, const GLfloat *value); \ + void programUniformMatrix2x4fv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, GLboolean transpose, const GLfloat *value); \ + void programUniformMatrix3fv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, GLboolean transpose, const GLfloat *value); \ + void programUniformMatrix3x2fv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, GLboolean transpose, const GLfloat *value); \ + void programUniformMatrix3x4fv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, GLboolean transpose, const GLfloat *value); \ + void programUniformMatrix4fv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, GLboolean transpose, const GLfloat *value); \ + void programUniformMatrix4x2fv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, GLboolean transpose, const GLfloat *value); \ + void programUniformMatrix4x3fv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei count, GLboolean transpose, const GLfloat *value); \ + void sampleMaski(GLuint maskNumber, GLbitfield mask); \ + void texStorage2DMultisample(TextureType targetPacked, GLsizei samples, GLenum internalformat, \ + GLsizei width, GLsizei height, GLboolean fixedsamplelocations); \ + void useProgramStages(ProgramPipelineID pipelinePacked, GLbitfield stages, \ + ShaderProgramID programPacked); \ + void validateProgramPipeline(ProgramPipelineID pipelinePacked); \ + void vertexAttribBinding(GLuint attribindex, GLuint bindingindex); \ + void vertexAttribFormat(GLuint attribindex, GLint size, VertexAttribType typePacked, \ + GLboolean normalized, GLuint relativeoffset); \ + void vertexAttribIFormat(GLuint attribindex, GLint size, VertexAttribType typePacked, \ + GLuint relativeoffset); \ + void vertexBindingDivisor(GLuint bindingindex, GLuint divisor); + +#endif // ANGLE_CONTEXT_API_3_1_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Context_gles_3_2_autogen.h b/gfx/angle/checkout/src/libANGLE/Context_gles_3_2_autogen.h new file mode 100644 index 0000000000..520b86c130 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Context_gles_3_2_autogen.h @@ -0,0 +1,83 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Context_gles_3_2_autogen.h: Creates a macro for interfaces in Context. + +#ifndef ANGLE_CONTEXT_GLES_3_2_AUTOGEN_H_ +#define ANGLE_CONTEXT_GLES_3_2_AUTOGEN_H_ + +#define ANGLE_GLES_3_2_CONTEXT_API \ + void blendBarrier(); \ + void blendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeAlpha); \ + void blendEquationi(GLuint buf, GLenum mode); \ + void blendFuncSeparatei(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, \ + GLenum dstAlpha); \ + void blendFunci(GLuint buf, GLenum src, GLenum dst); \ + void colorMaski(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); \ + void copyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, \ + GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, \ + GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, \ + GLsizei srcHeight, GLsizei srcDepth); \ + void debugMessageCallback(GLDEBUGPROC callback, const void *userParam); \ + void debugMessageControl(GLenum source, GLenum type, GLenum severity, GLsizei count, \ + const GLuint *ids, GLboolean enabled); \ + void debugMessageInsert(GLenum source, GLenum type, GLuint id, GLenum severity, \ + GLsizei length, const GLchar *buf); \ + void disablei(GLenum target, GLuint index); \ + void drawElementsBaseVertex(PrimitiveMode modePacked, GLsizei count, \ + DrawElementsType typePacked, const void *indices, \ + GLint basevertex); \ + void drawElementsInstancedBaseVertex(PrimitiveMode modePacked, GLsizei count, \ + DrawElementsType typePacked, const void *indices, \ + GLsizei instancecount, GLint basevertex); \ + void drawRangeElementsBaseVertex(PrimitiveMode modePacked, GLuint start, GLuint end, \ + GLsizei count, DrawElementsType typePacked, \ + const void *indices, GLint basevertex); \ + void enablei(GLenum target, GLuint index); \ + void framebufferTexture(GLenum target, GLenum attachment, TextureID texturePacked, \ + GLint level); \ + GLuint getDebugMessageLog(GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, \ + GLuint *ids, GLenum *severities, GLsizei *lengths, \ + GLchar *messageLog); \ + GLenum getGraphicsResetStatus(); \ + void getObjectLabel(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, \ + GLchar *label); \ + void getObjectPtrLabel(const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); \ + void getPointerv(GLenum pname, void **params); \ + void getSamplerParameterIiv(SamplerID samplerPacked, GLenum pname, GLint *params); \ + void getSamplerParameterIuiv(SamplerID samplerPacked, GLenum pname, GLuint *params); \ + void getTexParameterIiv(TextureType targetPacked, GLenum pname, GLint *params); \ + void getTexParameterIuiv(TextureType targetPacked, GLenum pname, GLuint *params); \ + void getnUniformfv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei bufSize, GLfloat *params); \ + void getnUniformiv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei bufSize, GLint *params); \ + void getnUniformuiv(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei bufSize, GLuint *params); \ + GLboolean isEnabledi(GLenum target, GLuint index) const; \ + void minSampleShading(GLfloat value); \ + void objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label); \ + void objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label); \ + void patchParameteri(GLenum pname, GLint value); \ + void popDebugGroup(); \ + void primitiveBoundingBox(GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, \ + GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW); \ + void pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message); \ + void readnPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, \ + GLsizei bufSize, void *data); \ + void samplerParameterIiv(SamplerID samplerPacked, GLenum pname, const GLint *param); \ + void samplerParameterIuiv(SamplerID samplerPacked, GLenum pname, const GLuint *param); \ + void texBuffer(TextureType targetPacked, GLenum internalformat, BufferID bufferPacked); \ + void texBufferRange(TextureType targetPacked, GLenum internalformat, BufferID bufferPacked, \ + GLintptr offset, GLsizeiptr size); \ + void texParameterIiv(TextureType targetPacked, GLenum pname, const GLint *params); \ + void texParameterIuiv(TextureType targetPacked, GLenum pname, const GLuint *params); \ + void texStorage3DMultisample(TextureType targetPacked, GLsizei samples, GLenum internalformat, \ + GLsizei width, GLsizei height, GLsizei depth, \ + GLboolean fixedsamplelocations); + +#endif // ANGLE_CONTEXT_API_3_2_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Context_gles_ext_autogen.h b/gfx/angle/checkout/src/libANGLE/Context_gles_ext_autogen.h new file mode 100644 index 0000000000..286a5061e2 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Context_gles_ext_autogen.h @@ -0,0 +1,616 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Context_gles_ext_autogen.h: Creates a macro for interfaces in Context. + +#ifndef ANGLE_CONTEXT_GLES_EXT_AUTOGEN_H_ +#define ANGLE_CONTEXT_GLES_EXT_AUTOGEN_H_ + +#define ANGLE_GLES_EXT_CONTEXT_API \ + \ + /* GLES1 Extensions */ \ + \ + /* GL_OES_draw_texture */ \ + void drawTexf(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height); \ + void drawTexfv(const GLfloat *coords); \ + void drawTexi(GLint x, GLint y, GLint z, GLint width, GLint height); \ + void drawTexiv(const GLint *coords); \ + void drawTexs(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height); \ + void drawTexsv(const GLshort *coords); \ + void drawTexx(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height); \ + void drawTexxv(const GLfixed *coords); \ + /* GL_OES_framebuffer_object */ \ + /* GL_OES_matrix_palette */ \ + void currentPaletteMatrix(GLuint matrixpaletteindex); \ + void loadPaletteFromModelViewMatrix(); \ + void matrixIndexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer); \ + void weightPointer(GLint size, GLenum type, GLsizei stride, const void *pointer); \ + /* GL_OES_point_size_array */ \ + void pointSizePointer(VertexAttribType typePacked, GLsizei stride, const void *pointer); \ + /* GL_OES_point_sprite */ \ + /* GL_OES_query_matrix */ \ + GLbitfield queryMatrixx(GLfixed *mantissa, GLint *exponent); \ + /* GL_OES_texture_cube_map */ \ + void getTexGenfv(GLenum coord, GLenum pname, GLfloat *params); \ + void getTexGeniv(GLenum coord, GLenum pname, GLint *params); \ + void getTexGenxv(GLenum coord, GLenum pname, GLfixed *params); \ + void texGenf(GLenum coord, GLenum pname, GLfloat param); \ + void texGenfv(GLenum coord, GLenum pname, const GLfloat *params); \ + void texGeni(GLenum coord, GLenum pname, GLint param); \ + void texGeniv(GLenum coord, GLenum pname, const GLint *params); \ + void texGenx(GLenum coord, GLenum pname, GLfixed param); \ + void texGenxv(GLenum coord, GLenum pname, const GLfixed *params); \ + \ + /* GLES2+ Extensions */ \ + \ + /* GL_AMD_performance_monitor */ \ + void beginPerfMonitor(GLuint monitor); \ + void deletePerfMonitors(GLsizei n, GLuint *monitors); \ + void endPerfMonitor(GLuint monitor); \ + void genPerfMonitors(GLsizei n, GLuint *monitors); \ + void getPerfMonitorCounterData(GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, \ + GLint *bytesWritten); \ + void getPerfMonitorCounterInfo(GLuint group, GLuint counter, GLenum pname, void *data); \ + void getPerfMonitorCounterString(GLuint group, GLuint counter, GLsizei bufSize, \ + GLsizei *length, GLchar *counterString); \ + void getPerfMonitorCounters(GLuint group, GLint *numCounters, GLint *maxActiveCounters, \ + GLsizei counterSize, GLuint *counters); \ + void getPerfMonitorGroupString(GLuint group, GLsizei bufSize, GLsizei *length, \ + GLchar *groupString); \ + void getPerfMonitorGroups(GLint *numGroups, GLsizei groupsSize, GLuint *groups); \ + void selectPerfMonitorCounters(GLuint monitor, GLboolean enable, GLuint group, \ + GLint numCounters, GLuint *counterList); \ + /* GL_ANDROID_extension_pack_es31a */ \ + /* GL_ANGLE_depth_texture */ \ + /* GL_ANGLE_framebuffer_blit */ \ + /* GL_ANGLE_instanced_arrays */ \ + /* GL_ANGLE_pack_reverse_row_order */ \ + /* GL_ANGLE_texture_usage */ \ + /* GL_ANGLE_translated_shader_source */ \ + void getTranslatedShaderSource(ShaderProgramID shaderPacked, GLsizei bufSize, GLsizei *length, \ + GLchar *source); \ + /* GL_APPLE_clip_distance */ \ + /* GL_ARB_sync */ \ + /* GL_EXT_EGL_image_array */ \ + /* GL_EXT_EGL_image_external_wrap_modes */ \ + /* GL_EXT_EGL_image_storage */ \ + void eGLImageTargetTexStorage(GLenum target, GLeglImageOES image, const GLint *attrib_list); \ + void eGLImageTargetTextureStorage(GLuint texture, GLeglImageOES image, \ + const GLint *attrib_list); \ + /* GL_EXT_YUV_target */ \ + /* GL_EXT_base_instance */ \ + void drawArraysInstancedBaseInstance(PrimitiveMode modePacked, GLint first, GLsizei count, \ + GLsizei instancecount, GLuint baseinstance); \ + void drawElementsInstancedBaseInstance(PrimitiveMode modePacked, GLsizei count, \ + DrawElementsType typePacked, const void *indices, \ + GLsizei instancecount, GLuint baseinstance); \ + void drawElementsInstancedBaseVertexBaseInstance( \ + PrimitiveMode modePacked, GLsizei count, DrawElementsType typePacked, const void *indices, \ + GLsizei instancecount, GLint basevertex, GLuint baseinstance); \ + /* GL_EXT_blend_func_extended */ \ + void bindFragDataLocation(ShaderProgramID programPacked, GLuint color, const GLchar *name); \ + void bindFragDataLocationIndexed(ShaderProgramID programPacked, GLuint colorNumber, \ + GLuint index, const GLchar *name); \ + GLint getFragDataIndex(ShaderProgramID programPacked, const GLchar *name); \ + GLint getProgramResourceLocationIndex(ShaderProgramID programPacked, GLenum programInterface, \ + const GLchar *name); \ + /* GL_EXT_blend_minmax */ \ + /* GL_EXT_buffer_storage */ \ + void bufferStorage(BufferBinding targetPacked, GLsizeiptr size, const void *data, \ + GLbitfield flags); \ + /* GL_EXT_clip_control */ \ + void clipControl(GLenum origin, GLenum depth); \ + /* GL_EXT_clip_cull_distance */ \ + /* GL_EXT_color_buffer_float */ \ + /* GL_EXT_color_buffer_half_float */ \ + /* GL_EXT_compressed_ETC1_RGB8_sub_texture */ \ + /* GL_EXT_copy_image */ \ + /* GL_EXT_debug_label */ \ + void labelObject(GLenum type, GLuint object, GLsizei length, const GLchar *label); \ + /* GL_EXT_debug_marker */ \ + void insertEventMarker(GLsizei length, const GLchar *marker); \ + void popGroupMarker(); \ + void pushGroupMarker(GLsizei length, const GLchar *marker); \ + /* GL_EXT_discard_framebuffer */ \ + void discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments); \ + /* GL_EXT_disjoint_timer_query */ \ + void getQueryObjecti64v(QueryID idPacked, GLenum pname, GLint64 *params); \ + void getQueryObjectiv(QueryID idPacked, GLenum pname, GLint *params); \ + void getQueryObjectui64v(QueryID idPacked, GLenum pname, GLuint64 *params); \ + void queryCounter(QueryID idPacked, QueryType targetPacked); \ + /* GL_EXT_draw_buffers */ \ + /* GL_EXT_draw_buffers_indexed */ \ + /* GL_EXT_draw_elements_base_vertex */ \ + void multiDrawElementsBaseVertex(PrimitiveMode modePacked, const GLsizei *count, \ + DrawElementsType typePacked, const void *const *indices, \ + GLsizei drawcount, const GLint *basevertex); \ + /* GL_EXT_external_buffer */ \ + void bufferStorageExternal(BufferBinding targetPacked, GLintptr offset, GLsizeiptr size, \ + GLeglClientBufferEXT clientBuffer, GLbitfield flags); \ + void namedBufferStorageExternal(GLuint buffer, GLintptr offset, GLsizeiptr size, \ + GLeglClientBufferEXT clientBuffer, GLbitfield flags); \ + /* GL_EXT_float_blend */ \ + /* GL_EXT_frag_depth */ \ + /* GL_EXT_geometry_shader */ \ + /* GL_EXT_gpu_shader5 */ \ + /* GL_EXT_instanced_arrays */ \ + /* GL_EXT_map_buffer_range */ \ + /* GL_EXT_memory_object */ \ + void bufferStorageMem(TextureType targetPacked, GLsizeiptr size, MemoryObjectID memoryPacked, \ + GLuint64 offset); \ + void createMemoryObjects(GLsizei n, MemoryObjectID *memoryObjectsPacked); \ + void deleteMemoryObjects(GLsizei n, const MemoryObjectID *memoryObjectsPacked); \ + void getMemoryObjectParameteriv(MemoryObjectID memoryObjectPacked, GLenum pname, \ + GLint *params); \ + void getUnsignedBytev(GLenum pname, GLubyte *data); \ + void getUnsignedBytei_v(GLenum target, GLuint index, GLubyte *data); \ + GLboolean isMemoryObject(MemoryObjectID memoryObjectPacked) const; \ + void memoryObjectParameteriv(MemoryObjectID memoryObjectPacked, GLenum pname, \ + const GLint *params); \ + void texStorageMem2D(TextureType targetPacked, GLsizei levels, GLenum internalFormat, \ + GLsizei width, GLsizei height, MemoryObjectID memoryPacked, \ + GLuint64 offset); \ + void texStorageMem2DMultisample(TextureType targetPacked, GLsizei samples, \ + GLenum internalFormat, GLsizei width, GLsizei height, \ + GLboolean fixedSampleLocations, MemoryObjectID memoryPacked, \ + GLuint64 offset); \ + void texStorageMem3D(TextureType targetPacked, GLsizei levels, GLenum internalFormat, \ + GLsizei width, GLsizei height, GLsizei depth, \ + MemoryObjectID memoryPacked, GLuint64 offset); \ + void texStorageMem3DMultisample(TextureType targetPacked, GLsizei samples, \ + GLenum internalFormat, GLsizei width, GLsizei height, \ + GLsizei depth, GLboolean fixedSampleLocations, \ + MemoryObjectID memoryPacked, GLuint64 offset); \ + /* GL_EXT_memory_object_fd */ \ + void importMemoryFd(MemoryObjectID memoryPacked, GLuint64 size, HandleType handleTypePacked, \ + GLint fd); \ + /* GL_EXT_multi_draw_indirect */ \ + void multiDrawArraysIndirect(PrimitiveMode modePacked, const void *indirect, \ + GLsizei drawcount, GLsizei stride); \ + void multiDrawElementsIndirect(PrimitiveMode modePacked, DrawElementsType typePacked, \ + const void *indirect, GLsizei drawcount, GLsizei stride); \ + /* GL_EXT_multisample_compatibility */ \ + /* GL_EXT_multisampled_render_to_texture */ \ + void framebufferTexture2DMultisample(GLenum target, GLenum attachment, \ + TextureTarget textargetPacked, TextureID texturePacked, \ + GLint level, GLsizei samples); \ + void renderbufferStorageMultisampleEXT(GLenum target, GLsizei samples, GLenum internalformat, \ + GLsizei width, GLsizei height); \ + /* GL_EXT_multisampled_render_to_texture2 */ \ + /* GL_EXT_occlusion_query_boolean */ \ + /* GL_EXT_primitive_bounding_box */ \ + /* GL_EXT_protected_textures */ \ + /* GL_EXT_pvrtc_sRGB */ \ + /* GL_EXT_read_format_bgra */ \ + /* GL_EXT_robustness */ \ + /* GL_EXT_sRGB */ \ + /* GL_EXT_sRGB_write_control */ \ + /* GL_EXT_semaphore */ \ + void deleteSemaphores(GLsizei n, const SemaphoreID *semaphoresPacked); \ + void genSemaphores(GLsizei n, SemaphoreID *semaphoresPacked); \ + void getSemaphoreParameterui64v(SemaphoreID semaphorePacked, GLenum pname, GLuint64 *params); \ + GLboolean isSemaphore(SemaphoreID semaphorePacked) const; \ + void semaphoreParameterui64v(SemaphoreID semaphorePacked, GLenum pname, \ + const GLuint64 *params); \ + void signalSemaphore(SemaphoreID semaphorePacked, GLuint numBufferBarriers, \ + const BufferID *buffersPacked, GLuint numTextureBarriers, \ + const TextureID *texturesPacked, const GLenum *dstLayouts); \ + void waitSemaphore(SemaphoreID semaphorePacked, GLuint numBufferBarriers, \ + const BufferID *buffersPacked, GLuint numTextureBarriers, \ + const TextureID *texturesPacked, const GLenum *srcLayouts); \ + /* GL_EXT_semaphore_fd */ \ + void importSemaphoreFd(SemaphoreID semaphorePacked, HandleType handleTypePacked, GLint fd); \ + /* GL_EXT_separate_shader_objects */ \ + /* GL_EXT_shader_framebuffer_fetch */ \ + /* GL_EXT_shader_framebuffer_fetch_non_coherent */ \ + void framebufferFetchBarrier(); \ + /* GL_EXT_shader_io_blocks */ \ + /* GL_EXT_shader_non_constant_global_initializers */ \ + /* GL_EXT_shader_texture_lod */ \ + /* GL_EXT_shadow_samplers */ \ + /* GL_EXT_tessellation_shader */ \ + /* GL_EXT_texture_border_clamp */ \ + /* GL_EXT_texture_buffer */ \ + /* GL_EXT_texture_compression_bptc */ \ + /* GL_EXT_texture_compression_dxt1 */ \ + /* GL_EXT_texture_compression_rgtc */ \ + /* GL_EXT_texture_compression_s3tc */ \ + /* GL_EXT_texture_compression_s3tc_srgb */ \ + /* GL_EXT_texture_cube_map_array */ \ + /* GL_EXT_texture_filter_anisotropic */ \ + /* GL_EXT_texture_format_BGRA8888 */ \ + /* GL_EXT_texture_format_sRGB_override */ \ + /* GL_EXT_texture_norm16 */ \ + /* GL_EXT_texture_rg */ \ + /* GL_EXT_texture_sRGB_R8 */ \ + /* GL_EXT_texture_sRGB_RG8 */ \ + /* GL_EXT_texture_sRGB_decode */ \ + /* GL_EXT_texture_storage */ \ + void texStorage1D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); \ + /* GL_EXT_texture_type_2_10_10_10_REV */ \ + /* GL_EXT_unpack_subimage */ \ + /* GL_IMG_texture_compression_pvrtc */ \ + /* GL_IMG_texture_compression_pvrtc2 */ \ + /* GL_KHR_blend_equation_advanced */ \ + /* GL_KHR_debug */ \ + /* GL_KHR_no_error */ \ + /* GL_KHR_parallel_shader_compile */ \ + void maxShaderCompilerThreads(GLuint count); \ + /* GL_KHR_robust_buffer_access_behavior */ \ + /* GL_KHR_texture_compression_astc_hdr */ \ + /* GL_KHR_texture_compression_astc_ldr */ \ + /* GL_KHR_texture_compression_astc_sliced_3d */ \ + /* GL_MESA_framebuffer_flip_y */ \ + void framebufferParameteriMESA(GLenum target, GLenum pname, GLint param); \ + void getFramebufferParameterivMESA(GLenum target, GLenum pname, GLint *params); \ + /* GL_NV_EGL_stream_consumer_external */ \ + /* GL_NV_depth_buffer_float2 */ \ + /* GL_NV_fence */ \ + void deleteFencesNV(GLsizei n, const FenceNVID *fencesPacked); \ + void finishFenceNV(FenceNVID fencePacked); \ + void genFencesNV(GLsizei n, FenceNVID *fencesPacked); \ + void getFenceivNV(FenceNVID fencePacked, GLenum pname, GLint *params); \ + GLboolean isFenceNV(FenceNVID fencePacked) const; \ + void setFenceNV(FenceNVID fencePacked, GLenum condition); \ + GLboolean testFenceNV(FenceNVID fencePacked); \ + /* GL_NV_framebuffer_blit */ \ + void blitFramebufferNV(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, \ + GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); \ + /* GL_NV_pack_subimage */ \ + /* GL_NV_pixel_buffer_object */ \ + /* GL_NV_read_depth */ \ + /* GL_NV_read_depth_stencil */ \ + /* GL_NV_read_stencil */ \ + /* GL_NV_robustness_video_memory_purge */ \ + /* GL_NV_shader_noperspective_interpolation */ \ + /* GL_OES_EGL_image */ \ + void eGLImageTargetRenderbufferStorage(GLenum target, GLeglImageOES image); \ + void eGLImageTargetTexture2D(TextureType targetPacked, GLeglImageOES image); \ + /* GL_OES_EGL_image_external */ \ + /* GL_OES_EGL_image_external_essl3 */ \ + /* GL_OES_EGL_sync */ \ + /* GL_OES_compressed_EAC_R11_signed_texture */ \ + /* GL_OES_compressed_EAC_R11_unsigned_texture */ \ + /* GL_OES_compressed_EAC_RG11_signed_texture */ \ + /* GL_OES_compressed_EAC_RG11_unsigned_texture */ \ + /* GL_OES_compressed_ETC1_RGB8_texture */ \ + /* GL_OES_compressed_ETC2_RGB8_texture */ \ + /* GL_OES_compressed_ETC2_RGBA8_texture */ \ + /* GL_OES_compressed_ETC2_punchthroughA_RGBA8_texture */ \ + /* GL_OES_compressed_ETC2_punchthroughA_sRGB8_alpha_texture */ \ + /* GL_OES_compressed_ETC2_sRGB8_alpha8_texture */ \ + /* GL_OES_compressed_ETC2_sRGB8_texture */ \ + /* GL_OES_compressed_paletted_texture */ \ + /* GL_OES_copy_image */ \ + /* GL_OES_depth24 */ \ + /* GL_OES_depth32 */ \ + /* GL_OES_depth_texture */ \ + /* GL_OES_depth_texture_cube_map */ \ + /* GL_OES_draw_buffers_indexed */ \ + /* GL_OES_draw_elements_base_vertex */ \ + /* GL_OES_element_index_uint */ \ + /* GL_OES_fbo_render_mipmap */ \ + /* GL_OES_geometry_shader */ \ + /* GL_OES_get_program_binary */ \ + /* GL_OES_mapbuffer */ \ + void *mapBuffer(BufferBinding targetPacked, GLenum access); \ + /* GL_OES_packed_depth_stencil */ \ + /* GL_OES_primitive_bounding_box */ \ + /* GL_OES_rgb8_rgba8 */ \ + /* GL_OES_sample_shading */ \ + /* GL_OES_sample_variables */ \ + /* GL_OES_shader_image_atomic */ \ + /* GL_OES_shader_io_blocks */ \ + /* GL_OES_shader_multisample_interpolation */ \ + /* GL_OES_standard_derivatives */ \ + /* GL_OES_surfaceless_context */ \ + /* GL_OES_texture_3D */ \ + void framebufferTexture3D(GLenum target, GLenum attachment, TextureTarget textargetPacked, \ + TextureID texturePacked, GLint level, GLint zoffset); \ + /* GL_OES_texture_border_clamp */ \ + /* GL_OES_texture_buffer */ \ + /* GL_OES_texture_compression_astc */ \ + /* GL_OES_texture_cube_map_array */ \ + /* GL_OES_texture_float */ \ + /* GL_OES_texture_float_linear */ \ + /* GL_OES_texture_half_float */ \ + /* GL_OES_texture_half_float_linear */ \ + /* GL_OES_texture_npot */ \ + /* GL_OES_texture_stencil8 */ \ + /* GL_OES_texture_storage_multisample_2d_array */ \ + /* GL_OES_vertex_array_object */ \ + /* GL_OES_vertex_half_float */ \ + /* GL_OES_vertex_type_10_10_10_2 */ \ + /* GL_OVR_multiview */ \ + void framebufferTextureMultiview(GLenum target, GLenum attachment, TextureID texturePacked, \ + GLint level, GLint baseViewIndex, GLsizei numViews); \ + /* GL_OVR_multiview2 */ \ + /* GL_QCOM_shading_rate */ \ + void shadingRateQCOM(GLenum rate); \ + /* GL_WEBGL_video_texture */ \ + \ + /* ANGLE Extensions */ \ + \ + /* GL_ANGLE_base_vertex_base_instance */ \ + void drawArraysInstancedBaseInstanceANGLE(PrimitiveMode modePacked, GLint first, \ + GLsizei count, GLsizei instanceCount, \ + GLuint baseInstance); \ + void drawElementsInstancedBaseVertexBaseInstanceANGLE( \ + PrimitiveMode modePacked, GLsizei count, DrawElementsType typePacked, \ + const GLvoid *indices, GLsizei instanceCount, GLint baseVertex, GLuint baseInstance); \ + void multiDrawArraysInstancedBaseInstance( \ + PrimitiveMode modePacked, const GLint *firsts, const GLsizei *counts, \ + const GLsizei *instanceCounts, const GLuint *baseInstances, GLsizei drawcount); \ + void multiDrawElementsInstancedBaseVertexBaseInstance( \ + PrimitiveMode modePacked, const GLsizei *counts, DrawElementsType typePacked, \ + const GLvoid *const *indices, const GLsizei *instanceCounts, const GLint *baseVertices, \ + const GLuint *baseInstances, GLsizei drawcount); \ + /* GL_ANGLE_base_vertex_base_instance_shader_builtin */ \ + /* GL_ANGLE_client_arrays */ \ + /* GL_ANGLE_compressed_texture_etc */ \ + /* GL_ANGLE_copy_texture_3d */ \ + void copyTexture3D(TextureID sourceIdPacked, GLint sourceLevel, \ + TextureTarget destTargetPacked, TextureID destIdPacked, GLint destLevel, \ + GLint internalFormat, GLenum destType, GLboolean unpackFlipY, \ + GLboolean unpackPremultiplyAlpha, GLboolean unpackUnmultiplyAlpha); \ + void copySubTexture3D(TextureID sourceIdPacked, GLint sourceLevel, \ + TextureTarget destTargetPacked, TextureID destIdPacked, GLint destLevel, \ + GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLint z, \ + GLint width, GLint height, GLint depth, GLboolean unpackFlipY, \ + GLboolean unpackPremultiplyAlpha, GLboolean unpackUnmultiplyAlpha); \ + /* GL_ANGLE_framebuffer_multisample */ \ + /* GL_ANGLE_get_image */ \ + void getTexImage(TextureTarget targetPacked, GLint level, GLenum format, GLenum type, \ + void *pixels); \ + void getCompressedTexImage(TextureTarget targetPacked, GLint level, void *pixels); \ + void getRenderbufferImage(GLenum target, GLenum format, GLenum type, void *pixels); \ + /* GL_ANGLE_get_serialized_context_string */ \ + /* GL_ANGLE_get_tex_level_parameter */ \ + /* GL_ANGLE_logic_op */ \ + void logicOpANGLE(LogicalOperation opcodePacked); \ + /* GL_ANGLE_lossy_etc_decode */ \ + /* GL_ANGLE_memory_object_flags */ \ + void texStorageMemFlags2D(TextureType targetPacked, GLsizei levels, GLenum internalFormat, \ + GLsizei width, GLsizei height, MemoryObjectID memoryPacked, \ + GLuint64 offset, GLbitfield createFlags, GLbitfield usageFlags, \ + const void *imageCreateInfoPNext); \ + void texStorageMemFlags2DMultisample( \ + TextureType targetPacked, GLsizei samples, GLenum internalFormat, GLsizei width, \ + GLsizei height, GLboolean fixedSampleLocations, MemoryObjectID memoryPacked, \ + GLuint64 offset, GLbitfield createFlags, GLbitfield usageFlags, \ + const void *imageCreateInfoPNext); \ + void texStorageMemFlags3D( \ + TextureType targetPacked, GLsizei levels, GLenum internalFormat, GLsizei width, \ + GLsizei height, GLsizei depth, MemoryObjectID memoryPacked, GLuint64 offset, \ + GLbitfield createFlags, GLbitfield usageFlags, const void *imageCreateInfoPNext); \ + void texStorageMemFlags3DMultisample( \ + TextureType targetPacked, GLsizei samples, GLenum internalFormat, GLsizei width, \ + GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, \ + MemoryObjectID memoryPacked, GLuint64 offset, GLbitfield createFlags, \ + GLbitfield usageFlags, const void *imageCreateInfoPNext); \ + /* GL_ANGLE_memory_object_fuchsia */ \ + void importMemoryZirconHandle(MemoryObjectID memoryPacked, GLuint64 size, \ + HandleType handleTypePacked, GLuint handle); \ + /* GL_ANGLE_memory_size */ \ + /* GL_ANGLE_multi_draw */ \ + void multiDrawArrays(PrimitiveMode modePacked, const GLint *firsts, const GLsizei *counts, \ + GLsizei drawcount); \ + void multiDrawArraysInstanced(PrimitiveMode modePacked, const GLint *firsts, \ + const GLsizei *counts, const GLsizei *instanceCounts, \ + GLsizei drawcount); \ + void multiDrawElements(PrimitiveMode modePacked, const GLsizei *counts, \ + DrawElementsType typePacked, const GLvoid *const *indices, \ + GLsizei drawcount); \ + void multiDrawElementsInstanced(PrimitiveMode modePacked, const GLsizei *counts, \ + DrawElementsType typePacked, const GLvoid *const *indices, \ + const GLsizei *instanceCounts, GLsizei drawcount); \ + /* GL_ANGLE_multiview_multisample */ \ + /* GL_ANGLE_program_binary */ \ + /* GL_ANGLE_program_cache_control */ \ + /* GL_ANGLE_provoking_vertex */ \ + void provokingVertex(ProvokingVertexConvention modePacked); \ + /* GL_ANGLE_read_only_depth_stencil_feedback_loops */ \ + /* GL_ANGLE_relaxed_vertex_attribute_type */ \ + /* GL_ANGLE_request_extension */ \ + void requestExtension(const GLchar *name); \ + void disableExtension(const GLchar *name); \ + /* GL_ANGLE_rgbx_internal_format */ \ + /* GL_ANGLE_robust_client_memory */ \ + void getBooleanvRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLboolean *params); \ + void getBufferParameterivRobust(BufferBinding targetPacked, GLenum pname, GLsizei bufSize, \ + GLsizei *length, GLint *params); \ + void getFloatvRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params); \ + void getFramebufferAttachmentParameterivRobust(GLenum target, GLenum attachment, GLenum pname, \ + GLsizei bufSize, GLsizei *length, \ + GLint *params); \ + void getIntegervRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLint *data); \ + void getProgramivRobust(ShaderProgramID programPacked, GLenum pname, GLsizei bufSize, \ + GLsizei *length, GLint *params); \ + void getRenderbufferParameterivRobust(GLenum target, GLenum pname, GLsizei bufSize, \ + GLsizei *length, GLint *params); \ + void getShaderivRobust(ShaderProgramID shaderPacked, GLenum pname, GLsizei bufSize, \ + GLsizei *length, GLint *params); \ + void getTexParameterfvRobust(TextureType targetPacked, GLenum pname, GLsizei bufSize, \ + GLsizei *length, GLfloat *params); \ + void getTexParameterivRobust(TextureType targetPacked, GLenum pname, GLsizei bufSize, \ + GLsizei *length, GLint *params); \ + void getUniformfvRobust(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei bufSize, GLsizei *length, GLfloat *params); \ + void getUniformivRobust(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei bufSize, GLsizei *length, GLint *params); \ + void getVertexAttribfvRobust(GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, \ + GLfloat *params); \ + void getVertexAttribivRobust(GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, \ + GLint *params); \ + void getVertexAttribPointervRobust(GLuint index, GLenum pname, GLsizei bufSize, \ + GLsizei *length, void **pointer); \ + void readPixelsRobust(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, \ + GLenum type, GLsizei bufSize, GLsizei *length, GLsizei *columns, \ + GLsizei *rows, void *pixels); \ + void texImage2DRobust(TextureTarget targetPacked, GLint level, GLint internalformat, \ + GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, \ + GLsizei bufSize, const void *pixels); \ + void texParameterfvRobust(TextureType targetPacked, GLenum pname, GLsizei bufSize, \ + const GLfloat *params); \ + void texParameterivRobust(TextureType targetPacked, GLenum pname, GLsizei bufSize, \ + const GLint *params); \ + void texSubImage2DRobust(TextureTarget targetPacked, GLint level, GLint xoffset, \ + GLint yoffset, GLsizei width, GLsizei height, GLenum format, \ + GLenum type, GLsizei bufSize, const void *pixels); \ + void texImage3DRobust(TextureTarget targetPacked, GLint level, GLint internalformat, \ + GLsizei width, GLsizei height, GLsizei depth, GLint border, \ + GLenum format, GLenum type, GLsizei bufSize, const void *pixels); \ + void texSubImage3DRobust(TextureTarget targetPacked, GLint level, GLint xoffset, \ + GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, \ + GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, \ + const void *pixels); \ + void compressedTexImage2DRobust( \ + TextureTarget targetPacked, GLint level, GLenum internalformat, GLsizei width, \ + GLsizei height, GLint border, GLsizei imageSize, GLsizei dataSize, const GLvoid *data); \ + void compressedTexSubImage2DRobust( \ + TextureTarget targetPacked, GLint level, GLsizei xoffset, GLsizei yoffset, GLsizei width, \ + GLsizei height, GLenum format, GLsizei imageSize, GLsizei dataSize, const GLvoid *data); \ + void compressedTexImage3DRobust(TextureTarget targetPacked, GLint level, \ + GLenum internalformat, GLsizei width, GLsizei height, \ + GLsizei depth, GLint border, GLsizei imageSize, \ + GLsizei dataSize, const GLvoid *data); \ + void compressedTexSubImage3DRobust(TextureTarget targetPacked, GLint level, GLint xoffset, \ + GLint yoffset, GLint zoffset, GLsizei width, \ + GLsizei height, GLsizei depth, GLenum format, \ + GLsizei imageSize, GLsizei dataSize, const GLvoid *data); \ + void getQueryivRobust(QueryType targetPacked, GLenum pname, GLsizei bufSize, GLsizei *length, \ + GLint *params); \ + void getQueryObjectuivRobust(QueryID idPacked, GLenum pname, GLsizei bufSize, GLsizei *length, \ + GLuint *params); \ + void getBufferPointervRobust(BufferBinding targetPacked, GLenum pname, GLsizei bufSize, \ + GLsizei *length, void **params); \ + void getIntegeri_vRobust(GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, \ + GLint *data); \ + void getInternalformativRobust(GLenum target, GLenum internalformat, GLenum pname, \ + GLsizei bufSize, GLsizei *length, GLint *params); \ + void getVertexAttribIivRobust(GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, \ + GLint *params); \ + void getVertexAttribIuivRobust(GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, \ + GLuint *params); \ + void getUniformuivRobust(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei bufSize, GLsizei *length, GLuint *params); \ + void getActiveUniformBlockivRobust(ShaderProgramID programPacked, \ + UniformBlockIndex uniformBlockIndexPacked, GLenum pname, \ + GLsizei bufSize, GLsizei *length, GLint *params); \ + void getInteger64vRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *data); \ + void getInteger64i_vRobust(GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, \ + GLint64 *data); \ + void getBufferParameteri64vRobust(BufferBinding targetPacked, GLenum pname, GLsizei bufSize, \ + GLsizei *length, GLint64 *params); \ + void samplerParameterivRobust(SamplerID samplerPacked, GLuint pname, GLsizei bufSize, \ + const GLint *param); \ + void samplerParameterfvRobust(SamplerID samplerPacked, GLenum pname, GLsizei bufSize, \ + const GLfloat *param); \ + void getSamplerParameterivRobust(SamplerID samplerPacked, GLenum pname, GLsizei bufSize, \ + GLsizei *length, GLint *params); \ + void getSamplerParameterfvRobust(SamplerID samplerPacked, GLenum pname, GLsizei bufSize, \ + GLsizei *length, GLfloat *params); \ + void getFramebufferParameterivRobust(GLenum target, GLenum pname, GLsizei bufSize, \ + GLsizei *length, GLint *params); \ + void getProgramInterfaceivRobust(ShaderProgramID programPacked, GLenum programInterface, \ + GLenum pname, GLsizei bufSize, GLsizei *length, \ + GLint *params); \ + void getBooleani_vRobust(GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, \ + GLboolean *data); \ + void getMultisamplefvRobust(GLenum pname, GLuint index, GLsizei bufSize, GLsizei *length, \ + GLfloat *val); \ + void getTexLevelParameterivRobust(TextureTarget targetPacked, GLint level, GLenum pname, \ + GLsizei bufSize, GLsizei *length, GLint *params); \ + void getTexLevelParameterfvRobust(TextureTarget targetPacked, GLint level, GLenum pname, \ + GLsizei bufSize, GLsizei *length, GLfloat *params); \ + void getPointervRobustANGLERobust(GLenum pname, GLsizei bufSize, GLsizei *length, \ + void **params); \ + void readnPixelsRobust(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, \ + GLenum type, GLsizei bufSize, GLsizei *length, GLsizei *columns, \ + GLsizei *rows, void *data); \ + void getnUniformfvRobust(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei bufSize, GLsizei *length, GLfloat *params); \ + void getnUniformivRobust(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei bufSize, GLsizei *length, GLint *params); \ + void getnUniformuivRobust(ShaderProgramID programPacked, UniformLocation locationPacked, \ + GLsizei bufSize, GLsizei *length, GLuint *params); \ + void texParameterIivRobust(TextureType targetPacked, GLenum pname, GLsizei bufSize, \ + const GLint *params); \ + void texParameterIuivRobust(TextureType targetPacked, GLenum pname, GLsizei bufSize, \ + const GLuint *params); \ + void getTexParameterIivRobust(TextureType targetPacked, GLenum pname, GLsizei bufSize, \ + GLsizei *length, GLint *params); \ + void getTexParameterIuivRobust(TextureType targetPacked, GLenum pname, GLsizei bufSize, \ + GLsizei *length, GLuint *params); \ + void samplerParameterIivRobust(SamplerID samplerPacked, GLenum pname, GLsizei bufSize, \ + const GLint *param); \ + void samplerParameterIuivRobust(SamplerID samplerPacked, GLenum pname, GLsizei bufSize, \ + const GLuint *param); \ + void getSamplerParameterIivRobust(SamplerID samplerPacked, GLenum pname, GLsizei bufSize, \ + GLsizei *length, GLint *params); \ + void getSamplerParameterIuivRobust(SamplerID samplerPacked, GLenum pname, GLsizei bufSize, \ + GLsizei *length, GLuint *params); \ + void getQueryObjectivRobust(QueryID idPacked, GLenum pname, GLsizei bufSize, GLsizei *length, \ + GLint *params); \ + void getQueryObjecti64vRobust(QueryID idPacked, GLenum pname, GLsizei bufSize, \ + GLsizei *length, GLint64 *params); \ + void getQueryObjectui64vRobust(QueryID idPacked, GLenum pname, GLsizei bufSize, \ + GLsizei *length, GLuint64 *params); \ + /* GL_ANGLE_robust_fragment_shader_output */ \ + /* GL_ANGLE_robust_resource_initialization */ \ + /* GL_ANGLE_semaphore_fuchsia */ \ + void importSemaphoreZirconHandle(SemaphoreID semaphorePacked, HandleType handleTypePacked, \ + GLuint handle); \ + /* GL_ANGLE_shader_pixel_local_storage */ \ + void framebufferMemorylessPixelLocalStorage(GLint plane, GLenum internalformat); \ + void framebufferTexturePixelLocalStorage(GLint plane, TextureID backingtexturePacked, \ + GLint level, GLint layer); \ + void beginPixelLocalStorage(GLsizei planes, const GLenum *loadops, const void *cleardata); \ + void endPixelLocalStorage(); \ + void pixelLocalStorageBarrier(); \ + /* GL_ANGLE_shader_pixel_local_storage_coherent */ \ + /* GL_ANGLE_texture_compression_dxt3 */ \ + /* GL_ANGLE_texture_compression_dxt5 */ \ + /* GL_ANGLE_texture_external_update */ \ + void texImage2DExternal(TextureTarget targetPacked, GLint level, GLint internalformat, \ + GLsizei width, GLsizei height, GLint border, GLenum format, \ + GLenum type); \ + void invalidateTexture(TextureType targetPacked); \ + /* GL_ANGLE_texture_multisample */ \ + /* GL_ANGLE_texture_rectangle */ \ + /* GL_ANGLE_vulkan_image */ \ + void acquireTextures(GLuint numTextures, const TextureID *texturesPacked, \ + const GLenum *layouts); \ + void releaseTextures(GLuint numTextures, const TextureID *texturesPacked, GLenum *layouts); \ + /* GL_ANGLE_webgl_compatibility */ \ + /* GL_ANGLE_yuv_internal_format */ \ + /* GL_CHROMIUM_bind_generates_resource */ \ + /* GL_CHROMIUM_bind_uniform_location */ \ + void bindUniformLocation(ShaderProgramID programPacked, UniformLocation locationPacked, \ + const GLchar *name); \ + /* GL_CHROMIUM_color_buffer_float_rgb */ \ + /* GL_CHROMIUM_color_buffer_float_rgba */ \ + /* GL_CHROMIUM_copy_compressed_texture */ \ + void compressedCopyTexture(TextureID sourceIdPacked, TextureID destIdPacked); \ + /* GL_CHROMIUM_copy_texture */ \ + void copyTexture(TextureID sourceIdPacked, GLint sourceLevel, TextureTarget destTargetPacked, \ + TextureID destIdPacked, GLint destLevel, GLint internalFormat, \ + GLenum destType, GLboolean unpackFlipY, GLboolean unpackPremultiplyAlpha, \ + GLboolean unpackUnmultiplyAlpha); \ + void copySubTexture(TextureID sourceIdPacked, GLint sourceLevel, \ + TextureTarget destTargetPacked, TextureID destIdPacked, GLint destLevel, \ + GLint xoffset, GLint yoffset, GLint x, GLint y, GLint width, GLint height, \ + GLboolean unpackFlipY, GLboolean unpackPremultiplyAlpha, \ + GLboolean unpackUnmultiplyAlpha); \ + /* GL_CHROMIUM_framebuffer_mixed_samples */ \ + void coverageModulation(GLenum components); \ + /* GL_CHROMIUM_lose_context */ \ + void loseContext(GraphicsResetStatus currentPacked, GraphicsResetStatus otherPacked); \ + /* GL_CHROMIUM_sync_query */ \ + /* GL_CHROMIUM_texture_filtering_hint */ + +#endif // ANGLE_CONTEXT_API_EXT_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Debug.cpp b/gfx/angle/checkout/src/libANGLE/Debug.cpp new file mode 100644 index 0000000000..da97ae9d9e --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Debug.cpp @@ -0,0 +1,507 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Debug.cpp: Defines debug state used for GL_KHR_debug + +#include "libANGLE/Debug.h" + +#include "common/debug.h" + +#include +#include + +namespace +{ +const char *GLSeverityToString(GLenum severity) +{ + switch (severity) + { + case GL_DEBUG_SEVERITY_HIGH: + return "HIGH"; + case GL_DEBUG_SEVERITY_MEDIUM: + return "MEDIUM"; + case GL_DEBUG_SEVERITY_LOW: + return "LOW"; + case GL_DEBUG_SEVERITY_NOTIFICATION: + default: + return "NOTIFICATION"; + } +} + +const char *EGLMessageTypeToString(egl::MessageType messageType) +{ + switch (messageType) + { + case egl::MessageType::Critical: + return "CRITICAL"; + case egl::MessageType::Error: + return "ERROR"; + case egl::MessageType::Warn: + return "WARNING"; + case egl::MessageType::Info: + default: + return "INFO"; + } +} + +const char *GLMessageTypeToString(GLenum type) +{ + switch (type) + { + case GL_DEBUG_TYPE_ERROR: + return "error"; + case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: + return "deprecated behavior"; + case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: + return "undefined behavior"; + case GL_DEBUG_TYPE_PORTABILITY: + return "portability"; + case GL_DEBUG_TYPE_PERFORMANCE: + return "performance"; + case GL_DEBUG_TYPE_MARKER: + return "marker"; + case GL_DEBUG_TYPE_PUSH_GROUP: + return "start of group"; + case GL_DEBUG_TYPE_POP_GROUP: + return "end of group"; + case GL_DEBUG_TYPE_OTHER: + default: + return "other message"; + } +} +} // namespace + +namespace gl +{ + +Debug::Control::Control() {} + +Debug::Control::~Control() {} + +Debug::Control::Control(const Control &other) = default; + +Debug::Group::Group() {} + +Debug::Group::~Group() {} + +Debug::Group::Group(const Group &other) = default; + +Debug::Debug(bool initialDebugState) + : mOutputEnabled(initialDebugState), + mCallbackFunction(nullptr), + mCallbackUserParam(nullptr), + mMessages(), + mMaxLoggedMessages(0), + mOutputSynchronous(false), + mGroups() +{ + pushDefaultGroup(); +} + +Debug::~Debug() {} + +void Debug::setMaxLoggedMessages(GLuint maxLoggedMessages) +{ + mMaxLoggedMessages = maxLoggedMessages; +} + +void Debug::setOutputEnabled(bool enabled) +{ + mOutputEnabled = enabled; +} + +bool Debug::isOutputEnabled() const +{ + return mOutputEnabled; +} + +void Debug::setOutputSynchronous(bool synchronous) +{ + mOutputSynchronous = synchronous; +} + +bool Debug::isOutputSynchronous() const +{ + return mOutputSynchronous; +} + +void Debug::setCallback(GLDEBUGPROCKHR callback, const void *userParam) +{ + mCallbackFunction = callback; + mCallbackUserParam = userParam; +} + +GLDEBUGPROCKHR Debug::getCallback() const +{ + return mCallbackFunction; +} + +const void *Debug::getUserParam() const +{ + return mCallbackUserParam; +} + +void Debug::insertMessage(GLenum source, + GLenum type, + GLuint id, + GLenum severity, + const std::string &message, + gl::LogSeverity logSeverity, + angle::EntryPoint entryPoint) const +{ + std::string messageCopy(message); + insertMessage(source, type, id, severity, std::move(messageCopy), logSeverity, entryPoint); +} + +void Debug::insertMessage(GLenum source, + GLenum type, + GLuint id, + GLenum severity, + std::string &&message, + gl::LogSeverity logSeverity, + angle::EntryPoint entryPoint) const +{ + { + // output all messages to the debug log + const char *messageTypeString = GLMessageTypeToString(type); + const char *severityString = GLSeverityToString(severity); + std::ostringstream messageStream; + if (entryPoint != angle::EntryPoint::GLInvalid) + { + messageStream << GetEntryPointName(entryPoint) << ": "; + } + messageStream << "GL " << messageTypeString << ": " << severityString << ": " << message; + switch (logSeverity) + { + case gl::LOG_FATAL: + FATAL() << messageStream.str(); + break; + case gl::LOG_ERR: + ERR() << messageStream.str(); + break; + case gl::LOG_WARN: + WARN() << messageStream.str(); + break; + case gl::LOG_INFO: + INFO() << messageStream.str(); + break; + case gl::LOG_EVENT: + ANGLE_LOG(EVENT) << messageStream.str(); + break; + } + } + + if (!isMessageEnabled(source, type, id, severity)) + { + return; + } + + if (mCallbackFunction != nullptr) + { + // TODO(geofflang) Check the synchronous flag and potentially flush messages from another + // thread. + mCallbackFunction(source, type, id, severity, static_cast(message.length()), + message.c_str(), mCallbackUserParam); + } + else + { + if (mMessages.size() >= mMaxLoggedMessages) + { + // Drop messages over the limit + return; + } + + Message m; + m.source = source; + m.type = type; + m.id = id; + m.severity = severity; + m.message = std::move(message); + + mMessages.push_back(std::move(m)); + } +} + +size_t Debug::getMessages(GLuint count, + GLsizei bufSize, + GLenum *sources, + GLenum *types, + GLuint *ids, + GLenum *severities, + GLsizei *lengths, + GLchar *messageLog) +{ + size_t messageCount = 0; + size_t messageStringIndex = 0; + while (messageCount <= count && !mMessages.empty()) + { + const Message &m = mMessages.front(); + + if (messageLog != nullptr) + { + // Check that this message can fit in the message buffer + if (messageStringIndex + m.message.length() + 1 > static_cast(bufSize)) + { + break; + } + + std::copy(m.message.begin(), m.message.end(), messageLog + messageStringIndex); + messageStringIndex += m.message.length(); + + messageLog[messageStringIndex] = '\0'; + messageStringIndex += 1; + } + + if (sources != nullptr) + { + sources[messageCount] = m.source; + } + + if (types != nullptr) + { + types[messageCount] = m.type; + } + + if (ids != nullptr) + { + ids[messageCount] = m.id; + } + + if (severities != nullptr) + { + severities[messageCount] = m.severity; + } + + if (lengths != nullptr) + { + lengths[messageCount] = static_cast(m.message.length()) + 1; + } + + mMessages.pop_front(); + + messageCount++; + } + + return messageCount; +} + +size_t Debug::getNextMessageLength() const +{ + return mMessages.empty() ? 0 : mMessages.front().message.length() + 1; +} + +size_t Debug::getMessageCount() const +{ + return mMessages.size(); +} + +void Debug::setMessageControl(GLenum source, + GLenum type, + GLenum severity, + std::vector &&ids, + bool enabled) +{ + Control c; + c.source = source; + c.type = type; + c.severity = severity; + c.ids = std::move(ids); + c.enabled = enabled; + + auto &controls = mGroups.back().controls; + controls.push_back(std::move(c)); +} + +void Debug::pushGroup(GLenum source, GLuint id, std::string &&message) +{ + insertMessage(source, GL_DEBUG_TYPE_PUSH_GROUP, id, GL_DEBUG_SEVERITY_NOTIFICATION, + std::string(message), gl::LOG_INFO, angle::EntryPoint::GLPushDebugGroup); + + Group g; + g.source = source; + g.id = id; + g.message = std::move(message); + mGroups.push_back(std::move(g)); +} + +void Debug::popGroup() +{ + // Make sure the default group is not about to be popped + ASSERT(mGroups.size() > 1); + + Group g = mGroups.back(); + mGroups.pop_back(); + + insertMessage(g.source, GL_DEBUG_TYPE_POP_GROUP, g.id, GL_DEBUG_SEVERITY_NOTIFICATION, + g.message, gl::LOG_INFO, angle::EntryPoint::GLPopDebugGroup); +} + +size_t Debug::getGroupStackDepth() const +{ + return mGroups.size(); +} + +void Debug::insertPerfWarning(GLenum severity, const char *message, uint32_t *repeatCount) const +{ + bool repeatLast; + + { + constexpr uint32_t kMaxRepeat = 4; + std::lock_guard lock(GetDebugMutex()); + + if (*repeatCount >= kMaxRepeat) + { + return; + } + + ++*repeatCount; + repeatLast = (*repeatCount == kMaxRepeat); + } + + std::string msg = message; + if (repeatLast) + { + msg += " (this message will no longer repeat)"; + } + + // Release the lock before we call insertMessage. It will re-acquire the lock. + insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_PERFORMANCE, 0, severity, std::move(msg), + gl::LOG_INFO, angle::EntryPoint::GLInvalid); +} + +bool Debug::isMessageEnabled(GLenum source, GLenum type, GLuint id, GLenum severity) const +{ + if (!mOutputEnabled) + { + return false; + } + + for (auto groupIter = mGroups.rbegin(); groupIter != mGroups.rend(); groupIter++) + { + const auto &controls = groupIter->controls; + for (auto controlIter = controls.rbegin(); controlIter != controls.rend(); controlIter++) + { + const auto &control = *controlIter; + + if (control.source != GL_DONT_CARE && control.source != source) + { + continue; + } + + if (control.type != GL_DONT_CARE && control.type != type) + { + continue; + } + + if (control.severity != GL_DONT_CARE && control.severity != severity) + { + continue; + } + + if (!control.ids.empty() && + std::find(control.ids.begin(), control.ids.end(), id) == control.ids.end()) + { + continue; + } + + return control.enabled; + } + } + + return true; +} + +void Debug::pushDefaultGroup() +{ + Group g; + g.source = GL_NONE; + g.id = 0; + g.message = ""; + + Control c0; + c0.source = GL_DONT_CARE; + c0.type = GL_DONT_CARE; + c0.severity = GL_DONT_CARE; + c0.enabled = true; + g.controls.push_back(std::move(c0)); + + Control c1; + c1.source = GL_DONT_CARE; + c1.type = GL_DONT_CARE; + c1.severity = GL_DEBUG_SEVERITY_LOW; + c1.enabled = false; + g.controls.push_back(std::move(c1)); + + mGroups.push_back(std::move(g)); +} +} // namespace gl + +namespace egl +{ + +namespace +{ +angle::PackedEnumBitSet GetDefaultMessageTypeBits() +{ + angle::PackedEnumBitSet result; + result.set(MessageType::Critical); + result.set(MessageType::Error); + return result; +} +} // anonymous namespace + +Debug::Debug() : mCallback(nullptr), mEnabledMessageTypes(GetDefaultMessageTypeBits()) {} + +void Debug::setCallback(EGLDEBUGPROCKHR callback, const AttributeMap &attribs) +{ + mCallback = callback; + + const angle::PackedEnumBitSet defaultMessageTypes = GetDefaultMessageTypeBits(); + if (mCallback != nullptr) + { + for (MessageType messageType : angle::AllEnums()) + { + mEnabledMessageTypes[messageType] = + (attribs.getAsInt(egl::ToEGLenum(messageType), defaultMessageTypes[messageType]) == + EGL_TRUE); + } + } +} + +EGLDEBUGPROCKHR Debug::getCallback() const +{ + return mCallback; +} + +bool Debug::isMessageTypeEnabled(MessageType type) const +{ + return mEnabledMessageTypes[type]; +} + +void Debug::insertMessage(EGLenum error, + const char *command, + MessageType messageType, + EGLLabelKHR threadLabel, + EGLLabelKHR objectLabel, + const std::string &message) const +{ + { + // output all messages to the debug log + const char *messageTypeString = EGLMessageTypeToString(messageType); + std::ostringstream messageStream; + messageStream << "EGL " << messageTypeString << ": " << command << ": " << message; + INFO() << messageStream.str(); + } + + // TODO(geofflang): Lock before checking the callback. http://anglebug.com/2464 + if (mCallback && isMessageTypeEnabled(messageType)) + { + mCallback(error, command, egl::ToEGLenum(messageType), threadLabel, objectLabel, + message.c_str()); + } +} + +} // namespace egl diff --git a/gfx/angle/checkout/src/libANGLE/Debug.h b/gfx/angle/checkout/src/libANGLE/Debug.h new file mode 100644 index 0000000000..873a60df6f --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Debug.h @@ -0,0 +1,180 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Debug.h: Defines debug state used for GL_KHR_debug + +#ifndef LIBANGLE_DEBUG_H_ +#define LIBANGLE_DEBUG_H_ + +#include "angle_gl.h" +#include "common/PackedEnums.h" +#include "common/angleutils.h" +#include "libANGLE/AttributeMap.h" +#include "libANGLE/Error.h" + +#include +#include +#include + +namespace gl +{ +class Context; + +class LabeledObject +{ + public: + virtual ~LabeledObject() {} + virtual angle::Result setLabel(const Context *context, const std::string &label) = 0; + virtual const std::string &getLabel() const = 0; +}; + +class Debug : angle::NonCopyable +{ + public: + Debug(bool initialDebugState); + ~Debug(); + + void setMaxLoggedMessages(GLuint maxLoggedMessages); + + void setOutputEnabled(bool enabled); + bool isOutputEnabled() const; + + void setOutputSynchronous(bool synchronous); + bool isOutputSynchronous() const; + + void setCallback(GLDEBUGPROCKHR callback, const void *userParam); + GLDEBUGPROCKHR getCallback() const; + const void *getUserParam() const; + + void insertMessage(GLenum source, + GLenum type, + GLuint id, + GLenum severity, + const std::string &message, + gl::LogSeverity logSeverity, + angle::EntryPoint entryPoint) const; + void insertMessage(GLenum source, + GLenum type, + GLuint id, + GLenum severity, + std::string &&message, + gl::LogSeverity logSeverity, + angle::EntryPoint entryPoint) const; + + void setMessageControl(GLenum source, + GLenum type, + GLenum severity, + std::vector &&ids, + bool enabled); + size_t getMessages(GLuint count, + GLsizei bufSize, + GLenum *sources, + GLenum *types, + GLuint *ids, + GLenum *severities, + GLsizei *lengths, + GLchar *messageLog); + size_t getNextMessageLength() const; + size_t getMessageCount() const; + + void pushGroup(GLenum source, GLuint id, std::string &&message); + void popGroup(); + size_t getGroupStackDepth() const; + + // Helper for ANGLE_PERF_WARNING + void insertPerfWarning(GLenum severity, const char *message, uint32_t *repeatCount) const; + + private: + bool isMessageEnabled(GLenum source, GLenum type, GLuint id, GLenum severity) const; + + void pushDefaultGroup(); + + struct Message + { + GLenum source; + GLenum type; + GLuint id; + GLenum severity; + std::string message; + }; + + struct Control + { + Control(); + ~Control(); + Control(const Control &other); + + GLenum source; + GLenum type; + GLenum severity; + std::vector ids; + bool enabled; + }; + + struct Group + { + Group(); + ~Group(); + Group(const Group &other); + + GLenum source; + GLuint id; + std::string message; + + std::vector controls; + }; + + bool mOutputEnabled; + GLDEBUGPROCKHR mCallbackFunction; + const void *mCallbackUserParam; + mutable std::deque mMessages; + GLuint mMaxLoggedMessages; + bool mOutputSynchronous; + std::vector mGroups; +}; +} // namespace gl + +namespace egl +{ +class LabeledObject +{ + public: + virtual ~LabeledObject() {} + virtual void setLabel(EGLLabelKHR label) = 0; + virtual EGLLabelKHR getLabel() const = 0; +}; + +class Debug : angle::NonCopyable +{ + public: + Debug(); + + void setCallback(EGLDEBUGPROCKHR callback, const AttributeMap &attribs); + EGLDEBUGPROCKHR getCallback() const; + bool isMessageTypeEnabled(MessageType type) const; + + void insertMessage(EGLenum error, + const char *command, + MessageType messageType, + EGLLabelKHR threadLabel, + EGLLabelKHR objectLabel, + const std::string &message) const; + + private: + EGLDEBUGPROCKHR mCallback; + angle::PackedEnumBitSet mEnabledMessageTypes; +}; +} // namespace egl + +// Generate a perf warning. Only outputs the same message a few times to avoid spamming the logs. +#define ANGLE_PERF_WARNING(debug, severity, message) \ + do \ + { \ + static uint32_t sRepeatCount = 0; \ + (debug).insertPerfWarning(severity, message, &sRepeatCount); \ + } while (0) + +#endif // LIBANGLE_DEBUG_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Device.cpp b/gfx/angle/checkout/src/libANGLE/Device.cpp new file mode 100644 index 0000000000..550708fd13 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Device.cpp @@ -0,0 +1,133 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Device.cpp: Implements the egl::Device class, representing the abstract +// device. Implements EGLDevice. + +#include "libANGLE/Device.h" + +#include + +#include +#include + +#include "anglebase/no_destructor.h" +#include "common/debug.h" +#include "common/platform.h" +#include "libANGLE/renderer/DeviceImpl.h" + +#if defined(ANGLE_ENABLE_D3D11) +# include "libANGLE/renderer/d3d/DeviceD3D.h" +#endif + +namespace egl +{ + +template +static std::string GenerateExtensionsString(const T &extensions) +{ + std::vector extensionsVector = extensions.getStrings(); + + std::ostringstream stream; + std::copy(extensionsVector.begin(), extensionsVector.end(), + std::ostream_iterator(stream, " ")); + return stream.str(); +} + +typedef std::set DeviceSet; +static DeviceSet *GetDeviceSet() +{ + static angle::base::NoDestructor devices; + return devices.get(); +} + +// Static factory methods +egl::Error Device::CreateDevice(EGLint deviceType, void *nativeDevice, Device **outDevice) +{ + *outDevice = nullptr; + + std::unique_ptr newDeviceImpl; + +#if defined(ANGLE_ENABLE_D3D11) + if (deviceType == EGL_D3D11_DEVICE_ANGLE) + { + newDeviceImpl.reset(new rx::DeviceD3D(deviceType, nativeDevice)); + } +#endif + + // Note that creating an EGL device from inputted D3D9 parameters isn't currently supported + + if (newDeviceImpl == nullptr) + { + return EglBadAttribute(); + } + + ANGLE_TRY(newDeviceImpl->initialize()); + *outDevice = new Device(nullptr, newDeviceImpl.release()); + + return NoError(); +} + +bool Device::IsValidDevice(const Device *device) +{ + const DeviceSet *deviceSet = GetDeviceSet(); + return deviceSet->find(const_cast(device)) != deviceSet->end(); +} + +Device::Device(Display *owningDisplay, rx::DeviceImpl *impl) + : mLabel(nullptr), mOwningDisplay(owningDisplay), mImplementation(impl) +{ + ASSERT(GetDeviceSet()->find(this) == GetDeviceSet()->end()); + GetDeviceSet()->insert(this); + initDeviceExtensions(); +} + +Device::~Device() +{ + ASSERT(GetDeviceSet()->find(this) != GetDeviceSet()->end()); + GetDeviceSet()->erase(this); +} + +void Device::setLabel(EGLLabelKHR label) +{ + mLabel = label; +} + +EGLLabelKHR Device::getLabel() const +{ + return mLabel; +} + +Error Device::getAttribute(EGLint attribute, EGLAttrib *value) +{ + void *nativeAttribute = nullptr; + egl::Error error = + getImplementation()->getAttribute(getOwningDisplay(), attribute, &nativeAttribute); + *value = reinterpret_cast(nativeAttribute); + return error; +} + +EGLint Device::getType() const +{ + return mImplementation.get()->getType(); +} + +void Device::initDeviceExtensions() +{ + mImplementation->generateExtensions(&mDeviceExtensions); + mDeviceExtensionString = GenerateExtensionsString(mDeviceExtensions); +} + +const DeviceExtensions &Device::getExtensions() const +{ + return mDeviceExtensions; +} + +const std::string &Device::getExtensionString() const +{ + return mDeviceExtensionString; +} +} // namespace egl diff --git a/gfx/angle/checkout/src/libANGLE/Device.h b/gfx/angle/checkout/src/libANGLE/Device.h new file mode 100644 index 0000000000..8fbdf72e68 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Device.h @@ -0,0 +1,60 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Device.h: Implements the egl::Device class, representing the abstract +// device. Implements EGLDevice. + +#ifndef LIBANGLE_DEVICE_H_ +#define LIBANGLE_DEVICE_H_ + +#include "common/angleutils.h" +#include "libANGLE/Display.h" +#include "libANGLE/Error.h" + +#include + +namespace rx +{ +class DeviceImpl; +} // namespace rx + +namespace egl +{ +class Device final : public LabeledObject, angle::NonCopyable +{ + public: + Device(Display *owningDisplay, rx::DeviceImpl *impl); + ~Device() override; + + void setLabel(EGLLabelKHR label) override; + EGLLabelKHR getLabel() const override; + + Error getAttribute(EGLint attribute, EGLAttrib *value); + Display *getOwningDisplay() const { return mOwningDisplay; } + EGLint getType() const; + + const DeviceExtensions &getExtensions() const; + const std::string &getExtensionString() const; + + rx::DeviceImpl *getImplementation() { return mImplementation.get(); } + + static egl::Error CreateDevice(EGLint deviceType, void *nativeDevice, Device **outDevice); + static bool IsValidDevice(const Device *device); + + private: + void initDeviceExtensions(); + + EGLLabelKHR mLabel; + + Display *mOwningDisplay; + std::unique_ptr mImplementation; + + DeviceExtensions mDeviceExtensions; + std::string mDeviceExtensionString; +}; +} // namespace egl + +#endif // LIBANGLE_DEVICE_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Display.cpp b/gfx/angle/checkout/src/libANGLE/Display.cpp new file mode 100644 index 0000000000..4b7ced36fb --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Display.cpp @@ -0,0 +1,2506 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Display.cpp: Implements the egl::Display class, representing the abstract +// display on which graphics are drawn. Implements EGLDisplay. +// [EGL 1.4] section 2.1.2 page 3. + +#include "libANGLE/Display.h" + +#include +#include +#include +#include + +#include +#include + +#include "anglebase/no_destructor.h" +#include "common/android_util.h" +#include "common/debug.h" +#include "common/mathutil.h" +#include "common/platform.h" +#include "common/string_utils.h" +#include "common/system_utils.h" +#include "common/tls.h" +#include "common/utilities.h" +#include "gpu_info_util/SystemInfo.h" +#include "libANGLE/Context.h" +#include "libANGLE/Device.h" +#include "libANGLE/EGLSync.h" +#include "libANGLE/Image.h" +#include "libANGLE/ResourceManager.h" +#include "libANGLE/Stream.h" +#include "libANGLE/Surface.h" +#include "libANGLE/Thread.h" +#include "libANGLE/capture/FrameCapture.h" +#include "libANGLE/histogram_macros.h" +#include "libANGLE/renderer/DeviceImpl.h" +#include "libANGLE/renderer/DisplayImpl.h" +#include "libANGLE/renderer/ImageImpl.h" +#include "libANGLE/trace.h" + +#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11) +# include + +# include "libANGLE/renderer/d3d/DisplayD3D.h" +#endif + +#if defined(ANGLE_ENABLE_OPENGL) +# if defined(ANGLE_PLATFORM_WINDOWS) +# include "libANGLE/renderer/gl/wgl/DisplayWGL.h" +# elif defined(ANGLE_PLATFORM_MACOS) || defined(ANGLE_PLATFORM_IOS) +# include "libANGLE/renderer/gl/apple/DisplayApple_api.h" +# elif defined(ANGLE_PLATFORM_LINUX) +# include "libANGLE/renderer/gl/egl/DisplayEGL.h" +# if defined(ANGLE_USE_GBM) +# include "libANGLE/renderer/gl/egl/gbm/DisplayGbm.h" +# endif +# if defined(ANGLE_USE_X11) +# include "libANGLE/renderer/gl/glx/DisplayGLX.h" +# endif +# elif defined(ANGLE_PLATFORM_ANDROID) +# include "libANGLE/renderer/gl/egl/android/DisplayAndroid.h" +# else +# error Unsupported OpenGL platform. +# endif +#endif + +#if defined(ANGLE_ENABLE_NULL) +# include "libANGLE/renderer/null/DisplayNULL.h" +#endif // defined(ANGLE_ENABLE_NULL) + +#if defined(ANGLE_ENABLE_VULKAN) +# include "libANGLE/renderer/vulkan/DisplayVk_api.h" +#endif // defined(ANGLE_ENABLE_VULKAN) + +#if defined(ANGLE_ENABLE_METAL) +# include "libANGLE/renderer/metal/DisplayMtl_api.h" +#endif // defined(ANGLE_ENABLE_METAL) + +namespace egl +{ + +namespace +{ + +constexpr angle::SubjectIndex kGPUSwitchedSubjectIndex = 0; + +static constexpr size_t kWindowSurfaceMapSize = 32; +typedef angle::FlatUnorderedMap + WindowSurfaceMap; +// Get a map of all EGL window surfaces to validate that no window has more than one EGL surface +// associated with it. +static WindowSurfaceMap *GetWindowSurfaces() +{ + static angle::base::NoDestructor windowSurfaces; + return windowSurfaces.get(); +} + +struct ANGLEPlatformDisplay +{ + ANGLEPlatformDisplay() = default; + + ANGLEPlatformDisplay(EGLNativeDisplayType nativeDisplayType) + : nativeDisplayType(nativeDisplayType) + {} + + ANGLEPlatformDisplay(EGLNativeDisplayType nativeDisplayType, + EGLAttrib powerPreference, + EGLAttrib platformANGLEType, + EGLAttrib deviceIdHigh, + EGLAttrib deviceIdLow) + : nativeDisplayType(nativeDisplayType), + powerPreference(powerPreference), + platformANGLEType(platformANGLEType), + deviceIdHigh(deviceIdHigh), + deviceIdLow(deviceIdLow) + {} + + auto tie() const + { + return std::tie(nativeDisplayType, powerPreference, platformANGLEType, deviceIdHigh, + deviceIdLow); + } + + EGLNativeDisplayType nativeDisplayType{EGL_DEFAULT_DISPLAY}; + EGLAttrib powerPreference{EGL_LOW_POWER_ANGLE}; + EGLAttrib platformANGLEType{EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE}; + EGLAttrib deviceIdHigh{0}; + EGLAttrib deviceIdLow{0}; +}; + +inline bool operator==(const ANGLEPlatformDisplay &a, const ANGLEPlatformDisplay &b) +{ + return a.tie() == b.tie(); +} + +static constexpr size_t kANGLEPlatformDisplayMapSize = 9; +typedef angle::FlatUnorderedMap + ANGLEPlatformDisplayMap; +static ANGLEPlatformDisplayMap *GetANGLEPlatformDisplayMap() +{ + static angle::base::NoDestructor displays; + return displays.get(); +} + +static constexpr size_t kDevicePlatformDisplayMapSize = 8; +typedef angle::FlatUnorderedMap + DevicePlatformDisplayMap; +static DevicePlatformDisplayMap *GetDevicePlatformDisplayMap() +{ + static angle::base::NoDestructor displays; + return displays.get(); +} + +rx::DisplayImpl *CreateDisplayFromDevice(Device *eglDevice, const DisplayState &state) +{ + rx::DisplayImpl *impl = nullptr; + + switch (eglDevice->getType()) + { +#if defined(ANGLE_ENABLE_D3D11) + case EGL_D3D11_DEVICE_ANGLE: + impl = new rx::DisplayD3D(state); + break; +#endif +#if defined(ANGLE_ENABLE_D3D9) + case EGL_D3D9_DEVICE_ANGLE: + // Currently the only way to get EGLDeviceEXT representing a D3D9 device + // is to retrieve one from an already-existing EGLDisplay. + // When eglGetPlatformDisplayEXT is called with a D3D9 EGLDeviceEXT, + // the already-existing display should be returned. + // Therefore this codepath to create a new display from the device + // should never be hit. + UNREACHABLE(); + break; +#endif + default: + UNREACHABLE(); + break; + } + + ASSERT(impl != nullptr); + return impl; +} + +// On platforms with support for multiple back-ends, allow an environment variable to control +// the default. This is useful to run angle with benchmarks without having to modify the +// benchmark source. Possible values for this environment variable (ANGLE_DEFAULT_PLATFORM) +// are: vulkan, gl, d3d11, null. +EGLAttrib GetDisplayTypeFromEnvironment() +{ + std::string angleDefaultEnv = angle::GetEnvironmentVar("ANGLE_DEFAULT_PLATFORM"); + angle::ToLower(&angleDefaultEnv); + +#if defined(ANGLE_ENABLE_VULKAN) + if ((angleDefaultEnv == "vulkan") || (angleDefaultEnv == "vulkan-null") || + (angleDefaultEnv == "swiftshader")) + { + return EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE; + } +#endif + +#if defined(ANGLE_ENABLE_OPENGL) + if (angleDefaultEnv == "gl") + { + return EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE; + } +#endif + +#if defined(ANGLE_ENABLE_D3D11) + if (angleDefaultEnv == "d3d11") + { + return EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE; + } +#endif + +#if defined(ANGLE_ENABLE_METAL) + if (angleDefaultEnv == "metal") + { + return EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE; + } +#endif + +#if defined(ANGLE_ENABLE_NULL) + if (angleDefaultEnv == "null") + { + return EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE; + } +#endif +#if defined(ANGLE_ENABLE_METAL) + if (angleDefaultEnv == "metal") + { + return EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE; + } + +#endif +#if defined(ANGLE_ENABLE_D3D11) + return EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE; +#elif defined(ANGLE_ENABLE_D3D9) + return EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE; +#elif defined(ANGLE_ENABLE_VULKAN) && defined(ANGLE_PLATFORM_ANDROID) + return EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE; +#elif defined(ANGLE_ENABLE_OPENGL) +# if defined(ANGLE_PLATFORM_ANDROID) || defined(ANGLE_USE_GBM) + return EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE; +# else + return EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE; +# endif +#elif defined(ANGLE_ENABLE_METAL) + return EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE; +#elif defined(ANGLE_ENABLE_VULKAN) + return EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE; +#elif defined(ANGLE_ENABLE_NULL) + return EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE; +#else +# error No default ANGLE platform type +#endif +} + +EGLAttrib GetDeviceTypeFromEnvironment() +{ + std::string angleDefaultEnv = angle::GetEnvironmentVar("ANGLE_DEFAULT_PLATFORM"); + angle::ToLower(&angleDefaultEnv); + +#if defined(ANGLE_ENABLE_VULKAN) + if (angleDefaultEnv == "vulkan-null") + { + return EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE; + } + else if (angleDefaultEnv == "swiftshader") + { + return EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE; + } +#endif + return EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE; +} + +EGLAttrib GetPlatformTypeFromEnvironment() +{ +#if defined(ANGLE_USE_OZONE) + return 0; +#elif defined(ANGLE_USE_X11) + return EGL_PLATFORM_X11_EXT; +#elif defined(ANGLE_USE_WAYLAND) + return EGL_PLATFORM_WAYLAND_EXT; +#elif defined(ANGLE_USE_VULKAN_DISPLAY) && defined(ANGLE_VULKAN_DISPLAY_MODE_SIMPLE) + return EGL_PLATFORM_VULKAN_DISPLAY_MODE_SIMPLE_ANGLE; +#elif defined(ANGLE_USE_VULKAN_DISPLAY) && defined(ANGLE_VULKAN_DISPLAY_MODE_HEADLESS) + return EGL_PLATFORM_VULKAN_DISPLAY_MODE_HEADLESS_ANGLE; +#else + return 0; +#endif // defined(ANGLE_USE_OZONE) +} + +rx::DisplayImpl *CreateDisplayFromAttribs(EGLAttrib displayType, + EGLAttrib deviceType, + EGLAttrib platformType, + const DisplayState &state) +{ + ASSERT(displayType != EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE); + rx::DisplayImpl *impl = nullptr; + + switch (displayType) + { + case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE: + UNREACHABLE(); + break; + + case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE: + case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE: +#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11) + impl = new rx::DisplayD3D(state); + break; +#else + // A D3D display was requested on a platform that doesn't support it + UNREACHABLE(); + break; +#endif + + case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE: +#if defined(ANGLE_ENABLE_OPENGL) +# if defined(ANGLE_PLATFORM_WINDOWS) + impl = new rx::DisplayWGL(state); + break; + +# elif defined(ANGLE_PLATFORM_MACOS) || defined(ANGLE_PLATFORM_IOS) + impl = rx::CreateDisplayCGLOrEAGL(state); + break; + +# elif defined(ANGLE_PLATFORM_LINUX) +# if defined(ANGLE_USE_GBM) + if (platformType == 0) + { + // If platformType is unknown, use DisplayGbm now. In the future, it should use + // DisplayEGL letting native EGL decide what display to use. + impl = new rx::DisplayGbm(state); + break; + } +# endif + if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_EGL_ANGLE) + { + impl = new rx::DisplayEGL(state); + break; + } +# if defined(ANGLE_USE_X11) + if (platformType == EGL_PLATFORM_X11_EXT) + { + impl = new rx::DisplayGLX(state); + break; + } +# endif + break; + +# elif defined(ANGLE_PLATFORM_ANDROID) + // No GL support on this platform, fail display creation. + impl = nullptr; + break; + +# else +# error Unsupported OpenGL platform. +# endif +#else + // No display available + UNREACHABLE(); + break; + +#endif // defined(ANGLE_ENABLE_OPENGL) + + case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE: +#if defined(ANGLE_ENABLE_OPENGL) +# if defined(ANGLE_PLATFORM_WINDOWS) + impl = new rx::DisplayWGL(state); +# elif defined(ANGLE_PLATFORM_LINUX) +# if defined(ANGLE_USE_GBM) + if (platformType == 0 || + platformType == EGL_PLATFORM_VULKAN_DISPLAY_MODE_HEADLESS_ANGLE) + { + // If platformType is unknown, use DisplayGbm now. In the future, it should use + // DisplayEGL letting native EGL decide what display to use. + // platformType == EGL_PLATFORM_VULKAN_DISPLAY_MODE_HEADLESS_ANGLE is a hack, + // to allow ChromeOS GLES backend to continue functioning when Vulkan is enabled. + impl = new rx::DisplayGbm(state); + break; + } +# endif + if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_EGL_ANGLE) + { + impl = new rx::DisplayEGL(state); + break; + } + else + { +# if defined(ANGLE_USE_X11) + if (platformType == EGL_PLATFORM_X11_EXT) + { + impl = new rx::DisplayGLX(state); + break; + } +# endif + } +# elif defined(ANGLE_PLATFORM_ANDROID) + impl = new rx::DisplayAndroid(state); +# else + // No GLES support on this platform, fail display creation. + impl = nullptr; +# endif +#endif // defined(ANGLE_ENABLE_OPENGL) + break; + + case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE: +#if defined(ANGLE_ENABLE_VULKAN) +# if defined(ANGLE_USE_VULKAN_NULL_DISPLAY) + if (rx::IsVulkanNullDisplayAvailable()) + { + impl = rx::CreateVulkanNullDisplay(state); + } + break; +# elif defined(ANGLE_PLATFORM_WINDOWS) + if (rx::IsVulkanWin32DisplayAvailable()) + { + impl = rx::CreateVulkanWin32Display(state); + } + break; +# elif defined(ANGLE_PLATFORM_LINUX) +# if defined(ANGLE_USE_GBM) + if (platformType == EGL_PLATFORM_GBM_KHR && rx::IsVulkanGbmDisplayAvailable()) + { + impl = rx::CreateVulkanGbmDisplay(state); + break; + } +# endif +# if defined(ANGLE_USE_X11) + if (platformType == EGL_PLATFORM_X11_EXT && rx::IsVulkanXcbDisplayAvailable()) + { + impl = rx::CreateVulkanXcbDisplay(state); + break; + } +# endif +# if defined(ANGLE_USE_WAYLAND) + if (platformType == EGL_PLATFORM_WAYLAND_EXT && rx::IsVulkanWaylandDisplayAvailable()) + { + impl = rx::CreateVulkanWaylandDisplay(state); + break; + } +# endif +# if defined(ANGLE_USE_VULKAN_DISPLAY) + if (platformType == EGL_PLATFORM_VULKAN_DISPLAY_MODE_SIMPLE_ANGLE && + rx::IsVulkanSimpleDisplayAvailable()) + { + impl = rx::CreateVulkanSimpleDisplay(state); + } + else if (platformType == EGL_PLATFORM_VULKAN_DISPLAY_MODE_HEADLESS_ANGLE && + rx::IsVulkanHeadlessDisplayAvailable()) + { + impl = rx::CreateVulkanHeadlessDisplay(state); + } + else + { + // Not supported creation type on vulkan display, fail display creation. + impl = nullptr; + } +# endif + break; +# elif defined(ANGLE_PLATFORM_ANDROID) + if (rx::IsVulkanAndroidDisplayAvailable()) + { + impl = rx::CreateVulkanAndroidDisplay(state); + } + break; +# elif defined(ANGLE_PLATFORM_FUCHSIA) + if (rx::IsVulkanFuchsiaDisplayAvailable()) + { + impl = rx::CreateVulkanFuchsiaDisplay(state); + } + break; +# elif defined(ANGLE_PLATFORM_GGP) + if (rx::IsVulkanGGPDisplayAvailable()) + { + impl = rx::CreateVulkanGGPDisplay(state); + } + break; +# elif defined(ANGLE_PLATFORM_APPLE) + if (rx::IsVulkanMacDisplayAvailable()) + { + impl = rx::CreateVulkanMacDisplay(state); + } + break; +# else +# error Unsupported Vulkan platform. +# endif +#else + // No display available + UNREACHABLE(); + break; +#endif // defined(ANGLE_ENABLE_VULKAN) + + case EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE: +#if defined(ANGLE_ENABLE_METAL) + if (rx::IsMetalDisplayAvailable()) + { + impl = rx::CreateMetalDisplay(state); + break; + } +#endif + // No display available + UNREACHABLE(); + break; + + case EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE: +#if defined(ANGLE_ENABLE_NULL) + impl = new rx::DisplayNULL(state); + break; +#else + // No display available + UNREACHABLE(); + break; +#endif // defined(ANGLE_ENABLE_NULL) + + default: + UNREACHABLE(); + break; + } + + return impl; +} + +void Display_logError(angle::PlatformMethods *platform, const char *errorMessage) +{ + gl::Trace(gl::LOG_ERR, errorMessage); +} + +void Display_logWarning(angle::PlatformMethods *platform, const char *warningMessage) +{ + gl::Trace(gl::LOG_WARN, warningMessage); +} + +void Display_logInfo(angle::PlatformMethods *platform, const char *infoMessage) +{ + // Uncomment to get info spam +#if defined(ANGLE_ENABLE_DEBUG_TRACE) + gl::Trace(gl::LOG_INFO, infoMessage); +#endif +} + +const std::vector EGLStringArrayToStringVector(const char **ary) +{ + std::vector vec; + if (ary != nullptr) + { + for (; *ary != nullptr; ary++) + { + vec.push_back(std::string(*ary)); + } + } + return vec; +} + +void ANGLESetDefaultDisplayPlatform(angle::EGLDisplayType display) +{ + angle::PlatformMethods *platformMethods = ANGLEPlatformCurrent(); + + ANGLEResetDisplayPlatform(display); + platformMethods->logError = Display_logError; + platformMethods->logWarning = Display_logWarning; + platformMethods->logInfo = Display_logInfo; +} + +void UpdateAttribsFromEnvironment(AttributeMap &attribMap) +{ + EGLAttrib displayType = + attribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE); + if (displayType == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE) + { + displayType = GetDisplayTypeFromEnvironment(); + attribMap.insert(EGL_PLATFORM_ANGLE_TYPE_ANGLE, displayType); + } + EGLAttrib deviceType = attribMap.get(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, 0); + if (deviceType == 0) + { + deviceType = GetDeviceTypeFromEnvironment(); + attribMap.insert(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, deviceType); + } + EGLAttrib platformType = attribMap.get(EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE, 0); + if (platformType == 0) + { + platformType = GetPlatformTypeFromEnvironment(); + attribMap.insert(EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE, platformType); + } +} + +static constexpr uint32_t kScratchBufferLifetime = 64u; + +} // anonymous namespace + +// ShareGroup +ShareGroup::ShareGroup(rx::EGLImplFactory *factory) + : mRefCount(1), + mImplementation(factory->createShareGroup()), + mFrameCaptureShared(new angle::FrameCaptureShared) +{} + +void ShareGroup::finishAllContexts() +{ + for (gl::Context *shareContext : mContexts) + { + if (shareContext->hasBeenCurrent() && !shareContext->isDestroyed()) + { + shareContext->finish(); + } + } +} + +void ShareGroup::addSharedContext(gl::Context *context) +{ + mContexts.insert(context); + + if (context->isRobustnessEnabled()) + { + mImplementation->onRobustContextAdd(); + } +} + +void ShareGroup::removeSharedContext(gl::Context *context) +{ + mContexts.erase(context); +} + +ShareGroup::~ShareGroup() +{ + SafeDelete(mImplementation); +} + +void ShareGroup::addRef() +{ + // This is protected by global lock, so no atomic is required + mRefCount++; +} + +void ShareGroup::release(const Display *display) +{ + if (--mRefCount == 0) + { + if (mImplementation) + { + mImplementation->onDestroy(display); + } + delete this; + } +} + +// DisplayState +DisplayState::DisplayState(EGLNativeDisplayType nativeDisplayId) + : label(nullptr), featuresAllDisabled(false), displayId(nativeDisplayId) +{} + +DisplayState::~DisplayState() {} + +// Note that ANGLE support on Ozone platform is limited. Our preferred support Matrix for +// EGL_ANGLE_platform_angle on Linux and Ozone/Linux/Fuchsia platforms should be the following: +// +// |--------------------------------------------------------| +// | ANGLE type | DEVICE type | PLATFORM type | Display | +// |--------------------------------------------------------| +// | OPENGL | EGL | ANY | EGL | +// | OPENGL | HARDWARE | X11_EXT | GLX | +// | OPENGLES | HARDWARE | X11_EXT | GLX | +// | OPENGLES | EGL | ANY | EGL | +// | VULKAN | HARDWARE | X11_EXT | VkXcb | +// | VULKAN | SWIFTSHADER | X11_EXT | VkXcb | +// | OPENGLES | HARDWARE | SURFACELESS_MESA | EGL* | +// | OPENGLES | HARDWARE | DEVICE_EXT | EGL | +// | VULKAN | HARDWARE | SURFACELESS_MESA | VkBase** | +// | VULKAN | SWIFTSHADER | SURFACELESS_MESA | VkBase** | +// |--------------------------------------------------------| +// +// * No surfaceless support yet. +// ** Not implemented yet. +// +// |-----------------------------------------------| +// | OS | BUILD type | Default PLATFORM type | +// |-----------------------------------------------| +// | Linux | X11 | X11_EXT | +// | Linux | Ozone | SURFACELESS_MESA | +// | Fuchsia | Ozone | FUCHSIA*** | +// |-----------------------------------------------| +// +// *** Chosen implicitly. No EGLAttrib available. +// +// For more details, please refer to +// https://docs.google.com/document/d/1XjHiDZQISq1AMrg_l1TX1_kIKvDpU76hidn9i4cAjl8/edit?disco=AAAAJl9V_YY +// +// static +Display *Display::GetDisplayFromNativeDisplay(EGLenum platform, + EGLNativeDisplayType nativeDisplay, + const AttributeMap &attribMap) +{ + Display *display = nullptr; + + AttributeMap updatedAttribMap(attribMap); + UpdateAttribsFromEnvironment(updatedAttribMap); + + EGLAttrib powerPreference = + updatedAttribMap.get(EGL_POWER_PREFERENCE_ANGLE, EGL_LOW_POWER_ANGLE); + EGLAttrib platformANGLEType = + updatedAttribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE); + EGLAttrib deviceIdHigh = updatedAttribMap.get(EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE, 0); + EGLAttrib deviceIdLow = updatedAttribMap.get(EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE, 0); + ANGLEPlatformDisplayMap *displays = GetANGLEPlatformDisplayMap(); + ANGLEPlatformDisplay displayKey(nativeDisplay, powerPreference, platformANGLEType, deviceIdHigh, + deviceIdLow); + const auto &iter = displays->find(displayKey); + if (iter != displays->end()) + { + display = iter->second; + } + + if (display == nullptr) + { + // Validate the native display + if (!Display::isValidNativeDisplay(nativeDisplay)) + { + return nullptr; + } + + display = new Display(platform, nativeDisplay, nullptr); + displays->insert(std::make_pair(displayKey, display)); + } + // Apply new attributes if the display is not initialized yet. + if (!display->isInitialized()) + { + display->setAttributes(updatedAttribMap); + + EGLAttrib displayType = display->mAttributeMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE); + EGLAttrib deviceType = display->mAttributeMap.get(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE); + EGLAttrib platformType = platform; + if (platform == EGL_PLATFORM_ANGLE_ANGLE) + { + platformType = + display->mAttributeMap.get(EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE); + } + rx::DisplayImpl *impl = + CreateDisplayFromAttribs(displayType, deviceType, platformType, display->getState()); + if (impl == nullptr) + { + // No valid display implementation for these attributes + return nullptr; + } + +#if defined(ANGLE_USE_ANDROID_TLS_SLOT) + angle::gUseAndroidOpenGLTlsSlot = displayType == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE; +#endif // defined(ANGLE_PLATFORM_ANDROID) + + display->setupDisplayPlatform(impl); + } + + return display; +} + +// static +Display *Display::GetExistingDisplayFromNativeDisplay(EGLNativeDisplayType nativeDisplay) +{ + ANGLEPlatformDisplayMap *displays = GetANGLEPlatformDisplayMap(); + const auto &iter = displays->find(nativeDisplay); + + // Check that there is a matching display + if (iter == displays->end()) + { + return nullptr; + } + + return iter->second; +} + +// static +Display *Display::GetDisplayFromDevice(Device *device, const AttributeMap &attribMap) +{ + Display *display = nullptr; + + ASSERT(Device::IsValidDevice(device)); + + ANGLEPlatformDisplayMap *anglePlatformDisplays = GetANGLEPlatformDisplayMap(); + DevicePlatformDisplayMap *devicePlatformDisplays = GetDevicePlatformDisplayMap(); + + // First see if this eglDevice is in use by a Display created using ANGLE platform + for (auto &displayMapEntry : *anglePlatformDisplays) + { + egl::Display *iterDisplay = displayMapEntry.second; + if (iterDisplay->getDevice() == device) + { + display = iterDisplay; + } + } + + if (display == nullptr) + { + // See if the eglDevice is in use by a Display created using the DEVICE platform + const auto &iter = devicePlatformDisplays->find(device); + if (iter != devicePlatformDisplays->end()) + { + display = iter->second; + } + } + + if (display == nullptr) + { + // Otherwise create a new Display + display = new Display(EGL_PLATFORM_DEVICE_EXT, 0, device); + devicePlatformDisplays->insert(std::make_pair(device, display)); + } + + // Apply new attributes if the display is not initialized yet. + if (!display->isInitialized()) + { + display->setAttributes(attribMap); + rx::DisplayImpl *impl = CreateDisplayFromDevice(device, display->getState()); + display->setupDisplayPlatform(impl); + } + + return display; +} + +// static +Display::EglDisplaySet Display::GetEglDisplaySet() +{ + Display::EglDisplaySet displays; + + ANGLEPlatformDisplayMap *anglePlatformDisplays = GetANGLEPlatformDisplayMap(); + DevicePlatformDisplayMap *devicePlatformDisplays = GetDevicePlatformDisplayMap(); + + for (auto anglePlatformDisplayMapEntry : *anglePlatformDisplays) + { + displays.insert(anglePlatformDisplayMapEntry.second); + } + + for (auto devicePlatformDisplayMapEntry : *devicePlatformDisplays) + { + displays.insert(devicePlatformDisplayMapEntry.second); + } + + return displays; +} + +Display::Display(EGLenum platform, EGLNativeDisplayType displayId, Device *eglDevice) + : mState(displayId), + mImplementation(nullptr), + mGPUSwitchedBinding(this, kGPUSwitchedSubjectIndex), + mAttributeMap(), + mConfigSet(), + mStreamSet(), + mInvalidContextSet(), + mInvalidImageSet(), + mInvalidStreamSet(), + mInvalidSurfaceSet(), + mInvalidSyncSet(), + mInitialized(false), + mDeviceLost(false), + mCaps(), + mDisplayExtensions(), + mDisplayExtensionString(), + mVendorString(), + mVersionString(), + mDevice(eglDevice), + mSurface(nullptr), + mPlatform(platform), + mTextureManager(nullptr), + mSemaphoreManager(nullptr), + mBlobCache(gl::kDefaultMaxProgramCacheMemoryBytes), + mMemoryProgramCache(mBlobCache), + mMemoryShaderCache(mBlobCache), + mGlobalTextureShareGroupUsers(0), + mGlobalSemaphoreShareGroupUsers(0), + mTerminatedByApi(false), + mActiveThreads() +{} + +Display::~Display() +{ + switch (mPlatform) + { + case EGL_PLATFORM_ANGLE_ANGLE: + case EGL_PLATFORM_GBM_KHR: + case EGL_PLATFORM_WAYLAND_EXT: + { + ANGLEPlatformDisplayMap *displays = GetANGLEPlatformDisplayMap(); + ANGLEPlatformDisplayMap::iterator iter = displays->find(ANGLEPlatformDisplay( + mState.displayId, + mAttributeMap.get(EGL_POWER_PREFERENCE_ANGLE, EGL_LOW_POWER_ANGLE), + mAttributeMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, + EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE), + mAttributeMap.get(EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE, 0), + mAttributeMap.get(EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE, 0))); + if (iter != displays->end()) + { + displays->erase(iter); + } + break; + } + case EGL_PLATFORM_DEVICE_EXT: + { + DevicePlatformDisplayMap *displays = GetDevicePlatformDisplayMap(); + DevicePlatformDisplayMap::iterator iter = displays->find(mDevice); + if (iter != displays->end()) + { + displays->erase(iter); + } + break; + } + default: + { + UNREACHABLE(); + } + } + + SafeDelete(mDevice); + SafeDelete(mImplementation); +} + +void Display::setLabel(EGLLabelKHR label) +{ + mState.label = label; +} + +EGLLabelKHR Display::getLabel() const +{ + return mState.label; +} + +void Display::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) +{ + ASSERT(index == kGPUSwitchedSubjectIndex); + ASSERT(message == angle::SubjectMessage::SubjectChanged); + for (gl::Context *context : mState.contextSet) + { + context->onGPUSwitch(); + } +} + +void Display::setupDisplayPlatform(rx::DisplayImpl *impl) +{ + ASSERT(!mInitialized); + + ASSERT(impl != nullptr); + SafeDelete(mImplementation); + mImplementation = impl; + + // TODO(anglebug.com/7365): Remove PlatformMethods. + const angle::PlatformMethods *platformMethods = + reinterpret_cast( + mAttributeMap.get(EGL_PLATFORM_ANGLE_PLATFORM_METHODS_ANGLEX, 0)); + if (platformMethods != nullptr) + { + *ANGLEPlatformCurrent() = *platformMethods; + } + else + { + ANGLESetDefaultDisplayPlatform(this); + } + + const char **featuresForceEnabled = + reinterpret_cast(mAttributeMap.get(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE, 0)); + const char **featuresForceDisabled = + reinterpret_cast(mAttributeMap.get(EGL_FEATURE_OVERRIDES_DISABLED_ANGLE, 0)); + mState.featureOverridesEnabled = EGLStringArrayToStringVector(featuresForceEnabled); + mState.featureOverridesDisabled = EGLStringArrayToStringVector(featuresForceDisabled); + mState.featuresAllDisabled = + static_cast(mAttributeMap.get(EGL_FEATURE_ALL_DISABLED_ANGLE, 0)); + mImplementation->addObserver(&mGPUSwitchedBinding); +} + +Error Display::initialize() +{ + mTerminatedByApi = false; + + ASSERT(mImplementation != nullptr); + mImplementation->setBlobCache(&mBlobCache); + + // Enable shader caching if debug layers are turned on. This allows us to test that shaders are + // properly saved & restored on all platforms. The cache won't allocate space until it's used + // and will be ignored entirely if the application / system sets it's own cache functions. + if (rx::ShouldUseDebugLayers(mAttributeMap)) + { + mBlobCache.resize(1024 * 1024); + } + + setGlobalDebugAnnotator(); + + gl::InitializeDebugMutexIfNeeded(); + + ANGLE_TRACE_EVENT0("gpu.angle", "egl::Display::initialize"); + + if (isInitialized()) + { + return NoError(); + } + + Error error = mImplementation->initialize(this); + if (error.isError()) + { + // Log extended error message here + ERR() << "ANGLE Display::initialize error " << error.getID() << ": " << error.getMessage(); + return error; + } + + mCaps = mImplementation->getCaps(); + + mConfigSet = mImplementation->generateConfigs(); + if (mConfigSet.size() == 0) + { + mImplementation->terminate(); + return EglNotInitialized() << "No configs were generated."; + } + + // OpenGL ES1 is implemented in the frontend, explicitly add ES1 support to all configs + for (auto &config : mConfigSet) + { + // TODO(geofflang): Enable the conformant bit once we pass enough tests + // config.second.conformant |= EGL_OPENGL_ES_BIT; + + config.second.renderableType |= EGL_OPENGL_ES_BIT; + + // If we aren't using desktop GL entry points, remove desktop GL support from all configs +#if !defined(ANGLE_ENABLE_GL_DESKTOP_FRONTEND) + config.second.renderableType &= ~EGL_OPENGL_BIT; +#endif + } + + if (!mState.featuresAllDisabled) + { + initializeFrontendFeatures(); + } + + mFeatures.clear(); + mFrontendFeatures.populateFeatureList(&mFeatures); + mImplementation->populateFeatureList(&mFeatures); + + initDisplayExtensions(); + initVendorString(); + initVersionString(); + initClientAPIString(); + + // Populate the Display's EGLDeviceEXT if the Display wasn't created using one + if (mPlatform == EGL_PLATFORM_DEVICE_EXT) + { + // For EGL_PLATFORM_DEVICE_EXT, mDevice should always be populated using + // an external device + ASSERT(mDevice != nullptr); + } + else if (GetClientExtensions().deviceQueryEXT) + { + std::unique_ptr impl(mImplementation->createDevice()); + ASSERT(impl); + error = impl->initialize(); + if (error.isError()) + { + ERR() << "Failed to initialize display because device creation failed: " + << error.getMessage(); + mImplementation->terminate(); + return error; + } + // Don't leak Device memory. + ASSERT(mDevice == nullptr); + mDevice = new Device(this, impl.release()); + } + else + { + mDevice = nullptr; + } + + mInitialized = true; + + return NoError(); +} + +Error Display::destroyInvalidEglObjects() +{ + // Destroy invalid EGL objects + while (!mInvalidContextSet.empty()) + { + gl::Context *context = *mInvalidContextSet.begin(); + context->setIsDestroyed(); + ANGLE_TRY(releaseContextImpl(context, &mInvalidContextSet)); + } + + while (!mInvalidImageSet.empty()) + { + destroyImageImpl(*mInvalidImageSet.begin(), &mInvalidImageSet); + } + + while (!mInvalidStreamSet.empty()) + { + destroyStreamImpl(*mInvalidStreamSet.begin(), &mInvalidStreamSet); + } + + while (!mInvalidSurfaceSet.empty()) + { + ANGLE_TRY(destroySurfaceImpl(*mInvalidSurfaceSet.begin(), &mInvalidSurfaceSet)); + } + + while (!mInvalidSyncSet.empty()) + { + destroySyncImpl(*mInvalidSyncSet.begin(), &mInvalidSyncSet); + } + + return NoError(); +} + +Error Display::terminate(Thread *thread, TerminateReason terminateReason) +{ + if (terminateReason == TerminateReason::Api) + { + mTerminatedByApi = true; + } + + // All subsequent calls assume the display to be valid and terminated by app. + // If it is not terminated or if it isn't even initialized, early return. + if (!mTerminatedByApi || !mInitialized) + { + return NoError(); + } + + // EGL 1.5 Specification + // 3.2 Initialization + // Termination marks all EGL-specific resources, such as contexts and surfaces, associated + // with the specified display for deletion. Handles to all such resources are invalid as soon + // as eglTerminate returns. Cache EGL objects that are no longer valid. + // + // It is fairly common for apps to call eglTerminate while some contexts and/or surfaces are + // still current on some thread. Since objects are refCounted, trying to destroy them right away + // would only result in a decRef. We instead cache such invalid objects and use other EGL + // entrypoints like eglReleaseThread or thread exit events (on the Android platform) to + // perform the necessary cleanup. + mInvalidImageSet.insert(mImageSet.begin(), mImageSet.end()); + mImageSet.clear(); + + mInvalidStreamSet.insert(mStreamSet.begin(), mStreamSet.end()); + mStreamSet.clear(); + + mInvalidSurfaceSet.insert(mState.surfaceSet.begin(), mState.surfaceSet.end()); + mState.surfaceSet.clear(); + + mInvalidSyncSet.insert(mSyncSet.begin(), mSyncSet.end()); + mSyncSet.clear(); + + // Cache total number of contexts before invalidation. This is used as a check to verify that + // no context is "lost" while being moved between the various sets. + size_t contextSetSizeBeforeInvalidation = mState.contextSet.size() + mInvalidContextSet.size(); + + // If app called eglTerminate and no active threads remain, + // force realease any context that is still current. + ContextSet contextsStillCurrent = {}; + for (gl::Context *context : mState.contextSet) + { + if (context->getRefCount() > 0) + { + if (terminateReason == TerminateReason::NoActiveThreads) + { + ASSERT(mTerminatedByApi); + context->release(); + (void)context->unMakeCurrent(this); + } + else + { + contextsStillCurrent.emplace(context); + continue; + } + } + + // Add context that is not current to mInvalidContextSet for cleanup. + mInvalidContextSet.emplace(context); + } + + // There are many methods that require contexts that are still current to be present in + // display's contextSet like during context release or to notify of state changes in a subject. + // So as to not interrupt this flow, do not remove contexts that are still current on some + // thread from display's contextSet even though eglTerminate marks such contexts as invalid. + // + // "mState.contextSet" will now contain only those contexts that are still current on some + // thread. + mState.contextSet = std::move(contextsStillCurrent); + + // Assert that the total number of contexts is the same before and after context invalidation. + ASSERT(contextSetSizeBeforeInvalidation == + mState.contextSet.size() + mInvalidContextSet.size()); + + if (!mState.contextSet.empty()) + { + // There was atleast 1 context that was current on some thread, early return. + return NoError(); + } + + mMemoryProgramCache.clear(); + mMemoryShaderCache.clear(); + mBlobCache.setBlobCacheFuncs(nullptr, nullptr); + + // The global texture and semaphore managers should be deleted with the last context that uses + // it. + ASSERT(mGlobalTextureShareGroupUsers == 0 && mTextureManager == nullptr); + ASSERT(mGlobalSemaphoreShareGroupUsers == 0 && mSemaphoreManager == nullptr); + + // Clean up all invalid objects + ANGLE_TRY(destroyInvalidEglObjects()); + + mConfigSet.clear(); + + if (mDevice != nullptr && mDevice->getOwningDisplay() != nullptr) + { + // Don't delete the device if it was created externally using eglCreateDeviceANGLE + // We also shouldn't set it to null in case eglInitialize() is called again later + SafeDelete(mDevice); + } + + mImplementation->terminate(); + + mDeviceLost = false; + + mInitialized = false; + + gl::UninitializeDebugAnnotations(); + + // TODO(jmadill): Store Platform in Display and deinit here. + ANGLEResetDisplayPlatform(this); + + return NoError(); +} + +Error Display::prepareForCall() +{ + return mImplementation->prepareForCall(); +} + +Error Display::releaseThread() +{ + ANGLE_TRY(mImplementation->releaseThread()); + return destroyInvalidEglObjects(); +} + +void Display::addActiveThread(Thread *thread) +{ + mActiveThreads.insert(thread); +} + +void Display::threadCleanup(Thread *thread) +{ + mActiveThreads.erase(thread); + const bool noActiveThreads = mActiveThreads.size() == 0; + + (void)terminate(thread, noActiveThreads ? TerminateReason::NoActiveThreads + : TerminateReason::InternalCleanup); +} + +std::vector Display::getConfigs(const egl::AttributeMap &attribs) const +{ + return mConfigSet.filter(attribs); +} + +std::vector Display::chooseConfig(const egl::AttributeMap &attribs) const +{ + egl::AttributeMap attribsWithDefaults = AttributeMap(); + + // Insert default values for attributes that have either an Exact or Mask selection criteria, + // and a default value that matters (e.g. isn't EGL_DONT_CARE): + attribsWithDefaults.insert(EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER); + attribsWithDefaults.insert(EGL_LEVEL, 0); + attribsWithDefaults.insert(EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT); + attribsWithDefaults.insert(EGL_SURFACE_TYPE, EGL_WINDOW_BIT); + attribsWithDefaults.insert(EGL_TRANSPARENT_TYPE, EGL_NONE); + if (getExtensions().pixelFormatFloat) + { + attribsWithDefaults.insert(EGL_COLOR_COMPONENT_TYPE_EXT, + EGL_COLOR_COMPONENT_TYPE_FIXED_EXT); + } + + // Add the caller-specified values (Note: the poorly-named insert() method will replace any + // of the default values from above): + for (auto attribIter = attribs.begin(); attribIter != attribs.end(); attribIter++) + { + attribsWithDefaults.insert(attribIter->first, attribIter->second); + } + + return mConfigSet.filter(attribsWithDefaults); +} + +Error Display::createWindowSurface(const Config *configuration, + EGLNativeWindowType window, + const AttributeMap &attribs, + Surface **outSurface) +{ + if (mImplementation->testDeviceLost()) + { + ANGLE_TRY(restoreLostDevice()); + } + + SurfacePointer surface(new WindowSurface(mImplementation, configuration, window, attribs, + mFrontendFeatures.forceRobustResourceInit.enabled), + this); + ANGLE_TRY(surface->initialize(this)); + + ASSERT(outSurface != nullptr); + *outSurface = surface.release(); + mState.surfaceSet.insert(*outSurface); + + WindowSurfaceMap *windowSurfaces = GetWindowSurfaces(); + ASSERT(windowSurfaces && windowSurfaces->find(window) == windowSurfaces->end()); + windowSurfaces->insert(std::make_pair(window, *outSurface)); + + mSurface = *outSurface; + + return NoError(); +} + +Error Display::createPbufferSurface(const Config *configuration, + const AttributeMap &attribs, + Surface **outSurface) +{ + ASSERT(isInitialized()); + + if (mImplementation->testDeviceLost()) + { + ANGLE_TRY(restoreLostDevice()); + } + + SurfacePointer surface(new PbufferSurface(mImplementation, configuration, attribs, + mFrontendFeatures.forceRobustResourceInit.enabled), + this); + ANGLE_TRY(surface->initialize(this)); + + ASSERT(outSurface != nullptr); + *outSurface = surface.release(); + mState.surfaceSet.insert(*outSurface); + + return NoError(); +} + +Error Display::createPbufferFromClientBuffer(const Config *configuration, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const AttributeMap &attribs, + Surface **outSurface) +{ + ASSERT(isInitialized()); + + if (mImplementation->testDeviceLost()) + { + ANGLE_TRY(restoreLostDevice()); + } + + SurfacePointer surface( + new PbufferSurface(mImplementation, configuration, buftype, clientBuffer, attribs, + mFrontendFeatures.forceRobustResourceInit.enabled), + this); + ANGLE_TRY(surface->initialize(this)); + + ASSERT(outSurface != nullptr); + *outSurface = surface.release(); + mState.surfaceSet.insert(*outSurface); + + return NoError(); +} + +Error Display::createPixmapSurface(const Config *configuration, + NativePixmapType nativePixmap, + const AttributeMap &attribs, + Surface **outSurface) +{ + ASSERT(isInitialized()); + + if (mImplementation->testDeviceLost()) + { + ANGLE_TRY(restoreLostDevice()); + } + + SurfacePointer surface(new PixmapSurface(mImplementation, configuration, nativePixmap, attribs, + mFrontendFeatures.forceRobustResourceInit.enabled), + this); + ANGLE_TRY(surface->initialize(this)); + + ASSERT(outSurface != nullptr); + *outSurface = surface.release(); + mState.surfaceSet.insert(*outSurface); + + return NoError(); +} + +Error Display::createImage(const gl::Context *context, + EGLenum target, + EGLClientBuffer buffer, + const AttributeMap &attribs, + Image **outImage) +{ + ASSERT(isInitialized()); + + if (mImplementation->testDeviceLost()) + { + ANGLE_TRY(restoreLostDevice()); + } + + egl::ImageSibling *sibling = nullptr; + if (IsTextureTarget(target)) + { + sibling = context->getTexture({egl_gl::EGLClientBufferToGLObjectHandle(buffer)}); + } + else if (IsRenderbufferTarget(target)) + { + sibling = context->getRenderbuffer({egl_gl::EGLClientBufferToGLObjectHandle(buffer)}); + } + else if (IsExternalImageTarget(target)) + { + sibling = new ExternalImageSibling(mImplementation, context, target, buffer, attribs); + } + else + { + UNREACHABLE(); + } + ASSERT(sibling != nullptr); + + angle::UniqueObjectPointer imagePtr( + new Image(mImplementation, context, target, sibling, attribs), this); + ANGLE_TRY(imagePtr->initialize(this)); + + Image *image = imagePtr.release(); + + ASSERT(outImage != nullptr); + *outImage = image; + + // Add this image to the list of all images and hold a ref to it. + image->addRef(); + mImageSet.insert(image); + + return NoError(); +} + +Error Display::createStream(const AttributeMap &attribs, Stream **outStream) +{ + ASSERT(isInitialized()); + + Stream *stream = new Stream(this, attribs); + + ASSERT(stream != nullptr); + mStreamSet.insert(stream); + + ASSERT(outStream != nullptr); + *outStream = stream; + + return NoError(); +} + +Error Display::createContext(const Config *configuration, + gl::Context *shareContext, + EGLenum clientType, + const AttributeMap &attribs, + gl::Context **outContext) +{ + ASSERT(!mTerminatedByApi); + ASSERT(isInitialized()); + + if (mImplementation->testDeviceLost()) + { + ANGLE_TRY(restoreLostDevice()); + } + + // This display texture sharing will allow the first context to create the texture share group. + bool usingDisplayTextureShareGroup = + attribs.get(EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE, EGL_FALSE) == EGL_TRUE; + gl::TextureManager *shareTextures = nullptr; + + if (usingDisplayTextureShareGroup) + { + ASSERT((mTextureManager == nullptr) == (mGlobalTextureShareGroupUsers == 0)); + if (mTextureManager == nullptr) + { + mTextureManager = new gl::TextureManager(); + } + + mGlobalTextureShareGroupUsers++; + shareTextures = mTextureManager; + } + + // This display semaphore sharing will allow the first context to create the semaphore share + // group. + bool usingDisplaySemaphoreShareGroup = + attribs.get(EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE, EGL_FALSE) == EGL_TRUE; + gl::SemaphoreManager *shareSemaphores = nullptr; + if (usingDisplaySemaphoreShareGroup) + { + ASSERT((mSemaphoreManager == nullptr) == (mGlobalSemaphoreShareGroupUsers == 0)); + if (mSemaphoreManager == nullptr) + { + mSemaphoreManager = new gl::SemaphoreManager(); + } + + mGlobalSemaphoreShareGroupUsers++; + shareSemaphores = mSemaphoreManager; + } + + gl::MemoryProgramCache *programCachePointer = &mMemoryProgramCache; + // Check context creation attributes to see if we are using EGL_ANGLE_program_cache_control. + // If not, keep caching enabled for EGL_ANDROID_blob_cache, which can have its callbacks set + // at any time. + bool usesProgramCacheControl = attribs.contains(EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE); + if (usesProgramCacheControl) + { + bool programCacheControlEnabled = + (attribs.get(EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE, GL_FALSE) == GL_TRUE); + // A program cache size of zero indicates it should be disabled. + if (!programCacheControlEnabled || mMemoryProgramCache.maxSize() == 0) + { + programCachePointer = nullptr; + } + } + + gl::MemoryShaderCache *shaderCachePointer = &mMemoryShaderCache; + // Check if shader caching frontend feature is enabled. + if (!mFrontendFeatures.cacheCompiledShader.enabled) + { + shaderCachePointer = nullptr; + } + + gl::Context *context = new gl::Context( + this, configuration, shareContext, shareTextures, shareSemaphores, programCachePointer, + shaderCachePointer, clientType, attribs, mDisplayExtensions, GetClientExtensions()); + Error error = context->initialize(); + if (error.isError()) + { + delete context; + return error; + } + + if (shareContext != nullptr) + { + shareContext->setShared(); + } + + ASSERT(context != nullptr); + mState.contextSet.insert(context); + + ASSERT(outContext != nullptr); + *outContext = context; + return NoError(); +} + +Error Display::createSync(const gl::Context *currentContext, + EGLenum type, + const AttributeMap &attribs, + Sync **outSync) +{ + ASSERT(isInitialized()); + + if (mImplementation->testDeviceLost()) + { + ANGLE_TRY(restoreLostDevice()); + } + + angle::UniqueObjectPointer syncPtr(new Sync(mImplementation, type, attribs), + this); + + ANGLE_TRY(syncPtr->initialize(this, currentContext)); + + Sync *sync = syncPtr.release(); + + sync->addRef(); + mSyncSet.insert(sync); + + *outSync = sync; + return NoError(); +} + +Error Display::makeCurrent(Thread *thread, + gl::Context *previousContext, + egl::Surface *drawSurface, + egl::Surface *readSurface, + gl::Context *context) +{ + if (!mInitialized) + { + return NoError(); + } + + bool contextChanged = context != previousContext; + if (previousContext != nullptr && contextChanged) + { + previousContext->release(); + thread->setCurrent(nullptr); + + auto error = previousContext->unMakeCurrent(this); + if (previousContext->getRefCount() == 0 && previousContext->isDestroyed()) + { + // The previous Context may have been created with a different Display. + Display *previousDisplay = previousContext->getDisplay(); + ANGLE_TRY(previousDisplay->releaseContext(previousContext, thread)); + } + ANGLE_TRY(error); + } + + thread->setCurrent(context); + + ANGLE_TRY(mImplementation->makeCurrent(this, drawSurface, readSurface, context)); + + if (context != nullptr) + { + ANGLE_TRY(context->makeCurrent(this, drawSurface, readSurface)); + if (contextChanged) + { + context->addRef(); + } + } + + // Tick all the scratch buffers to make sure they get cleaned up eventually if they stop being + // used. + { + std::lock_guard lock(mScratchBufferMutex); + + for (angle::ScratchBuffer &scatchBuffer : mScratchBuffers) + { + scatchBuffer.tick(); + } + for (angle::ScratchBuffer &zeroFilledBuffer : mZeroFilledBuffers) + { + zeroFilledBuffer.tick(); + } + } + + return NoError(); +} + +Error Display::restoreLostDevice() +{ + for (ContextSet::iterator ctx = mState.contextSet.begin(); ctx != mState.contextSet.end(); + ctx++) + { + if ((*ctx)->isResetNotificationEnabled()) + { + // If reset notifications have been requested, application must delete all contexts + // first + return EglContextLost(); + } + } + + return mImplementation->restoreLostDevice(this); +} + +Error Display::destroySurfaceImpl(Surface *surface, SurfaceSet *surfaces) +{ + if (surface->getType() == EGL_WINDOW_BIT) + { + WindowSurfaceMap *windowSurfaces = GetWindowSurfaces(); + ASSERT(windowSurfaces); + + bool surfaceRemoved = false; + for (WindowSurfaceMap::iterator iter = windowSurfaces->begin(); + iter != windowSurfaces->end(); iter++) + { + if (iter->second == surface) + { + windowSurfaces->erase(iter); + surfaceRemoved = true; + break; + } + } + + ASSERT(surfaceRemoved); + } + + auto iter = surfaces->find(surface); + ASSERT(iter != surfaces->end()); + surfaces->erase(iter); + ANGLE_TRY(surface->onDestroy(this)); + return NoError(); +} + +void Display::destroyImageImpl(Image *image, ImageSet *images) +{ + auto iter = images->find(image); + ASSERT(iter != images->end()); + (*iter)->release(this); + images->erase(iter); +} + +void Display::destroyStreamImpl(Stream *stream, StreamSet *streams) +{ + streams->erase(stream); + SafeDelete(stream); +} + +// releaseContext must be called with the context being deleted as current. +// To do that we can only call this in two places, Display::makeCurrent at the point where this +// context is being made uncurrent and in Display::destroyContext where we make the context current +// as part of destruction. +Error Display::releaseContext(gl::Context *context, Thread *thread) +{ + return releaseContextImpl(context, &mState.contextSet); +} + +Error Display::releaseContextImpl(gl::Context *context, ContextSet *contexts) +{ + ASSERT(context->getRefCount() == 0); + + // Use scoped_ptr to make sure the context is always freed. + std::unique_ptr unique_context(context); + ASSERT(contexts->find(context) != contexts->end()); + contexts->erase(context); + + if (context->usingDisplayTextureShareGroup()) + { + ASSERT(mGlobalTextureShareGroupUsers >= 1 && mTextureManager != nullptr); + if (mGlobalTextureShareGroupUsers == 1) + { + // If this is the last context using the global share group, destroy the global + // texture manager so that the textures can be destroyed while a context still + // exists + mTextureManager->release(context); + mTextureManager = nullptr; + } + mGlobalTextureShareGroupUsers--; + } + + if (context->usingDisplaySemaphoreShareGroup()) + { + ASSERT(mGlobalSemaphoreShareGroupUsers >= 1 && mSemaphoreManager != nullptr); + if (mGlobalSemaphoreShareGroupUsers == 1) + { + // If this is the last context using the global share group, destroy the global + // semaphore manager so that the semaphores can be destroyed while a context still + // exists + mSemaphoreManager->release(context); + mSemaphoreManager = nullptr; + } + mGlobalSemaphoreShareGroupUsers--; + } + + ANGLE_TRY(context->onDestroy(this)); + + return NoError(); +} + +Error Display::destroyContext(Thread *thread, gl::Context *context) +{ + auto *currentContext = thread->getContext(); + auto *currentDrawSurface = thread->getCurrentDrawSurface(); + auto *currentReadSurface = thread->getCurrentReadSurface(); + + context->setIsDestroyed(); + + // If the context is still current on at least 1 thread, just return since it'll be released + // once no threads have it current anymore. + if (context->getRefCount() > 0) + { + return NoError(); + } + + // For external context, we cannot change the current native context, and the API user should + // make sure the native context is current. + if (context->isExternal()) + { + ANGLE_TRY(releaseContext(context, thread)); + } + else + { + // Keep |currentContext| alive, while releasing |context|. + gl::ScopedContextRef scopedContextRef(currentContext); + + // keep |currentDrawSurface| and |currentReadSurface| alive as well + // while releasing |context|. + ScopedSurfaceRef drawSurfaceRef(currentDrawSurface); + ScopedSurfaceRef readSurfaceRef( + currentReadSurface == currentDrawSurface ? nullptr : currentReadSurface); + + // Make the context current, so we can release resources belong to the context, and then + // when context is released from the current, it will be destroyed. + // TODO(http://www.anglebug.com/6322): Don't require a Context to be current in order to + // destroy it. + ANGLE_TRY(makeCurrent(thread, currentContext, nullptr, nullptr, context)); + ANGLE_TRY( + makeCurrent(thread, context, currentDrawSurface, currentReadSurface, currentContext)); + } + + // If eglTerminate() has previously been called and this is the last Context the Display owns, + // we can now fully terminate the display and release all of its resources. + if (mTerminatedByApi) + { + for (const gl::Context *ctx : mState.contextSet) + { + if (ctx->getRefCount() > 0) + { + return NoError(); + } + } + + return terminate(thread, TerminateReason::InternalCleanup); + } + + return NoError(); +} + +void Display::destroySyncImpl(Sync *sync, SyncSet *syncs) +{ + auto iter = syncs->find(sync); + ASSERT(iter != syncs->end()); + (*iter)->release(this); + syncs->erase(iter); +} + +void Display::destroyImage(Image *image) +{ + return destroyImageImpl(image, &mImageSet); +} + +void Display::destroyStream(Stream *stream) +{ + return destroyStreamImpl(stream, &mStreamSet); +} + +Error Display::destroySurface(Surface *surface) +{ + return destroySurfaceImpl(surface, &mState.surfaceSet); +} + +void Display::destroySync(Sync *sync) +{ + return destroySyncImpl(sync, &mSyncSet); +} + +bool Display::isDeviceLost() const +{ + ASSERT(isInitialized()); + return mDeviceLost; +} + +bool Display::testDeviceLost() +{ + ASSERT(isInitialized()); + + if (!mDeviceLost && mImplementation->testDeviceLost()) + { + notifyDeviceLost(); + } + + return mDeviceLost; +} + +void Display::notifyDeviceLost() +{ + if (mDeviceLost) + { + return; + } + + for (ContextSet::iterator context = mState.contextSet.begin(); + context != mState.contextSet.end(); context++) + { + (*context)->markContextLost(gl::GraphicsResetStatus::UnknownContextReset); + } + + mDeviceLost = true; +} + +void Display::setBlobCacheFuncs(EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get) +{ + mBlobCache.setBlobCacheFuncs(set, get); + mImplementation->setBlobCacheFuncs(set, get); +} + +// static +EGLClientBuffer Display::GetNativeClientBuffer(const AHardwareBuffer *buffer) +{ + return angle::android::AHardwareBufferToClientBuffer(buffer); +} + +// static +Error Display::CreateNativeClientBuffer(const egl::AttributeMap &attribMap, + EGLClientBuffer *eglClientBuffer) +{ + int androidHardwareBufferFormat = gl::GetAndroidHardwareBufferFormatFromChannelSizes(attribMap); + int width = attribMap.getAsInt(EGL_WIDTH, 0); + int height = attribMap.getAsInt(EGL_HEIGHT, 0); + int usage = attribMap.getAsInt(EGL_NATIVE_BUFFER_USAGE_ANDROID, 0); + + // https://developer.android.com/ndk/reference/group/a-hardware-buffer#ahardwarebuffer_lock + // for AHardwareBuffer_lock() + // The passed AHardwareBuffer must have one layer, otherwise the call will fail. + constexpr int kLayerCount = 1; + + *eglClientBuffer = angle::android::CreateEGLClientBufferFromAHardwareBuffer( + width, height, kLayerCount, androidHardwareBufferFormat, usage); + + return (*eglClientBuffer == nullptr) + ? egl::EglBadParameter() << "native client buffer allocation failed." + : NoError(); +} + +Error Display::waitClient(const gl::Context *context) +{ + return mImplementation->waitClient(context); +} + +Error Display::waitNative(const gl::Context *context, EGLint engine) +{ + return mImplementation->waitNative(context, engine); +} + +const Caps &Display::getCaps() const +{ + return mCaps; +} + +bool Display::isInitialized() const +{ + return mInitialized; +} + +bool Display::isValidConfig(const Config *config) const +{ + return mConfigSet.contains(config); +} + +bool Display::isValidContext(const gl::Context *context) const +{ + return mState.contextSet.find(const_cast(context)) != mState.contextSet.end(); +} + +bool Display::isValidSurface(const Surface *surface) const +{ + return mState.surfaceSet.find(const_cast(surface)) != mState.surfaceSet.end(); +} + +bool Display::isValidImage(const Image *image) const +{ + return mImageSet.find(const_cast(image)) != mImageSet.end(); +} + +bool Display::isValidStream(const Stream *stream) const +{ + return mStreamSet.find(const_cast(stream)) != mStreamSet.end(); +} + +bool Display::isValidSync(const Sync *sync) const +{ + return mSyncSet.find(const_cast(sync)) != mSyncSet.end(); +} + +bool Display::hasExistingWindowSurface(EGLNativeWindowType window) +{ + WindowSurfaceMap *windowSurfaces = GetWindowSurfaces(); + ASSERT(windowSurfaces); + + return windowSurfaces->find(window) != windowSurfaces->end(); +} + +static ClientExtensions GenerateClientExtensions() +{ + ClientExtensions extensions; + + extensions.clientExtensions = true; + extensions.platformBase = true; + extensions.platformANGLE = true; + +#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11) + extensions.platformANGLED3D = true; + extensions.platformDevice = true; +#endif + +#if defined(ANGLE_USE_GBM) + extensions.platformGbmKHR = true; +#endif + +#if defined(ANGLE_USE_WAYLAND) + extensions.platformWaylandEXT = true; +#endif + +#if defined(ANGLE_ENABLE_D3D11) +# if defined(ANGLE_ENABLE_WINDOWS_UWP) + extensions.platformANGLED3D11ON12 = true; +# else + extensions.platformANGLED3D11ON12 = IsWindows10OrGreater(); +# endif + extensions.platformANGLEDeviceId = true; +#endif + +#if defined(ANGLE_ENABLE_OPENGL) + extensions.platformANGLEOpenGL = true; +#endif + +#if defined(ANGLE_ENABLE_NULL) + extensions.platformANGLENULL = true; +#endif + +#if defined(ANGLE_ENABLE_D3D11) + extensions.deviceCreation = true; + extensions.deviceCreationD3D11 = true; + extensions.experimentalPresentPath = true; +#endif + +#if defined(ANGLE_ENABLE_VULKAN) + extensions.platformANGLEVulkan = true; + extensions.platformANGLEDeviceId = true; +#endif + +#if defined(ANGLE_ENABLE_SWIFTSHADER) + extensions.platformANGLEDeviceTypeSwiftShader = true; +#endif + +#if defined(ANGLE_ENABLE_METAL) + extensions.platformANGLEMetal = true; + extensions.platformANGLEDeviceId = true; +#endif + +#if defined(ANGLE_USE_X11) + extensions.x11Visual = true; +#endif + +#if defined(ANGLE_PLATFORM_LINUX) + extensions.platformANGLEDeviceTypeEGLANGLE = true; +#endif + +#if (defined(ANGLE_PLATFORM_IOS) && !defined(ANGLE_PLATFORM_MACCATALYST)) || \ + (defined(ANGLE_PLATFORM_MACCATALYST) && defined(ANGLE_CPU_ARM64)) + extensions.platformANGLEDeviceContextVolatileEagl = true; +#endif + +#if defined(ANGLE_PLATFORM_MACOS) || defined(ANGLE_PLATFORM_MACCATALYST) + extensions.platformANGLEDeviceContextVolatileCgl = true; +#endif + +#if defined(ANGLE_ENABLE_METAL) + extensions.displayPowerPreferenceANGLE = true; +#endif + + extensions.clientGetAllProcAddresses = true; + extensions.debug = true; + extensions.featureControlANGLE = true; + extensions.deviceQueryEXT = true; + + return extensions; +} + +template +static std::string GenerateExtensionsString(const T &extensions) +{ + std::vector extensionsVector = extensions.getStrings(); + + std::ostringstream stream; + std::copy(extensionsVector.begin(), extensionsVector.end(), + std::ostream_iterator(stream, " ")); + return stream.str(); +} + +// static +const ClientExtensions &Display::GetClientExtensions() +{ + static const ClientExtensions clientExtensions = GenerateClientExtensions(); + return clientExtensions; +} + +// static +const std::string &Display::GetClientExtensionString() +{ + static const angle::base::NoDestructor clientExtensionsString( + GenerateExtensionsString(GetClientExtensions())); + return *clientExtensionsString; +} + +void Display::initDisplayExtensions() +{ + mDisplayExtensions = mImplementation->getExtensions(); + + // Some extensions are always available because they are implemented in the EGL layer. + mDisplayExtensions.createContext = true; + mDisplayExtensions.createContextNoError = !mFrontendFeatures.forceGlErrorChecking.enabled; + mDisplayExtensions.createContextWebGLCompatibility = true; + mDisplayExtensions.createContextBindGeneratesResource = true; + mDisplayExtensions.createContextClientArrays = true; + mDisplayExtensions.pixelFormatFloat = true; + mDisplayExtensions.reusableSyncKHR = true; + + // Force EGL_KHR_get_all_proc_addresses on. + mDisplayExtensions.getAllProcAddresses = true; + + // Enable program cache control since it is not back-end dependent. + mDisplayExtensions.programCacheControlANGLE = true; + + // Request extension is implemented in the ANGLE frontend + mDisplayExtensions.createContextExtensionsEnabled = true; + + // Blob cache extension is provided by the ANGLE frontend + mDisplayExtensions.blobCache = true; + + // The EGL_ANDROID_recordable extension is provided by the ANGLE frontend, and will always + // say that ANativeWindow is not recordable. + mDisplayExtensions.recordable = true; + + // All backends support specific context versions + mDisplayExtensions.createContextBackwardsCompatible = true; + + mDisplayExtensionString = GenerateExtensionsString(mDisplayExtensions); +} + +bool Display::isValidNativeWindow(EGLNativeWindowType window) const +{ + return mImplementation->isValidNativeWindow(window); +} + +Error Display::validateClientBuffer(const Config *configuration, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const AttributeMap &attribs) const +{ + return mImplementation->validateClientBuffer(configuration, buftype, clientBuffer, attribs); +} + +Error Display::validateImageClientBuffer(const gl::Context *context, + EGLenum target, + EGLClientBuffer clientBuffer, + const egl::AttributeMap &attribs) const +{ + return mImplementation->validateImageClientBuffer(context, target, clientBuffer, attribs); +} + +Error Display::valdiatePixmap(const Config *config, + EGLNativePixmapType pixmap, + const AttributeMap &attributes) const +{ + return mImplementation->validatePixmap(config, pixmap, attributes); +} + +bool Display::isValidDisplay(const egl::Display *display) +{ + const ANGLEPlatformDisplayMap *anglePlatformDisplayMap = GetANGLEPlatformDisplayMap(); + for (const auto &displayPair : *anglePlatformDisplayMap) + { + if (displayPair.second == display) + { + return true; + } + } + + const DevicePlatformDisplayMap *devicePlatformDisplayMap = GetDevicePlatformDisplayMap(); + for (const auto &displayPair : *devicePlatformDisplayMap) + { + if (displayPair.second == display) + { + return true; + } + } + + return false; +} + +bool Display::isValidNativeDisplay(EGLNativeDisplayType display) +{ + // TODO(jmadill): handle this properly + if (display == EGL_DEFAULT_DISPLAY) + { + return true; + } + +#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(ANGLE_ENABLE_WINDOWS_UWP) + if (display == EGL_SOFTWARE_DISPLAY_ANGLE || display == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE || + display == EGL_D3D11_ONLY_DISPLAY_ANGLE) + { + return true; + } + return (WindowFromDC(display) != nullptr); +#else + return true; +#endif +} + +void Display::initVendorString() +{ + mVendorString = "Google Inc."; + std::string vendorStringImpl = mImplementation->getVendorString(); + if (!vendorStringImpl.empty()) + { + mVendorString += " (" + vendorStringImpl + ")"; + } +} + +void Display::initVersionString() +{ + mVersionString = mImplementation->getVersionString(true); +} + +void Display::initClientAPIString() +{ + // If the max supported desktop version is not None, we support a desktop GL frontend. + if (mImplementation->getMaxSupportedDesktopVersion().valid()) + { + mClientAPIString = "OpenGL_ES OpenGL"; + } + else + { + mClientAPIString = "OpenGL_ES"; + } +} + +void Display::initializeFrontendFeatures() +{ + // Enable on all Impls + ANGLE_FEATURE_CONDITION((&mFrontendFeatures), loseContextOnOutOfMemory, true); + ANGLE_FEATURE_CONDITION((&mFrontendFeatures), allowCompressedFormats, true); + + // No longer enable this on any Impl - crbug.com/1165751 + ANGLE_FEATURE_CONDITION((&mFrontendFeatures), scalarizeVecAndMatConstructorArgs, false); + + // Disabled by default. To reduce the risk, create a feature to enable + // compressing pipeline cache in multi-thread pool. + ANGLE_FEATURE_CONDITION(&mFrontendFeatures, enableCompressingPipelineCacheInThreadPool, false); + + // Disabled by default until work on the extension is complete - anglebug.com/7279. + ANGLE_FEATURE_CONDITION(&mFrontendFeatures, emulatePixelLocalStorage, false); + + mImplementation->initializeFrontendFeatures(&mFrontendFeatures); + + rx::ApplyFeatureOverrides(&mFrontendFeatures, mState); +} + +const DisplayExtensions &Display::getExtensions() const +{ + return mDisplayExtensions; +} + +const std::string &Display::getExtensionString() const +{ + return mDisplayExtensionString; +} + +const std::string &Display::getVendorString() const +{ + return mVendorString; +} + +const std::string &Display::getVersionString() const +{ + return mVersionString; +} + +const std::string &Display::getClientAPIString() const +{ + return mClientAPIString; +} + +std::string Display::getBackendRendererDescription() const +{ + return mImplementation->getRendererDescription(); +} + +std::string Display::getBackendVendorString() const +{ + return mImplementation->getVendorString(); +} + +std::string Display::getBackendVersionString(bool includeFullVersion) const +{ + return mImplementation->getVersionString(includeFullVersion); +} + +Device *Display::getDevice() const +{ + return mDevice; +} + +Surface *Display::getWGLSurface() const +{ + return mSurface; +} + +gl::Version Display::getMaxSupportedESVersion() const +{ + return mImplementation->getMaxSupportedESVersion(); +} + +EGLint Display::programCacheGetAttrib(EGLenum attrib) const +{ + switch (attrib) + { + case EGL_PROGRAM_CACHE_KEY_LENGTH_ANGLE: + return static_cast(BlobCache::kKeyLength); + + case EGL_PROGRAM_CACHE_SIZE_ANGLE: + return static_cast(mMemoryProgramCache.entryCount()); + + default: + UNREACHABLE(); + return 0; + } +} + +Error Display::programCacheQuery(EGLint index, + void *key, + EGLint *keysize, + void *binary, + EGLint *binarysize) +{ + ASSERT(index >= 0 && index < static_cast(mMemoryProgramCache.entryCount())); + + const BlobCache::Key *programHash = nullptr; + BlobCache::Value programBinary; + // TODO(jmadill): Make this thread-safe. + bool result = + mMemoryProgramCache.getAt(static_cast(index), &programHash, &programBinary); + if (!result) + { + return EglBadAccess() << "Program binary not accessible."; + } + + ASSERT(keysize && binarysize); + + if (key) + { + ASSERT(*keysize == static_cast(BlobCache::kKeyLength)); + memcpy(key, programHash->data(), BlobCache::kKeyLength); + } + + if (binary) + { + // Note: we check the size here instead of in the validation code, since we need to + // access the cache as atomically as possible. It's possible that the cache contents + // could change between the validation size check and the retrieval. + if (programBinary.size() > static_cast(*binarysize)) + { + return EglBadAccess() << "Program binary too large or changed during access."; + } + + memcpy(binary, programBinary.data(), programBinary.size()); + } + + *binarysize = static_cast(programBinary.size()); + *keysize = static_cast(BlobCache::kKeyLength); + + return NoError(); +} + +Error Display::programCachePopulate(const void *key, + EGLint keysize, + const void *binary, + EGLint binarysize) +{ + ASSERT(keysize == static_cast(BlobCache::kKeyLength)); + + BlobCache::Key programHash; + memcpy(programHash.data(), key, BlobCache::kKeyLength); + + if (!mMemoryProgramCache.putBinary(programHash, reinterpret_cast(binary), + static_cast(binarysize))) + { + return EglBadAccess() << "Failed to copy program binary into the cache."; + } + + return NoError(); +} + +EGLint Display::programCacheResize(EGLint limit, EGLenum mode) +{ + switch (mode) + { + case EGL_PROGRAM_CACHE_RESIZE_ANGLE: + { + size_t initialSize = mMemoryProgramCache.size(); + mMemoryProgramCache.resize(static_cast(limit)); + return static_cast(initialSize); + } + + case EGL_PROGRAM_CACHE_TRIM_ANGLE: + return static_cast(mMemoryProgramCache.trim(static_cast(limit))); + + default: + UNREACHABLE(); + return 0; + } +} + +void Display::overrideFrontendFeatures(const std::vector &featureNames, bool enabled) +{ + mFrontendFeatures.overrideFeatures(featureNames, enabled); +} + +const char *Display::queryStringi(const EGLint name, const EGLint index) +{ + const char *result = nullptr; + switch (name) + { + case EGL_FEATURE_NAME_ANGLE: + result = mFeatures[index]->name; + break; + case EGL_FEATURE_CATEGORY_ANGLE: + result = angle::FeatureCategoryToString(mFeatures[index]->category); + break; + case EGL_FEATURE_DESCRIPTION_ANGLE: + result = mFeatures[index]->description; + break; + case EGL_FEATURE_BUG_ANGLE: + result = mFeatures[index]->bug; + break; + case EGL_FEATURE_STATUS_ANGLE: + result = angle::FeatureStatusToString(mFeatures[index]->enabled); + break; + case EGL_FEATURE_CONDITION_ANGLE: + result = mFeatures[index]->condition; + break; + default: + UNREACHABLE(); + return nullptr; + } + return result; +} + +EGLAttrib Display::queryAttrib(const EGLint attribute) +{ + EGLAttrib value = 0; + switch (attribute) + { + case EGL_DEVICE_EXT: + value = reinterpret_cast(mDevice); + break; + + case EGL_FEATURE_COUNT_ANGLE: + value = mFeatures.size(); + break; + + default: + UNREACHABLE(); + } + return value; +} + +angle::ScratchBuffer Display::requestScratchBuffer() +{ + return requestScratchBufferImpl(&mScratchBuffers); +} + +void Display::returnScratchBuffer(angle::ScratchBuffer scratchBuffer) +{ + returnScratchBufferImpl(std::move(scratchBuffer), &mScratchBuffers); +} + +angle::ScratchBuffer Display::requestZeroFilledBuffer() +{ + return requestScratchBufferImpl(&mZeroFilledBuffers); +} + +void Display::returnZeroFilledBuffer(angle::ScratchBuffer zeroFilledBuffer) +{ + returnScratchBufferImpl(std::move(zeroFilledBuffer), &mZeroFilledBuffers); +} + +angle::ScratchBuffer Display::requestScratchBufferImpl( + std::vector *bufferVector) +{ + std::lock_guard lock(mScratchBufferMutex); + if (!bufferVector->empty()) + { + angle::ScratchBuffer buffer = std::move(bufferVector->back()); + bufferVector->pop_back(); + return buffer; + } + + return angle::ScratchBuffer(kScratchBufferLifetime); +} + +void Display::returnScratchBufferImpl(angle::ScratchBuffer scratchBuffer, + std::vector *bufferVector) +{ + std::lock_guard lock(mScratchBufferMutex); + bufferVector->push_back(std::move(scratchBuffer)); +} + +Error Display::handleGPUSwitch() +{ + ANGLE_TRY(mImplementation->handleGPUSwitch()); + initVendorString(); + return NoError(); +} + +Error Display::forceGPUSwitch(EGLint gpuIDHigh, EGLint gpuIDLow) +{ + ANGLE_TRY(mImplementation->forceGPUSwitch(gpuIDHigh, gpuIDLow)); + initVendorString(); + return NoError(); +} + +bool Display::supportsDmaBufFormat(EGLint format) const +{ + return mImplementation->supportsDmaBufFormat(format); +} + +Error Display::queryDmaBufFormats(EGLint max_formats, EGLint *formats, EGLint *num_formats) +{ + ANGLE_TRY(mImplementation->queryDmaBufFormats(max_formats, formats, num_formats)); + return NoError(); +} + +Error Display::queryDmaBufModifiers(EGLint format, + EGLint max_modifiers, + EGLuint64KHR *modifiers, + EGLBoolean *external_only, + EGLint *num_modifiers) +{ + ANGLE_TRY(mImplementation->queryDmaBufModifiers(format, max_modifiers, modifiers, external_only, + num_modifiers)); + return NoError(); +} + +} // namespace egl diff --git a/gfx/angle/checkout/src/libANGLE/Display.h b/gfx/angle/checkout/src/libANGLE/Display.h new file mode 100644 index 0000000000..da00026e7b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Display.h @@ -0,0 +1,427 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Display.h: Defines the egl::Display class, representing the abstract +// display on which graphics are drawn. Implements EGLDisplay. +// [EGL 1.4] section 2.1.2 page 3. + +#ifndef LIBANGLE_DISPLAY_H_ +#define LIBANGLE_DISPLAY_H_ + +#include +#include +#include + +#include "libANGLE/AttributeMap.h" +#include "libANGLE/BlobCache.h" +#include "libANGLE/Caps.h" +#include "libANGLE/Config.h" +#include "libANGLE/Context.h" +#include "libANGLE/Debug.h" +#include "libANGLE/Error.h" +#include "libANGLE/LoggingAnnotator.h" +#include "libANGLE/MemoryProgramCache.h" +#include "libANGLE/MemoryShaderCache.h" +#include "libANGLE/Observer.h" +#include "libANGLE/Version.h" +#include "platform/Feature.h" +#include "platform/FrontendFeatures_autogen.h" + +namespace angle +{ +class FrameCaptureShared; +} // namespace angle + +namespace gl +{ +class Context; +class TextureManager; +class SemaphoreManager; +} // namespace gl + +namespace rx +{ +class DisplayImpl; +class EGLImplFactory; +class ShareGroupImpl; +} // namespace rx + +namespace egl +{ +class Device; +class Image; +class Stream; +class Surface; +class Sync; +class Thread; + +using ContextSet = angle::HashSet; +using SurfaceSet = angle::HashSet; +using ThreadSet = angle::HashSet; + +struct DisplayState final : private angle::NonCopyable +{ + DisplayState(EGLNativeDisplayType nativeDisplayId); + ~DisplayState(); + + EGLLabelKHR label; + ContextSet contextSet; + SurfaceSet surfaceSet; + std::vector featureOverridesEnabled; + std::vector featureOverridesDisabled; + bool featuresAllDisabled; + EGLNativeDisplayType displayId; +}; + +class ShareGroup final : angle::NonCopyable +{ + public: + ShareGroup(rx::EGLImplFactory *factory); + + void addRef(); + + void release(const egl::Display *display); + + rx::ShareGroupImpl *getImplementation() const { return mImplementation; } + + rx::Serial generateFramebufferSerial() { return mFramebufferSerialFactory.generate(); } + + angle::FrameCaptureShared *getFrameCaptureShared() { return mFrameCaptureShared.get(); } + + void finishAllContexts(); + + const ContextSet &getContexts() const { return mContexts; } + void addSharedContext(gl::Context *context); + void removeSharedContext(gl::Context *context); + + size_t getShareGroupContextCount() const { return mContexts.size(); } + + protected: + ~ShareGroup(); + + private: + size_t mRefCount; + rx::ShareGroupImpl *mImplementation; + rx::SerialFactory mFramebufferSerialFactory; + + // Note: we use a raw pointer here so we can exclude frame capture sources from the build. + std::unique_ptr mFrameCaptureShared; + + // The list of contexts within the share group + ContextSet mContexts; +}; + +// Constant coded here as a reasonable limit. +constexpr EGLAttrib kProgramCacheSizeAbsoluteMax = 0x4000000; + +class Display final : public LabeledObject, + public angle::ObserverInterface, + public angle::NonCopyable +{ + public: + ~Display() override; + + void setLabel(EGLLabelKHR label) override; + EGLLabelKHR getLabel() const override; + + // Observer implementation. + void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; + + Error initialize(); + + enum class TerminateReason + { + Api, + InternalCleanup, + NoActiveThreads, + + InvalidEnum, + EnumCount = InvalidEnum, + }; + Error terminate(Thread *thread, TerminateReason terminateReason); + // Called before all display state dependent EGL functions. Backends can set up, for example, + // thread-specific backend state through this function. Not called for functions that do not + // need the state. + Error prepareForCall(); + // Called on eglReleaseThread. Backends can tear down thread-specific backend state through + // this function. + Error releaseThread(); + + // Helpers to maintain active thread set to assist with freeing invalid EGL objects. + void addActiveThread(Thread *thread); + void threadCleanup(Thread *thread); + + static Display *GetDisplayFromDevice(Device *device, const AttributeMap &attribMap); + static Display *GetDisplayFromNativeDisplay(EGLenum platform, + EGLNativeDisplayType nativeDisplay, + const AttributeMap &attribMap); + static Display *GetExistingDisplayFromNativeDisplay(EGLNativeDisplayType nativeDisplay); + + using EglDisplaySet = angle::HashSet; + static EglDisplaySet GetEglDisplaySet(); + + static const ClientExtensions &GetClientExtensions(); + static const std::string &GetClientExtensionString(); + + std::vector getConfigs(const AttributeMap &attribs) const; + std::vector chooseConfig(const AttributeMap &attribs) const; + + Error createWindowSurface(const Config *configuration, + EGLNativeWindowType window, + const AttributeMap &attribs, + Surface **outSurface); + Error createPbufferSurface(const Config *configuration, + const AttributeMap &attribs, + Surface **outSurface); + Error createPbufferFromClientBuffer(const Config *configuration, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const AttributeMap &attribs, + Surface **outSurface); + Error createPixmapSurface(const Config *configuration, + NativePixmapType nativePixmap, + const AttributeMap &attribs, + Surface **outSurface); + + Error createImage(const gl::Context *context, + EGLenum target, + EGLClientBuffer buffer, + const AttributeMap &attribs, + Image **outImage); + + Error createStream(const AttributeMap &attribs, Stream **outStream); + + Error createContext(const Config *configuration, + gl::Context *shareContext, + const EGLenum clientType, + const AttributeMap &attribs, + gl::Context **outContext); + + Error createSync(const gl::Context *currentContext, + EGLenum type, + const AttributeMap &attribs, + Sync **outSync); + + Error makeCurrent(Thread *thread, + gl::Context *previousContext, + Surface *drawSurface, + Surface *readSurface, + gl::Context *context); + + Error destroySurface(Surface *surface); + void destroyImage(Image *image); + void destroyStream(Stream *stream); + Error destroyContext(Thread *thread, gl::Context *context); + + void destroySync(Sync *sync); + + bool isInitialized() const; + bool isValidConfig(const Config *config) const; + bool isValidContext(const gl::Context *context) const; + bool isValidSurface(const Surface *surface) const; + bool isValidImage(const Image *image) const; + bool isValidStream(const Stream *stream) const; + bool isValidSync(const Sync *sync) const; + bool isValidNativeWindow(EGLNativeWindowType window) const; + + Error validateClientBuffer(const Config *configuration, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const AttributeMap &attribs) const; + Error validateImageClientBuffer(const gl::Context *context, + EGLenum target, + EGLClientBuffer clientBuffer, + const egl::AttributeMap &attribs) const; + Error valdiatePixmap(const Config *config, + EGLNativePixmapType pixmap, + const AttributeMap &attributes) const; + + static bool isValidDisplay(const Display *display); + static bool isValidNativeDisplay(EGLNativeDisplayType display); + static bool hasExistingWindowSurface(EGLNativeWindowType window); + + bool isDeviceLost() const; + bool testDeviceLost(); + void notifyDeviceLost(); + + void setBlobCacheFuncs(EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get); + bool areBlobCacheFuncsSet() const { return mBlobCache.areBlobCacheFuncsSet(); } + BlobCache &getBlobCache() { return mBlobCache; } + + static EGLClientBuffer GetNativeClientBuffer(const struct AHardwareBuffer *buffer); + static Error CreateNativeClientBuffer(const egl::AttributeMap &attribMap, + EGLClientBuffer *eglClientBuffer); + + Error waitClient(const gl::Context *context); + Error waitNative(const gl::Context *context, EGLint engine); + + const Caps &getCaps() const; + + const DisplayExtensions &getExtensions() const; + const std::string &getExtensionString() const; + const std::string &getVendorString() const; + const std::string &getVersionString() const; + const std::string &getClientAPIString() const; + + std::string getBackendRendererDescription() const; + std::string getBackendVendorString() const; + std::string getBackendVersionString(bool includeFullVersion) const; + + EGLint programCacheGetAttrib(EGLenum attrib) const; + Error programCacheQuery(EGLint index, + void *key, + EGLint *keysize, + void *binary, + EGLint *binarysize); + Error programCachePopulate(const void *key, + EGLint keysize, + const void *binary, + EGLint binarysize); + EGLint programCacheResize(EGLint limit, EGLenum mode); + + const AttributeMap &getAttributeMap() const { return mAttributeMap; } + EGLNativeDisplayType getNativeDisplayId() const { return mState.displayId; } + + rx::DisplayImpl *getImplementation() const { return mImplementation; } + Device *getDevice() const; + Surface *getWGLSurface() const; + EGLenum getPlatform() const { return mPlatform; } + + gl::Version getMaxSupportedESVersion() const; + + const DisplayState &getState() const { return mState; } + + const angle::FrontendFeatures &getFrontendFeatures() { return mFrontendFeatures; } + void overrideFrontendFeatures(const std::vector &featureNames, bool enabled); + + const angle::FeatureList &getFeatures() const { return mFeatures; } + + const char *queryStringi(const EGLint name, const EGLint index); + + EGLAttrib queryAttrib(const EGLint attribute); + + angle::ScratchBuffer requestScratchBuffer(); + void returnScratchBuffer(angle::ScratchBuffer scratchBuffer); + + angle::ScratchBuffer requestZeroFilledBuffer(); + void returnZeroFilledBuffer(angle::ScratchBuffer zeroFilledBuffer); + + egl::Error handleGPUSwitch(); + egl::Error forceGPUSwitch(EGLint gpuIDHigh, EGLint gpuIDLow); + + std::mutex &getDisplayGlobalMutex() { return mDisplayGlobalMutex; } + std::mutex &getProgramCacheMutex() { return mProgramCacheMutex; } + + gl::MemoryShaderCache *getMemoryShaderCache() { return &mMemoryShaderCache; } + + // Installs LoggingAnnotator as the global DebugAnnotator, for back-ends that do not implement + // their own DebugAnnotator. + void setGlobalDebugAnnotator() { gl::InitializeDebugAnnotations(&mAnnotator); } + + bool supportsDmaBufFormat(EGLint format) const; + Error queryDmaBufFormats(EGLint max_formats, EGLint *formats, EGLint *num_formats); + Error queryDmaBufModifiers(EGLint format, + EGLint max_modifiers, + EGLuint64KHR *modifiers, + EGLBoolean *external_only, + EGLint *num_modifiers); + + private: + Display(EGLenum platform, EGLNativeDisplayType displayId, Device *eglDevice); + + void setAttributes(const AttributeMap &attribMap) { mAttributeMap = attribMap; } + + void setupDisplayPlatform(rx::DisplayImpl *impl); + + void updateAttribsFromEnvironment(const AttributeMap &attribMap); + + Error restoreLostDevice(); + Error releaseContext(gl::Context *context, Thread *thread); + Error releaseContextImpl(gl::Context *context, ContextSet *contexts); + + void initDisplayExtensions(); + void initVendorString(); + void initVersionString(); + void initClientAPIString(); + void initializeFrontendFeatures(); + + angle::ScratchBuffer requestScratchBufferImpl(std::vector *bufferVector); + void returnScratchBufferImpl(angle::ScratchBuffer scratchBuffer, + std::vector *bufferVector); + + Error destroyInvalidEglObjects(); + + DisplayState mState; + rx::DisplayImpl *mImplementation; + angle::ObserverBinding mGPUSwitchedBinding; + + AttributeMap mAttributeMap; + + ConfigSet mConfigSet; + + typedef angle::HashSet ImageSet; + ImageSet mImageSet; + + typedef angle::HashSet StreamSet; + StreamSet mStreamSet; + + typedef angle::HashSet SyncSet; + SyncSet mSyncSet; + + void destroyImageImpl(Image *image, ImageSet *images); + void destroyStreamImpl(Stream *stream, StreamSet *streams); + Error destroySurfaceImpl(Surface *surface, SurfaceSet *surfaces); + void destroySyncImpl(Sync *sync, SyncSet *syncs); + + ContextSet mInvalidContextSet; + ImageSet mInvalidImageSet; + StreamSet mInvalidStreamSet; + SurfaceSet mInvalidSurfaceSet; + SyncSet mInvalidSyncSet; + + bool mInitialized; + bool mDeviceLost; + + Caps mCaps; + + DisplayExtensions mDisplayExtensions; + std::string mDisplayExtensionString; + + std::string mVendorString; + std::string mVersionString; + std::string mClientAPIString; + + Device *mDevice; + Surface *mSurface; + EGLenum mPlatform; + angle::LoggingAnnotator mAnnotator; + + gl::TextureManager *mTextureManager; + gl::SemaphoreManager *mSemaphoreManager; + BlobCache mBlobCache; + gl::MemoryProgramCache mMemoryProgramCache; + gl::MemoryShaderCache mMemoryShaderCache; + size_t mGlobalTextureShareGroupUsers; + size_t mGlobalSemaphoreShareGroupUsers; + + angle::FrontendFeatures mFrontendFeatures; + + angle::FeatureList mFeatures; + + std::mutex mScratchBufferMutex; + std::vector mScratchBuffers; + std::vector mZeroFilledBuffers; + + std::mutex mDisplayGlobalMutex; + std::mutex mProgramCacheMutex; + + bool mTerminatedByApi; + ThreadSet mActiveThreads; +}; + +} // namespace egl + +#endif // LIBANGLE_DISPLAY_H_ diff --git a/gfx/angle/checkout/src/libANGLE/EGLSync.cpp b/gfx/angle/checkout/src/libANGLE/EGLSync.cpp new file mode 100644 index 0000000000..ddca5de902 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/EGLSync.cpp @@ -0,0 +1,114 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// EGLSync.cpp: Implements the egl::Sync class. + +#include "libANGLE/EGLSync.h" + +#include "angle_gl.h" + +#include "common/utilities.h" +#include "libANGLE/renderer/EGLImplFactory.h" +#include "libANGLE/renderer/EGLReusableSync.h" +#include "libANGLE/renderer/EGLSyncImpl.h" + +namespace egl +{ + +Sync::Sync(rx::EGLImplFactory *factory, EGLenum type, const AttributeMap &attribs) + : mLabel(nullptr), + mType(type), + mCondition(EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR), + mNativeFenceFD( + attribs.getAsInt(EGL_SYNC_NATIVE_FENCE_FD_ANDROID, EGL_NO_NATIVE_FENCE_FD_ANDROID)) +{ + switch (type) + { + case EGL_SYNC_FENCE: + case EGL_SYNC_NATIVE_FENCE_ANDROID: + case EGL_SYNC_METAL_SHARED_EVENT_ANGLE: + mFence = std::unique_ptr(factory->createSync(attribs)); + break; + + case EGL_SYNC_REUSABLE_KHR: + mFence = std::unique_ptr(new rx::ReusableSync(attribs)); + break; + + default: + UNREACHABLE(); + } + + // Per extension spec: Signaling Condition. + // "If the EGL_SYNC_NATIVE_FENCE_FD_ANDROID attribute is not + // EGL_NO_NATIVE_FENCE_FD_ANDROID then the EGL_SYNC_CONDITION_KHR attribute + // is set to EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID and the EGL_SYNC_STATUS_KHR + // attribute is set to reflect the signal status of the native fence object. + if ((mType == EGL_SYNC_NATIVE_FENCE_ANDROID) && + (mNativeFenceFD != EGL_NO_NATIVE_FENCE_FD_ANDROID)) + { + mCondition = EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID; + } +} + +void Sync::onDestroy(const Display *display) +{ + ASSERT(mFence); + mFence->onDestroy(display); + mFence.reset(); +} + +Sync::~Sync() {} + +Error Sync::initialize(const Display *display, const gl::Context *context) +{ + return mFence->initialize(display, context, mType); +} + +void Sync::setLabel(EGLLabelKHR label) +{ + mLabel = label; +} + +EGLLabelKHR Sync::getLabel() const +{ + return mLabel; +} + +Error Sync::clientWait(const Display *display, + const gl::Context *context, + EGLint flags, + EGLTime timeout, + EGLint *outResult) +{ + return mFence->clientWait(display, context, flags, timeout, outResult); +} + +Error Sync::serverWait(const Display *display, const gl::Context *context, EGLint flags) +{ + return mFence->serverWait(display, context, flags); +} + +Error Sync::signal(const Display *display, const gl::Context *context, EGLint mode) +{ + return mFence->signal(display, context, mode); +} + +Error Sync::getStatus(const Display *display, EGLint *outStatus) const +{ + return mFence->getStatus(display, outStatus); +} + +Error Sync::copyMetalSharedEventANGLE(const Display *display, void **result) const +{ + return mFence->copyMetalSharedEventANGLE(display, result); +} + +Error Sync::dupNativeFenceFD(const Display *display, EGLint *result) const +{ + return mFence->dupNativeFenceFD(display, result); +} + +} // namespace egl diff --git a/gfx/angle/checkout/src/libANGLE/EGLSync.h b/gfx/angle/checkout/src/libANGLE/EGLSync.h new file mode 100644 index 0000000000..2f97e9c3da --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/EGLSync.h @@ -0,0 +1,72 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// EGLSync.h: Defines the egl::Sync classes, which support the EGL_KHR_fence_sync, +// EGL_KHR_wait_sync and EGL 1.5 sync objects. + +#ifndef LIBANGLE_EGLSYNC_H_ +#define LIBANGLE_EGLSYNC_H_ + +#include "libANGLE/Debug.h" +#include "libANGLE/Error.h" +#include "libANGLE/RefCountObject.h" + +#include "common/angleutils.h" + +namespace rx +{ +class EGLImplFactory; +class EGLSyncImpl; +} // namespace rx + +namespace gl +{ +class Context; +} // namespace gl + +namespace egl +{ +class Sync final : public angle::RefCountObject, public LabeledObject +{ + public: + Sync(rx::EGLImplFactory *factory, EGLenum type, const AttributeMap &attribs); + ~Sync() override; + + void setLabel(EGLLabelKHR label) override; + EGLLabelKHR getLabel() const override; + + void onDestroy(const Display *display) override; + + Error initialize(const Display *display, const gl::Context *context); + Error clientWait(const Display *display, + const gl::Context *context, + EGLint flags, + EGLTime timeout, + EGLint *outResult); + Error serverWait(const Display *display, const gl::Context *context, EGLint flags); + Error signal(const Display *display, const gl::Context *context, EGLint mode); + Error getStatus(const Display *display, EGLint *outStatus) const; + + Error copyMetalSharedEventANGLE(const Display *display, void **result) const; + Error dupNativeFenceFD(const Display *display, EGLint *result) const; + + EGLenum getType() const { return mType; } + EGLint getCondition() const { return mCondition; } + EGLint getNativeFenceFD() const { return mNativeFenceFD; } + + private: + std::unique_ptr mFence; + + EGLLabelKHR mLabel; + + EGLenum mType; + EGLint mCondition; + EGLint mNativeFenceFD; +}; + +} // namespace egl + +#endif // LIBANGLE_FENCE_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Error.cpp b/gfx/angle/checkout/src/libANGLE/Error.cpp new file mode 100644 index 0000000000..977e8d66e0 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Error.cpp @@ -0,0 +1,67 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Error.cpp: Implements the egl::Error and gl::Error classes which encapsulate API errors +// and optional error messages. + +#include "libANGLE/Error.h" + +#include "common/angleutils.h" +#include "common/debug.h" +#include "common/utilities.h" + +#include + +namespace +{ +std::unique_ptr EmplaceErrorString(std::string &&message) +{ + return message.empty() ? std::unique_ptr() + : std::unique_ptr(new std::string(std::move(message))); +} +} // anonymous namespace + +namespace egl +{ + +Error::Error(EGLint errorCode, std::string &&message) + : mCode(errorCode), mID(errorCode), mMessage(EmplaceErrorString(std::move(message))) +{} + +Error::Error(EGLint errorCode, EGLint id, std::string &&message) + : mCode(errorCode), mID(id), mMessage(EmplaceErrorString(std::move(message))) +{} + +void Error::createMessageString() const +{ + if (!mMessage) + { + mMessage.reset(new std::string(GetGenericErrorMessage(mCode))); + } +} + +const std::string &Error::getMessage() const +{ + createMessageString(); + return *mMessage; +} + +std::ostream &operator<<(std::ostream &os, const Error &err) +{ + return gl::FmtHex(os, err.getCode()); +} +} // namespace egl + +namespace angle +{ +egl::Error ResultToEGL(Result result) +{ + if (result == Result::Continue) + return egl::NoError(); + + return egl::Error(EGL_BAD_ACCESS); +} +} // namespace angle diff --git a/gfx/angle/checkout/src/libANGLE/Error.h b/gfx/angle/checkout/src/libANGLE/Error.h new file mode 100644 index 0000000000..7f075352cc --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Error.h @@ -0,0 +1,206 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Error.h: Defines the egl::Error and gl::Error classes which encapsulate API errors +// and optional error messages. + +#ifndef LIBANGLE_ERROR_H_ +#define LIBANGLE_ERROR_H_ + +#include +#include +#include "angle_gl.h" +#include "common/angleutils.h" +#include "common/debug.h" + +#include +#include +#include + +namespace angle +{ +template +class ErrorStreamBase : angle::NonCopyable +{ + public: + ErrorStreamBase() : mID(EnumT) {} + ErrorStreamBase(GLuint id) : mID(id) {} + + template + ErrorStreamBase &operator<<(T value) + { + mErrorStream << value; + return *this; + } + + operator ErrorT() { return ErrorT(EnumT, mID, mErrorStream.str()); } + + private: + GLuint mID; + std::ostringstream mErrorStream; +}; +} // namespace angle + +namespace egl +{ +class Error; +} // namespace egl + +namespace egl +{ + +class [[nodiscard]] Error final +{ + public: + explicit inline Error(EGLint errorCode); + Error(EGLint errorCode, std::string &&message); + Error(EGLint errorCode, EGLint id, std::string &&message); + inline Error(const Error &other); + inline Error(Error &&other); + inline ~Error() = default; + + inline Error &operator=(const Error &other); + inline Error &operator=(Error &&other); + + inline EGLint getCode() const; + inline EGLint getID() const; + inline bool isError() const; + + const std::string &getMessage() const; + + static inline Error NoError(); + + private: + void createMessageString() const; + + friend std::ostream &operator<<(std::ostream &os, const Error &err); + + EGLint mCode; + EGLint mID; + mutable std::unique_ptr mMessage; +}; + +namespace priv +{ + +template +using ErrorStream = angle::ErrorStreamBase; + +} // namespace priv + +using EglBadAccess = priv::ErrorStream; +using EglBadAlloc = priv::ErrorStream; +using EglBadAttribute = priv::ErrorStream; +using EglBadConfig = priv::ErrorStream; +using EglBadContext = priv::ErrorStream; +using EglBadCurrentSurface = priv::ErrorStream; +using EglBadDevice = priv::ErrorStream; +using EglBadDisplay = priv::ErrorStream; +using EglBadMatch = priv::ErrorStream; +using EglBadNativeWindow = priv::ErrorStream; +using EglBadNativePixmap = priv::ErrorStream; +using EglBadParameter = priv::ErrorStream; +using EglBadState = priv::ErrorStream; +using EglBadStream = priv::ErrorStream; +using EglBadSurface = priv::ErrorStream; +using EglContextLost = priv::ErrorStream; +using EglNotInitialized = priv::ErrorStream; + +inline Error NoError() +{ + return Error::NoError(); +} + +} // namespace egl + +#define ANGLE_CONCAT1(x, y) x##y +#define ANGLE_CONCAT2(x, y) ANGLE_CONCAT1(x, y) +#define ANGLE_LOCAL_VAR ANGLE_CONCAT2(_localVar, __LINE__) + +#define ANGLE_TRY_TEMPLATE(EXPR, FUNC) \ + do \ + { \ + auto ANGLE_LOCAL_VAR = EXPR; \ + if (ANGLE_UNLIKELY(IsError(ANGLE_LOCAL_VAR))) \ + { \ + FUNC(ANGLE_LOCAL_VAR); \ + } \ + } while (0) + +#define ANGLE_RETURN(X) return X; +#define ANGLE_TRY(EXPR) ANGLE_TRY_TEMPLATE(EXPR, ANGLE_RETURN) + +// TODO(jmadill): Remove after EGL error refactor. http://anglebug.com/3041 +#define ANGLE_SWALLOW_ERR(EXPR) \ + do \ + { \ + auto ANGLE_LOCAL_VAR = EXPR; \ + if (ANGLE_UNLIKELY(IsError(ANGLE_LOCAL_VAR))) \ + { \ + ERR() << "Unhandled internal error: " << ANGLE_LOCAL_VAR; \ + } \ + } while (0) + +#undef ANGLE_LOCAL_VAR +#undef ANGLE_CONCAT2 +#undef ANGLE_CONCAT1 + +#define ANGLE_CHECK(CONTEXT, EXPR, MESSAGE, ERROR) \ + do \ + { \ + if (ANGLE_UNLIKELY(!(EXPR))) \ + { \ + CONTEXT->handleError(ERROR, MESSAGE, __FILE__, ANGLE_FUNCTION, __LINE__); \ + return angle::Result::Stop; \ + } \ + } while (0) + +namespace angle +{ +// Result signals if calling code should continue running or early exit. A value of Stop can +// either indicate an Error or a non-Error early exit condition such as a detected no-op. +// Incomplete signals special cases that are neither success nor failure but require +// special attention. +enum class [[nodiscard]] Result{ + Continue, + Stop, + Incomplete, +}; + +// TODO(jmadill): Remove this when refactor is complete. http://anglebug.com/3041 +egl::Error ResultToEGL(Result result); +} // namespace angle + +// TODO(jmadill): Remove this when refactor is complete. http://anglebug.com/3041 +inline bool IsError(angle::Result result) +{ + return result == angle::Result::Stop; +} + +// TODO(jmadill): Remove this when refactor is complete. http://anglebug.com/3041 +inline bool IsError(const egl::Error &err) +{ + return err.isError(); +} + +// TODO(jmadill): Remove this when refactor is complete. http://anglebug.com/3041 +inline bool IsError(bool value) +{ + return !value; +} + +// Utility macro for handling implementation methods inside Validation. +#define ANGLE_HANDLE_VALIDATION_ERR(X) \ + do \ + { \ + (void)(X); \ + return false; \ + } while (0) + +#define ANGLE_VALIDATION_TRY(EXPR) ANGLE_TRY_TEMPLATE(EXPR, ANGLE_HANDLE_VALIDATION_ERR) + +#include "Error.inc" + +#endif // LIBANGLE_ERROR_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Error.inc b/gfx/angle/checkout/src/libANGLE/Error.inc new file mode 100644 index 0000000000..e6a8032895 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Error.inc @@ -0,0 +1,91 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Error.inc: Inline definitions of egl::Error and gl::Error classes which encapsulate API errors +// and optional error messages. + +#include "common/angleutils.h" + +#include + +namespace egl +{ + +Error::Error(EGLint errorCode) + : mCode(errorCode), + mID(0) +{ +} + +Error::Error(const Error &other) + : mCode(other.mCode), + mID(other.mID) +{ + if (other.mMessage) + { + createMessageString(); + *mMessage = *(other.mMessage); + } +} + +Error::Error(Error &&other) + : mCode(other.mCode), + mID(other.mID), + mMessage(std::move(other.mMessage)) +{ +} + +Error &Error::operator=(const Error &other) +{ + mCode = other.mCode; + mID = other.mID; + + if (other.mMessage) + { + createMessageString(); + *mMessage = *(other.mMessage); + } + else + { + mMessage.reset(); + } + + return *this; +} + +Error &Error::operator=(Error &&other) +{ + if (this != &other) + { + mCode = other.mCode; + mID = other.mID; + mMessage = std::move(other.mMessage); + } + + return *this; +} + +EGLint Error::getCode() const +{ + return mCode; +} + +EGLint Error::getID() const +{ + return mID; +} + +bool Error::isError() const +{ + return (mCode != EGL_SUCCESS); +} + +// Static +Error Error::NoError() +{ + return Error(EGL_SUCCESS); +} + +} diff --git a/gfx/angle/checkout/src/libANGLE/ErrorStrings.h b/gfx/angle/checkout/src/libANGLE/ErrorStrings.h new file mode 100644 index 0000000000..df352b8114 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/ErrorStrings.h @@ -0,0 +1,627 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ErrorStrings.h: Contains mapping of commonly used error messages + +#ifndef LIBANGLE_ERRORSTRINGS_H_ +#define LIBANGLE_ERRORSTRINGS_H_ + +namespace gl +{ +namespace err +{ +#define MSG constexpr const char * + +// clang-format off +MSG k3DDepthStencil = "Format cannot be GL_DEPTH_COMPONENT or GL_DEPTH_STENCIL if target is GL_TEXTURE_3D"; +MSG kANGLECopyTexture3DUnavailable = "GL_ANGLE_copy_texture_3d extension not available."; +MSG kANGLECopyTextureMissingRequiredExtension = "Copy*TextureCHROMIUM from EXTERNAL_OES to integer format requires OES_EGL_image_external_essl3"; +MSG kAdvancedBlendEquationWithMRT = "Advanced blend equation can only be used when only one draw buffer is not NONE"; +MSG kAdvancedBlendExtensionNotEnabled = "GL_KHR_blend_equation_advanced extension not enabled."; +MSG kAtomicCounterResourceName = "Active atomic counter resources are not assigned name strings."; +MSG kAttributeListNotNull = "Attribute list must be NULL or GL_NONE"; +MSG kAttributeZeroRequiresDivisorLimitation = "The current context doesn't support setting a non-zero divisor on the attribute with index zero. Please reorder the attributes in your vertex shader so that attribute zero can have a zero divisor."; +MSG kBaseLevelNegative = "Base level must be at least 0."; +MSG kBaseLevelNonZero = "Base level must be 0."; +MSG kBaseLevelOutOfRange = "Texture base level out of range"; +MSG kBlendEquationNotEnabled = "Active fragment shader does not include the layout qualifier matching the blend equation"; +MSG kBlitDepthOrStencilFormatMismatch = "Depth/stencil buffer format combination not allowed for blit."; +MSG kBlitDimensionsOutOfRange = "BlitFramebuffer dimensions out of 32-bit integer range."; +MSG kBlitExtensionDepthStencilWholeBufferBlit = "Only whole-buffer depth and stencil blits are supported by this extension."; +MSG kBlitExtensionFormatMismatch = "Attempting to blit and the read and draw buffer formats don't match. read: 0x%04X draw: 0x%04X"; +MSG kBlitExtensionFromInvalidAttachmentType = "Blits are only supported from 2D texture, renderbuffer or default framebuffer attachments in this extension."; +MSG kBlitExtensionLinear = "Linear blit not supported in this extension."; +MSG kBlitExtensionMultisampledDepthOrStencil = "Multisampled depth/stencil blit is not supported by this extension."; +MSG kBlitExtensionMultisampledWholeBufferBlit = "Only whole-buffer blit is supported from a multisampled read buffer in this extension."; +MSG kBlitExtensionNotAvailable = "Blit extension not available."; +MSG kBlitExtensionScaleOrFlip = "Scaling and flipping in BlitFramebufferANGLE not supported by this implementation."; +MSG kBlitExtensionToInvalidAttachmentType = "Blits are only supported to 2D texture, renderbuffer or default framebuffer attachments in this extension."; +MSG kBlitFeedbackLoop = "Blit feedback loop: the read and draw framebuffers are the same."; +MSG kBlitFramebufferMissing = "Read and draw framebuffers must both exist for a blit to succeed."; +MSG kBlitFromMultiview = "Attempt to read from a multi-view framebuffer."; +MSG kBlitIntegerWithLinearFilter = "Cannot use GL_LINEAR filter when blitting a integer framebuffer."; +MSG kBlitInvalidFilter = "Invalid blit filter."; +MSG kBlitInvalidMask = "Invalid blit mask."; +MSG kBlitMissingColor = "Attempt to read from a missing color attachment of a complete framebuffer."; +MSG kBlitMissingDepthOrStencil = "Attempt to read from a missing depth/stencil attachment of a complete framebuffer."; +MSG kBlitMultisampledBoundsMismatch = "Attempt to blit from a multisampled framebuffer and the bounds don't match with the draw framebuffer."; +MSG kBlitMultisampledFormatOrBoundsMismatch = "Attempt to blit from a multisampled framebuffer and the bounds or format of the color buffer don't match with the draw framebuffer."; +MSG kBlitOnlyNearestForNonColor = "Only nearest filtering can be used when blitting buffers other than the color buffer."; +MSG kBlitSameImageColor = "Read and write color attachments cannot be the same image."; +MSG kBlitSameImageDepthOrStencil = "Read and write depth stencil attachments cannot be the same image."; +MSG kBlitToMultiview = "Attempt to write to a multi-view framebuffer."; +MSG kBlitTypeMismatchFixedOrFloat = "If the read buffer contains fixed-point or floating-point values, the draw buffer must as well."; +MSG kBlitTypeMismatchFixedPoint = "If the read buffer contains fixed-point values, the draw buffer must as well."; +MSG kBlitTypeMismatchSignedInteger = "If the read buffer contains signed integer values the draw buffer must as well."; +MSG kBlitTypeMismatchUnsignedInteger = "If the read buffer contains unsigned integer values the draw buffer must as well."; +MSG kBlitYUVFramebuffer = "Blitting to or from a YUV framebuffer is disallowed."; +MSG kBufferAlreadyMapped = "Buffer is already mapped."; +MSG kBufferBoundForTransformFeedback = "Buffer is bound for transform feedback."; +MSG kBufferImmutable = "Buffer is immutable."; +MSG kBufferMapped = "An active buffer is mapped"; +MSG kBufferNotBound = "A buffer must be bound."; +MSG kBufferNotMappable = "Attempted to map buffer object zero."; +MSG kBufferNotMapped = "Buffer is not mapped."; +MSG kBufferNotUpdatable = "Buffer is not updatable."; +MSG kBufferOffsetOverflow = "Buffer offset overflow."; +MSG kBufferPointerNotAvailable = "Can not get pointer for reserved buffer name zero."; +MSG kCannotPopDefaultDebugGroup = "Cannot pop the default debug group."; +MSG kClientBufferInvalid = "Size must not exceed the size of clientbuffer"; +MSG kClientDataInVertexArray = "Client data cannot be used with a non-default vertex array object."; +MSG kColorNumberGreaterThanMaxDrawBuffers = "Color number for primary color greater than or equal to MAX_DRAW_BUFFERS"; +MSG kColorNumberGreaterThanMaxDualSourceDrawBuffers = "Color number for secondary color greater than or equal to MAX_DUAL_SOURCE_DRAW_BUFFERS"; +MSG kCompressedDataSizeTooSmall = "dataSize is too small"; +MSG kCompressedMismatch = "Compressed data is valid if-and-only-if the texture is compressed."; +MSG kCompressedTextureDimensionsMustMatchData = "Compressed texture dimensions must exactly match the dimensions of the data passed in."; +MSG kCompressedTexturesNotAttachable = "Compressed textures cannot be attached to a framebuffer."; +MSG kConstantColorAlphaLimitation = "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR as color factors is not supported by this implementation."; +MSG kContextLost = "Context has been lost."; +MSG kCopyAlias = "The read and write copy regions alias memory."; +MSG kCopyFromYUVFramebuffer = "Copying from a YUV framebuffer is disallowed."; +MSG kCubemapFacesEqualDimensions = "Each cubemap face must have equal width and height."; +MSG kCubemapIncomplete = "Texture is not cubemap complete. All cubemaps faces must be defined and be the same size."; +MSG kCubemapInvalidDepth = "The cubemap depth must be a multiple of 6."; +MSG kDataTypeNotAligned = "Data is not evenly divisible into the number of bytes needed to store in memory a datum indicated by type."; +MSG kDefaultFramebuffer = "Default framebuffer is bound."; +MSG kDefaultFramebufferAttachmentOnUserFBO = "Invalid attachment when a user framebuffer is bound."; +MSG kDefaultFramebufferInvalidAttachment = "Invalid attachment when the default framebuffer is bound."; +MSG kDefaultFramebufferInvalidDrawBuffer = "Only NONE or BACK are valid draw buffers for the default framebuffer"; +MSG kDefaultFramebufferTarget = "It is invalid to change default FBO's attachments"; +MSG kDefaultVertexArray = "Default vertex array object is bound."; +MSG kDestinationImmutable = "Destination texture cannot be immutable."; +MSG kDestinationLevelNotDefined = "The destination level of the destination texture must be defined."; +MSG kDestinationTextureTooSmall = "Destination texture too small."; +MSG kDimensionsMustBePow2 = "Texture dimensions must be power-of-two."; +MSG kDispatchIndirectBufferNotBound = "Dispatch indirect buffer must be bound."; +MSG kDrawBufferMaskMismatch = "Active draw buffers with missing fragment shader outputs."; +MSG kDrawBuffersIndexedExtensionNotAvailable = "EXT/OES_draw_buffers_indexed is not available."; +MSG kES31OrDrawBuffersIndexedExtensionNotAvailable = "EXT/OES_draw_buffers_indexed or ES 3.1 are required but not available."; +MSG kDrawBufferTypeMismatch = "Fragment shader output type does not match the bound framebuffer attachment type."; +MSG kDrawFramebufferIncomplete = "Draw framebuffer is incomplete"; +MSG kDrawIndirectBufferNotBound = "Draw indirect buffer must be bound."; +MSG kEGLImageCannotCreate2DMultisampled = "Cannot create a 2D texture from a multisampled EGL image."; +MSG kEGLImageRenderbufferFormatNotSupported = "EGL image internal format is not supported as a renderbuffer."; +MSG kEGLImageTextureFormatNotSupported = "EGL image internal format is not supported as a texture."; +MSG kEGLImageTextureTargetMismatch = "The source EGL image is incompatible with the target texture type."; +MSG kElementArrayBufferBoundForTransformFeedback = "It is undefined behavior to use an element array buffer that is bound for transform feedback."; +MSG kElementArrayNoBufferOrPointer = "No element array buffer and no pointer."; +MSG kEnumInvalid = "Invalid enum provided."; +MSG kEnumNotSupported = "Enum 0x%04X is currently not supported."; +MSG kEnumRequiresGLES30 = "Enum requires GLES 3.0"; +MSG kEnumRequiresGLES31 = "Enum requires GLES 3.1"; +MSG kES1or32Required = "OpenGL ES 1.x or 3.2 Required"; +MSG kES31Required = "OpenGL ES 3.1 Required"; +MSG kES32Required = "OpenGL ES 3.2 Required"; +MSG kES3Required = "OpenGL ES 3.0 Required."; +MSG kExceedsComputeWorkGroupCountX = "num_groups_x cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[0]"; +MSG kExceedsComputeWorkGroupCountY = "num_groups_y cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[1]"; +MSG kExceedsComputeWorkGroupCountZ = "num_groups_z cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[2]"; +MSG kExceedsElementRange = "Element value exceeds element range."; +MSG kExceedsFramebufferHeight = "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_HEIGHT."; +MSG kExceedsFramebufferSamples = "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_SAMPLES."; +MSG kExceedsFramebufferWidth = "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_WIDTH."; +MSG kExceedsMaxColorAttachments = "Index is greater than the maximum supported color attachments"; +MSG kExceedsMaxDebugGroupStackDepth = "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups."; +MSG kExceedsMaxDebugMessageLength = "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH."; +MSG kExceedsMaxDrawBuffers = "Draw buffer greater than MAX_DRAW_BUFFERS."; +MSG kExceedsMaxElement = "Element value exceeds maximum element index."; +MSG kExceedsMaxImageUnits = "Index must be within [0, MAX_IMAGE_UNITS)."; +MSG kExceedsMaxLabelLength = "Label length is larger than GL_MAX_LABEL_LENGTH."; +MSG kExceedsMaxShaderStorageBufferBindings = "Index must be within [0, MAX_SHADER_STORAGE_BUFFER_BINDINGS)."; +MSG kExceedsMaxVertexAttribBindings = "Index must be within [0, MAX_VERTEX_ATTRIB_BINDINGS)."; +MSG kExceedsMaxVertexAttribStride = "Stride must be within [0, MAX_VERTEX_ATTRIB_STRIDE)."; +MSG kExceedsNumExtensions = "Index must be within [0, NUM_EXTENSIONS)."; +MSG kExceedsNumRequestableExtensions = "Index must be within [0, NUM_REQUESTABLE_EXTENSIONS_ANGLE)."; +MSG kExpectedProgramName = "Expected a program name, but found a shader name."; +MSG kExpectedShaderName = "Expected a shader name, but found a program name."; +MSG kExtensionNotEnabled = "Extension is not enabled."; +MSG kExtensionNotDisablable = "Extension is not disablable."; +MSG kExtensionNotRequestable = "Extension is not requestable."; +MSG kExternalBufferInvalidOffset = "Offset must be zero for external buffers"; +MSG kExternalTextureAttachmentNotYUV = "External texture attached to framebuffer is not YUV."; +MSG kExternalTextureNotSupported = "External texture extension not enabled"; +MSG kFeedbackLoop = "Feedback loop formed between Framebuffer and active Texture."; +MSG kFixedNotInWebGL = "GL_FIXED is not supported in WebGL."; +MSG kFormatNotRenderable = "Internal format is not renderable."; +MSG kFragDataBindingIndexOutOfRange = "Fragment output color index must be zero or one."; +MSG kFragmentInputTypeNotFloatingPoint = "Fragment input type is not a floating point scalar or vector."; +MSG kFramebufferFetchNonCoherentExtensionNotEnabled = "GL_EXT_shader_framebuffer_fetch_non_coherent not enabled."; +MSG kFramebufferIncomplete = "Framebuffer is incomplete."; +MSG kFramebufferIncompleteAttachment = "Attachment type must be compatible with attachment object."; +MSG kFramebufferIncompleteAttachmentDepthGreaterThanMaxLayers = "Framebuffer is incomplete: Attachment depth is greater than MAX_FRAMEBUFFER_LAYERS."; +MSG kFramebufferIncompleteAttachmentInconsistantBitPlanes = "Framebuffer is incomplete: Attachments have inconsistent bit plane counts."; +MSG kFramebufferIncompleteAttachmentLayerGreaterThanDepth = "Framebuffer is incomplete: Attachment layer is greater than texture layer count."; +MSG kFramebufferIncompleteAttachmentLevelNotBaseLevelForIncompleteMipTexture = "Framebuffer is incomplete: Attachment level not equal to the base level and the texture is not mipmap complete."; +MSG kFramebufferIncompleteAttachmentLevelOutOfBaseMaxLevelRange = "Framebuffer is incomplete: Attachment level is not in the [base level, max level] range."; +MSG kFramebufferIncompleteAttachmentNoDepthBitsInDepthBuffer = "Framebuffer is incomplete: Depth attachment has no depth bits."; +MSG kFramebufferIncompleteAttachmentNoStencilBitsInStencilBuffer = "Framebuffer is incomplete: Stencil attachment has no stencil bits."; +MSG kFramebufferIncompleteAttachmentNotCubeComplete = "Framebuffer is incomplete: Attachment is an incomplete cube map."; +MSG kFramebufferIncompleteAttachmentNotRenderable = "Framebuffer is incomplete: Attachment is not renderable."; +MSG kFramebufferIncompleteAttachmentSamplesGreaterThanMaxSupportedSamples = "Framebuffer is incomplete: Attachment samples are greater than the maximum supported samples for this format."; +MSG kFramebufferIncompleteAttachmentsNotUnique = "Framebuffer is incomplete: All attachments must be unique."; +MSG kFramebufferIncompleteAttachmentWebGLDepthBufferHasStencilBits = "Framebuffer is incomplete: Stencil attachment has depth bits."; +MSG kFramebufferIncompleteAttachmentWebGLDepthStencilNoDepthOrStencilBits = "Framebuffer is incomplete: Depth stencil attachment has no depth bits or no stencil bits."; +MSG kFramebufferIncompleteAttachmentWebGLStencilBufferHasDepthBits = "Framebuffer is incomplete: Stencil attachment has depth bits."; +MSG kFramebufferIncompleteAttachmentZeroSize = "Framebuffer is incomplete: Attachment has zero size."; +MSG kFramebufferIncompleteColorBitsUsedExceedsMaxColorBitsSupported = "Framebuffer is incomplete: The total number of color bits exceeds the number of output bits supported."; +MSG kFramebufferIncompleteDefaultZeroSize = "Framebuffer is incomplete: No attachments and default size is zero."; +MSG kFramebufferIncompleteDepthAndStencilBuffersNotTheSame = "Framebuffer is incomplete: Depth and stencil attachments are not the same."; +MSG kFramebufferIncompleteDepthStencilInColorBuffer = "Framebuffer is incomplete: Depth stencil texture in color attachment."; +MSG kFramebufferIncompleteDriverUnsupported = "Framebuffer is incomplete: Driver does not support this framebuffer configuration."; +MSG kFramebufferIncompleteInconsistantAttachmentSizes = "Framebuffer is incomplete: Attachments are not all the same size."; +MSG kFramebufferIncompleteInternalError = "Framebuffer is incomplete: Internal error."; +MSG kFramebufferIncompleteMismatchedLayeredAttachments = "Framebuffer is incomplete: If one attachment is layered, all must be layered."; +MSG kFramebufferIncompleteMismatchedLayeredTexturetypes = "Framebuffer is incomplete: If an attachments are layered, they must all be the same texture type."; +MSG kFramebufferIncompleteMultisampleDepthStencilSampleCountDivisibleByColorSampleCount = "Framebuffer is incomplete: Depth stencil sample count must be divisible by the color sample count."; +MSG kFramebufferIncompleteMultisampleInconsistentFixedSampleLocations = "Framebuffer is incomplete: Attachments have inconsistent fixed sample locations."; +MSG kFramebufferIncompleteMultisampleInconsistentSampleCounts = "Framebuffer is incomplete: Attachments have different sample counts."; +MSG kFramebufferIncompleteMultisampleNonFixedSamplesWithRenderbuffers = "Framebuffer is incomplete: All textures must have fixed samples if paired with multisample renderbuffers."; +MSG kFramebufferIncompleteMultiviewBaseViewMismatch = "Framebuffer is incomplete: Attachments have inconsistent multiview base view."; +MSG kFramebufferIncompleteMultiviewMismatch = "Framebuffer is incomplete: Attachments have inconsistent multiview enabled state."; +MSG kFramebufferIncompleteMultiviewViewsMismatch = "Framebuffer is incomplete: Attachments have inconsistent multiview view counts."; +MSG kFramebufferIncompleteSurfaceless = "Framebuffer is incomplete: Framebuffer is surfaceless."; +MSG kFramebufferIncompleteUnsupportedMissmatchedDimensions = "Framebuffer is incomplete: Mismatched attachment sizes are unsupported."; +MSG kFramebufferIncompleteUnsupportedNonUniqueAttachments = "Framebuffer is incomplete: Non-unique attachments are unsupported."; +MSG kFramebufferIncompleteUnsupportedSeparateDepthStencilBuffers = "Framebuffer is incomplete: Separate depth and stencil buffers are unsupported."; +MSG kFramebufferIncompleteWebGLDepthStencilInconsistant = "Framebuffer is incomplete: WebGL depth stencil state is inconsistent."; +MSG kFramebufferTextureInvalidLayer = "Layer invalid for framebuffer texture attachment."; +MSG kFramebufferTextureInvalidMipLevel = "Mip level invalid for framebuffer texture attachment."; +MSG kFramebufferTextureLayerIncorrectTextureType = "Texture is not a three-dimensional, two-dimensional array, two-dimensional multisample array, cube map, or cube map array texture."; +MSG kGenerateMipmapNotAllowed = "Texture format does not support mipmap generation."; +MSG kGenerateMipmapZeroSize = "Cannot generate mipmaps for a zero-size texture in a WebGL context."; +MSG kGeometryShaderExtensionNotEnabled = "GL_EXT_geometry_shader or GL_OES_geometry_shader extension not enabled."; +MSG kGetImageExtensionNotEnabled = "GL_ANGLE_get_image extension not enabled."; +MSG kGetImageCompressed = "Texture is compressed, call GetCompressedTexImage instead."; +MSG kGetImageNotCompressed = "Texture is not compressed, call GetTexImage instead."; +MSG kGLES1Only = "GLES1-only function."; +MSG kImageSizeMustBeZero = "imageSize must be 0 if no texture data is provided."; +MSG kImageSizeTooSmall = "imageSize is too small."; +MSG kImmutableMemoryObject = "The memory object is immutable."; +MSG kImmutableTextureBound = "The value of TEXTURE_IMMUTABLE_FORMAT for the texture currently bound to target on the active texture unit is true."; +MSG kIncompatibleDrawModeAgainstGeometryShader = "Primitive mode is incompatible with the input primitive type of the geometry shader."; +MSG kIncompatibleDrawModeWithTessellationShader = "When tessellation is active the primitive mode must be GL_PATCHES."; +MSG kIncompatibleDrawModeWithoutTessellationShader = "When tessellation is not active the primitive mode must not be GL_PATCHES."; +MSG kIncompatibleTextures = "Texture formats are not compatible"; +MSG kIndexExceedsActiveUniformBlockCount = "Index exceeds active uniform block count."; +MSG kIndexExceedsMaxActiveUniform = "Index must be less than program active uniform count."; +MSG kIndexExceedsMaxActiveUniformBlock = "Index must be less than program active uniform block count."; +MSG kIndexExceedsMaxAtomicCounterBufferBindings = "Index must be less than MAX_ATOMIC_COUNTER_BUFFER_BINDINGS."; +MSG kIndexExceedsMaxDrawBuffer = "Index must be less than MAX_DRAW_BUFFERS."; +MSG kIndexExceedsMaxTransformFeedbackAttribs = "Index must be less than MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS."; +MSG kIndexExceedsMaxUniformBufferBindings = "Index must be less than MAX_UNIFORM_BUFFER_BINDINGS."; +MSG kIndexExceedsMaxVertexAttribute = "Index must be less than MAX_VERTEX_ATTRIBS."; +MSG kIndexExceedsMaxWorkgroupDimensions = "Index must be less than the number of workgroup dimensions (3)."; +MSG kIndexExceedsSamples = "Index must be less than the value of SAMPLES."; +MSG kIndexExceedsTransformFeedbackBufferBindings = "Index is greater than or equal to the number of TRANSFORM_FEEDBACK_BUFFER indexed binding points."; +MSG kInsufficientBufferSize = "Insufficient buffer size."; +MSG kInsufficientParams = "More parameters are required than were provided."; +MSG kInsufficientVertexBufferSize = "Vertex buffer is not big enough for the draw call"; +MSG kIntegerOverflow = "Integer overflow."; +MSG kInternalFormatRequiresTexture2D = "internalformat is an ETC1 or PVRTC1 format."; +MSG kInternalFormatRequiresTexture2DArray = "internalformat is an ETC2/EAC format and target is not GL_TEXTURE_2D_ARRAY."; +MSG kInternalFormatRequiresTexture2DArrayS3TC = "internalformat is an S3TC format and target is not GL_TEXTURE_2D_ARRAY."; +MSG kInternalFormatRequiresTexture2DArrayRGTC = "internalformat is an RGTC format and target is not GL_TEXTURE_2D_ARRAY."; +MSG kInternalFormatRequiresTexture2DArrayBPTC = "internalformat is a BPTC format and target is not GL_TEXTURE_2D_ARRAY."; +MSG kInternalFormatRequiresTexture2DArrayASTC = "internalformat is an ASTC format and target is not GL_TEXTURE_2D_ARRAY."; +MSG kInvalidAccessBits = "Invalid access bits."; +MSG kInvalidAccessBitsFlush = "The explicit flushing bit may only be set if the buffer is mapped for writing."; +MSG kInvalidAccessBitsRead = "Invalid access bits when mapping buffer for reading"; +MSG kInvalidAccessBitsReadWrite = "Need to map buffer for either reading or writing."; +MSG kInvalidAttachment = "Invalid Attachment Type."; +MSG kInvalidBindBufferSize = "Invalid buffer binding size."; +MSG kInvalidBindUniformLocation = "Location must be less than (MAX_VERTEX_UNIFORM_VECTORS + MAX_FRAGMENT_UNIFORM_VECTORS) * 4"; +MSG kInvalidBlendEquation = "Invalid blend equation."; +MSG kInvalidBlendFunction = "Invalid blend function."; +MSG kInvalidBlendStateForYUV = "Blending must be disabled when writing to YUV framebuffers."; +MSG kInvalidBooleanValue = "Invalid boolean value. Must be GL_FALSE or GL_TRUE."; +MSG kInvalidBorder = "Border must be 0."; +MSG kInvalidBufferName = "name is not a valid buffer."; +MSG kInvalidBufferTypes = "Invalid buffer target."; +MSG kInvalidBufferUsage = "Invalid buffer usage enum."; +MSG kInvalidBufferUsageFlags = "Invalid buffer usage flags."; +MSG kInvalidClearMask = "Invalid mask bits."; +MSG kInvalidClientState = "Invalid client vertex array type."; +MSG kInvalidClipPlane = "Invalid clip plane."; +MSG kInvalidColorMaskForYUV = "Red, green and blue color writes must be enabled when writing to YUV framebuffers."; +MSG kInvalidCombinedImageUnit = "Specified unit must be in [GL_TEXTURE0, GL_TEXTURE0 + GL_MAX_COMBINED_IMAGE_UNITS)"; +MSG kInvalidComponents = "Invalid components."; +MSG kInvalidCompressedFormat = "Not a valid compressed texture format."; +MSG kInvalidCompressedImageSize = "Invalid compressed image size."; +MSG kInvalidCompressedRegionSize = "Invalid region for compressed texture format."; +MSG kInvalidConstantColor = "CONSTANT_COLOR (or ONE_MINUS_CONSTANT_COLOR) and CONSTANT_ALPHA (or ONE_MINUS_CONSTANT_ALPHA) cannot be used together as source and destination color factors in the blend function."; +MSG kInvalidCopyCombination = "Invalid copy texture format combination."; +MSG kInvalidCoverageComponents = "components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE."; +MSG kInvalidCoverMode = "Invalid cover mode."; +MSG kInvalidExternalCreateFlags = "Create flags must only include bits defined by GL_ANGLE_external_objects_flags"; +MSG kInvalidCullMode = "Cull mode not recognized."; +MSG kInvalidDebugSeverity = "Invalid debug severity."; +MSG kInvalidDebugSource = "Invalid debug source."; +MSG kInvalidDebugSourceType = "If count is greater than zero, source and type cannot be GL_DONT_CARE."; +MSG kInvalidDebugType = "Invalid debug type."; +MSG kInvalidDefaultReadBuffer = "Read buffer must be GL_NONE or GL_BACK when reading from the default framebuffer."; +MSG kInvalidDepthEnum = "Invalid depth enum."; +MSG kInvalidDepthRange = "Near value cannot be greater than far."; +MSG kInvalidDepthStencilDrawBuffer = "Draw buffer must be zero when using depth or stencil."; +MSG kInvalidDestinationTexture = "Destination texture is not a valid texture object."; +MSG kInvalidDestinationTextureType = "Invalid destination texture type."; +MSG kInvalidDrawBuffer = "Invalid draw buffer."; +MSG kInvalidDrawBufferCountForDefault = "The default framebuffer must have exactly one draw buffer."; +MSG kInvalidDrawBufferValue = "Ith value does not match COLOR_ATTACHMENTi or NONE."; +MSG kInvalidDrawMode = "Invalid draw mode."; +MSG kInvalidDrawModeTransformFeedback = "Draw mode must match current transform feedback object's draw mode."; +MSG kInvalidEGLImage = "EGL image is not valid."; +MSG kInvalidElementRange = "Invalid element range."; +MSG kInvalidEmulatedFormat = "Implementation format is emulated."; +MSG kInvalidFence = "Invalid fence object."; +MSG kInvalidFenceCondition = "Invalid value for condition."; +MSG kInvalidFenceState = "Fence must be set."; +MSG kInvalidFillMode = "Invalid fill mode."; +MSG kInvalidFilterTexture = "Texture only supports NEAREST and LINEAR filtering."; +MSG kInvalidFlags = "Invalid value for flags."; +MSG kInvalidFlushOutOfRange = "Flushed range does not fit into buffer mapping dimensions."; +MSG kInvalidFlushTarget = "Attempted to flush a buffer not mapped for explicit flushing."; +MSG kInvalidFlushZero = "Attempted to flush buffer object zero."; +MSG kInvalidFogDensity = "Invalid fog density (must be nonnegative)."; +MSG kInvalidFogMode = "Invalid fog mode."; +MSG kInvalidFogParameter = "Invalid fog parameter."; +MSG kInvalidFormat = "Invalid format."; +MSG kInvalidFormatCombination = "Invalid combination of format, type and internalFormat."; +MSG kInvalidFragmentInputBinding = "No such binding."; +MSG kInvalidFramebufferAttachmentParameter = "Invalid parameter name for framebuffer attachment."; +MSG kInvalidFramebufferLayer = "Framebuffer layer cannot be less than 0 or greater than GL_MAX_FRAMEBUFFER_LAYERS_EXT."; +MSG kInvalidFramebufferName = "name is not a valid framebuffer."; +MSG kInvalidFramebufferTarget = "Invalid framebuffer target."; +MSG kInvalidFramebufferTextureLevel = "Mipmap level must be 0 when attaching a texture."; +MSG kInvalidHandleType = "Invalid handle type."; +MSG kInvalidImageAccess = "access is not one of the supported tokens."; +MSG kInvalidImageLayout = "Invalid image layout."; +MSG kInvalidImageFormat = "format is not one of supported image unit formats."; +MSG kInvalidIndentifier = "Invalid identifier."; +MSG kInvalidIndirectOffset = "indirect must be a multiple of the size of uint in basic machine units."; +MSG kInvalidInternalFormat = "Invalid internal format 0x%04X."; +MSG kInvalidLight = "Invalid light."; +MSG kInvalidLightModelParameter = "Invalid light model parameter."; +MSG kInvalidLightParameter = "Invalid light parameter."; +MSG kInvalidLogicOp = "Invalid logical operation."; +MSG kInvalidMapPointerQuery = "GL_BUFFER_MAP_POINTER can only be queried with GetBufferPointerv."; +MSG kInvalidMaterialFace = "Invalid material face."; +MSG kInvalidMaterialParameter = "Invalid material parameter."; +MSG kInvalidMatrixMode = "Invalid matrix mode."; +MSG kInvalidMemoryBarrierBit = "Invalid memory barrier bit."; +MSG kInvalidMemoryObject = "Invalid memory object."; +MSG kInvalidMemoryObjectParameter = "Invalid memory object parameter."; +MSG kInvalidMipLevel = "Level of detail outside of range."; +MSG kInvalidMipLevels = "Invalid level count."; +MSG kInvalidMultisampledFramebufferOperation = "Invalid operation on multisampled framebuffer"; +MSG kInvalidMultitextureUnit = "Specified unit must be in [GL_TEXTURE0, GL_TEXTURE0 + GL_MAX_TEXTURE_UNITS)"; +MSG kInvalidName = "Invalid name."; +MSG kInvalidNameCharacters = "Name contains invalid characters."; +MSG kInvalidOriginEnum = "Invalid origin enum."; +MSG kInvalidPackParametersForWebGL = "Invalid combination of pack parameters for WebGL."; +MSG kInvalidPerfMonitor = "Invalid perf monitor."; +MSG kInvalidPerfMonitorCounter = "Invalid perf monitor counter."; +MSG kInvalidPerfMonitorGroup = "Invalid perf monitor counter group."; +MSG kInvalidPname = "Invalid pname."; +MSG kInvalidPointerQuery = "Invalid pointer query."; +MSG kInvalidPointParameter = "Invalid point parameter."; +MSG kInvalidPointParameterValue = "Invalid point parameter value (must be non-negative)."; +MSG kInvalidPointSizeValue = "Invalid point size (must be positive)."; +MSG kInvalidPrecision = "Invalid or unsupported precision type."; +MSG kInvalidPrimitiveMode = "Invalid primitive mode."; +MSG kInvalidProgramBinaryFormat = "Program binary format is not valid."; +MSG kInvalidProgramInterface = "Invalid program interface."; +MSG kInvalidProgramName = "Program object expected."; +MSG kInvalidProgramPipelineName = "name is not a valid program pipeline."; +MSG kInvalidProgramResourceIndex = "Invalid program resource index."; +MSG kInvalidProgramResourceProperty = "Invalid program resource property."; +MSG kInvalidProjectionMatrix = "Invalid projection matrix. Left/right, top/bottom, near/far intervals cannot be zero, and near/far cannot be less than zero."; +MSG kInvalidPropCount = "Invalid propCount."; +MSG kInvalidPropertyForProgramInterface = "Not an allowed program resource property for this program interface"; +MSG kInvalidProvokingVertex = "Invalid provoking vertex."; +MSG kInvalidQueryId = "Invalid query Id."; +MSG kInvalidQueryName = "name is not a valid query."; +MSG kInvalidQueryTarget = "Invalid query target."; +MSG kInvalidQueryType = "Invalid query type."; +MSG kInvalidRange = "Invalid range."; +MSG kInvalidReadBuffer = "Invalid read buffer"; +MSG kInvalidRenderbufferInternalFormat = "Invalid renderbuffer internalformat."; +MSG kInvalidRenderbufferName = "name is not a valid renderbuffer."; +MSG kInvalidRenderbufferTarget = "Invalid renderbuffer target."; +MSG kInvalidRenderbufferTextureParameter = "Invalid parameter name for renderbuffer attachment."; +MSG kInvalidRenderbufferWidthHeight = "Renderbuffer width and height cannot be negative and cannot exceed maximum texture size."; +MSG kInvalidResetStatus = "Reset status is not valid"; +MSG kInvalidSampleMaskNumber = "MaskNumber cannot be greater than or equal to the value of MAX_SAMPLE_MASK_WORDS."; +MSG kInvalidSampler = "Sampler is not valid"; +MSG kInvalidSamplerName = "name is not a valid sampler."; +MSG kInvalidShaderBinaryFormat = "Invalid shader binary format."; +MSG kInvalidShaderName = "Shader object expected."; +MSG kInvalidShaderType = "Invalid shader type."; +MSG kInvalidShadingModel = "Invalid shading model."; +MSG kInvalidShadingRate = "Invalid shading rate."; +MSG kInvalidSourceTexture = "Source texture is not a valid texture object."; +MSG kInvalidSourceTextureInternalFormat = "Source texture internal format is invalid."; +MSG kInvalidSourceTextureLevel = "Invalid source texture level."; +MSG kInvalidSourceTextureSize = "Invalid source texture height or width."; +MSG kInvalidSourceTextureType = "Source texture must be a valid texture type."; +MSG kInvalidStencil = "Invalid stencil."; +MSG kInvalidStencilBitMask = "Invalid stencil bit mask."; +MSG kInvalidSyncPointer = "Not a valid sync pointer."; +MSG kInvalidTarget = "Invalid target."; +MSG kInvalidTextureCombine = "Invalid texture combine mode."; +MSG kInvalidTextureCombineOp = "Invalid texture combine operand."; +MSG kInvalidTextureCombineSrc = "Invalid texture combine source."; +MSG kInvalidTextureEnvMode = "Invalid texture environment mode."; +MSG kInvalidTextureEnvParameter = "Invalid texture environment parameter."; +MSG kInvalidTextureEnvScale = "Invalid texture environment scale."; +MSG kInvalidTextureEnvTarget = "Invalid texture environment target."; +MSG kInvalidTextureFilterParam = "Texture filter not recognized."; +MSG kInvalidTextureLevel = "Texture level does not exist."; +MSG kInvalidTextureName = "Not a valid texture object name."; +MSG kInvalidTextureRange = "Cannot be less than 0 or greater than maximum number of textures."; +MSG kInvalidTextureTarget = "Invalid or unsupported texture target."; +MSG kInvalidTextureType = "Texture has incompatible target."; +MSG kInvalidTextureWrap = "Texture wrap mode not recognized."; +MSG kInvalidTimeout = "Invalid value for timeout."; +MSG kInvalidTransformation = "Invalid transformation."; +MSG kInvalidTransformFeedbackAttribsCount = "Count exceeds MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS."; +MSG kInvalidTransformFeedbackName = "name is not a valid transform feedback."; +MSG kInvalidType = "Invalid type."; +MSG kInvalidUniformCount = "Only array uniforms may have count > 1."; +MSG kInvalidUniformLocation = "Invalid uniform location"; +MSG kInvalidUnpackAlignment = "Unpack alignment must be 1, 2, 4 or 8."; +MSG kInvalidUnpackParametersForWebGL = "Invalid combination of unpack parameters for WebGL."; +MSG kInvalidExternalUsageFlags = "Usage flags must only include bits defined by GL_ANGLE_external_objects_flags"; +MSG kInvalidValueExceedsMaxPatchSize = "Value must be less than or equal to MAX_PATCH_SIZE."; +MSG kInvalidValueNonPositive = "Value must be greater than zero."; +MSG kInvalidVaryingLocation = "Location exceeds max varying."; +MSG kInvalidVertexArray = "Vertex array does not exist."; +MSG kInvalidVertexArrayName = "name is not a valid vertex array."; +MSG kInvalidVertexAttribSize2101010 = "Type is INT_2_10_10_10_REV or UNSIGNED_INT_2_10_10_10_REV and size is not 4."; +MSG kInvalidVertexAttribSize1010102 = "Type is INT_10_10_10_2_OES or UNSIGNED_INT_10_10_10_2_OES and size is not 3 or 4."; +MSG kInvalidVertexAttrSize = "Vertex attribute size must be 1, 2, 3, or 4."; +MSG kInvalidVertexPointerSize = "Size for built-in vertex attribute is outside allowed range."; +MSG kInvalidVertexPointerStride = "Invalid stride for built-in vertex attribute."; +MSG kInvalidVertexPointerType = "Invalid type for built-in vertex attribute."; +MSG kInvalidWidth = "Invalid width."; +MSG kInvalidWrapModeTexture = "Invalid wrap mode for texture type."; +MSG kInvalidZOffset = "zoffset is larger than MAX_3D_TEXTURE_SIZE-1"; +MSG kLengthZero = "Length must not be zero."; +MSG kLevelNotZero = "Texture level must be zero."; +MSG kLightParameterOutOfRange = "Light parameter out of range."; +MSG kMapOutOfRange = "Mapped range does not fit into buffer dimensions."; +MSG kMaterialParameterOutOfRange = "Material parameter out of range."; +MSG kMatrixStackOverflow = "Current matrix stack is full."; +MSG kMatrixStackUnderflow = "Current matrix stack has only a single matrix."; +MSG kMaxActiveVariablesInterface = "MAX_NUM_ACTIVE_VARIABLES requires a buffer or block interface."; +MSG kMismatchedFormat = "Format must match internal format."; +MSG kMismatchedTargetAndFormat = "Invalid texture target and format combination."; +MSG kMismatchedTypeAndFormat = "Invalid format and type combination."; +MSG kMismatchedVariableProgram = "Variable is not part of the current program."; +MSG kMissingName = "No name given."; +MSG kMissingReadAttachment = "Missing read attachment."; +MSG kMissingTexture = "No Texture is bound to the specified target."; +MSG kMissingTextureName = "texture is not the name of an existing texture object."; +MSG kMultisampleArrayExtensionRequired = "GL_ANGLE_texture_multisample_array not enabled."; +MSG kMultisampleTextureExtensionOrES31Required = "GL_ANGLE_texture_multisample or GLES 3.1 required."; +MSG kMultisampleTextureExtensionOrGetTexLevelParameterExtensionOrES31Required = "GL_ANGLE_texture_multisample, GL_ANGLE_get_tex_level_parameter or GLES 3.1 required."; +MSG kMultiviewActive = "The number of views in the active draw framebuffer is greater than 1."; +MSG kMultiviewMismatch = "The number of views in the active program and draw framebuffer does not match."; +MSG kMultiviewNotAvailable = "ANGLE_multiview is not available."; +MSG kMultiviewReadFramebuffer = "The active read framebuffer object has multiview attachments."; +MSG kMultiviewTimerQuery = "There is an active query for target GL_TIME_ELAPSED_EXT when the number of views in the active draw framebuffer is greater than 1."; +MSG kMultiviewTransformFeedback = "There is an active transform feedback object when the number of views in the active draw framebuffer is greater than 1."; +MSG kMultiviewViewsTooLarge = "numViews cannot be greater than GL_MAX_VIEWS_ANGLE."; +MSG kMultiviewViewsTooSmall = "numViews cannot be less than 1."; +MSG kMustHaveElementArrayBinding = "Must have element array buffer bound."; +MSG kNameBeginsWithGL = "Attributes that begin with 'gl_' are not allowed."; +MSG kNegativeAttachments = "Negative number of attachments."; +MSG kNegativeBaseViewIndex = "Negative baseViewIndex."; +MSG kNegativeBufferSize = "Negative buffer size."; +MSG kNegativeBufSize = "Invalid bufSize."; +MSG kNegativeCount = "Negative count."; +MSG kNegativeHeightWidthDepth = "Cannot have negative height, width, or depth."; +MSG kNegativeLayer = "Negative layer."; +MSG kNegativeLength = "Negative length."; +MSG kNegativeLevel = "Level is negative."; +MSG kNegativeLocation = "Location cannot be less than 0."; +MSG kNegativeMaxCount = "Negative maxcount."; +MSG kNegativeOffset = "Negative offset."; +MSG kNegativeParam = "param is negative."; +MSG kNegativePrimcount = "Primcount must be greater than or equal to zero."; +MSG kNegativeSize = "Negative size."; +MSG kNegativeStart = "Cannot have negative start."; +MSG kNegativeStride = "Cannot have negative stride."; +MSG kNegativeXYZ = "x = y = or z cannot be negative."; +MSG kNoActiveComputeShaderStage = "No active compute shader stage in this program."; +MSG kNoActiveGeometryShaderStage = "No active geometry shader stage in this program."; +MSG kNoActiveGraphicsShaderStage = "It is a undefined behaviour to render without vertex shader stage or fragment shader stage."; +MSG kNoActiveProgramWithComputeShader = "No active program for the compute shader stage."; +MSG kNoDefinedClearConversion = "No defined conversion between clear value and attachment format."; +MSG kNonPositiveDrawTextureDimension = "Both width and height argument of drawn texture must be positive."; +MSG kNonPositiveSize = "Size must be greater than 0"; +MSG kNoProgramBinaryFormats = "No program binary formats supported."; +MSG kNoReadFramebuffer = "No active read framebuffer."; +MSG kNoSampleAlphaToCoveragesLimitation = "Current renderer doesn't support alpha-to-coverage."; +MSG kNotTextureComplete = "The texture is not complete."; +MSG kNoTransformArray = "No transform array given."; +MSG kNoTransformFeedbackOutputVariables = "The active program has specified no output variables to record."; +MSG kNoZeroDivisor = "At least one enabled attribute must have a divisor of zero."; +MSG kNVFenceNotSupported = "GL_NV_fence is not supported"; +MSG kObjectNotGenerated = "Object cannot be used because it has not been generated."; +MSG kOffsetAlignment = "offset must be a multiple of 4."; +MSG kOffsetAndSizeAlignment = "Offset and size must be multiple of 4."; +MSG kOffsetMustBeMultipleOfType = "Offset must be a multiple of the passed in datatype."; +MSG kOffsetMustBeMultipleOfUint = "Offset must be a multiple of sizeof(uint) in basic machine units."; +MSG kOffsetOverflow = "Offset overflows texture dimensions."; +MSG kOtherQueryActive = "Other query is active."; +MSG kOutsideOfBounds = "Parameter outside of bounds."; +MSG kParamOverflow = "The provided parameters overflow with the provided buffer."; +MSG kPixelDataNotNull = "Pixel data must be null."; +MSG kPixelDataNull = "Pixel data cannot be null."; +MSG kPixelPackBufferBoundForTransformFeedback = "It is undefined behavior to use a pixel pack buffer that is bound for transform feedback."; +MSG kPixelUnpackBufferBoundForTransformFeedback = "It is undefined behavior to use a pixel unpack buffer that is bound for transform feedback."; +MSG kPLSActive = "Operation not permitted while pixel local storage is active."; +MSG kPLSDefaultFramebufferBound = "Default framebuffer object name 0 does not support pixel local storage."; +MSG kPLSDitherEnabled = "Attempted to begin pixel local storage with GL_DITHER enabled."; +MSG kPLSDimensionsDontMatchRenderingArea = "Pixel local storage backing texture dimensions not equal to the rendering area."; +MSG kPLSEnablingDeinitializedPlane = "Attempted to enable a pixel local storage plane that is in a deinitialized state."; +MSG kPLSExtensionNotEnabled = "GL_ANGLE_shader_pixel_local_storage not enabled."; +MSG kPLSInactive = "Pixel local storage is not active."; +MSG kPLSInvalidInternalformat = "Invalid pixel local storage internal format."; +MSG kPLSInvalidLoadOperation = "Invalid pixel local storage Load Operation."; +MSG kPLSInvalidTextureType = "Invalid pixel local storage texture type."; +MSG kPLSKeepingMemorylessPlane = "Load Operation GL_KEEP is invalid for memoryless planes."; +MSG kPLSMaxColorAttachmentsExceded = "Framebuffer cannot have images attached to color attachment points on or after COLOR_ATTACHMENT0 + MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE_ANGLE."; +MSG kPLSMaxCombinedDrawBuffersAndPlanesExceded = "Framebuffer cannot have images attached to color attachment points on or after COLOR_ATTACHMENT0 + MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES_ANGLE - ."; +MSG kPLSMismatchedBackingTextureSizes = "Mismatched pixel local storage backing texture sizes."; +MSG kPLSMultisamplingEnabled = "Attempted to begin pixel local storage with a multisampled framebuffer."; +MSG kPLSNoAttachmentsNoTextureBacked = "Draw framebuffer has no attachments and no enabled, texture-backed pixel local storage planes."; +MSG kPLSNullClearData = "cleardata cannot null if Load Operation GL_CLEAR_ANGLE is specified."; +MSG kPLSNullLoadOps = "loadops cannot null."; +MSG kPLSPlaneLessThanZero = "Plane cannot be less than 0."; +MSG kPLSPlaneOutOfRange = "Plane must be less than GL_MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE."; +MSG kPLSPlanesLessThanOne = "Planes must be greater than 0."; +MSG kPLSPlanesOutOfRange = "Planes must be less than or equal to GL_MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE."; +MSG kPLSRasterizerDiscardEnabled = "Attempted to begin pixel local storage with GL_RASTERIZER_DISCARD enabled."; +MSG kPLSReservedDrawBufferInUse = "When beginning pixel local storage, glDrawBuffers must all be GL_NONE at indices greater than or equal to: min(GL_MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PLS_ANGLE, GL_MAX_COMBINED_DRAW_BUFFERS_AND_PLS_PLANES_ANGLE - )."; +MSG kPLSSampleAlphaToCoverageEnabled = "Attempted to begin pixel local storage with GL_SAMPLE_ALPHA_TO_COVERAGE enabled."; +MSG kPLSSampleCoverageEnabled = "Attempted to begin pixel local storage with GL_SAMPLE_COVERAGE enabled."; +MSG kPointSizeArrayExtensionNotEnabled = "GL_OES_point_size_array not enabled."; +MSG kProgramDoesNotExist = "Program doesn't exist."; +MSG kProgramInterfaceMustBeProgramOutput = "programInterface must be set to GL_PROGRAM_OUTPUT."; +MSG kProgramNotBound = "A program must be bound."; +MSG kProgramNotLinked = "Program not linked."; +MSG kQueryActive = "Query is active."; +MSG kQueryExtensionNotEnabled = "Query extension not enabled."; +MSG kQueryInactive = "Query is not active."; +MSG kQueryTargetMismatch = "Query type does not match target."; +MSG kReadBufferNone = "Read buffer is GL_NONE."; +MSG kReadBufferNotAttached = "Read buffer has no attachment."; +MSG kRectangleTextureCompressed = "Rectangle texture cannot have a compressed format."; +MSG kRelativeOffsetTooLarge = "relativeOffset cannot be greater than MAX_VERTEX_ATTRIB_RELATIVE_OFFSET."; +MSG kRenderableInternalFormat = "SizedInternalformat must be color-renderable, depth-renderable, or stencil-renderable."; +MSG kRenderbufferNotBound = "A renderbuffer must be bound."; +MSG kResourceMaxRenderbufferSize = "Desired resource size is greater than max renderbuffer size."; +MSG kResourceMaxTextureSize = "Desired resource size is greater than max texture size."; +MSG kRobustResourceInitializationExtensionRequired = "EGL_ANGLE_robust_resource_initialization not enabled."; +MSG kSamplerFormatMismatch = "Mismatch between texture format and sampler type (signed/unsigned/float/shadow)."; +MSG kSamplerUniformValueOutOfRange = "Sampler uniform value out of range."; +MSG kSamplesOutOfRange = "Samples must not be greater than maximum supported value for the format."; +MSG kSamplesZero = "Samples may not be zero."; +MSG kShaderAttachmentHasShader = "Shader attachment already has a shader."; +MSG kShaderSourceInvalidCharacters = "Shader source contains invalid characters."; +MSG kShaderStorageBufferOffsetAlignment = "Offset must be multiple of value of SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT."; +MSG kShaderToDetachMustBeAttached = "Shader to be detached must be currently attached to the program."; +MSG kShadingRateExtensionNotAvailable = "GL_QCOM_shading_rate extension not available."; +MSG kSourceLevelNotDefined = "The source level of the source texture must be defined."; +MSG kSourceTextureLevelZeroDefined = "Source texture must level 0 defined."; +MSG kSourceTextureMustBeCompressed = "Source texture must have a compressed internal format."; +MSG kSourceTextureTooSmall = "The specified dimensions are outside of the bounds of the texture."; +MSG kStencilReferenceMaskOrMismatch = "Stencil reference and mask values must be the same for front facing and back facing triangles."; +MSG kStrideExceedsWebGLLimit = "Stride is over the maximum stride allowed by WebGL."; +MSG kStrideMustBeMultipleOfType = "Stride must be a multiple of the passed in datatype."; +MSG kSyncMissing = "Sync object does not exist."; +MSG kTargetMustBeTexture2DMultisampleArrayOES = "Target must be TEXTURE_2D_MULTISAMPLE_ARRAY_OES."; +MSG kTessellationShaderExtensionNotEnabled = "GL_EXT_tessellation_shader extension not enabled."; +MSG kTessellationShaderRequiresBothControlAndEvaluation = "Tessellation requires both control and evaluation shaders."; +MSG kTessellationShaderRequiresVertexShader = "Any command that transfers vertices to the GL requires a vertex shader if the current program uses a tessellation shader."; +MSG kTextureBufferExtensionNotAvailable = "Texture buffer extension not available."; +MSG kTextureBufferOffsetAlignment = "Offset must be multiple of value of TEXTURE_BUFFER_OFFSET_ALIGNMENT."; +MSG kTextureBufferSize = "Texture buffer size must be a positive integer."; +MSG kTextureBufferSizeOffset = "Texture buffer offset + size must be less than or equal to BUFFER_SIZE."; +MSG kTextureBufferTarget = "Target must be TEXTURE_BUFFER."; +MSG kTextureBufferInternalFormat = "Internal format is not an accepted sized internal format."; +MSG kTextureBufferInvalidBuffer = "If buffer is nonzero, it must match the name of an existing buffer object."; +MSG kTextureFormatMismatch = "Passed in texture target and format must match the one originally used to define the texture."; +MSG kTextureIsImmutable = "Texture is immutable."; +MSG kTextureIsNotImmutable = "Texture is not immutable."; +MSG kTextureIsNeitherImmutableNorTextureBuffer = "Texture is not the name of an immutable texture object or a buffer texture."; +MSG kTextureLayerOutOfRange = "Layer is larger than texture depth."; +MSG kTextureLevelOutOfRange = "Level is larger than texture level count."; +MSG kTextureNotBound = "A texture must be bound."; +MSG kTextureNotPow2 = "The texture is a non-power-of-two texture."; +MSG kTextureRectangleNotSupported = "Context does not support GL_ANGLE_texture_rectangle"; +MSG kTextureSizeTooSmall = "Texture dimensions must all be greater than zero."; +MSG kTextureTargetMismatch = "Textarget must match the texture target type."; +MSG kTextureTargetMismatchWithLabel = "Textarget must match the texture target type. Requested: %d Texture's: %d label: %s"; +MSG kTextureTargetRequiresES31 = "Texture target requires at least OpenGL ES 3.1."; +MSG kTextureTypeConflict = "Two textures of different types use the same sampler location."; +MSG kTextureTypeMismatch = "Passed in texture type must match the one originally used to define the texture."; +MSG kTextureWidthOrHeightOutOfRange = "Width and height must be less than or equal to GL_MAX_TEXTURE_SIZE."; +MSG kTextureDepthOutOfRange = "Depth must be less than or equal to MAX_ARRAY_TEXTURE_LAYERS"; +MSG kTransfomFeedbackAlreadyActive = "Transform feedback is already active."; +MSG kTransformFeedbackActiveDelete = "Attempt to delete an active transform feedback."; +MSG kTransformFeedbackActiveDuringLink = "Cannot link program while program is associated with an active transform feedback object."; +MSG kTransformFeedbackBufferDoubleBound = "A transform feedback buffer that would be written to is also bound to a non-transform-feedback target, which would cause undefined behavior."; +MSG kTransformFeedbackBufferMissing = "Every binding point used in transform feedback mode must have a buffer object bound."; +MSG kTransformFeedbackBufferMultipleOutputs = "Transform feedback has a buffer bound to multiple outputs."; +MSG kTransformFeedbackBufferTooSmall = "Not enough space in bound transform feedback buffers."; +MSG kTransformFeedbackDoesNotExist = "Transform feedback object that does not exist."; +MSG kTransformFeedbackNotActive = "No Transform Feedback object is active."; +MSG kTransformFeedbackNotPaused = "The active Transform Feedback object is not paused."; +MSG kTransformFeedbackPaused = "The active Transform Feedback object is paused."; +MSG kTransformFeedbackProgramBinary = "Cannot change program binary while program is associated with an active transform feedback object."; +MSG kTransformFeedbackTargetActive = "Target is TRANSFORM_FEEDBACK_BUFFER and transform feedback is currently active."; +MSG kTransformFeedbackUseProgram = "Cannot change active program while transform feedback is unpaused."; +MSG kTransformFeedbackVaryingIndexOutOfRange = "Index must be less than the transform feedback varying count in the program."; +MSG kTypeNotUnsignedShortByte = "Only UNSIGNED_SHORT and UNSIGNED_BYTE types are supported."; +MSG kUniformBufferBoundForTransformFeedback = "It is undefined behavior to use an uniform buffer that is bound for transform feedback."; +MSG kUniformBufferOffsetAlignment = "Offset must be multiple of value of UNIFORM_BUFFER_OFFSET_ALIGNMENT."; +MSG kUniformBufferTooSmall = "It is undefined behaviour to use a uniform buffer that is too small."; +MSG kUniformBufferUnbound = "It is undefined behaviour to have a used but unbound uniform buffer."; +MSG kUniformSizeMismatch = "Uniform size does not match uniform method."; +MSG kUniformTypeMismatch = "Uniform type does not match uniform method."; +MSG kUnimplementedComputeShaderPrecision = "Compute shader precision not yet implemented."; +MSG kUnknownParameter = "Unknown parameter value."; +MSG kUnsizedInternalFormatUnsupported = "Internalformat is one of the unsupported unsized base internalformats."; +MSG kUnsupportedDrawModeForTransformFeedback = "The draw command is unsupported when transform feedback is active and not paused."; +MSG kUnsupportedFloatBlending = "GL_BLEND with floating-point color attachments requires the EXT_float_blend extension."; +MSG kVertexArrayNoBuffer = "An enabled vertex array has no buffer."; +MSG kVertexArrayNoBufferPointer = "An enabled vertex array has no buffer and no pointer."; +MSG kVertexBufferBoundForTransformFeedback = "It is undefined behavior to use a vertex buffer that is bound for transform feedback."; +MSG kVertexShaderTypeMismatch = "Vertex shader input type does not match the type of the bound vertex attribute."; +MSG kViewportNegativeSize = "Viewport size cannot be negative."; +MSG kViewsExceedMaxArrayLayers = "baseViewIndex+numViews cannot be greater than GL_MAX_ARRAY_TEXTURE_LAYERS."; +MSG kWebgl2NameLengthLimitExceeded = "Location lengths must not be greater than 1024 characters."; +MSG kWebglBindAttribLocationReservedPrefix = "Attributes that begin with 'webgl_', or '_webgl_' are not allowed."; +MSG kWebglNameLengthLimitExceeded = "Location name lengths must not be greater than 256 characters."; +MSG kYUVOutputMissmatch = "Program and framebuffer YUV output state does not match."; +MSG kYUVTargetExtensionRequired = "GL_EXT_YUV_target not enabled."; +MSG kZeroBoundToTarget = "Zero is bound to target."; +MSG kUnrecognizedShaderStageBit = "Unrecognized shader stage bit."; +MSG kProgramNotSeparable = "Program object was not linked with its PROGRAM_SEPARABLE status set."; +MSG kProgramPipelineDoesNotExist = "Program pipeline does not exist."; +MSG kNotAllStagesOfSeparableProgramUsed = "A program object is active for at least one, but not all of the shader stages that were present when the program was linked."; +MSG kNoExecutableCodeInstalled = "There is no current program object specified by UseProgram, there is a current program pipeline object, and that object is empty (no executable code is installed for any stage)."; +MSG kProgramPipelineLinkFailed = "Program pipeline link failed"; +MSG kProtectedTexturesExtensionRequired = "GL_EXT_protected_textures not enabled."; + +// clang-format on + +#undef MSG +} // namespace err +} // namespace gl +#endif // LIBANGLE_ERRORSTRINGS_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Fence.cpp b/gfx/angle/checkout/src/libANGLE/Fence.cpp new file mode 100644 index 0000000000..af173dff29 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Fence.cpp @@ -0,0 +1,124 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Fence.cpp: Implements the gl::FenceNV and gl::Sync classes. + +#include "libANGLE/Fence.h" + +#include "angle_gl.h" + +#include "common/utilities.h" +#include "libANGLE/renderer/FenceNVImpl.h" +#include "libANGLE/renderer/GLImplFactory.h" +#include "libANGLE/renderer/SyncImpl.h" + +namespace gl +{ + +FenceNV::FenceNV(rx::GLImplFactory *factory) + : mFence(factory->createFenceNV()), mIsSet(false), mStatus(GL_FALSE), mCondition(GL_NONE) +{} + +FenceNV::~FenceNV() +{ + SafeDelete(mFence); +} + +void FenceNV::onDestroy(const gl::Context *context) +{ + mFence->onDestroy(context); +} + +angle::Result FenceNV::set(const Context *context, GLenum condition) +{ + ANGLE_TRY(mFence->set(context, condition)); + + mCondition = condition; + mStatus = GL_FALSE; + mIsSet = true; + + return angle::Result::Continue; +} + +angle::Result FenceNV::test(const Context *context, GLboolean *outResult) +{ + // Flush the command buffer by default + ANGLE_TRY(mFence->test(context, &mStatus)); + + *outResult = mStatus; + return angle::Result::Continue; +} + +angle::Result FenceNV::finish(const Context *context) +{ + ASSERT(mIsSet); + + ANGLE_TRY(mFence->finish(context)); + + mStatus = GL_TRUE; + + return angle::Result::Continue; +} + +Sync::Sync(rx::GLImplFactory *factory, GLuint id) + : RefCountObject(factory->generateSerial(), id), + mFence(factory->createSync()), + mLabel(), + mCondition(GL_SYNC_GPU_COMMANDS_COMPLETE), + mFlags(0) +{} + +void Sync::onDestroy(const Context *context) +{ + ASSERT(mFence); + mFence->onDestroy(context); +} + +Sync::~Sync() +{ + SafeDelete(mFence); +} + +angle::Result Sync::setLabel(const Context *context, const std::string &label) +{ + mLabel = label; + return angle::Result::Continue; +} + +const std::string &Sync::getLabel() const +{ + return mLabel; +} + +angle::Result Sync::set(const Context *context, GLenum condition, GLbitfield flags) +{ + ANGLE_TRY(mFence->set(context, condition, flags)); + + mCondition = condition; + mFlags = flags; + return angle::Result::Continue; +} + +angle::Result Sync::clientWait(const Context *context, + GLbitfield flags, + GLuint64 timeout, + GLenum *outResult) +{ + ASSERT(mCondition != GL_NONE); + return mFence->clientWait(context, flags, timeout, outResult); +} + +angle::Result Sync::serverWait(const Context *context, GLbitfield flags, GLuint64 timeout) +{ + return mFence->serverWait(context, flags, timeout); +} + +angle::Result Sync::getStatus(const Context *context, GLint *outResult) const +{ + return mFence->getStatus(context, outResult); +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/Fence.h b/gfx/angle/checkout/src/libANGLE/Fence.h new file mode 100644 index 0000000000..2852b328fd --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Fence.h @@ -0,0 +1,88 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Fence.h: Defines the gl::FenceNV and gl::Sync classes, which support the GL_NV_fence +// extension and GLES3 sync objects. + +#ifndef LIBANGLE_FENCE_H_ +#define LIBANGLE_FENCE_H_ + +#include "libANGLE/Debug.h" +#include "libANGLE/Error.h" +#include "libANGLE/RefCountObject.h" + +#include "common/angleutils.h" + +namespace rx +{ +class GLImplFactory; +class FenceNVImpl; +class SyncImpl; +} // namespace rx + +namespace gl +{ + +class FenceNV final : angle::NonCopyable +{ + public: + explicit FenceNV(rx::GLImplFactory *factory); + virtual ~FenceNV(); + + void onDestroy(const gl::Context *context); + angle::Result set(const Context *context, GLenum condition); + angle::Result test(const Context *context, GLboolean *outResult); + angle::Result finish(const Context *context); + + bool isSet() const { return mIsSet; } + GLboolean getStatus() const { return mStatus; } + GLenum getCondition() const { return mCondition; } + + private: + rx::FenceNVImpl *mFence; + + bool mIsSet; + + GLboolean mStatus; + GLenum mCondition; +}; + +class Sync final : public RefCountObject, public LabeledObject +{ + public: + Sync(rx::GLImplFactory *factory, GLuint id); + ~Sync() override; + + void onDestroy(const Context *context) override; + + angle::Result setLabel(const Context *context, const std::string &label) override; + const std::string &getLabel() const override; + + angle::Result set(const Context *context, GLenum condition, GLbitfield flags); + angle::Result clientWait(const Context *context, + GLbitfield flags, + GLuint64 timeout, + GLenum *outResult); + angle::Result serverWait(const Context *context, GLbitfield flags, GLuint64 timeout); + angle::Result getStatus(const Context *context, GLint *outResult) const; + + GLenum getCondition() const { return mCondition; } + GLbitfield getFlags() const { return mFlags; } + + rx::SyncImpl *getImplementation() const { return mFence; } + + private: + rx::SyncImpl *mFence; + + std::string mLabel; + + GLenum mCondition; + GLbitfield mFlags; +}; + +} // namespace gl + +#endif // LIBANGLE_FENCE_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Framebuffer.cpp b/gfx/angle/checkout/src/libANGLE/Framebuffer.cpp new file mode 100644 index 0000000000..08250b0b2d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Framebuffer.cpp @@ -0,0 +1,2727 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Framebuffer.cpp: Implements the gl::Framebuffer class. Implements GL framebuffer +// objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105. + +#include "libANGLE/Framebuffer.h" + +#include "common/Optional.h" +#include "common/bitset_utils.h" +#include "common/utilities.h" +#include "libANGLE/Config.h" +#include "libANGLE/Context.h" +#include "libANGLE/Display.h" +#include "libANGLE/ErrorStrings.h" +#include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/PixelLocalStorage.h" +#include "libANGLE/Renderbuffer.h" +#include "libANGLE/Surface.h" +#include "libANGLE/Texture.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/ContextImpl.h" +#include "libANGLE/renderer/FramebufferImpl.h" +#include "libANGLE/renderer/GLImplFactory.h" +#include "libANGLE/renderer/RenderbufferImpl.h" +#include "libANGLE/renderer/SurfaceImpl.h" + +using namespace angle; + +namespace gl +{ + +namespace +{ + +// Check the |checkAttachment| in reference to |firstAttachment| for the sake of multiview +// framebuffer completeness. +FramebufferStatus CheckMultiviewStateMatchesForCompleteness( + const FramebufferAttachment *firstAttachment, + const FramebufferAttachment *checkAttachment) +{ + ASSERT(firstAttachment && checkAttachment); + ASSERT(firstAttachment->isAttached() && checkAttachment->isAttached()); + + if (firstAttachment->isMultiview() != checkAttachment->isMultiview()) + { + return FramebufferStatus::Incomplete(GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR, + err::kFramebufferIncompleteMultiviewMismatch); + } + if (firstAttachment->getNumViews() != checkAttachment->getNumViews()) + { + return FramebufferStatus::Incomplete(GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR, + err::kFramebufferIncompleteMultiviewViewsMismatch); + } + if (checkAttachment->getBaseViewIndex() + checkAttachment->getNumViews() > + checkAttachment->getSize().depth) + { + return FramebufferStatus::Incomplete(GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR, + err::kFramebufferIncompleteMultiviewBaseViewMismatch); + } + + return FramebufferStatus::Complete(); +} + +FramebufferStatus CheckAttachmentCompleteness(const Context *context, + const FramebufferAttachment &attachment) +{ + ASSERT(attachment.isAttached()); + + const Extents &size = attachment.getSize(); + if (size.width == 0 || size.height == 0) + { + return FramebufferStatus::Incomplete(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, + err::kFramebufferIncompleteAttachmentZeroSize); + } + + if (!attachment.isRenderable(context)) + { + return FramebufferStatus::Incomplete(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, + err::kFramebufferIncompleteAttachmentNotRenderable); + } + + if (attachment.type() == GL_TEXTURE) + { + // [EXT_geometry_shader] Section 9.4.1, "Framebuffer Completeness" + // If is a three-dimensional texture or a two-dimensional array texture and the + // attachment is not layered, the selected layer is less than the depth or layer count, + // respectively, of the texture. + if (!attachment.isLayered()) + { + if (attachment.layer() >= size.depth) + { + return FramebufferStatus::Incomplete( + GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, + err::kFramebufferIncompleteAttachmentLayerGreaterThanDepth); + } + } + // If is a three-dimensional texture or a two-dimensional array texture and the + // attachment is layered, the depth or layer count, respectively, of the texture is less + // than or equal to the value of MAX_FRAMEBUFFER_LAYERS_EXT. + else + { + if (size.depth >= context->getCaps().maxFramebufferLayers) + { + return FramebufferStatus::Incomplete( + GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, + err::kFramebufferIncompleteAttachmentDepthGreaterThanMaxLayers); + } + } + + // ES3 specifies that cube map texture attachments must be cube complete. + // This language is missing from the ES2 spec, but we enforce it here because some + // desktop OpenGL drivers also enforce this validation. + // TODO(jmadill): Check if OpenGL ES2 drivers enforce cube completeness. + const Texture *texture = attachment.getTexture(); + ASSERT(texture); + if (texture->getType() == TextureType::CubeMap && + !texture->getTextureState().isCubeComplete()) + { + return FramebufferStatus::Incomplete( + GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, + err::kFramebufferIncompleteAttachmentNotCubeComplete); + } + + if (!texture->getImmutableFormat()) + { + GLuint attachmentMipLevel = static_cast(attachment.mipLevel()); + + // From the ES 3.0 spec, pg 213: + // If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is TEXTURE and the value of + // FRAMEBUFFER_ATTACHMENT_OBJECT_NAME does not name an immutable-format texture, + // then the value of FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL must be in the + // range[levelbase, q], where levelbase is the value of TEXTURE_BASE_LEVEL and q is + // the effective maximum texture level defined in the Mipmapping discussion of + // section 3.8.10.4. + if (attachmentMipLevel < texture->getBaseLevel() || + attachmentMipLevel > texture->getMipmapMaxLevel()) + { + return FramebufferStatus::Incomplete( + GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, + err::kFramebufferIncompleteAttachmentLevelOutOfBaseMaxLevelRange); + } + + // Form the ES 3.0 spec, pg 213/214: + // If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is TEXTURE and the value of + // FRAMEBUFFER_ATTACHMENT_OBJECT_NAME does not name an immutable-format texture and + // the value of FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL is not levelbase, then the + // texture must be mipmap complete, and if FRAMEBUFFER_ATTACHMENT_OBJECT_NAME names + // a cubemap texture, the texture must also be cube complete. + if (attachmentMipLevel != texture->getBaseLevel() && !texture->isMipmapComplete()) + { + return FramebufferStatus::Incomplete( + GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, + err::kFramebufferIncompleteAttachmentLevelNotBaseLevelForIncompleteMipTexture); + } + } + } + + return FramebufferStatus::Complete(); +} + +FramebufferStatus CheckAttachmentSampleCounts(const Context *context, + GLsizei currAttachmentSamples, + GLsizei samples, + bool colorAttachment) +{ + if (currAttachmentSamples != samples) + { + if (colorAttachment) + { + // APPLE_framebuffer_multisample, which EXT_draw_buffers refers to, requires that + // all color attachments have the same number of samples for the FBO to be complete. + return FramebufferStatus::Incomplete( + GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE, + err::kFramebufferIncompleteMultisampleInconsistentSampleCounts); + } + else + { + // CHROMIUM_framebuffer_mixed_samples allows a framebuffer to be considered complete + // when its depth or stencil samples are a multiple of the number of color samples. + if (!context->getExtensions().framebufferMixedSamplesCHROMIUM) + { + return FramebufferStatus::Incomplete( + GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE, + err::kFramebufferIncompleteMultisampleInconsistentSampleCounts); + } + + if ((currAttachmentSamples % std::max(samples, 1)) != 0) + { + return FramebufferStatus::Incomplete( + GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE, + err:: + kFramebufferIncompleteMultisampleDepthStencilSampleCountDivisibleByColorSampleCount); + } + } + } + + return FramebufferStatus::Complete(); +} + +FramebufferStatus CheckAttachmentSampleCompleteness(const Context *context, + const FramebufferAttachment &attachment, + bool colorAttachment, + Optional *samples, + Optional *fixedSampleLocations, + Optional *renderToTextureSamples) +{ + ASSERT(attachment.isAttached()); + + if (attachment.type() == GL_TEXTURE) + { + const Texture *texture = attachment.getTexture(); + ASSERT(texture); + GLenum sizedInternalFormat = attachment.getFormat().info->sizedInternalFormat; + const TextureCaps &formatCaps = context->getTextureCaps().get(sizedInternalFormat); + if (static_cast(attachment.getSamples()) > formatCaps.getMaxSamples()) + { + return FramebufferStatus::Incomplete( + GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE, + err::kFramebufferIncompleteAttachmentSamplesGreaterThanMaxSupportedSamples); + } + + const ImageIndex &attachmentImageIndex = attachment.getTextureImageIndex(); + bool fixedSampleloc = texture->getAttachmentFixedSampleLocations(attachmentImageIndex); + if (fixedSampleLocations->valid() && fixedSampleloc != fixedSampleLocations->value()) + { + return FramebufferStatus::Incomplete( + GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE, + err::kFramebufferIncompleteMultisampleInconsistentFixedSampleLocations); + } + else + { + *fixedSampleLocations = fixedSampleloc; + } + } + + if (renderToTextureSamples->valid()) + { + // Only check against RenderToTextureSamples if they actually exist. + if (renderToTextureSamples->value() != + FramebufferAttachment::kDefaultRenderToTextureSamples) + { + FramebufferStatus sampleCountStatus = + CheckAttachmentSampleCounts(context, attachment.getRenderToTextureSamples(), + renderToTextureSamples->value(), colorAttachment); + if (!sampleCountStatus.isComplete()) + { + return sampleCountStatus; + } + } + } + else + { + *renderToTextureSamples = attachment.getRenderToTextureSamples(); + } + + if (samples->valid()) + { + // RenderToTextureSamples takes precedence if they exist. + if (renderToTextureSamples->value() == + FramebufferAttachment::kDefaultRenderToTextureSamples) + { + + FramebufferStatus sampleCountStatus = CheckAttachmentSampleCounts( + context, attachment.getSamples(), samples->value(), colorAttachment); + if (!sampleCountStatus.isComplete()) + { + return sampleCountStatus; + } + } + } + else + { + *samples = attachment.getSamples(); + } + + return FramebufferStatus::Complete(); +} + +// Needed to index into the attachment arrays/bitsets. +static_assert(static_cast(IMPLEMENTATION_MAX_DRAW_BUFFERS) == + Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX, + "Framebuffer Dirty bit mismatch"); +static_assert(static_cast(IMPLEMENTATION_MAX_DRAW_BUFFERS) == + Framebuffer::DIRTY_BIT_DEPTH_ATTACHMENT, + "Framebuffer Dirty bit mismatch"); +static_assert(static_cast(IMPLEMENTATION_MAX_DRAW_BUFFERS + 1) == + Framebuffer::DIRTY_BIT_STENCIL_ATTACHMENT, + "Framebuffer Dirty bit mismatch"); + +angle::Result InitAttachment(const Context *context, FramebufferAttachment *attachment) +{ + ASSERT(attachment->isAttached()); + if (attachment->initState() == InitState::MayNeedInit) + { + ANGLE_TRY(attachment->initializeContents(context)); + } + return angle::Result::Continue; +} + +bool AttachmentOverlapsWithTexture(const FramebufferAttachment &attachment, + const Texture *texture, + const Sampler *sampler) +{ + if (!attachment.isTextureWithId(texture->id())) + { + return false; + } + + const gl::ImageIndex &index = attachment.getTextureImageIndex(); + GLuint attachmentLevel = static_cast(index.getLevelIndex()); + GLuint textureEffectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel(); + GLuint textureMaxLevel = textureEffectiveBaseLevel; + if ((sampler && IsMipmapFiltered(sampler->getSamplerState().getMinFilter())) || + IsMipmapFiltered(texture->getSamplerState().getMinFilter())) + { + textureMaxLevel = texture->getMipmapMaxLevel(); + } + + return attachmentLevel >= textureEffectiveBaseLevel && attachmentLevel <= textureMaxLevel; +} + +} // anonymous namespace + +bool FramebufferStatus::isComplete() const +{ + return status == GL_FRAMEBUFFER_COMPLETE; +} + +FramebufferStatus FramebufferStatus::Complete() +{ + FramebufferStatus result; + result.status = GL_FRAMEBUFFER_COMPLETE; + result.reason = nullptr; + return result; +} + +FramebufferStatus FramebufferStatus::Incomplete(GLenum status, const char *reason) +{ + ASSERT(status != GL_FRAMEBUFFER_COMPLETE); + + FramebufferStatus result; + result.status = status; + result.reason = reason; + return result; +} + +// This constructor is only used for default framebuffers. +FramebufferState::FramebufferState(rx::Serial serial) + : mId(Framebuffer::kDefaultDrawFramebufferHandle), + mFramebufferSerial(serial), + mLabel(), + mColorAttachments(1), + mColorAttachmentsMask(0), + mDrawBufferStates(1, GL_BACK), + mReadBufferState(GL_BACK), + mDrawBufferTypeMask(), + mDefaultWidth(0), + mDefaultHeight(0), + mDefaultSamples(0), + mDefaultFixedSampleLocations(GL_FALSE), + mDefaultLayers(0), + mFlipY(GL_FALSE), + mWebGLDepthStencilConsistent(true), + mDefaultFramebufferReadAttachmentInitialized(false), + mSrgbWriteControlMode(SrgbWriteControlMode::Default) +{ + ASSERT(mDrawBufferStates.size() > 0); + mEnabledDrawBuffers.set(0); +} + +FramebufferState::FramebufferState(const Caps &caps, FramebufferID id, rx::Serial serial) + : mId(id), + mFramebufferSerial(serial), + mLabel(), + mColorAttachments(caps.maxColorAttachments), + mColorAttachmentsMask(0), + mDrawBufferStates(caps.maxDrawBuffers, GL_NONE), + mReadBufferState(GL_COLOR_ATTACHMENT0_EXT), + mDrawBufferTypeMask(), + mDefaultWidth(0), + mDefaultHeight(0), + mDefaultSamples(0), + mDefaultFixedSampleLocations(GL_FALSE), + mDefaultLayers(0), + mFlipY(GL_FALSE), + mWebGLDepthStencilConsistent(true), + mDefaultFramebufferReadAttachmentInitialized(false), + mSrgbWriteControlMode(SrgbWriteControlMode::Default) +{ + ASSERT(mId != Framebuffer::kDefaultDrawFramebufferHandle); + ASSERT(mDrawBufferStates.size() > 0); + mDrawBufferStates[0] = GL_COLOR_ATTACHMENT0_EXT; +} + +FramebufferState::~FramebufferState() {} + +const std::string &FramebufferState::getLabel() const +{ + return mLabel; +} + +const FramebufferAttachment *FramebufferState::getAttachment(const Context *context, + GLenum attachment) const +{ + if (attachment >= GL_COLOR_ATTACHMENT0 && attachment <= GL_COLOR_ATTACHMENT15) + { + return getColorAttachment(attachment - GL_COLOR_ATTACHMENT0); + } + + // WebGL1 allows a developer to query for attachment parameters even when "inconsistant" (i.e. + // multiple conflicting attachment points) and requires us to return the framebuffer attachment + // associated with WebGL. + switch (attachment) + { + case GL_COLOR: + case GL_BACK: + return getColorAttachment(0); + case GL_DEPTH: + case GL_DEPTH_ATTACHMENT: + if (context->isWebGL1()) + { + return getWebGLDepthAttachment(); + } + else + { + return getDepthAttachment(); + } + case GL_STENCIL: + case GL_STENCIL_ATTACHMENT: + if (context->isWebGL1()) + { + return getWebGLStencilAttachment(); + } + else + { + return getStencilAttachment(); + } + case GL_DEPTH_STENCIL: + case GL_DEPTH_STENCIL_ATTACHMENT: + if (context->isWebGL1()) + { + return getWebGLDepthStencilAttachment(); + } + else + { + return getDepthStencilAttachment(); + } + default: + UNREACHABLE(); + return nullptr; + } +} + +uint32_t FramebufferState::getReadIndex() const +{ + ASSERT(mReadBufferState == GL_BACK || + (mReadBufferState >= GL_COLOR_ATTACHMENT0 && mReadBufferState <= GL_COLOR_ATTACHMENT15)); + uint32_t readIndex = mReadBufferState == GL_BACK ? 0 : mReadBufferState - GL_COLOR_ATTACHMENT0; + ASSERT(readIndex < mColorAttachments.size()); + return readIndex; +} + +const FramebufferAttachment *FramebufferState::getReadAttachment() const +{ + if (mReadBufferState == GL_NONE) + { + return nullptr; + } + + uint32_t readIndex = getReadIndex(); + const gl::FramebufferAttachment &framebufferAttachment = + isDefault() ? mDefaultFramebufferReadAttachment : mColorAttachments[readIndex]; + + return framebufferAttachment.isAttached() ? &framebufferAttachment : nullptr; +} + +const FramebufferAttachment *FramebufferState::getReadPixelsAttachment(GLenum readFormat) const +{ + switch (readFormat) + { + case GL_DEPTH_COMPONENT: + return getDepthAttachment(); + case GL_STENCIL_INDEX_OES: + return getStencilOrDepthStencilAttachment(); + case GL_DEPTH_STENCIL_OES: + return getDepthStencilAttachment(); + default: + return getReadAttachment(); + } +} + +const FramebufferAttachment *FramebufferState::getFirstNonNullAttachment() const +{ + auto *colorAttachment = getFirstColorAttachment(); + if (colorAttachment) + { + return colorAttachment; + } + return getDepthOrStencilAttachment(); +} + +const FramebufferAttachment *FramebufferState::getFirstColorAttachment() const +{ + for (const FramebufferAttachment &colorAttachment : mColorAttachments) + { + if (colorAttachment.isAttached()) + { + return &colorAttachment; + } + } + + return nullptr; +} + +const FramebufferAttachment *FramebufferState::getDepthOrStencilAttachment() const +{ + if (mDepthAttachment.isAttached()) + { + return &mDepthAttachment; + } + if (mStencilAttachment.isAttached()) + { + return &mStencilAttachment; + } + return nullptr; +} + +const FramebufferAttachment *FramebufferState::getStencilOrDepthStencilAttachment() const +{ + if (mStencilAttachment.isAttached()) + { + return &mStencilAttachment; + } + return getDepthStencilAttachment(); +} + +const FramebufferAttachment *FramebufferState::getColorAttachment(size_t colorAttachment) const +{ + ASSERT(colorAttachment < mColorAttachments.size()); + return mColorAttachments[colorAttachment].isAttached() ? &mColorAttachments[colorAttachment] + : nullptr; +} + +const FramebufferAttachment *FramebufferState::getDepthAttachment() const +{ + return mDepthAttachment.isAttached() ? &mDepthAttachment : nullptr; +} + +const FramebufferAttachment *FramebufferState::getWebGLDepthAttachment() const +{ + return mWebGLDepthAttachment.isAttached() ? &mWebGLDepthAttachment : nullptr; +} + +const FramebufferAttachment *FramebufferState::getWebGLDepthStencilAttachment() const +{ + return mWebGLDepthStencilAttachment.isAttached() ? &mWebGLDepthStencilAttachment : nullptr; +} + +const FramebufferAttachment *FramebufferState::getStencilAttachment() const +{ + return mStencilAttachment.isAttached() ? &mStencilAttachment : nullptr; +} + +const FramebufferAttachment *FramebufferState::getWebGLStencilAttachment() const +{ + return mWebGLStencilAttachment.isAttached() ? &mWebGLStencilAttachment : nullptr; +} + +const FramebufferAttachment *FramebufferState::getDepthStencilAttachment() const +{ + // A valid depth-stencil attachment has the same resource bound to both the + // depth and stencil attachment points. + if (mDepthAttachment.isAttached() && mStencilAttachment.isAttached() && + mDepthAttachment == mStencilAttachment) + { + return &mDepthAttachment; + } + + return nullptr; +} + +const Extents FramebufferState::getAttachmentExtentsIntersection() const +{ + int32_t width = std::numeric_limits::max(); + int32_t height = std::numeric_limits::max(); + for (const FramebufferAttachment &attachment : mColorAttachments) + { + if (attachment.isAttached()) + { + width = std::min(width, attachment.getSize().width); + height = std::min(height, attachment.getSize().height); + } + } + + if (mDepthAttachment.isAttached()) + { + width = std::min(width, mDepthAttachment.getSize().width); + height = std::min(height, mDepthAttachment.getSize().height); + } + + if (mStencilAttachment.isAttached()) + { + width = std::min(width, mStencilAttachment.getSize().width); + height = std::min(height, mStencilAttachment.getSize().height); + } + + return Extents(width, height, 0); +} + +bool FramebufferState::attachmentsHaveSameDimensions() const +{ + Optional attachmentSize; + + auto hasMismatchedSize = [&attachmentSize](const FramebufferAttachment &attachment) { + if (!attachment.isAttached()) + { + return false; + } + + if (!attachmentSize.valid()) + { + attachmentSize = attachment.getSize(); + return false; + } + + const auto &prevSize = attachmentSize.value(); + const auto &curSize = attachment.getSize(); + return (curSize.width != prevSize.width || curSize.height != prevSize.height); + }; + + for (const auto &attachment : mColorAttachments) + { + if (hasMismatchedSize(attachment)) + { + return false; + } + } + + if (hasMismatchedSize(mDepthAttachment)) + { + return false; + } + + return !hasMismatchedSize(mStencilAttachment); +} + +bool FramebufferState::hasSeparateDepthAndStencilAttachments() const +{ + // if we have both a depth and stencil buffer, they must refer to the same object + // since we only support packed_depth_stencil and not separate depth and stencil + return (getDepthAttachment() != nullptr && getStencilAttachment() != nullptr && + getDepthStencilAttachment() == nullptr); +} + +const FramebufferAttachment *FramebufferState::getDrawBuffer(size_t drawBufferIdx) const +{ + ASSERT(drawBufferIdx < mDrawBufferStates.size()); + if (mDrawBufferStates[drawBufferIdx] != GL_NONE) + { + // ES3 spec: "If the GL is bound to a draw framebuffer object, the ith buffer listed in bufs + // must be COLOR_ATTACHMENTi or NONE" + ASSERT(mDrawBufferStates[drawBufferIdx] == GL_COLOR_ATTACHMENT0 + drawBufferIdx || + (drawBufferIdx == 0 && mDrawBufferStates[drawBufferIdx] == GL_BACK)); + + if (mDrawBufferStates[drawBufferIdx] == GL_BACK) + { + return getColorAttachment(0); + } + else + { + return getColorAttachment(mDrawBufferStates[drawBufferIdx] - GL_COLOR_ATTACHMENT0); + } + } + else + { + return nullptr; + } +} + +size_t FramebufferState::getDrawBufferCount() const +{ + return mDrawBufferStates.size(); +} + +bool FramebufferState::colorAttachmentsAreUniqueImages() const +{ + for (size_t firstAttachmentIdx = 0; firstAttachmentIdx < mColorAttachments.size(); + firstAttachmentIdx++) + { + const FramebufferAttachment &firstAttachment = mColorAttachments[firstAttachmentIdx]; + if (!firstAttachment.isAttached()) + { + continue; + } + + for (size_t secondAttachmentIdx = firstAttachmentIdx + 1; + secondAttachmentIdx < mColorAttachments.size(); secondAttachmentIdx++) + { + const FramebufferAttachment &secondAttachment = mColorAttachments[secondAttachmentIdx]; + if (!secondAttachment.isAttached()) + { + continue; + } + + if (firstAttachment == secondAttachment) + { + return false; + } + } + } + + return true; +} + +bool FramebufferState::hasDepth() const +{ + return (mDepthAttachment.isAttached() && mDepthAttachment.getDepthSize() > 0); +} + +bool FramebufferState::hasStencil() const +{ + return (mStencilAttachment.isAttached() && mStencilAttachment.getStencilSize() > 0); +} + +bool FramebufferState::hasExternalTextureAttachment() const +{ + // External textures can only be bound to color attachment 0 + return (mColorAttachments[0].isAttached() && mColorAttachments[0].isExternalTexture()); +} + +bool FramebufferState::hasYUVAttachment() const +{ + // The only attachments that can be YUV are external textures and surfaces, both are attached at + // color attachment 0. + return (mColorAttachments[0].isAttached() && mColorAttachments[0].isYUV()); +} + +bool FramebufferState::isMultiview() const +{ + const FramebufferAttachment *attachment = getFirstNonNullAttachment(); + if (attachment == nullptr) + { + return false; + } + return attachment->isMultiview(); +} + +int FramebufferState::getBaseViewIndex() const +{ + const FramebufferAttachment *attachment = getFirstNonNullAttachment(); + if (attachment == nullptr) + { + return GL_NONE; + } + return attachment->getBaseViewIndex(); +} + +Box FramebufferState::getDimensions() const +{ + Extents extents = getExtents(); + return Box(0, 0, 0, extents.width, extents.height, extents.depth); +} + +Extents FramebufferState::getExtents() const +{ + // OpenGLES3.0 (https://www.khronos.org/registry/OpenGL/specs/es/3.0/es_spec_3.0.pdf + // section 4.4.4.2) allows attachments have unequal size. + const FramebufferAttachment *first = getFirstNonNullAttachment(); + if (first) + { + return getAttachmentExtentsIntersection(); + } + return Extents(getDefaultWidth(), getDefaultHeight(), 0); +} + +bool FramebufferState::isDefault() const +{ + return mId == Framebuffer::kDefaultDrawFramebufferHandle; +} + +bool FramebufferState::isBoundAsDrawFramebuffer(const Context *context) const +{ + return context->getState().getDrawFramebuffer()->id() == mId; +} + +const FramebufferID Framebuffer::kDefaultDrawFramebufferHandle = {0}; + +Framebuffer::Framebuffer(const Context *context, rx::GLImplFactory *factory) + : mState(context->getShareGroup()->generateFramebufferSerial()), + mImpl(factory->createFramebuffer(mState)), + mCachedStatus(FramebufferStatus::Incomplete(GL_FRAMEBUFFER_UNDEFINED_OES, + err::kFramebufferIncompleteSurfaceless)), + mDirtyDepthAttachmentBinding(this, DIRTY_BIT_DEPTH_ATTACHMENT), + mDirtyStencilAttachmentBinding(this, DIRTY_BIT_STENCIL_ATTACHMENT) +{ + mDirtyColorAttachmentBindings.emplace_back(this, DIRTY_BIT_COLOR_ATTACHMENT_0); + SetComponentTypeMask(getDrawbufferWriteType(0), 0, &mState.mDrawBufferTypeMask); +} + +Framebuffer::Framebuffer(const Context *context, rx::GLImplFactory *factory, FramebufferID id) + : mState(context->getCaps(), id, context->getShareGroup()->generateFramebufferSerial()), + mImpl(factory->createFramebuffer(mState)), + mCachedStatus(), + mDirtyDepthAttachmentBinding(this, DIRTY_BIT_DEPTH_ATTACHMENT), + mDirtyStencilAttachmentBinding(this, DIRTY_BIT_STENCIL_ATTACHMENT) +{ + ASSERT(mImpl != nullptr); + ASSERT(mState.mColorAttachments.size() == + static_cast(context->getCaps().maxColorAttachments)); + + for (uint32_t colorIndex = 0; + colorIndex < static_cast(mState.mColorAttachments.size()); ++colorIndex) + { + mDirtyColorAttachmentBindings.emplace_back(this, DIRTY_BIT_COLOR_ATTACHMENT_0 + colorIndex); + } + if (context->getClientVersion() >= ES_3_0) + { + mDirtyBits.set(DIRTY_BIT_READ_BUFFER); + } +} + +Framebuffer::~Framebuffer() +{ + SafeDelete(mImpl); +} + +void Framebuffer::onDestroy(const Context *context) +{ + if (isDefault()) + { + std::ignore = unsetSurfaces(context); + } + + for (auto &attachment : mState.mColorAttachments) + { + attachment.detach(context, mState.mFramebufferSerial); + } + mState.mDepthAttachment.detach(context, mState.mFramebufferSerial); + mState.mStencilAttachment.detach(context, mState.mFramebufferSerial); + mState.mWebGLDepthAttachment.detach(context, mState.mFramebufferSerial); + mState.mWebGLStencilAttachment.detach(context, mState.mFramebufferSerial); + mState.mWebGLDepthStencilAttachment.detach(context, mState.mFramebufferSerial); + + if (mPixelLocalStorage) + { + mPixelLocalStorage->onFramebufferDestroyed(context); + } + + mImpl->destroy(context); +} + +egl::Error Framebuffer::setSurfaces(const Context *context, + egl::Surface *surface, + egl::Surface *readSurface) +{ + // This has to be a default framebuffer. + ASSERT(isDefault()); + ASSERT(mDirtyColorAttachmentBindings.size() == 1); + ASSERT(mDirtyColorAttachmentBindings[0].getSubjectIndex() == DIRTY_BIT_COLOR_ATTACHMENT_0); + + ASSERT(!mState.mColorAttachments[0].isAttached()); + ASSERT(!mState.mDepthAttachment.isAttached()); + ASSERT(!mState.mStencilAttachment.isAttached()); + + if (surface) + { + setAttachmentImpl(context, GL_FRAMEBUFFER_DEFAULT, GL_BACK, ImageIndex(), surface, + FramebufferAttachment::kDefaultNumViews, + FramebufferAttachment::kDefaultBaseViewIndex, false, + FramebufferAttachment::kDefaultRenderToTextureSamples); + mDirtyBits.set(DIRTY_BIT_COLOR_ATTACHMENT_0); + + if (surface->getConfig()->depthSize > 0) + { + setAttachmentImpl(context, GL_FRAMEBUFFER_DEFAULT, GL_DEPTH, ImageIndex(), surface, + FramebufferAttachment::kDefaultNumViews, + FramebufferAttachment::kDefaultBaseViewIndex, false, + FramebufferAttachment::kDefaultRenderToTextureSamples); + mDirtyBits.set(DIRTY_BIT_DEPTH_ATTACHMENT); + } + + if (surface->getConfig()->stencilSize > 0) + { + setAttachmentImpl(context, GL_FRAMEBUFFER_DEFAULT, GL_STENCIL, ImageIndex(), surface, + FramebufferAttachment::kDefaultNumViews, + FramebufferAttachment::kDefaultBaseViewIndex, false, + FramebufferAttachment::kDefaultRenderToTextureSamples); + mDirtyBits.set(DIRTY_BIT_STENCIL_ATTACHMENT); + } + + mState.mSurfaceTextureOffset = surface->getTextureOffset(); + + // Ensure the backend has a chance to synchronize its content for a new backbuffer. + mDirtyBits.set(DIRTY_BIT_COLOR_BUFFER_CONTENTS_0); + } + + setReadSurface(context, readSurface); + + SetComponentTypeMask(getDrawbufferWriteType(0), 0, &mState.mDrawBufferTypeMask); + + ASSERT(mCachedStatus.value().status == GL_FRAMEBUFFER_UNDEFINED_OES); + ASSERT(mCachedStatus.value().reason == err::kFramebufferIncompleteSurfaceless); + if (surface) + { + mCachedStatus = FramebufferStatus::Complete(); + ANGLE_TRY(surface->getImplementation()->attachToFramebuffer(context, this)); + } + + return egl::NoError(); +} + +void Framebuffer::setReadSurface(const Context *context, egl::Surface *readSurface) +{ + // This has to be a default framebuffer. + ASSERT(isDefault()); + ASSERT(mDirtyColorAttachmentBindings.size() == 1); + ASSERT(mDirtyColorAttachmentBindings[0].getSubjectIndex() == DIRTY_BIT_COLOR_ATTACHMENT_0); + + // Read surface is not attached. + ASSERT(!mState.mDefaultFramebufferReadAttachment.isAttached()); + + // updateAttachment() without mState.mResourceNeedsInit.set() + mState.mDefaultFramebufferReadAttachment.attach( + context, GL_FRAMEBUFFER_DEFAULT, GL_BACK, ImageIndex(), readSurface, + FramebufferAttachment::kDefaultNumViews, FramebufferAttachment::kDefaultBaseViewIndex, + false, FramebufferAttachment::kDefaultRenderToTextureSamples, mState.mFramebufferSerial); + + if (context->getClientVersion() >= ES_3_0) + { + mDirtyBits.set(DIRTY_BIT_READ_BUFFER); + } +} + +egl::Error Framebuffer::unsetSurfaces(const Context *context) +{ + // This has to be a default framebuffer. + ASSERT(isDefault()); + ASSERT(mDirtyColorAttachmentBindings.size() == 1); + ASSERT(mDirtyColorAttachmentBindings[0].getSubjectIndex() == DIRTY_BIT_COLOR_ATTACHMENT_0); + + if (mState.mColorAttachments[0].isAttached()) + { + const egl::Surface *surface = mState.mColorAttachments[0].getSurface(); + mState.mColorAttachments[0].detach(context, mState.mFramebufferSerial); + mDirtyBits.set(DIRTY_BIT_COLOR_ATTACHMENT_0); + + if (mState.mDepthAttachment.isAttached()) + { + mState.mDepthAttachment.detach(context, mState.mFramebufferSerial); + mDirtyBits.set(DIRTY_BIT_DEPTH_ATTACHMENT); + } + + if (mState.mStencilAttachment.isAttached()) + { + mState.mStencilAttachment.detach(context, mState.mFramebufferSerial); + mDirtyBits.set(DIRTY_BIT_STENCIL_ATTACHMENT); + } + + ANGLE_TRY(surface->getImplementation()->detachFromFramebuffer(context, this)); + + ASSERT(mCachedStatus.value().status == GL_FRAMEBUFFER_COMPLETE); + mCachedStatus = FramebufferStatus::Incomplete(GL_FRAMEBUFFER_UNDEFINED_OES, + err::kFramebufferIncompleteSurfaceless); + } + else + { + ASSERT(!mState.mDepthAttachment.isAttached()); + ASSERT(!mState.mStencilAttachment.isAttached()); + ASSERT(mCachedStatus.value().status == GL_FRAMEBUFFER_UNDEFINED_OES); + ASSERT(mCachedStatus.value().reason == err::kFramebufferIncompleteSurfaceless); + } + + mState.mDefaultFramebufferReadAttachment.detach(context, mState.mFramebufferSerial); + mState.mDefaultFramebufferReadAttachmentInitialized = false; + return egl::NoError(); +} + +angle::Result Framebuffer::setLabel(const Context *context, const std::string &label) +{ + mState.mLabel = label; + + if (mImpl) + { + return mImpl->onLabelUpdate(context); + } + return angle::Result::Continue; +} + +const std::string &Framebuffer::getLabel() const +{ + return mState.mLabel; +} + +bool Framebuffer::detachTexture(const Context *context, TextureID textureId) +{ + return detachResourceById(context, GL_TEXTURE, textureId.value); +} + +bool Framebuffer::detachRenderbuffer(const Context *context, RenderbufferID renderbufferId) +{ + return detachResourceById(context, GL_RENDERBUFFER, renderbufferId.value); +} + +bool Framebuffer::detachResourceById(const Context *context, GLenum resourceType, GLuint resourceId) +{ + bool found = false; + + for (size_t colorIndex = 0; colorIndex < mState.mColorAttachments.size(); ++colorIndex) + { + if (detachMatchingAttachment(context, &mState.mColorAttachments[colorIndex], resourceType, + resourceId)) + { + found = true; + } + } + + if (context->isWebGL1()) + { + const std::array attachments = { + {&mState.mWebGLDepthStencilAttachment, &mState.mWebGLDepthAttachment, + &mState.mWebGLStencilAttachment}}; + for (FramebufferAttachment *attachment : attachments) + { + if (detachMatchingAttachment(context, attachment, resourceType, resourceId)) + { + found = true; + } + } + } + else + { + if (detachMatchingAttachment(context, &mState.mDepthAttachment, resourceType, resourceId)) + { + found = true; + } + if (detachMatchingAttachment(context, &mState.mStencilAttachment, resourceType, resourceId)) + { + found = true; + } + } + + return found; +} + +bool Framebuffer::detachMatchingAttachment(const Context *context, + FramebufferAttachment *attachment, + GLenum matchType, + GLuint matchId) +{ + if (attachment->isAttached() && attachment->type() == matchType && attachment->id() == matchId) + { + // We go through resetAttachment to make sure that all the required bookkeeping will be done + // such as updating enabled draw buffer state. + resetAttachment(context, attachment->getBinding()); + return true; + } + + return false; +} + +const FramebufferAttachment *Framebuffer::getColorAttachment(size_t colorAttachment) const +{ + return mState.getColorAttachment(colorAttachment); +} + +const FramebufferAttachment *Framebuffer::getDepthAttachment() const +{ + return mState.getDepthAttachment(); +} + +const FramebufferAttachment *Framebuffer::getStencilAttachment() const +{ + return mState.getStencilAttachment(); +} + +const FramebufferAttachment *Framebuffer::getDepthStencilAttachment() const +{ + return mState.getDepthStencilAttachment(); +} + +const FramebufferAttachment *Framebuffer::getDepthOrStencilAttachment() const +{ + return mState.getDepthOrStencilAttachment(); +} + +const FramebufferAttachment *Framebuffer::getStencilOrDepthStencilAttachment() const +{ + return mState.getStencilOrDepthStencilAttachment(); +} + +const FramebufferAttachment *Framebuffer::getReadColorAttachment() const +{ + return mState.getReadAttachment(); +} + +GLenum Framebuffer::getReadColorAttachmentType() const +{ + const FramebufferAttachment *readAttachment = mState.getReadAttachment(); + return (readAttachment != nullptr ? readAttachment->type() : GL_NONE); +} + +const FramebufferAttachment *Framebuffer::getFirstColorAttachment() const +{ + return mState.getFirstColorAttachment(); +} + +const FramebufferAttachment *Framebuffer::getFirstNonNullAttachment() const +{ + return mState.getFirstNonNullAttachment(); +} + +const FramebufferAttachment *Framebuffer::getAttachment(const Context *context, + GLenum attachment) const +{ + return mState.getAttachment(context, attachment); +} + +size_t Framebuffer::getDrawbufferStateCount() const +{ + return mState.mDrawBufferStates.size(); +} + +GLenum Framebuffer::getDrawBufferState(size_t drawBuffer) const +{ + ASSERT(drawBuffer < mState.mDrawBufferStates.size()); + return mState.mDrawBufferStates[drawBuffer]; +} + +const DrawBuffersVector &Framebuffer::getDrawBufferStates() const +{ + return mState.getDrawBufferStates(); +} + +void Framebuffer::setDrawBuffers(size_t count, const GLenum *buffers) +{ + auto &drawStates = mState.mDrawBufferStates; + + ASSERT(count <= drawStates.size()); + std::copy(buffers, buffers + count, drawStates.begin()); + std::fill(drawStates.begin() + count, drawStates.end(), GL_NONE); + mDirtyBits.set(DIRTY_BIT_DRAW_BUFFERS); + + mState.mEnabledDrawBuffers.reset(); + mState.mDrawBufferTypeMask.reset(); + + for (size_t index = 0; index < count; ++index) + { + SetComponentTypeMask(getDrawbufferWriteType(index), index, &mState.mDrawBufferTypeMask); + + if (drawStates[index] != GL_NONE && mState.mColorAttachments[index].isAttached()) + { + mState.mEnabledDrawBuffers.set(index); + } + } +} + +const FramebufferAttachment *Framebuffer::getDrawBuffer(size_t drawBuffer) const +{ + return mState.getDrawBuffer(drawBuffer); +} + +ComponentType Framebuffer::getDrawbufferWriteType(size_t drawBuffer) const +{ + const FramebufferAttachment *attachment = mState.getDrawBuffer(drawBuffer); + if (attachment == nullptr) + { + return ComponentType::NoType; + } + + GLenum componentType = attachment->getFormat().info->componentType; + switch (componentType) + { + case GL_INT: + return ComponentType::Int; + case GL_UNSIGNED_INT: + return ComponentType::UnsignedInt; + + default: + return ComponentType::Float; + } +} + +ComponentTypeMask Framebuffer::getDrawBufferTypeMask() const +{ + return mState.mDrawBufferTypeMask; +} + +DrawBufferMask Framebuffer::getDrawBufferMask() const +{ + return mState.mEnabledDrawBuffers; +} + +bool Framebuffer::hasEnabledDrawBuffer() const +{ + for (size_t drawbufferIdx = 0; drawbufferIdx < mState.mDrawBufferStates.size(); ++drawbufferIdx) + { + if (getDrawBuffer(drawbufferIdx) != nullptr) + { + return true; + } + } + + return false; +} + +GLenum Framebuffer::getReadBufferState() const +{ + return mState.mReadBufferState; +} + +void Framebuffer::setReadBuffer(GLenum buffer) +{ + ASSERT(buffer == GL_BACK || buffer == GL_NONE || + (buffer >= GL_COLOR_ATTACHMENT0 && + (buffer - GL_COLOR_ATTACHMENT0) < mState.mColorAttachments.size())); + if (mState.mReadBufferState != buffer) + { + mState.mReadBufferState = buffer; + mDirtyBits.set(DIRTY_BIT_READ_BUFFER); + } +} + +size_t Framebuffer::getNumColorAttachments() const +{ + return mState.mColorAttachments.size(); +} + +bool Framebuffer::hasDepth() const +{ + return mState.hasDepth(); +} + +bool Framebuffer::hasStencil() const +{ + return mState.hasStencil(); +} + +bool Framebuffer::hasExternalTextureAttachment() const +{ + return mState.hasExternalTextureAttachment(); +} + +bool Framebuffer::hasYUVAttachment() const +{ + return mState.hasYUVAttachment(); +} + +bool Framebuffer::usingExtendedDrawBuffers() const +{ + for (size_t drawbufferIdx = 1; drawbufferIdx < mState.mDrawBufferStates.size(); ++drawbufferIdx) + { + if (getDrawBuffer(drawbufferIdx) != nullptr) + { + return true; + } + } + + return false; +} + +void Framebuffer::invalidateCompletenessCache() +{ + if (!isDefault()) + { + mCachedStatus.reset(); + } + onStateChange(angle::SubjectMessage::DirtyBitsFlagged); +} + +const FramebufferStatus &Framebuffer::checkStatusImpl(const Context *context) const +{ + ASSERT(!isDefault()); + ASSERT(hasAnyDirtyBit() || !mCachedStatus.valid()); + + mCachedStatus = checkStatusWithGLFrontEnd(context); + + if (mCachedStatus.value().isComplete()) + { + // We can skip syncState on several back-ends. + if (mImpl->shouldSyncStateBeforeCheckStatus()) + { + // This binding is not totally correct. It is ok because the parameter isn't used in + // the GL back-end and the GL back-end is the only user of syncStateBeforeCheckStatus. + angle::Result err = syncState(context, GL_FRAMEBUFFER, Command::Other); + if (err != angle::Result::Continue) + { + mCachedStatus = + FramebufferStatus::Incomplete(0, err::kFramebufferIncompleteInternalError); + return mCachedStatus.value(); + } + } + + mCachedStatus = mImpl->checkStatus(context); + } + + return mCachedStatus.value(); +} + +FramebufferStatus Framebuffer::checkStatusWithGLFrontEnd(const Context *context) const +{ + const State &state = context->getState(); + + ASSERT(!isDefault()); + + bool hasAttachments = false; + Optional colorbufferSize; + Optional samples; + Optional fixedSampleLocations; + bool hasRenderbuffer = false; + Optional renderToTextureSamples; + + const FramebufferAttachment *firstAttachment = getFirstNonNullAttachment(); + + Optional isLayered; + Optional colorAttachmentsTextureType; + + for (const FramebufferAttachment &colorAttachment : mState.mColorAttachments) + { + if (colorAttachment.isAttached()) + { + FramebufferStatus attachmentCompleteness = + CheckAttachmentCompleteness(context, colorAttachment); + if (!attachmentCompleteness.isComplete()) + { + return attachmentCompleteness; + } + + const InternalFormat &format = *colorAttachment.getFormat().info; + if (format.depthBits > 0 || format.stencilBits > 0) + { + return FramebufferStatus::Incomplete( + GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, + err::kFramebufferIncompleteDepthStencilInColorBuffer); + } + + FramebufferStatus attachmentSampleCompleteness = + CheckAttachmentSampleCompleteness(context, colorAttachment, true, &samples, + &fixedSampleLocations, &renderToTextureSamples); + if (!attachmentSampleCompleteness.isComplete()) + { + return attachmentSampleCompleteness; + } + + // in GLES 2.0, all color attachments attachments must have the same number of bitplanes + // in GLES 3.0, there is no such restriction + if (state.getClientMajorVersion() < 3) + { + if (colorbufferSize.valid()) + { + if (format.pixelBytes != colorbufferSize.value()) + { + return FramebufferStatus::Incomplete( + GL_FRAMEBUFFER_UNSUPPORTED, + err::kFramebufferIncompleteAttachmentInconsistantBitPlanes); + } + } + else + { + colorbufferSize = format.pixelBytes; + } + } + + FramebufferStatus attachmentMultiviewCompleteness = + CheckMultiviewStateMatchesForCompleteness(firstAttachment, &colorAttachment); + if (!attachmentMultiviewCompleteness.isComplete()) + { + return attachmentMultiviewCompleteness; + } + + hasRenderbuffer = hasRenderbuffer || (colorAttachment.type() == GL_RENDERBUFFER); + + if (!hasAttachments) + { + isLayered = colorAttachment.isLayered(); + if (isLayered.value()) + { + colorAttachmentsTextureType = colorAttachment.getTextureImageIndex().getType(); + } + hasAttachments = true; + } + else + { + // [EXT_geometry_shader] section 9.4.1, "Framebuffer Completeness" + // If any framebuffer attachment is layered, all populated attachments + // must be layered. Additionally, all populated color attachments must + // be from textures of the same target. {FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT } + ASSERT(isLayered.valid()); + if (isLayered.value() != colorAttachment.isLayered()) + { + return FramebufferStatus::Incomplete( + GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT, + err::kFramebufferIncompleteMismatchedLayeredAttachments); + } + else if (isLayered.value()) + { + ASSERT(colorAttachmentsTextureType.valid()); + if (colorAttachmentsTextureType.value() != + colorAttachment.getTextureImageIndex().getType()) + { + return FramebufferStatus::Incomplete( + GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT, + err::kFramebufferIncompleteMismatchedLayeredTexturetypes); + } + } + } + } + } + + const FramebufferAttachment &depthAttachment = mState.mDepthAttachment; + if (depthAttachment.isAttached()) + { + FramebufferStatus attachmentCompleteness = + CheckAttachmentCompleteness(context, depthAttachment); + if (!attachmentCompleteness.isComplete()) + { + return attachmentCompleteness; + } + + const InternalFormat &format = *depthAttachment.getFormat().info; + if (format.depthBits == 0) + { + return FramebufferStatus::Incomplete( + GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, + err::kFramebufferIncompleteAttachmentNoDepthBitsInDepthBuffer); + } + + FramebufferStatus attachmentSampleCompleteness = + CheckAttachmentSampleCompleteness(context, depthAttachment, false, &samples, + &fixedSampleLocations, &renderToTextureSamples); + if (!attachmentSampleCompleteness.isComplete()) + { + return attachmentSampleCompleteness; + } + + FramebufferStatus attachmentMultiviewCompleteness = + CheckMultiviewStateMatchesForCompleteness(firstAttachment, &depthAttachment); + if (!attachmentMultiviewCompleteness.isComplete()) + { + return attachmentMultiviewCompleteness; + } + + hasRenderbuffer = hasRenderbuffer || (depthAttachment.type() == GL_RENDERBUFFER); + + if (!hasAttachments) + { + isLayered = depthAttachment.isLayered(); + hasAttachments = true; + } + else + { + // [EXT_geometry_shader] section 9.4.1, "Framebuffer Completeness" + // If any framebuffer attachment is layered, all populated attachments + // must be layered. {FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT } + ASSERT(isLayered.valid()); + if (isLayered.value() != depthAttachment.isLayered()) + { + return FramebufferStatus::Incomplete( + GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT, + err::kFramebufferIncompleteMismatchedLayeredAttachments); + } + } + } + + const FramebufferAttachment &stencilAttachment = mState.mStencilAttachment; + if (stencilAttachment.isAttached()) + { + FramebufferStatus attachmentCompleteness = + CheckAttachmentCompleteness(context, stencilAttachment); + if (!attachmentCompleteness.isComplete()) + { + return attachmentCompleteness; + } + + const InternalFormat &format = *stencilAttachment.getFormat().info; + if (format.stencilBits == 0) + { + return FramebufferStatus::Incomplete( + GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, + err::kFramebufferIncompleteAttachmentNoStencilBitsInStencilBuffer); + } + + FramebufferStatus attachmentSampleCompleteness = + CheckAttachmentSampleCompleteness(context, stencilAttachment, false, &samples, + &fixedSampleLocations, &renderToTextureSamples); + if (!attachmentSampleCompleteness.isComplete()) + { + return attachmentSampleCompleteness; + } + + FramebufferStatus attachmentMultiviewCompleteness = + CheckMultiviewStateMatchesForCompleteness(firstAttachment, &stencilAttachment); + if (!attachmentMultiviewCompleteness.isComplete()) + { + return attachmentMultiviewCompleteness; + } + + hasRenderbuffer = hasRenderbuffer || (stencilAttachment.type() == GL_RENDERBUFFER); + + if (!hasAttachments) + { + hasAttachments = true; + } + else + { + // [EXT_geometry_shader] section 9.4.1, "Framebuffer Completeness" + // If any framebuffer attachment is layered, all populated attachments + // must be layered. + // {FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT } + ASSERT(isLayered.valid()); + if (isLayered.value() != stencilAttachment.isLayered()) + { + return FramebufferStatus::Incomplete( + GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT, + err::kFramebufferIncompleteMismatchedLayeredAttachments); + } + } + } + + // Starting from ES 3.0 stencil and depth, if present, should be the same image + if (state.getClientMajorVersion() >= 3 && depthAttachment.isAttached() && + stencilAttachment.isAttached() && stencilAttachment != depthAttachment) + { + return FramebufferStatus::Incomplete( + GL_FRAMEBUFFER_UNSUPPORTED, + err::kFramebufferIncompleteDepthAndStencilBuffersNotTheSame); + } + + // Special additional validation for WebGL 1 DEPTH/STENCIL/DEPTH_STENCIL. + if (state.isWebGL1()) + { + if (!mState.mWebGLDepthStencilConsistent) + { + return FramebufferStatus::Incomplete( + GL_FRAMEBUFFER_UNSUPPORTED, + err::kFramebufferIncompleteWebGLDepthStencilInconsistant); + } + + if (mState.mWebGLDepthStencilAttachment.isAttached()) + { + if (mState.mWebGLDepthStencilAttachment.getDepthSize() == 0 || + mState.mWebGLDepthStencilAttachment.getStencilSize() == 0) + { + return FramebufferStatus::Incomplete( + GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, + err::kFramebufferIncompleteAttachmentWebGLDepthStencilNoDepthOrStencilBits); + } + + FramebufferStatus attachmentMultiviewCompleteness = + CheckMultiviewStateMatchesForCompleteness(firstAttachment, + &mState.mWebGLDepthStencilAttachment); + if (!attachmentMultiviewCompleteness.isComplete()) + { + return attachmentMultiviewCompleteness; + } + } + else if (mState.mStencilAttachment.isAttached() && + mState.mStencilAttachment.getDepthSize() > 0) + { + return FramebufferStatus::Incomplete( + GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, + err::kFramebufferIncompleteAttachmentWebGLStencilBufferHasDepthBits); + } + else if (mState.mDepthAttachment.isAttached() && + mState.mDepthAttachment.getStencilSize() > 0) + { + return FramebufferStatus::Incomplete( + GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, + err::kFramebufferIncompleteAttachmentWebGLDepthBufferHasStencilBits); + } + } + + // ES3.1(section 9.4) requires that if no image is attached to the framebuffer, and either the + // value of the framebuffer's FRAMEBUFFER_DEFAULT_WIDTH or FRAMEBUFFER_DEFAULT_HEIGHT parameters + // is zero, the framebuffer is considered incomplete. + GLint defaultWidth = mState.getDefaultWidth(); + GLint defaultHeight = mState.getDefaultHeight(); + if (!hasAttachments && (defaultWidth == 0 || defaultHeight == 0)) + { + return FramebufferStatus::Incomplete(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT, + err::kFramebufferIncompleteDefaultZeroSize); + } + + // In ES 2.0 and WebGL, all color attachments must have the same width and height. + // In ES 3.0, there is no such restriction. + if ((state.getClientMajorVersion() < 3 || state.getExtensions().webglCompatibilityANGLE) && + !mState.attachmentsHaveSameDimensions()) + { + return FramebufferStatus::Incomplete( + GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS, + err::kFramebufferIncompleteInconsistantAttachmentSizes); + } + + // ES3.1(section 9.4) requires that if the attached images are a mix of renderbuffers and + // textures, the value of TEXTURE_FIXED_SAMPLE_LOCATIONS must be TRUE for all attached textures. + if (fixedSampleLocations.valid() && hasRenderbuffer && !fixedSampleLocations.value()) + { + return FramebufferStatus::Incomplete( + GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE, + err::kFramebufferIncompleteMultisampleNonFixedSamplesWithRenderbuffers); + } + + // The WebGL conformance tests implicitly define that all framebuffer + // attachments must be unique. For example, the same level of a texture can + // not be attached to two different color attachments. + if (state.getExtensions().webglCompatibilityANGLE) + { + if (!mState.colorAttachmentsAreUniqueImages()) + { + return FramebufferStatus::Incomplete(GL_FRAMEBUFFER_UNSUPPORTED, + err::kFramebufferIncompleteAttachmentsNotUnique); + } + } + + return FramebufferStatus::Complete(); +} + +angle::Result Framebuffer::discard(const Context *context, size_t count, const GLenum *attachments) +{ + // Back-ends might make the contents of the FBO undefined. In WebGL 2.0, invalidate operations + // can be no-ops, so we should probably do that to ensure consistency. + // TODO(jmadill): WebGL behaviour, and robust resource init behaviour without WebGL. + + return mImpl->discard(context, count, attachments); +} + +angle::Result Framebuffer::invalidate(const Context *context, + size_t count, + const GLenum *attachments) +{ + // Back-ends might make the contents of the FBO undefined. In WebGL 2.0, invalidate operations + // can be no-ops, so we should probably do that to ensure consistency. + // TODO(jmadill): WebGL behaviour, and robust resource init behaviour without WebGL. + + return mImpl->invalidate(context, count, attachments); +} + +bool Framebuffer::partialClearNeedsInit(const Context *context, + bool color, + bool depth, + bool stencil) +{ + const auto &glState = context->getState(); + + if (!glState.isRobustResourceInitEnabled()) + { + return false; + } + + if (depth && context->getFrontendFeatures().forceDepthAttachmentInitOnClear.enabled) + { + return true; + } + + // Scissors can affect clearing. + // TODO(jmadill): Check for complete scissor overlap. + if (glState.isScissorTestEnabled()) + { + return true; + } + + // If colors masked, we must clear before we clear. Do a simple check. + // TODO(jmadill): Filter out unused color channels from the test. + if (color && glState.anyActiveDrawBufferChannelMasked()) + { + return true; + } + + const auto &depthStencil = glState.getDepthStencilState(); + if (stencil && (depthStencil.stencilMask != depthStencil.stencilWritemask || + depthStencil.stencilBackMask != depthStencil.stencilBackWritemask)) + { + return true; + } + + return false; +} + +angle::Result Framebuffer::invalidateSub(const Context *context, + size_t count, + const GLenum *attachments, + const Rectangle &area) +{ + // Back-ends might make the contents of the FBO undefined. In WebGL 2.0, invalidate operations + // can be no-ops, so we should probably do that to ensure consistency. + // TODO(jmadill): Make a invalidate no-op in WebGL 2.0. + + return mImpl->invalidateSub(context, count, attachments, area); +} + +angle::Result Framebuffer::clear(const Context *context, GLbitfield mask) +{ + ASSERT(mask && !context->getState().isRasterizerDiscardEnabled()); + + return mImpl->clear(context, mask); +} + +angle::Result Framebuffer::clearBufferfv(const Context *context, + GLenum buffer, + GLint drawbuffer, + const GLfloat *values) +{ + return mImpl->clearBufferfv(context, buffer, drawbuffer, values); +} + +angle::Result Framebuffer::clearBufferuiv(const Context *context, + GLenum buffer, + GLint drawbuffer, + const GLuint *values) +{ + return mImpl->clearBufferuiv(context, buffer, drawbuffer, values); +} + +angle::Result Framebuffer::clearBufferiv(const Context *context, + GLenum buffer, + GLint drawbuffer, + const GLint *values) +{ + return mImpl->clearBufferiv(context, buffer, drawbuffer, values); +} + +angle::Result Framebuffer::clearBufferfi(const Context *context, + GLenum buffer, + GLint drawbuffer, + GLfloat depth, + GLint stencil) +{ + const bool clearDepth = + getDepthAttachment() != nullptr && context->getState().getDepthStencilState().depthMask; + const bool clearStencil = getStencilAttachment() != nullptr && + context->getState().getDepthStencilState().stencilWritemask != 0; + + if (clearDepth && clearStencil) + { + ASSERT(buffer == GL_DEPTH_STENCIL); + ANGLE_TRY(mImpl->clearBufferfi(context, GL_DEPTH_STENCIL, drawbuffer, depth, stencil)); + } + else if (clearDepth && !clearStencil) + { + ANGLE_TRY(mImpl->clearBufferfv(context, GL_DEPTH, drawbuffer, &depth)); + } + else if (!clearDepth && clearStencil) + { + ANGLE_TRY(mImpl->clearBufferiv(context, GL_STENCIL, drawbuffer, &stencil)); + } + + return angle::Result::Continue; +} + +GLenum Framebuffer::getImplementationColorReadFormat(const Context *context) +{ + const gl::InternalFormat &format = mImpl->getImplementationColorReadFormat(context); + return format.getReadPixelsFormat(context->getExtensions()); +} + +GLenum Framebuffer::getImplementationColorReadType(const Context *context) +{ + const gl::InternalFormat &format = mImpl->getImplementationColorReadFormat(context); + return format.getReadPixelsType(context->getClientVersion()); +} + +angle::Result Framebuffer::readPixels(const Context *context, + const Rectangle &area, + GLenum format, + GLenum type, + const PixelPackState &pack, + Buffer *packBuffer, + void *pixels) +{ + ANGLE_TRY(mImpl->readPixels(context, area, format, type, pack, packBuffer, pixels)); + + if (packBuffer) + { + packBuffer->onDataChanged(); + } + + return angle::Result::Continue; +} + +angle::Result Framebuffer::blit(const Context *context, + const Rectangle &sourceArea, + const Rectangle &destArea, + GLbitfield mask, + GLenum filter) +{ + ASSERT(mask != 0); + + ANGLE_TRY(mImpl->blit(context, sourceArea, destArea, mask, filter)); + + // Mark the contents of the attachments dirty + if ((mask & GL_COLOR_BUFFER_BIT) != 0) + { + for (size_t colorIndex : mState.mEnabledDrawBuffers) + { + mDirtyBits.set(DIRTY_BIT_COLOR_BUFFER_CONTENTS_0 + colorIndex); + } + } + if ((mask & GL_DEPTH_BUFFER_BIT) != 0) + { + mDirtyBits.set(DIRTY_BIT_DEPTH_BUFFER_CONTENTS); + } + if ((mask & GL_STENCIL_BUFFER_BIT) != 0) + { + mDirtyBits.set(DIRTY_BIT_STENCIL_BUFFER_CONTENTS); + } + onStateChange(angle::SubjectMessage::DirtyBitsFlagged); + + return angle::Result::Continue; +} + +int Framebuffer::getSamples(const Context *context) const +{ + if (!isComplete(context)) + { + return 0; + } + + ASSERT(mCachedStatus.valid() && mCachedStatus.value().isComplete()); + + // For a complete framebuffer, all attachments must have the same sample count. + // In this case return the first nonzero sample size. + const FramebufferAttachment *firstNonNullAttachment = mState.getFirstNonNullAttachment(); + ASSERT(firstNonNullAttachment == nullptr || firstNonNullAttachment->isAttached()); + + return firstNonNullAttachment ? firstNonNullAttachment->getSamples() : 0; +} + +int Framebuffer::getReadBufferResourceSamples(const Context *context) const +{ + if (!isComplete(context)) + { + return 0; + } + + ASSERT(mCachedStatus.valid() && mCachedStatus.value().isComplete()); + + const FramebufferAttachment *readAttachment = mState.getReadAttachment(); + ASSERT(readAttachment == nullptr || readAttachment->isAttached()); + + return readAttachment ? readAttachment->getResourceSamples() : 0; +} + +angle::Result Framebuffer::getSamplePosition(const Context *context, + size_t index, + GLfloat *xy) const +{ + ANGLE_TRY(mImpl->getSamplePosition(context, index, xy)); + return angle::Result::Continue; +} + +bool Framebuffer::hasValidDepthStencil() const +{ + return mState.getDepthStencilAttachment() != nullptr; +} + +const gl::Offset &Framebuffer::getSurfaceTextureOffset() const +{ + return mState.getSurfaceTextureOffset(); +} + +void Framebuffer::setAttachment(const Context *context, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource) +{ + setAttachment(context, type, binding, textureIndex, resource, + FramebufferAttachment::kDefaultNumViews, + FramebufferAttachment::kDefaultBaseViewIndex, false, + FramebufferAttachment::kDefaultRenderToTextureSamples); +} + +void Framebuffer::setAttachmentMultisample(const Context *context, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource, + GLsizei samples) +{ + setAttachment(context, type, binding, textureIndex, resource, + FramebufferAttachment::kDefaultNumViews, + FramebufferAttachment::kDefaultBaseViewIndex, false, samples); +} + +void Framebuffer::setAttachment(const Context *context, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource, + GLsizei numViews, + GLuint baseViewIndex, + bool isMultiview, + GLsizei samplesIn) +{ + GLsizei samples = samplesIn; + // Match the sample count to the attachment's sample count. + if (resource) + { + const InternalFormat *info = resource->getAttachmentFormat(binding, textureIndex).info; + ASSERT(info); + GLenum sizedInternalFormat = info->sizedInternalFormat; + const TextureCaps &formatCaps = context->getTextureCaps().get(sizedInternalFormat); + samples = formatCaps.getNearestSamples(samples); + } + + // Context may be null in unit tests. + if (!context || !context->isWebGL1()) + { + setAttachmentImpl(context, type, binding, textureIndex, resource, numViews, baseViewIndex, + isMultiview, samples); + return; + } + + switch (binding) + { + case GL_DEPTH_STENCIL: + case GL_DEPTH_STENCIL_ATTACHMENT: + mState.mWebGLDepthStencilAttachment.attach( + context, type, binding, textureIndex, resource, numViews, baseViewIndex, + isMultiview, samples, mState.mFramebufferSerial); + break; + case GL_DEPTH: + case GL_DEPTH_ATTACHMENT: + mState.mWebGLDepthAttachment.attach(context, type, binding, textureIndex, resource, + numViews, baseViewIndex, isMultiview, samples, + mState.mFramebufferSerial); + break; + case GL_STENCIL: + case GL_STENCIL_ATTACHMENT: + mState.mWebGLStencilAttachment.attach(context, type, binding, textureIndex, resource, + numViews, baseViewIndex, isMultiview, samples, + mState.mFramebufferSerial); + break; + default: + setAttachmentImpl(context, type, binding, textureIndex, resource, numViews, + baseViewIndex, isMultiview, samples); + return; + } + + commitWebGL1DepthStencilIfConsistent(context, numViews, baseViewIndex, isMultiview, samples); +} + +void Framebuffer::setAttachmentMultiview(const Context *context, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource, + GLsizei numViews, + GLint baseViewIndex) +{ + setAttachment(context, type, binding, textureIndex, resource, numViews, baseViewIndex, true, + FramebufferAttachment::kDefaultRenderToTextureSamples); +} + +void Framebuffer::commitWebGL1DepthStencilIfConsistent(const Context *context, + GLsizei numViews, + GLuint baseViewIndex, + bool isMultiview, + GLsizei samples) +{ + int count = 0; + + std::array attachments = {{&mState.mWebGLDepthStencilAttachment, + &mState.mWebGLDepthAttachment, + &mState.mWebGLStencilAttachment}}; + for (FramebufferAttachment *attachment : attachments) + { + if (attachment->isAttached()) + { + count++; + } + } + + mState.mWebGLDepthStencilConsistent = (count <= 1); + if (!mState.mWebGLDepthStencilConsistent) + { + // Inconsistent. + return; + } + + auto getImageIndexIfTextureAttachment = [](const FramebufferAttachment &attachment) { + if (attachment.type() == GL_TEXTURE) + { + return attachment.getTextureImageIndex(); + } + else + { + return ImageIndex(); + } + }; + + if (mState.mWebGLDepthAttachment.isAttached()) + { + const auto &depth = mState.mWebGLDepthAttachment; + setAttachmentImpl(context, depth.type(), GL_DEPTH_ATTACHMENT, + getImageIndexIfTextureAttachment(depth), depth.getResource(), numViews, + baseViewIndex, isMultiview, samples); + setAttachmentImpl(context, GL_NONE, GL_STENCIL_ATTACHMENT, ImageIndex(), nullptr, numViews, + baseViewIndex, isMultiview, samples); + } + else if (mState.mWebGLStencilAttachment.isAttached()) + { + const auto &stencil = mState.mWebGLStencilAttachment; + setAttachmentImpl(context, GL_NONE, GL_DEPTH_ATTACHMENT, ImageIndex(), nullptr, numViews, + baseViewIndex, isMultiview, samples); + setAttachmentImpl(context, stencil.type(), GL_STENCIL_ATTACHMENT, + getImageIndexIfTextureAttachment(stencil), stencil.getResource(), + numViews, baseViewIndex, isMultiview, samples); + } + else if (mState.mWebGLDepthStencilAttachment.isAttached()) + { + const auto &depthStencil = mState.mWebGLDepthStencilAttachment; + setAttachmentImpl(context, depthStencil.type(), GL_DEPTH_ATTACHMENT, + getImageIndexIfTextureAttachment(depthStencil), + depthStencil.getResource(), numViews, baseViewIndex, isMultiview, + samples); + setAttachmentImpl(context, depthStencil.type(), GL_STENCIL_ATTACHMENT, + getImageIndexIfTextureAttachment(depthStencil), + depthStencil.getResource(), numViews, baseViewIndex, isMultiview, + samples); + } + else + { + setAttachmentImpl(context, GL_NONE, GL_DEPTH_ATTACHMENT, ImageIndex(), nullptr, numViews, + baseViewIndex, isMultiview, samples); + setAttachmentImpl(context, GL_NONE, GL_STENCIL_ATTACHMENT, ImageIndex(), nullptr, numViews, + baseViewIndex, isMultiview, samples); + } +} + +void Framebuffer::setAttachmentImpl(const Context *context, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource, + GLsizei numViews, + GLuint baseViewIndex, + bool isMultiview, + GLsizei samples) +{ + switch (binding) + { + case GL_DEPTH_STENCIL: + case GL_DEPTH_STENCIL_ATTACHMENT: + updateAttachment(context, &mState.mDepthAttachment, DIRTY_BIT_DEPTH_ATTACHMENT, + &mDirtyDepthAttachmentBinding, type, binding, textureIndex, resource, + numViews, baseViewIndex, isMultiview, samples); + updateAttachment(context, &mState.mStencilAttachment, DIRTY_BIT_STENCIL_ATTACHMENT, + &mDirtyStencilAttachmentBinding, type, binding, textureIndex, resource, + numViews, baseViewIndex, isMultiview, samples); + break; + + case GL_DEPTH: + case GL_DEPTH_ATTACHMENT: + updateAttachment(context, &mState.mDepthAttachment, DIRTY_BIT_DEPTH_ATTACHMENT, + &mDirtyDepthAttachmentBinding, type, binding, textureIndex, resource, + numViews, baseViewIndex, isMultiview, samples); + break; + + case GL_STENCIL: + case GL_STENCIL_ATTACHMENT: + updateAttachment(context, &mState.mStencilAttachment, DIRTY_BIT_STENCIL_ATTACHMENT, + &mDirtyStencilAttachmentBinding, type, binding, textureIndex, resource, + numViews, baseViewIndex, isMultiview, samples); + break; + + case GL_BACK: + updateAttachment(context, &mState.mColorAttachments[0], DIRTY_BIT_COLOR_ATTACHMENT_0, + &mDirtyColorAttachmentBindings[0], type, binding, textureIndex, + resource, numViews, baseViewIndex, isMultiview, samples); + mState.mColorAttachmentsMask.set(0); + + break; + + default: + { + size_t colorIndex = binding - GL_COLOR_ATTACHMENT0; + ASSERT(colorIndex < mState.mColorAttachments.size()); + size_t dirtyBit = DIRTY_BIT_COLOR_ATTACHMENT_0 + colorIndex; + updateAttachment(context, &mState.mColorAttachments[colorIndex], dirtyBit, + &mDirtyColorAttachmentBindings[colorIndex], type, binding, + textureIndex, resource, numViews, baseViewIndex, isMultiview, samples); + + if (!resource) + { + mFloat32ColorAttachmentBits.reset(colorIndex); + mState.mColorAttachmentsMask.reset(colorIndex); + } + else + { + updateFloat32ColorAttachmentBits( + colorIndex, resource->getAttachmentFormat(binding, textureIndex).info); + mState.mColorAttachmentsMask.set(colorIndex); + } + + bool enabled = (type != GL_NONE && getDrawBufferState(colorIndex) != GL_NONE); + mState.mEnabledDrawBuffers.set(colorIndex, enabled); + SetComponentTypeMask(getDrawbufferWriteType(colorIndex), colorIndex, + &mState.mDrawBufferTypeMask); + } + break; + } +} + +void Framebuffer::updateAttachment(const Context *context, + FramebufferAttachment *attachment, + size_t dirtyBit, + angle::ObserverBinding *onDirtyBinding, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource, + GLsizei numViews, + GLuint baseViewIndex, + bool isMultiview, + GLsizei samples) +{ + attachment->attach(context, type, binding, textureIndex, resource, numViews, baseViewIndex, + isMultiview, samples, mState.mFramebufferSerial); + mDirtyBits.set(dirtyBit); + mState.mResourceNeedsInit.set(dirtyBit, attachment->initState() == InitState::MayNeedInit); + onDirtyBinding->bind(resource); + + invalidateCompletenessCache(); +} + +void Framebuffer::resetAttachment(const Context *context, GLenum binding) +{ + setAttachment(context, GL_NONE, binding, ImageIndex(), nullptr); +} + +void Framebuffer::setWriteControlMode(SrgbWriteControlMode srgbWriteControlMode) +{ + if (srgbWriteControlMode != mState.getWriteControlMode()) + { + mState.mSrgbWriteControlMode = srgbWriteControlMode; + mDirtyBits.set(DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE); + } +} + +angle::Result Framebuffer::syncState(const Context *context, + GLenum framebufferBinding, + Command command) const +{ + if (mDirtyBits.any()) + { + mDirtyBitsGuard = mDirtyBits; + ANGLE_TRY(mImpl->syncState(context, framebufferBinding, mDirtyBits, command)); + mDirtyBits.reset(); + mDirtyBitsGuard.reset(); + } + return angle::Result::Continue; +} + +void Framebuffer::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) +{ + if (message != angle::SubjectMessage::SubjectChanged) + { + // This can be triggered by SubImage calls for Textures. + if (message == angle::SubjectMessage::ContentsChanged) + { + mDirtyBits.set(DIRTY_BIT_COLOR_BUFFER_CONTENTS_0 + index); + onStateChange(angle::SubjectMessage::DirtyBitsFlagged); + return; + } + + // Swapchain changes should only result in color buffer changes. + if (message == angle::SubjectMessage::SwapchainImageChanged) + { + if (index < DIRTY_BIT_COLOR_ATTACHMENT_MAX) + { + mDirtyBits.set(DIRTY_BIT_COLOR_BUFFER_CONTENTS_0 + index); + onStateChange(angle::SubjectMessage::DirtyBitsFlagged); + } + return; + } + + ASSERT(message != angle::SubjectMessage::BindingChanged); + + // This can be triggered by external changes to the default framebuffer. + if (message == angle::SubjectMessage::SurfaceChanged) + { + onStateChange(angle::SubjectMessage::SurfaceChanged); + return; + } + + // This can be triggered by freeing TextureStorage in D3D back-end. + if (message == angle::SubjectMessage::StorageReleased) + { + mDirtyBits.set(index); + invalidateCompletenessCache(); + return; + } + + // This can be triggered by the GL back-end TextureGL class. + ASSERT(message == angle::SubjectMessage::DirtyBitsFlagged); + return; + } + + ASSERT(!mDirtyBitsGuard.valid() || mDirtyBitsGuard.value().test(index)); + mDirtyBits.set(index); + + invalidateCompletenessCache(); + + FramebufferAttachment *attachment = getAttachmentFromSubjectIndex(index); + + // Mark the appropriate init flag. + mState.mResourceNeedsInit.set(index, attachment->initState() == InitState::MayNeedInit); + + // Update mFloat32ColorAttachmentBits Cache + if (index < DIRTY_BIT_COLOR_ATTACHMENT_MAX) + { + ASSERT(index != DIRTY_BIT_DEPTH_ATTACHMENT); + ASSERT(index != DIRTY_BIT_STENCIL_ATTACHMENT); + updateFloat32ColorAttachmentBits(index - DIRTY_BIT_COLOR_ATTACHMENT_0, + attachment->getFormat().info); + } +} + +FramebufferAttachment *Framebuffer::getAttachmentFromSubjectIndex(angle::SubjectIndex index) +{ + switch (index) + { + case DIRTY_BIT_DEPTH_ATTACHMENT: + return &mState.mDepthAttachment; + case DIRTY_BIT_STENCIL_ATTACHMENT: + return &mState.mStencilAttachment; + default: + size_t colorIndex = (index - DIRTY_BIT_COLOR_ATTACHMENT_0); + ASSERT(colorIndex < mState.mColorAttachments.size()); + return &mState.mColorAttachments[colorIndex]; + } +} + +bool Framebuffer::formsRenderingFeedbackLoopWith(const Context *context) const +{ + const State &glState = context->getState(); + const ProgramExecutable *executable = glState.getLinkedProgramExecutable(context); + + // In some error cases there may be no bound program or executable. + if (!executable) + return false; + + const ActiveTextureMask &activeTextures = executable->getActiveSamplersMask(); + const ActiveTextureTypeArray &textureTypes = executable->getActiveSamplerTypes(); + + for (size_t textureIndex : activeTextures) + { + unsigned int uintIndex = static_cast(textureIndex); + Texture *texture = glState.getSamplerTexture(uintIndex, textureTypes[textureIndex]); + const Sampler *sampler = glState.getSampler(uintIndex); + if (texture && texture->isSamplerComplete(context, sampler) && + texture->isBoundToFramebuffer(mState.mFramebufferSerial)) + { + // Check for level overlap. + for (const FramebufferAttachment &attachment : mState.mColorAttachments) + { + if (AttachmentOverlapsWithTexture(attachment, texture, sampler)) + { + return true; + } + } + + if (AttachmentOverlapsWithTexture(mState.mDepthAttachment, texture, sampler)) + { + return true; + } + + if (AttachmentOverlapsWithTexture(mState.mStencilAttachment, texture, sampler)) + { + return true; + } + } + } + + return false; +} + +bool Framebuffer::formsCopyingFeedbackLoopWith(TextureID copyTextureID, + GLint copyTextureLevel, + GLint copyTextureLayer) const +{ + if (mState.isDefault()) + { + // It seems impossible to form a texture copying feedback loop with the default FBO. + return false; + } + + const FramebufferAttachment *readAttachment = getReadColorAttachment(); + ASSERT(readAttachment); + + if (readAttachment->isTextureWithId(copyTextureID)) + { + const auto &imageIndex = readAttachment->getTextureImageIndex(); + if (imageIndex.getLevelIndex() == copyTextureLevel) + { + // Check 3D/Array texture layers. + return !imageIndex.hasLayer() || copyTextureLayer == ImageIndex::kEntireLevel || + imageIndex.getLayerIndex() == copyTextureLayer; + } + } + return false; +} + +GLint Framebuffer::getDefaultWidth() const +{ + return mState.getDefaultWidth(); +} + +GLint Framebuffer::getDefaultHeight() const +{ + return mState.getDefaultHeight(); +} + +GLint Framebuffer::getDefaultSamples() const +{ + return mState.getDefaultSamples(); +} + +bool Framebuffer::getDefaultFixedSampleLocations() const +{ + return mState.getDefaultFixedSampleLocations(); +} + +GLint Framebuffer::getDefaultLayers() const +{ + return mState.getDefaultLayers(); +} + +bool Framebuffer::getFlipY() const +{ + return mState.getFlipY(); +} + +void Framebuffer::setDefaultWidth(const Context *context, GLint defaultWidth) +{ + mState.mDefaultWidth = defaultWidth; + mDirtyBits.set(DIRTY_BIT_DEFAULT_WIDTH); + invalidateCompletenessCache(); +} + +void Framebuffer::setDefaultHeight(const Context *context, GLint defaultHeight) +{ + mState.mDefaultHeight = defaultHeight; + mDirtyBits.set(DIRTY_BIT_DEFAULT_HEIGHT); + invalidateCompletenessCache(); +} + +void Framebuffer::setDefaultSamples(const Context *context, GLint defaultSamples) +{ + mState.mDefaultSamples = defaultSamples; + mDirtyBits.set(DIRTY_BIT_DEFAULT_SAMPLES); + invalidateCompletenessCache(); +} + +void Framebuffer::setDefaultFixedSampleLocations(const Context *context, + bool defaultFixedSampleLocations) +{ + mState.mDefaultFixedSampleLocations = defaultFixedSampleLocations; + mDirtyBits.set(DIRTY_BIT_DEFAULT_FIXED_SAMPLE_LOCATIONS); + invalidateCompletenessCache(); +} + +void Framebuffer::setDefaultLayers(GLint defaultLayers) +{ + mState.mDefaultLayers = defaultLayers; + mDirtyBits.set(DIRTY_BIT_DEFAULT_LAYERS); +} + +void Framebuffer::setFlipY(bool flipY) +{ + mState.mFlipY = flipY; + mDirtyBits.set(DIRTY_BIT_FLIP_Y); + invalidateCompletenessCache(); +} + +GLsizei Framebuffer::getNumViews() const +{ + return mState.getNumViews(); +} + +GLint Framebuffer::getBaseViewIndex() const +{ + return mState.getBaseViewIndex(); +} + +bool Framebuffer::isMultiview() const +{ + return mState.isMultiview(); +} + +bool Framebuffer::readDisallowedByMultiview() const +{ + return (mState.isMultiview() && mState.getNumViews() > 1); +} + +angle::Result Framebuffer::ensureClearAttachmentsInitialized(const Context *context, + GLbitfield mask) +{ + const auto &glState = context->getState(); + if (!context->isRobustResourceInitEnabled() || glState.isRasterizerDiscardEnabled()) + { + return angle::Result::Continue; + } + + const DepthStencilState &depthStencil = glState.getDepthStencilState(); + + bool color = (mask & GL_COLOR_BUFFER_BIT) != 0 && !glState.allActiveDrawBufferChannelsMasked(); + bool depth = (mask & GL_DEPTH_BUFFER_BIT) != 0 && !depthStencil.isDepthMaskedOut(); + bool stencil = (mask & GL_STENCIL_BUFFER_BIT) != 0 && !depthStencil.isStencilMaskedOut(); + + if (!color && !depth && !stencil) + { + return angle::Result::Continue; + } + + if (partialClearNeedsInit(context, color, depth, stencil)) + { + ANGLE_TRY(ensureDrawAttachmentsInitialized(context)); + } + + // If the impl encounters an error during a a full (non-partial) clear, the attachments will + // still be marked initialized. This simplifies design, allowing this method to be called before + // the clear. + markDrawAttachmentsInitialized(color, depth, stencil); + + return angle::Result::Continue; +} + +angle::Result Framebuffer::ensureClearBufferAttachmentsInitialized(const Context *context, + GLenum buffer, + GLint drawbuffer) +{ + if (!context->isRobustResourceInitEnabled() || + context->getState().isRasterizerDiscardEnabled() || + context->isClearBufferMaskedOut(buffer, drawbuffer)) + { + return angle::Result::Continue; + } + + if (partialBufferClearNeedsInit(context, buffer)) + { + ANGLE_TRY(ensureBufferInitialized(context, buffer, drawbuffer)); + } + + // If the impl encounters an error during a a full (non-partial) clear, the attachments will + // still be marked initialized. This simplifies design, allowing this method to be called before + // the clear. + markBufferInitialized(buffer, drawbuffer); + + return angle::Result::Continue; +} + +angle::Result Framebuffer::ensureDrawAttachmentsInitialized(const Context *context) +{ + if (!context->isRobustResourceInitEnabled()) + { + return angle::Result::Continue; + } + + // Note: we don't actually filter by the draw attachment enum. Just init everything. + for (size_t bit : mState.mResourceNeedsInit) + { + switch (bit) + { + case DIRTY_BIT_DEPTH_ATTACHMENT: + ANGLE_TRY(InitAttachment(context, &mState.mDepthAttachment)); + break; + case DIRTY_BIT_STENCIL_ATTACHMENT: + ANGLE_TRY(InitAttachment(context, &mState.mStencilAttachment)); + break; + default: + ANGLE_TRY(InitAttachment(context, &mState.mColorAttachments[bit])); + break; + } + } + + mState.mResourceNeedsInit.reset(); + return angle::Result::Continue; +} + +angle::Result Framebuffer::ensureReadAttachmentsInitialized(const Context *context) +{ + ASSERT(context->isRobustResourceInitEnabled()); + + if (mState.mResourceNeedsInit.none()) + { + return angle::Result::Continue; + } + + if (mState.mReadBufferState != GL_NONE) + { + if (isDefault()) + { + if (!mState.mDefaultFramebufferReadAttachmentInitialized) + { + ANGLE_TRY(InitAttachment(context, &mState.mDefaultFramebufferReadAttachment)); + mState.mDefaultFramebufferReadAttachmentInitialized = true; + } + } + else + { + size_t readIndex = mState.getReadIndex(); + if (mState.mResourceNeedsInit[readIndex]) + { + ANGLE_TRY(InitAttachment(context, &mState.mColorAttachments[readIndex])); + mState.mResourceNeedsInit.reset(readIndex); + } + } + } + + // Conservatively init depth since it can be read by BlitFramebuffer. + if (hasDepth()) + { + if (mState.mResourceNeedsInit[DIRTY_BIT_DEPTH_ATTACHMENT]) + { + ANGLE_TRY(InitAttachment(context, &mState.mDepthAttachment)); + mState.mResourceNeedsInit.reset(DIRTY_BIT_DEPTH_ATTACHMENT); + } + } + + // Conservatively init stencil since it can be read by BlitFramebuffer. + if (hasStencil()) + { + if (mState.mResourceNeedsInit[DIRTY_BIT_STENCIL_ATTACHMENT]) + { + ANGLE_TRY(InitAttachment(context, &mState.mStencilAttachment)); + mState.mResourceNeedsInit.reset(DIRTY_BIT_STENCIL_ATTACHMENT); + } + } + + return angle::Result::Continue; +} + +void Framebuffer::markDrawAttachmentsInitialized(bool color, bool depth, bool stencil) +{ + // Mark attachments as initialized. + if (color) + { + for (auto colorIndex : mState.mEnabledDrawBuffers) + { + auto &colorAttachment = mState.mColorAttachments[colorIndex]; + ASSERT(colorAttachment.isAttached()); + colorAttachment.setInitState(InitState::Initialized); + mState.mResourceNeedsInit.reset(colorIndex); + } + } + + if (depth && mState.mDepthAttachment.isAttached()) + { + mState.mDepthAttachment.setInitState(InitState::Initialized); + mState.mResourceNeedsInit.reset(DIRTY_BIT_DEPTH_ATTACHMENT); + } + + if (stencil && mState.mStencilAttachment.isAttached()) + { + mState.mStencilAttachment.setInitState(InitState::Initialized); + mState.mResourceNeedsInit.reset(DIRTY_BIT_STENCIL_ATTACHMENT); + } +} + +void Framebuffer::markBufferInitialized(GLenum bufferType, GLint bufferIndex) +{ + switch (bufferType) + { + case GL_COLOR: + { + ASSERT(bufferIndex < static_cast(mState.mColorAttachments.size())); + if (mState.mColorAttachments[bufferIndex].isAttached()) + { + mState.mColorAttachments[bufferIndex].setInitState(InitState::Initialized); + mState.mResourceNeedsInit.reset(bufferIndex); + } + break; + } + case GL_DEPTH: + { + if (mState.mDepthAttachment.isAttached()) + { + mState.mDepthAttachment.setInitState(InitState::Initialized); + mState.mResourceNeedsInit.reset(DIRTY_BIT_DEPTH_ATTACHMENT); + } + break; + } + case GL_STENCIL: + { + if (mState.mStencilAttachment.isAttached()) + { + mState.mStencilAttachment.setInitState(InitState::Initialized); + mState.mResourceNeedsInit.reset(DIRTY_BIT_STENCIL_ATTACHMENT); + } + break; + } + case GL_DEPTH_STENCIL: + { + if (mState.mDepthAttachment.isAttached()) + { + mState.mDepthAttachment.setInitState(InitState::Initialized); + mState.mResourceNeedsInit.reset(DIRTY_BIT_DEPTH_ATTACHMENT); + } + if (mState.mStencilAttachment.isAttached()) + { + mState.mStencilAttachment.setInitState(InitState::Initialized); + mState.mResourceNeedsInit.reset(DIRTY_BIT_STENCIL_ATTACHMENT); + } + break; + } + default: + UNREACHABLE(); + break; + } +} + +Box Framebuffer::getDimensions() const +{ + return mState.getDimensions(); +} + +Extents Framebuffer::getExtents() const +{ + return mState.getExtents(); +} + +angle::Result Framebuffer::ensureBufferInitialized(const Context *context, + GLenum bufferType, + GLint bufferIndex) +{ + ASSERT(context->isRobustResourceInitEnabled()); + + if (mState.mResourceNeedsInit.none()) + { + return angle::Result::Continue; + } + + switch (bufferType) + { + case GL_COLOR: + { + ASSERT(bufferIndex < static_cast(mState.mColorAttachments.size())); + if (mState.mResourceNeedsInit[bufferIndex]) + { + ANGLE_TRY(InitAttachment(context, &mState.mColorAttachments[bufferIndex])); + mState.mResourceNeedsInit.reset(bufferIndex); + } + break; + } + case GL_DEPTH: + { + if (mState.mResourceNeedsInit[DIRTY_BIT_DEPTH_ATTACHMENT]) + { + ANGLE_TRY(InitAttachment(context, &mState.mDepthAttachment)); + mState.mResourceNeedsInit.reset(DIRTY_BIT_DEPTH_ATTACHMENT); + } + break; + } + case GL_STENCIL: + { + if (mState.mResourceNeedsInit[DIRTY_BIT_STENCIL_ATTACHMENT]) + { + ANGLE_TRY(InitAttachment(context, &mState.mStencilAttachment)); + mState.mResourceNeedsInit.reset(DIRTY_BIT_STENCIL_ATTACHMENT); + } + break; + } + case GL_DEPTH_STENCIL: + { + if (mState.mResourceNeedsInit[DIRTY_BIT_DEPTH_ATTACHMENT]) + { + ANGLE_TRY(InitAttachment(context, &mState.mDepthAttachment)); + mState.mResourceNeedsInit.reset(DIRTY_BIT_DEPTH_ATTACHMENT); + } + if (mState.mResourceNeedsInit[DIRTY_BIT_STENCIL_ATTACHMENT]) + { + ANGLE_TRY(InitAttachment(context, &mState.mStencilAttachment)); + mState.mResourceNeedsInit.reset(DIRTY_BIT_STENCIL_ATTACHMENT); + } + break; + } + default: + UNREACHABLE(); + break; + } + + return angle::Result::Continue; +} + +bool Framebuffer::partialBufferClearNeedsInit(const Context *context, GLenum bufferType) +{ + if (!context->isRobustResourceInitEnabled() || mState.mResourceNeedsInit.none()) + { + return false; + } + + switch (bufferType) + { + case GL_COLOR: + return partialClearNeedsInit(context, true, false, false); + case GL_DEPTH: + return partialClearNeedsInit(context, false, true, false); + case GL_STENCIL: + return partialClearNeedsInit(context, false, false, true); + case GL_DEPTH_STENCIL: + return partialClearNeedsInit(context, false, true, true); + default: + UNREACHABLE(); + return false; + } +} + +PixelLocalStorage &Framebuffer::getPixelLocalStorage(const Context *context) +{ + if (!mPixelLocalStorage) + { + mPixelLocalStorage = PixelLocalStorage::Make(context); + } + return *mPixelLocalStorage.get(); +} + +std::unique_ptr Framebuffer::detachPixelLocalStorage() +{ + return std::move(mPixelLocalStorage); +} +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/Framebuffer.h b/gfx/angle/checkout/src/libANGLE/Framebuffer.h new file mode 100644 index 0000000000..024ad49687 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Framebuffer.h @@ -0,0 +1,538 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Framebuffer.h: Defines the gl::Framebuffer class. Implements GL framebuffer +// objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105. + +#ifndef LIBANGLE_FRAMEBUFFER_H_ +#define LIBANGLE_FRAMEBUFFER_H_ + +#include + +#include "common/FixedVector.h" +#include "common/Optional.h" +#include "common/angleutils.h" +#include "libANGLE/Constants.h" +#include "libANGLE/Debug.h" +#include "libANGLE/Error.h" +#include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/Observer.h" +#include "libANGLE/RefCountObject.h" +#include "libANGLE/State.h" +#include "libANGLE/angletypes.h" + +namespace rx +{ +class GLImplFactory; +class FramebufferImpl; +class RenderbufferImpl; +class SurfaceImpl; +} // namespace rx + +namespace egl +{ +class Display; +class Surface; +} // namespace egl + +namespace gl +{ +struct Caps; +class Context; +struct Extensions; +class Framebuffer; +class ImageIndex; +class PixelLocalStorage; +class Renderbuffer; +class TextureCapsMap; + +struct FramebufferStatus +{ + bool isComplete() const; + + static FramebufferStatus Complete(); + static FramebufferStatus Incomplete(GLenum status, const char *reason); + + GLenum status = GL_FRAMEBUFFER_COMPLETE; + const char *reason = nullptr; +}; + +class FramebufferState final : angle::NonCopyable +{ + public: + explicit FramebufferState(rx::Serial serial); + FramebufferState(const Caps &caps, FramebufferID id, rx::Serial serial); + ~FramebufferState(); + + const std::string &getLabel() const; + uint32_t getReadIndex() const; + + const FramebufferAttachment *getAttachment(const Context *context, GLenum attachment) const; + const FramebufferAttachment *getReadAttachment() const; + const FramebufferAttachment *getFirstNonNullAttachment() const; + const FramebufferAttachment *getFirstColorAttachment() const; + const FramebufferAttachment *getDepthOrStencilAttachment() const; + const FramebufferAttachment *getStencilOrDepthStencilAttachment() const; + const FramebufferAttachment *getColorAttachment(size_t colorAttachment) const; + const FramebufferAttachment *getDepthAttachment() const; + const FramebufferAttachment *getStencilAttachment() const; + const FramebufferAttachment *getDepthStencilAttachment() const; + const FramebufferAttachment *getReadPixelsAttachment(GLenum readFormat) const; + + const DrawBuffersVector &getDrawBufferStates() const { return mDrawBufferStates; } + DrawBufferMask getEnabledDrawBuffers() const { return mEnabledDrawBuffers; } + GLenum getReadBufferState() const { return mReadBufferState; } + + const DrawBuffersVector &getColorAttachments() const + { + return mColorAttachments; + } + const DrawBufferMask getColorAttachmentsMask() const { return mColorAttachmentsMask; } + + const Extents getAttachmentExtentsIntersection() const; + bool attachmentsHaveSameDimensions() const; + bool hasSeparateDepthAndStencilAttachments() const; + bool colorAttachmentsAreUniqueImages() const; + Box getDimensions() const; + Extents getExtents() const; + + const FramebufferAttachment *getDrawBuffer(size_t drawBufferIdx) const; + size_t getDrawBufferCount() const; + + GLint getDefaultWidth() const { return mDefaultWidth; } + GLint getDefaultHeight() const { return mDefaultHeight; } + GLint getDefaultSamples() const { return mDefaultSamples; } + bool getDefaultFixedSampleLocations() const { return mDefaultFixedSampleLocations; } + GLint getDefaultLayers() const { return mDefaultLayers; } + bool getFlipY() const { return mFlipY; } + + bool hasDepth() const; + bool hasStencil() const; + + bool hasExternalTextureAttachment() const; + bool hasYUVAttachment() const; + + bool isMultiview() const; + + ANGLE_INLINE GLsizei getNumViews() const + { + const FramebufferAttachment *attachment = getFirstNonNullAttachment(); + if (attachment == nullptr) + { + return FramebufferAttachment::kDefaultNumViews; + } + return attachment->getNumViews(); + } + + GLint getBaseViewIndex() const; + + SrgbWriteControlMode getWriteControlMode() const { return mSrgbWriteControlMode; } + + FramebufferID id() const { return mId; } + + bool isDefault() const; + + const Offset &getSurfaceTextureOffset() const { return mSurfaceTextureOffset; } + + rx::Serial getFramebufferSerial() const { return mFramebufferSerial; } + + bool isBoundAsDrawFramebuffer(const Context *context) const; + + private: + const FramebufferAttachment *getWebGLDepthStencilAttachment() const; + const FramebufferAttachment *getWebGLDepthAttachment() const; + const FramebufferAttachment *getWebGLStencilAttachment() const; + + friend class Framebuffer; + + // The Framebuffer ID is unique to a Context. + // The Framebuffer Serial is unique to a Share Group. + FramebufferID mId; + rx::Serial mFramebufferSerial; + std::string mLabel; + + DrawBuffersVector mColorAttachments; + FramebufferAttachment mDepthAttachment; + FramebufferAttachment mStencilAttachment; + + // Tracks all the color buffers attached to this FramebufferDesc + DrawBufferMask mColorAttachmentsMask; + + DrawBuffersVector mDrawBufferStates; + GLenum mReadBufferState; + DrawBufferMask mEnabledDrawBuffers; + ComponentTypeMask mDrawBufferTypeMask; + + GLint mDefaultWidth; + GLint mDefaultHeight; + GLint mDefaultSamples; + bool mDefaultFixedSampleLocations; + GLint mDefaultLayers; + bool mFlipY; + + // It's necessary to store all this extra state so we can restore attachments + // when DEPTH_STENCIL/DEPTH/STENCIL is unbound in WebGL 1. + FramebufferAttachment mWebGLDepthStencilAttachment; + FramebufferAttachment mWebGLDepthAttachment; + FramebufferAttachment mWebGLStencilAttachment; + bool mWebGLDepthStencilConsistent; + + // Tracks if we need to initialize the resources for each attachment. + angle::BitSet mResourceNeedsInit; + + bool mDefaultFramebufferReadAttachmentInitialized; + FramebufferAttachment mDefaultFramebufferReadAttachment; + + // EXT_sRGB_write_control + SrgbWriteControlMode mSrgbWriteControlMode; + + Offset mSurfaceTextureOffset; +}; + +class Framebuffer final : public angle::ObserverInterface, + public LabeledObject, + public angle::Subject +{ + public: + // Constructor to build default framebuffers. + Framebuffer(const Context *context, rx::GLImplFactory *factory); + // Constructor to build application-defined framebuffers + Framebuffer(const Context *context, rx::GLImplFactory *factory, FramebufferID id); + + ~Framebuffer() override; + void onDestroy(const Context *context); + + egl::Error setSurfaces(const Context *context, + egl::Surface *surface, + egl::Surface *readSurface); + void setReadSurface(const Context *context, egl::Surface *readSurface); + egl::Error unsetSurfaces(const Context *context); + angle::Result setLabel(const Context *context, const std::string &label) override; + const std::string &getLabel() const override; + + rx::FramebufferImpl *getImplementation() const { return mImpl; } + + FramebufferID id() const { return mState.mId; } + + void setAttachment(const Context *context, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource); + void setAttachmentMultisample(const Context *context, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource, + GLsizei samples); + void setAttachmentMultiview(const Context *context, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource, + GLsizei numViews, + GLint baseViewIndex); + void resetAttachment(const Context *context, GLenum binding); + + bool detachTexture(const Context *context, TextureID texture); + bool detachRenderbuffer(const Context *context, RenderbufferID renderbuffer); + + const FramebufferAttachment *getColorAttachment(size_t colorAttachment) const; + const FramebufferAttachment *getDepthAttachment() const; + const FramebufferAttachment *getStencilAttachment() const; + const FramebufferAttachment *getDepthStencilAttachment() const; + const FramebufferAttachment *getDepthOrStencilAttachment() const; + const FramebufferAttachment *getStencilOrDepthStencilAttachment() const; + const FramebufferAttachment *getReadColorAttachment() const; + GLenum getReadColorAttachmentType() const; + const FramebufferAttachment *getFirstColorAttachment() const; + const FramebufferAttachment *getFirstNonNullAttachment() const; + + const DrawBuffersVector &getColorAttachments() const + { + return mState.mColorAttachments; + } + + const FramebufferState &getState() const { return mState; } + + const FramebufferAttachment *getAttachment(const Context *context, GLenum attachment) const; + bool isMultiview() const; + bool readDisallowedByMultiview() const; + GLsizei getNumViews() const; + GLint getBaseViewIndex() const; + Extents getExtents() const; + + size_t getDrawbufferStateCount() const; + GLenum getDrawBufferState(size_t drawBuffer) const; + const DrawBuffersVector &getDrawBufferStates() const; + void setDrawBuffers(size_t count, const GLenum *buffers); + const FramebufferAttachment *getDrawBuffer(size_t drawBuffer) const; + ComponentType getDrawbufferWriteType(size_t drawBuffer) const; + ComponentTypeMask getDrawBufferTypeMask() const; + DrawBufferMask getDrawBufferMask() const; + bool hasEnabledDrawBuffer() const; + + GLenum getReadBufferState() const; + void setReadBuffer(GLenum buffer); + + size_t getNumColorAttachments() const; + bool hasDepth() const; + bool hasStencil() const; + + bool hasExternalTextureAttachment() const; + bool hasYUVAttachment() const; + + bool usingExtendedDrawBuffers() const; + + // This method calls checkStatus. + int getSamples(const Context *context) const; + int getReadBufferResourceSamples(const Context *context) const; + + angle::Result getSamplePosition(const Context *context, size_t index, GLfloat *xy) const; + + GLint getDefaultWidth() const; + GLint getDefaultHeight() const; + GLint getDefaultSamples() const; + bool getDefaultFixedSampleLocations() const; + GLint getDefaultLayers() const; + bool getFlipY() const; + void setDefaultWidth(const Context *context, GLint defaultWidth); + void setDefaultHeight(const Context *context, GLint defaultHeight); + void setDefaultSamples(const Context *context, GLint defaultSamples); + void setDefaultFixedSampleLocations(const Context *context, bool defaultFixedSampleLocations); + void setDefaultLayers(GLint defaultLayers); + void setFlipY(bool flipY); + + void invalidateCompletenessCache(); + ANGLE_INLINE bool cachedStatusValid() { return mCachedStatus.valid(); } + + ANGLE_INLINE const FramebufferStatus &checkStatus(const Context *context) const + { + // The default framebuffer is always complete except when it is surfaceless in which + // case it is always unsupported. + ASSERT(!isDefault() || mCachedStatus.valid()); + if (isDefault() || (!hasAnyDirtyBit() && mCachedStatus.valid())) + { + return mCachedStatus.value(); + } + + return checkStatusImpl(context); + } + + // Helper for checkStatus == GL_FRAMEBUFFER_COMPLETE. + ANGLE_INLINE bool isComplete(const Context *context) const + { + return checkStatus(context).isComplete(); + } + + bool hasValidDepthStencil() const; + + // Returns the offset into the texture backing the default framebuffer's surface if any. Returns + // zero offset otherwise. The renderer will apply the offset to scissor and viewport rects used + // for draws, clears, and blits. + const Offset &getSurfaceTextureOffset() const; + + angle::Result discard(const Context *context, size_t count, const GLenum *attachments); + angle::Result invalidate(const Context *context, size_t count, const GLenum *attachments); + angle::Result invalidateSub(const Context *context, + size_t count, + const GLenum *attachments, + const Rectangle &area); + + angle::Result clear(const Context *context, GLbitfield mask); + angle::Result clearBufferfv(const Context *context, + GLenum buffer, + GLint drawbuffer, + const GLfloat *values); + angle::Result clearBufferuiv(const Context *context, + GLenum buffer, + GLint drawbuffer, + const GLuint *values); + angle::Result clearBufferiv(const Context *context, + GLenum buffer, + GLint drawbuffer, + const GLint *values); + angle::Result clearBufferfi(const Context *context, + GLenum buffer, + GLint drawbuffer, + GLfloat depth, + GLint stencil); + + GLenum getImplementationColorReadFormat(const Context *context); + GLenum getImplementationColorReadType(const Context *context); + + angle::Result readPixels(const Context *context, + const Rectangle &area, + GLenum format, + GLenum type, + const PixelPackState &pack, + Buffer *packBuffer, + void *pixels); + + angle::Result blit(const Context *context, + const Rectangle &sourceArea, + const Rectangle &destArea, + GLbitfield mask, + GLenum filter); + bool isDefault() const { return mState.isDefault(); } + + enum DirtyBitType : size_t + { + DIRTY_BIT_COLOR_ATTACHMENT_0, + DIRTY_BIT_COLOR_ATTACHMENT_MAX = + DIRTY_BIT_COLOR_ATTACHMENT_0 + IMPLEMENTATION_MAX_DRAW_BUFFERS, + DIRTY_BIT_DEPTH_ATTACHMENT = DIRTY_BIT_COLOR_ATTACHMENT_MAX, + DIRTY_BIT_STENCIL_ATTACHMENT, + DIRTY_BIT_COLOR_BUFFER_CONTENTS_0, + DIRTY_BIT_COLOR_BUFFER_CONTENTS_MAX = + DIRTY_BIT_COLOR_BUFFER_CONTENTS_0 + IMPLEMENTATION_MAX_DRAW_BUFFERS, + DIRTY_BIT_DEPTH_BUFFER_CONTENTS = DIRTY_BIT_COLOR_BUFFER_CONTENTS_MAX, + DIRTY_BIT_STENCIL_BUFFER_CONTENTS, + DIRTY_BIT_DRAW_BUFFERS, + DIRTY_BIT_READ_BUFFER, + DIRTY_BIT_DEFAULT_WIDTH, + DIRTY_BIT_DEFAULT_HEIGHT, + DIRTY_BIT_DEFAULT_SAMPLES, + DIRTY_BIT_DEFAULT_FIXED_SAMPLE_LOCATIONS, + DIRTY_BIT_DEFAULT_LAYERS, + DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE, + DIRTY_BIT_FLIP_Y, + DIRTY_BIT_UNKNOWN, + DIRTY_BIT_MAX = DIRTY_BIT_UNKNOWN + }; + + using DirtyBits = angle::BitSet; + bool hasAnyDirtyBit() const { return mDirtyBits.any(); } + + DrawBufferMask getActiveFloat32ColorAttachmentDrawBufferMask() const + { + return mFloat32ColorAttachmentBits & getDrawBufferMask(); + } + + bool hasResourceThatNeedsInit() const { return mState.mResourceNeedsInit.any(); } + + angle::Result syncState(const Context *context, + GLenum framebufferBinding, + Command command) const; + + void setWriteControlMode(SrgbWriteControlMode srgbWriteControlMode); + + // Observer implementation + void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; + + bool formsRenderingFeedbackLoopWith(const Context *context) const; + bool formsCopyingFeedbackLoopWith(TextureID copyTextureID, + GLint copyTextureLevel, + GLint copyTextureLayer) const; + + angle::Result ensureClearAttachmentsInitialized(const Context *context, GLbitfield mask); + angle::Result ensureClearBufferAttachmentsInitialized(const Context *context, + GLenum buffer, + GLint drawbuffer); + angle::Result ensureDrawAttachmentsInitialized(const Context *context); + + // Conservatively initializes both read color and depth. Blit can access the depth buffer. + angle::Result ensureReadAttachmentsInitialized(const Context *context); + Box getDimensions() const; + + // ANGLE_shader_pixel_local_storage. + // Lazily creates a PixelLocalStorage object for this Framebuffer. + PixelLocalStorage &getPixelLocalStorage(const Context *); + // Returns nullptr if the pixel local storage object has not been created yet. + const PixelLocalStorage *peekPixelLocalStorage() const { return mPixelLocalStorage.get(); } + // Detaches the the pixel local storage object so the Context can call deleteContextObjects(). + std::unique_ptr detachPixelLocalStorage(); + + static const FramebufferID kDefaultDrawFramebufferHandle; + + private: + bool detachResourceById(const Context *context, GLenum resourceType, GLuint resourceId); + bool detachMatchingAttachment(const Context *context, + FramebufferAttachment *attachment, + GLenum matchType, + GLuint matchId); + FramebufferStatus checkStatusWithGLFrontEnd(const Context *context) const; + const FramebufferStatus &checkStatusImpl(const Context *context) const; + void setAttachment(const Context *context, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource, + GLsizei numViews, + GLuint baseViewIndex, + bool isMultiview, + GLsizei samplesIn); + void commitWebGL1DepthStencilIfConsistent(const Context *context, + GLsizei numViews, + GLuint baseViewIndex, + bool isMultiview, + GLsizei samples); + void setAttachmentImpl(const Context *context, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource, + GLsizei numViews, + GLuint baseViewIndex, + bool isMultiview, + GLsizei samples); + void updateAttachment(const Context *context, + FramebufferAttachment *attachment, + size_t dirtyBit, + angle::ObserverBinding *onDirtyBinding, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource, + GLsizei numViews, + GLuint baseViewIndex, + bool isMultiview, + GLsizei samples); + + void markDrawAttachmentsInitialized(bool color, bool depth, bool stencil); + void markBufferInitialized(GLenum bufferType, GLint bufferIndex); + angle::Result ensureBufferInitialized(const Context *context, + GLenum bufferType, + GLint bufferIndex); + + // Checks that we have a partially masked clear: + // * some color channels are masked out + // * some stencil values are masked out + // * scissor test partially overlaps the framebuffer + bool partialClearNeedsInit(const Context *context, bool color, bool depth, bool stencil); + bool partialBufferClearNeedsInit(const Context *context, GLenum bufferType); + + FramebufferAttachment *getAttachmentFromSubjectIndex(angle::SubjectIndex index); + + ANGLE_INLINE void updateFloat32ColorAttachmentBits(size_t index, const InternalFormat *format) + { + mFloat32ColorAttachmentBits.set(index, format->type == GL_FLOAT); + } + + FramebufferState mState; + rx::FramebufferImpl *mImpl; + + mutable Optional mCachedStatus; + DrawBuffersVector mDirtyColorAttachmentBindings; + angle::ObserverBinding mDirtyDepthAttachmentBinding; + angle::ObserverBinding mDirtyStencilAttachmentBinding; + + mutable DirtyBits mDirtyBits; + DrawBufferMask mFloat32ColorAttachmentBits; + + // The dirty bits guard is checked when we get a dependent state change message. We verify that + // we don't set a dirty bit that isn't already set, when inside the dirty bits syncState. + mutable Optional mDirtyBitsGuard; + + // ANGLE_shader_pixel_local_storage + std::unique_ptr mPixelLocalStorage; +}; + +using UniqueFramebufferPointer = angle::UniqueObjectPointer; + +} // namespace gl + +#endif // LIBANGLE_FRAMEBUFFER_H_ diff --git a/gfx/angle/checkout/src/libANGLE/FramebufferAttachment.cpp b/gfx/angle/checkout/src/libANGLE/FramebufferAttachment.cpp new file mode 100644 index 0000000000..6a3e88051f --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/FramebufferAttachment.cpp @@ -0,0 +1,350 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// FramebufferAttachment.cpp: the gl::FramebufferAttachment class and its derived classes +// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108. + +#include "libANGLE/FramebufferAttachment.h" + +#include "common/utilities.h" +#include "libANGLE/Config.h" +#include "libANGLE/Context.h" +#include "libANGLE/Renderbuffer.h" +#include "libANGLE/Surface.h" +#include "libANGLE/Texture.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/FramebufferAttachmentObjectImpl.h" +#include "libANGLE/renderer/FramebufferImpl.h" + +namespace gl +{ + +////// FramebufferAttachment::Target Implementation ////// + +const GLsizei FramebufferAttachment::kDefaultNumViews = 1; +const GLint FramebufferAttachment::kDefaultBaseViewIndex = 0; +const GLint FramebufferAttachment::kDefaultRenderToTextureSamples = 0; + +FramebufferAttachment::Target::Target() : mBinding(GL_NONE), mTextureIndex() {} + +FramebufferAttachment::Target::Target(GLenum binding, const ImageIndex &imageIndex) + : mBinding(binding), mTextureIndex(imageIndex) +{} + +FramebufferAttachment::Target::Target(const Target &other) + : mBinding(other.mBinding), mTextureIndex(other.mTextureIndex) +{} + +FramebufferAttachment::Target &FramebufferAttachment::Target::operator=(const Target &other) +{ + this->mBinding = other.mBinding; + this->mTextureIndex = other.mTextureIndex; + return *this; +} + +////// FramebufferAttachment Implementation ////// + +FramebufferAttachment::FramebufferAttachment() + : mType(GL_NONE), + mResource(nullptr), + mNumViews(kDefaultNumViews), + mIsMultiview(false), + mBaseViewIndex(kDefaultBaseViewIndex), + mRenderToTextureSamples(kDefaultRenderToTextureSamples) +{} + +FramebufferAttachment::FramebufferAttachment(const Context *context, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource, + rx::Serial framebufferSerial) + : mResource(nullptr) +{ + attach(context, type, binding, textureIndex, resource, kDefaultNumViews, kDefaultBaseViewIndex, + false, kDefaultRenderToTextureSamples, framebufferSerial); +} + +FramebufferAttachment::FramebufferAttachment(FramebufferAttachment &&other) + : FramebufferAttachment() +{ + *this = std::move(other); +} + +FramebufferAttachment &FramebufferAttachment::operator=(FramebufferAttachment &&other) +{ + std::swap(mType, other.mType); + std::swap(mTarget, other.mTarget); + std::swap(mResource, other.mResource); + std::swap(mNumViews, other.mNumViews); + std::swap(mIsMultiview, other.mIsMultiview); + std::swap(mBaseViewIndex, other.mBaseViewIndex); + std::swap(mRenderToTextureSamples, other.mRenderToTextureSamples); + return *this; +} + +FramebufferAttachment::~FramebufferAttachment() +{ + ASSERT(!isAttached()); +} + +void FramebufferAttachment::detach(const Context *context, rx::Serial framebufferSerial) +{ + mType = GL_NONE; + if (mResource != nullptr) + { + mResource->onDetach(context, framebufferSerial); + mResource = nullptr; + } + mNumViews = kDefaultNumViews; + mIsMultiview = false; + mBaseViewIndex = kDefaultBaseViewIndex; + + // not technically necessary, could omit for performance + mTarget = Target(); +} + +void FramebufferAttachment::attach(const Context *context, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource, + GLsizei numViews, + GLuint baseViewIndex, + bool isMultiview, + GLsizei samples, + rx::Serial framebufferSerial) +{ + if (resource == nullptr) + { + detach(context, framebufferSerial); + return; + } + + mType = type; + mTarget = Target(binding, textureIndex); + mNumViews = numViews; + mBaseViewIndex = baseViewIndex; + mIsMultiview = isMultiview; + mRenderToTextureSamples = type == GL_RENDERBUFFER ? kDefaultRenderToTextureSamples : samples; + resource->onAttach(context, framebufferSerial); + + if (mResource != nullptr) + { + mResource->onDetach(context, framebufferSerial); + } + + mResource = resource; +} + +GLuint FramebufferAttachment::getRedSize() const +{ + return getSize().empty() ? 0 : getFormat().info->redBits; +} + +GLuint FramebufferAttachment::getGreenSize() const +{ + return getSize().empty() ? 0 : getFormat().info->greenBits; +} + +GLuint FramebufferAttachment::getBlueSize() const +{ + return getSize().empty() ? 0 : getFormat().info->blueBits; +} + +GLuint FramebufferAttachment::getAlphaSize() const +{ + return getSize().empty() ? 0 : getFormat().info->alphaBits; +} + +GLuint FramebufferAttachment::getDepthSize() const +{ + return getSize().empty() ? 0 : getFormat().info->depthBits; +} + +GLuint FramebufferAttachment::getStencilSize() const +{ + return getSize().empty() ? 0 : getFormat().info->stencilBits; +} + +GLenum FramebufferAttachment::getComponentType() const +{ + return getFormat().info->componentType; +} + +GLenum FramebufferAttachment::getColorEncoding() const +{ + return getFormat().info->colorEncoding; +} + +GLuint FramebufferAttachment::id() const +{ + return mResource->getId(); +} + +TextureTarget FramebufferAttachment::cubeMapFace() const +{ + ASSERT(mType == GL_TEXTURE); + + const auto &index = mTarget.textureIndex(); + return index.getType() == TextureType::CubeMap ? index.getTarget() : TextureTarget::InvalidEnum; +} + +GLint FramebufferAttachment::mipLevel() const +{ + ASSERT(type() == GL_TEXTURE); + return mTarget.textureIndex().getLevelIndex(); +} + +GLint FramebufferAttachment::layer() const +{ + ASSERT(mType == GL_TEXTURE); + + const gl::ImageIndex &index = mTarget.textureIndex(); + return (index.has3DLayer() ? index.getLayerIndex() : 0); +} + +bool FramebufferAttachment::isLayered() const +{ + return mTarget.textureIndex().isLayered(); +} + +bool FramebufferAttachment::isMultiview() const +{ + return mIsMultiview; +} + +GLint FramebufferAttachment::getBaseViewIndex() const +{ + return mBaseViewIndex; +} + +bool FramebufferAttachment::isRenderToTexture() const +{ + ASSERT(mRenderToTextureSamples == kDefaultRenderToTextureSamples || mType == GL_TEXTURE); + + if (mType == GL_RENDERBUFFER) + { + return getRenderbuffer()->getMultisamplingMode() == + MultisamplingMode::MultisampledRenderToTexture; + } + return mRenderToTextureSamples != kDefaultRenderToTextureSamples; +} + +GLsizei FramebufferAttachment::getRenderToTextureSamples() const +{ + ASSERT(mRenderToTextureSamples == kDefaultRenderToTextureSamples || mType == GL_TEXTURE); + + if (mType == GL_RENDERBUFFER) + { + return getRenderbuffer()->getState().getSamples(); + } + return mRenderToTextureSamples; +} + +Texture *FramebufferAttachment::getTexture() const +{ + return rx::GetAs(mResource); +} + +Renderbuffer *FramebufferAttachment::getRenderbuffer() const +{ + return rx::GetAs(mResource); +} + +const egl::Surface *FramebufferAttachment::getSurface() const +{ + return rx::GetAs(mResource); +} + +FramebufferAttachmentObject *FramebufferAttachment::getResource() const +{ + return mResource; +} + +bool FramebufferAttachment::operator==(const FramebufferAttachment &other) const +{ + if (mResource != other.mResource || mType != other.mType || mNumViews != other.mNumViews || + mIsMultiview != other.mIsMultiview || mBaseViewIndex != other.mBaseViewIndex || + mRenderToTextureSamples != other.mRenderToTextureSamples) + { + return false; + } + + if (mType == GL_TEXTURE && getTextureImageIndex() != other.getTextureImageIndex()) + { + return false; + } + + return true; +} + +bool FramebufferAttachment::operator!=(const FramebufferAttachment &other) const +{ + return !(*this == other); +} + +InitState FramebufferAttachment::initState() const +{ + return mResource ? mResource->initState(mTarget.binding(), mTarget.textureIndex()) + : InitState::Initialized; +} + +angle::Result FramebufferAttachment::initializeContents(const Context *context) +{ + ASSERT(mResource); + ANGLE_TRY(mResource->initializeContents(context, mTarget.binding(), mTarget.textureIndex())); + setInitState(InitState::Initialized); + return angle::Result::Continue; +} + +void FramebufferAttachment::setInitState(InitState initState) const +{ + ASSERT(mResource); + mResource->setInitState(mTarget.binding(), mTarget.textureIndex(), initState); +} + +////// FramebufferAttachmentObject Implementation ////// + +FramebufferAttachmentObject::FramebufferAttachmentObject() {} + +FramebufferAttachmentObject::~FramebufferAttachmentObject() {} + +angle::Result FramebufferAttachmentObject::getAttachmentRenderTarget( + const Context *context, + GLenum binding, + const ImageIndex &imageIndex, + GLsizei samples, + rx::FramebufferAttachmentRenderTarget **rtOut) const +{ + return getAttachmentImpl()->getAttachmentRenderTarget(context, binding, imageIndex, samples, + rtOut); +} + +angle::Result FramebufferAttachmentObject::initializeContents(const Context *context, + GLenum binding, + const ImageIndex &imageIndex) +{ + ASSERT(context->isRobustResourceInitEnabled()); + + // Because gl::Texture cannot support tracking individual layer dirtiness, we only handle + // initializing entire mip levels for textures with layers + if (imageIndex.usesTex3D() && imageIndex.hasLayer()) + { + // Compute the layer count so we get a correct layer index. + const gl::Extents &size = getAttachmentSize(imageIndex); + + ImageIndex fullMipIndex = ImageIndex::MakeFromType( + imageIndex.getType(), imageIndex.getLevelIndex(), ImageIndex::kEntireLevel, size.depth); + return getAttachmentImpl()->initializeContents(context, binding, fullMipIndex); + } + else + { + return getAttachmentImpl()->initializeContents(context, binding, imageIndex); + } +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/FramebufferAttachment.h b/gfx/angle/checkout/src/libANGLE/FramebufferAttachment.h new file mode 100644 index 0000000000..8b4f04ae0b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/FramebufferAttachment.h @@ -0,0 +1,307 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// FramebufferAttachment.h: Defines the wrapper class gl::FramebufferAttachment, as well as the +// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108. + +#ifndef LIBANGLE_FRAMEBUFFERATTACHMENT_H_ +#define LIBANGLE_FRAMEBUFFERATTACHMENT_H_ + +#include "angle_gl.h" +#include "common/angleutils.h" +#include "libANGLE/Error.h" +#include "libANGLE/ImageIndex.h" +#include "libANGLE/Observer.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/FramebufferAttachmentObjectImpl.h" + +namespace egl +{ +class Surface; +} + +namespace rx +{ +// An implementation-specific object associated with an attachment. + +class FramebufferAttachmentRenderTarget : angle::NonCopyable +{ + public: + FramebufferAttachmentRenderTarget() {} + virtual ~FramebufferAttachmentRenderTarget() {} +}; + +class FramebufferAttachmentObjectImpl; +} // namespace rx + +namespace gl +{ +class FramebufferAttachmentObject; +class Renderbuffer; +class Texture; + +// FramebufferAttachment implements a GL framebuffer attachment. +// Attachments are "light" containers, which store pointers to ref-counted GL objects. +// We support GL texture (2D/3D/Cube/2D array) and renderbuffer object attachments. +// Note: Our old naming scheme used the term "Renderbuffer" for both GL renderbuffers and for +// framebuffer attachments, which confused their usage. + +class FramebufferAttachment final +{ + public: + FramebufferAttachment(); + + FramebufferAttachment(const Context *context, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource, + rx::Serial framebufferSerial); + + FramebufferAttachment(FramebufferAttachment &&other); + FramebufferAttachment &operator=(FramebufferAttachment &&other); + + ~FramebufferAttachment(); + + void detach(const Context *context, rx::Serial framebufferSerial); + void attach(const Context *context, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource, + GLsizei numViews, + GLuint baseViewIndex, + bool isMultiview, + GLsizei samples, + rx::Serial framebufferSerial); + + // Helper methods + GLuint getRedSize() const; + GLuint getGreenSize() const; + GLuint getBlueSize() const; + GLuint getAlphaSize() const; + GLuint getDepthSize() const; + GLuint getStencilSize() const; + GLenum getComponentType() const; + GLenum getColorEncoding() const; + + bool isTextureWithId(TextureID textureId) const + { + return mType == GL_TEXTURE && id() == textureId.value; + } + bool isExternalTexture() const + { + return mType == GL_TEXTURE && getTextureImageIndex().getType() == gl::TextureType::External; + } + bool isRenderbufferWithId(GLuint renderbufferId) const + { + return mType == GL_RENDERBUFFER && id() == renderbufferId; + } + + GLenum getBinding() const { return mTarget.binding(); } + GLuint id() const; + + // These methods are only legal to call on Texture attachments + const ImageIndex &getTextureImageIndex() const; + TextureTarget cubeMapFace() const; + GLint mipLevel() const; + GLint layer() const; + bool isLayered() const; + + GLsizei getNumViews() const { return mNumViews; } + + bool isMultiview() const; + GLint getBaseViewIndex() const; + + bool isRenderToTexture() const; + GLsizei getRenderToTextureSamples() const; + + // The size of the underlying resource the attachment points to. The 'depth' value will + // correspond to a 3D texture depth or the layer count of a 2D array texture. For Surfaces and + // Renderbuffers, it will always be 1. + Extents getSize() const; + Format getFormat() const; + GLsizei getSamples() const; + // This will always return the actual sample count of the attachment even if + // render_to_texture extension is active on this FBattachment object. + GLsizei getResourceSamples() const; + GLenum type() const { return mType; } + bool isAttached() const { return mType != GL_NONE; } + bool isRenderable(const Context *context) const; + bool isYUV() const; + bool isCreatedWithAHB() const; + + Renderbuffer *getRenderbuffer() const; + Texture *getTexture() const; + const egl::Surface *getSurface() const; + FramebufferAttachmentObject *getResource() const; + InitState initState() const; + angle::Result initializeContents(const Context *context); + void setInitState(InitState initState) const; + + // "T" must be static_castable from FramebufferAttachmentRenderTarget + template + angle::Result getRenderTarget(const Context *context, GLsizei samples, T **rtOut) const + { + static_assert(std::is_base_of(), + "Invalid RenderTarget class."); + return getRenderTargetImpl( + context, samples, reinterpret_cast(rtOut)); + } + + bool operator==(const FramebufferAttachment &other) const; + bool operator!=(const FramebufferAttachment &other) const; + + static const GLsizei kDefaultNumViews; + static const GLint kDefaultBaseViewIndex; + static const GLint kDefaultRenderToTextureSamples; + + private: + angle::Result getRenderTargetImpl(const Context *context, + GLsizei samples, + rx::FramebufferAttachmentRenderTarget **rtOut) const; + + // A framebuffer attachment points to one of three types of resources: Renderbuffers, + // Textures and egl::Surface. The "Target" struct indicates which part of the + // object an attachment references. For the three types: + // - a Renderbuffer has a unique renderable target, and needs no target index + // - a Texture has targets for every image and uses an ImageIndex + // - a Surface has targets for Color and Depth/Stencil, and uses the attachment binding + class Target + { + public: + Target(); + Target(GLenum binding, const ImageIndex &imageIndex); + Target(const Target &other); + Target &operator=(const Target &other); + + GLenum binding() const { return mBinding; } + const ImageIndex &textureIndex() const { return mTextureIndex; } + + private: + GLenum mBinding; + ImageIndex mTextureIndex; + }; + + GLenum mType; + Target mTarget; + FramebufferAttachmentObject *mResource; + GLsizei mNumViews; + bool mIsMultiview; + GLint mBaseViewIndex; + // A single-sampled texture can be attached to a framebuffer either as single-sampled or as + // multisampled-render-to-texture. In the latter case, |mRenderToTextureSamples| will contain + // the number of samples. For renderbuffers, the number of samples is inherited from the + // renderbuffer itself. + // + // Note that textures cannot change storage between single and multisample once attached to a + // framebuffer. Renderbuffers instead can, and caching the number of renderbuffer samples here + // can lead to stale data. + GLsizei mRenderToTextureSamples; +}; + +// A base class for objects that FBO Attachments may point to. +class FramebufferAttachmentObject : public angle::Subject, public angle::ObserverInterface +{ + public: + FramebufferAttachmentObject(); + ~FramebufferAttachmentObject() override; + + virtual Extents getAttachmentSize(const ImageIndex &imageIndex) const = 0; + virtual Format getAttachmentFormat(GLenum binding, const ImageIndex &imageIndex) const = 0; + virtual GLsizei getAttachmentSamples(const ImageIndex &imageIndex) const = 0; + virtual bool isRenderable(const Context *context, + GLenum binding, + const ImageIndex &imageIndex) const = 0; + virtual bool isYUV() const = 0; + virtual bool isCreatedWithAHB() const = 0; + virtual bool hasProtectedContent() const = 0; + + virtual void onAttach(const Context *context, rx::Serial framebufferSerial) = 0; + virtual void onDetach(const Context *context, rx::Serial framebufferSerial) = 0; + virtual GLuint getId() const = 0; + + // These are used for robust resource initialization. + virtual InitState initState(GLenum binding, const ImageIndex &imageIndex) const = 0; + virtual void setInitState(GLenum binding, + const ImageIndex &imageIndex, + InitState initState) = 0; + + angle::Result getAttachmentRenderTarget(const Context *context, + GLenum binding, + const ImageIndex &imageIndex, + GLsizei samples, + rx::FramebufferAttachmentRenderTarget **rtOut) const; + + angle::Result initializeContents(const Context *context, + GLenum binding, + const ImageIndex &imageIndex); + + protected: + virtual rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const = 0; +}; + +inline const ImageIndex &FramebufferAttachment::getTextureImageIndex() const +{ + ASSERT(type() == GL_TEXTURE); + return mTarget.textureIndex(); +} + +inline Extents FramebufferAttachment::getSize() const +{ + ASSERT(mResource); + return mResource->getAttachmentSize(mTarget.textureIndex()); +} + +inline Format FramebufferAttachment::getFormat() const +{ + ASSERT(mResource); + return mResource->getAttachmentFormat(mTarget.binding(), mTarget.textureIndex()); +} + +inline GLsizei FramebufferAttachment::getSamples() const +{ + return isRenderToTexture() ? getRenderToTextureSamples() : getResourceSamples(); +} + +inline GLsizei FramebufferAttachment::getResourceSamples() const +{ + ASSERT(mResource); + return mResource->getAttachmentSamples(mTarget.textureIndex()); +} + +inline angle::Result FramebufferAttachment::getRenderTargetImpl( + const Context *context, + GLsizei samples, + rx::FramebufferAttachmentRenderTarget **rtOut) const +{ + ASSERT(mResource); + return mResource->getAttachmentRenderTarget(context, mTarget.binding(), mTarget.textureIndex(), + samples, rtOut); +} + +inline bool FramebufferAttachment::isRenderable(const Context *context) const +{ + ASSERT(mResource); + return mResource->isRenderable(context, mTarget.binding(), mTarget.textureIndex()); +} + +inline bool FramebufferAttachment::isYUV() const +{ + ASSERT(mResource); + return mResource->isYUV(); +} + +inline bool FramebufferAttachment::isCreatedWithAHB() const +{ + ASSERT(mResource); + return mResource->isCreatedWithAHB(); +} + +} // namespace gl + +#endif // LIBANGLE_FRAMEBUFFERATTACHMENT_H_ diff --git a/gfx/angle/checkout/src/libANGLE/GLES1Renderer.cpp b/gfx/angle/checkout/src/libANGLE/GLES1Renderer.cpp new file mode 100644 index 0000000000..4ca3d47189 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/GLES1Renderer.cpp @@ -0,0 +1,1197 @@ +// +// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// GLES1Renderer.cpp: Implements the GLES1Renderer renderer. + +#include "libANGLE/GLES1Renderer.h" + +#include +#include +#include +#include + +#include "common/hash_utils.h" +#include "libANGLE/Context.h" +#include "libANGLE/Context.inl.h" +#include "libANGLE/Program.h" +#include "libANGLE/ResourceManager.h" +#include "libANGLE/Shader.h" +#include "libANGLE/State.h" +#include "libANGLE/renderer/ContextImpl.h" + +namespace +{ +#include "libANGLE/GLES1Shaders.inc" + +uint32_t GetLogicOpUniform(const gl::FramebufferAttachment *color, gl::LogicalOperation logicOp) +{ + const uint32_t red = color->getRedSize(); + const uint32_t green = color->getGreenSize(); + const uint32_t blue = color->getBlueSize(); + const uint32_t alpha = color->getAlphaSize(); + + ASSERT(red <= 8 && green <= 8 && blue <= 8 && alpha <= 8); + + return red | green << 4 | blue << 8 | alpha << 12 | static_cast(logicOp) << 16; +} +} // anonymous namespace + +namespace gl +{ +GLES1ShaderState::GLES1ShaderState() = default; +GLES1ShaderState::~GLES1ShaderState() = default; +GLES1ShaderState::GLES1ShaderState(const GLES1ShaderState &other) +{ + memcpy(this, &other, sizeof(GLES1ShaderState)); +} + +bool operator==(const GLES1ShaderState &a, const GLES1ShaderState &b) +{ + return memcmp(&a, &b, sizeof(GLES1ShaderState)) == 0; +} +bool operator!=(const GLES1ShaderState &a, const GLES1ShaderState &b) +{ + return !(a == b); +} + +size_t GLES1ShaderState::hash() const +{ + return angle::ComputeGenericHash(*this); +} + +GLES1Renderer::GLES1Renderer() : mRendererProgramInitialized(false) {} + +void GLES1Renderer::onDestroy(Context *context, State *state) +{ + if (mRendererProgramInitialized) + { + (void)state->setProgram(context, 0); + + for (const auto &iter : mUberShaderState) + { + const GLES1UberShaderState &UberShaderState = iter.second; + mShaderPrograms->deleteProgram(context, {UberShaderState.programState.program}); + } + mShaderPrograms->release(context); + mShaderPrograms = nullptr; + mRendererProgramInitialized = false; + } +} + +GLES1Renderer::~GLES1Renderer() = default; + +angle::Result GLES1Renderer::prepareForDraw(PrimitiveMode mode, Context *context, State *glState) +{ + GLES1State &gles1State = glState->gles1(); + + GLES1ShaderState::BoolTexArray &tex2DEnables = mShaderState.tex2DEnables; + GLES1ShaderState::BoolTexArray &texCubeEnables = mShaderState.texCubeEnables; + GLES1ShaderState::IntTexArray &tex2DFormats = mShaderState.tex2DFormats; + + for (int i = 0; i < kTexUnitCount; i++) + { + // GL_OES_cube_map allows only one of TEXTURE_2D / TEXTURE_CUBE_MAP + // to be enabled per unit, thankfully. From the extension text: + // + // -- Section 3.8.10 "Texture Application" + // + // Replace the beginning sentences of the first paragraph (page 138) + // with: + // + // "Texturing is enabled or disabled using the generic Enable + // and Disable commands, respectively, with the symbolic constants + // TEXTURE_2D or TEXTURE_CUBE_MAP_OES to enable the two-dimensional or cube + // map texturing respectively. If the cube map texture and the two- + // dimensional texture are enabled, then cube map texturing is used. If + // texturing is disabled, a rasterized fragment is passed on unaltered to the + // next stage of the GL (although its texture coordinates may be discarded). + // Otherwise, a texture value is found according to the parameter values of + // the currently bound texture image of the appropriate dimensionality. + + texCubeEnables[i] = gles1State.isTextureTargetEnabled(i, TextureType::CubeMap); + tex2DEnables[i] = + !texCubeEnables[i] && gles1State.isTextureTargetEnabled(i, TextureType::_2D); + + Texture *curr2DTexture = glState->getSamplerTexture(i, TextureType::_2D); + if (curr2DTexture) + { + tex2DFormats[i] = gl::GetUnsizedFormat( + curr2DTexture->getFormat(TextureTarget::_2D, 0).info->internalFormat); + } + + Texture *currCubeTexture = glState->getSamplerTexture(i, TextureType::CubeMap); + + // > If texturing is enabled for a texture unit at the time a primitive is rasterized, if + // > TEXTURE MIN FILTER is one that requires a mipmap, and if the texture image bound to the + // > enabled texture target is not complete, then it is as if texture mapping were disabled + // > for that texture unit. + if (tex2DEnables[i] && curr2DTexture && IsMipmapFiltered(curr2DTexture->getMinFilter())) + { + tex2DEnables[i] = curr2DTexture->isMipmapComplete(); + } + if (texCubeEnables[i] && currCubeTexture && + IsMipmapFiltered(currCubeTexture->getMinFilter())) + { + texCubeEnables[i] = curr2DTexture->isMipmapComplete(); + } + } + + GLES1ShaderState::IntTexArray &texEnvModes = mShaderState.texEnvModes; + GLES1ShaderState::IntTexArray &texCombineRgbs = mShaderState.texCombineRgbs; + GLES1ShaderState::IntTexArray &texCombineAlphas = mShaderState.texCombineAlphas; + GLES1ShaderState::IntTexArray &texCombineSrc0Rgbs = mShaderState.texCombineSrc0Rgbs; + GLES1ShaderState::IntTexArray &texCombineSrc0Alphas = mShaderState.texCombineSrc0Alphas; + GLES1ShaderState::IntTexArray &texCombineSrc1Rgbs = mShaderState.texCombineSrc1Rgbs; + GLES1ShaderState::IntTexArray &texCombineSrc1Alphas = mShaderState.texCombineSrc1Alphas; + GLES1ShaderState::IntTexArray &texCombineSrc2Rgbs = mShaderState.texCombineSrc2Rgbs; + GLES1ShaderState::IntTexArray &texCombineSrc2Alphas = mShaderState.texCombineSrc2Alphas; + GLES1ShaderState::IntTexArray &texCombineOp0Rgbs = mShaderState.texCombineOp0Rgbs; + GLES1ShaderState::IntTexArray &texCombineOp0Alphas = mShaderState.texCombineOp0Alphas; + GLES1ShaderState::IntTexArray &texCombineOp1Rgbs = mShaderState.texCombineOp1Rgbs; + GLES1ShaderState::IntTexArray &texCombineOp1Alphas = mShaderState.texCombineOp1Alphas; + GLES1ShaderState::IntTexArray &texCombineOp2Rgbs = mShaderState.texCombineOp2Rgbs; + GLES1ShaderState::IntTexArray &texCombineOp2Alphas = mShaderState.texCombineOp2Alphas; + + if (gles1State.isDirty(GLES1State::DIRTY_GLES1_TEXTURE_ENVIRONMENT)) + { + for (int i = 0; i < kTexUnitCount; i++) + { + const auto &env = gles1State.textureEnvironment(i); + texEnvModes[i] = ToGLenum(env.mode); + texCombineRgbs[i] = ToGLenum(env.combineRgb); + texCombineAlphas[i] = ToGLenum(env.combineAlpha); + texCombineSrc0Rgbs[i] = ToGLenum(env.src0Rgb); + texCombineSrc0Alphas[i] = ToGLenum(env.src0Alpha); + texCombineSrc1Rgbs[i] = ToGLenum(env.src1Rgb); + texCombineSrc1Alphas[i] = ToGLenum(env.src1Alpha); + texCombineSrc2Rgbs[i] = ToGLenum(env.src2Rgb); + texCombineSrc2Alphas[i] = ToGLenum(env.src2Alpha); + texCombineOp0Rgbs[i] = ToGLenum(env.op0Rgb); + texCombineOp0Alphas[i] = ToGLenum(env.op0Alpha); + texCombineOp1Rgbs[i] = ToGLenum(env.op1Rgb); + texCombineOp1Alphas[i] = ToGLenum(env.op1Alpha); + texCombineOp2Rgbs[i] = ToGLenum(env.op2Rgb); + texCombineOp2Alphas[i] = ToGLenum(env.op2Alpha); + } + } + + bool enableClipPlanes = false; + GLES1ShaderState::BoolClipPlaneArray &clipPlaneEnables = mShaderState.clipPlaneEnables; + for (int i = 0; i < kClipPlaneCount; i++) + { + clipPlaneEnables[i] = glState->getEnableFeature(GL_CLIP_PLANE0 + i); + enableClipPlanes = enableClipPlanes || clipPlaneEnables[i]; + } + + mShaderState.mGLES1StateEnabled[GLES1StateEnables::ClipPlanes] = enableClipPlanes; + mShaderState.mGLES1StateEnabled[GLES1StateEnables::DrawTexture] = mDrawTextureEnabled; + mShaderState.mGLES1StateEnabled[GLES1StateEnables::PointRasterization] = + mode == PrimitiveMode::Points; + mShaderState.mGLES1StateEnabled[GLES1StateEnables::ShadeModelFlat] = + gles1State.mShadeModel == ShadingModel::Flat; + mShaderState.mGLES1StateEnabled[GLES1StateEnables::AlphaTest] = + glState->getEnableFeature(GL_ALPHA_TEST); + mShaderState.mGLES1StateEnabled[GLES1StateEnables::Lighting] = + glState->getEnableFeature(GL_LIGHTING); + mShaderState.mGLES1StateEnabled[GLES1StateEnables::RescaleNormal] = + glState->getEnableFeature(GL_RESCALE_NORMAL); + mShaderState.mGLES1StateEnabled[GLES1StateEnables::Normalize] = + glState->getEnableFeature(GL_NORMALIZE); + mShaderState.mGLES1StateEnabled[GLES1StateEnables::Fog] = glState->getEnableFeature(GL_FOG); + mShaderState.mGLES1StateEnabled[GLES1StateEnables::PointSprite] = + glState->getEnableFeature(GL_POINT_SPRITE_OES); + mShaderState.mGLES1StateEnabled[GLES1StateEnables::ColorMaterial] = + glState->getEnableFeature(GL_COLOR_MATERIAL); + + // TODO (lfy@google.com): Implement two-sided lighting model (lightModel.twoSided) + mShaderState.mGLES1StateEnabled[GLES1StateEnables::LightModelTwoSided] = false; + + GLES1ShaderState::BoolTexArray &pointSpriteCoordReplaces = + mShaderState.pointSpriteCoordReplaces; + for (int i = 0; i < kTexUnitCount; i++) + { + const auto &env = gles1State.textureEnvironment(i); + pointSpriteCoordReplaces[i] = env.pointSpriteCoordReplace; + } + + GLES1ShaderState::BoolLightArray &lightEnables = mShaderState.lightEnables; + for (int i = 0; i < kLightCount; i++) + { + const auto &light = gles1State.mLights[i]; + lightEnables[i] = light.enabled; + } + + mShaderState.alphaTestFunc = gles1State.mAlphaTestFunc; + mShaderState.fogMode = gles1State.fogParameters().mode; + + const bool hasLogicOpANGLE = context->getExtensions().logicOpANGLE; + const bool hasFramebufferFetch = context->getExtensions().shaderFramebufferFetchEXT || + context->getExtensions().shaderFramebufferFetchNonCoherentEXT; + + if (!hasLogicOpANGLE && hasFramebufferFetch) + { + mShaderState.mGLES1StateEnabled[GLES1StateEnables::LogicOpThroughFramebufferFetch] = + gles1State.mLogicOpEnabled; + } + + // All the states set before this spot affect ubershader creation + + ANGLE_TRY(initializeRendererProgram(context, glState)); + + GLES1UberShaderState UberShaderState = getUberShaderState(); + + const GLES1ProgramState &programState = UberShaderState.programState; + GLES1UniformBuffers &uniformBuffers = UberShaderState.uniformBuffers; + + Program *programObject = getProgram(programState.program); + + // If anything is dirty in gles1 or the common parts of gles1/2, just redo these parts + // completely for now. + + // Feature enables + + // Texture unit enables and format info + std::array texCropRects; + Vec4Uniform *cropRectBuffer = texCropRects.data(); + for (int i = 0; i < kTexUnitCount; i++) + { + Texture *curr2DTexture = glState->getSamplerTexture(i, TextureType::_2D); + if (curr2DTexture) + { + const gl::Rectangle &cropRect = curr2DTexture->getCrop(); + + GLfloat textureWidth = + static_cast(curr2DTexture->getWidth(TextureTarget::_2D, 0)); + GLfloat textureHeight = + static_cast(curr2DTexture->getHeight(TextureTarget::_2D, 0)); + + if (textureWidth > 0.0f && textureHeight > 0.0f) + { + cropRectBuffer[i][0] = cropRect.x / textureWidth; + cropRectBuffer[i][1] = cropRect.y / textureHeight; + cropRectBuffer[i][2] = cropRect.width / textureWidth; + cropRectBuffer[i][3] = cropRect.height / textureHeight; + } + } + } + setUniform4fv(programObject, programState.drawTextureNormalizedCropRectLoc, kTexUnitCount, + reinterpret_cast(cropRectBuffer)); + + if (gles1State.isDirty(GLES1State::DIRTY_GLES1_LOGIC_OP) && hasLogicOpANGLE) + { + context->setLogicOpEnabled(gles1State.mLogicOpEnabled); + context->setLogicOp(gles1State.mLogicOp); + } + else if (hasFramebufferFetch) + { + const Framebuffer *drawFramebuffer = glState->getDrawFramebuffer(); + const FramebufferAttachment *colorAttachment = drawFramebuffer->getColorAttachment(0); + + if (gles1State.mLogicOpEnabled) + { + if (gles1State.isDirty(GLES1State::DIRTY_GLES1_LOGIC_OP)) + { + // Set up uniform value for logic op + setUniform1ui(programObject, programState.logicOpLoc, + GetLogicOpUniform(colorAttachment, gles1State.mLogicOp)); + } + + // Issue a framebuffer fetch barrier if non-coherent + if (!context->getExtensions().shaderFramebufferFetchEXT) + { + context->framebufferFetchBarrier(); + } + } + } + + // Client state / current vector enables + if (gles1State.isDirty(GLES1State::DIRTY_GLES1_CLIENT_STATE_ENABLE) || + gles1State.isDirty(GLES1State::DIRTY_GLES1_CURRENT_VECTOR)) + { + if (!gles1State.isClientStateEnabled(ClientVertexArrayType::Normal)) + { + const angle::Vector3 normal = gles1State.getCurrentNormal(); + context->vertexAttrib3f(kNormalAttribIndex, normal.x(), normal.y(), normal.z()); + } + + if (!gles1State.isClientStateEnabled(ClientVertexArrayType::Color)) + { + const ColorF color = gles1State.getCurrentColor(); + context->vertexAttrib4f(kColorAttribIndex, color.red, color.green, color.blue, + color.alpha); + } + + if (!gles1State.isClientStateEnabled(ClientVertexArrayType::PointSize)) + { + GLfloat pointSize = gles1State.mPointParameters.pointSize; + context->vertexAttrib1f(kPointSizeAttribIndex, pointSize); + } + + for (int i = 0; i < kTexUnitCount; i++) + { + if (!gles1State.mTexCoordArrayEnabled[i]) + { + const TextureCoordF texcoord = gles1State.getCurrentTextureCoords(i); + context->vertexAttrib4f(kTextureCoordAttribIndexBase + i, texcoord.s, texcoord.t, + texcoord.r, texcoord.q); + } + } + } + + // Matrices + if (gles1State.isDirty(GLES1State::DIRTY_GLES1_MATRICES)) + { + angle::Mat4 proj = gles1State.mProjectionMatrices.back(); + setUniformMatrix4fv(programObject, programState.projMatrixLoc, 1, GL_FALSE, proj.data()); + + angle::Mat4 modelview = gles1State.mModelviewMatrices.back(); + setUniformMatrix4fv(programObject, programState.modelviewMatrixLoc, 1, GL_FALSE, + modelview.data()); + + angle::Mat4 modelviewInvTr = modelview.transpose().inverse(); + setUniformMatrix4fv(programObject, programState.modelviewInvTrLoc, 1, GL_FALSE, + modelviewInvTr.data()); + + Mat4Uniform *textureMatrixBuffer = uniformBuffers.textureMatrices.data(); + + for (int i = 0; i < kTexUnitCount; i++) + { + angle::Mat4 textureMatrix = gles1State.mTextureMatrices[i].back(); + memcpy(textureMatrixBuffer + i, textureMatrix.data(), sizeof(Mat4Uniform)); + } + + setUniformMatrix4fv(programObject, programState.textureMatrixLoc, kTexUnitCount, GL_FALSE, + reinterpret_cast(uniformBuffers.textureMatrices.data())); + } + + if (gles1State.isDirty(GLES1State::DIRTY_GLES1_TEXTURE_ENVIRONMENT)) + { + for (int i = 0; i < kTexUnitCount; i++) + { + const auto &env = gles1State.textureEnvironment(i); + + uniformBuffers.texEnvColors[i][0] = env.color.red; + uniformBuffers.texEnvColors[i][1] = env.color.green; + uniformBuffers.texEnvColors[i][2] = env.color.blue; + uniformBuffers.texEnvColors[i][3] = env.color.alpha; + + uniformBuffers.texEnvRgbScales[i] = env.rgbScale; + uniformBuffers.texEnvAlphaScales[i] = env.alphaScale; + } + + setUniform4fv(programObject, programState.textureEnvColorLoc, kTexUnitCount, + reinterpret_cast(uniformBuffers.texEnvColors.data())); + setUniform1fv(programObject, programState.rgbScaleLoc, kTexUnitCount, + uniformBuffers.texEnvRgbScales.data()); + setUniform1fv(programObject, programState.alphaScaleLoc, kTexUnitCount, + uniformBuffers.texEnvAlphaScales.data()); + } + + // Alpha test + if (gles1State.isDirty(GLES1State::DIRTY_GLES1_ALPHA_TEST)) + { + setUniform1f(programObject, programState.alphaTestRefLoc, gles1State.mAlphaTestRef); + } + + // Shading, materials, and lighting + if (gles1State.isDirty(GLES1State::DIRTY_GLES1_MATERIAL)) + { + const auto &material = gles1State.mMaterial; + + setUniform4fv(programObject, programState.materialAmbientLoc, 1, material.ambient.data()); + setUniform4fv(programObject, programState.materialDiffuseLoc, 1, material.diffuse.data()); + setUniform4fv(programObject, programState.materialSpecularLoc, 1, material.specular.data()); + setUniform4fv(programObject, programState.materialEmissiveLoc, 1, material.emissive.data()); + setUniform1f(programObject, programState.materialSpecularExponentLoc, + material.specularExponent); + } + + if (gles1State.isDirty(GLES1State::DIRTY_GLES1_LIGHTS)) + { + const auto &lightModel = gles1State.mLightModel; + + setUniform4fv(programObject, programState.lightModelSceneAmbientLoc, 1, + lightModel.color.data()); + + for (int i = 0; i < kLightCount; i++) + { + const auto &light = gles1State.mLights[i]; + memcpy(uniformBuffers.lightAmbients.data() + i, light.ambient.data(), + sizeof(Vec4Uniform)); + memcpy(uniformBuffers.lightDiffuses.data() + i, light.diffuse.data(), + sizeof(Vec4Uniform)); + memcpy(uniformBuffers.lightSpeculars.data() + i, light.specular.data(), + sizeof(Vec4Uniform)); + memcpy(uniformBuffers.lightPositions.data() + i, light.position.data(), + sizeof(Vec4Uniform)); + memcpy(uniformBuffers.lightDirections.data() + i, light.direction.data(), + sizeof(Vec3Uniform)); + uniformBuffers.spotlightExponents[i] = light.spotlightExponent; + uniformBuffers.spotlightCutoffAngles[i] = light.spotlightCutoffAngle; + uniformBuffers.attenuationConsts[i] = light.attenuationConst; + uniformBuffers.attenuationLinears[i] = light.attenuationLinear; + uniformBuffers.attenuationQuadratics[i] = light.attenuationQuadratic; + } + + setUniform4fv(programObject, programState.lightAmbientsLoc, kLightCount, + reinterpret_cast(uniformBuffers.lightAmbients.data())); + setUniform4fv(programObject, programState.lightDiffusesLoc, kLightCount, + reinterpret_cast(uniformBuffers.lightDiffuses.data())); + setUniform4fv(programObject, programState.lightSpecularsLoc, kLightCount, + reinterpret_cast(uniformBuffers.lightSpeculars.data())); + setUniform4fv(programObject, programState.lightPositionsLoc, kLightCount, + reinterpret_cast(uniformBuffers.lightPositions.data())); + setUniform3fv(programObject, programState.lightDirectionsLoc, kLightCount, + reinterpret_cast(uniformBuffers.lightDirections.data())); + setUniform1fv(programObject, programState.lightSpotlightExponentsLoc, kLightCount, + reinterpret_cast(uniformBuffers.spotlightExponents.data())); + setUniform1fv(programObject, programState.lightSpotlightCutoffAnglesLoc, kLightCount, + reinterpret_cast(uniformBuffers.spotlightCutoffAngles.data())); + setUniform1fv(programObject, programState.lightAttenuationConstsLoc, kLightCount, + reinterpret_cast(uniformBuffers.attenuationConsts.data())); + setUniform1fv(programObject, programState.lightAttenuationLinearsLoc, kLightCount, + reinterpret_cast(uniformBuffers.attenuationLinears.data())); + setUniform1fv(programObject, programState.lightAttenuationQuadraticsLoc, kLightCount, + reinterpret_cast(uniformBuffers.attenuationQuadratics.data())); + } + + if (gles1State.isDirty(GLES1State::DIRTY_GLES1_FOG)) + { + const FogParameters &fog = gles1State.fogParameters(); + setUniform1f(programObject, programState.fogDensityLoc, fog.density); + setUniform1f(programObject, programState.fogStartLoc, fog.start); + setUniform1f(programObject, programState.fogEndLoc, fog.end); + setUniform4fv(programObject, programState.fogColorLoc, 1, fog.color.data()); + } + + // Clip planes + if (gles1State.isDirty(GLES1State::DIRTY_GLES1_CLIP_PLANES)) + { + for (int i = 0; i < kClipPlaneCount; i++) + { + gles1State.getClipPlane( + i, reinterpret_cast(uniformBuffers.clipPlanes.data() + i)); + } + + setUniform4fv(programObject, programState.clipPlanesLoc, kClipPlaneCount, + reinterpret_cast(uniformBuffers.clipPlanes.data())); + } + + // Point rasterization + { + const PointParameters &pointParams = gles1State.mPointParameters; + + setUniform1f(programObject, programState.pointSizeMinLoc, pointParams.pointSizeMin); + setUniform1f(programObject, programState.pointSizeMaxLoc, pointParams.pointSizeMax); + setUniform3fv(programObject, programState.pointDistanceAttenuationLoc, 1, + pointParams.pointDistanceAttenuation.data()); + } + + // Draw texture + { + setUniform4fv(programObject, programState.drawTextureCoordsLoc, 1, mDrawTextureCoords); + setUniform2fv(programObject, programState.drawTextureDimsLoc, 1, mDrawTextureDims); + } + + gles1State.clearDirty(); + + // None of those are changes in sampler, so there is no need to set the GL_PROGRAM dirty. + // Otherwise, put the dirtying here. + + return angle::Result::Continue; +} + +// static +int GLES1Renderer::VertexArrayIndex(ClientVertexArrayType type, const GLES1State &gles1) +{ + switch (type) + { + case ClientVertexArrayType::Vertex: + return kVertexAttribIndex; + case ClientVertexArrayType::Normal: + return kNormalAttribIndex; + case ClientVertexArrayType::Color: + return kColorAttribIndex; + case ClientVertexArrayType::PointSize: + return kPointSizeAttribIndex; + case ClientVertexArrayType::TextureCoord: + return kTextureCoordAttribIndexBase + gles1.getClientTextureUnit(); + default: + UNREACHABLE(); + return 0; + } +} + +// static +ClientVertexArrayType GLES1Renderer::VertexArrayType(int attribIndex) +{ + switch (attribIndex) + { + case kVertexAttribIndex: + return ClientVertexArrayType::Vertex; + case kNormalAttribIndex: + return ClientVertexArrayType::Normal; + case kColorAttribIndex: + return ClientVertexArrayType::Color; + case kPointSizeAttribIndex: + return ClientVertexArrayType::PointSize; + default: + if (attribIndex < kTextureCoordAttribIndexBase + kTexUnitCount) + { + return ClientVertexArrayType::TextureCoord; + } + UNREACHABLE(); + return ClientVertexArrayType::InvalidEnum; + } +} + +// static +int GLES1Renderer::TexCoordArrayIndex(unsigned int unit) +{ + return kTextureCoordAttribIndexBase + unit; +} + +void GLES1Renderer::drawTexture(Context *context, + State *glState, + float x, + float y, + float z, + float width, + float height) +{ + + // get viewport + const gl::Rectangle &viewport = glState->getViewport(); + + // Translate from viewport to NDC for feeding the shader. + // Recenter, rescale. (e.g., [0, 0, 1080, 1920] -> [-1, -1, 1, 1]) + float xNdc = scaleScreenCoordinateToNdc(x, static_cast(viewport.width)); + float yNdc = scaleScreenCoordinateToNdc(y, static_cast(viewport.height)); + float wNdc = scaleScreenDimensionToNdc(width, static_cast(viewport.width)); + float hNdc = scaleScreenDimensionToNdc(height, static_cast(viewport.height)); + + float zNdc = 2.0f * clamp(z, 0.0f, 1.0f) - 1.0f; + + mDrawTextureCoords[0] = xNdc; + mDrawTextureCoords[1] = yNdc; + mDrawTextureCoords[2] = zNdc; + + mDrawTextureDims[0] = wNdc; + mDrawTextureDims[1] = hNdc; + + mDrawTextureEnabled = true; + + AttributesMask prevAttributesMask = glState->gles1().getVertexArraysAttributeMask(); + + setAttributesEnabled(context, glState, AttributesMask()); + + glState->gles1().setAllDirty(); + + context->drawArrays(PrimitiveMode::Triangles, 0, 6); + + setAttributesEnabled(context, glState, prevAttributesMask); + + mDrawTextureEnabled = false; +} + +Shader *GLES1Renderer::getShader(ShaderProgramID handle) const +{ + return mShaderPrograms->getShader(handle); +} + +Program *GLES1Renderer::getProgram(ShaderProgramID handle) const +{ + return mShaderPrograms->getProgram(handle); +} + +angle::Result GLES1Renderer::compileShader(Context *context, + ShaderType shaderType, + const char *src, + ShaderProgramID *shaderOut) +{ + rx::ContextImpl *implementation = context->getImplementation(); + const Limitations &limitations = implementation->getNativeLimitations(); + + ShaderProgramID shader = mShaderPrograms->createShader(implementation, limitations, shaderType); + + Shader *shaderObject = getShader(shader); + ANGLE_CHECK(context, shaderObject, "Missing shader object", GL_INVALID_OPERATION); + + shaderObject->setSource(1, &src, nullptr); + shaderObject->compile(context); + + *shaderOut = shader; + + if (!shaderObject->isCompiled(context)) + { + GLint infoLogLength = shaderObject->getInfoLogLength(context); + std::vector infoLog(infoLogLength, 0); + shaderObject->getInfoLog(context, infoLogLength - 1, nullptr, infoLog.data()); + + ERR() << "Internal GLES 1 shader compile failed. Info log: " << infoLog.data(); + ANGLE_CHECK(context, false, "GLES1Renderer shader compile failed.", GL_INVALID_OPERATION); + return angle::Result::Stop; + } + + return angle::Result::Continue; +} + +angle::Result GLES1Renderer::linkProgram(Context *context, + State *glState, + ShaderProgramID vertexShader, + ShaderProgramID fragmentShader, + const angle::HashMap &attribLocs, + ShaderProgramID *programOut) +{ + ShaderProgramID program = mShaderPrograms->createProgram(context->getImplementation()); + + Program *programObject = getProgram(program); + ANGLE_CHECK(context, programObject, "Missing program object", GL_INVALID_OPERATION); + + *programOut = program; + + programObject->attachShader(getShader(vertexShader)); + programObject->attachShader(getShader(fragmentShader)); + + for (auto it : attribLocs) + { + GLint index = it.first; + const std::string &name = it.second; + programObject->bindAttributeLocation(index, name.c_str()); + } + + ANGLE_TRY(programObject->link(context)); + programObject->resolveLink(context); + + ANGLE_TRY(glState->onProgramExecutableChange(context, programObject)); + + if (!programObject->isLinked()) + { + GLint infoLogLength = programObject->getExecutable().getInfoLogLength(); + std::vector infoLog(infoLogLength, 0); + programObject->getExecutable().getInfoLog(infoLogLength - 1, nullptr, infoLog.data()); + + ERR() << "Internal GLES 1 shader link failed. Info log: " << infoLog.data(); + ANGLE_CHECK(context, false, "GLES1Renderer program link failed.", GL_INVALID_OPERATION); + return angle::Result::Stop; + } + + programObject->detachShader(context, getShader(vertexShader)); + programObject->detachShader(context, getShader(fragmentShader)); + + return angle::Result::Continue; +} + +const char *GLES1Renderer::getShaderBool(GLES1StateEnables state) +{ + if (mShaderState.mGLES1StateEnabled[state]) + { + return "true"; + } + else + { + return "false"; + } +} + +void GLES1Renderer::addShaderDefine(std::stringstream &outStream, + GLES1StateEnables state, + const char *enableString) +{ + outStream << "\n"; + outStream << "#define " << enableString << " " << getShaderBool(state); +} + +void GLES1Renderer::addShaderInt(std::stringstream &outStream, const char *name, int value) +{ + outStream << "\n"; + outStream << "const int " << name << " = " << value << ";"; +} + +void GLES1Renderer::addShaderIntTexArray(std::stringstream &outStream, + const char *texString, + GLES1ShaderState::IntTexArray &texState) +{ + outStream << "\n"; + outStream << "const int " << texString << "[kMaxTexUnits] = int[kMaxTexUnits]("; + for (int i = 0; i < kTexUnitCount; i++) + { + if (i != 0) + { + outStream << ", "; + } + outStream << texState[i]; + } + outStream << ");"; +} + +void GLES1Renderer::addShaderBoolTexArray(std::stringstream &outStream, + const char *name, + GLES1ShaderState::BoolTexArray &value) +{ + outStream << std::boolalpha; + outStream << "\n"; + outStream << "bool " << name << "[kMaxTexUnits] = bool[kMaxTexUnits]("; + for (int i = 0; i < kTexUnitCount; i++) + { + if (i != 0) + { + outStream << ", "; + } + outStream << value[i]; + } + outStream << ");"; +} + +void GLES1Renderer::addShaderBoolLightArray(std::stringstream &outStream, + const char *name, + GLES1ShaderState::BoolLightArray &value) +{ + outStream << std::boolalpha; + outStream << "\n"; + outStream << "bool " << name << "[kMaxLights] = bool[kMaxLights]("; + for (int i = 0; i < kLightCount; i++) + { + if (i != 0) + { + outStream << ", "; + } + outStream << value[i]; + } + outStream << ");"; +} + +void GLES1Renderer::addShaderBoolClipPlaneArray(std::stringstream &outStream, + const char *name, + GLES1ShaderState::BoolClipPlaneArray &value) +{ + outStream << std::boolalpha; + outStream << "\n"; + outStream << "bool " << name << "[kMaxClipPlanes] = bool[kMaxClipPlanes]("; + for (int i = 0; i < kClipPlaneCount; i++) + { + if (i != 0) + { + outStream << ", "; + } + outStream << value[i]; + } + outStream << ");"; +} + +void GLES1Renderer::addVertexShaderDefs(std::stringstream &outStream) +{ + addShaderDefine(outStream, GLES1StateEnables::Lighting, "enable_lighting"); + addShaderDefine(outStream, GLES1StateEnables::ColorMaterial, "enable_color_material"); + addShaderDefine(outStream, GLES1StateEnables::DrawTexture, "enable_draw_texture"); + addShaderDefine(outStream, GLES1StateEnables::PointRasterization, "point_rasterization"); + addShaderDefine(outStream, GLES1StateEnables::RescaleNormal, "enable_rescale_normal"); + addShaderDefine(outStream, GLES1StateEnables::Normalize, "enable_normalize"); + addShaderDefine(outStream, GLES1StateEnables::LightModelTwoSided, "light_model_two_sided"); + + // bool light_enables[kMaxLights] = bool[kMaxLights](...); + addShaderBoolLightArray(outStream, "light_enables", mShaderState.lightEnables); +} + +void GLES1Renderer::addFragmentShaderDefs(std::stringstream &outStream) +{ + addShaderDefine(outStream, GLES1StateEnables::Fog, "enable_fog"); + addShaderDefine(outStream, GLES1StateEnables::ClipPlanes, "enable_clip_planes"); + addShaderDefine(outStream, GLES1StateEnables::DrawTexture, "enable_draw_texture"); + addShaderDefine(outStream, GLES1StateEnables::PointRasterization, "point_rasterization"); + addShaderDefine(outStream, GLES1StateEnables::PointSprite, "point_sprite_enabled"); + addShaderDefine(outStream, GLES1StateEnables::AlphaTest, "enable_alpha_test"); + addShaderDefine(outStream, GLES1StateEnables::ShadeModelFlat, "shade_model_flat"); + + // bool enable_texture_2d[kMaxTexUnits] = bool[kMaxTexUnits](...); + addShaderBoolTexArray(outStream, "enable_texture_2d", mShaderState.tex2DEnables); + + // bool enable_texture_cube_map[kMaxTexUnits] = bool[kMaxTexUnits](...); + addShaderBoolTexArray(outStream, "enable_texture_cube_map", mShaderState.texCubeEnables); + + // int texture_format[kMaxTexUnits] = int[kMaxTexUnits](...); + addShaderIntTexArray(outStream, "texture_format", mShaderState.tex2DFormats); + + // bool point_sprite_coord_replace[kMaxTexUnits] = bool[kMaxTexUnits](...); + addShaderBoolTexArray(outStream, "point_sprite_coord_replace", + mShaderState.pointSpriteCoordReplaces); + + // bool clip_plane_enables[kMaxClipPlanes] = bool[kMaxClipPlanes](...); + addShaderBoolClipPlaneArray(outStream, "clip_plane_enables", mShaderState.clipPlaneEnables); + + // int texture_format[kMaxTexUnits] = int[kMaxTexUnits](...); + addShaderIntTexArray(outStream, "texture_env_mode", mShaderState.texEnvModes); + + // int combine_rgb[kMaxTexUnits]; + addShaderIntTexArray(outStream, "combine_rgb", mShaderState.texCombineRgbs); + + // int combine_alpha[kMaxTexUnits]; + addShaderIntTexArray(outStream, "combine_alpha", mShaderState.texCombineAlphas); + + // int src0_rgb[kMaxTexUnits]; + addShaderIntTexArray(outStream, "src0_rgb", mShaderState.texCombineSrc0Rgbs); + + // int src0_alpha[kMaxTexUnits]; + addShaderIntTexArray(outStream, "src0_alpha", mShaderState.texCombineSrc0Alphas); + + // int src1_rgb[kMaxTexUnits]; + addShaderIntTexArray(outStream, "src1_rgb", mShaderState.texCombineSrc1Rgbs); + + // int src1_alpha[kMaxTexUnits]; + addShaderIntTexArray(outStream, "src1_alpha", mShaderState.texCombineSrc1Alphas); + + // int src2_rgb[kMaxTexUnits]; + addShaderIntTexArray(outStream, "src2_rgb", mShaderState.texCombineSrc2Rgbs); + + // int src2_alpha[kMaxTexUnits]; + addShaderIntTexArray(outStream, "src2_alpha", mShaderState.texCombineSrc2Alphas); + + // int op0_rgb[kMaxTexUnits]; + addShaderIntTexArray(outStream, "op0_rgb", mShaderState.texCombineOp0Rgbs); + + // int op0_alpha[kMaxTexUnits]; + addShaderIntTexArray(outStream, "op0_alpha", mShaderState.texCombineOp0Alphas); + + // int op1_rgb[kMaxTexUnits]; + addShaderIntTexArray(outStream, "op1_rgb", mShaderState.texCombineOp1Rgbs); + + // int op1_alpha[kMaxTexUnits]; + addShaderIntTexArray(outStream, "op1_alpha", mShaderState.texCombineOp1Alphas); + + // int op2_rgb[kMaxTexUnits]; + addShaderIntTexArray(outStream, "op2_rgb", mShaderState.texCombineOp2Rgbs); + + // int op2_alpha[kMaxTexUnits]; + addShaderIntTexArray(outStream, "op2_alpha", mShaderState.texCombineOp2Alphas); + + // int alpha_func; + addShaderInt(outStream, "alpha_func", ToGLenum(mShaderState.alphaTestFunc)); + + // int fog_mode; + addShaderInt(outStream, "fog_mode", ToGLenum(mShaderState.fogMode)); +} + +angle::Result GLES1Renderer::initializeRendererProgram(Context *context, State *glState) +{ + // See if we have the shader for this combination of states + if (mUberShaderState.find(mShaderState) != mUberShaderState.end()) + { + Program *programObject = getProgram(getUberShaderState().programState.program); + + // If this is different than the current program, we need to sync everything + // TODO: This could be optimized to only dirty state that differs between the two programs + if (glState->getProgram()->id() != programObject->id()) + { + glState->gles1().setAllDirty(); + } + + ANGLE_TRY(glState->setProgram(context, programObject)); + return angle::Result::Continue; + } + + if (!mRendererProgramInitialized) + { + mShaderPrograms = new ShaderProgramManager(); + } + + // If we get here, we don't have a shader for this state, need to create it + GLES1ProgramState &programState = mUberShaderState[mShaderState].programState; + + ShaderProgramID vertexShader; + ShaderProgramID fragmentShader; + + std::stringstream GLES1DrawVShaderStateDefs; + addVertexShaderDefs(GLES1DrawVShaderStateDefs); + + std::stringstream vertexStream; + vertexStream << kGLES1DrawVShaderHeader; + vertexStream << GLES1DrawVShaderStateDefs.str(); + vertexStream << kGLES1DrawVShader; + + ANGLE_TRY( + compileShader(context, ShaderType::Vertex, vertexStream.str().c_str(), &vertexShader)); + + std::stringstream GLES1DrawFShaderStateDefs; + addFragmentShaderDefs(GLES1DrawFShaderStateDefs); + + std::stringstream fragmentStream; + fragmentStream << kGLES1DrawFShaderVersion; + if (mShaderState.mGLES1StateEnabled[GLES1StateEnables::LogicOpThroughFramebufferFetch]) + { + if (context->getExtensions().shaderFramebufferFetchEXT) + { + fragmentStream << "#extension GL_EXT_shader_framebuffer_fetch : require\n"; + } + else + { + fragmentStream << "#extension GL_EXT_shader_framebuffer_fetch_non_coherent : require\n"; + } + } + fragmentStream << kGLES1DrawFShaderHeader; + fragmentStream << GLES1DrawFShaderStateDefs.str(); + fragmentStream << kGLES1DrawFShaderUniformDefs; + if (mShaderState.mGLES1StateEnabled[GLES1StateEnables::LogicOpThroughFramebufferFetch]) + { + if (context->getExtensions().shaderFramebufferFetchEXT) + { + fragmentStream << kGLES1DrawFShaderFramebufferFetchOutputDef; + } + else + { + fragmentStream << kGLES1DrawFShaderFramebufferFetchNonCoherentOutputDef; + } + fragmentStream << kGLES1DrawFShaderLogicOpFramebufferFetchEnabled; + } + else + { + fragmentStream << kGLES1DrawFShaderOutputDef; + fragmentStream << kGLES1DrawFShaderLogicOpFramebufferFetchDisabled; + } + fragmentStream << kGLES1DrawFShaderFunctions; + fragmentStream << kGLES1DrawFShaderMultitexturing; + fragmentStream << kGLES1DrawFShaderMain; + + ANGLE_TRY(compileShader(context, ShaderType::Fragment, fragmentStream.str().c_str(), + &fragmentShader)); + + angle::HashMap attribLocs; + + attribLocs[(GLint)kVertexAttribIndex] = "pos"; + attribLocs[(GLint)kNormalAttribIndex] = "normal"; + attribLocs[(GLint)kColorAttribIndex] = "color"; + attribLocs[(GLint)kPointSizeAttribIndex] = "pointsize"; + + for (int i = 0; i < kTexUnitCount; i++) + { + std::stringstream ss; + ss << "texcoord" << i; + attribLocs[kTextureCoordAttribIndexBase + i] = ss.str(); + } + + ANGLE_TRY(linkProgram(context, glState, vertexShader, fragmentShader, attribLocs, + &programState.program)); + + mShaderPrograms->deleteShader(context, vertexShader); + mShaderPrograms->deleteShader(context, fragmentShader); + + Program *programObject = getProgram(programState.program); + + programState.projMatrixLoc = programObject->getUniformLocation("projection"); + programState.modelviewMatrixLoc = programObject->getUniformLocation("modelview"); + programState.textureMatrixLoc = programObject->getUniformLocation("texture_matrix"); + programState.modelviewInvTrLoc = programObject->getUniformLocation("modelview_invtr"); + + for (int i = 0; i < kTexUnitCount; i++) + { + std::stringstream ss2d; + std::stringstream sscube; + + ss2d << "tex_sampler" << i; + sscube << "tex_cube_sampler" << i; + + programState.tex2DSamplerLocs[i] = programObject->getUniformLocation(ss2d.str().c_str()); + programState.texCubeSamplerLocs[i] = + programObject->getUniformLocation(sscube.str().c_str()); + } + + programState.textureEnvColorLoc = programObject->getUniformLocation("texture_env_color"); + programState.rgbScaleLoc = programObject->getUniformLocation("texture_env_rgb_scale"); + programState.alphaScaleLoc = programObject->getUniformLocation("texture_env_alpha_scale"); + + programState.alphaTestRefLoc = programObject->getUniformLocation("alpha_test_ref"); + + programState.materialAmbientLoc = programObject->getUniformLocation("material_ambient"); + programState.materialDiffuseLoc = programObject->getUniformLocation("material_diffuse"); + programState.materialSpecularLoc = programObject->getUniformLocation("material_specular"); + programState.materialEmissiveLoc = programObject->getUniformLocation("material_emissive"); + programState.materialSpecularExponentLoc = + programObject->getUniformLocation("material_specular_exponent"); + + programState.lightModelSceneAmbientLoc = + programObject->getUniformLocation("light_model_scene_ambient"); + + programState.lightAmbientsLoc = programObject->getUniformLocation("light_ambients"); + programState.lightDiffusesLoc = programObject->getUniformLocation("light_diffuses"); + programState.lightSpecularsLoc = programObject->getUniformLocation("light_speculars"); + programState.lightPositionsLoc = programObject->getUniformLocation("light_positions"); + programState.lightDirectionsLoc = programObject->getUniformLocation("light_directions"); + programState.lightSpotlightExponentsLoc = + programObject->getUniformLocation("light_spotlight_exponents"); + programState.lightSpotlightCutoffAnglesLoc = + programObject->getUniformLocation("light_spotlight_cutoff_angles"); + programState.lightAttenuationConstsLoc = + programObject->getUniformLocation("light_attenuation_consts"); + programState.lightAttenuationLinearsLoc = + programObject->getUniformLocation("light_attenuation_linears"); + programState.lightAttenuationQuadraticsLoc = + programObject->getUniformLocation("light_attenuation_quadratics"); + + programState.fogDensityLoc = programObject->getUniformLocation("fog_density"); + programState.fogStartLoc = programObject->getUniformLocation("fog_start"); + programState.fogEndLoc = programObject->getUniformLocation("fog_end"); + programState.fogColorLoc = programObject->getUniformLocation("fog_color"); + + programState.clipPlanesLoc = programObject->getUniformLocation("clip_planes"); + + programState.logicOpLoc = programObject->getUniformLocation("logic_op"); + + programState.pointSizeMinLoc = programObject->getUniformLocation("point_size_min"); + programState.pointSizeMaxLoc = programObject->getUniformLocation("point_size_max"); + programState.pointDistanceAttenuationLoc = + programObject->getUniformLocation("point_distance_attenuation"); + + programState.drawTextureCoordsLoc = programObject->getUniformLocation("draw_texture_coords"); + programState.drawTextureDimsLoc = programObject->getUniformLocation("draw_texture_dims"); + programState.drawTextureNormalizedCropRectLoc = + programObject->getUniformLocation("draw_texture_normalized_crop_rect"); + + ANGLE_TRY(glState->setProgram(context, programObject)); + + for (int i = 0; i < kTexUnitCount; i++) + { + setUniform1i(context, programObject, programState.tex2DSamplerLocs[i], i); + setUniform1i(context, programObject, programState.texCubeSamplerLocs[i], i + kTexUnitCount); + } + glState->setObjectDirty(GL_PROGRAM); + + // We just created a new program, we need to sync everything + glState->gles1().setAllDirty(); + + mRendererProgramInitialized = true; + return angle::Result::Continue; +} + +void GLES1Renderer::setUniform1i(Context *context, + Program *programObject, + UniformLocation location, + GLint value) +{ + if (location.value == -1) + return; + programObject->setUniform1iv(context, location, 1, &value); +} + +void GLES1Renderer::setUniform1ui(Program *programObject, UniformLocation location, GLuint value) +{ + if (location.value == -1) + return; + programObject->setUniform1uiv(location, 1, &value); +} + +void GLES1Renderer::setUniform1iv(Context *context, + Program *programObject, + UniformLocation location, + GLint count, + const GLint *value) +{ + if (location.value == -1) + return; + programObject->setUniform1iv(context, location, count, value); +} + +void GLES1Renderer::setUniformMatrix4fv(Program *programObject, + UniformLocation location, + GLint count, + GLboolean transpose, + const GLfloat *value) +{ + if (location.value == -1) + return; + programObject->setUniformMatrix4fv(location, count, transpose, value); +} + +void GLES1Renderer::setUniform4fv(Program *programObject, + UniformLocation location, + GLint count, + const GLfloat *value) +{ + if (location.value == -1) + return; + programObject->setUniform4fv(location, count, value); +} + +void GLES1Renderer::setUniform3fv(Program *programObject, + UniformLocation location, + GLint count, + const GLfloat *value) +{ + if (location.value == -1) + return; + programObject->setUniform3fv(location, count, value); +} + +void GLES1Renderer::setUniform2fv(Program *programObject, + UniformLocation location, + GLint count, + const GLfloat *value) +{ + if (location.value == -1) + return; + programObject->setUniform2fv(location, count, value); +} + +void GLES1Renderer::setUniform1f(Program *programObject, UniformLocation location, GLfloat value) +{ + if (location.value == -1) + return; + programObject->setUniform1fv(location, 1, &value); +} + +void GLES1Renderer::setUniform1fv(Program *programObject, + UniformLocation location, + GLint count, + const GLfloat *value) +{ + if (location.value == -1) + return; + programObject->setUniform1fv(location, count, value); +} + +void GLES1Renderer::setAttributesEnabled(Context *context, State *glState, AttributesMask mask) +{ + GLES1State &gles1 = glState->gles1(); + + ClientVertexArrayType nonTexcoordArrays[] = { + ClientVertexArrayType::Vertex, + ClientVertexArrayType::Normal, + ClientVertexArrayType::Color, + ClientVertexArrayType::PointSize, + }; + + for (const ClientVertexArrayType attrib : nonTexcoordArrays) + { + int index = VertexArrayIndex(attrib, glState->gles1()); + + if (mask.test(index)) + { + gles1.setClientStateEnabled(attrib, true); + context->enableVertexAttribArray(index); + } + else + { + gles1.setClientStateEnabled(attrib, false); + context->disableVertexAttribArray(index); + } + } + + for (unsigned int i = 0; i < kTexUnitCount; i++) + { + int index = TexCoordArrayIndex(i); + + if (mask.test(index)) + { + gles1.setTexCoordArrayEnabled(i, true); + context->enableVertexAttribArray(index); + } + else + { + gles1.setTexCoordArrayEnabled(i, false); + context->disableVertexAttribArray(index); + } + } +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/GLES1Renderer.h b/gfx/angle/checkout/src/libANGLE/GLES1Renderer.h new file mode 100644 index 0000000000..5694b79752 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/GLES1Renderer.h @@ -0,0 +1,340 @@ +// +// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// GLES1Renderer.h: Defines GLES1 emulation rendering operations on top of a GLES3 +// context. Used by Context.h. + +#ifndef LIBANGLE_GLES1_RENDERER_H_ +#define LIBANGLE_GLES1_RENDERER_H_ + +#include "GLES1State.h" +#include "angle_gl.h" +#include "common/angleutils.h" +#include "libANGLE/angletypes.h" + +#include +#include +#include + +namespace gl +{ +class Context; +class GLES1State; +class Program; +class State; +class Shader; +class ShaderProgramManager; + +enum class GLES1StateEnables : uint64_t +{ + Lighting = 0, + Fog = 1, + ClipPlanes = 2, + DrawTexture = 3, + PointRasterization = 4, + PointSprite = 5, + RescaleNormal = 6, + Normalize = 7, + AlphaTest = 8, + ShadeModelFlat = 9, + ColorMaterial = 10, + LightModelTwoSided = 11, + LogicOpThroughFramebufferFetch = 12, + + InvalidEnum = 13, + EnumCount = 13, +}; + +constexpr int kClipPlaneCount = 6; +constexpr int kTexUnitCount = 4; +constexpr int kLightCount = 8; + +using GLES1StateEnabledBitSet = angle::PackedEnumBitSet; + +struct GLES1ShaderState +{ + GLES1ShaderState(); + ~GLES1ShaderState(); + GLES1ShaderState(const GLES1ShaderState &other); + + size_t hash() const; + + GLES1StateEnabledBitSet mGLES1StateEnabled; + + using BoolLightArray = bool[kLightCount]; + using BoolTexArray = bool[kTexUnitCount]; + using BoolClipPlaneArray = bool[kClipPlaneCount]; + using IntTexArray = int[kTexUnitCount]; + + BoolTexArray tex2DEnables = {false, false, false, false}; + BoolTexArray texCubeEnables = {false, false, false, false}; + + IntTexArray tex2DFormats = {GL_RGBA, GL_RGBA, GL_RGBA, GL_RGBA}; + + IntTexArray texEnvModes = {}; + IntTexArray texCombineRgbs = {}; + IntTexArray texCombineAlphas = {}; + IntTexArray texCombineSrc0Rgbs = {}; + IntTexArray texCombineSrc0Alphas = {}; + IntTexArray texCombineSrc1Rgbs = {}; + IntTexArray texCombineSrc1Alphas = {}; + IntTexArray texCombineSrc2Rgbs = {}; + IntTexArray texCombineSrc2Alphas = {}; + IntTexArray texCombineOp0Rgbs = {}; + IntTexArray texCombineOp0Alphas = {}; + IntTexArray texCombineOp1Rgbs = {}; + IntTexArray texCombineOp1Alphas = {}; + IntTexArray texCombineOp2Rgbs = {}; + IntTexArray texCombineOp2Alphas = {}; + + BoolTexArray pointSpriteCoordReplaces = {}; + + BoolLightArray lightEnables = {}; + + BoolClipPlaneArray clipPlaneEnables = {}; + + AlphaTestFunc alphaTestFunc = {}; + + FogMode fogMode = {}; +}; + +bool operator==(const GLES1ShaderState &a, const GLES1ShaderState &b); +bool operator!=(const GLES1ShaderState &a, const GLES1ShaderState &b); + +} // namespace gl + +namespace std +{ +template <> +struct hash +{ + size_t operator()(const gl::GLES1ShaderState &key) const { return key.hash(); } +}; +} // namespace std + +namespace gl +{ + +class GLES1Renderer final : angle::NonCopyable +{ + public: + GLES1Renderer(); + ~GLES1Renderer(); + + void onDestroy(Context *context, State *state); + + angle::Result prepareForDraw(PrimitiveMode mode, Context *context, State *glState); + + static int VertexArrayIndex(ClientVertexArrayType type, const GLES1State &gles1); + static ClientVertexArrayType VertexArrayType(int attribIndex); + static int TexCoordArrayIndex(unsigned int unit); + + void drawTexture(Context *context, + State *glState, + float x, + float y, + float z, + float width, + float height); + + private: + using Mat4Uniform = float[16]; + using Vec4Uniform = float[4]; + using Vec3Uniform = float[3]; + + Shader *getShader(ShaderProgramID handle) const; + Program *getProgram(ShaderProgramID handle) const; + + angle::Result compileShader(Context *context, + ShaderType shaderType, + const char *src, + ShaderProgramID *shaderOut); + angle::Result linkProgram(Context *context, + State *glState, + ShaderProgramID vshader, + ShaderProgramID fshader, + const angle::HashMap &attribLocs, + ShaderProgramID *programOut); + angle::Result initializeRendererProgram(Context *context, State *glState); + + void setUniform1i(Context *context, + Program *programObject, + UniformLocation location, + GLint value); + void setUniform1ui(Program *programObject, UniformLocation location, GLuint value); + void setUniform1iv(Context *context, + Program *programObject, + UniformLocation location, + GLint count, + const GLint *value); + void setUniformMatrix4fv(Program *programObject, + UniformLocation location, + GLint count, + GLboolean transpose, + const GLfloat *value); + void setUniform4fv(Program *programObject, + UniformLocation location, + GLint count, + const GLfloat *value); + void setUniform3fv(Program *programObject, + UniformLocation location, + GLint count, + const GLfloat *value); + void setUniform2fv(Program *programObject, + UniformLocation location, + GLint count, + const GLfloat *value); + void setUniform1f(Program *programObject, UniformLocation location, GLfloat value); + void setUniform1fv(Program *programObject, + UniformLocation location, + GLint count, + const GLfloat *value); + + void setAttributesEnabled(Context *context, State *glState, AttributesMask mask); + + static constexpr int kVertexAttribIndex = 0; + static constexpr int kNormalAttribIndex = 1; + static constexpr int kColorAttribIndex = 2; + static constexpr int kPointSizeAttribIndex = 3; + static constexpr int kTextureCoordAttribIndexBase = 4; + + bool mRendererProgramInitialized; + ShaderProgramManager *mShaderPrograms; + + GLES1ShaderState mShaderState = {}; + + const char *getShaderBool(GLES1StateEnables state); + void addShaderDefine(std::stringstream &outStream, + GLES1StateEnables state, + const char *enableString); + void addShaderInt(std::stringstream &outStream, const char *name, int value); + void addShaderIntTexArray(std::stringstream &outStream, + const char *texString, + GLES1ShaderState::IntTexArray &texState); + void addShaderBoolTexArray(std::stringstream &outStream, + const char *texString, + GLES1ShaderState::BoolTexArray &texState); + void addShaderBoolLightArray(std::stringstream &outStream, + const char *name, + GLES1ShaderState::BoolLightArray &value); + void addShaderBoolClipPlaneArray(std::stringstream &outStream, + const char *name, + GLES1ShaderState::BoolClipPlaneArray &value); + void addVertexShaderDefs(std::stringstream &outStream); + void addFragmentShaderDefs(std::stringstream &outStream); + + struct GLES1ProgramState + { + ShaderProgramID program; + + UniformLocation projMatrixLoc; + UniformLocation modelviewMatrixLoc; + UniformLocation textureMatrixLoc; + UniformLocation modelviewInvTrLoc; + + // Texturing + std::array tex2DSamplerLocs; + std::array texCubeSamplerLocs; + + UniformLocation textureEnvColorLoc; + UniformLocation rgbScaleLoc; + UniformLocation alphaScaleLoc; + + // Alpha test + UniformLocation alphaTestRefLoc; + + // Shading, materials, and lighting + UniformLocation materialAmbientLoc; + UniformLocation materialDiffuseLoc; + UniformLocation materialSpecularLoc; + UniformLocation materialEmissiveLoc; + UniformLocation materialSpecularExponentLoc; + + UniformLocation lightModelSceneAmbientLoc; + + UniformLocation lightAmbientsLoc; + UniformLocation lightDiffusesLoc; + UniformLocation lightSpecularsLoc; + UniformLocation lightPositionsLoc; + UniformLocation lightDirectionsLoc; + UniformLocation lightSpotlightExponentsLoc; + UniformLocation lightSpotlightCutoffAnglesLoc; + UniformLocation lightAttenuationConstsLoc; + UniformLocation lightAttenuationLinearsLoc; + UniformLocation lightAttenuationQuadraticsLoc; + + // Fog + UniformLocation fogDensityLoc; + UniformLocation fogStartLoc; + UniformLocation fogEndLoc; + UniformLocation fogColorLoc; + + // Clip planes + UniformLocation clipPlanesLoc; + + // Logic op + UniformLocation logicOpLoc; + + // Point rasterization + UniformLocation pointSizeMinLoc; + UniformLocation pointSizeMaxLoc; + UniformLocation pointDistanceAttenuationLoc; + + // Draw texture + UniformLocation drawTextureCoordsLoc; + UniformLocation drawTextureDimsLoc; + UniformLocation drawTextureNormalizedCropRectLoc; + }; + + struct GLES1UniformBuffers + { + std::array textureMatrices; + + std::array texEnvColors; + std::array texEnvRgbScales; + std::array texEnvAlphaScales; + + // Lighting + std::array lightAmbients; + std::array lightDiffuses; + std::array lightSpeculars; + std::array lightPositions; + std::array lightDirections; + std::array spotlightExponents; + std::array spotlightCutoffAngles; + std::array attenuationConsts; + std::array attenuationLinears; + std::array attenuationQuadratics; + + // Clip planes + std::array clipPlanes; + + // Texture crop rectangles + std::array texCropRects; + }; + + struct GLES1UberShaderState + { + GLES1UniformBuffers uniformBuffers; + GLES1ProgramState programState; + }; + + GLES1UberShaderState &getUberShaderState() + { + ASSERT(mUberShaderState.find(mShaderState) != mUberShaderState.end()); + return mUberShaderState[mShaderState]; + } + + angle::HashMap mUberShaderState; + + bool mDrawTextureEnabled = false; + GLfloat mDrawTextureCoords[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + GLfloat mDrawTextureDims[2] = {0.0f, 0.0f}; +}; + +} // namespace gl + +#endif // LIBANGLE_GLES1_RENDERER_H_ diff --git a/gfx/angle/checkout/src/libANGLE/GLES1Shaders.inc b/gfx/angle/checkout/src/libANGLE/GLES1Shaders.inc new file mode 100644 index 0000000000..1c1ff51927 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/GLES1Shaders.inc @@ -0,0 +1,1218 @@ +// +// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// GLES1Shaders.inc: Defines GLES1 emulation shader. + +// The following variables are added in GLES1Renderer::initializeRendererProgram +// bool clip_plane_enables +// bool enable_alpha_test +// bool enable_clip_planes +// bool enable_color_material +// bool enable_draw_texture +// bool enable_fog +// bool enable_lighting +// bool enable_normalize +// bool enable_rescale_normal +// bool enable_texture_2d[kMaxTexUnits] +// bool enable_texture_cube_map[kMaxTexUnits] +// bool light_enables[kMaxLights] +// bool light_model_two_sided +// bool point_rasterization +// bool point_sprite_coord_replace +// bool point_sprite_enabled +// bool shade_model_flat +// int texture_format[kMaxTexUnits]; +// int texture_env_mode[kMaxTexUnits]; +// int combine_rgb[kMaxTexUnits]; +// int combine_alpha[kMaxTexUnits]; +// int src0_rgb[kMaxTexUnits]; +// int src0_alpha[kMaxTexUnits]; +// int src1_rgb[kMaxTexUnits]; +// int src1_alpha[kMaxTexUnits]; +// int src2_rgb[kMaxTexUnits]; +// int src2_alpha[kMaxTexUnits]; +// int op0_rgb[kMaxTexUnits]; +// int op0_alpha[kMaxTexUnits]; +// int op1_rgb[kMaxTexUnits]; +// int op1_alpha[kMaxTexUnits]; +// int op2_rgb[kMaxTexUnits]; +// int op2_alpha[kMaxTexUnits]; +// int alpha_func; +// int fog_mode; + +constexpr char kGLES1DrawVShaderHeader[] = R"(#version 300 es +precision highp float; + +#define kMaxTexUnits 4 +#define kMaxLights 8 +)"; + +constexpr char kGLES1DrawVShader[] = R"( + +in vec4 pos; +in vec3 normal; +in vec4 color; +in float pointsize; +in vec4 texcoord0; +in vec4 texcoord1; +in vec4 texcoord2; +in vec4 texcoord3; + +uniform mat4 projection; +uniform mat4 modelview; +uniform mat4 modelview_invtr; +uniform mat4 texture_matrix[kMaxTexUnits]; + +// Point rasterization////////////////////////////////////////////////////////// + +uniform float point_size_min; +uniform float point_size_max; +uniform vec3 point_distance_attenuation; + +// Shading: flat shading, lighting, and materials/////////////////////////////// + +uniform vec4 material_ambient; +uniform vec4 material_diffuse; +uniform vec4 material_specular; +uniform vec4 material_emissive; +uniform float material_specular_exponent; + +uniform vec4 light_model_scene_ambient; + +uniform vec4 light_ambients[kMaxLights]; +uniform vec4 light_diffuses[kMaxLights]; +uniform vec4 light_speculars[kMaxLights]; +uniform vec4 light_positions[kMaxLights]; +uniform vec3 light_directions[kMaxLights]; +uniform float light_spotlight_exponents[kMaxLights]; +uniform float light_spotlight_cutoff_angles[kMaxLights]; +uniform float light_attenuation_consts[kMaxLights]; +uniform float light_attenuation_linears[kMaxLights]; +uniform float light_attenuation_quadratics[kMaxLights]; + +// GL_OES_draw_texture uniforms///////////////////////////////////////////////// + +uniform vec4 draw_texture_coords; +uniform vec2 draw_texture_dims; +uniform vec4 draw_texture_normalized_crop_rect[kMaxTexUnits]; + +// Varyings///////////////////////////////////////////////////////////////////// + +out vec4 pos_varying; +out vec3 normal_varying; +out vec4 color_varying; +flat out vec4 color_varying_flat; +out vec4 texcoord0_varying; +out vec4 texcoord1_varying; +out vec4 texcoord2_varying; +out vec4 texcoord3_varying; + +float posDot(vec3 a, vec3 b) +{ + return max(dot(a, b), 0.0); +} + +vec4 doLighting(vec4 vertexColor) +{ + vec4 materialAmbientActual = material_ambient; + vec4 materialDiffuseActual = material_diffuse; + + if (enable_color_material) + { + materialAmbientActual = vertexColor; + materialDiffuseActual = vertexColor; + } + + vec4 lightingResult = material_emissive + materialAmbientActual * light_model_scene_ambient; + + for (int i = 0; i < kMaxLights; i++) + { + + if (!light_enables[i]) + continue; + + vec4 lightAmbient = light_ambients[i]; + vec4 lightDiffuse = light_diffuses[i]; + vec4 lightSpecular = light_speculars[i]; + vec4 lightPos = light_positions[i]; + vec3 lightDir = light_directions[i]; + float attConst = light_attenuation_consts[i]; + float attLinear = light_attenuation_linears[i]; + float attQuadratic = light_attenuation_quadratics[i]; + float spotAngle = light_spotlight_cutoff_angles[i]; + float spotExponent = light_spotlight_exponents[i]; + + vec3 toLight; + if (lightPos.w == 0.0) + { + toLight = lightPos.xyz; + } + else + { + toLight = (lightPos.xyz / lightPos.w - pos_varying.xyz); + } + + float lightDist = length(toLight); + vec3 h = normalize(toLight) + vec3(0.0, 0.0, 1.0); + float ndotL = posDot(normal_varying, normalize(toLight)); + float ndoth = posDot(normal_varying, normalize(h)); + + float specAtt; + + if (ndotL != 0.0) + { + specAtt = 1.0; + } + else + { + specAtt = 0.0; + } + + float att; + + if (lightPos.w != 0.0) + { + float attDenom = + (attConst + attLinear * lightDist + attQuadratic * lightDist * lightDist); + att = 1.0 / attDenom; + } + else + { + att = 1.0; + } + + float spot; + + float spotAngleCos = cos(radians(spotAngle)); + vec3 toSurfaceDir = -normalize(toLight); + float spotDot = posDot(toSurfaceDir, normalize(lightDir)); + + if (spotAngle == 180.0 || lightPos.w == 0.0) + { + spot = 1.0; + } + else + { + if (spotDot < spotAngleCos) + { + spot = 0.0; + } + else + { + spot = pow(spotDot, spotExponent); + } + } + + vec4 contrib = materialAmbientActual * lightAmbient; + contrib += ndotL * materialDiffuseActual * lightDiffuse; + if (ndoth > 0.0 && material_specular_exponent > 0.0) + { + contrib += specAtt * pow(ndoth, material_specular_exponent) * material_specular * + lightSpecular; + } + else + { + if (ndoth > 0.0) + { + contrib += specAtt * material_specular * lightSpecular; + } + } + contrib *= att * spot; + lightingResult += contrib; + } + + return lightingResult; +} + +const vec4 drawTextureVertices[6] = vec4[]( + vec4(0.0, 0.0, 0.0, 1.0), + vec4(1.0, 0.0, 0.0, 1.0), + vec4(1.0, 1.0, 0.0, 1.0), + vec4(0.0, 0.0, 0.0, 1.0), + vec4(1.0, 1.0, 0.0, 1.0), + vec4(0.0, 1.0, 0.0, 1.0)); + +vec4 drawTexturePosition(int vertexId) +{ + + float drawTexX = draw_texture_coords[0]; + float drawTexY = draw_texture_coords[1]; + float drawTexZ = draw_texture_coords[2]; + float drawTexW = draw_texture_dims[0]; + float drawTexH = draw_texture_dims[1]; + + return vec4(drawTexX, drawTexY, drawTexZ, 0.0) + + drawTextureVertices[vertexId] * + vec4(drawTexW, drawTexH, 1.0, 1.0); +} + +vec4 drawTextureTexCoord(int vertexId, int textureUnit) +{ + float texCropU = draw_texture_normalized_crop_rect[textureUnit].x; + float texCropV = draw_texture_normalized_crop_rect[textureUnit].y; + float texCropW = draw_texture_normalized_crop_rect[textureUnit].z; + float texCropH = draw_texture_normalized_crop_rect[textureUnit].w; + + return vec4(texCropU, texCropV, 0.0, 0.0) + + drawTextureVertices[vertexId] * + vec4(texCropW, texCropH, 0.0, 0.0); +} + +vec4 calcWorldPosition(vec4 posInput) +{ + return modelview * posInput; +} + +vec4 calcNdcFromWorldPosition(vec4 worldPos) +{ + return projection * worldPos; +} + +float calcPointSize(vec4 ndcPos) +{ + float dist = length(ndcPos.z); + float attConst = point_distance_attenuation[0]; + float attLinear = point_distance_attenuation[1]; + float attQuad = point_distance_attenuation[2]; + float attPart = attConst + attLinear * dist + attQuad * dist * dist; + float attPointSize = pointsize / pow(attPart, 0.5); + + return clamp(attPointSize, point_size_min, point_size_max); +} + +vec3 calcNormal(vec3 normalInput) +{ + mat3 mvInvTr3 = mat3(modelview_invtr); + vec3 result = mvInvTr3 * normalInput; + + if (enable_rescale_normal) + { + float rescale = 1.0; + vec3 rescaleVec = vec3(mvInvTr3[2]); + float len = length(rescaleVec); + if (len > 0.0) + { + rescale = 1.0 / len; + } + result *= rescale; + } + + if (enable_normalize) + { + result = normalize(result); + } + + return result; +} + +void main() +{ + if (enable_draw_texture) + { + int vertexId = gl_VertexID; + vec4 posDrawTexture = drawTexturePosition(vertexId); + + gl_Position = posDrawTexture; + pos_varying = posDrawTexture; + + normal_varying = normal; + + gl_PointSize = pointsize; + + texcoord0_varying = drawTextureTexCoord(vertexId, 0); + texcoord1_varying = drawTextureTexCoord(vertexId, 1); + texcoord2_varying = drawTextureTexCoord(vertexId, 2); + texcoord3_varying = drawTextureTexCoord(vertexId, 3); + } + else + { + vec4 worldPos = calcWorldPosition(pos); + vec4 ndcPos = calcNdcFromWorldPosition(worldPos); + + gl_Position = ndcPos; + pos_varying = worldPos; + + normal_varying = calcNormal(normal); + + // Avoid calculating point size stuff + // if we are not rendering points. + if (point_rasterization) + { + gl_PointSize = calcPointSize(ndcPos); + } + else + { + gl_PointSize = pointsize; + } + + texcoord0_varying = texture_matrix[0] * texcoord0; + texcoord1_varying = texture_matrix[1] * texcoord1; + texcoord2_varying = texture_matrix[2] * texcoord2; + texcoord3_varying = texture_matrix[3] * texcoord3; + } + + vec4 vertex_color = color; + + if (enable_lighting) + { + vertex_color = doLighting(color); + } + + vertex_color = clamp(vertex_color, vec4(0), vec4(1)); + + color_varying = vertex_color; + color_varying_flat = vertex_color; +} +)"; + +constexpr char kGLES1DrawFShaderVersion[] = R"(#version 300 es +)"; + +constexpr char kGLES1DrawFShaderHeader[] = R"(precision highp float; + +// Defines for GL constants +#define kMaxTexUnits 4 +#define kMaxClipPlanes 6 + +#define kModulate 0x2100 +#define kDecal 0x2101 +#define kCombine 0x8570 +#define kReplace 0x1E01 +#define kBlend 0x0BE2 +#define kAdd 0x0104 + +#define kAddSigned 0x8574 +#define kInterpolate 0x8575 +#define kSubtract 0x84E7 +#define kDot3Rgb 0x86AE +#define kDot3Rgba 0x86AF + +#define kAlpha 0x1906 +#define kRGB 0x1907 +#define kRGBA 0x1908 +#define kLuminance 0x1909 +#define kLuminanceAlpha 0x190A + +#define kTexture 0x1702 +#define kConstant 0x8576 +#define kPrimaryColor 0x8577 +#define kPrevious 0x8578 + +#define kSrcColor 0x0300 +#define kOneMinusSrcColor 0x0301 +#define kSrcAlpha 0x0302 +#define kOneMinusSrcAlpha 0x0303 + +#define kLinear 0x2601 +#define kExp 0x0800 +#define kExp2 0x0801 + +#define kNever 0x0200 +#define kLess 0x0201 +#define kEqual 0x0202 +#define kLequal 0x0203 +#define kGreater 0x0204 +#define kNotequal 0x0205 +#define kGequal 0x0206 +#define kAlways 0x0207 +#define kZero 0x0 +#define kOne 0x1 + +#define kAnd 0u +#define kAndInverted 1u +#define kAndReverse 2u +#define kClear 3u +#define kCopy 4u +#define kCopyInverted 5u +#define kEquiv 6u +#define kInvert 7u +#define kNand 8u +#define kNoop 9u +#define kNor 10u +#define kOr 11u +#define kOrInverted 12u +#define kOrReverse 13u +#define kSet 14u +#define kXor 15u +)"; + +constexpr char kGLES1DrawFShaderUniformDefs[] = R"( + +// Texture units /////////////////////////////////////////////////////////////// + +// These are not arrays because hw support for arrays +// of samplers is rather lacking. + +uniform sampler2D tex_sampler0; +uniform samplerCube tex_cube_sampler0; + +uniform sampler2D tex_sampler1; +uniform samplerCube tex_cube_sampler1; + +uniform sampler2D tex_sampler2; +uniform samplerCube tex_cube_sampler2; + +uniform sampler2D tex_sampler3; +uniform samplerCube tex_cube_sampler3; + +uniform vec4 texture_env_color[kMaxTexUnits]; +uniform float texture_env_rgb_scale[kMaxTexUnits]; +uniform float texture_env_alpha_scale[kMaxTexUnits]; + +// Vertex attributes//////////////////////////////////////////////////////////// + +in vec4 pos_varying; +in vec3 normal_varying; +in vec4 color_varying; +flat in vec4 color_varying_flat; +in vec4 texcoord0_varying; +in vec4 texcoord1_varying; +in vec4 texcoord2_varying; +in vec4 texcoord3_varying; + +// Alpha test/////////////////////////////////////////////////////////////////// + +uniform float alpha_test_ref; + +// Fog ///////////////////////////////////////////////////////////////////////// + +uniform float fog_density; +uniform float fog_start; +uniform float fog_end; +uniform vec4 fog_color; + +// User clip plane ///////////////////////////////////////////////////////////// + +uniform vec4 clip_planes[kMaxClipPlanes]; + +// Logic Op //////////////////////////////////////////////////////////////////// + +// Format is: +// - 4x4 bits depicting the bit width of each channel of color output +// - 4 bits for the op based on LogicalOperation's packing +uniform highp uint logic_op; + +// Point rasterization////////////////////////////////////////////////////////// + +// GL_OES_draw_texture////////////////////////////////////////////////////////// +)"; + +constexpr char kGLES1DrawFShaderOutputDef[] = R"( +out vec4 frag_color; +)"; + +constexpr char kGLES1DrawFShaderFramebufferFetchOutputDef[] = R"( +inout vec4 frag_color; +)"; + +constexpr char kGLES1DrawFShaderFramebufferFetchNonCoherentOutputDef[] = R"( +layout(noncoherent) inout vec4 frag_color; +)"; + +constexpr char kGLES1DrawFShaderFunctions[] = R"( + +bool doAlphaTest(vec4 currentFragment) +{ + bool shouldPassAlpha = false; + float incAlpha = currentFragment.a; + + switch (alpha_func) + { + case kNever: + shouldPassAlpha = false; + break; + case kLess: + shouldPassAlpha = incAlpha < alpha_test_ref; + break; + case kLequal: + shouldPassAlpha = incAlpha <= alpha_test_ref; + break; + case kEqual: + shouldPassAlpha = incAlpha == alpha_test_ref; + break; + case kGequal: + shouldPassAlpha = incAlpha >= alpha_test_ref; + break; + case kGreater: + shouldPassAlpha = incAlpha > alpha_test_ref; + break; + case kNotequal: + shouldPassAlpha = incAlpha != alpha_test_ref; + break; + case kAlways: + default: + shouldPassAlpha = true; + break; + } + + return shouldPassAlpha; +} + +bool doClipPlaneTest() +{ + bool res = true; + + for (int i = 0; i < kMaxClipPlanes; i++) + { + if (clip_plane_enables[i]) + { + float dist = dot(clip_planes[i].xyz, pos_varying.xyz) + clip_planes[i].w * pos_varying.w; + res = res && (dist >= 0.0); + } + } + + return res; +} + +vec4 doFog(vec4 currentFragment) +{ + + float eyeDist = -pos_varying.z / pos_varying.w; + float f = 1.0; + switch (fog_mode) + { + case kExp: + f = exp(-fog_density * eyeDist); + break; + case kExp2: + f = exp(-(pow(fog_density * eyeDist, 2.0))); + break; + case kLinear: + f = (fog_end - eyeDist) / (fog_end - fog_start); + break; + default: + break; + } + + f = clamp(f, 0.0, 1.0); + vec4 result = vec4(f * currentFragment.rgb + (1.0 - f) * fog_color.rgb, currentFragment.a); + return result; +} +)"; + +constexpr char kGLES1DrawFShaderLogicOpFramebufferFetchDisabled[] = R"( +vec4 applyLogicOp(vec4 currentFragment) +{ + return currentFragment; +} +)"; + +// applyLogicOp takes logic-op information from a packed uniform and applies it to the color +// attachment using framebuffer fetch. See the description of logic_op above for the format of the +// uniform. +// +// In particular, 4 bits in logic_op (at offset 16) contain the packed logical operation (of +// LogicalOperation type). Based on the selected operation, the formula specified in the spec is +// applied (applied as bitwise operations on unorm values). +constexpr char kGLES1DrawFShaderLogicOpFramebufferFetchEnabled[] = R"( +vec4 applyLogicOp(vec4 currentFragment) +{ + vec4 previousFragment = frag_color; + + mediump uvec4 channelWidths = uvec4(logic_op & 0xFu, + logic_op >> 4u & 0xFu, + logic_op >> 8u & 0xFu, + logic_op >> 12u & 0xFu); + + mediump uvec4 channelMasks = (uvec4(1) << channelWidths) - 1u; + + mediump uvec4 src = uvec4(round(currentFragment * vec4(channelMasks))); + mediump uvec4 dst = uvec4(round(previousFragment * vec4(channelMasks))); + mediump uvec4 result; + + switch (logic_op >> 16u & 0xFu) + { + case kAnd: + result = src & dst; + break; + case kAndInverted: + result = ~src & dst; + break; + case kAndReverse: + result = src & ~dst; + break; + case kClear: + result = uvec4(0); + break; + case kCopy: + result = src; + break; + case kCopyInverted: + result = ~src; + break; + case kEquiv: + result = ~(src ^ dst); + break; + case kInvert: + result = ~dst; + break; + case kNand: + result = ~(src & dst); + break; + case kNoop: + result = dst; + break; + case kNor: + result = ~(src | dst); + break; + case kOr: + result = src | dst; + break; + case kOrInverted: + result = ~src | dst; + break; + case kOrReverse: + result = src | ~dst; + break; + case kSet: + result = channelMasks; + break; + case kXor: + result = src ^ dst; + break; + } + + result &= channelMasks; + + // Avoid division by zero for formats without alpha + channelMasks.a = max(channelMasks.a, 1u); + + return vec4(result) / vec4(channelMasks); +} +)"; + +constexpr char kGLES1DrawFShaderMultitexturing[] = R"( + +bool isTextureUnitEnabled(int unit) +{ + return enable_texture_2d[unit] || enable_texture_cube_map[unit]; +} + +vec4 getTextureColor(int unit) +{ + vec4 res; + + switch (unit) + { + case 0: + if (enable_texture_2d[0]) + { + res = texture(tex_sampler0, texcoord0_varying.xy); + } + else if (enable_texture_cube_map[0]) + { + res = texture(tex_cube_sampler0, texcoord0_varying.xyz); + } + break; + case 1: + if (enable_texture_2d[1]) + { + res = texture(tex_sampler1, texcoord1_varying.xy); + } + else if (enable_texture_cube_map[1]) + { + res = texture(tex_cube_sampler1, texcoord1_varying.xyz); + } + break; + case 2: + if (enable_texture_2d[2]) + { + res = texture(tex_sampler2, texcoord2_varying.xy); + } + else if (enable_texture_cube_map[2]) + { + res = texture(tex_cube_sampler2, texcoord2_varying.xyz); + } + break; + case 3: + if (enable_texture_2d[3]) + { + res = texture(tex_sampler3, texcoord3_varying.xy); + } + else if (enable_texture_cube_map[3]) + { + // TODO: Weird stuff happens + // res = texture(tex_cube_sampler3, texcoord3_varying.xyz); + } + break; + default: + break; + } + + return res; +} + +vec4 getPointSpriteTextureColor(int unit) +{ + vec4 res; + + switch (unit) + { + case 0: + if (enable_texture_2d[0]) + { + res = texture(tex_sampler0, gl_PointCoord.xy); + } + break; + case 1: + if (enable_texture_2d[1]) + { + res = texture(tex_sampler1, gl_PointCoord.xy); + } + break; + case 2: + if (enable_texture_2d[2]) + { + res = texture(tex_sampler2, gl_PointCoord.xy); + } + break; + case 3: + if (enable_texture_2d[3]) + { + res = texture(tex_sampler3, gl_PointCoord.xy); + } + break; + default: + break; + } + + return res; +} + +vec3 textureCombineSrcnOpnRgb(int srcnRgb, + int opnRgb, + vec4 textureEnvColor, + vec4 vertexColor, + vec4 texturePrevColor, + vec4 textureColor) +{ + vec3 res; + vec4 op; + + switch (srcnRgb) + { + case kTexture: + op = textureColor; + break; + case kConstant: + op = textureEnvColor; + break; + case kPrimaryColor: + op = vertexColor; + break; + case kPrevious: + op = texturePrevColor; + break; + default: + op = texturePrevColor; + break; + } + + switch (opnRgb) + { + case kSrcColor: + res = op.rgb; + break; + case kOneMinusSrcColor: + res = 1.0 - op.rgb; + break; + case kSrcAlpha: + res = vec3(op.a, op.a, op.a); + break; + case kOneMinusSrcAlpha: + res = vec3(1.0 - op.a, 1.0 - op.a, 1.0 - op.a); + break; + default: + break; + } + + return res; +} + +float textureCombineSrcnOpnAlpha(int srcn, + int opn, + vec4 textureEnvColor, + vec4 vertexColor, + vec4 texturePrevColor, + vec4 textureColor) +{ + float res; + vec4 op; + + switch (srcn) + { + case kTexture: + op = textureColor; + break; + case kConstant: + op = textureEnvColor; + break; + case kPrimaryColor: + op = vertexColor; + break; + case kPrevious: + op = texturePrevColor; + break; + default: + op = texturePrevColor; + break; + } + + switch (opn) + { + case kSrcAlpha: + res = op.a; + break; + case kOneMinusSrcAlpha: + res = 1.0 - op.a; + break; + default: + break; + } + + return res; +} + +vec4 textureCombine(int combineRgb, + int combineAlpha, + int src0Rgb, + int src0Alpha, + int src1Rgb, + int src1Alpha, + int src2Rgb, + int src2Alpha, + int op0Rgb, + int op0Alpha, + int op1Rgb, + int op1Alpha, + int op2Rgb, + int op2Alpha, + vec4 textureEnvColor, + float rgbScale, + float alphaScale, + vec4 vertexColor, + vec4 texturePrevColor, + vec4 textureColor) +{ + + vec3 resRgb; + float resAlpha; + + vec3 arg0Rgb; + float arg0Alpha; + vec3 arg1Rgb; + float arg1Alpha; + vec3 arg2Rgb; + float arg2Alpha; + float dotVal; + + arg0Rgb = textureCombineSrcnOpnRgb(src0Rgb, op0Rgb, textureEnvColor, vertexColor, + texturePrevColor, textureColor); + arg0Alpha = textureCombineSrcnOpnAlpha(src0Alpha, op0Alpha, textureEnvColor, vertexColor, + texturePrevColor, textureColor); + + if (combineRgb != kReplace) + { + arg1Rgb = textureCombineSrcnOpnRgb(src1Rgb, op1Rgb, textureEnvColor, vertexColor, + texturePrevColor, textureColor); + } + + if (combineAlpha != kReplace) + { + arg1Alpha = textureCombineSrcnOpnAlpha(src1Alpha, op1Alpha, textureEnvColor, vertexColor, + texturePrevColor, textureColor); + } + + if (combineRgb == kInterpolate) + { + arg2Rgb = textureCombineSrcnOpnRgb(src2Rgb, op2Rgb, textureEnvColor, vertexColor, + texturePrevColor, textureColor); + } + + if (combineAlpha == kInterpolate) + { + arg2Alpha = textureCombineSrcnOpnAlpha(src2Alpha, op2Alpha, textureEnvColor, vertexColor, + texturePrevColor, textureColor); + } + + switch (combineRgb) + { + case kReplace: + resRgb = arg0Rgb; + break; + case kModulate: + resRgb = arg0Rgb * arg1Rgb; + break; + case kAdd: + resRgb = arg0Rgb + arg1Rgb; + break; + case kAddSigned: + resRgb = arg0Rgb + arg1Rgb - 0.5; + break; + case kInterpolate: + resRgb = arg0Rgb * arg2Rgb + arg1Rgb * (1.0 - arg2Rgb); + break; + case kSubtract: + resRgb = arg0Rgb - arg1Rgb; + break; + default: + break; + } + + switch (combineAlpha) + { + case kReplace: + resAlpha = arg0Alpha; + break; + case kModulate: + resAlpha = arg0Alpha * arg1Alpha; + break; + case kAdd: + resAlpha = arg0Alpha + arg1Alpha; + break; + case kAddSigned: + resAlpha = arg0Alpha + arg1Alpha - 0.5; + break; + case kInterpolate: + resAlpha = arg0Alpha * arg2Alpha + arg1Alpha * (1.0 - arg2Alpha); + break; + case kSubtract: + resAlpha = arg0Alpha - arg1Alpha; + break; + default: + break; + } + + if (combineRgb == kDot3Rgb || combineRgb == kDot3Rgba) + { + dotVal = 4.0 * dot(arg0Rgb - 0.5, arg1Rgb - 0.5); + + if (combineRgb == kDot3Rgb) + { + return vec4(dotVal, dotVal, dotVal, resAlpha); + } + else + { + return vec4(dotVal, dotVal, dotVal, dotVal); + } + } + else + { + return vec4(resRgb, resAlpha); + } +} + +vec4 textureFunction(int unit, + int texFormat, + int envMode, + int combineRgb, + int combineAlpha, + int src0Rgb, + int src0Alpha, + int src1Rgb, + int src1Alpha, + int src2Rgb, + int src2Alpha, + int op0Rgb, + int op0Alpha, + int op1Rgb, + int op1Alpha, + int op2Rgb, + int op2Alpha, + vec4 textureEnvColor, + float rgbScale, + float alphaScale, + vec4 vertexColor, + vec4 texturePrevColor, + vec4 textureColor) +{ + + if (!isTextureUnitEnabled(unit)) + { + return texturePrevColor; + } + + vec4 res; + + switch (envMode) + { + case kReplace: + switch (texFormat) + { + case kAlpha: + res.rgb = texturePrevColor.rgb; + res.a = textureColor.a; + break; + case kRGBA: + case kLuminanceAlpha: + res.rgba = textureColor.rgba; + break; + case kRGB: + case kLuminance: + default: + res.rgb = textureColor.rgb; + res.a = texturePrevColor.a; + break; + } + break; + case kModulate: + switch (texFormat) + { + case kAlpha: + res.rgb = texturePrevColor.rgb; + res.a = texturePrevColor.a * textureColor.a; + break; + case kRGBA: + case kLuminanceAlpha: + res.rgba = texturePrevColor.rgba * textureColor.rgba; + break; + case kRGB: + case kLuminance: + default: + res.rgb = texturePrevColor.rgb * textureColor.rgb; + res.a = texturePrevColor.a; + break; + } + break; + case kDecal: + switch (texFormat) + { + case kRGB: + res.rgb = textureColor.rgb; + res.a = texturePrevColor.a; + break; + case kRGBA: + res.rgb = texturePrevColor.rgb * (1.0 - textureColor.a) + + textureColor.rgb * textureColor.a; + res.a = texturePrevColor.a; + break; + case kAlpha: + case kLuminance: + case kLuminanceAlpha: + default: + res.rgb = texturePrevColor.rgb * textureColor.rgb; + res.a = texturePrevColor.a; + break; + } + break; + case kBlend: + switch (texFormat) + { + case kAlpha: + res.rgb = texturePrevColor.rgb; + res.a = textureColor.a * texturePrevColor.a; + break; + case kLuminance: + case kRGB: + res.rgb = texturePrevColor.rgb * (1.0 - textureColor.rgb) + + textureEnvColor.rgb * textureColor.rgb; + res.a = texturePrevColor.a; + break; + case kLuminanceAlpha: + case kRGBA: + default: + res.rgb = texturePrevColor.rgb * (1.0 - textureColor.rgb) + + textureEnvColor.rgb * textureColor.rgb; + res.a = textureColor.a * texturePrevColor.a; + break; + } + break; + case kAdd: + switch (texFormat) + { + case kAlpha: + res.rgb = texturePrevColor.rgb; + res.a = textureColor.a * texturePrevColor.a; + break; + case kLuminance: + case kRGB: + res.rgb = texturePrevColor.rgb + textureColor.rgb; + res.a = texturePrevColor.a; + break; + case kLuminanceAlpha: + case kRGBA: + default: + res.rgb = texturePrevColor.rgb + textureColor.rgb; + res.a = textureColor.a * texturePrevColor.a; + break; + } + break; + case kCombine: + res = textureCombine(combineRgb, combineAlpha, src0Rgb, src0Alpha, src1Rgb, src1Alpha, + src2Rgb, src2Alpha, op0Rgb, op0Alpha, op1Rgb, op1Alpha, op2Rgb, + op2Alpha, textureEnvColor, rgbScale, alphaScale, vertexColor, + texturePrevColor, textureColor); + res.rgb *= rgbScale; + res.a *= alphaScale; + break; + default: + break; + } + + return clamp(res, 0.0, 1.0); +} +)"; + +constexpr char kGLES1DrawFShaderMain[] = R"( +void main() +{ + if (enable_clip_planes && !enable_draw_texture) + { + if (!doClipPlaneTest()) + { + discard; + } + } + + vec4 vertex_color; + + if (shade_model_flat) + { + vertex_color = color_varying_flat; + } + else + { + vertex_color = color_varying; + } + + vec4 currentFragment = vertex_color; + + vec4 texturePrevColor = currentFragment; + + for (int i = 0; i < kMaxTexUnits; i++) + { + vec4 textureColor; + + if (point_rasterization && point_sprite_enabled && + point_sprite_coord_replace[i]) { + textureColor = getPointSpriteTextureColor(i); + } else { + textureColor = getTextureColor(i); + } + + currentFragment = textureFunction( + i, texture_format[i], texture_env_mode[i], combine_rgb[i], combine_alpha[i], + src0_rgb[i], src0_alpha[i], src1_rgb[i], src1_alpha[i], src2_rgb[i], src2_alpha[i], + op0_rgb[i], op0_alpha[i], op1_rgb[i], op1_alpha[i], op2_rgb[i], op2_alpha[i], + texture_env_color[i], texture_env_rgb_scale[i], texture_env_alpha_scale[i], + vertex_color, texturePrevColor, textureColor); + + texturePrevColor = currentFragment; + } + + if (enable_fog) + { + currentFragment = doFog(currentFragment); + } + + if (enable_alpha_test && !doAlphaTest(currentFragment)) + { + discard; + } + + frag_color = applyLogicOp(currentFragment); +} +)"; diff --git a/gfx/angle/checkout/src/libANGLE/GLES1State.cpp b/gfx/angle/checkout/src/libANGLE/GLES1State.cpp new file mode 100644 index 0000000000..17ad0de3ad --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/GLES1State.cpp @@ -0,0 +1,609 @@ +// +// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// GLES1State.cpp: Implements the GLES1State class, tracking state +// for GLES1 contexts. + +#include "libANGLE/GLES1State.h" + +#include "libANGLE/Context.h" +#include "libANGLE/GLES1Renderer.h" + +namespace gl +{ + +TextureCoordF::TextureCoordF() = default; + +TextureCoordF::TextureCoordF(float _s, float _t, float _r, float _q) : s(_s), t(_t), r(_r), q(_q) {} + +bool TextureCoordF::operator==(const TextureCoordF &other) const +{ + return s == other.s && t == other.t && r == other.r && q == other.q; +} + +MaterialParameters::MaterialParameters() = default; + +LightModelParameters::LightModelParameters() = default; + +LightParameters::LightParameters() = default; + +LightParameters::LightParameters(const LightParameters &other) = default; + +FogParameters::FogParameters() = default; + +TextureEnvironmentParameters::TextureEnvironmentParameters() = default; + +TextureEnvironmentParameters::TextureEnvironmentParameters( + const TextureEnvironmentParameters &other) = default; + +PointParameters::PointParameters() = default; + +PointParameters::PointParameters(const PointParameters &other) = default; + +ClipPlaneParameters::ClipPlaneParameters() = default; + +ClipPlaneParameters::ClipPlaneParameters(bool enabled, const angle::Vector4 &equation) + : enabled(enabled), equation(equation) +{} + +ClipPlaneParameters::ClipPlaneParameters(const ClipPlaneParameters &other) = default; + +ClipPlaneParameters &ClipPlaneParameters::operator=(const ClipPlaneParameters &other) = default; + +GLES1State::GLES1State() + : mGLState(nullptr), + mVertexArrayEnabled(false), + mNormalArrayEnabled(false), + mColorArrayEnabled(false), + mPointSizeArrayEnabled(false), + mLineSmoothEnabled(false), + mPointSmoothEnabled(false), + mPointSpriteEnabled(false), + mAlphaTestEnabled(false), + mLogicOpEnabled(false), + mLightingEnabled(false), + mFogEnabled(false), + mRescaleNormalEnabled(false), + mNormalizeEnabled(false), + mColorMaterialEnabled(false), + mReflectionMapEnabled(false), + mCurrentColor({0.0f, 0.0f, 0.0f, 0.0f}), + mCurrentNormal({0.0f, 0.0f, 0.0f}), + mClientActiveTexture(0), + mMatrixMode(MatrixType::Modelview), + mShadeModel(ShadingModel::Smooth), + mAlphaTestFunc(AlphaTestFunc::AlwaysPass), + mAlphaTestRef(0.0f), + mLogicOp(LogicalOperation::Copy), + mLineSmoothHint(HintSetting::DontCare), + mPointSmoothHint(HintSetting::DontCare), + mPerspectiveCorrectionHint(HintSetting::DontCare), + mFogHint(HintSetting::DontCare) +{} + +GLES1State::~GLES1State() = default; + +// Taken from the GLES 1.x spec which specifies all initial state values. +void GLES1State::initialize(const Context *context, const State *state) +{ + mGLState = state; + + const Caps &caps = context->getCaps(); + + mTexUnitEnables.resize(caps.maxMultitextureUnits); + for (auto &enables : mTexUnitEnables) + { + enables.reset(); + } + + mVertexArrayEnabled = false; + mNormalArrayEnabled = false; + mColorArrayEnabled = false; + mPointSizeArrayEnabled = false; + mTexCoordArrayEnabled.resize(caps.maxMultitextureUnits, false); + + mLineSmoothEnabled = false; + mPointSmoothEnabled = false; + mPointSpriteEnabled = false; + mLogicOpEnabled = false; + mAlphaTestEnabled = false; + mLightingEnabled = false; + mFogEnabled = false; + mRescaleNormalEnabled = false; + mNormalizeEnabled = false; + mColorMaterialEnabled = false; + mReflectionMapEnabled = false; + + mMatrixMode = MatrixType::Modelview; + + mCurrentColor = {1.0f, 1.0f, 1.0f, 1.0f}; + mCurrentNormal = {0.0f, 0.0f, 1.0f}; + mCurrentTextureCoords.resize(caps.maxMultitextureUnits); + mClientActiveTexture = 0; + + mTextureEnvironments.resize(caps.maxMultitextureUnits); + + mModelviewMatrices.push_back(angle::Mat4()); + mProjectionMatrices.push_back(angle::Mat4()); + mTextureMatrices.resize(caps.maxMultitextureUnits); + for (auto &stack : mTextureMatrices) + { + stack.push_back(angle::Mat4()); + } + + mMaterial.ambient = {0.2f, 0.2f, 0.2f, 1.0f}; + mMaterial.diffuse = {0.8f, 0.8f, 0.8f, 1.0f}; + mMaterial.specular = {0.0f, 0.0f, 0.0f, 1.0f}; + mMaterial.emissive = {0.0f, 0.0f, 0.0f, 1.0f}; + + mMaterial.specularExponent = 0.0f; + + mLightModel.color = {0.2f, 0.2f, 0.2f, 1.0f}; + mLightModel.twoSided = false; + + mLights.resize(caps.maxLights); + + // GL_LIGHT0 is special and has default state that avoids all-black renderings. + mLights[0].diffuse = {1.0f, 1.0f, 1.0f, 1.0f}; + mLights[0].specular = {1.0f, 1.0f, 1.0f, 1.0f}; + + mFog.mode = FogMode::Exp; + mFog.density = 1.0f; + mFog.start = 0.0f; + mFog.end = 1.0f; + + mFog.color = {0.0f, 0.0f, 0.0f, 0.0f}; + + mShadeModel = ShadingModel::Smooth; + + mAlphaTestFunc = AlphaTestFunc::AlwaysPass; + mAlphaTestRef = 0.0f; + + mLogicOp = LogicalOperation::Copy; + + mClipPlanes.resize(caps.maxClipPlanes, + ClipPlaneParameters(false, angle::Vector4(0.0f, 0.0f, 0.0f, 0.0f))); + + mLineSmoothHint = HintSetting::DontCare; + mPointSmoothHint = HintSetting::DontCare; + mPerspectiveCorrectionHint = HintSetting::DontCare; + mFogHint = HintSetting::DontCare; + + // The user-specified point size, GL_POINT_SIZE_MAX, + // is initially equal to the implementation maximum. + mPointParameters.pointSizeMax = caps.maxAliasedPointSize; + + mDirtyBits.set(); +} + +void GLES1State::setAlphaFunc(AlphaTestFunc func, GLfloat ref) +{ + setDirty(DIRTY_GLES1_ALPHA_TEST); + mAlphaTestFunc = func; + mAlphaTestRef = ref; +} + +void GLES1State::setClientTextureUnit(unsigned int unit) +{ + setDirty(DIRTY_GLES1_CLIENT_ACTIVE_TEXTURE); + mClientActiveTexture = unit; +} + +unsigned int GLES1State::getClientTextureUnit() const +{ + return mClientActiveTexture; +} + +void GLES1State::setCurrentColor(const ColorF &color) +{ + setDirty(DIRTY_GLES1_CURRENT_VECTOR); + mCurrentColor = color; + + // > When enabled, both the ambient (acm) and diffuse (dcm) properties of both the front and + // > back material are immediately set to the value of the current color, and will track changes + // > to the current color resulting from either the Color commands or drawing vertex arrays with + // > the color array enabled. + // > The replacements made to material properties are permanent; the replaced values remain + // > until changed by either sending a new color or by setting a new material value when + // > COLOR_MATERIAL is not currently enabled, to override that particular value. + if (isColorMaterialEnabled()) + { + mMaterial.ambient = color; + mMaterial.diffuse = color; + } +} + +const ColorF &GLES1State::getCurrentColor() const +{ + return mCurrentColor; +} + +void GLES1State::setCurrentNormal(const angle::Vector3 &normal) +{ + setDirty(DIRTY_GLES1_CURRENT_VECTOR); + mCurrentNormal = normal; +} + +const angle::Vector3 &GLES1State::getCurrentNormal() const +{ + return mCurrentNormal; +} + +bool GLES1State::shouldHandleDirtyProgram() +{ + bool ret = isDirty(DIRTY_GLES1_PROGRAM); + clearDirtyBits(DIRTY_GLES1_PROGRAM); + return ret; +} + +void GLES1State::setCurrentTextureCoords(unsigned int unit, const TextureCoordF &coords) +{ + setDirty(DIRTY_GLES1_CURRENT_VECTOR); + mCurrentTextureCoords[unit] = coords; +} + +const TextureCoordF &GLES1State::getCurrentTextureCoords(unsigned int unit) const +{ + return mCurrentTextureCoords[unit]; +} + +void GLES1State::setMatrixMode(MatrixType mode) +{ + setDirty(DIRTY_GLES1_MATRICES); + mMatrixMode = mode; +} + +MatrixType GLES1State::getMatrixMode() const +{ + return mMatrixMode; +} + +GLint GLES1State::getCurrentMatrixStackDepth(GLenum queryType) const +{ + switch (queryType) + { + case GL_MODELVIEW_STACK_DEPTH: + return clampCast(mModelviewMatrices.size()); + case GL_PROJECTION_STACK_DEPTH: + return clampCast(mProjectionMatrices.size()); + case GL_TEXTURE_STACK_DEPTH: + return clampCast(mTextureMatrices[mGLState->getActiveSampler()].size()); + default: + UNREACHABLE(); + return 0; + } +} + +void GLES1State::pushMatrix() +{ + setDirty(DIRTY_GLES1_MATRICES); + auto &stack = currentMatrixStack(); + stack.push_back(stack.back()); +} + +void GLES1State::popMatrix() +{ + setDirty(DIRTY_GLES1_MATRICES); + auto &stack = currentMatrixStack(); + stack.pop_back(); +} + +GLES1State::MatrixStack &GLES1State::currentMatrixStack() +{ + setDirty(DIRTY_GLES1_MATRICES); + switch (mMatrixMode) + { + case MatrixType::Modelview: + return mModelviewMatrices; + case MatrixType::Projection: + return mProjectionMatrices; + case MatrixType::Texture: + return mTextureMatrices[mGLState->getActiveSampler()]; + default: + UNREACHABLE(); + return mModelviewMatrices; + } +} + +const angle::Mat4 &GLES1State::getModelviewMatrix() const +{ + return mModelviewMatrices.back(); +} + +const GLES1State::MatrixStack &GLES1State::getMatrixStack(MatrixType mode) const +{ + switch (mode) + { + case MatrixType::Modelview: + return mModelviewMatrices; + case MatrixType::Projection: + return mProjectionMatrices; + case MatrixType::Texture: + return mTextureMatrices[mGLState->getActiveSampler()]; + default: + UNREACHABLE(); + return mModelviewMatrices; + } +} + +const GLES1State::MatrixStack &GLES1State::currentMatrixStack() const +{ + return getMatrixStack(mMatrixMode); +} + +void GLES1State::loadMatrix(const angle::Mat4 &m) +{ + setDirty(DIRTY_GLES1_MATRICES); + currentMatrixStack().back() = m; +} + +void GLES1State::multMatrix(const angle::Mat4 &m) +{ + setDirty(DIRTY_GLES1_MATRICES); + angle::Mat4 currentMatrix = currentMatrixStack().back(); + currentMatrixStack().back() = currentMatrix.product(m); +} + +void GLES1State::setLogicOpEnabled(bool enabled) +{ + setDirty(DIRTY_GLES1_LOGIC_OP); + mLogicOpEnabled = enabled; +} + +void GLES1State::setLogicOp(LogicalOperation opcodePacked) +{ + setDirty(DIRTY_GLES1_LOGIC_OP); + mLogicOp = opcodePacked; +} + +void GLES1State::setClientStateEnabled(ClientVertexArrayType clientState, bool enable) +{ + setDirty(DIRTY_GLES1_CLIENT_STATE_ENABLE); + switch (clientState) + { + case ClientVertexArrayType::Vertex: + mVertexArrayEnabled = enable; + break; + case ClientVertexArrayType::Normal: + mNormalArrayEnabled = enable; + break; + case ClientVertexArrayType::Color: + mColorArrayEnabled = enable; + break; + case ClientVertexArrayType::PointSize: + mPointSizeArrayEnabled = enable; + break; + case ClientVertexArrayType::TextureCoord: + mTexCoordArrayEnabled[mClientActiveTexture] = enable; + break; + default: + UNREACHABLE(); + break; + } +} + +void GLES1State::setTexCoordArrayEnabled(unsigned int unit, bool enable) +{ + setDirty(DIRTY_GLES1_CLIENT_STATE_ENABLE); + mTexCoordArrayEnabled[unit] = enable; +} + +bool GLES1State::isClientStateEnabled(ClientVertexArrayType clientState) const +{ + switch (clientState) + { + case ClientVertexArrayType::Vertex: + return mVertexArrayEnabled; + case ClientVertexArrayType::Normal: + return mNormalArrayEnabled; + case ClientVertexArrayType::Color: + return mColorArrayEnabled; + case ClientVertexArrayType::PointSize: + return mPointSizeArrayEnabled; + case ClientVertexArrayType::TextureCoord: + return mTexCoordArrayEnabled[mClientActiveTexture]; + default: + UNREACHABLE(); + return false; + } +} + +bool GLES1State::isTexCoordArrayEnabled(unsigned int unit) const +{ + ASSERT(unit < mTexCoordArrayEnabled.size()); + return mTexCoordArrayEnabled[unit]; +} + +bool GLES1State::isTextureTargetEnabled(unsigned int unit, const TextureType type) const +{ + if (mTexUnitEnables.empty()) + { + return false; + } + return mTexUnitEnables[unit].test(type); +} + +LightModelParameters &GLES1State::lightModelParameters() +{ + setDirty(DIRTY_GLES1_LIGHTS); + return mLightModel; +} + +const LightModelParameters &GLES1State::lightModelParameters() const +{ + return mLightModel; +} + +LightParameters &GLES1State::lightParameters(unsigned int light) +{ + setDirty(DIRTY_GLES1_LIGHTS); + return mLights[light]; +} + +const LightParameters &GLES1State::lightParameters(unsigned int light) const +{ + return mLights[light]; +} + +MaterialParameters &GLES1State::materialParameters() +{ + setDirty(DIRTY_GLES1_MATERIAL); + return mMaterial; +} + +const MaterialParameters &GLES1State::materialParameters() const +{ + return mMaterial; +} + +bool GLES1State::isColorMaterialEnabled() const +{ + return mColorMaterialEnabled; +} + +void GLES1State::setShadeModel(ShadingModel model) +{ + setDirty(DIRTY_GLES1_SHADE_MODEL); + mShadeModel = model; +} + +void GLES1State::setClipPlane(unsigned int plane, const GLfloat *equation) +{ + setDirty(DIRTY_GLES1_CLIP_PLANES); + assert(plane < mClipPlanes.size()); + mClipPlanes[plane].equation[0] = equation[0]; + mClipPlanes[plane].equation[1] = equation[1]; + mClipPlanes[plane].equation[2] = equation[2]; + mClipPlanes[plane].equation[3] = equation[3]; +} + +void GLES1State::getClipPlane(unsigned int plane, GLfloat *equation) const +{ + assert(plane < mClipPlanes.size()); + equation[0] = mClipPlanes[plane].equation[0]; + equation[1] = mClipPlanes[plane].equation[1]; + equation[2] = mClipPlanes[plane].equation[2]; + equation[3] = mClipPlanes[plane].equation[3]; +} + +FogParameters &GLES1State::fogParameters() +{ + setDirty(DIRTY_GLES1_FOG); + return mFog; +} + +const FogParameters &GLES1State::fogParameters() const +{ + return mFog; +} + +TextureEnvironmentParameters &GLES1State::textureEnvironment(unsigned int unit) +{ + setDirty(DIRTY_GLES1_TEXTURE_ENVIRONMENT); + assert(unit < mTextureEnvironments.size()); + return mTextureEnvironments[unit]; +} + +const TextureEnvironmentParameters &GLES1State::textureEnvironment(unsigned int unit) const +{ + assert(unit < mTextureEnvironments.size()); + return mTextureEnvironments[unit]; +} + +bool operator==(const TextureEnvironmentParameters &a, const TextureEnvironmentParameters &b) +{ + return a.tie() == b.tie(); +} + +bool operator!=(const TextureEnvironmentParameters &a, const TextureEnvironmentParameters &b) +{ + return !(a == b); +} + +PointParameters &GLES1State::pointParameters() +{ + setDirty(DIRTY_GLES1_POINT_PARAMETERS); + return mPointParameters; +} + +const PointParameters &GLES1State::pointParameters() const +{ + return mPointParameters; +} + +AttributesMask GLES1State::getVertexArraysAttributeMask() const +{ + AttributesMask attribsMask; + + ClientVertexArrayType nonTexcoordArrays[] = { + ClientVertexArrayType::Vertex, + ClientVertexArrayType::Normal, + ClientVertexArrayType::Color, + ClientVertexArrayType::PointSize, + }; + + for (const ClientVertexArrayType attrib : nonTexcoordArrays) + { + attribsMask.set(GLES1Renderer::VertexArrayIndex(attrib, *this), + isClientStateEnabled(attrib)); + } + + for (unsigned int i = 0; i < kTexUnitCount; i++) + { + attribsMask.set(GLES1Renderer::TexCoordArrayIndex(i), isTexCoordArrayEnabled(i)); + } + + return attribsMask; +} + +AttributesMask GLES1State::getActiveAttributesMask() const +{ + // The program always has 8 attributes enabled. + return AttributesMask(0xFF); +} + +void GLES1State::setHint(GLenum target, GLenum mode) +{ + setDirty(DIRTY_GLES1_HINT_SETTING); + HintSetting setting = FromGLenum(mode); + switch (target) + { + case GL_PERSPECTIVE_CORRECTION_HINT: + mPerspectiveCorrectionHint = setting; + break; + case GL_POINT_SMOOTH_HINT: + mPointSmoothHint = setting; + break; + case GL_LINE_SMOOTH_HINT: + mLineSmoothHint = setting; + break; + case GL_FOG_HINT: + mFogHint = setting; + break; + default: + UNREACHABLE(); + } +} + +GLenum GLES1State::getHint(GLenum target) const +{ + switch (target) + { + case GL_PERSPECTIVE_CORRECTION_HINT: + return ToGLenum(mPerspectiveCorrectionHint); + case GL_POINT_SMOOTH_HINT: + return ToGLenum(mPointSmoothHint); + case GL_LINE_SMOOTH_HINT: + return ToGLenum(mLineSmoothHint); + case GL_FOG_HINT: + return ToGLenum(mFogHint); + default: + UNREACHABLE(); + return 0; + } +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/GLES1State.h b/gfx/angle/checkout/src/libANGLE/GLES1State.h new file mode 100644 index 0000000000..e9c108b58b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/GLES1State.h @@ -0,0 +1,351 @@ +// +// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// GLES1State.h: Defines the GLES1State class holding the state of +// a GLES1 context. + +#ifndef LIBANGLE_GLES1STATE_H_ +#define LIBANGLE_GLES1STATE_H_ + +#include + +#include "common/FixedVector.h" +#include "common/angleutils.h" +#include "common/bitset_utils.h" +#include "common/matrix_utils.h" +#include "common/vector_utils.h" +#include "libANGLE/Caps.h" +#include "libANGLE/angletypes.h" + +namespace gl +{ + +// State types specific to GLES1 contexts, from the OpenGL ES 1.1 spec "State Tables" section +struct TextureCoordF +{ + TextureCoordF(); + TextureCoordF(float _s, float _t, float _r, float _q); + bool operator==(const TextureCoordF &other) const; + + GLfloat s = 0.0f; + GLfloat t = 0.0f; + GLfloat r = 0.0f; + GLfloat q = 0.0f; +}; + +struct MaterialParameters +{ + MaterialParameters(); + + ColorF ambient; + ColorF diffuse; + ColorF specular; + ColorF emissive; + GLfloat specularExponent; +}; + +struct LightModelParameters +{ + LightModelParameters(); + + ColorF color; + bool twoSided; +}; + +struct LightParameters +{ + LightParameters(); + LightParameters(const LightParameters &other); + + bool enabled = false; + ColorF ambient = {0.0f, 0.0f, 0.0f, 1.0f}; + ColorF diffuse = {0.0f, 0.0f, 0.0f, 1.0f}; + ColorF specular = {0.0f, 0.0f, 0.0f, 1.0f}; + angle::Vector4 position = {0.0f, 0.0f, 1.0f, 0.0f}; + angle::Vector3 direction = {0.0f, 0.0f, -1.0f}; + GLfloat spotlightExponent = 0.0f; + GLfloat spotlightCutoffAngle = 180.0f; + GLfloat attenuationConst = 1.0f; + GLfloat attenuationLinear = 0.0f; + GLfloat attenuationQuadratic = 0.0f; +}; + +struct FogParameters +{ + FogParameters(); + + FogMode mode; + GLfloat density; + GLfloat start; + GLfloat end; + ColorF color; +}; + +struct TextureEnvironmentParameters +{ + TextureEnvironmentParameters(); + TextureEnvironmentParameters(const TextureEnvironmentParameters &other); + + TextureEnvMode mode = TextureEnvMode::Modulate; + TextureCombine combineRgb = TextureCombine::Modulate; + TextureCombine combineAlpha = TextureCombine::Modulate; + + TextureSrc src0Rgb = TextureSrc::Texture; + TextureSrc src0Alpha = TextureSrc::Texture; + + TextureSrc src1Rgb = TextureSrc::Previous; + TextureSrc src1Alpha = TextureSrc::Previous; + + TextureSrc src2Rgb = TextureSrc::Constant; + TextureSrc src2Alpha = TextureSrc::Constant; + + TextureOp op0Rgb = TextureOp::SrcColor; + TextureOp op0Alpha = TextureOp::SrcAlpha; + + TextureOp op1Rgb = TextureOp::SrcColor; + TextureOp op1Alpha = TextureOp::SrcAlpha; + + TextureOp op2Rgb = TextureOp::SrcAlpha; + TextureOp op2Alpha = TextureOp::SrcAlpha; + + ColorF color = {0.0f, 0.0f, 0.0f, 0.0f}; + GLfloat rgbScale = 1.0f; + GLfloat alphaScale = 1.0f; + + bool pointSpriteCoordReplace = false; + + auto tie() const + { + return std::tie(mode, combineRgb, combineAlpha, src0Rgb, src0Alpha, src1Rgb, src1Alpha, + src2Rgb, src2Alpha, op0Rgb, op0Alpha, op1Rgb, op1Alpha, op2Rgb, op2Alpha, + color, rgbScale, alphaScale, pointSpriteCoordReplace); + } +}; + +bool operator==(const TextureEnvironmentParameters &a, const TextureEnvironmentParameters &b); +bool operator!=(const TextureEnvironmentParameters &a, const TextureEnvironmentParameters &b); + +struct PointParameters +{ + PointParameters(); + PointParameters(const PointParameters &other); + + GLfloat pointSizeMin = 0.0f; + GLfloat pointSizeMax = 1.0f; + GLfloat pointFadeThresholdSize = 1.0f; + angle::Vector3 pointDistanceAttenuation = {1.0f, 0.0f, 0.0f}; + GLfloat pointSize = 1.0f; +}; + +struct ClipPlaneParameters +{ + ClipPlaneParameters(); + ClipPlaneParameters(bool enabled, const angle::Vector4 &equation); + ClipPlaneParameters(const ClipPlaneParameters &other); + ClipPlaneParameters &operator=(const ClipPlaneParameters &other); + + bool enabled; + angle::Vector4 equation; +}; + +class Context; +class GLES1Renderer; +class State; + +class GLES1State final : angle::NonCopyable +{ + public: + GLES1State(); + ~GLES1State(); + + void initialize(const Context *context, const State *state); + + void setAlphaFunc(AlphaTestFunc func, GLfloat ref); + void setClientTextureUnit(unsigned int unit); + unsigned int getClientTextureUnit() const; + + void setCurrentColor(const ColorF &color); + const ColorF &getCurrentColor() const; + + void setCurrentNormal(const angle::Vector3 &normal); + const angle::Vector3 &getCurrentNormal() const; + + void setCurrentTextureCoords(unsigned int unit, const TextureCoordF &coords); + const TextureCoordF &getCurrentTextureCoords(unsigned int unit) const; + + void setMatrixMode(MatrixType mode); + MatrixType getMatrixMode() const; + + GLint getCurrentMatrixStackDepth(GLenum param) const; + + void pushMatrix(); + void popMatrix(); + + using MatrixStack = angle::FixedVector; + MatrixStack ¤tMatrixStack(); + const MatrixStack ¤tMatrixStack() const; + const MatrixStack &getMatrixStack(MatrixType mode) const; + + const angle::Mat4 &getModelviewMatrix() const; + + void loadMatrix(const angle::Mat4 &m); + void multMatrix(const angle::Mat4 &m); + + void setLogicOpEnabled(bool enabled); + void setLogicOp(LogicalOperation opcodePacked); + + void setClientStateEnabled(ClientVertexArrayType clientState, bool enable); + void setTexCoordArrayEnabled(unsigned int unit, bool enable); + bool isClientStateEnabled(ClientVertexArrayType clientState) const; + bool isTexCoordArrayEnabled(unsigned int unit) const; + bool isTextureTargetEnabled(unsigned int unit, const TextureType type) const; + + LightModelParameters &lightModelParameters(); + const LightModelParameters &lightModelParameters() const; + + LightParameters &lightParameters(unsigned int light); + const LightParameters &lightParameters(unsigned int light) const; + + MaterialParameters &materialParameters(); + const MaterialParameters &materialParameters() const; + bool isColorMaterialEnabled() const; + + void setShadeModel(ShadingModel model); + + void setClipPlane(unsigned int plane, const GLfloat *equation); + void getClipPlane(unsigned int plane, GLfloat *equation) const; + + FogParameters &fogParameters(); + const FogParameters &fogParameters() const; + + TextureEnvironmentParameters &textureEnvironment(unsigned int unit); + const TextureEnvironmentParameters &textureEnvironment(unsigned int unit) const; + + PointParameters &pointParameters(); + const PointParameters &pointParameters() const; + + AttributesMask getVertexArraysAttributeMask() const; + AttributesMask getActiveAttributesMask() const; + + bool shouldHandleDirtyProgram(); + + void setHint(GLenum target, GLenum mode); + GLenum getHint(GLenum target) const; + + enum DirtyGles1Type + { + DIRTY_GLES1_TEXTURE_UNIT_ENABLE = 0, + DIRTY_GLES1_CLIENT_STATE_ENABLE, + DIRTY_GLES1_FEATURE_ENABLE, + DIRTY_GLES1_CURRENT_VECTOR, + DIRTY_GLES1_CLIENT_ACTIVE_TEXTURE, + DIRTY_GLES1_MATRICES, + DIRTY_GLES1_TEXTURE_ENVIRONMENT, + DIRTY_GLES1_MATERIAL, + DIRTY_GLES1_LIGHTS, + DIRTY_GLES1_FOG, + DIRTY_GLES1_SHADE_MODEL, + DIRTY_GLES1_POINT_PARAMETERS, + DIRTY_GLES1_ALPHA_TEST, + DIRTY_GLES1_LOGIC_OP, + DIRTY_GLES1_CLIP_PLANES, + DIRTY_GLES1_HINT_SETTING, + DIRTY_GLES1_PROGRAM, + DIRTY_GLES1_MAX, + }; + + void setAllDirty() { mDirtyBits.set(); } + + private: + friend class State; + friend class GLES1Renderer; + + // Back pointer for reading from State. + const State *mGLState; + + using DirtyBits = angle::BitSet; + DirtyBits mDirtyBits; + + void setDirty(DirtyGles1Type type) { mDirtyBits.set(type); } + void clearDirty() { mDirtyBits.reset(); } + void clearDirtyBits(const DirtyGles1Type &bitset) { mDirtyBits &= ~bitset; } + bool isDirty(DirtyGles1Type type) const { return mDirtyBits.test(type); } + + // All initial state values come from the + // OpenGL ES 1.1 spec. + std::vector> mTexUnitEnables; + + // Table 6.4, 6.5 (IsEnabled) + bool mVertexArrayEnabled; + bool mNormalArrayEnabled; + bool mColorArrayEnabled; + bool mPointSizeArrayEnabled; + std::vector mTexCoordArrayEnabled; + + // Table 6.7-6.16 (IsEnabled) + bool mLineSmoothEnabled; + bool mPointSmoothEnabled; + bool mPointSpriteEnabled; + bool mAlphaTestEnabled; + bool mLogicOpEnabled; + bool mLightingEnabled; + bool mFogEnabled; + bool mRescaleNormalEnabled; + bool mNormalizeEnabled; + bool mColorMaterialEnabled; + bool mReflectionMapEnabled; + + // Table 6.3 + ColorF mCurrentColor; + angle::Vector3 mCurrentNormal; + // Invariant: mCurrentTextureCoords size is == GL_MAX_TEXTURE_UNITS. + std::vector mCurrentTextureCoords; + + // Table 6.4 + unsigned int mClientActiveTexture; + + // Table 6.7 + MatrixType mMatrixMode; + MatrixStack mProjectionMatrices; + MatrixStack mModelviewMatrices; + std::vector mTextureMatrices; + + // Table 6.15 + using TextureEnvironments = std::vector; + TextureEnvironments mTextureEnvironments; + + // Table 6.9, 2.8 + MaterialParameters mMaterial; + LightModelParameters mLightModel; + + // Table 6.10 + std::vector mLights; + + // Table 6.8 + FogParameters mFog; + ShadingModel mShadeModel; + + // Table 6.11 + PointParameters mPointParameters; + + // Table 6.16 + AlphaTestFunc mAlphaTestFunc; + GLfloat mAlphaTestRef; + LogicalOperation mLogicOp; + + // Table 6.7 + std::vector mClipPlanes; + + // Table 6.19 + HintSetting mLineSmoothHint; + HintSetting mPointSmoothHint; + HintSetting mPerspectiveCorrectionHint; + HintSetting mFogHint; +}; + +} // namespace gl + +#endif // LIBANGLE_GLES1STATE_H_ diff --git a/gfx/angle/checkout/src/libANGLE/HandleAllocator.cpp b/gfx/angle/checkout/src/libANGLE/HandleAllocator.cpp new file mode 100644 index 0000000000..ff49233e1d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/HandleAllocator.cpp @@ -0,0 +1,184 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// HandleAllocator.cpp: Implements the gl::HandleAllocator class, which is used +// to allocate GL handles. + +#include "libANGLE/HandleAllocator.h" + +#include +#include +#include + +#include "common/debug.h" + +namespace gl +{ + +struct HandleAllocator::HandleRangeComparator +{ + bool operator()(const HandleRange &range, GLuint handle) const { return (range.end < handle); } +}; + +HandleAllocator::HandleAllocator() : mBaseValue(1), mNextValue(1), mLoggingEnabled(false) +{ + mUnallocatedList.push_back(HandleRange(1, std::numeric_limits::max())); +} + +HandleAllocator::HandleAllocator(GLuint maximumHandleValue) + : mBaseValue(1), mNextValue(1), mLoggingEnabled(false) +{ + mUnallocatedList.push_back(HandleRange(1, maximumHandleValue)); +} + +HandleAllocator::~HandleAllocator() {} + +void HandleAllocator::setBaseHandle(GLuint value) +{ + ASSERT(mBaseValue == mNextValue); + mBaseValue = value; + mNextValue = value; +} + +GLuint HandleAllocator::allocate() +{ + ASSERT(!mUnallocatedList.empty() || !mReleasedList.empty()); + + // Allocate from released list, logarithmic time for pop_heap. + if (!mReleasedList.empty()) + { + std::pop_heap(mReleasedList.begin(), mReleasedList.end(), std::greater()); + GLuint reusedHandle = mReleasedList.back(); + mReleasedList.pop_back(); + + if (mLoggingEnabled) + { + WARN() << "HandleAllocator::allocate reusing " << reusedHandle << std::endl; + } + + return reusedHandle; + } + + // Allocate from unallocated list, constant time. + auto listIt = mUnallocatedList.begin(); + + GLuint freeListHandle = listIt->begin; + ASSERT(freeListHandle > 0); + + if (listIt->begin == listIt->end) + { + mUnallocatedList.erase(listIt); + } + else + { + listIt->begin++; + } + + if (mLoggingEnabled) + { + WARN() << "HandleAllocator::allocate allocating " << freeListHandle << std::endl; + } + + return freeListHandle; +} + +void HandleAllocator::release(GLuint handle) +{ + if (mLoggingEnabled) + { + WARN() << "HandleAllocator::release releasing " << handle << std::endl; + } + + // Try consolidating the ranges first. + for (HandleRange &handleRange : mUnallocatedList) + { + if (handleRange.begin - 1 == handle) + { + handleRange.begin--; + return; + } + + if (handleRange.end == handle - 1) + { + handleRange.end++; + return; + } + } + + // Add to released list, logarithmic time for push_heap. + mReleasedList.push_back(handle); + std::push_heap(mReleasedList.begin(), mReleasedList.end(), std::greater()); +} + +void HandleAllocator::reserve(GLuint handle) +{ + if (mLoggingEnabled) + { + WARN() << "HandleAllocator::reserve reserving " << handle << std::endl; + } + + // Clear from released list -- might be a slow operation. + if (!mReleasedList.empty()) + { + auto releasedIt = std::find(mReleasedList.begin(), mReleasedList.end(), handle); + if (releasedIt != mReleasedList.end()) + { + mReleasedList.erase(releasedIt); + std::make_heap(mReleasedList.begin(), mReleasedList.end(), std::greater()); + return; + } + } + + // Not in released list, reserve in the unallocated list. + auto boundIt = std::lower_bound(mUnallocatedList.begin(), mUnallocatedList.end(), handle, + HandleRangeComparator()); + + ASSERT(boundIt != mUnallocatedList.end()); + + GLuint begin = boundIt->begin; + GLuint end = boundIt->end; + + if (handle == begin || handle == end) + { + if (begin == end) + { + mUnallocatedList.erase(boundIt); + } + else if (handle == begin) + { + boundIt->begin++; + } + else + { + ASSERT(handle == end); + boundIt->end--; + } + return; + } + + ASSERT(begin < handle && handle < end); + + // need to split the range + auto placementIt = mUnallocatedList.erase(boundIt); + placementIt = mUnallocatedList.insert(placementIt, HandleRange(handle + 1, end)); + mUnallocatedList.insert(placementIt, HandleRange(begin, handle - 1)); +} + +void HandleAllocator::reset() +{ + mUnallocatedList.clear(); + mUnallocatedList.push_back(HandleRange(1, std::numeric_limits::max())); + mReleasedList.clear(); + mBaseValue = 1; + mNextValue = 1; +} + +void HandleAllocator::enableLogging(bool enabled) +{ + mLoggingEnabled = enabled; +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/HandleAllocator.h b/gfx/angle/checkout/src/libANGLE/HandleAllocator.h new file mode 100644 index 0000000000..985d1adaba --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/HandleAllocator.h @@ -0,0 +1,65 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// HandleAllocator.h: Defines the gl::HandleAllocator class, which is used to +// allocate GL handles. + +#ifndef LIBANGLE_HANDLEALLOCATOR_H_ +#define LIBANGLE_HANDLEALLOCATOR_H_ + +#include "common/angleutils.h" + +#include "angle_gl.h" + +namespace gl +{ + +class HandleAllocator final : angle::NonCopyable +{ + public: + // Maximum handle = MAX_UINT-1 + HandleAllocator(); + // Specify maximum handle value. Used for testing. + HandleAllocator(GLuint maximumHandleValue); + + ~HandleAllocator(); + + void setBaseHandle(GLuint value); + + GLuint allocate(); + void release(GLuint handle); + void reserve(GLuint handle); + void reset(); + + void enableLogging(bool enabled); + + private: + GLuint mBaseValue; + GLuint mNextValue; + + // Represents an inclusive range [begin, end] + struct HandleRange + { + HandleRange(GLuint beginIn, GLuint endIn) : begin(beginIn), end(endIn) {} + + GLuint begin; + GLuint end; + }; + + struct HandleRangeComparator; + + // The freelist consists of never-allocated handles, stored + // as ranges, and handles that were previously allocated and + // released, stored in a heap. + std::vector mUnallocatedList; + std::vector mReleasedList; + + bool mLoggingEnabled; +}; + +} // namespace gl + +#endif // LIBANGLE_HANDLEALLOCATOR_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Image.cpp b/gfx/angle/checkout/src/libANGLE/Image.cpp new file mode 100644 index 0000000000..6292b5ee46 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Image.cpp @@ -0,0 +1,581 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Image.cpp: Implements the egl::Image class representing the EGLimage object. + +#include "libANGLE/Image.h" + +#include "common/debug.h" +#include "common/utilities.h" +#include "libANGLE/Context.h" +#include "libANGLE/Renderbuffer.h" +#include "libANGLE/Texture.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/EGLImplFactory.h" +#include "libANGLE/renderer/ImageImpl.h" + +namespace egl +{ + +namespace +{ +gl::ImageIndex GetImageIndex(EGLenum eglTarget, const egl::AttributeMap &attribs) +{ + if (!IsTextureTarget(eglTarget)) + { + return gl::ImageIndex(); + } + + gl::TextureTarget target = egl_gl::EGLImageTargetToTextureTarget(eglTarget); + GLint mip = static_cast(attribs.get(EGL_GL_TEXTURE_LEVEL_KHR, 0)); + GLint layer = static_cast(attribs.get(EGL_GL_TEXTURE_ZOFFSET_KHR, 0)); + + if (target == gl::TextureTarget::_3D) + { + return gl::ImageIndex::Make3D(mip, layer); + } + else + { + ASSERT(layer == 0); + return gl::ImageIndex::MakeFromTarget(target, mip, 1); + } +} + +const Display *DisplayFromContext(const gl::Context *context) +{ + return (context ? context->getDisplay() : nullptr); +} + +angle::SubjectIndex kExternalImageImplSubjectIndex = 0; +} // anonymous namespace + +ImageSibling::ImageSibling() : FramebufferAttachmentObject(), mSourcesOf(), mTargetOf() {} + +ImageSibling::~ImageSibling() +{ + // EGL images should hold a ref to their targets and siblings, a Texture should not be deletable + // while it is attached to an EGL image. + // Child class should orphan images before destruction. + ASSERT(mSourcesOf.empty()); + ASSERT(mTargetOf.get() == nullptr); +} + +void ImageSibling::setTargetImage(const gl::Context *context, egl::Image *imageTarget) +{ + ASSERT(imageTarget != nullptr); + mTargetOf.set(DisplayFromContext(context), imageTarget); + imageTarget->addTargetSibling(this); +} + +angle::Result ImageSibling::orphanImages(const gl::Context *context, + RefCountObjectReleaser *outReleaseImage) +{ + ASSERT(outReleaseImage != nullptr); + + if (mTargetOf.get() != nullptr) + { + // Can't be a target and have sources. + ASSERT(mSourcesOf.empty()); + + ANGLE_TRY(mTargetOf->orphanSibling(context, this)); + *outReleaseImage = mTargetOf.set(DisplayFromContext(context), nullptr); + } + else + { + for (Image *sourceImage : mSourcesOf) + { + ANGLE_TRY(sourceImage->orphanSibling(context, this)); + } + mSourcesOf.clear(); + } + + return angle::Result::Continue; +} + +void ImageSibling::addImageSource(egl::Image *imageSource) +{ + ASSERT(imageSource != nullptr); + mSourcesOf.insert(imageSource); +} + +void ImageSibling::removeImageSource(egl::Image *imageSource) +{ + ASSERT(mSourcesOf.find(imageSource) != mSourcesOf.end()); + mSourcesOf.erase(imageSource); +} + +bool ImageSibling::isEGLImageTarget() const +{ + return (mTargetOf.get() != nullptr); +} + +gl::InitState ImageSibling::sourceEGLImageInitState() const +{ + ASSERT(isEGLImageTarget()); + return mTargetOf->sourceInitState(); +} + +void ImageSibling::setSourceEGLImageInitState(gl::InitState initState) const +{ + ASSERT(isEGLImageTarget()); + mTargetOf->setInitState(initState); +} + +bool ImageSibling::isRenderable(const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex) const +{ + ASSERT(isEGLImageTarget()); + return mTargetOf->isRenderable(context); +} + +bool ImageSibling::isYUV() const +{ + return mTargetOf.get() && mTargetOf->isYUV(); +} + +bool ImageSibling::isCreatedWithAHB() const +{ + return mTargetOf.get() && mTargetOf->isCreatedWithAHB(); +} + +bool ImageSibling::hasProtectedContent() const +{ + return mTargetOf.get() && mTargetOf->hasProtectedContent(); +} + +void ImageSibling::notifySiblings(angle::SubjectMessage message) +{ + if (mTargetOf.get()) + { + mTargetOf->notifySiblings(this, message); + } + for (Image *source : mSourcesOf) + { + source->notifySiblings(this, message); + } +} + +ExternalImageSibling::ExternalImageSibling(rx::EGLImplFactory *factory, + const gl::Context *context, + EGLenum target, + EGLClientBuffer buffer, + const AttributeMap &attribs) + : mImplementation(factory->createExternalImageSibling(context, target, buffer, attribs)), + mImplObserverBinding(this, kExternalImageImplSubjectIndex) +{ + mImplObserverBinding.bind(mImplementation.get()); +} + +ExternalImageSibling::~ExternalImageSibling() = default; + +void ExternalImageSibling::onDestroy(const egl::Display *display) +{ + mImplementation->onDestroy(display); +} + +Error ExternalImageSibling::initialize(const egl::Display *display) +{ + return mImplementation->initialize(display); +} + +gl::Extents ExternalImageSibling::getAttachmentSize(const gl::ImageIndex &imageIndex) const +{ + return mImplementation->getSize(); +} + +gl::Format ExternalImageSibling::getAttachmentFormat(GLenum binding, + const gl::ImageIndex &imageIndex) const +{ + return mImplementation->getFormat(); +} + +GLsizei ExternalImageSibling::getAttachmentSamples(const gl::ImageIndex &imageIndex) const +{ + return static_cast(mImplementation->getSamples()); +} + +GLuint ExternalImageSibling::getLevelCount() const +{ + return static_cast(mImplementation->getLevelCount()); +} + +bool ExternalImageSibling::isRenderable(const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex) const +{ + return mImplementation->isRenderable(context); +} + +bool ExternalImageSibling::isTextureable(const gl::Context *context) const +{ + return mImplementation->isTexturable(context); +} + +bool ExternalImageSibling::isYUV() const +{ + return mImplementation->isYUV(); +} + +bool ExternalImageSibling::isCubeMap() const +{ + return mImplementation->isCubeMap(); +} + +bool ExternalImageSibling::hasProtectedContent() const +{ + return mImplementation->hasProtectedContent(); +} + +void ExternalImageSibling::onAttach(const gl::Context *context, rx::Serial framebufferSerial) {} + +void ExternalImageSibling::onDetach(const gl::Context *context, rx::Serial framebufferSerial) {} + +GLuint ExternalImageSibling::getId() const +{ + UNREACHABLE(); + return 0; +} + +gl::InitState ExternalImageSibling::initState(GLenum binding, + const gl::ImageIndex &imageIndex) const +{ + return gl::InitState::Initialized; +} + +void ExternalImageSibling::setInitState(GLenum binding, + const gl::ImageIndex &imageIndex, + gl::InitState initState) +{} + +rx::ExternalImageSiblingImpl *ExternalImageSibling::getImplementation() const +{ + return mImplementation.get(); +} + +void ExternalImageSibling::onSubjectStateChange(angle::SubjectIndex index, + angle::SubjectMessage message) +{ + onStateChange(message); +} + +rx::FramebufferAttachmentObjectImpl *ExternalImageSibling::getAttachmentImpl() const +{ + return mImplementation.get(); +} + +ImageState::ImageState(EGLenum target, ImageSibling *buffer, const AttributeMap &attribs) + : label(nullptr), + target(target), + imageIndex(GetImageIndex(target, attribs)), + source(buffer), + format(GL_NONE), + yuv(false), + cubeMap(false), + size(), + samples(), + levelCount(1), + sourceType(target), + colorspace( + static_cast(attribs.get(EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_DEFAULT_EXT))), + hasProtectedContent(static_cast(attribs.get(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE))) +{} + +ImageState::~ImageState() {} + +Image::Image(rx::EGLImplFactory *factory, + const gl::Context *context, + EGLenum target, + ImageSibling *buffer, + const AttributeMap &attribs) + : mState(target, buffer, attribs), + mImplementation(factory->createImage(mState, context, target, attribs)), + mOrphanedAndNeedsInit(false) +{ + ASSERT(mImplementation != nullptr); + ASSERT(buffer != nullptr); + + mState.source->addImageSource(this); +} + +void Image::onDestroy(const Display *display) +{ + // All targets should hold a ref to the egl image and it should not be deleted until there are + // no siblings left. + ASSERT([&] { + std::unique_lock lock(mState.targetsLock); + return mState.targets.empty(); + }()); + + // Make sure the implementation gets a chance to clean up before we delete the source. + mImplementation->onDestroy(display); + + // Tell the source that it is no longer used by this image + if (mState.source != nullptr) + { + mState.source->removeImageSource(this); + + // If the source is an external object, delete it + if (IsExternalImageTarget(mState.sourceType)) + { + ExternalImageSibling *externalSibling = rx::GetAs(mState.source); + externalSibling->onDestroy(display); + delete externalSibling; + } + + mState.source = nullptr; + } +} + +Image::~Image() +{ + SafeDelete(mImplementation); +} + +void Image::setLabel(EGLLabelKHR label) +{ + mState.label = label; +} + +EGLLabelKHR Image::getLabel() const +{ + return mState.label; +} + +void Image::addTargetSibling(ImageSibling *sibling) +{ + std::unique_lock lock(mState.targetsLock); + mState.targets.insert(sibling); +} + +angle::Result Image::orphanSibling(const gl::Context *context, ImageSibling *sibling) +{ + ASSERT(sibling != nullptr); + + // notify impl + ANGLE_TRY(mImplementation->orphan(context, sibling)); + + if (mState.source == sibling) + { + // The external source of an image cannot be redefined so it cannot be orphaned. + ASSERT(!IsExternalImageTarget(mState.sourceType)); + + // If the sibling is the source, it cannot be a target. + ASSERT([&] { + std::unique_lock lock(mState.targetsLock); + return mState.targets.find(sibling) == mState.targets.end(); + }()); + mState.source = nullptr; + mOrphanedAndNeedsInit = + (sibling->initState(GL_NONE, mState.imageIndex) == gl::InitState::MayNeedInit); + } + else + { + std::unique_lock lock(mState.targetsLock); + mState.targets.erase(sibling); + } + + return angle::Result::Continue; +} + +const gl::Format &Image::getFormat() const +{ + return mState.format; +} + +bool Image::isRenderable(const gl::Context *context) const +{ + if (IsTextureTarget(mState.sourceType)) + { + return mState.format.info->textureAttachmentSupport(context->getClientVersion(), + context->getExtensions()); + } + else if (IsRenderbufferTarget(mState.sourceType)) + { + return mState.format.info->renderbufferSupport(context->getClientVersion(), + context->getExtensions()); + } + else if (IsExternalImageTarget(mState.sourceType)) + { + ASSERT(mState.source != nullptr); + return mState.source->isRenderable(context, GL_NONE, gl::ImageIndex()); + } + + UNREACHABLE(); + return false; +} + +bool Image::isTexturable(const gl::Context *context) const +{ + if (IsTextureTarget(mState.sourceType)) + { + return mState.format.info->textureSupport(context->getClientVersion(), + context->getExtensions()); + } + else if (IsRenderbufferTarget(mState.sourceType)) + { + return true; + } + else if (IsExternalImageTarget(mState.sourceType)) + { + ASSERT(mState.source != nullptr); + return rx::GetAs(mState.source)->isTextureable(context); + } + + UNREACHABLE(); + return false; +} + +bool Image::isYUV() const +{ + return mState.yuv; +} + +bool Image::isCreatedWithAHB() const +{ + return mState.target == EGL_NATIVE_BUFFER_ANDROID; +} + +bool Image::isCubeMap() const +{ + return mState.cubeMap; +} + +size_t Image::getWidth() const +{ + return mState.size.width; +} + +size_t Image::getHeight() const +{ + return mState.size.height; +} + +const gl::Extents &Image::getExtents() const +{ + return mState.size; +} + +bool Image::isLayered() const +{ + return mState.imageIndex.isLayered(); +} + +size_t Image::getSamples() const +{ + return mState.samples; +} + +GLuint Image::getLevelCount() const +{ + return mState.levelCount; +} + +bool Image::hasProtectedContent() const +{ + return mState.hasProtectedContent; +} + +rx::ImageImpl *Image::getImplementation() const +{ + return mImplementation; +} + +Error Image::initialize(const Display *display) +{ + if (IsExternalImageTarget(mState.sourceType)) + { + ExternalImageSibling *externalSibling = rx::GetAs(mState.source); + ANGLE_TRY(externalSibling->initialize(display)); + + mState.hasProtectedContent = externalSibling->hasProtectedContent(); + mState.levelCount = externalSibling->getLevelCount(); + mState.cubeMap = externalSibling->isCubeMap(); + + // External siblings can be YUV + mState.yuv = externalSibling->isYUV(); + } + + mState.format = mState.source->getAttachmentFormat(GL_NONE, mState.imageIndex); + + if (mState.colorspace != EGL_GL_COLORSPACE_DEFAULT_EXT) + { + GLenum nonLinearFormat = mState.format.info->sizedInternalFormat; + if (!gl::ColorspaceFormatOverride(mState.colorspace, &nonLinearFormat)) + { + // the colorspace format is not supported + return egl::EglBadMatch(); + } + mState.format = gl::Format(nonLinearFormat); + } + + if (!IsExternalImageTarget(mState.sourceType)) + { + // Account for the fact that GL_ANGLE_yuv_internal_format extension maybe enabled, + // in which case the internal format itself could be YUV. + mState.yuv = gl::IsYuvFormat(mState.format.info->sizedInternalFormat); + } + + mState.size = mState.source->getAttachmentSize(mState.imageIndex); + mState.samples = mState.source->getAttachmentSamples(mState.imageIndex); + + if (IsTextureTarget(mState.sourceType)) + { + mState.size.depth = 1; + } + + return mImplementation->initialize(display); +} + +bool Image::orphaned() const +{ + return (mState.source == nullptr); +} + +gl::InitState Image::sourceInitState() const +{ + if (orphaned()) + { + return mOrphanedAndNeedsInit ? gl::InitState::MayNeedInit : gl::InitState::Initialized; + } + + return mState.source->initState(GL_NONE, mState.imageIndex); +} + +void Image::setInitState(gl::InitState initState) +{ + if (orphaned()) + { + mOrphanedAndNeedsInit = false; + } + + return mState.source->setInitState(GL_NONE, mState.imageIndex, initState); +} + +Error Image::exportVkImage(void *vkImage, void *vkImageCreateInfo) +{ + return mImplementation->exportVkImage(vkImage, vkImageCreateInfo); +} + +void Image::notifySiblings(const ImageSibling *notifier, angle::SubjectMessage message) +{ + if (mState.source && mState.source != notifier) + { + mState.source->onSubjectStateChange(rx::kTextureImageSiblingMessageIndex, message); + } + + std::unique_lock lock(mState.targetsLock); + for (ImageSibling *target : mState.targets) + { + if (target != notifier) + { + target->onSubjectStateChange(rx::kTextureImageSiblingMessageIndex, message); + } + } +} + +} // namespace egl diff --git a/gfx/angle/checkout/src/libANGLE/Image.h b/gfx/angle/checkout/src/libANGLE/Image.h new file mode 100644 index 0000000000..7c1747f804 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Image.h @@ -0,0 +1,216 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Image.h: Defines the egl::Image class representing the EGLimage object. + +#ifndef LIBANGLE_IMAGE_H_ +#define LIBANGLE_IMAGE_H_ + +#include "common/FastVector.h" +#include "common/angleutils.h" +#include "libANGLE/AttributeMap.h" +#include "libANGLE/Debug.h" +#include "libANGLE/Error.h" +#include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/RefCountObject.h" +#include "libANGLE/formatutils.h" + +namespace rx +{ +class EGLImplFactory; +class ImageImpl; +class ExternalImageSiblingImpl; + +// Used for distinguishing dirty bit messages from gl::Texture/rx::TexureImpl/gl::Image. +constexpr size_t kTextureImageImplObserverMessageIndex = 0; +constexpr size_t kTextureImageSiblingMessageIndex = 1; +} // namespace rx + +namespace egl +{ +class Image; +class Display; + +// Only currently Renderbuffers and Textures can be bound with images. This makes the relationship +// explicit, and also ensures that an image sibling can determine if it's been initialized or not, +// which is important for the robust resource init extension with Textures and EGLImages. +class ImageSibling : public gl::FramebufferAttachmentObject +{ + public: + ImageSibling(); + ~ImageSibling() override; + + bool isEGLImageTarget() const; + gl::InitState sourceEGLImageInitState() const; + void setSourceEGLImageInitState(gl::InitState initState) const; + + bool isRenderable(const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex) const override; + bool isYUV() const override; + bool isCreatedWithAHB() const override; + bool hasProtectedContent() const override; + + protected: + // Set the image target of this sibling + void setTargetImage(const gl::Context *context, egl::Image *imageTarget); + + // Orphan all EGL image sources and targets + angle::Result orphanImages(const gl::Context *context, + RefCountObjectReleaser *outReleaseImage); + + void notifySiblings(angle::SubjectMessage message); + + private: + friend class Image; + + // Called from Image only to add a new source image + void addImageSource(egl::Image *imageSource); + + // Called from Image only to remove a source image when the Image is being deleted + void removeImageSource(egl::Image *imageSource); + + static constexpr size_t kSourcesOfSetSize = 2; + angle::FlatUnorderedSet mSourcesOf; + BindingPointer mTargetOf; +}; + +// Wrapper for EGLImage sources that are not owned by ANGLE, these often have to do +// platform-specific queries for format and size information. +class ExternalImageSibling : public ImageSibling +{ + public: + ExternalImageSibling(rx::EGLImplFactory *factory, + const gl::Context *context, + EGLenum target, + EGLClientBuffer buffer, + const AttributeMap &attribs); + ~ExternalImageSibling() override; + + void onDestroy(const egl::Display *display); + + Error initialize(const Display *display); + + gl::Extents getAttachmentSize(const gl::ImageIndex &imageIndex) const override; + gl::Format getAttachmentFormat(GLenum binding, const gl::ImageIndex &imageIndex) const override; + GLsizei getAttachmentSamples(const gl::ImageIndex &imageIndex) const override; + GLuint getLevelCount() const; + bool isRenderable(const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex) const override; + bool isTextureable(const gl::Context *context) const; + bool isYUV() const override; + bool isCubeMap() const; + bool hasProtectedContent() const override; + + void onAttach(const gl::Context *context, rx::Serial framebufferSerial) override; + void onDetach(const gl::Context *context, rx::Serial framebufferSerial) override; + GLuint getId() const override; + + gl::InitState initState(GLenum binding, const gl::ImageIndex &imageIndex) const override; + void setInitState(GLenum binding, + const gl::ImageIndex &imageIndex, + gl::InitState initState) override; + + rx::ExternalImageSiblingImpl *getImplementation() const; + + protected: + rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override; + + private: + // ObserverInterface implementation. + void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; + + std::unique_ptr mImplementation; + angle::ObserverBinding mImplObserverBinding; +}; + +struct ImageState : private angle::NonCopyable +{ + ImageState(EGLenum target, ImageSibling *buffer, const AttributeMap &attribs); + ~ImageState(); + + EGLLabelKHR label; + EGLenum target; + gl::ImageIndex imageIndex; + ImageSibling *source; + + gl::Format format; + bool yuv; + bool cubeMap; + gl::Extents size; + size_t samples; + GLuint levelCount; + EGLenum sourceType; + EGLenum colorspace; + bool hasProtectedContent; + + mutable std::mutex targetsLock; + + static constexpr size_t kTargetsSetSize = 2; + angle::FlatUnorderedSet targets; +}; + +class Image final : public RefCountObject, public LabeledObject +{ + public: + Image(rx::EGLImplFactory *factory, + const gl::Context *context, + EGLenum target, + ImageSibling *buffer, + const AttributeMap &attribs); + + void onDestroy(const Display *display) override; + ~Image() override; + + void setLabel(EGLLabelKHR label) override; + EGLLabelKHR getLabel() const override; + + const gl::Format &getFormat() const; + bool isRenderable(const gl::Context *context) const; + bool isTexturable(const gl::Context *context) const; + bool isYUV() const; + bool isCreatedWithAHB() const; + // Returns true only if the eglImage contains a complete cubemap + bool isCubeMap() const; + size_t getWidth() const; + size_t getHeight() const; + const gl::Extents &getExtents() const; + bool isLayered() const; + size_t getSamples() const; + GLuint getLevelCount() const; + bool hasProtectedContent() const; + + Error initialize(const Display *display); + + rx::ImageImpl *getImplementation() const; + + bool orphaned() const; + gl::InitState sourceInitState() const; + void setInitState(gl::InitState initState); + + Error exportVkImage(void *vkImage, void *vkImageCreateInfo); + + private: + friend class ImageSibling; + + // Called from ImageSibling only notify the image that a new target sibling exists for state + // tracking. + void addTargetSibling(ImageSibling *sibling); + + // Called from ImageSibling only to notify the image that a sibling (source or target) has + // been respecified and state tracking should be updated. + angle::Result orphanSibling(const gl::Context *context, ImageSibling *sibling); + + void notifySiblings(const ImageSibling *notifier, angle::SubjectMessage message); + + ImageState mState; + rx::ImageImpl *mImplementation; + bool mOrphanedAndNeedsInit; +}; +} // namespace egl + +#endif // LIBANGLE_IMAGE_H_ diff --git a/gfx/angle/checkout/src/libANGLE/ImageIndex.cpp b/gfx/angle/checkout/src/libANGLE/ImageIndex.cpp new file mode 100644 index 0000000000..55e0393fa4 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/ImageIndex.cpp @@ -0,0 +1,388 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ImageIndex.cpp: Implementation for ImageIndex methods. + +#include "libANGLE/ImageIndex.h" + +#include "common/utilities.h" +#include "libANGLE/Constants.h" +#include "libANGLE/angletypes.h" + +#include + +namespace gl +{ +namespace +{ +GLint TextureTargetToLayer(TextureTarget target) +{ + switch (target) + { + case TextureTarget::CubeMapPositiveX: + return 0; + case TextureTarget::CubeMapNegativeX: + return 1; + case TextureTarget::CubeMapPositiveY: + return 2; + case TextureTarget::CubeMapNegativeY: + return 3; + case TextureTarget::CubeMapPositiveZ: + return 4; + case TextureTarget::CubeMapNegativeZ: + return 5; + case TextureTarget::External: + case TextureTarget::Rectangle: + case TextureTarget::_2D: + case TextureTarget::VideoImage: + case TextureTarget::_2DArray: + case TextureTarget::_2DMultisample: + case TextureTarget::_2DMultisampleArray: + case TextureTarget::_3D: + case TextureTarget::Buffer: + case TextureTarget::CubeMapArray: + return ImageIndex::kEntireLevel; + default: + UNREACHABLE(); + return 0; + } +} + +bool IsArrayTarget(TextureTarget target) +{ + switch (target) + { + case TextureTarget::_2DArray: + case TextureTarget::_2DMultisampleArray: + case TextureTarget::CubeMapArray: + return true; + default: + return false; + } +} +} // anonymous namespace + +TextureTarget TextureTypeToTarget(TextureType type, GLint layerIndex) +{ + if (type == TextureType::CubeMap) + { + // As GL_TEXTURE_CUBE_MAP cannot be a texture target in texImage*D APIs, so we don't allow + // an entire cube map to have a texture target. + ASSERT(layerIndex != ImageIndex::kEntireLevel); + return CubeFaceIndexToTextureTarget(layerIndex); + } + else + { + return NonCubeTextureTypeToTarget(type); + } +} + +ImageIndex::ImageIndex() + : mType(TextureType::InvalidEnum), mLevelIndex(0), mLayerIndex(0), mLayerCount(kEntireLevel) +{} + +ImageIndex::ImageIndex(const ImageIndex &other) = default; + +ImageIndex &ImageIndex::operator=(const ImageIndex &other) = default; + +bool ImageIndex::hasLayer() const +{ + return mLayerIndex != kEntireLevel; +} + +bool ImageIndex::isLayered() const +{ + switch (mType) + { + case TextureType::_2DArray: + case TextureType::_2DMultisampleArray: + case TextureType::CubeMap: + case TextureType::_3D: + case TextureType::CubeMapArray: + return mLayerIndex == kEntireLevel; + default: + return false; + } +} + +bool ImageIndex::has3DLayer() const +{ + // It's quicker to check != CubeMap than calling usesTex3D, which checks multiple types. This + // ASSERT validates the check gives the same result. + ASSERT(!hasLayer() || ((mType != TextureType::CubeMap) == usesTex3D())); + return (hasLayer() && mType != TextureType::CubeMap); +} + +bool ImageIndex::usesTex3D() const +{ + return mType == TextureType::_3D || mType == TextureType::_2DArray || + mType == TextureType::_2DMultisampleArray || mType == TextureType::CubeMapArray; +} + +TextureTarget ImageIndex::getTarget() const +{ + return TextureTypeToTarget(mType, mLayerIndex); +} + +gl::TextureTarget ImageIndex::getTargetOrFirstCubeFace() const +{ + if (isEntireLevelCubeMap()) + { + return gl::kCubeMapTextureTargetMin; + } + else + { + return getTarget(); + } +} + +GLint ImageIndex::cubeMapFaceIndex() const +{ + ASSERT(mType == TextureType::CubeMap); + ASSERT(mLayerIndex == kEntireLevel || mLayerIndex < static_cast(kCubeFaceCount)); + return mLayerIndex; +} + +bool ImageIndex::valid() const +{ + return mType != TextureType::InvalidEnum; +} + +bool ImageIndex::isEntireLevelCubeMap() const +{ + return mType == TextureType::CubeMap && mLayerIndex == ImageIndex::kEntireLevel; +} + +ImageIndex ImageIndex::Make2D(GLint levelIndex) +{ + return ImageIndex(TextureType::_2D, levelIndex, kEntireLevel, 1); +} + +ImageIndex ImageIndex::MakeRectangle(GLint levelIndex) +{ + return ImageIndex(TextureType::Rectangle, levelIndex, kEntireLevel, 1); +} + +ImageIndex ImageIndex::MakeCubeMapFace(TextureTarget target, GLint levelIndex) +{ + ASSERT(IsCubeMapFaceTarget(target)); + return ImageIndex(TextureType::CubeMap, levelIndex, TextureTargetToLayer(target), 1); +} + +ImageIndex ImageIndex::Make2DArray(GLint levelIndex, GLint layerIndex) +{ + return ImageIndex(TextureType::_2DArray, levelIndex, layerIndex, 1); +} + +ImageIndex ImageIndex::Make2DArrayRange(GLint levelIndex, GLint layerIndex, GLint numLayers) +{ + return ImageIndex(TextureType::_2DArray, levelIndex, layerIndex, numLayers); +} + +ImageIndex ImageIndex::Make3D(GLint levelIndex, GLint layerIndex) +{ + return ImageIndex(TextureType::_3D, levelIndex, layerIndex, 1); +} + +ImageIndex ImageIndex::MakeFromTarget(TextureTarget target, GLint levelIndex, GLint depth) +{ + return ImageIndex(TextureTargetToType(target), levelIndex, TextureTargetToLayer(target), + IsArrayTarget(target) ? depth : 1); +} + +ImageIndex ImageIndex::MakeFromType(TextureType type, + GLint levelIndex, + GLint layerIndex, + GLint layerCount) +{ + GLint overrideLayerCount = + (type == TextureType::CubeMap && layerIndex == kEntireLevel ? kCubeFaceCount : layerCount); + return ImageIndex(type, levelIndex, layerIndex, overrideLayerCount); +} + +ImageIndex ImageIndex::MakeBuffer() +{ + return ImageIndex(TextureType::Buffer, 0, kEntireLevel, 1); +} + +ImageIndex ImageIndex::Make2DMultisample() +{ + return ImageIndex(TextureType::_2DMultisample, 0, kEntireLevel, 1); +} + +ImageIndex ImageIndex::Make2DMultisampleArray(GLint layerIndex) +{ + return ImageIndex(TextureType::_2DMultisampleArray, 0, layerIndex, 1); +} + +ImageIndex ImageIndex::Make2DMultisampleArrayRange(GLint layerIndex, GLint numLayers) +{ + return ImageIndex(TextureType::_2DMultisampleArray, 0, layerIndex, numLayers); +} + +bool ImageIndex::operator<(const ImageIndex &b) const +{ + return std::tie(mType, mLevelIndex, mLayerIndex, mLayerCount) < + std::tie(b.mType, b.mLevelIndex, b.mLayerIndex, b.mLayerCount); +} + +bool ImageIndex::operator==(const ImageIndex &b) const +{ + return std::tie(mType, mLevelIndex, mLayerIndex, mLayerCount) == + std::tie(b.mType, b.mLevelIndex, b.mLayerIndex, b.mLayerCount); +} + +bool ImageIndex::operator!=(const ImageIndex &b) const +{ + return !(*this == b); +} + +ImageIndex::ImageIndex(TextureType type, GLint levelIndex, GLint layerIndex, GLint layerCount) + : mType(type), mLevelIndex(levelIndex), mLayerIndex(layerIndex), mLayerCount(layerCount) +{} + +ImageIndexIterator ImageIndex::getLayerIterator(GLint layerCount) const +{ + ASSERT(mType != TextureType::_2D && !hasLayer()); + return ImageIndexIterator::MakeGeneric(mType, mLevelIndex, mLevelIndex + 1, 0, layerCount); +} + +ImageIndexIterator::ImageIndexIterator(const ImageIndexIterator &other) = default; + +ImageIndexIterator ImageIndexIterator::Make2D(GLint minMip, GLint maxMip) +{ + return ImageIndexIterator(TextureType::_2D, Range(minMip, maxMip), + Range(ImageIndex::kEntireLevel, ImageIndex::kEntireLevel), + nullptr); +} + +ImageIndexIterator ImageIndexIterator::MakeRectangle(GLint minMip, GLint maxMip) +{ + return ImageIndexIterator(TextureType::Rectangle, Range(minMip, maxMip), + Range(ImageIndex::kEntireLevel, ImageIndex::kEntireLevel), + nullptr); +} + +ImageIndexIterator ImageIndexIterator::MakeCube(GLint minMip, GLint maxMip) +{ + return ImageIndexIterator(TextureType::CubeMap, Range(minMip, maxMip), + Range(0, 6), nullptr); +} + +ImageIndexIterator ImageIndexIterator::Make3D(GLint minMip, + GLint maxMip, + GLint minLayer, + GLint maxLayer) +{ + return ImageIndexIterator(TextureType::_3D, Range(minMip, maxMip), + Range(minLayer, maxLayer), nullptr); +} + +ImageIndexIterator ImageIndexIterator::Make2DArray(GLint minMip, + GLint maxMip, + const GLsizei *layerCounts) +{ + return ImageIndexIterator(TextureType::_2DArray, Range(minMip, maxMip), + Range(0, IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS), + layerCounts); +} + +ImageIndexIterator ImageIndexIterator::Make2DMultisample() +{ + return ImageIndexIterator(TextureType::_2DMultisample, Range(0, 1), + Range(ImageIndex::kEntireLevel, ImageIndex::kEntireLevel), + nullptr); +} + +ImageIndexIterator ImageIndexIterator::MakeBuffer() +{ + return ImageIndexIterator(TextureType::Buffer, Range(0, 1), + Range(ImageIndex::kEntireLevel, ImageIndex::kEntireLevel), + nullptr); +} + +ImageIndexIterator ImageIndexIterator::Make2DMultisampleArray(const GLsizei *layerCounts) +{ + return ImageIndexIterator(TextureType::_2DMultisampleArray, Range(0, 1), + Range(0, IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS), + layerCounts); +} + +ImageIndexIterator ImageIndexIterator::MakeGeneric(TextureType type, + GLint minMip, + GLint maxMip, + GLint minLayer, + GLint maxLayer) +{ + if (type == TextureType::CubeMap) + { + return MakeCube(minMip, maxMip); + } + + return ImageIndexIterator(type, Range(minMip, maxMip), Range(minLayer, maxLayer), + nullptr); +} + +ImageIndexIterator::ImageIndexIterator(TextureType type, + const Range &mipRange, + const Range &layerRange, + const GLsizei *layerCounts) + : mMipRange(mipRange), + mLayerRange(layerRange), + mLayerCounts(layerCounts), + mCurrentIndex(type, mipRange.low(), layerRange.low(), 1) +{} + +GLint ImageIndexIterator::maxLayer() const +{ + if (mLayerCounts) + { + ASSERT(mCurrentIndex.hasLayer()); + return (mCurrentIndex.getLevelIndex() < mMipRange.high()) + ? mLayerCounts[mCurrentIndex.getLevelIndex()] + : 0; + } + return mLayerRange.high(); +} + +ImageIndex ImageIndexIterator::next() +{ + ASSERT(hasNext()); + + // Make a copy of the current index to return + ImageIndex previousIndex = mCurrentIndex; + + // Iterate layers in the inner loop for now. We can add switchable + // layer or mip iteration if we need it. + + if (mCurrentIndex.hasLayer() && mCurrentIndex.getLayerIndex() < maxLayer() - 1) + { + mCurrentIndex.mLayerIndex++; + } + else if (mCurrentIndex.mLevelIndex < mMipRange.high() - 1) + { + mCurrentIndex.mLayerIndex = mLayerRange.low(); + mCurrentIndex.mLevelIndex++; + } + else + { + mCurrentIndex = ImageIndex(); + } + + return previousIndex; +} + +ImageIndex ImageIndexIterator::current() const +{ + return mCurrentIndex; +} + +bool ImageIndexIterator::hasNext() const +{ + return mCurrentIndex.valid(); +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/ImageIndex.h b/gfx/angle/checkout/src/libANGLE/ImageIndex.h new file mode 100644 index 0000000000..4625d310d8 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/ImageIndex.h @@ -0,0 +1,133 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ImageIndex.h: A helper struct for indexing into an Image array + +#ifndef LIBANGLE_IMAGE_INDEX_H_ +#define LIBANGLE_IMAGE_INDEX_H_ + +#include "common/PackedEnums.h" +#include "common/mathutil.h" + +#include "angle_gl.h" + +namespace gl +{ + +class ImageIndexIterator; + +class ImageIndex +{ + public: + ImageIndex(); + ImageIndex(const ImageIndex &other); + ImageIndex &operator=(const ImageIndex &other); + + TextureType getType() const { return mType; } + GLint getLevelIndex() const { return mLevelIndex; } + GLint getLayerIndex() const { return mLayerIndex; } + GLint getLayerCount() const { return mLayerCount; } + + bool hasLayer() const; + bool has3DLayer() const; + bool usesTex3D() const; + GLint cubeMapFaceIndex() const; + bool valid() const; + // Note that you cannot use this function when the ImageIndex represents an entire level of cube + // map. + TextureTarget getTarget() const; + + TextureTarget getTargetOrFirstCubeFace() const; + + bool isLayered() const; + bool isEntireLevelCubeMap() const; + + static ImageIndex MakeBuffer(); + static ImageIndex Make2D(GLint levelIndex); + static ImageIndex MakeRectangle(GLint levelIndex); + static ImageIndex MakeCubeMapFace(TextureTarget target, GLint levelIndex); + static ImageIndex Make2DArray(GLint levelIndex, GLint layerIndex = kEntireLevel); + static ImageIndex Make2DArrayRange(GLint levelIndex, GLint layerIndex, GLint layerCount); + static ImageIndex Make3D(GLint levelIndex, GLint layerIndex = kEntireLevel); + static ImageIndex MakeFromTarget(TextureTarget target, GLint levelIndex, GLint depth = 0); + static ImageIndex MakeFromType(TextureType type, + GLint levelIndex, + GLint layerIndex = kEntireLevel, + GLint layerCount = 1); + static ImageIndex Make2DMultisample(); + static ImageIndex Make2DMultisampleArray(GLint layerIndex = kEntireLevel); + static ImageIndex Make2DMultisampleArrayRange(GLint layerIndex, GLint layerCount); + + static constexpr GLint kEntireLevel = static_cast(-1); + + bool operator<(const ImageIndex &b) const; + bool operator==(const ImageIndex &b) const; + bool operator!=(const ImageIndex &b) const; + + // Only valid for 3D/Cube textures with layers. + ImageIndexIterator getLayerIterator(GLint layerCount) const; + + private: + friend class ImageIndexIterator; + + ImageIndex(TextureType type, GLint leveIndex, GLint layerIndex, GLint layerCount); + + TextureType mType; + GLint mLevelIndex; + GLint mLayerIndex; + GLint mLayerCount; +}; + +// To be used like this: +// +// ImageIndexIterator it = ...; +// while (it.hasNext()) +// { +// ImageIndex current = it.next(); +// } +class ImageIndexIterator +{ + public: + ImageIndexIterator(const ImageIndexIterator &other); + + static ImageIndexIterator MakeBuffer(); + static ImageIndexIterator Make2D(GLint minMip, GLint maxMip); + static ImageIndexIterator MakeRectangle(GLint minMip, GLint maxMip); + static ImageIndexIterator MakeCube(GLint minMip, GLint maxMip); + static ImageIndexIterator Make3D(GLint minMip, GLint maxMip, GLint minLayer, GLint maxLayer); + static ImageIndexIterator Make2DArray(GLint minMip, GLint maxMip, const GLsizei *layerCounts); + static ImageIndexIterator Make2DMultisample(); + static ImageIndexIterator Make2DMultisampleArray(const GLsizei *layerCounts); + static ImageIndexIterator MakeGeneric(TextureType type, + GLint minMip, + GLint maxMip, + GLint minLayer, + GLint maxLayer); + + ImageIndex next(); + ImageIndex current() const; + bool hasNext() const; + + private: + ImageIndexIterator(TextureType type, + const Range &mipRange, + const Range &layerRange, + const GLsizei *layerCounts); + + GLint maxLayer() const; + + const Range mMipRange; + const Range mLayerRange; + const GLsizei *const mLayerCounts; + + ImageIndex mCurrentIndex; +}; + +TextureTarget TextureTypeToTarget(TextureType type, GLint layerIndex); + +} // namespace gl + +#endif // LIBANGLE_IMAGE_INDEX_H_ diff --git a/gfx/angle/checkout/src/libANGLE/IndexRangeCache.cpp b/gfx/angle/checkout/src/libANGLE/IndexRangeCache.cpp new file mode 100644 index 0000000000..d16b2bd9c7 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/IndexRangeCache.cpp @@ -0,0 +1,116 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// IndexRangeCache.cpp: Defines the gl::IndexRangeCache class which stores information about +// ranges of indices. + +#include "libANGLE/IndexRangeCache.h" + +#include "common/debug.h" +#include "libANGLE/formatutils.h" + +namespace gl +{ + +IndexRangeCache::IndexRangeCache() {} + +IndexRangeCache::~IndexRangeCache() {} + +void IndexRangeCache::addRange(DrawElementsType type, + size_t offset, + size_t count, + bool primitiveRestartEnabled, + const IndexRange &range) +{ + mIndexRangeCache[IndexRangeKey(type, offset, count, primitiveRestartEnabled)] = range; +} + +bool IndexRangeCache::findRange(DrawElementsType type, + size_t offset, + size_t count, + bool primitiveRestartEnabled, + IndexRange *outRange) const +{ + auto i = mIndexRangeCache.find(IndexRangeKey(type, offset, count, primitiveRestartEnabled)); + if (i != mIndexRangeCache.end()) + { + if (outRange) + { + *outRange = i->second; + } + return true; + } + else + { + if (outRange) + { + *outRange = IndexRange(); + } + return false; + } +} + +void IndexRangeCache::invalidateRange(size_t offset, size_t size) +{ + size_t invalidateStart = offset; + size_t invalidateEnd = offset + size; + + auto i = mIndexRangeCache.begin(); + while (i != mIndexRangeCache.end()) + { + size_t rangeStart = i->first.offset; + size_t rangeEnd = + i->first.offset + (GetDrawElementsTypeSize(i->first.type) * i->first.count); + + if (invalidateEnd < rangeStart || invalidateStart > rangeEnd) + { + ++i; + } + else + { + mIndexRangeCache.erase(i++); + } + } +} + +void IndexRangeCache::clear() +{ + mIndexRangeCache.clear(); +} + +IndexRangeCache::IndexRangeKey::IndexRangeKey() + : IndexRangeCache::IndexRangeKey(DrawElementsType::InvalidEnum, 0, 0, false) +{} + +IndexRangeCache::IndexRangeKey::IndexRangeKey(DrawElementsType type_, + size_t offset_, + size_t count_, + bool primitiveRestartEnabled_) + : type(type_), offset(offset_), count(count_), primitiveRestartEnabled(primitiveRestartEnabled_) +{} + +bool IndexRangeCache::IndexRangeKey::operator<(const IndexRangeKey &rhs) const +{ + if (type != rhs.type) + { + return type < rhs.type; + } + if (offset != rhs.offset) + { + return offset < rhs.offset; + } + if (count != rhs.count) + { + return count < rhs.count; + } + if (primitiveRestartEnabled != rhs.primitiveRestartEnabled) + { + return primitiveRestartEnabled; + } + return false; +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/IndexRangeCache.h b/gfx/angle/checkout/src/libANGLE/IndexRangeCache.h new file mode 100644 index 0000000000..0a0c22fe04 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/IndexRangeCache.h @@ -0,0 +1,63 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// IndexRangeCache.h: Defines the gl::IndexRangeCache class which stores information about +// ranges of indices. + +#ifndef LIBANGLE_INDEXRANGECACHE_H_ +#define LIBANGLE_INDEXRANGECACHE_H_ + +#include "angle_gl.h" +#include "common/PackedEnums.h" +#include "common/angleutils.h" +#include "common/mathutil.h" + +#include + +namespace gl +{ + +class IndexRangeCache +{ + public: + IndexRangeCache(); + ~IndexRangeCache(); + + void addRange(DrawElementsType type, + size_t offset, + size_t count, + bool primitiveRestartEnabled, + const IndexRange &range); + bool findRange(DrawElementsType type, + size_t offset, + size_t count, + bool primitiveRestartEnabled, + IndexRange *outRange) const; + + void invalidateRange(size_t offset, size_t size); + void clear(); + + private: + struct IndexRangeKey + { + IndexRangeKey(); + IndexRangeKey(DrawElementsType type, size_t offset, size_t count, bool primitiveRestart); + + bool operator<(const IndexRangeKey &rhs) const; + + DrawElementsType type; + size_t offset; + size_t count; + bool primitiveRestartEnabled; + }; + + typedef std::map IndexRangeMap; + IndexRangeMap mIndexRangeCache; +}; + +} // namespace gl + +#endif // LIBANGLE_INDEXRANGECACHE_H_ diff --git a/gfx/angle/checkout/src/libANGLE/InfoLog.h b/gfx/angle/checkout/src/libANGLE/InfoLog.h new file mode 100644 index 0000000000..53333ea1aa --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/InfoLog.h @@ -0,0 +1,90 @@ +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// InfoLog.h: Defines the gl::InfoLog class to handle the logs generated when +// compiling/linking shaders so useful error messages can be returned to the caller. + +#ifndef LIBANGLE_INFOLOG_H_ +#define LIBANGLE_INFOLOG_H_ + +namespace gl +{ + +class InfoLog : angle::NonCopyable +{ + public: + InfoLog(); + ~InfoLog(); + + size_t getLength() const; + void getLog(GLsizei bufSize, GLsizei *length, char *infoLog) const; + + void appendSanitized(const char *message); + void reset(); + + // This helper class ensures we append a newline after writing a line. + class StreamHelper : angle::NonCopyable + { + public: + StreamHelper(StreamHelper &&rhs) : mStream(rhs.mStream) { rhs.mStream = nullptr; } + + StreamHelper &operator=(StreamHelper &&rhs) + { + std::swap(mStream, rhs.mStream); + return *this; + } + + ~StreamHelper() + { + // Write newline when destroyed on the stack + if (mStream && !mStream->str().empty()) + { + (*mStream) << std::endl; + } + } + + template + StreamHelper &operator<<(const T &value) + { + (*mStream) << value; + return *this; + } + + private: + friend class InfoLog; + + StreamHelper(std::stringstream *stream) : mStream(stream) { ASSERT(stream); } + + std::stringstream *mStream; + }; + + template + StreamHelper operator<<(const T &value) + { + ensureInitialized(); + StreamHelper helper(mLazyStream.get()); + helper << value; + return helper; + } + + std::string str() const { return mLazyStream ? mLazyStream->str() : ""; } + + bool empty() const; + + private: + void ensureInitialized() + { + if (!mLazyStream) + { + mLazyStream.reset(new std::stringstream()); + } + } + + std::unique_ptr mLazyStream; +}; + +} // namespace gl + +#endif // LIBANGLE_INFOLOG_H_ diff --git a/gfx/angle/checkout/src/libANGLE/LoggingAnnotator.cpp b/gfx/angle/checkout/src/libANGLE/LoggingAnnotator.cpp new file mode 100644 index 0000000000..4cf999c4a0 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/LoggingAnnotator.cpp @@ -0,0 +1,63 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// LoggingAnnotator.cpp: DebugAnnotator implementing logging +// + +#include "libANGLE/LoggingAnnotator.h" + +#include "libANGLE/trace.h" + +namespace angle +{ + +bool LoggingAnnotator::getStatus(const gl::Context *context) +{ + return false; +} + +void LoggingAnnotator::beginEvent(gl::Context *context, + EntryPoint entryPoint, + const char *eventName, + const char *eventMessage) +{ + ANGLE_TRACE_EVENT_BEGIN0("gpu.angle", eventName); +} + +void LoggingAnnotator::endEvent(gl::Context *context, const char *eventName, EntryPoint entryPoint) +{ + ANGLE_TRACE_EVENT_END0("gpu.angle", eventName); +} + +void LoggingAnnotator::setMarker(gl::Context *context, const char *markerName) +{ + ANGLE_TRACE_EVENT_INSTANT0("gpu.angle", markerName); +} + +void LoggingAnnotator::logMessage(const gl::LogMessage &msg) const +{ + auto *plat = ANGLEPlatformCurrent(); + if (plat != nullptr) + { + switch (msg.getSeverity()) + { + case gl::LOG_FATAL: + case gl::LOG_ERR: + plat->logError(plat, msg.getMessage().c_str()); + break; + case gl::LOG_WARN: + plat->logWarning(plat, msg.getMessage().c_str()); + break; + case gl::LOG_INFO: + plat->logInfo(plat, msg.getMessage().c_str()); + break; + default: + UNREACHABLE(); + } + } + gl::Trace(msg.getSeverity(), msg.getMessage().c_str()); +} + +} // namespace angle diff --git a/gfx/angle/checkout/src/libANGLE/LoggingAnnotator.h b/gfx/angle/checkout/src/libANGLE/LoggingAnnotator.h new file mode 100644 index 0000000000..7a86d4e72f --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/LoggingAnnotator.h @@ -0,0 +1,39 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// LoggingAnnotator.h: DebugAnnotator implementing logging +// + +#ifndef LIBANGLE_LOGGINGANNOTATOR_H_ +#define LIBANGLE_LOGGINGANNOTATOR_H_ + +#include "common/debug.h" + +namespace gl +{ +class Context; +} // namespace gl + +namespace angle +{ + +class LoggingAnnotator : public gl::DebugAnnotator +{ + public: + LoggingAnnotator() {} + ~LoggingAnnotator() override {} + void beginEvent(gl::Context *context, + EntryPoint entryPoint, + const char *eventName, + const char *eventMessage) override; + void endEvent(gl::Context *context, const char *eventName, EntryPoint entryPoint) override; + void setMarker(gl::Context *context, const char *markerName) override; + bool getStatus(const gl::Context *context) override; + void logMessage(const gl::LogMessage &msg) const override; +}; + +} // namespace angle + +#endif // LIBANGLE_LOGGINGANNOTATOR_H_ diff --git a/gfx/angle/checkout/src/libANGLE/MemoryObject.cpp b/gfx/angle/checkout/src/libANGLE/MemoryObject.cpp new file mode 100644 index 0000000000..a137f265c5 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/MemoryObject.cpp @@ -0,0 +1,66 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// MemoryObject.h: Implements the gl::MemoryObject class [EXT_external_objects] + +#include "libANGLE/MemoryObject.h" + +#include "common/angleutils.h" +#include "libANGLE/renderer/GLImplFactory.h" +#include "libANGLE/renderer/MemoryObjectImpl.h" + +namespace gl +{ + +MemoryObject::MemoryObject(rx::GLImplFactory *factory, MemoryObjectID id) + : RefCountObject(factory->generateSerial(), id), + mImplementation(factory->createMemoryObject()), + mImmutable(false), + mDedicatedMemory(false), + mProtectedMemory(false) +{} + +MemoryObject::~MemoryObject() {} + +void MemoryObject::onDestroy(const Context *context) +{ + mImplementation->onDestroy(context); +} + +angle::Result MemoryObject::setDedicatedMemory(const Context *context, bool dedicatedMemory) +{ + ANGLE_TRY(mImplementation->setDedicatedMemory(context, dedicatedMemory)); + mDedicatedMemory = dedicatedMemory; + return angle::Result::Continue; +} + +angle::Result MemoryObject::setProtectedMemory(const Context *context, bool protectedMemory) +{ + ANGLE_TRY(mImplementation->setProtectedMemory(context, protectedMemory)); + mProtectedMemory = protectedMemory; + return angle::Result::Continue; +} + +angle::Result MemoryObject::importFd(Context *context, + GLuint64 size, + HandleType handleType, + GLint fd) +{ + ANGLE_TRY(mImplementation->importFd(context, size, handleType, fd)); + mImmutable = true; + return angle::Result::Continue; +} + +angle::Result MemoryObject::importZirconHandle(Context *context, + GLuint64 size, + HandleType handleType, + GLuint handle) +{ + ANGLE_TRY(mImplementation->importZirconHandle(context, size, handleType, handle)); + mImmutable = true; + return angle::Result::Continue; +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/MemoryObject.h b/gfx/angle/checkout/src/libANGLE/MemoryObject.h new file mode 100644 index 0000000000..0507f7e2c3 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/MemoryObject.h @@ -0,0 +1,60 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// MemoryObject.h: Defines the gl::MemoryObject class [EXT_external_objects] + +#ifndef LIBANGLE_MEMORYOBJECT_H_ +#define LIBANGLE_MEMORYOBJECT_H_ + +#include "angle_gl.h" +#include "common/PackedEnums.h" +#include "common/angleutils.h" +#include "libANGLE/Error.h" +#include "libANGLE/RefCountObject.h" + +namespace rx +{ +class GLImplFactory; +class MemoryObjectImpl; +} // namespace rx + +namespace gl +{ +class Context; + +class MemoryObject final : public RefCountObject +{ + public: + MemoryObject(rx::GLImplFactory *factory, MemoryObjectID id); + ~MemoryObject() override; + + void onDestroy(const Context *context) override; + + rx::MemoryObjectImpl *getImplementation() const { return mImplementation.get(); } + + bool isImmutable() const { return mImmutable; } + + angle::Result setDedicatedMemory(const Context *context, bool dedicatedMemory); + bool isDedicatedMemory() const { return mDedicatedMemory; } + angle::Result setProtectedMemory(const Context *context, bool protectedMemory); + bool isProtectedMemory() const { return mProtectedMemory; } + + angle::Result importFd(Context *context, GLuint64 size, HandleType handleType, GLint fd); + angle::Result importZirconHandle(Context *context, + GLuint64 size, + HandleType handleType, + GLuint handle); + + private: + std::unique_ptr mImplementation; + + bool mImmutable; + bool mDedicatedMemory; + bool mProtectedMemory; +}; + +} // namespace gl + +#endif // LIBANGLE_MEMORYOBJECT_H_ diff --git a/gfx/angle/checkout/src/libANGLE/MemoryProgramCache.cpp b/gfx/angle/checkout/src/libANGLE/MemoryProgramCache.cpp new file mode 100644 index 0000000000..35894913a6 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/MemoryProgramCache.cpp @@ -0,0 +1,283 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// MemoryProgramCache: Stores compiled and linked programs in memory so they don't +// always have to be re-compiled. Can be used in conjunction with the platform +// layer to warm up the cache from disk. + +// Include zlib first, otherwise FAR gets defined elsewhere. +#define USE_SYSTEM_ZLIB +#include "compression_utils_portable.h" + +#include "libANGLE/MemoryProgramCache.h" + +#include +#include + +#include "common/angle_version_info.h" +#include "common/utilities.h" +#include "libANGLE/BinaryStream.h" +#include "libANGLE/Context.h" +#include "libANGLE/Debug.h" +#include "libANGLE/Uniform.h" +#include "libANGLE/capture/FrameCapture.h" +#include "libANGLE/histogram_macros.h" +#include "libANGLE/renderer/ProgramImpl.h" +#include "platform/PlatformMethods.h" + +namespace gl +{ + +namespace +{ +class HashStream final : angle::NonCopyable +{ + public: + std::string str() { return mStringStream.str(); } + + template + HashStream &operator<<(T value) + { + mStringStream << value << kSeparator; + return *this; + } + + private: + static constexpr char kSeparator = ':'; + std::ostringstream mStringStream; +}; + +HashStream &operator<<(HashStream &stream, Shader *shader) +{ + if (shader) + { + stream << shader->getSourceString().c_str() << shader->getSourceString().length() + << shader->getCompilerResourcesString().c_str(); + } + return stream; +} + +HashStream &operator<<(HashStream &stream, const ProgramBindings &bindings) +{ + for (const auto &binding : bindings.getStableIterationMap()) + { + stream << binding.first << binding.second; + } + return stream; +} + +HashStream &operator<<(HashStream &stream, const ProgramAliasedBindings &bindings) +{ + for (const auto &binding : bindings.getStableIterationMap()) + { + stream << binding.first << binding.second.location; + } + return stream; +} + +HashStream &operator<<(HashStream &stream, const std::vector &strings) +{ + for (const auto &str : strings) + { + stream << str; + } + return stream; +} + +HashStream &operator<<(HashStream &stream, const std::vector &locations) +{ + for (const auto &loc : locations) + { + stream << loc.index << loc.arrayIndex << loc.ignored; + } + return stream; +} + +} // anonymous namespace + +MemoryProgramCache::MemoryProgramCache(egl::BlobCache &blobCache) : mBlobCache(blobCache) {} + +MemoryProgramCache::~MemoryProgramCache() {} + +void MemoryProgramCache::ComputeHash(const Context *context, + const Program *program, + egl::BlobCache::Key *hashOut) +{ + // Compute the program hash. Start with the shader hashes and resource strings. + HashStream hashStream; + for (ShaderType shaderType : AllShaderTypes()) + { + hashStream << program->getAttachedShader(shaderType); + } + + // Add some ANGLE metadata and Context properties, such as version and back-end. + hashStream << angle::GetANGLECommitHash() << context->getClientMajorVersion() + << context->getClientMinorVersion() << context->getString(GL_RENDERER); + + // Hash pre-link program properties. + hashStream << program->getAttributeBindings() << program->getUniformLocationBindings() + << program->getFragmentOutputLocations() << program->getFragmentOutputIndexes() + << program->getState().getTransformFeedbackVaryingNames() + << program->getState().getTransformFeedbackBufferMode() + << program->getState().getOutputLocations() + << program->getState().getSecondaryOutputLocations(); + + // Include the status of FrameCapture, which adds source strings to the binary + hashStream << context->getShareGroup()->getFrameCaptureShared()->enabled(); + + // Call the secure SHA hashing function. + const std::string &programKey = hashStream.str(); + angle::base::SHA1HashBytes(reinterpret_cast(programKey.c_str()), + programKey.length(), hashOut->data()); +} + +angle::Result MemoryProgramCache::getProgram(const Context *context, + Program *program, + egl::BlobCache::Key *hashOut) +{ + // If caching is effectively disabled, don't bother calculating the hash. + if (!mBlobCache.isCachingEnabled()) + { + return angle::Result::Incomplete; + } + + ComputeHash(context, program, hashOut); + + angle::MemoryBuffer uncompressedData; + switch (mBlobCache.getAndDecompress(context->getScratchBuffer(), *hashOut, &uncompressedData)) + { + case egl::BlobCache::GetAndDecompressResult::NotFound: + return angle::Result::Incomplete; + + case egl::BlobCache::GetAndDecompressResult::DecompressFailure: + ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_LOW, + "Error decompressing program binary data fetched from cache."); + return angle::Result::Incomplete; + + case egl::BlobCache::GetAndDecompressResult::GetSuccess: + angle::Result result = + program->loadBinary(context, GL_PROGRAM_BINARY_ANGLE, uncompressedData.data(), + static_cast(uncompressedData.size())); + ANGLE_TRY(result); + + if (result == angle::Result::Continue) + return angle::Result::Continue; + + // Cache load failed, evict + ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_LOW, + "Failed to load program binary from cache."); + remove(*hashOut); + + return angle::Result::Incomplete; + } + + UNREACHABLE(); + return angle::Result::Incomplete; +} + +bool MemoryProgramCache::getAt(size_t index, + const egl::BlobCache::Key **hashOut, + egl::BlobCache::Value *programOut) +{ + return mBlobCache.getAt(index, hashOut, programOut); +} + +void MemoryProgramCache::remove(const egl::BlobCache::Key &programHash) +{ + mBlobCache.remove(programHash); +} + +angle::Result MemoryProgramCache::putProgram(const egl::BlobCache::Key &programHash, + const Context *context, + const Program *program) +{ + // If caching is effectively disabled, don't bother serializing the program. + if (!mBlobCache.isCachingEnabled()) + { + return angle::Result::Incomplete; + } + + angle::MemoryBuffer serializedProgram; + ANGLE_TRY(program->serialize(context, &serializedProgram)); + + angle::MemoryBuffer compressedData; + if (!egl::CompressBlobCacheData(serializedProgram.size(), serializedProgram.data(), + &compressedData)) + { + ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_LOW, + "Error compressing binary data."); + return angle::Result::Incomplete; + } + + { + std::scoped_lock lock(mBlobCache.getMutex()); + // TODO: http://anglebug.com/7568 + // This was a workaround for Chrome until it added support for EGL_ANDROID_blob_cache, + // tracked by http://anglebug.com/2516. This issue has since been closed, but removing this + // still causes a test failure. + auto *platform = ANGLEPlatformCurrent(); + platform->cacheProgram(platform, programHash, compressedData.size(), compressedData.data()); + } + + mBlobCache.put(programHash, std::move(compressedData)); + return angle::Result::Continue; +} + +angle::Result MemoryProgramCache::updateProgram(const Context *context, const Program *program) +{ + egl::BlobCache::Key programHash; + ComputeHash(context, program, &programHash); + return putProgram(programHash, context, program); +} + +bool MemoryProgramCache::putBinary(const egl::BlobCache::Key &programHash, + const uint8_t *binary, + size_t length) +{ + // Copy the binary. + angle::MemoryBuffer newEntry; + if (!newEntry.resize(length)) + { + return false; + } + memcpy(newEntry.data(), binary, length); + + // Store the binary. + mBlobCache.populate(programHash, std::move(newEntry)); + + return true; +} + +void MemoryProgramCache::clear() +{ + mBlobCache.clear(); +} + +void MemoryProgramCache::resize(size_t maxCacheSizeBytes) +{ + mBlobCache.resize(maxCacheSizeBytes); +} + +size_t MemoryProgramCache::entryCount() const +{ + return mBlobCache.entryCount(); +} + +size_t MemoryProgramCache::trim(size_t limit) +{ + return mBlobCache.trim(limit); +} + +size_t MemoryProgramCache::size() const +{ + return mBlobCache.size(); +} + +size_t MemoryProgramCache::maxSize() const +{ + return mBlobCache.maxSize(); +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/MemoryProgramCache.h b/gfx/angle/checkout/src/libANGLE/MemoryProgramCache.h new file mode 100644 index 0000000000..92f774ebed --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/MemoryProgramCache.h @@ -0,0 +1,87 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// MemoryProgramCache: Stores compiled and linked programs in memory so they don't +// always have to be re-compiled. Can be used in conjunction with the platform +// layer to warm up the cache from disk. + +#ifndef LIBANGLE_MEMORY_PROGRAM_CACHE_H_ +#define LIBANGLE_MEMORY_PROGRAM_CACHE_H_ + +#include + +#include "common/MemoryBuffer.h" +#include "libANGLE/BlobCache.h" +#include "libANGLE/Error.h" + +namespace gl +{ +class Context; +class Program; +class ProgramState; + +class MemoryProgramCache final : angle::NonCopyable +{ + public: + explicit MemoryProgramCache(egl::BlobCache &blobCache); + ~MemoryProgramCache(); + + static void ComputeHash(const Context *context, + const Program *program, + egl::BlobCache::Key *hashOut); + + // For querying the contents of the cache. + bool getAt(size_t index, + const egl::BlobCache::Key **hashOut, + egl::BlobCache::Value *programOut); + + // Evict a program from the binary cache. + void remove(const egl::BlobCache::Key &programHash); + + // Helper method that serializes a program. + angle::Result putProgram(const egl::BlobCache::Key &programHash, + const Context *context, + const Program *program); + + // Same as putProgram but computes the hash. + angle::Result updateProgram(const Context *context, const Program *program); + + // Store a binary directly. TODO(syoussefi): deprecated. Will be removed once Chrome supports + // EGL_ANDROID_blob_cache. http://anglebug.com/2516 + [[nodiscard]] bool putBinary(const egl::BlobCache::Key &programHash, + const uint8_t *binary, + size_t length); + + // Check the cache, and deserialize and load the program if found. Evict existing hash if load + // fails. + angle::Result getProgram(const Context *context, + Program *program, + egl::BlobCache::Key *hashOut); + + // Empty the cache. + void clear(); + + // Resize the cache. Discards current contents. + void resize(size_t maxCacheSizeBytes); + + // Returns the number of entries in the cache. + size_t entryCount() const; + + // Reduces the current cache size and returns the number of bytes freed. + size_t trim(size_t limit); + + // Returns the current cache size in bytes. + size_t size() const; + + // Returns the maximum cache size in bytes. + size_t maxSize() const; + + private: + egl::BlobCache &mBlobCache; +}; + +} // namespace gl + +#endif // LIBANGLE_MEMORY_PROGRAM_CACHE_H_ diff --git a/gfx/angle/checkout/src/libANGLE/MemoryShaderCache.cpp b/gfx/angle/checkout/src/libANGLE/MemoryShaderCache.cpp new file mode 100644 index 0000000000..2bd7baef5e --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/MemoryShaderCache.cpp @@ -0,0 +1,155 @@ +// +// Copyright 2022 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// MemoryShaderCache: Stores compiled shader in memory so they don't +// always have to be re-compiled. Can be used in conjunction with the platform +// layer to warm up the cache from disk. + +#include "libANGLE/MemoryShaderCache.h" + +#include +#include + +#include "common/angle_version_info.h" +#include "common/utilities.h" +#include "libANGLE/BinaryStream.h" +#include "libANGLE/Compiler.h" +#include "libANGLE/Context.h" +#include "libANGLE/Debug.h" +#include "libANGLE/Uniform.h" +#include "libANGLE/histogram_macros.h" +#include "libANGLE/renderer/ShaderImpl.h" +#include "platform/PlatformMethods.h" + +namespace gl +{ + +namespace +{ +void ComputeHash(const Context *context, + const Shader *shader, + const ShCompileOptions &compileOptions, + const ShCompilerInstance &compilerInstance, + egl::BlobCache::Key *hashOut) +{ + BinaryOutputStream hashStream; + // Compute the shader hash. Start with the shader hashes and resource strings. + hashStream.writeEnum(shader->getType()); + hashStream.writeString(shader->getSourceString()); + + // Include the commit hash + hashStream.writeString(angle::GetANGLECommitHash()); + + hashStream.writeEnum(Compiler::SelectShaderSpec(context->getState())); + hashStream.writeEnum(compilerInstance.getShaderOutputType()); + hashStream.writeBytes(reinterpret_cast(&compileOptions), + sizeof(compileOptions)); + + // Include the ShBuiltInResources, which represent the extensions and constants used by the + // shader. + const ShBuiltInResources resources = compilerInstance.getBuiltInResources(); + hashStream.writeBytes(reinterpret_cast(&resources), sizeof(resources)); + + // Call the secure SHA hashing function. + const std::vector &shaderKey = hashStream.getData(); + angle::base::SHA1HashBytes(shaderKey.data(), shaderKey.size(), hashOut->data()); +} +} // namespace + +MemoryShaderCache::MemoryShaderCache(egl::BlobCache &blobCache) : mBlobCache(blobCache) {} + +MemoryShaderCache::~MemoryShaderCache() {} + +angle::Result MemoryShaderCache::getShader(const Context *context, + Shader *shader, + const ShCompileOptions &compileOptions, + const ShCompilerInstance &compilerInstance, + egl::BlobCache::Key *hashOut) +{ + // If caching is effectively disabled, don't bother calculating the hash. + if (!mBlobCache.isCachingEnabled()) + { + return angle::Result::Incomplete; + } + + ComputeHash(context, shader, compileOptions, compilerInstance, hashOut); + + angle::MemoryBuffer uncompressedData; + switch (mBlobCache.getAndDecompress(context->getScratchBuffer(), *hashOut, &uncompressedData)) + { + case egl::BlobCache::GetAndDecompressResult::DecompressFailure: + ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_LOW, + "Error decompressing shader binary data from cache."); + return angle::Result::Incomplete; + + case egl::BlobCache::GetAndDecompressResult::NotFound: + return angle::Result::Incomplete; + + case egl::BlobCache::GetAndDecompressResult::GetSuccess: + angle::Result result = shader->loadBinary(context, uncompressedData.data(), + static_cast(uncompressedData.size())); + + { + std::scoped_lock lock(mHistogramMutex); + ANGLE_HISTOGRAM_BOOLEAN("GPU.ANGLE.ShaderCache.LoadBinarySuccess", + result == angle::Result::Continue); + } + ANGLE_TRY(result); + + if (result == angle::Result::Continue) + return angle::Result::Continue; + + // Cache load failed, evict. + ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_LOW, + "Failed to load shader binary from cache."); + mBlobCache.remove(*hashOut); + return angle::Result::Incomplete; + } + + UNREACHABLE(); + return angle::Result::Incomplete; +} + +angle::Result MemoryShaderCache::putShader(const Context *context, + const egl::BlobCache::Key &shaderHash, + const Shader *shader) +{ + // If caching is effectively disabled, don't bother serializing the shader. + if (!mBlobCache.isCachingEnabled()) + { + return angle::Result::Incomplete; + } + + angle::MemoryBuffer serializedShader; + ANGLE_TRY(shader->serialize(nullptr, &serializedShader)); + + size_t compressedSize; + if (!mBlobCache.compressAndPut(shaderHash, std::move(serializedShader), &compressedSize)) + { + ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_LOW, + "Error compressing shader binary data for insertion into cache."); + return angle::Result::Incomplete; + } + + { + std::scoped_lock lock(mHistogramMutex); + ANGLE_HISTOGRAM_COUNTS("GPU.ANGLE.ShaderCache.ShaderBinarySizeBytes", + static_cast(compressedSize)); + } + + return angle::Result::Continue; +} + +void MemoryShaderCache::clear() +{ + mBlobCache.clear(); +} + +size_t MemoryShaderCache::maxSize() const +{ + return mBlobCache.maxSize(); +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/MemoryShaderCache.h b/gfx/angle/checkout/src/libANGLE/MemoryShaderCache.h new file mode 100644 index 0000000000..464201d4c7 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/MemoryShaderCache.h @@ -0,0 +1,60 @@ +// +// Copyright 2022 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// MemoryShaderCache: Stores compiled shaders in memory so they don't +// always have to be re-compiled. Can be used in conjunction with the platform +// layer to warm up the cache from disk. + +#ifndef LIBANGLE_MEMORY_SHADER_CACHE_H_ +#define LIBANGLE_MEMORY_SHADER_CACHE_H_ + +#include + +#include "GLSLANG/ShaderLang.h" +#include "common/MemoryBuffer.h" +#include "libANGLE/BlobCache.h" +#include "libANGLE/Error.h" + +namespace gl +{ +class Context; +class Shader; +class ShaderState; +class ShCompilerInstance; + +class MemoryShaderCache final : angle::NonCopyable +{ + public: + explicit MemoryShaderCache(egl::BlobCache &blobCache); + ~MemoryShaderCache(); + + // Helper method that serializes a shader. + angle::Result putShader(const Context *context, + const egl::BlobCache::Key &shaderHash, + const Shader *shader); + + // Check the cache, and deserialize and load the shader if found. Evict existing hash if load + // fails. + angle::Result getShader(const Context *context, + Shader *shader, + const ShCompileOptions &compileOptions, + const ShCompilerInstance &compilerInstance, + egl::BlobCache::Key *hashOut); + + // Empty the cache. + void clear(); + + // Returns the maximum cache size in bytes. + size_t maxSize() const; + + private: + egl::BlobCache &mBlobCache; + + std::mutex mHistogramMutex; +}; + +} // namespace gl + +#endif // LIBANGLE_MEMORY_SHADER_CACHE_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Observer.cpp b/gfx/angle/checkout/src/libANGLE/Observer.cpp new file mode 100644 index 0000000000..75f51648a4 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Observer.cpp @@ -0,0 +1,113 @@ +// +// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Observer: +// Implements the Observer pattern for sending state change notifications +// from Subject objects to dependent Observer objects. +// +// See design document: +// https://docs.google.com/document/d/15Edfotqg6_l1skTEL8ADQudF_oIdNa7i8Po43k6jMd4/ + +#include "libANGLE/Observer.h" + +#include + +#include "common/debug.h" + +namespace angle +{ +namespace +{} // anonymous namespace + +// Observer implementation. +ObserverInterface::~ObserverInterface() = default; + +// Subject implementation. +Subject::Subject() {} + +Subject::~Subject() +{ + resetObservers(); +} + +bool Subject::hasObservers() const +{ + return !mObservers.empty(); +} + +void Subject::onStateChange(SubjectMessage message) const +{ + if (mObservers.empty()) + return; + + for (const ObserverBindingBase *binding : mObservers) + { + binding->getObserver()->onSubjectStateChange(binding->getSubjectIndex(), message); + } +} + +void Subject::resetObservers() +{ + for (angle::ObserverBindingBase *binding : mObservers) + { + binding->onSubjectReset(); + } + mObservers.clear(); +} + +// ObserverBinding implementation. +ObserverBinding::ObserverBinding() : ObserverBindingBase(nullptr, 0), mSubject(nullptr) {} + +ObserverBinding::ObserverBinding(ObserverInterface *observer, SubjectIndex index) + : ObserverBindingBase(observer, index), mSubject(nullptr) +{ + ASSERT(observer); +} + +ObserverBinding::~ObserverBinding() +{ + reset(); +} + +ObserverBinding::ObserverBinding(const ObserverBinding &other) + : ObserverBindingBase(other), mSubject(nullptr) +{ + bind(other.mSubject); +} + +ObserverBinding &ObserverBinding::operator=(const ObserverBinding &other) +{ + reset(); + ObserverBindingBase::operator=(other); + bind(other.mSubject); + return *this; +} + +void ObserverBinding::bind(Subject *subject) +{ + ASSERT(getObserver() || !subject); + if (mSubject) + { + mSubject->removeObserver(this); + } + + mSubject = subject; + + if (mSubject) + { + mSubject->addObserver(this); + } +} + +void ObserverBinding::onStateChange(SubjectMessage message) const +{ + getObserver()->onSubjectStateChange(getSubjectIndex(), message); +} + +void ObserverBinding::onSubjectReset() +{ + mSubject = nullptr; +} +} // namespace angle diff --git a/gfx/angle/checkout/src/libANGLE/Observer.h b/gfx/angle/checkout/src/libANGLE/Observer.h new file mode 100644 index 0000000000..a07a224b99 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Observer.h @@ -0,0 +1,167 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Observer: +// Implements the Observer pattern for sending state change notifications +// from Subject objects to dependent Observer objects. +// +// See design document: +// https://docs.google.com/document/d/15Edfotqg6_l1skTEL8ADQudF_oIdNa7i8Po43k6jMd4/ + +#ifndef LIBANGLE_OBSERVER_H_ +#define LIBANGLE_OBSERVER_H_ + +#include "common/FastVector.h" +#include "common/angleutils.h" + +namespace angle +{ +template +bool IsInContainer(const HaystackT &haystack, const NeedleT &needle) +{ + return std::find(haystack.begin(), haystack.end(), needle) != haystack.end(); +} + +using SubjectIndex = size_t; + +// Messages are used to distinguish different Subject events that get sent to a single Observer. +// It could be possible to improve the handling by using different callback functions instead +// of a single handler function. But in some cases we want to share a single binding between +// Observer and Subject and handle different types of events. +enum class SubjectMessage +{ + // Used by gl::VertexArray to notify gl::Context of a gl::Buffer binding count change. Triggers + // a validation cache update. Also used by gl::Texture to notify gl::Framebuffer of loops. + BindingChanged, + + // Only the contents (pixels, bytes, etc) changed in this Subject. Distinct from the object + // storage. + ContentsChanged, + + // Sent by gl::Sampler, gl::Texture, gl::Framebuffer and others to notifiy gl::Context. This + // flag indicates to call syncState before next use. + DirtyBitsFlagged, + + // Generic state change message. Used in multiple places for different purposes. + SubjectChanged, + + // Indicates a bound gl::Buffer is now mapped or unmapped. Passed from gl::Buffer, through + // gl::VertexArray, into gl::Context. Used to track validation. + SubjectMapped, + SubjectUnmapped, + // Indicates a bound buffer's storage was reallocated due to glBufferData call or optimizations + // to prevent having to flush pending commands and waiting for the GPU to become idle. + InternalMemoryAllocationChanged, + + // Indicates an external change to the default framebuffer. + SurfaceChanged, + // Indicates the system framebuffer's swapchain changed, i.e. color buffer changed but no + // depth/stencil buffer change. + SwapchainImageChanged, + + // Indicates a separable program's textures or images changed in the ProgramExecutable. + ProgramTextureOrImageBindingChanged, + // Indicates a separable program was successfully re-linked. + ProgramRelinked, + // Indicates a separable program's sampler uniforms were updated. + SamplerUniformsUpdated, + // Other types of uniform change. + ProgramUniformUpdated, + + // Indicates a Storage of back-end in gl::Texture has been released. + StorageReleased, + + // Indicates that all pending updates are complete in the subject. + InitializationComplete, +}; + +// The observing class inherits from this interface class. +class ObserverInterface +{ + public: + virtual ~ObserverInterface(); + virtual void onSubjectStateChange(SubjectIndex index, SubjectMessage message) = 0; +}; + +class ObserverBindingBase +{ + public: + ObserverBindingBase(ObserverInterface *observer, SubjectIndex subjectIndex) + : mObserver(observer), mIndex(subjectIndex) + {} + virtual ~ObserverBindingBase() {} + + ObserverBindingBase(const ObserverBindingBase &other) = default; + ObserverBindingBase &operator=(const ObserverBindingBase &other) = default; + + ObserverInterface *getObserver() const { return mObserver; } + SubjectIndex getSubjectIndex() const { return mIndex; } + + virtual void onSubjectReset() {} + + private: + ObserverInterface *mObserver; + SubjectIndex mIndex; +}; + +constexpr size_t kMaxFixedObservers = 8; + +// Maintains a list of observer bindings. Sends update messages to the observer. +class Subject : NonCopyable +{ + public: + Subject(); + virtual ~Subject(); + + void onStateChange(SubjectMessage message) const; + bool hasObservers() const; + void resetObservers(); + ANGLE_INLINE size_t getObserversCount() const { return mObservers.size(); } + + ANGLE_INLINE void addObserver(ObserverBindingBase *observer) + { + ASSERT(!IsInContainer(mObservers, observer)); + mObservers.push_back(observer); + } + ANGLE_INLINE void removeObserver(ObserverBindingBase *observer) + { + ASSERT(IsInContainer(mObservers, observer)); + mObservers.remove_and_permute(observer); + } + + private: + // Keep a short list of observers so we can allocate/free them quickly. But since we support + // unlimited bindings, have a spill-over list of that uses dynamic allocation. + angle::FastVector mObservers; +}; + +// Keeps a binding between a Subject and Observer, with a specific subject index. +class ObserverBinding final : public ObserverBindingBase +{ + public: + ObserverBinding(); + ObserverBinding(ObserverInterface *observer, SubjectIndex index); + ~ObserverBinding() override; + ObserverBinding(const ObserverBinding &other); + ObserverBinding &operator=(const ObserverBinding &other); + + void bind(Subject *subject); + + ANGLE_INLINE void reset() { bind(nullptr); } + + void onStateChange(SubjectMessage message) const; + void onSubjectReset() override; + + ANGLE_INLINE const Subject *getSubject() const { return mSubject; } + + ANGLE_INLINE void assignSubject(Subject *subject) { mSubject = subject; } + + private: + Subject *mSubject; +}; + +} // namespace angle + +#endif // LIBANGLE_OBSERVER_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Overlay.cpp b/gfx/angle/checkout/src/libANGLE/Overlay.cpp new file mode 100644 index 0000000000..e84b125361 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Overlay.cpp @@ -0,0 +1,103 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Overlay.cpp: +// Implements the Overlay class. +// + +#include "libANGLE/Overlay.h" + +#include "common/string_utils.h" +#include "common/system_utils.h" +#include "libANGLE/Context.h" +#include "libANGLE/Overlay_font_autogen.h" +#include "libANGLE/renderer/GLImplFactory.h" +#include "libANGLE/renderer/OverlayImpl.h" + +#include + +namespace gl +{ +namespace +{ +#define ANGLE_WIDGET_NAME_PROC(WIDGET_ID) {ANGLE_STRINGIFY(WIDGET_ID), WidgetId::WIDGET_ID}, + +constexpr std::pair kWidgetNames[] = { + ANGLE_WIDGET_ID_X(ANGLE_WIDGET_NAME_PROC)}; +} // namespace + +OverlayState::OverlayState() : mEnabledWidgetCount(0), mOverlayWidgets{} {} +OverlayState::~OverlayState() = default; + +Overlay::Overlay(rx::GLImplFactory *factory) + : mLastPerSecondUpdate(0), mImplementation(factory->createOverlay(mState)) +{} +Overlay::~Overlay() = default; + +void Overlay::init() +{ + initOverlayWidgets(); + mLastPerSecondUpdate = angle::GetCurrentSystemTime(); + + ASSERT(std::all_of( + mState.mOverlayWidgets.begin(), mState.mOverlayWidgets.end(), + [](const std::unique_ptr &widget) { return widget.get() != nullptr; })); + + enableOverlayWidgetsFromEnvironment(); +} + +void Overlay::destroy(const gl::Context *context) +{ + ASSERT(mImplementation); + mImplementation->onDestroy(context); +} + +void Overlay::enableOverlayWidgetsFromEnvironment() +{ + std::vector enabledWidgets = angle::GetStringsFromEnvironmentVarOrAndroidProperty( + "ANGLE_OVERLAY", "debug.angle.overlay", ":"); + + for (const std::pair &widgetName : kWidgetNames) + { + for (const std::string &enabledWidget : enabledWidgets) + { + if (angle::NamesMatchWithWildcard(enabledWidget.c_str(), widgetName.first)) + { + mState.mOverlayWidgets[widgetName.second]->enabled = true; + ++mState.mEnabledWidgetCount; + break; + } + } + } +} + +void Overlay::onSwap() const +{ + // Increment FPS counter. + getPerSecondWidget(WidgetId::FPS)->add(1); + + // Update per second values every second. + double currentTime = angle::GetCurrentSystemTime(); + double timeDiff = currentTime - mLastPerSecondUpdate; + if (timeDiff >= 1.0) + { + for (const std::unique_ptr &widget : mState.mOverlayWidgets) + { + if (widget->type == WidgetType::PerSecond) + { + overlay::PerSecond *perSecond = + reinterpret_cast(widget.get()); + perSecond->lastPerSecondCount = static_cast(perSecond->count / timeDiff); + perSecond->count = 0; + } + } + mLastPerSecondUpdate += 1.0; + } +} + +MockOverlay::MockOverlay(rx::GLImplFactory *implFactory) {} +MockOverlay::~MockOverlay() = default; + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/Overlay.h b/gfx/angle/checkout/src/libANGLE/Overlay.h new file mode 100644 index 0000000000..124e00d3e6 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Overlay.h @@ -0,0 +1,154 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Overlay.h: +// Defines the Overlay class that handles overlay widgets. +// + +#ifndef LIBANGLE_OVERLAY_H_ +#define LIBANGLE_OVERLAY_H_ + +#include "common/PackedEnums.h" +#include "common/angleutils.h" +#include "libANGLE/Error.h" +#include "libANGLE/OverlayWidgets.h" +#include "libANGLE/angletypes.h" + +namespace rx +{ +class OverlayImpl; +class GLImplFactory; +} // namespace rx + +namespace gl +{ +class Context; + +class OverlayState : angle::NonCopyable +{ + public: + OverlayState(); + ~OverlayState(); + + size_t getWidgetCoordinatesBufferSize() const; + size_t getTextWidgetsBufferSize() const; + size_t getGraphWidgetsBufferSize() const; + + const uint8_t *getFontData() const; + void fillWidgetData(const gl::Extents &imageExtents, + uint8_t *textData, + uint8_t *graphData, + uint32_t *activeTextWidgetCountOut, + uint32_t *activeGraphWidgetCountOut) const; + + uint32_t getEnabledWidgetCount() const { return mEnabledWidgetCount; } + + private: + friend class Overlay; + + uint32_t mEnabledWidgetCount; + + angle::PackedEnumMap> mOverlayWidgets; +}; + +class Overlay : angle::NonCopyable +{ + public: + Overlay(rx::GLImplFactory *implFactory); + ~Overlay(); + + void init(); + void destroy(const gl::Context *context); + + void onSwap() const; + + overlay::Text *getTextWidget(WidgetId id) const + { + return getWidgetAs(id); + } + overlay::Count *getCountWidget(WidgetId id) const + { + return getWidgetAs(id); + } + overlay::PerSecond *getPerSecondWidget(WidgetId id) const + { + return getWidgetAs(id); + } + overlay::RunningGraph *getRunningGraphWidget(WidgetId id) const + { + return getWidgetAs(id); + } + overlay::RunningHistogram *getRunningHistogramWidget(WidgetId id) const + { + return getWidgetAs(id); + } + + rx::OverlayImpl *getImplementation() const { return mImplementation.get(); } + + bool isEnabled() const + { + return mImplementation != nullptr && mState.getEnabledWidgetCount() > 0; + } + + private: + template + Widget *getWidgetAs(WidgetId id) const + { + ASSERT(mState.mOverlayWidgets[id] != nullptr); + ASSERT(mState.mOverlayWidgets[id]->type == Type); + return rx::GetAs(mState.mOverlayWidgets[id].get()); + } + void initOverlayWidgets(); + void enableOverlayWidgetsFromEnvironment(); + + // Time tracking for PerSecond items. + mutable double mLastPerSecondUpdate; + + OverlayState mState; + std::unique_ptr mImplementation; +}; + +class MockOverlay +{ + public: + MockOverlay(rx::GLImplFactory *implFactory); + ~MockOverlay(); + + void init() {} + void destroy(const Context *context) {} + + void onSwap() const {} + + const overlay::Mock *getTextWidget(WidgetId id) const { return &mMock; } + const overlay::Mock *getCountWidget(WidgetId id) const { return &mMock; } + const overlay::Mock *getPerSecondWidget(WidgetId id) const { return &mMock; } + const overlay::Mock *getRunningGraphWidget(WidgetId id) const { return &mMock; } + const overlay::Mock *getRunningHistogramWidget(WidgetId id) const { return &mMock; } + + bool isEnabled() const { return false; } + + private: + overlay::Mock mMock; +}; + +#if ANGLE_ENABLE_OVERLAY +using OverlayType = Overlay; +using CountWidget = overlay::Count; +using PerSecondWidget = overlay::PerSecond; +using RunningGraphWidget = overlay::RunningGraph; +using RunningHistogramWidget = overlay::RunningHistogram; +using TextWidget = overlay::Text; +#else // !ANGLE_ENABLE_OVERLAY +using OverlayType = MockOverlay; +using CountWidget = const overlay::Mock; +using PerSecondWidget = const overlay::Mock; +using RunningGraphWidget = const overlay::Mock; +using RunningHistogramWidget = const overlay::Mock; +using TextWidget = const overlay::Mock; +#endif // ANGLE_ENABLE_OVERLAY + +} // namespace gl + +#endif // LIBANGLE_OVERLAY_H_ diff --git a/gfx/angle/checkout/src/libANGLE/OverlayWidgets.cpp b/gfx/angle/checkout/src/libANGLE/OverlayWidgets.cpp new file mode 100644 index 0000000000..f0581ce9d8 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/OverlayWidgets.cpp @@ -0,0 +1,737 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// OverlayWidgets.cpp: +// Implements functions that interpret widget data. Data formats and limits correspond to the +// Vulkan implementation (as the only implementation). They are generic enough so other backends +// could respect them too, if they implement the overlay. +// + +#include "libANGLE/Overlay.h" +#include "libANGLE/Overlay_font_autogen.h" + +#include + +namespace gl +{ +namespace +{ +// Internally, every widget is either Text or Graph. +enum class WidgetInternalType +{ + Text, + Graph, + + InvalidEnum, + EnumCount = InvalidEnum, +}; + +// A map that says how the API-facing widget types map to internal types. +constexpr angle::PackedEnumMap kWidgetTypeToInternalMap = { + {WidgetType::Count, WidgetInternalType::Text}, + {WidgetType::Text, WidgetInternalType::Text}, + {WidgetType::PerSecond, WidgetInternalType::Text}, + {WidgetType::RunningGraph, WidgetInternalType::Graph}, + {WidgetType::RunningHistogram, WidgetInternalType::Graph}, +}; + +// Structures and limits matching uniform buffers in vulkan/shaders/src/OverlayDraw.comp. The size +// of text and graph widgets is chosen such that they could fit in uniform buffers with minimum +// required Vulkan size. +constexpr size_t kMaxRenderableTextWidgets = 32; +constexpr size_t kMaxRenderableGraphWidgets = 32; +constexpr size_t kMaxTextLength = 256; +constexpr size_t kMaxGraphDataSize = 256; + +constexpr angle::PackedEnumMap kWidgetInternalTypeMaxWidgets = { + {WidgetInternalType::Text, kMaxRenderableTextWidgets}, + {WidgetInternalType::Graph, kMaxRenderableGraphWidgets}, +}; + +ANGLE_ENABLE_STRUCT_PADDING_WARNINGS + +// Structure matching buffer in vulkan/shaders/src/OverlayCull.comp. +struct WidgetCoordinates +{ + uint32_t coordinates[kMaxRenderableTextWidgets + kMaxRenderableGraphWidgets][4]; +}; + +// Structures matching buffers in vulkan/shaders/src/OverlayDraw.comp. +struct TextWidgetData +{ + uint32_t coordinates[4]; + float color[4]; + uint32_t fontSize[3]; + uint32_t padding; + uint8_t text[kMaxTextLength]; +}; + +struct GraphWidgetData +{ + uint32_t coordinates[4]; + float color[4]; + uint32_t valueWidth; + uint32_t padding[3]; + uint32_t values[kMaxGraphDataSize]; +}; + +struct TextWidgets +{ + TextWidgetData widgets[kMaxRenderableTextWidgets]; +}; + +struct GraphWidgets +{ + GraphWidgetData widgets[kMaxRenderableGraphWidgets]; +}; + +ANGLE_DISABLE_STRUCT_PADDING_WARNINGS + +uint32_t GetWidgetCoord(int32_t src, uint32_t extent) +{ + int32_t dst = src < 0 ? extent + src : src; + + return std::min(std::max(dst, 0), extent - 1); +} + +void GetWidgetCoordinates(const int32_t srcCoords[4], + const gl::Extents &imageExtent, + uint32_t dstCoordsOut[4]) +{ + dstCoordsOut[0] = GetWidgetCoord(srcCoords[0], imageExtent.width); + dstCoordsOut[1] = GetWidgetCoord(srcCoords[1], imageExtent.height); + dstCoordsOut[2] = GetWidgetCoord(srcCoords[2], imageExtent.width); + dstCoordsOut[3] = GetWidgetCoord(srcCoords[3], imageExtent.height); +} + +void GetWidgetColor(const float srcColor[4], float dstColor[4]) +{ + memcpy(dstColor, srcColor, 4 * sizeof(dstColor[0])); +} + +void GetTextFontSize(int srcFontSize, uint32_t dstFontSize[3]) +{ + // .xy contains the font glyph width/height + dstFontSize[0] = overlay::kFontGlyphWidth >> srcFontSize; + dstFontSize[1] = overlay::kFontGlyphHeight >> srcFontSize; + // .z contains the mip + dstFontSize[2] = srcFontSize; +} + +void GetGraphValueWidth(const int32_t srcCoords[4], size_t valueCount, uint32_t *dstValueWidth) +{ + const int32_t graphWidth = std::abs(srcCoords[2] - srcCoords[0]); + + // If valueCount doesn't divide graphWidth, the graph bars won't fit well in its frame. + // Fix initOverlayWidgets() in that case. + ASSERT(graphWidth % valueCount == 0); + + *dstValueWidth = graphWidth / valueCount; +} + +void GetTextString(const std::string &src, uint8_t textOut[kMaxTextLength]) +{ + for (size_t i = 0; i < src.length() && i < kMaxTextLength; ++i) + { + // The font image has 95 ASCII characters starting from ' '. + textOut[i] = src[i] - ' '; + } +} + +void GetGraphValues(const std::vector srcValues, + size_t startIndex, + float scale, + uint32_t valuesOut[kMaxGraphDataSize]) +{ + ASSERT(srcValues.size() <= kMaxGraphDataSize); + + for (size_t i = 0; i < srcValues.size(); ++i) + { + size_t index = (startIndex + i) % srcValues.size(); + valuesOut[i] = static_cast(srcValues[index] * scale); + } +} + +std::vector CreateHistogram(const std::vector values) +{ + std::vector histogram(values.size(), 0); + + for (uint64_t rank : values) + { + ++histogram[static_cast(rank)]; + } + + return histogram; +} + +using OverlayWidgetCounts = angle::PackedEnumMap; +using AppendWidgetDataFunc = void (*)(const overlay::Widget *widget, + const gl::Extents &imageExtent, + TextWidgetData *textWidget, + GraphWidgetData *graphWidget, + OverlayWidgetCounts *widgetCounts); +} // namespace + +namespace overlay_impl +{ +#define ANGLE_DECLARE_APPEND_WIDGET_PROC(WIDGET_ID) \ + static void Append##WIDGET_ID(const overlay::Widget *widget, const gl::Extents &imageExtent, \ + TextWidgetData *textWidget, GraphWidgetData *graphWidget, \ + OverlayWidgetCounts *widgetCounts); + +// This class interprets the generic data collected in every element into a human-understandable +// widget. This often means generating text specific to this item and scaling graph data to +// something sensible. +class AppendWidgetDataHelper +{ + public: + ANGLE_WIDGET_ID_X(ANGLE_DECLARE_APPEND_WIDGET_PROC) + + private: + static std::ostream &OutputPerSecond(std::ostream &out, const overlay::PerSecond *perSecond); + + static std::ostream &OutputText(std::ostream &out, const overlay::Text *text); + + static std::ostream &OutputCount(std::ostream &out, const overlay::Count *count); + + static void AppendTextCommon(const overlay::Widget *widget, + const gl::Extents &imageExtent, + const std::string &text, + TextWidgetData *textWidget, + OverlayWidgetCounts *widgetCounts); + + using FormatGraphTitleFunc = std::function; + static void AppendRunningGraphCommon(const overlay::Widget *widget, + const gl::Extents &imageExtent, + TextWidgetData *textWidget, + GraphWidgetData *graphWidget, + OverlayWidgetCounts *widgetCounts, + FormatGraphTitleFunc formatFunc); + + using FormatHistogramTitleFunc = + std::function; + static void AppendRunningHistogramCommon(const overlay::Widget *widget, + const gl::Extents &imageExtent, + TextWidgetData *textWidget, + GraphWidgetData *graphWidget, + OverlayWidgetCounts *widgetCounts, + FormatHistogramTitleFunc formatFunc); + + static void AppendGraphCommon(const overlay::Widget *widget, + const gl::Extents &imageExtent, + const std::vector runningValues, + size_t startIndex, + float scale, + GraphWidgetData *graphWidget, + OverlayWidgetCounts *widgetCounts); +}; + +void AppendWidgetDataHelper::AppendTextCommon(const overlay::Widget *widget, + const gl::Extents &imageExtent, + const std::string &text, + TextWidgetData *textWidget, + OverlayWidgetCounts *widgetCounts) +{ + GetWidgetCoordinates(widget->coords, imageExtent, textWidget->coordinates); + GetWidgetColor(widget->color, textWidget->color); + GetTextFontSize(widget->fontSize, textWidget->fontSize); + GetTextString(text, textWidget->text); + + ++(*widgetCounts)[WidgetInternalType::Text]; +} + +void AppendWidgetDataHelper::AppendGraphCommon(const overlay::Widget *widget, + const gl::Extents &imageExtent, + const std::vector runningValues, + size_t startIndex, + float scale, + GraphWidgetData *graphWidget, + OverlayWidgetCounts *widgetCounts) +{ + const overlay::RunningGraph *widgetAsGraph = static_cast(widget); + + GetWidgetCoordinates(widget->coords, imageExtent, graphWidget->coordinates); + GetWidgetColor(widget->color, graphWidget->color); + GetGraphValueWidth(widget->coords, widgetAsGraph->runningValues.size(), + &graphWidget->valueWidth); + GetGraphValues(runningValues, startIndex, scale, graphWidget->values); + + ++(*widgetCounts)[WidgetInternalType::Graph]; +} + +void AppendWidgetDataHelper::AppendRunningGraphCommon( + const overlay::Widget *widget, + const gl::Extents &imageExtent, + TextWidgetData *textWidget, + GraphWidgetData *graphWidget, + OverlayWidgetCounts *widgetCounts, + AppendWidgetDataHelper::FormatGraphTitleFunc formatFunc) +{ + const overlay::RunningGraph *graph = static_cast(widget); + const overlay::Widget *matchToWidget = widget->matchToWidget; + + if (matchToWidget == nullptr) + { + matchToWidget = widget; + } + const overlay::RunningGraph *matchToGraph = + static_cast(matchToWidget); + + const uint64_t maxValue = + *std::max_element(graph->runningValues.begin(), graph->runningValues.end()); + const uint64_t maxValueInMatchToGraph = + *std::max_element(matchToGraph->runningValues.begin(), matchToGraph->runningValues.end()); + const int32_t graphHeight = std::abs(widget->coords[3] - widget->coords[1]); + const float graphScale = static_cast(graphHeight) / maxValueInMatchToGraph; + + const size_t graphSize = graph->runningValues.size(); + const size_t currentIdx = graph->lastValueIndex - 1; + + const uint64_t curValue = graph->runningValues[(graphSize + currentIdx) % graphSize]; + + AppendGraphCommon(widget, imageExtent, graph->runningValues, graph->lastValueIndex + 1, + graphScale, graphWidget, widgetCounts); + + if ((*widgetCounts)[WidgetInternalType::Text] < + kWidgetInternalTypeMaxWidgets[WidgetInternalType::Text]) + { + std::string text = formatFunc(curValue, maxValue); + AppendTextCommon(&graph->description, imageExtent, text, textWidget, widgetCounts); + } +} + +// static +void AppendWidgetDataHelper::AppendRunningHistogramCommon(const overlay::Widget *widget, + const gl::Extents &imageExtent, + TextWidgetData *textWidget, + GraphWidgetData *graphWidget, + OverlayWidgetCounts *widgetCounts, + FormatHistogramTitleFunc formatFunc) +{ + const overlay::RunningHistogram *runningHistogram = + static_cast(widget); + + std::vector histogram = CreateHistogram(runningHistogram->runningValues); + auto peakRangeIt = std::max_element(histogram.rbegin(), histogram.rend()); + const uint64_t peakRangeValue = *peakRangeIt; + const int32_t graphHeight = std::abs(widget->coords[3] - widget->coords[1]); + const float graphScale = static_cast(graphHeight) / peakRangeValue; + auto maxValueIter = std::find_if(histogram.rbegin(), histogram.rend(), + [](uint64_t value) { return value != 0; }); + + AppendGraphCommon(widget, imageExtent, histogram, 0, graphScale, graphWidget, widgetCounts); + + if ((*widgetCounts)[WidgetInternalType::Text] < + kWidgetInternalTypeMaxWidgets[WidgetInternalType::Text]) + { + size_t peakRange = std::distance(peakRangeIt, histogram.rend() - 1); + size_t maxValueRange = std::distance(maxValueIter, histogram.rend() - 1); + + std::string text = formatFunc(peakRange, maxValueRange, histogram.size()); + AppendTextCommon(&runningHistogram->description, imageExtent, text, textWidget, + widgetCounts); + } +} + +void AppendWidgetDataHelper::AppendFPS(const overlay::Widget *widget, + const gl::Extents &imageExtent, + TextWidgetData *textWidget, + GraphWidgetData *graphWidget, + OverlayWidgetCounts *widgetCounts) +{ + const overlay::PerSecond *fps = static_cast(widget); + std::ostringstream text; + text << "FPS: "; + OutputPerSecond(text, fps); + + AppendTextCommon(widget, imageExtent, text.str(), textWidget, widgetCounts); +} + +void AppendWidgetDataHelper::AppendVulkanLastValidationMessage(const overlay::Widget *widget, + const gl::Extents &imageExtent, + TextWidgetData *textWidget, + GraphWidgetData *graphWidget, + OverlayWidgetCounts *widgetCounts) +{ + const overlay::Text *lastValidationMessage = static_cast(widget); + std::ostringstream text; + text << "Last VVL Message: "; + OutputText(text, lastValidationMessage); + + AppendTextCommon(widget, imageExtent, text.str(), textWidget, widgetCounts); +} + +void AppendWidgetDataHelper::AppendVulkanValidationMessageCount(const overlay::Widget *widget, + const gl::Extents &imageExtent, + TextWidgetData *textWidget, + GraphWidgetData *graphWidget, + OverlayWidgetCounts *widgetCounts) +{ + const overlay::Count *validationMessageCount = static_cast(widget); + std::ostringstream text; + text << "VVL Message Count: "; + OutputCount(text, validationMessageCount); + + AppendTextCommon(widget, imageExtent, text.str(), textWidget, widgetCounts); +} + +void AppendWidgetDataHelper::AppendVulkanRenderPassCount(const overlay::Widget *widget, + const gl::Extents &imageExtent, + TextWidgetData *textWidget, + GraphWidgetData *graphWidget, + OverlayWidgetCounts *widgetCounts) +{ + auto format = [](uint64_t curValue, uint64_t maxValue) { + std::ostringstream text; + text << "RenderPass Count: " << maxValue; + return text.str(); + }; + + AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format); +} + +void AppendWidgetDataHelper::AppendVulkanSecondaryCommandBufferPoolWaste( + const overlay::Widget *widget, + const gl::Extents &imageExtent, + TextWidgetData *textWidget, + GraphWidgetData *graphWidget, + OverlayWidgetCounts *widgetCounts) +{ + auto format = [](size_t peakRange, size_t maxValueRange, size_t numRanges) { + std::ostringstream text; + size_t peakPercent = (peakRange * 100 + 50) / numRanges; + text << "CB Pool Waste (Peak: " << peakPercent << "%)"; + return text.str(); + }; + + AppendRunningHistogramCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, + format); +} + +void AppendWidgetDataHelper::AppendVulkanRenderPassBufferCount(const overlay::Widget *widget, + const gl::Extents &imageExtent, + TextWidgetData *textWidget, + GraphWidgetData *graphWidget, + OverlayWidgetCounts *widgetCounts) +{ + auto format = [](uint64_t curValue, uint64_t maxValue) { + std::ostringstream text; + text << "RP VkBuffers (Max: " << maxValue << ")"; + return text.str(); + }; + + AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format); +} + +void AppendWidgetDataHelper::AppendVulkanWriteDescriptorSetCount(const overlay::Widget *widget, + const gl::Extents &imageExtent, + TextWidgetData *textWidget, + GraphWidgetData *graphWidget, + OverlayWidgetCounts *widgetCounts) +{ + auto format = [](uint64_t curValue, uint64_t maxValue) { + std::ostringstream text; + text << "WriteDescriptorSet Count: " << maxValue; + return text.str(); + }; + + AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format); +} + +void AppendWidgetDataHelper::AppendVulkanDescriptorSetAllocations(const overlay::Widget *widget, + const gl::Extents &imageExtent, + TextWidgetData *textWidget, + GraphWidgetData *graphWidget, + OverlayWidgetCounts *widgetCounts) +{ + auto format = [](uint64_t curValue, uint64_t maxValue) { + std::ostringstream text; + text << "Descriptor Set Allocations: " << maxValue; + return text.str(); + }; + + AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format); +} + +void AppendWidgetDataHelper::AppendVulkanShaderResourceDSHitRate(const overlay::Widget *widget, + const gl::Extents &imageExtent, + TextWidgetData *textWidget, + GraphWidgetData *graphWidget, + OverlayWidgetCounts *widgetCounts) +{ + auto format = [](uint64_t curValue, uint64_t maxValue) { + std::ostringstream text; + text << "Shader Resource DS Hit Rate (Max: " << maxValue << "%)"; + return text.str(); + }; + + AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format); +} + +void AppendWidgetDataHelper::AppendVulkanDynamicBufferAllocations(const overlay::Widget *widget, + const gl::Extents &imageExtent, + TextWidgetData *textWidget, + GraphWidgetData *graphWidget, + OverlayWidgetCounts *widgetCounts) +{ + auto format = [](uint64_t curValue, uint64_t maxValue) { + std::ostringstream text; + text << "DynamicBuffer Allocations (Max: " << maxValue << ")"; + return text.str(); + }; + + AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format); +} + +void AppendWidgetDataHelper::AppendVulkanTextureDescriptorCacheSize( + const overlay::Widget *widget, + const gl::Extents &imageExtent, + TextWidgetData *textWidget, + GraphWidgetData *graphWidget, + OverlayWidgetCounts *widgetCounts) +{ + auto format = [](uint64_t curValue, uint64_t maxValue) { + std::ostringstream text; + text << "Total Texture Descriptor Cache Size: " << curValue; + return text.str(); + }; + + AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format); +} + +void AppendWidgetDataHelper::AppendVulkanUniformDescriptorCacheSize( + const overlay::Widget *widget, + const gl::Extents &imageExtent, + TextWidgetData *textWidget, + GraphWidgetData *graphWidget, + OverlayWidgetCounts *widgetCounts) +{ + auto format = [](uint64_t curValue, uint64_t maxValue) { + std::ostringstream text; + text << "Total Uniform Descriptor Cache Size: " << curValue; + return text.str(); + }; + + AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format); +} + +void AppendWidgetDataHelper::AppendVulkanDescriptorCacheSize(const overlay::Widget *widget, + const gl::Extents &imageExtent, + TextWidgetData *textWidget, + GraphWidgetData *graphWidget, + OverlayWidgetCounts *widgetCounts) +{ + auto format = [](uint64_t curValue, uint64_t maxValue) { + std::ostringstream text; + text << "Total Descriptor Cache Size: " << curValue; + return text.str(); + }; + + AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format); +} + +void AppendWidgetDataHelper::AppendVulkanDescriptorCacheKeySize(const overlay::Widget *widget, + const gl::Extents &imageExtent, + TextWidgetData *textWidget, + GraphWidgetData *graphWidget, + OverlayWidgetCounts *widgetCounts) +{ + const overlay::Count *countWidget = static_cast(widget); + std::ostringstream text; + double kb = static_cast(countWidget->count) / 1000.0; + text << "DS Cache Key Size: " << std::fixed << std::setprecision(1) << kb << " kb"; + + AppendTextCommon(widget, imageExtent, text.str(), textWidget, widgetCounts); +} + +void AppendWidgetDataHelper::AppendVulkanAttemptedSubmissions(const overlay::Widget *widget, + const gl::Extents &imageExtent, + TextWidgetData *textWidget, + GraphWidgetData *graphWidget, + OverlayWidgetCounts *widgetCounts) +{ + auto format = [](uint64_t curValue, uint64_t maxValue) { + std::ostringstream text; + text << "Attempted submissions (peak): " << maxValue; + return text.str(); + }; + + AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format); +} + +void AppendWidgetDataHelper::AppendVulkanActualSubmissions(const overlay::Widget *widget, + const gl::Extents &imageExtent, + TextWidgetData *textWidget, + GraphWidgetData *graphWidget, + OverlayWidgetCounts *widgetCounts) +{ + auto format = [](uint64_t curValue, uint64_t maxValue) { + std::ostringstream text; + text << "Actual submissions (peak): " << maxValue; + return text.str(); + }; + + AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format); +} + +void AppendWidgetDataHelper::AppendVulkanPipelineCacheLookups(const overlay::Widget *widget, + const gl::Extents &imageExtent, + TextWidgetData *textWidget, + GraphWidgetData *graphWidget, + OverlayWidgetCounts *widgetCounts) +{ + auto format = [](uint64_t curValue, uint64_t maxValue) { + std::ostringstream text; + text << "Pipeline Cache Lookups (peak): " << maxValue; + return text.str(); + }; + + AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format); +} + +void AppendWidgetDataHelper::AppendVulkanPipelineCacheMisses(const overlay::Widget *widget, + const gl::Extents &imageExtent, + TextWidgetData *textWidget, + GraphWidgetData *graphWidget, + OverlayWidgetCounts *widgetCounts) +{ + auto format = [](uint64_t curValue, uint64_t maxValue) { + std::ostringstream text; + text << "Pipeline Cache Misses (peak): " << maxValue; + return text.str(); + }; + + AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format); +} + +void AppendWidgetDataHelper::AppendVulkanTotalPipelineCacheHitTimeMs( + const overlay::Widget *widget, + const gl::Extents &imageExtent, + TextWidgetData *textWidget, + GraphWidgetData *graphWidget, + OverlayWidgetCounts *widgetCounts) +{ + const overlay::Count *totalTime = static_cast(widget); + std::ostringstream text; + text << "Total Pipeline Cache Hit Time: "; + OutputCount(text, totalTime); + text << "ms"; + + AppendTextCommon(widget, imageExtent, text.str(), textWidget, widgetCounts); +} + +void AppendWidgetDataHelper::AppendVulkanTotalPipelineCacheMissTimeMs( + const overlay::Widget *widget, + const gl::Extents &imageExtent, + TextWidgetData *textWidget, + GraphWidgetData *graphWidget, + OverlayWidgetCounts *widgetCounts) +{ + const overlay::Count *totalTime = static_cast(widget); + std::ostringstream text; + text << "Total Pipeline Cache Miss Time: "; + OutputCount(text, totalTime); + text << "ms"; + + AppendTextCommon(widget, imageExtent, text.str(), textWidget, widgetCounts); +} + +std::ostream &AppendWidgetDataHelper::OutputPerSecond(std::ostream &out, + const overlay::PerSecond *perSecond) +{ + return out << perSecond->lastPerSecondCount; +} + +std::ostream &AppendWidgetDataHelper::OutputText(std::ostream &out, const overlay::Text *text) +{ + return out << text->text; +} + +std::ostream &AppendWidgetDataHelper::OutputCount(std::ostream &out, const overlay::Count *count) +{ + return out << count->count; +} +} // namespace overlay_impl + +namespace +{ +#define ANGLE_APPEND_WIDGET_MAP_PROC(WIDGET_ID) \ + {WidgetId::WIDGET_ID, overlay_impl::AppendWidgetDataHelper::Append##WIDGET_ID}, + +constexpr angle::PackedEnumMap kWidgetIdToAppendDataFuncMap = { + ANGLE_WIDGET_ID_X(ANGLE_APPEND_WIDGET_MAP_PROC)}; +} // namespace + +namespace overlay +{ +const Text *Widget::getDescriptionWidget() const +{ + return nullptr; +} +RunningGraph::RunningGraph(size_t n) : runningValues(n, 0) {} +RunningGraph::~RunningGraph() = default; +const Text *RunningGraph::getDescriptionWidget() const +{ + return &description; +} +} // namespace overlay + +size_t OverlayState::getWidgetCoordinatesBufferSize() const +{ + return sizeof(WidgetCoordinates); +} + +size_t OverlayState::getTextWidgetsBufferSize() const +{ + return sizeof(TextWidgets); +} + +size_t OverlayState::getGraphWidgetsBufferSize() const +{ + return sizeof(GraphWidgets); +} + +void OverlayState::fillWidgetData(const gl::Extents &imageExtents, + uint8_t *textData, + uint8_t *graphData, + uint32_t *activeTextWidgetCountOut, + uint32_t *activeGraphWidgetCountOut) const +{ + TextWidgets *textWidgets = reinterpret_cast(textData); + GraphWidgets *graphWidgets = reinterpret_cast(graphData); + + memset(textWidgets, overlay::kFontCharacters, sizeof(*textWidgets)); + memset(graphWidgets, 0, sizeof(*graphWidgets)); + + OverlayWidgetCounts widgetCounts = {}; + + for (WidgetId id : angle::AllEnums()) + { + const std::unique_ptr &widget = mOverlayWidgets[id]; + if (!widget->enabled) + { + continue; + } + + WidgetInternalType internalType = kWidgetTypeToInternalMap[widget->type]; + ASSERT(internalType != WidgetInternalType::InvalidEnum); + + if (widgetCounts[internalType] >= kWidgetInternalTypeMaxWidgets[internalType]) + { + continue; + } + + AppendWidgetDataFunc appendFunc = kWidgetIdToAppendDataFuncMap[id]; + ASSERT(appendFunc); + appendFunc(widget.get(), imageExtents, + &textWidgets->widgets[widgetCounts[WidgetInternalType::Text]], + &graphWidgets->widgets[widgetCounts[WidgetInternalType::Graph]], &widgetCounts); + } + + *activeTextWidgetCountOut = widgetCounts[WidgetInternalType::Text]; + *activeGraphWidgetCountOut = widgetCounts[WidgetInternalType::Graph]; +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/OverlayWidgets.h b/gfx/angle/checkout/src/libANGLE/OverlayWidgets.h new file mode 100644 index 0000000000..b8a5f01e52 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/OverlayWidgets.h @@ -0,0 +1,201 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// OverlayWidgets.h: +// Defines the Overlay* widget classes and corresponding enums. +// + +#ifndef LIBANGLE_OVERLAYWIDGETS_H_ +#define LIBANGLE_OVERLAYWIDGETS_H_ + +#include "common/angleutils.h" +#include "libANGLE/Overlay_autogen.h" + +namespace gl +{ +class Overlay; +class OverlayState; + +namespace overlay_impl +{ +class AppendWidgetDataHelper; +} // namespace overlay_impl + +enum class WidgetType +{ + // Text types: + + // A total count of some event. + Count, + // A single line of ASCII text. Retains content until changed. + Text, + // A per-second value. + PerSecond, + + // Graph types: + + // A graph of the last N values. + RunningGraph, + // A histogram of the last N values (values between 0 and 1). + RunningHistogram, + + InvalidEnum, + EnumCount = InvalidEnum, +}; + +namespace overlay +{ +class Text; +class Widget +{ + public: + virtual ~Widget() {} + + virtual const Text *getDescriptionWidget() const; + + protected: + WidgetType type; + // Whether this item should be drawn. + bool enabled = false; + + // For text items, size of the font. This is a value in [0, overlay::kFontMipCount) which + // determines the font size to use. + int fontSize; + + // The area covered by the item, predetermined by the overlay class. Negative values + // indicate offset from the left/bottom of the image. + int32_t coords[4]; + float color[4]; + + // In some cases, a widget may need to match its contents (e.g. graph height scaling) with + // another related widget. In such a case, this pointer will point to the widget it needs to + // match to. + Widget *matchToWidget; + + friend class gl::Overlay; + friend class gl::OverlayState; + friend class overlay_impl::AppendWidgetDataHelper; +}; + +class Count : public Widget +{ + public: + ~Count() override {} + void add(uint64_t n) { count += n; } + void set(uint64_t n) { count = n; } + void reset() { count = 0; } + + protected: + uint64_t count = 0; + + friend class gl::Overlay; + friend class overlay_impl::AppendWidgetDataHelper; +}; + +class PerSecond : public Count +{ + public: + ~PerSecond() override {} + + protected: + uint64_t lastPerSecondCount = 0; + + friend class gl::Overlay; + friend class overlay_impl::AppendWidgetDataHelper; +}; + +class Text : public Widget +{ + public: + ~Text() override {} + void set(std::string &&str) { text = std::move(str); } + + protected: + std::string text; + + friend class overlay_impl::AppendWidgetDataHelper; +}; + +class RunningGraph : public Widget +{ + public: + // Out of line constructor to satisfy chromium-style. + RunningGraph(size_t n); + ~RunningGraph() override; + + void add(uint64_t n) + { + if (!ignoreFirstValue) + { + runningValues[lastValueIndex] += n; + } + } + + void next() + { + if (ignoreFirstValue) + { + ignoreFirstValue = false; + } + else + { + lastValueIndex = (lastValueIndex + 1) % runningValues.size(); + runningValues[lastValueIndex] = 0; + } + } + + const Text *getDescriptionWidget() const override; + + protected: + std::vector runningValues; + size_t lastValueIndex = 0; + Text description; + bool ignoreFirstValue = true; + + friend class gl::Overlay; + friend class gl::OverlayState; + friend class overlay_impl::AppendWidgetDataHelper; +}; + +class RunningHistogram : public RunningGraph +{ + public: + RunningHistogram(size_t n) : RunningGraph(n) {} + ~RunningHistogram() override {} + + void set(float n) + { + ASSERT(n >= 0.0f && n <= 1.0f); + uint64_t rank = + n == 1.0f ? runningValues.size() - 1 : static_cast(n * runningValues.size()); + + runningValues[lastValueIndex] = rank; + } + + private: + // Do not use the add() function from RunningGraph + using RunningGraph::add; +}; + +// If overlay is disabled, all the above classes would be replaced with Mock, turning them into +// noop. +class Mock +{ + public: + void reset() const {} + template + void set(T) const + {} + template + void add(T) const + {} + void next() const {} +}; + +} // namespace overlay + +} // namespace gl + +#endif // LIBANGLE_OVERLAYWIDGETS_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Overlay_autogen.cpp b/gfx/angle/checkout/src/libANGLE/Overlay_autogen.cpp new file mode 100644 index 0000000000..eb2a146188 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Overlay_autogen.cpp @@ -0,0 +1,824 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_overlay_widgets.py using data from overlay_widgets.json. +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Overlay_autogen.cpp: +// Autogenerated overlay widget declarations. + +#include "libANGLE/Overlay.h" +#include "libANGLE/OverlayWidgets.h" +#include "libANGLE/Overlay_font_autogen.h" +#include "libANGLE/renderer/driver_utils.h" + +namespace gl +{ +using namespace overlay; + +namespace +{ +int GetFontSize(int fontSize, bool largeFont) +{ + if (largeFont && fontSize > 0) + { + return fontSize - 1; + } + return fontSize; +} +} // anonymous namespace + +void Overlay::initOverlayWidgets() +{ + const bool kLargeFont = rx::IsAndroid(); + + { + PerSecond *widget = new PerSecond; + { + const int32_t fontSize = GetFontSize(kFontMipLarge, kLargeFont); + const int32_t offsetX = 10; + const int32_t offsetY = 10; + const int32_t width = 12 * (kFontGlyphWidth >> fontSize); + const int32_t height = (kFontGlyphHeight >> fontSize); + + widget->type = WidgetType::PerSecond; + widget->fontSize = fontSize; + widget->coords[0] = offsetX; + widget->coords[1] = offsetY; + widget->coords[2] = offsetX + width; + widget->coords[3] = offsetY + height; + widget->color[0] = 0.4980392156862745f; + widget->color[1] = 0.7490196078431373f; + widget->color[2] = 1.0f; + widget->color[3] = 1.0f; + widget->matchToWidget = nullptr; + } + mState.mOverlayWidgets[WidgetId::FPS].reset(widget); + } + + { + Text *widget = new Text; + { + const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont); + const int32_t offsetX = 10; + const int32_t offsetY = -10; + const int32_t width = 150 * (kFontGlyphWidth >> fontSize); + const int32_t height = (kFontGlyphHeight >> fontSize); + + widget->type = WidgetType::Text; + widget->fontSize = fontSize; + widget->coords[0] = offsetX; + widget->coords[1] = offsetY - height; + widget->coords[2] = offsetX + width; + widget->coords[3] = offsetY; + widget->color[0] = 1.0f; + widget->color[1] = 0.0f; + widget->color[2] = 0.0f; + widget->color[3] = 1.0f; + widget->matchToWidget = nullptr; + } + mState.mOverlayWidgets[WidgetId::VulkanLastValidationMessage].reset(widget); + } + + { + Count *widget = new Count; + { + const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont); + const int32_t offsetX = 10; + const int32_t offsetY = + mState.mOverlayWidgets[WidgetId::VulkanLastValidationMessage]->coords[1]; + const int32_t width = 25 * (kFontGlyphWidth >> fontSize); + const int32_t height = (kFontGlyphHeight >> fontSize); + + widget->type = WidgetType::Count; + widget->fontSize = fontSize; + widget->coords[0] = offsetX; + widget->coords[1] = offsetY - height; + widget->coords[2] = offsetX + width; + widget->coords[3] = offsetY; + widget->color[0] = 1.0f; + widget->color[1] = 0.0f; + widget->color[2] = 0.0f; + widget->color[3] = 1.0f; + widget->matchToWidget = nullptr; + } + mState.mOverlayWidgets[WidgetId::VulkanValidationMessageCount].reset(widget); + } + + { + RunningGraph *widget = new RunningGraph(60); + { + const int32_t fontSize = GetFontSize(0, kLargeFont); + const int32_t offsetX = 10; + const int32_t offsetY = 100; + const int32_t width = 5 * static_cast(widget->runningValues.size()); + const int32_t height = 100; + + widget->type = WidgetType::RunningGraph; + widget->fontSize = fontSize; + widget->coords[0] = offsetX; + widget->coords[1] = offsetY; + widget->coords[2] = offsetX + width; + widget->coords[3] = offsetY + height; + widget->color[0] = 0.29411764705882354f; + widget->color[1] = 0.7843137254901961f; + widget->color[2] = 0.0f; + widget->color[3] = 0.7843137254901961f; + widget->matchToWidget = nullptr; + } + mState.mOverlayWidgets[WidgetId::VulkanRenderPassCount].reset(widget); + { + const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont); + const int32_t offsetX = + mState.mOverlayWidgets[WidgetId::VulkanRenderPassCount]->coords[0]; + const int32_t offsetY = + mState.mOverlayWidgets[WidgetId::VulkanRenderPassCount]->coords[1]; + const int32_t width = 40 * (kFontGlyphWidth >> fontSize); + const int32_t height = (kFontGlyphHeight >> fontSize); + + widget->description.type = WidgetType::Text; + widget->description.fontSize = fontSize; + widget->description.coords[0] = offsetX; + widget->description.coords[1] = std::max(offsetY - height, 1); + widget->description.coords[2] = offsetX + width; + widget->description.coords[3] = offsetY; + widget->description.color[0] = 0.29411764705882354f; + widget->description.color[1] = 0.7843137254901961f; + widget->description.color[2] = 0.0f; + widget->description.color[3] = 1.0f; + widget->description.matchToWidget = nullptr; + } + } + + { + RunningGraph *widget = new RunningGraph(100); + { + const int32_t fontSize = GetFontSize(0, kLargeFont); + const int32_t offsetX = -50; + const int32_t offsetY = 100; + const int32_t width = 6 * static_cast(widget->runningValues.size()); + const int32_t height = 100; + + widget->type = WidgetType::RunningGraph; + widget->fontSize = fontSize; + widget->coords[0] = offsetX - width; + widget->coords[1] = offsetY; + widget->coords[2] = offsetX; + widget->coords[3] = offsetY + height; + widget->color[0] = 1.0f; + widget->color[1] = 0.7843137254901961f; + widget->color[2] = 0.29411764705882354f; + widget->color[3] = 0.7843137254901961f; + widget->matchToWidget = nullptr; + } + mState.mOverlayWidgets[WidgetId::VulkanRenderPassBufferCount].reset(widget); + { + const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont); + const int32_t offsetX = + mState.mOverlayWidgets[WidgetId::VulkanRenderPassBufferCount]->coords[0]; + const int32_t offsetY = + mState.mOverlayWidgets[WidgetId::VulkanRenderPassBufferCount]->coords[1]; + const int32_t width = 40 * (kFontGlyphWidth >> fontSize); + const int32_t height = (kFontGlyphHeight >> fontSize); + + widget->description.type = WidgetType::Text; + widget->description.fontSize = fontSize; + widget->description.coords[0] = offsetX; + widget->description.coords[1] = std::max(offsetY - height, 1); + widget->description.coords[2] = std::min(offsetX + width, -1); + widget->description.coords[3] = offsetY; + widget->description.color[0] = 1.0f; + widget->description.color[1] = 0.7843137254901961f; + widget->description.color[2] = 0.29411764705882354f; + widget->description.color[3] = 1.0f; + widget->description.matchToWidget = nullptr; + } + } + + { + RunningHistogram *widget = new RunningHistogram(50); + { + const int32_t fontSize = GetFontSize(0, kLargeFont); + const int32_t offsetX = -50; + const int32_t offsetY = 100; + const int32_t width = 6 * static_cast(widget->runningValues.size()); + const int32_t height = 100; + + widget->type = WidgetType::RunningHistogram; + widget->fontSize = fontSize; + widget->coords[0] = offsetX - width; + widget->coords[1] = offsetY; + widget->coords[2] = offsetX; + widget->coords[3] = offsetY + height; + widget->color[0] = 1.0f; + widget->color[1] = 0.7843137254901961f; + widget->color[2] = 0.29411764705882354f; + widget->color[3] = 0.7843137254901961f; + widget->matchToWidget = nullptr; + } + mState.mOverlayWidgets[WidgetId::VulkanSecondaryCommandBufferPoolWaste].reset(widget); + { + const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont); + const int32_t offsetX = + mState.mOverlayWidgets[WidgetId::VulkanSecondaryCommandBufferPoolWaste]->coords[0]; + const int32_t offsetY = + mState.mOverlayWidgets[WidgetId::VulkanSecondaryCommandBufferPoolWaste]->coords[1]; + const int32_t width = 40 * (kFontGlyphWidth >> fontSize); + const int32_t height = (kFontGlyphHeight >> fontSize); + + widget->description.type = WidgetType::Text; + widget->description.fontSize = fontSize; + widget->description.coords[0] = offsetX; + widget->description.coords[1] = std::max(offsetY - height, 1); + widget->description.coords[2] = std::min(offsetX + width, -1); + widget->description.coords[3] = offsetY; + widget->description.color[0] = 1.0f; + widget->description.color[1] = 0.7843137254901961f; + widget->description.color[2] = 0.29411764705882354f; + widget->description.color[3] = 1.0f; + widget->description.matchToWidget = nullptr; + } + } + + { + RunningGraph *widget = new RunningGraph(60); + { + const int32_t fontSize = GetFontSize(0, kLargeFont); + const int32_t offsetX = 10; + const int32_t offsetY = 220; + const int32_t width = 5 * static_cast(widget->runningValues.size()); + const int32_t height = 100; + + widget->type = WidgetType::RunningGraph; + widget->fontSize = fontSize; + widget->coords[0] = offsetX; + widget->coords[1] = offsetY; + widget->coords[2] = offsetX + width; + widget->coords[3] = offsetY + height; + widget->color[0] = 0.29411764705882354f; + widget->color[1] = 0.7843137254901961f; + widget->color[2] = 0.0f; + widget->color[3] = 0.7843137254901961f; + widget->matchToWidget = nullptr; + } + mState.mOverlayWidgets[WidgetId::VulkanWriteDescriptorSetCount].reset(widget); + { + const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont); + const int32_t offsetX = + mState.mOverlayWidgets[WidgetId::VulkanWriteDescriptorSetCount]->coords[0]; + const int32_t offsetY = + mState.mOverlayWidgets[WidgetId::VulkanWriteDescriptorSetCount]->coords[1]; + const int32_t width = 40 * (kFontGlyphWidth >> fontSize); + const int32_t height = (kFontGlyphHeight >> fontSize); + + widget->description.type = WidgetType::Text; + widget->description.fontSize = fontSize; + widget->description.coords[0] = offsetX; + widget->description.coords[1] = std::max(offsetY - height, 1); + widget->description.coords[2] = offsetX + width; + widget->description.coords[3] = offsetY; + widget->description.color[0] = 0.29411764705882354f; + widget->description.color[1] = 0.7843137254901961f; + widget->description.color[2] = 0.0f; + widget->description.color[3] = 1.0f; + widget->description.matchToWidget = nullptr; + } + } + + { + RunningGraph *widget = new RunningGraph(60); + { + const int32_t fontSize = GetFontSize(0, kLargeFont); + const int32_t offsetX = 0; + const int32_t offsetY = 250; + const int32_t width = 6 * static_cast(widget->runningValues.size()); + const int32_t height = 100; + + widget->type = WidgetType::RunningGraph; + widget->fontSize = fontSize; + widget->coords[0] = offsetX; + widget->coords[1] = offsetY; + widget->coords[2] = offsetX + width; + widget->coords[3] = offsetY + height; + widget->color[0] = 1.0f; + widget->color[1] = 0.0f; + widget->color[2] = 0.29411764705882354f; + widget->color[3] = 0.7843137254901961f; + widget->matchToWidget = nullptr; + } + mState.mOverlayWidgets[WidgetId::VulkanDescriptorSetAllocations].reset(widget); + { + const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont); + const int32_t offsetX = + mState.mOverlayWidgets[WidgetId::VulkanDescriptorSetAllocations]->coords[0]; + const int32_t offsetY = + mState.mOverlayWidgets[WidgetId::VulkanDescriptorSetAllocations]->coords[1]; + const int32_t width = 40 * (kFontGlyphWidth >> fontSize); + const int32_t height = (kFontGlyphHeight >> fontSize); + + widget->description.type = WidgetType::Text; + widget->description.fontSize = fontSize; + widget->description.coords[0] = offsetX; + widget->description.coords[1] = std::max(offsetY - height, 1); + widget->description.coords[2] = offsetX + width; + widget->description.coords[3] = offsetY; + widget->description.color[0] = 1.0f; + widget->description.color[1] = 0.0f; + widget->description.color[2] = 0.29411764705882354f; + widget->description.color[3] = 1.0f; + widget->description.matchToWidget = nullptr; + } + } + + { + RunningGraph *widget = new RunningGraph(60); + { + const int32_t fontSize = GetFontSize(0, kLargeFont); + const int32_t offsetX = -50; + const int32_t offsetY = 360; + const int32_t width = 6 * static_cast(widget->runningValues.size()); + const int32_t height = 100; + + widget->type = WidgetType::RunningGraph; + widget->fontSize = fontSize; + widget->coords[0] = offsetX - width; + widget->coords[1] = offsetY; + widget->coords[2] = offsetX; + widget->coords[3] = offsetY + height; + widget->color[0] = 1.0f; + widget->color[1] = 0.0f; + widget->color[2] = 0.29411764705882354f; + widget->color[3] = 0.7843137254901961f; + widget->matchToWidget = nullptr; + } + mState.mOverlayWidgets[WidgetId::VulkanShaderResourceDSHitRate].reset(widget); + { + const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont); + const int32_t offsetX = + mState.mOverlayWidgets[WidgetId::VulkanShaderResourceDSHitRate]->coords[0]; + const int32_t offsetY = + mState.mOverlayWidgets[WidgetId::VulkanShaderResourceDSHitRate]->coords[1]; + const int32_t width = 40 * (kFontGlyphWidth >> fontSize); + const int32_t height = (kFontGlyphHeight >> fontSize); + + widget->description.type = WidgetType::Text; + widget->description.fontSize = fontSize; + widget->description.coords[0] = offsetX; + widget->description.coords[1] = std::max(offsetY - height, 1); + widget->description.coords[2] = std::min(offsetX + width, -1); + widget->description.coords[3] = offsetY; + widget->description.color[0] = 1.0f; + widget->description.color[1] = 0.0f; + widget->description.color[2] = 0.29411764705882354f; + widget->description.color[3] = 1.0f; + widget->description.matchToWidget = nullptr; + } + } + + { + RunningGraph *widget = new RunningGraph(120); + { + const int32_t fontSize = GetFontSize(0, kLargeFont); + const int32_t offsetX = -50; + const int32_t offsetY = -50; + const int32_t width = 5 * static_cast(widget->runningValues.size()); + const int32_t height = 100; + + widget->type = WidgetType::RunningGraph; + widget->fontSize = fontSize; + widget->coords[0] = offsetX - width; + widget->coords[1] = offsetY - height; + widget->coords[2] = offsetX; + widget->coords[3] = offsetY; + widget->color[0] = 0.0f; + widget->color[1] = 0.7843137254901961f; + widget->color[2] = 0.29411764705882354f; + widget->color[3] = 0.7843137254901961f; + widget->matchToWidget = nullptr; + } + mState.mOverlayWidgets[WidgetId::VulkanDynamicBufferAllocations].reset(widget); + { + const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont); + const int32_t offsetX = + mState.mOverlayWidgets[WidgetId::VulkanDynamicBufferAllocations]->coords[2]; + const int32_t offsetY = + mState.mOverlayWidgets[WidgetId::VulkanDynamicBufferAllocations]->coords[1]; + const int32_t width = 40 * (kFontGlyphWidth >> fontSize); + const int32_t height = (kFontGlyphHeight >> fontSize); + + widget->description.type = WidgetType::Text; + widget->description.fontSize = fontSize; + widget->description.coords[0] = offsetX - width; + widget->description.coords[1] = offsetY - height; + widget->description.coords[2] = offsetX; + widget->description.coords[3] = offsetY; + widget->description.color[0] = 0.0f; + widget->description.color[1] = 0.7843137254901961f; + widget->description.color[2] = 0.29411764705882354f; + widget->description.color[3] = 1.0f; + widget->description.matchToWidget = nullptr; + } + } + + { + RunningGraph *widget = new RunningGraph(60); + { + const int32_t fontSize = GetFontSize(0, kLargeFont); + const int32_t offsetX = 0; + const int32_t offsetY = 450; + const int32_t width = 5 * static_cast(widget->runningValues.size()); + const int32_t height = 100; + + widget->type = WidgetType::RunningGraph; + widget->fontSize = fontSize; + widget->coords[0] = offsetX; + widget->coords[1] = offsetY; + widget->coords[2] = offsetX + width; + widget->coords[3] = offsetY + height; + widget->color[0] = 0.0f; + widget->color[1] = 0.7843137254901961f; + widget->color[2] = 0.7254901960784313f; + widget->color[3] = 0.7843137254901961f; + widget->matchToWidget = nullptr; + } + mState.mOverlayWidgets[WidgetId::VulkanDescriptorCacheSize].reset(widget); + { + const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont); + const int32_t offsetX = + mState.mOverlayWidgets[WidgetId::VulkanDescriptorCacheSize]->coords[0]; + const int32_t offsetY = + mState.mOverlayWidgets[WidgetId::VulkanDescriptorCacheSize]->coords[1]; + const int32_t width = 90 * (kFontGlyphWidth >> fontSize); + const int32_t height = (kFontGlyphHeight >> fontSize); + + widget->description.type = WidgetType::Text; + widget->description.fontSize = fontSize; + widget->description.coords[0] = offsetX; + widget->description.coords[1] = std::max(offsetY - height, 1); + widget->description.coords[2] = offsetX + width; + widget->description.coords[3] = offsetY; + widget->description.color[0] = 0.0f; + widget->description.color[1] = 0.7843137254901961f; + widget->description.color[2] = 0.29411764705882354f; + widget->description.color[3] = 1.0f; + widget->description.matchToWidget = nullptr; + } + } + + { + RunningGraph *widget = new RunningGraph(60); + { + const int32_t fontSize = GetFontSize(0, kLargeFont); + const int32_t offsetX = 0; + const int32_t offsetY = 450; + const int32_t width = 5 * static_cast(widget->runningValues.size()); + const int32_t height = 100; + + widget->type = WidgetType::RunningGraph; + widget->fontSize = fontSize; + widget->coords[0] = offsetX; + widget->coords[1] = offsetY; + widget->coords[2] = offsetX + width; + widget->coords[3] = offsetY + height; + widget->color[0] = 0.0f; + widget->color[1] = 0.7843137254901961f; + widget->color[2] = 0.29411764705882354f; + widget->color[3] = 0.7843137254901961f; + widget->matchToWidget = nullptr; + } + mState.mOverlayWidgets[WidgetId::VulkanTextureDescriptorCacheSize].reset(widget); + { + const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont); + const int32_t offsetX = + mState.mOverlayWidgets[WidgetId::VulkanTextureDescriptorCacheSize]->coords[0]; + const int32_t offsetY = + mState.mOverlayWidgets[WidgetId::VulkanTextureDescriptorCacheSize]->coords[1]; + const int32_t width = 90 * (kFontGlyphWidth >> fontSize); + const int32_t height = (kFontGlyphHeight >> fontSize); + + widget->description.type = WidgetType::Text; + widget->description.fontSize = fontSize; + widget->description.coords[0] = offsetX; + widget->description.coords[1] = std::max(offsetY - height, 1); + widget->description.coords[2] = offsetX + width; + widget->description.coords[3] = offsetY; + widget->description.color[0] = 0.0f; + widget->description.color[1] = 0.7843137254901961f; + widget->description.color[2] = 0.29411764705882354f; + widget->description.color[3] = 1.0f; + widget->description.matchToWidget = nullptr; + } + } + + { + RunningGraph *widget = new RunningGraph(60); + { + const int32_t fontSize = GetFontSize(0, kLargeFont); + const int32_t offsetX = 0; + const int32_t offsetY = 450; + const int32_t width = 5 * static_cast(widget->runningValues.size()); + const int32_t height = 100; + + widget->type = WidgetType::RunningGraph; + widget->fontSize = fontSize; + widget->coords[0] = offsetX; + widget->coords[1] = offsetY; + widget->coords[2] = offsetX + width; + widget->coords[3] = offsetY + height; + widget->color[0] = 0.0f; + widget->color[1] = 0.7843137254901961f; + widget->color[2] = 1.0f; + widget->color[3] = 0.7843137254901961f; + widget->matchToWidget = nullptr; + } + mState.mOverlayWidgets[WidgetId::VulkanUniformDescriptorCacheSize].reset(widget); + { + const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont); + const int32_t offsetX = + mState.mOverlayWidgets[WidgetId::VulkanUniformDescriptorCacheSize]->coords[0]; + const int32_t offsetY = + mState.mOverlayWidgets[WidgetId::VulkanUniformDescriptorCacheSize]->coords[1]; + const int32_t width = 90 * (kFontGlyphWidth >> fontSize); + const int32_t height = (kFontGlyphHeight >> fontSize); + + widget->description.type = WidgetType::Text; + widget->description.fontSize = fontSize; + widget->description.coords[0] = offsetX; + widget->description.coords[1] = std::max(offsetY - height, 1); + widget->description.coords[2] = offsetX + width; + widget->description.coords[3] = offsetY; + widget->description.color[0] = 0.0f; + widget->description.color[1] = 0.7843137254901961f; + widget->description.color[2] = 0.29411764705882354f; + widget->description.color[3] = 1.0f; + widget->description.matchToWidget = nullptr; + } + } + + { + Count *widget = new Count; + { + const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont); + const int32_t offsetX = 10; + const int32_t offsetY = 100; + const int32_t width = 30 * (kFontGlyphWidth >> fontSize); + const int32_t height = (kFontGlyphHeight >> fontSize); + + widget->type = WidgetType::Count; + widget->fontSize = fontSize; + widget->coords[0] = offsetX; + widget->coords[1] = offsetY; + widget->coords[2] = offsetX + width; + widget->coords[3] = offsetY + height; + widget->color[0] = 1.0f; + widget->color[1] = 1.0f; + widget->color[2] = 1.0f; + widget->color[3] = 1.0f; + widget->matchToWidget = nullptr; + } + mState.mOverlayWidgets[WidgetId::VulkanDescriptorCacheKeySize].reset(widget); + } + + { + RunningGraph *widget = new RunningGraph(60); + { + const int32_t fontSize = GetFontSize(0, kLargeFont); + const int32_t offsetX = -50; + const int32_t offsetY = 50; + const int32_t width = 5 * static_cast(widget->runningValues.size()); + const int32_t height = 100; + + widget->type = WidgetType::RunningGraph; + widget->fontSize = fontSize; + widget->coords[0] = offsetX - width; + widget->coords[1] = offsetY; + widget->coords[2] = offsetX; + widget->coords[3] = offsetY + height; + widget->color[0] = 1.0f; + widget->color[1] = 0.0f; + widget->color[2] = 0.0f; + widget->color[3] = 0.39215686274509803f; + widget->matchToWidget = nullptr; + } + mState.mOverlayWidgets[WidgetId::VulkanAttemptedSubmissions].reset(widget); + { + const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont); + const int32_t offsetX = + mState.mOverlayWidgets[WidgetId::VulkanAttemptedSubmissions]->coords[0]; + const int32_t offsetY = + mState.mOverlayWidgets[WidgetId::VulkanAttemptedSubmissions]->coords[1]; + const int32_t width = 45 * (kFontGlyphWidth >> fontSize); + const int32_t height = (kFontGlyphHeight >> fontSize); + + widget->description.type = WidgetType::Text; + widget->description.fontSize = fontSize; + widget->description.coords[0] = offsetX; + widget->description.coords[1] = std::max(offsetY - height, 1); + widget->description.coords[2] = std::min(offsetX + width, -1); + widget->description.coords[3] = offsetY; + widget->description.color[0] = 0.7843137254901961f; + widget->description.color[1] = 0.0f; + widget->description.color[2] = 0.29411764705882354f; + widget->description.color[3] = 1.0f; + widget->description.matchToWidget = nullptr; + } + } + + { + RunningGraph *widget = new RunningGraph(60); + { + const int32_t fontSize = GetFontSize(0, kLargeFont); + const int32_t offsetX = + mState.mOverlayWidgets[WidgetId::VulkanAttemptedSubmissions]->coords[0]; + const int32_t offsetY = + mState.mOverlayWidgets[WidgetId::VulkanAttemptedSubmissions]->coords[1]; + const int32_t width = 5 * static_cast(widget->runningValues.size()); + const int32_t height = 100; + + widget->type = WidgetType::RunningGraph; + widget->fontSize = fontSize; + widget->coords[0] = offsetX; + widget->coords[1] = offsetY; + widget->coords[2] = std::min(offsetX + width, -1); + widget->coords[3] = offsetY + height; + widget->color[0] = 0.0f; + widget->color[1] = 1.0f; + widget->color[2] = 0.0f; + widget->color[3] = 0.7843137254901961f; + widget->matchToWidget = + mState.mOverlayWidgets[WidgetId::VulkanAttemptedSubmissions].get(); + } + mState.mOverlayWidgets[WidgetId::VulkanActualSubmissions].reset(widget); + { + const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont); + const int32_t offsetX = + mState.mOverlayWidgets[WidgetId::VulkanActualSubmissions]->coords[0]; + const int32_t offsetY = + mState.mOverlayWidgets[WidgetId::VulkanActualSubmissions]->coords[3]; + const int32_t width = 45 * (kFontGlyphWidth >> fontSize); + const int32_t height = (kFontGlyphHeight >> fontSize); + + widget->description.type = WidgetType::Text; + widget->description.fontSize = fontSize; + widget->description.coords[0] = offsetX; + widget->description.coords[1] = offsetY; + widget->description.coords[2] = std::min(offsetX + width, -1); + widget->description.coords[3] = offsetY + height; + widget->description.color[0] = 0.0f; + widget->description.color[1] = 0.7843137254901961f; + widget->description.color[2] = 0.29411764705882354f; + widget->description.color[3] = 1.0f; + widget->description.matchToWidget = nullptr; + } + } + + { + RunningGraph *widget = new RunningGraph(60); + { + const int32_t fontSize = GetFontSize(0, kLargeFont); + const int32_t offsetX = -50; + const int32_t offsetY = -50; + const int32_t width = 5 * static_cast(widget->runningValues.size()); + const int32_t height = 100; + + widget->type = WidgetType::RunningGraph; + widget->fontSize = fontSize; + widget->coords[0] = offsetX - width; + widget->coords[1] = offsetY - height; + widget->coords[2] = offsetX; + widget->coords[3] = offsetY; + widget->color[0] = 0.0f; + widget->color[1] = 1.0f; + widget->color[2] = 0.0f; + widget->color[3] = 0.39215686274509803f; + widget->matchToWidget = nullptr; + } + mState.mOverlayWidgets[WidgetId::VulkanPipelineCacheLookups].reset(widget); + { + const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont); + const int32_t offsetX = + mState.mOverlayWidgets[WidgetId::VulkanPipelineCacheLookups]->coords[0]; + const int32_t offsetY = + mState.mOverlayWidgets[WidgetId::VulkanPipelineCacheLookups]->coords[1]; + const int32_t width = 45 * (kFontGlyphWidth >> fontSize); + const int32_t height = (kFontGlyphHeight >> fontSize); + + widget->description.type = WidgetType::Text; + widget->description.fontSize = fontSize; + widget->description.coords[0] = offsetX; + widget->description.coords[1] = offsetY - height; + widget->description.coords[2] = std::min(offsetX + width, -1); + widget->description.coords[3] = offsetY; + widget->description.color[0] = 0.0f; + widget->description.color[1] = 0.7843137254901961f; + widget->description.color[2] = 0.29411764705882354f; + widget->description.color[3] = 1.0f; + widget->description.matchToWidget = nullptr; + } + } + + { + RunningGraph *widget = new RunningGraph(60); + { + const int32_t fontSize = GetFontSize(0, kLargeFont); + const int32_t offsetX = + mState.mOverlayWidgets[WidgetId::VulkanPipelineCacheLookups]->coords[0]; + const int32_t offsetY = + mState.mOverlayWidgets[WidgetId::VulkanPipelineCacheLookups]->coords[1]; + const int32_t width = 5 * static_cast(widget->runningValues.size()); + const int32_t height = 100; + + widget->type = WidgetType::RunningGraph; + widget->fontSize = fontSize; + widget->coords[0] = offsetX; + widget->coords[1] = offsetY; + widget->coords[2] = std::min(offsetX + width, -1); + widget->coords[3] = std::min(offsetY + height, -1); + widget->color[0] = 1.0f; + widget->color[1] = 0.0f; + widget->color[2] = 0.0f; + widget->color[3] = 0.7843137254901961f; + widget->matchToWidget = + mState.mOverlayWidgets[WidgetId::VulkanPipelineCacheLookups].get(); + } + mState.mOverlayWidgets[WidgetId::VulkanPipelineCacheMisses].reset(widget); + { + const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont); + const int32_t offsetX = mState.mOverlayWidgets[WidgetId::VulkanPipelineCacheLookups] + ->getDescriptionWidget() + ->coords[0]; + const int32_t offsetY = mState.mOverlayWidgets[WidgetId::VulkanPipelineCacheLookups] + ->getDescriptionWidget() + ->coords[1]; + const int32_t width = 45 * (kFontGlyphWidth >> fontSize); + const int32_t height = (kFontGlyphHeight >> fontSize); + + widget->description.type = WidgetType::Text; + widget->description.fontSize = fontSize; + widget->description.coords[0] = offsetX; + widget->description.coords[1] = offsetY - height; + widget->description.coords[2] = std::min(offsetX + width, -1); + widget->description.coords[3] = offsetY; + widget->description.color[0] = 0.7843137254901961f; + widget->description.color[1] = 0.0f; + widget->description.color[2] = 0.29411764705882354f; + widget->description.color[3] = 1.0f; + widget->description.matchToWidget = nullptr; + } + } + + { + Count *widget = new Count; + { + const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont); + const int32_t offsetX = + mState.mOverlayWidgets[WidgetId::VulkanPipelineCacheMisses]->coords[0]; + const int32_t offsetY = + mState.mOverlayWidgets[WidgetId::VulkanPipelineCacheMisses]->coords[3]; + const int32_t width = 45 * (kFontGlyphWidth >> fontSize); + const int32_t height = (kFontGlyphHeight >> fontSize); + + widget->type = WidgetType::Count; + widget->fontSize = fontSize; + widget->coords[0] = offsetX; + widget->coords[1] = offsetY; + widget->coords[2] = std::min(offsetX + width, -1); + widget->coords[3] = std::min(offsetY + height, -1); + widget->color[0] = 1.0f; + widget->color[1] = 0.0f; + widget->color[2] = 0.0f; + widget->color[3] = 1.0f; + widget->matchToWidget = nullptr; + } + mState.mOverlayWidgets[WidgetId::VulkanTotalPipelineCacheMissTimeMs].reset(widget); + } + + { + Count *widget = new Count; + { + const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont); + const int32_t offsetX = + mState.mOverlayWidgets[WidgetId::VulkanTotalPipelineCacheMissTimeMs]->coords[0]; + const int32_t offsetY = + mState.mOverlayWidgets[WidgetId::VulkanTotalPipelineCacheMissTimeMs]->coords[3]; + const int32_t width = 45 * (kFontGlyphWidth >> fontSize); + const int32_t height = (kFontGlyphHeight >> fontSize); + + widget->type = WidgetType::Count; + widget->fontSize = fontSize; + widget->coords[0] = offsetX; + widget->coords[1] = offsetY; + widget->coords[2] = std::min(offsetX + width, -1); + widget->coords[3] = std::min(offsetY + height, -1); + widget->color[0] = 0.0f; + widget->color[1] = 1.0f; + widget->color[2] = 0.0f; + widget->color[3] = 1.0f; + widget->matchToWidget = nullptr; + } + mState.mOverlayWidgets[WidgetId::VulkanTotalPipelineCacheHitTimeMs].reset(widget); + } +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/Overlay_autogen.h b/gfx/angle/checkout/src/libANGLE/Overlay_autogen.h new file mode 100644 index 0000000000..32ddd88559 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Overlay_autogen.h @@ -0,0 +1,83 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_overlay_widgets.py using data from overlay_widgets.json. +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Overlay_autogen.cpp: +// Autogenerated overlay widget declarations. + +namespace gl +{ +enum class WidgetId +{ + // Frames per second (Count/Second). + FPS, + // Last validation error (Text). + VulkanLastValidationMessage, + // Number of validation errors and warnings (Count). + VulkanValidationMessageCount, + // Number of RenderPasses in a frame (Count). + VulkanRenderPassCount, + // Number of buffers used in RenderPasses (Count). + VulkanRenderPassBufferCount, + // Secondary Command Buffer pool memory waste (Bytes). + VulkanSecondaryCommandBufferPoolWaste, + // Number of Descriptor Set writes in a frame (Count). + VulkanWriteDescriptorSetCount, + // Descriptor Set Allocations. + VulkanDescriptorSetAllocations, + // Shader Resource Descriptor Set Cache Hit Rate. + VulkanShaderResourceDSHitRate, + // Buffer Allocations Made By vk::DynamicBuffer. + VulkanDynamicBufferAllocations, + // Total size of all descriptor set caches + VulkanDescriptorCacheSize, + // Number of cached Texture descriptor sets + VulkanTextureDescriptorCacheSize, + // Number of cached default uniform descriptor sets + VulkanUniformDescriptorCacheSize, + // Total size of all keys in the descriptor set caches + VulkanDescriptorCacheKeySize, + // Number of times the Vulkan backend attempted to submit commands + VulkanAttemptedSubmissions, + // Number of times the Vulkan backend actually submitted commands + VulkanActualSubmissions, + // Number of times the Vulkan backend has looked up the pipeline cache + VulkanPipelineCacheLookups, + // Number of times the Vulkan backend has missed the pipeline cache + VulkanPipelineCacheMisses, + // Total time spent creating pipelines that missed the cache. + VulkanTotalPipelineCacheMissTimeMs, + // Total time spent creating pipelines that hit the cache. + VulkanTotalPipelineCacheHitTimeMs, + + InvalidEnum, + EnumCount = InvalidEnum, +}; + +// We can use this "X" macro to generate multiple code patterns. +#define ANGLE_WIDGET_ID_X(PROC) \ + PROC(FPS) \ + PROC(VulkanLastValidationMessage) \ + PROC(VulkanValidationMessageCount) \ + PROC(VulkanRenderPassCount) \ + PROC(VulkanRenderPassBufferCount) \ + PROC(VulkanSecondaryCommandBufferPoolWaste) \ + PROC(VulkanWriteDescriptorSetCount) \ + PROC(VulkanDescriptorSetAllocations) \ + PROC(VulkanShaderResourceDSHitRate) \ + PROC(VulkanDynamicBufferAllocations) \ + PROC(VulkanDescriptorCacheSize) \ + PROC(VulkanTextureDescriptorCacheSize) \ + PROC(VulkanUniformDescriptorCacheSize) \ + PROC(VulkanDescriptorCacheKeySize) \ + PROC(VulkanAttemptedSubmissions) \ + PROC(VulkanActualSubmissions) \ + PROC(VulkanPipelineCacheLookups) \ + PROC(VulkanPipelineCacheMisses) \ + PROC(VulkanTotalPipelineCacheMissTimeMs) \ + PROC(VulkanTotalPipelineCacheHitTimeMs) + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/Overlay_font_autogen.cpp b/gfx/angle/checkout/src/libANGLE/Overlay_font_autogen.cpp new file mode 100644 index 0000000000..7df5893304 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Overlay_font_autogen.cpp @@ -0,0 +1,5078 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_overlay_fonts.py using images from overlay/DejaVuSansMono-Bold.ttf. +// +// Copyright 2022 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Overlay_font_autogen.cpp: +// Autogenerated overlay font data. + +#include "libANGLE/Overlay_font_autogen.h" +#include "libANGLE/Overlay.h" + +#include + +namespace gl +{ +using namespace overlay; + +// Save binary size if the font images are never to be used. +#if ANGLE_ENABLE_OVERLAY +namespace +{ +constexpr uint8_t kFontData[67830] = { + // clang-format off +// Large +// ' ' + 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, + 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, 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, 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, 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, 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, 0, 0, 0, 0,0x28,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x28,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x28,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x28,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x28,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x28,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x28,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x28,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x28,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x1D,0xFF,0xFF,0xFF,0x95, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x05,0xFE,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xEB,0xFF,0xFF,0x64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xD2,0xFF,0xFF,0x4C, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xB9,0xFF,0xFF,0x34, 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, 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, 0,0x28,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x28,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x28,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x28,0xFF,0xFF,0xFF,0xA0, 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, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0xBC,0xFF,0xFF,0xE4, 0, 0, 0,0x7C,0xFF,0xFF,0xFF,0x24, 0, 0, + 0, 0, 0,0xBC,0xFF,0xFF,0xE4, 0, 0, 0,0x7C,0xFF,0xFF,0xFF,0x24, 0, 0, + 0, 0, 0,0xBC,0xFF,0xFF,0xE4, 0, 0, 0,0x7C,0xFF,0xFF,0xFF,0x24, 0, 0, + 0, 0, 0,0xBC,0xFF,0xFF,0xE4, 0, 0, 0,0x7C,0xFF,0xFF,0xFF,0x24, 0, 0, + 0, 0, 0,0xBC,0xFF,0xFF,0xE4, 0, 0, 0,0x7C,0xFF,0xFF,0xFF,0x24, 0, 0, + 0, 0, 0,0xBC,0xFF,0xFF,0xE4, 0, 0, 0,0x7C,0xFF,0xFF,0xFF,0x24, 0, 0, + 0, 0, 0,0xBC,0xFF,0xFF,0xE4, 0, 0, 0,0x7C,0xFF,0xFF,0xFF,0x24, 0, 0, + 0, 0, 0,0xBC,0xFF,0xFF,0xE4, 0, 0, 0,0x7C,0xFF,0xFF,0xFF,0x24, 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, 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, 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, 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, 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, + 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0, 0,0x43,0xFF,0xFF,0xE1, 0, 0,0x43,0xFF,0xFF,0xE7, 0, + 0, 0, 0, 0, 0, 0,0x87,0xFF,0xFF,0x9C, 0, 0,0x87,0xFF,0xFF,0xA2, 0, + 0, 0, 0, 0, 0, 0,0xCC,0xFF,0xFF,0x57, 0, 0,0xCB,0xFF,0xFF,0x5B, 0, + 0, 0, 0, 0, 0,0x13,0xFD,0xFF,0xFE,0x14, 0,0x11,0xFD,0xFF,0xFE,0x16, 0, + 0, 0, 0, 0, 0,0x56,0xFF,0xFF,0xCE, 0, 0,0x52,0xFF,0xFF,0xCF, 0, 0, + 0,0x58,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0,0x58,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0,0x58,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0, 0, 0, 0,0x5F,0xFF,0xFF,0xC1, 0, 0,0x56,0xFF,0xFF,0xC9, 0, 0, 0, + 0, 0, 0, 0,0xA3,0xFF,0xFF,0x7E, 0, 0,0x99,0xFF,0xFF,0x86, 0, 0, 0, + 0, 0, 0, 0,0xE5,0xFF,0xFF,0x3B, 0, 0,0xDC,0xFF,0xFF,0x43, 0, 0, 0, + 0, 0, 0,0x2A,0xFF,0xFF,0xF4,0x05, 0,0x1E,0xFF,0xFF,0xF8,0x08, 0, 0, 0, +0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC8, 0, +0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC8, 0, +0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC8, 0, + 0, 0,0x2F,0xFF,0xFF,0xF1,0x04, 0,0x27,0xFF,0xFF,0xF6,0x07, 0, 0, 0, 0, + 0, 0,0x73,0xFF,0xFF,0xB1, 0, 0,0x6B,0xFF,0xFF,0xB9, 0, 0, 0, 0, 0, + 0, 0,0xB7,0xFF,0xFF,0x6D, 0, 0,0xAF,0xFF,0xFF,0x75, 0, 0, 0, 0, 0, + 0,0x05,0xF4,0xFF,0xFF,0x29, 0,0x03,0xEF,0xFF,0xFF,0x31, 0, 0, 0, 0, 0, + 0,0x3E,0xFF,0xFF,0xE5, 0, 0,0x36,0xFF,0xFF,0xEC,0x01, 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, 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, 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, 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, +// '$' + 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, 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, 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,0x2C,0xFF,0xD4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x2C,0xFF,0xD5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x2C,0xFF,0xD7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0x0E,0x79,0xCA,0xF4,0xFF,0xFF,0xE6,0xBF,0x81,0x32, 0, 0, 0, + 0, 0, 0,0x2A,0xE2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x24, 0, 0, + 0, 0,0x05,0xDB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x24, 0, 0, + 0, 0,0x58,0xFF,0xFF,0xFF,0xB5,0x46,0xFF,0xD4,0x1F,0x63,0xD0,0xFF,0x24, 0, 0, + 0, 0,0x94,0xFF,0xFF,0xFF,0x2A,0x2C,0xFF,0xD4, 0, 0,0x02,0x7A,0x21, 0, 0, + 0, 0,0xA7,0xFF,0xFF,0xFF,0x1B,0x2C,0xFF,0xD4, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x96,0xFF,0xFF,0xFF,0x6B,0x2C,0xFF,0xD4, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x58,0xFF,0xFF,0xFF,0xFB,0xA8,0xFF,0xD5, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x05,0xD8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEA,0xA6,0x3F, 0, 0, 0, 0, + 0, 0, 0,0x25,0xDB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA0,0x06, 0, 0, + 0, 0, 0, 0,0x09,0x76,0xDA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x91, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x43,0xFF,0xEF,0xD6,0xFF,0xFF,0xFF,0xFB,0x1A, 0, + 0, 0, 0, 0, 0, 0, 0,0x2C,0xFF,0xD4,0x04,0xB8,0xFF,0xFF,0xFF,0x5A, 0, + 0, 0, 0, 0, 0, 0, 0,0x2C,0xFF,0xD4, 0,0x59,0xFF,0xFF,0xFF,0x72, 0, + 0, 0,0x77,0x5F,0x02, 0, 0,0x2C,0xFF,0xD4, 0,0x6D,0xFF,0xFF,0xFF,0x62, 0, + 0, 0,0x90,0xFF,0xDB,0x76,0x2D,0x35,0xFF,0xD5,0x3C,0xE5,0xFF,0xFF,0xFF,0x24, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA3, 0, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xB9,0x0A, 0, 0, + 0, 0,0x0A,0x46,0x88,0xBE,0xDC,0xF7,0xFF,0xFF,0xEC,0xB9,0x5A,0x02, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x30,0xFF,0xD6, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x2F,0xFF,0xD5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x2E,0xFF,0xD4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x2D,0xFF,0xD4, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, + 0, 0,0x40,0xBD,0xF4,0xF2,0xB9,0x39, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x5E,0xFD,0xFF,0xFF,0xFF,0xFF,0xFB,0x53, 0, 0, 0, 0, 0, 0, 0, 0, +0x18,0xF5,0xFF,0xCD,0x22,0x26,0xD4,0xFF,0xF2,0x14, 0, 0, 0, 0, 0, 0, 0, +0x67,0xFF,0xFF,0x3E, 0, 0,0x47,0xFF,0xFF,0x61, 0, 0, 0, 0, 0, 0, 0, +0x82,0xFF,0xFF,0x15, 0, 0,0x1D,0xFF,0xFF,0x7D, 0, 0, 0, 0, 0, 0, 0, +0x68,0xFF,0xFF,0x3E, 0, 0,0x46,0xFF,0xFF,0x62, 0, 0, 0, 0, 0, 0, 0, +0x19,0xF6,0xFF,0xCD,0x22,0x24,0xD2,0xFF,0xF2,0x14, 0, 0, 0, 0, 0,0x02, 0, + 0,0x60,0xFD,0xFF,0xFF,0xFF,0xFF,0xFC,0x57, 0, 0, 0, 0,0x19,0x7C,0xE1,0x45, + 0, 0,0x42,0xBE,0xF5,0xF3,0xBB,0x3C, 0, 0,0x01,0x47,0xAE,0xFB,0xD4,0x6F,0x11, + 0, 0, 0, 0, 0, 0, 0, 0,0x17,0x78,0xDE,0xF5,0xA0,0x3A, 0, 0, 0, + 0, 0, 0, 0, 0,0x01,0x43,0xAA,0xFA,0xD0,0x6B,0x0F, 0, 0, 0, 0, 0, + 0, 0, 0,0x15,0x75,0xDB,0xF4,0x9C,0x37, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x3A,0xA7,0xF9,0xCD,0x68,0x0D, 0, 0, 0,0x67,0xD1,0xF8,0xE9,0x9F,0x1C, 0, + 0,0x6F,0x99,0x32, 0, 0, 0, 0, 0,0x9A,0xFF,0xFF,0xFF,0xFF,0xFF,0xE9,0x25, + 0, 0, 0, 0, 0, 0, 0, 0,0x4D,0xFF,0xFF,0xA0,0x12,0x49,0xF3,0xFF,0xC6, + 0, 0, 0, 0, 0, 0, 0, 0,0xA7,0xFF,0xF3,0x0B, 0, 0,0x89,0xFF,0xFF, + 0, 0, 0, 0, 0, 0, 0, 0,0xC2,0xFF,0xD5, 0, 0, 0,0x5D,0xFF,0xFF, + 0, 0, 0, 0, 0, 0, 0, 0,0xA8,0xFF,0xF2,0x09, 0, 0,0x87,0xFF,0xFF, + 0, 0, 0, 0, 0, 0, 0, 0,0x4F,0xFF,0xFF,0x9B,0x11,0x46,0xF2,0xFF,0xC7, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0x9E,0xFF,0xFF,0xFF,0xFF,0xFF,0xEB,0x27, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0x01,0x69,0xD2,0xF9,0xEA,0xA1,0x1E, 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, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0x01,0x56,0xB0,0xE2,0xF7,0xF8,0xDA,0x95,0x36, 0, 0, 0, 0, + 0, 0, 0,0x07,0xB7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, + 0, 0, 0,0x7B,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, + 0, 0, 0,0xCF,0xFF,0xFF,0xFF,0x98,0x1B,0x08,0x26,0x5D,0xC4,0x13, 0, 0, 0, + 0, 0, 0,0xE1,0xFF,0xFF,0xFF,0x29, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0xB6,0xFF,0xFF,0xFF,0x75, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0x52,0xFF,0xFF,0xFF,0xF0,0x19, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0xC3,0xFF,0xFF,0xFF,0xB8, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0x5D,0xF5,0xFF,0xFF,0xFF,0xFF,0x66, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x77,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF1,0x1D, 0, 0, 0, 0, 0, 0, + 0,0x45,0xFD,0xFF,0xFF,0xCB,0xA3,0xFF,0xFF,0xFF,0xB7, 0, 0,0x18,0xFF,0xFF,0xFF, + 0,0xCB,0xFF,0xFF,0xE9,0x14,0x0E,0xE6,0xFF,0xFF,0xFF,0x60, 0,0x0B,0xFF,0xFF,0xFF, +0x2E,0xFF,0xFF,0xFF,0x89, 0, 0,0x55,0xFF,0xFF,0xFF,0xEF,0x19,0x1D,0xFF,0xFF,0xFF, +0x59,0xFF,0xFF,0xFF,0x5F, 0, 0, 0,0xB5,0xFF,0xFF,0xFF,0xB1,0x48,0xFF,0xFF,0xEA, +0x71,0xFF,0xFF,0xFF,0x6B, 0, 0, 0,0x20,0xF5,0xFF,0xFF,0xFF,0xDB,0xFF,0xFF,0xAF, +0x5F,0xFF,0xFF,0xFF,0xB1, 0, 0, 0, 0,0x76,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x4F, +0x25,0xFF,0xFF,0xFF,0xFE,0x46, 0, 0, 0,0x04,0xD1,0xFF,0xFF,0xFF,0xFF,0xC7,0x02, + 0,0xBE,0xFF,0xFF,0xFF,0xF5,0x6E,0x15,0x09,0x44,0xCB,0xFF,0xFF,0xFF,0xFF,0x5A, 0, + 0,0x27,0xEE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD8,0x07, + 0, 0,0x31,0xDD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x85, + 0, 0, 0,0x09,0x69,0xBB,0xEA,0xFB,0xF3,0xD3,0x94,0x3C,0x55,0xFF,0xFF,0xFF,0xFA, + 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, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0x84, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0x84, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0x84, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0x84, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0x84, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0x84, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0x84, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0x84, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0,0x77,0xFF,0xFF,0xD4,0x01, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,0x23,0xF6,0xFF,0xFF,0x5A, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,0xAE,0xFF,0xFF,0xDB,0x03, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x37,0xFF,0xFF,0xFF,0x69, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFA,0x13, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x1E,0xFD,0xFF,0xFF,0xB3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x7C,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xCB,0xFF,0xFF,0xFF,0x1F, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x0F,0xFE,0xFF,0xFF,0xE8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x42,0xFF,0xFF,0xFF,0xB2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x68,0xFF,0xFF,0xFF,0x95, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x83,0xFF,0xFF,0xFF,0x82, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x8F,0xFF,0xFF,0xFF,0x70, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x8F,0xFF,0xFF,0xFF,0x71, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x83,0xFF,0xFF,0xFF,0x83, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x68,0xFF,0xFF,0xFF,0x95, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x41,0xFF,0xFF,0xFF,0xB4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x0E,0xFE,0xFF,0xFF,0xE9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xCA,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x7A,0xFF,0xFF,0xFF,0x5D, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x1D,0xFD,0xFF,0xFF,0xB5, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xAF,0xFF,0xFF,0xFB,0x14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x35,0xFF,0xFF,0xFF,0x6B, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,0xAD,0xFF,0xFF,0xDC,0x03, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,0x22,0xF6,0xFF,0xFF,0x5A, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0x76,0xFF,0xFF,0xD4,0x01, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0x62,0xFF,0xFF,0xE1,0x0C, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0x05,0xE0,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x69,0xFF,0xFF,0xFB,0x28, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x07,0xEC,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x97,0xFF,0xFF,0xFD,0x27, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x3D,0xFF,0xFF,0xFF,0x8F, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x01,0xE3,0xFF,0xFF,0xEB,0x03, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x3E, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x71,0xFF,0xFF,0xFF,0x80, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x3B,0xFF,0xFF,0xFF,0xB6, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x1E,0xFF,0xFF,0xFF,0xDB, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x0B,0xFF,0xFF,0xFF,0xF6, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,0xF8,0xFF,0xFF,0xFF,0x03, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,0xF9,0xFF,0xFF,0xFF,0x02, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x0C,0xFF,0xFF,0xFF,0xF5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x1E,0xFF,0xFF,0xFF,0xDA, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF,0xB5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x73,0xFF,0xFF,0xFF,0x7F, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xA9,0xFF,0xFF,0xFF,0x3C, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x01,0xE4,0xFF,0xFF,0xEA,0x03, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x3E,0xFF,0xFF,0xFF,0x8F, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x98,0xFF,0xFF,0xFD,0x27, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x07,0xEC,0xFF,0xFF,0xAB, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x6A,0xFF,0xFF,0xFB,0x27, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0x05,0xE0,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0x62,0xFF,0xFF,0xE1,0x0C, 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, 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, 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, + 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, 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, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x84,0xFF,0xE8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x84,0xFF,0xE8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x84,0xFF,0xE8, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x7E,0xA7,0x2A, 0, 0,0x84,0xFF,0xE8, 0, 0,0x0B,0x74,0xC7,0x09, 0, + 0,0x15,0xF6,0xFF,0xFD,0xAA,0x2D,0x84,0xFF,0xE8,0x0D,0x78,0xEB,0xFF,0xFF,0x73, 0, + 0, 0,0x2B,0xA2,0xFB,0xFF,0xFE,0xE8,0xFF,0xF9,0xED,0xFF,0xFF,0xD2,0x5B,0x03, 0, + 0, 0, 0, 0,0x1E,0x92,0xF5,0xFF,0xFF,0xFF,0xFF,0xC5,0x4D,0x01, 0, 0, 0, + 0, 0, 0, 0,0x1E,0x91,0xF5,0xFF,0xFF,0xFF,0xFF,0xC5,0x4C,0x01, 0, 0, 0, + 0, 0,0x2A,0xA1,0xFB,0xFF,0xFD,0xE4,0xFF,0xF8,0xE9,0xFF,0xFF,0xD2,0x5A,0x03, 0, + 0,0x15,0xF6,0xFF,0xFD,0xA7,0x28,0x84,0xFF,0xE8,0x0A,0x74,0xE9,0xFF,0xFF,0x73, 0, + 0, 0,0x7E,0xA7,0x28, 0, 0,0x84,0xFF,0xE8, 0, 0,0x0A,0x73,0xC8,0x09, 0, + 0, 0, 0, 0, 0, 0, 0,0x84,0xFF,0xE8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x84,0xFF,0xE8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x84,0xFF,0xE8, 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, 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, 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, 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, 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, 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, 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, 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, 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, + 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, 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, 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, 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, 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, 0, 0, 0, 0, 0,0xF4,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xF4,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xF4,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xF4,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xF4,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xF4,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, 0, +0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80, +0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80, +0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80, + 0, 0, 0, 0, 0, 0, 0,0xF4,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xF4,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xF4,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xF4,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xF4,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xF4,0xFF,0xFF,0x68, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, + 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, 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,0x78,0xFF,0xFF,0xFF,0xF4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x78,0xFF,0xFF,0xFF,0xF4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x78,0xFF,0xFF,0xFF,0xF4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x7A,0xFF,0xFF,0xFF,0xEF, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xAD,0xFF,0xFF,0xFF,0x8C, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x02,0xEE,0xFF,0xFF,0xF2,0x14, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x35,0xFF,0xFF,0xFF,0x7F, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x7A,0xFF,0xFF,0xEB,0x0D, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0xBE,0xFF,0xFF,0x73, 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, 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, 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, + 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, 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, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0xBC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x34, 0, 0, 0, + 0, 0, 0, 0,0xBC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x34, 0, 0, 0, + 0, 0, 0, 0,0xBC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x34, 0, 0, 0, + 0, 0, 0, 0,0xBC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x34, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 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, 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, 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, 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, +// '/' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x80,0xFF,0xFF,0xA0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x0A,0xEB,0xFF,0xFE,0x2B, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x6D,0xFF,0xFF,0xB2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x04,0xDF,0xFF,0xFF,0x3C, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x5B,0xFF,0xFF,0xC5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xD1,0xFF,0xFF,0x4E, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0x49,0xFF,0xFF,0xD7,0x01, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0xBF,0xFF,0xFF,0x61, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,0x36,0xFF,0xFF,0xE4,0x06, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,0xAD,0xFF,0xFF,0x74, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x26,0xFD,0xFF,0xF0,0x0D, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x9B,0xFF,0xFF,0x86, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x18,0xF8,0xFF,0xF8,0x18, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x88,0xFF,0xFF,0x99, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x0E,0xF0,0xFF,0xFD,0x25, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x76,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0x06,0xE6,0xFF,0xFF,0x36, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0x64,0xFF,0xFF,0xBE, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0x02,0xD8,0xFF,0xFF,0x48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0x51,0xFF,0xFF,0xD1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0xC8,0xFF,0xFF,0x5A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x3F,0xFF,0xFF,0xE0,0x04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xB6,0xFF,0xFF,0x6D, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x2D,0xFF,0xFF,0xEC,0x0A, 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, 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, + 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, 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, 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, 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, 0,0x39,0xA2,0xE0,0xF8,0xEB,0xC5,0x6F,0x07, 0, 0, 0, 0, + 0, 0, 0, 0,0x81,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD3,0x1C, 0, 0, 0, + 0, 0, 0,0x66,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xCF,0x06, 0, 0, + 0, 0,0x0E,0xED,0xFF,0xFF,0xFF,0x80,0x0D,0x33,0xE0,0xFF,0xFF,0xFF,0x6C, 0, 0, + 0, 0,0x69,0xFF,0xFF,0xFF,0xC2, 0, 0, 0,0x4D,0xFF,0xFF,0xFF,0xDA, 0, 0, + 0, 0,0xB5,0xFF,0xFF,0xFF,0x69, 0, 0, 0,0x04,0xF0,0xFF,0xFF,0xFF,0x28, 0, + 0, 0,0xEC,0xFF,0xFF,0xFF,0x36, 0, 0, 0, 0,0xC1,0xFF,0xFF,0xFF,0x5F, 0, + 0,0x14,0xFF,0xFF,0xFF,0xFF,0x15, 0, 0, 0, 0,0x9F,0xFF,0xFF,0xFF,0x86, 0, + 0,0x2E,0xFF,0xFF,0xFF,0xFE,0x03,0x61,0xEF,0xBE,0x0B,0x8B,0xFF,0xFF,0xFF,0xA0, 0, + 0,0x39,0xFF,0xFF,0xFF,0xF9, 0,0xEF,0xFF,0xFF,0x67,0x83,0xFF,0xFF,0xFF,0xAC, 0, + 0,0x41,0xFF,0xFF,0xFF,0xF5, 0,0xF0,0xFF,0xFF,0x68,0x7E,0xFF,0xFF,0xFF,0xB5, 0, + 0,0x39,0xFF,0xFF,0xFF,0xF9, 0,0x64,0xEF,0xBE,0x0C,0x83,0xFF,0xFF,0xFF,0xAC, 0, + 0,0x2E,0xFF,0xFF,0xFF,0xFE,0x03, 0, 0, 0, 0,0x8B,0xFF,0xFF,0xFF,0xA0, 0, + 0,0x14,0xFF,0xFF,0xFF,0xFF,0x15, 0, 0, 0, 0,0x9F,0xFF,0xFF,0xFF,0x86, 0, + 0, 0,0xEC,0xFF,0xFF,0xFF,0x36, 0, 0, 0, 0,0xC1,0xFF,0xFF,0xFF,0x5F, 0, + 0, 0,0xB5,0xFF,0xFF,0xFF,0x68, 0, 0, 0,0x04,0xF0,0xFF,0xFF,0xFF,0x28, 0, + 0, 0,0x69,0xFF,0xFF,0xFF,0xC0, 0, 0, 0,0x4C,0xFF,0xFF,0xFF,0xDB, 0, 0, + 0, 0,0x0E,0xED,0xFF,0xFF,0xFF,0x7E,0x0C,0x32,0xDF,0xFF,0xFF,0xFF,0x6D, 0, 0, + 0, 0, 0,0x66,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD2,0x07, 0, 0, + 0, 0, 0, 0,0x81,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD5,0x1D, 0, 0, 0, + 0, 0, 0, 0, 0,0x39,0xA3,0xE0,0xF8,0xED,0xC6,0x70,0x07, 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, 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, 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, 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, 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, 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, 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,0x1D,0x58,0x92,0xCD,0xFC,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, + 0, 0,0x04,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, + 0, 0,0x04,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, + 0, 0,0x04,0xE2,0xA7,0x6C,0x31,0xAF,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xAC,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xAC,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xAC,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xAC,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xAC,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xAC,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xAC,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xAC,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xAC,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xAC,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xAC,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xAC,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xAC,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xAC,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, + 0, 0,0x58,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x14, + 0, 0,0x58,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x14, + 0, 0,0x58,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x14, + 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, 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, 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, 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, +// '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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x1A,0x59,0x99,0xCC,0xEC,0xFB,0xF4,0xDE,0xAB,0x55,0x04, 0, 0, 0, 0, + 0, 0,0xEC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xCD,0x22, 0, 0, 0, + 0, 0,0xEC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE1,0x11, 0, 0, + 0, 0,0xEC,0xFF,0xBB,0x5E,0x1E,0x08,0x24,0x8C,0xFF,0xFF,0xFF,0xFF,0x89, 0, 0, + 0, 0,0xAD,0x32, 0, 0, 0, 0, 0, 0,0x9B,0xFF,0xFF,0xFF,0xDC, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x4C,0xFF,0xFF,0xFF,0xFC,0x02, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x42,0xFF,0xFF,0xFF,0xF9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x81,0xFF,0xFF,0xFF,0xD0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0x12,0xEC,0xFF,0xFF,0xFF,0x7A, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0xAE,0xFF,0xFF,0xFF,0xE7,0x0E, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,0x7D,0xFF,0xFF,0xFF,0xFE,0x4B, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x5F,0xFF,0xFF,0xFF,0xFF,0x77, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x4A,0xFB,0xFF,0xFF,0xFF,0x89, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x38,0xF5,0xFF,0xFF,0xFF,0x93, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0x2A,0xED,0xFF,0xFF,0xFF,0x98,0x01, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0x1E,0xE3,0xFF,0xFF,0xFF,0x9B,0x01, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x13,0xD7,0xFF,0xFF,0xFF,0x9D,0x01, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x0B,0xC9,0xFF,0xFF,0xFF,0xA0,0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x5F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x0C, 0, + 0,0x60,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x0C, 0, + 0,0x60,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x0C, 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, 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, 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, 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, +// '3' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x0B,0x47,0x88,0xC2,0xE7,0xF9,0xF9,0xE8,0xBE,0x79,0x18, 0, 0, 0, 0, + 0, 0,0x98,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF3,0x5E, 0, 0, 0, + 0, 0,0x98,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x4A, 0, 0, + 0, 0,0x98,0xFF,0xD6,0x70,0x29,0x08,0x17,0x58,0xE4,0xFF,0xFF,0xFF,0xCB, 0, 0, + 0, 0,0x7D,0x59,0x01, 0, 0, 0, 0, 0,0x3E,0xFF,0xFF,0xFF,0xFE,0x05, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x04,0xFD,0xFF,0xFF,0xFF,0x0B, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x32,0xFF,0xFF,0xFF,0xD8, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,0x14,0x50,0xDC,0xFF,0xFF,0xFF,0x59, 0, 0, + 0, 0, 0, 0, 0,0x78,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEA,0x52, 0, 0, 0, + 0, 0, 0, 0, 0,0x78,0xFF,0xFF,0xFF,0xFF,0xFF,0xB1,0x24, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x78,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0x90,0x03, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x01,0x1C,0x5A,0xE3,0xFF,0xFF,0xFF,0x97, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x23,0xF7,0xFF,0xFF,0xFE,0x27, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0x70, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x7D,0xFF,0xFF,0xFF,0x8D, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x93,0xFF,0xFF,0xFF,0x84, 0, + 0,0x37,0x89,0x0C, 0, 0, 0, 0, 0, 0,0x14,0xE6,0xFF,0xFF,0xFF,0x5E, 0, + 0,0x3C,0xFF,0xF0,0x92,0x4B,0x1B,0x07,0x16,0x4E,0xD5,0xFF,0xFF,0xFF,0xF5,0x14, 0, + 0,0x3C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x73, 0, 0, + 0,0x3C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF8,0x76, 0, 0, 0, + 0,0x01,0x30,0x70,0xAF,0xD0,0xE4,0xF7,0xF8,0xE7,0xBD,0x7C,0x1D, 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, 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, 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, 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, +// '4' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,0x08,0xD8,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,0x8B,0xFF,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x37,0xFC,0xFF,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x07,0xD6,0xFF,0xFF,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x88,0xFF,0xFF,0xF5,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, + 0, 0, 0, 0, 0,0x35,0xFC,0xFF,0xFF,0x73,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, + 0, 0, 0, 0,0x06,0xD4,0xFF,0xFF,0xA3,0x2C,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, + 0, 0, 0, 0,0x85,0xFF,0xFF,0xEB,0x14,0x2C,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, + 0, 0, 0,0x32,0xFB,0xFF,0xFF,0x5C, 0,0x2C,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, + 0, 0,0x05,0xD2,0xFF,0xFF,0xB8, 0, 0,0x2C,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, + 0, 0,0x82,0xFF,0xFF,0xF4,0x20, 0, 0,0x2C,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, + 0,0x30,0xFA,0xFF,0xFF,0x71, 0, 0, 0,0x2C,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, + 0,0x8F,0xFF,0xFF,0xCA,0x03, 0, 0, 0,0x2C,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, + 0,0x90,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x28, + 0,0x90,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x28, + 0,0x90,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x28, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0x2C,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0x2C,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0x2C,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0x2C,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0x2C,0xFF,0xFF,0xFF,0xD4, 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, 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, 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, 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, +// '5' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x44,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x38, 0, 0, + 0, 0,0x44,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x38, 0, 0, + 0, 0,0x44,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x38, 0, 0, + 0, 0,0x44,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x44,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x44,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x44,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x44,0xFF,0xFF,0xFF,0xCC,0xEF,0xFA,0xE9,0xB9,0x65,0x05, 0, 0, 0, 0, + 0, 0,0x44,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD5,0x25, 0, 0, 0, + 0, 0,0x44,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE4,0x18, 0, 0, + 0, 0,0x41,0xBF,0x6B,0x32,0x16,0x07,0x29,0x8E,0xFD,0xFF,0xFF,0xFF,0xA6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x64,0xFF,0xFF,0xFF,0xFE,0x17, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xD6,0xFF,0xFF,0xFF,0x55, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x9F,0xFF,0xFF,0xFF,0x71, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x9F,0xFF,0xFF,0xFF,0x70, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xD1,0xFF,0xFF,0xFF,0x53, 0, + 0, 0,0x9F,0x0F, 0, 0, 0, 0, 0, 0,0x56,0xFF,0xFF,0xFF,0xFC,0x13, 0, + 0, 0,0xF8,0xEC,0x80,0x30,0x0A,0x08,0x2D,0x89,0xFA,0xFF,0xFF,0xFF,0x9B, 0, 0, + 0, 0,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD6,0x12, 0, 0, + 0, 0,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xB8,0x17, 0, 0, 0, + 0, 0,0x20,0x64,0xA7,0xCF,0xE6,0xFA,0xF1,0xD5,0x9C,0x40, 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, 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, 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, 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, +// '6' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x3D,0x94,0xD3,0xEC,0xF8,0xDD,0xB4,0x60,0x0E, 0, 0, + 0, 0, 0, 0,0x0F,0xB0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x94, 0, 0, + 0, 0, 0,0x0C,0xCE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x94, 0, 0, + 0, 0, 0,0x91,0xFF,0xFF,0xFF,0xE3,0x62,0x19,0x07,0x2D,0x91,0xFA,0x94, 0, 0, + 0, 0,0x1A,0xFC,0xFF,0xFF,0xE7,0x1B, 0, 0, 0, 0, 0,0x30,0x72, 0, 0, + 0, 0,0x75,0xFF,0xFF,0xFF,0x66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xB9,0xFF,0xFF,0xFE,0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xE8,0xFF,0xFF,0xDF,0x18,0x90,0xDA,0xF7,0xF3,0xD0,0x81,0x0F, 0, 0, 0, + 0,0x08,0xFF,0xFF,0xFF,0xE5,0xE6,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x24, 0, 0, + 0,0x17,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD1,0x04, 0, + 0,0x21,0xFF,0xFF,0xFF,0xFF,0xFF,0x93,0x17,0x0C,0x6A,0xFC,0xFF,0xFF,0xFF,0x55, 0, + 0,0x19,0xFF,0xFF,0xFF,0xFF,0xD3, 0, 0, 0, 0,0x9B,0xFF,0xFF,0xFF,0xA2, 0, + 0,0x0E,0xFF,0xFF,0xFF,0xFF,0x7B, 0, 0, 0, 0,0x41,0xFF,0xFF,0xFF,0xCE, 0, + 0,0x01,0xF6,0xFF,0xFF,0xFF,0x5D, 0, 0, 0, 0,0x22,0xFF,0xFF,0xFF,0xDE, 0, + 0, 0,0xD2,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0,0x22,0xFF,0xFF,0xFF,0xD6, 0, + 0, 0,0xA1,0xFF,0xFF,0xFF,0x7B, 0, 0, 0, 0,0x41,0xFF,0xFF,0xFF,0xBD, 0, + 0, 0,0x55,0xFF,0xFF,0xFF,0xD3, 0, 0, 0, 0,0x9B,0xFF,0xFF,0xFF,0x85, 0, + 0, 0,0x09,0xE5,0xFF,0xFF,0xFF,0x92,0x15,0x0C,0x69,0xFC,0xFF,0xFF,0xFE,0x27, 0, + 0, 0, 0,0x5B,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x95, 0, 0, + 0, 0, 0, 0,0x73,0xFA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA7,0x07, 0, 0, + 0, 0, 0, 0, 0,0x29,0x91,0xD6,0xF1,0xF9,0xE4,0xAC,0x49, 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, 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, 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, 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, +// '7' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x18,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x48, 0, + 0,0x18,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x48, 0, + 0,0x18,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x47, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x75,0xFF,0xFF,0xFF,0xF9,0x15, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xD6,0xFF,0xFF,0xFF,0xA8, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0x39,0xFF,0xFF,0xFF,0xFF,0x43, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0x9B,0xFF,0xFF,0xFF,0xDC,0x01, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,0x0A,0xF1,0xFF,0xFF,0xFF,0x78, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,0x5E,0xFF,0xFF,0xFF,0xFA,0x17, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,0xC0,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x22,0xFE,0xFF,0xFF,0xFF,0x47, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x84,0xFF,0xFF,0xFF,0xDF,0x02, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x02,0xE2,0xFF,0xFF,0xFF,0x7B, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x47,0xFF,0xFF,0xFF,0xFB,0x1A, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xA9,0xFF,0xFF,0xFF,0xB0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x12,0xF8,0xFF,0xFF,0xFF,0x4A, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x6C,0xFF,0xFF,0xFF,0xE2,0x02, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0xCE,0xFF,0xFF,0xFF,0x7F, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0x2F,0xFF,0xFF,0xFF,0xFC,0x1C, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0x92,0xFF,0xFF,0xFF,0xB4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0x06,0xEC,0xFF,0xFF,0xFF,0x4E, 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, 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, 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, + 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, 0, 0, 0, +// '8' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0x09,0x6A,0xBC,0xE9,0xFA,0xF2,0xD3,0x94,0x2B, 0, 0, 0, 0, + 0, 0, 0,0x25,0xDA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0x74, 0, 0, 0, + 0, 0,0x08,0xDC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x56, 0, 0, + 0, 0,0x5F,0xFF,0xFF,0xFF,0xE0,0x47,0x0C,0x1F,0x99,0xFF,0xFF,0xFF,0xD1, 0, 0, + 0, 0,0x97,0xFF,0xFF,0xFF,0x49, 0, 0, 0,0x01,0xD0,0xFF,0xFF,0xFF,0x0A, 0, + 0, 0,0x9C,0xFF,0xFF,0xFF,0x1A, 0, 0, 0, 0,0xA3,0xFF,0xFF,0xFF,0x0F, 0, + 0, 0,0x72,0xFF,0xFF,0xFF,0x4B, 0, 0, 0,0x01,0xD1,0xFF,0xFF,0xE5, 0, 0, + 0, 0,0x11,0xEE,0xFF,0xFF,0xE0,0x46,0x0B,0x1F,0x98,0xFF,0xFF,0xFF,0x71, 0, 0, + 0, 0, 0,0x31,0xE1,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0x8A,0x01, 0, 0, + 0, 0, 0, 0,0x1C,0xD2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x6E, 0, 0, 0, 0, + 0, 0, 0,0x56,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBB,0x0A, 0, 0, + 0, 0,0x3D,0xFC,0xFF,0xFF,0xDF,0x49,0x0E,0x26,0x9B,0xFF,0xFF,0xFF,0xAF, 0, 0, + 0, 0,0xBE,0xFF,0xFF,0xFB,0x29, 0, 0, 0, 0,0xB1,0xFF,0xFF,0xFF,0x35, 0, + 0,0x06,0xFD,0xFF,0xFF,0xBE, 0, 0, 0, 0, 0,0x4B,0xFF,0xFF,0xFF,0x7A, 0, + 0,0x23,0xFF,0xFF,0xFF,0xA1, 0, 0, 0, 0, 0,0x2E,0xFF,0xFF,0xFF,0x9A, 0, + 0,0x1C,0xFF,0xFF,0xFF,0xBF, 0, 0, 0, 0, 0,0x4C,0xFF,0xFF,0xFF,0x92, 0, + 0,0x03,0xF0,0xFF,0xFF,0xFB,0x29, 0, 0, 0, 0,0xB5,0xFF,0xFF,0xFF,0x6A, 0, + 0, 0,0xA2,0xFF,0xFF,0xFF,0xDF,0x49,0x0E,0x25,0x9D,0xFF,0xFF,0xFF,0xFA,0x1E, 0, + 0, 0,0x23,0xF1,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8C, 0, 0, + 0, 0, 0,0x3E,0xE8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x9A,0x03, 0, 0, + 0, 0, 0, 0,0x10,0x74,0xC0,0xEB,0xFB,0xF3,0xD8,0x9E,0x3A, 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, 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, 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, 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, +// '9' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0x17,0x86,0xCE,0xF0,0xF8,0xE4,0xB4,0x60,0x03, 0, 0, 0, 0, + 0, 0, 0,0x47,0xF1,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xCC,0x16, 0, 0, 0, + 0, 0,0x2B,0xF6,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xCD,0x04, 0, 0, + 0, 0,0xB2,0xFF,0xFF,0xFF,0xBC,0x26,0x07,0x49,0xEB,0xFF,0xFF,0xFF,0x66, 0, 0, + 0,0x11,0xFD,0xFF,0xFF,0xF7,0x14, 0, 0, 0,0x64,0xFF,0xFF,0xFF,0xCD, 0, 0, + 0,0x47,0xFF,0xFF,0xFF,0xB3, 0, 0, 0, 0,0x0C,0xFF,0xFF,0xFF,0xFF,0x1A, 0, + 0,0x60,0xFF,0xFF,0xFF,0x95, 0, 0, 0, 0, 0,0xED,0xFF,0xFF,0xFF,0x49, 0, + 0,0x67,0xFF,0xFF,0xFF,0x94, 0, 0, 0, 0, 0,0xEE,0xFF,0xFF,0xFF,0x70, 0, + 0,0x57,0xFF,0xFF,0xFF,0xB3, 0, 0, 0, 0,0x0C,0xFF,0xFF,0xFF,0xFF,0x85, 0, + 0,0x2B,0xFF,0xFF,0xFF,0xF7,0x14, 0, 0, 0,0x64,0xFF,0xFF,0xFF,0xFF,0x90, 0, + 0,0x01,0xDD,0xFF,0xFF,0xFF,0xBC,0x25,0x06,0x48,0xEB,0xFF,0xFF,0xFF,0xFF,0x98, 0, + 0, 0,0x60,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8D, 0, + 0, 0, 0,0x91,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD4,0xFF,0xFF,0xFF,0x7F, 0, + 0, 0, 0, 0,0x49,0xB2,0xE9,0xFB,0xED,0xBC,0x56,0x69,0xFF,0xFF,0xFF,0x5E, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x97,0xFF,0xFF,0xFF,0x2F, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x06,0xE7,0xFF,0xFF,0xE7,0x03, 0, + 0, 0,0x1E,0x7E,0x01, 0, 0, 0, 0, 0,0x89,0xFF,0xFF,0xFF,0x8C, 0, 0, + 0, 0,0x20,0xFF,0xC9,0x4F,0x0F,0x0A,0x36,0xA4,0xFF,0xFF,0xFF,0xEE,0x17, 0, 0, + 0, 0,0x20,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0x53, 0, 0, 0, + 0, 0,0x20,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE7,0x4C, 0, 0, 0, 0, + 0, 0, 0,0x39,0x93,0xD0,0xEF,0xF6,0xE2,0xB5,0x6B,0x0B, 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, 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, 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, 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, +// ':' + 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, 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, 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, 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, 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, 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 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, 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, 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, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 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, 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, 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, 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, +// ';' + 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, 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, 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, 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, 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, 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 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, 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, 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, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xA5,0xFF,0xFF,0xFF,0xFF,0x10, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xCE,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x08,0xFA,0xFF,0xFF,0xFC,0x28, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x3A,0xFF,0xFF,0xFF,0x9D, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x70,0xFF,0xFF,0xF8,0x1E, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0xA5,0xFF,0xFF,0x8F, 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, 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, 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, + 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, 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, 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, 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, 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,0x05,0x54,0xB8,0x35, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x28,0x8C,0xEA,0xFF,0xFF,0x38, + 0, 0, 0, 0, 0, 0, 0, 0,0x0A,0x60,0xC4,0xFF,0xFF,0xFF,0xFF,0xFF,0x38, + 0, 0, 0, 0, 0, 0,0x34,0x98,0xF1,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC5,0x1F, + 0, 0, 0,0x11,0x6C,0xD0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD6,0x7B,0x21, 0, 0, + 0,0x39,0xA4,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF,0xE4,0x8C,0x31, 0, 0, 0, 0, 0, + 0,0xC0,0xFF,0xFF,0xFF,0xFF,0xEF,0x9D,0x42,0x02, 0, 0, 0, 0, 0, 0, 0, + 0,0xC0,0xFF,0xFF,0xFF,0x9C,0x0C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0xC0,0xFF,0xFF,0xFF,0xFF,0xEA,0x95,0x3A, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x3D,0xA9,0xF9,0xFF,0xFF,0xFF,0xFF,0xFF,0xDF,0x85,0x2A, 0, 0, 0, 0, 0, + 0, 0, 0,0x13,0x70,0xD3,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD0,0x75,0x1C, 0, 0, + 0, 0, 0, 0, 0, 0,0x38,0x9B,0xF2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xC0,0x1E, + 0, 0, 0, 0, 0, 0, 0, 0,0x0B,0x63,0xC6,0xFF,0xFF,0xFF,0xFF,0xFF,0x38, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x2A,0x8E,0xEB,0xFF,0xFF,0x38, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x06,0x55,0xB9,0x35, + 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0, 0, + 0,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x38, + 0,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x38, + 0,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x38, + 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, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x38, + 0,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x38, + 0,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x38, + 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0, 0, + 0,0xA3,0x83,0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0xC0,0xFF,0xFE,0xBB,0x57,0x06, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0xC0,0xFF,0xFF,0xFF,0xFF,0xEC,0x8F,0x2B, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x7C,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC7,0x63,0x0C, 0, 0, 0, 0, 0, + 0, 0,0x07,0x51,0xAC,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF,0xF3,0x9B,0x37, 0, 0, 0, + 0, 0, 0, 0, 0,0x0F,0x62,0xBD,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xD3,0x6F,0x0B, + 0, 0, 0, 0, 0, 0, 0, 0,0x1A,0x73,0xCE,0xFF,0xFF,0xFF,0xFF,0xFF,0x38, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x4B,0xE9,0xFF,0xFF,0xFF,0x38, + 0, 0, 0, 0, 0, 0, 0, 0,0x15,0x6B,0xC6,0xFF,0xFF,0xFF,0xFF,0xFF,0x38, + 0, 0, 0, 0, 0,0x0B,0x5B,0xB6,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xD7,0x74,0x0C, + 0, 0,0x05,0x4B,0xA6,0xF5,0xFF,0xFF,0xFF,0xFF,0xFF,0xF4,0x9F,0x3B, 0, 0, 0, + 0,0x79,0xEB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xCA,0x66,0x0D, 0, 0, 0, 0, 0, + 0,0xC0,0xFF,0xFF,0xFF,0xFF,0xED,0x91,0x2D, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0xC0,0xFF,0xFE,0xBC,0x59,0x07, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0xA4,0x84,0x21, 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, 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, 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, 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, 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, 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, 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, + 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, 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,0x37,0x96,0xD7,0xF4,0xF7,0xE0,0xAB,0x4B, 0, 0, 0, 0, + 0, 0, 0,0x27,0xBB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xAA,0x06, 0, 0, + 0, 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x82, 0, 0, + 0, 0, 0,0xB4,0xFF,0xB7,0x57,0x1A,0x06,0x23,0xA3,0xFF,0xFF,0xFF,0xE9, 0, 0, + 0, 0, 0,0x8A,0x3A, 0, 0, 0, 0, 0,0x0A,0xFD,0xFF,0xFF,0xFF,0x0C, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x17,0xFF,0xFF,0xFF,0xF4,0x01, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0x01,0xA6,0xFF,0xFF,0xFF,0x98, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,0x01,0x95,0xFF,0xFF,0xFF,0xD7,0x0E, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x01,0x9E,0xFF,0xFF,0xFF,0xD8,0x19, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x90,0xFF,0xFF,0xFF,0xD1,0x16, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x3B,0xFF,0xFF,0xFF,0xD8,0x14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x97,0xFF,0xFF,0xFF,0x45, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xBA,0xFF,0xFF,0xFF,0x10, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xC4,0xFF,0xFF,0xFF,0x04, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xC4,0xFF,0xFF,0xFF,0x04, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xC4,0xFF,0xFF,0xFF,0x04, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xC4,0xFF,0xFF,0xFF,0x04, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xC4,0xFF,0xFF,0xFF,0x04, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xC4,0xFF,0xFF,0xFF,0x04, 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, 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, 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, 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, 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, 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, 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, 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, 0,0x11,0x69,0xB9,0xE0,0xF8,0xEF,0xCA,0x7D,0x10, 0, 0, 0, + 0, 0, 0, 0,0x5E,0xEB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE9,0x37, 0, 0, + 0, 0, 0,0x82,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEE,0x1F, 0, + 0, 0,0x6C,0xFF,0xFF,0xFF,0xDA,0x67,0x1F,0x06,0x16,0x5A,0xE2,0xFF,0xFF,0xA6, 0, + 0,0x22,0xF5,0xFF,0xFF,0xAB,0x0A, 0, 0, 0, 0, 0,0x1C,0xEF,0xFF,0xFB,0x0D, + 0,0xA1,0xFF,0xFF,0xC4,0x06, 0, 0, 0, 0, 0, 0, 0,0x8F,0xFF,0xFF,0x43, +0x11,0xF7,0xFF,0xFB,0x29, 0, 0,0x12,0x8C,0xDD,0xF8,0xE1,0x7E,0x68,0xFF,0xFF,0x5C, +0x5B,0xFF,0xFF,0xAF, 0, 0,0x1A,0xDC,0xFF,0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,0x67, +0x92,0xFF,0xFF,0x58, 0, 0,0xB5,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x68, +0xC1,0xFF,0xFF,0x20, 0,0x28,0xFF,0xFF,0xFF,0x84,0x1A,0x13,0x6A,0xF9,0xFF,0xFF,0x68, +0xD5,0xFF,0xFC, 0, 0,0x68,0xFF,0xFF,0xB7, 0, 0, 0, 0,0x8D,0xFF,0xFF,0x68, +0xE4,0xFF,0xEE, 0, 0,0x84,0xFF,0xFF,0x75, 0, 0, 0, 0,0x4A,0xFF,0xFF,0x68, +0xE2,0xFF,0xF1, 0, 0,0x83,0xFF,0xFF,0x75, 0, 0, 0, 0,0x4B,0xFF,0xFF,0x68, +0xD0,0xFF,0xFF,0x04, 0,0x67,0xFF,0xFF,0xB7, 0, 0, 0, 0,0x8D,0xFF,0xFF,0x68, +0xBA,0xFF,0xFF,0x2D, 0,0x26,0xFF,0xFF,0xFF,0x84,0x19,0x13,0x69,0xF9,0xFF,0xFF,0x68, +0x85,0xFF,0xFF,0x6B, 0, 0,0xB2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x68, +0x48,0xFF,0xFF,0xCF, 0, 0,0x19,0xDB,0xFF,0xFF,0xFF,0xFF,0xFF,0xE7,0xFF,0xFF,0x68, +0x05,0xE5,0xFF,0xFF,0x54, 0, 0,0x11,0x8B,0xDE,0xFA,0xE6,0x8C,0x63,0xFF,0xFF,0x68, + 0,0x79,0xFF,0xFF,0xEC,0x24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x0A,0xD7,0xFF,0xFF,0xE8,0x3C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x2F,0xF4,0xFF,0xFF,0xFF,0xAD,0x54,0x1D,0x07,0x14,0x31,0x70,0xCE,0x4F, 0, + 0, 0, 0,0x35,0xEA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDB,0x06, + 0, 0, 0, 0,0x1E,0xA6,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xCA,0x1A, + 0, 0, 0, 0, 0, 0,0x2B,0x7C,0xC1,0xE1,0xF6,0xF6,0xDD,0xA6,0x4D,0x02, 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, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 'A' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x04,0xF2,0xFF,0xFF,0xFF,0xFF,0x6A, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x3D,0xFF,0xFF,0xFF,0xFF,0xFF,0xB0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x82,0xFF,0xFF,0xFF,0xFF,0xFF,0xF1,0x04, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0xC8,0xFF,0xFF,0xF9,0xFF,0xFF,0xFF,0x3B, 0, 0, 0, 0, + 0, 0, 0, 0,0x10,0xFC,0xFF,0xFF,0x9B,0xFF,0xFF,0xFF,0x81, 0, 0, 0, 0, + 0, 0, 0, 0,0x53,0xFF,0xFF,0xFF,0x49,0xD8,0xFF,0xFF,0xC7, 0, 0, 0, 0, + 0, 0, 0, 0,0x98,0xFF,0xFF,0xFD,0x0F,0x9B,0xFF,0xFF,0xFC,0x10, 0, 0, 0, + 0, 0, 0, 0,0xDD,0xFF,0xFF,0xD0, 0,0x5E,0xFF,0xFF,0xFF,0x52, 0, 0, 0, + 0, 0, 0,0x23,0xFF,0xFF,0xFF,0x93, 0,0x21,0xFF,0xFF,0xFF,0x98, 0, 0, 0, + 0, 0, 0,0x69,0xFF,0xFF,0xFF,0x57, 0, 0,0xE4,0xFF,0xFF,0xDE, 0, 0, 0, + 0, 0, 0,0xAE,0xFF,0xFF,0xFF,0x1A, 0, 0,0xA7,0xFF,0xFF,0xFF,0x23, 0, 0, + 0, 0,0x03,0xF0,0xFF,0xFF,0xDE, 0, 0, 0,0x6A,0xFF,0xFF,0xFF,0x69, 0, 0, + 0, 0,0x39,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xAF, 0, 0, + 0, 0,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF0,0x03, 0, + 0, 0,0xC4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3A, 0, + 0,0x0E,0xFB,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0,0x61,0xFF,0xFF,0xFF,0x80, 0, + 0,0x4F,0xFF,0xFF,0xFF,0x99, 0, 0, 0, 0, 0,0x29,0xFF,0xFF,0xFF,0xC6, 0, + 0,0x95,0xFF,0xFF,0xFF,0x62, 0, 0, 0, 0, 0,0x01,0xF0,0xFF,0xFF,0xFC,0x0F, + 0,0xDA,0xFF,0xFF,0xFF,0x2C, 0, 0, 0, 0, 0, 0,0xBB,0xFF,0xFF,0xFF,0x51, +0x1F,0xFF,0xFF,0xFF,0xF3,0x02, 0, 0, 0, 0, 0, 0,0x83,0xFF,0xFF,0xFF,0x97, +0x65,0xFF,0xFF,0xFF,0xBF, 0, 0, 0, 0, 0, 0, 0,0x4C,0xFF,0xFF,0xFF,0xDD, + 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, 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, 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, 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, +// 'B' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x3C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xF3,0xDE,0xB2,0x66,0x09, 0, 0, 0, + 0,0x3C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE2,0x31, 0, 0, + 0,0x3C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE7,0x0F, 0, + 0,0x3C,0xFF,0xFF,0xFF,0xD0, 0, 0,0x02,0x1B,0x75,0xFE,0xFF,0xFF,0xFF,0x67, 0, + 0,0x3C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0,0xAD,0xFF,0xFF,0xFF,0x98, 0, + 0,0x3C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0,0x86,0xFF,0xFF,0xFF,0xA0, 0, + 0,0x3C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0,0xA9,0xFF,0xFF,0xFF,0x7A, 0, + 0,0x3C,0xFF,0xFF,0xFF,0xD0, 0, 0,0x02,0x18,0x6C,0xFD,0xFF,0xFF,0xF5,0x1E, 0, + 0,0x3C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x40, 0, 0, + 0,0x3C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF5,0x9B,0x1C, 0, 0, 0, + 0,0x3C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0x78, 0, 0, + 0,0x3C,0xFF,0xFF,0xFF,0xD0, 0, 0,0x01,0x14,0x56,0xE6,0xFF,0xFF,0xFF,0x70, 0, + 0,0x3C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0,0x3F,0xFF,0xFF,0xFF,0xEE,0x08, + 0,0x3C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,0xEE,0xFF,0xFF,0xFF,0x3F, + 0,0x3C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,0xD8,0xFF,0xFF,0xFF,0x5E, + 0,0x3C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,0xE7,0xFF,0xFF,0xFF,0x5F, + 0,0x3C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0,0x2A,0xFF,0xFF,0xFF,0xFF,0x45, + 0,0x3C,0xFF,0xFF,0xFF,0xD0, 0, 0,0x01,0x10,0x47,0xD5,0xFF,0xFF,0xFF,0xF7,0x0B, + 0,0x3C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x86, 0, + 0,0x3C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x9A,0x03, 0, + 0,0x3C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF6,0xE6,0xC1,0x89,0x30, 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, 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, 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, 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, +// 'C' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x0C,0x6A,0xB4,0xE0,0xF6,0xF0,0xD4,0xA5,0x4A,0x04, 0, + 0, 0, 0, 0, 0,0x51,0xE7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x50, 0, + 0, 0, 0, 0,0x5F,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x50, 0, + 0, 0, 0,0x26,0xF7,0xFF,0xFF,0xFF,0xDF,0x56,0x13,0x10,0x59,0xE1,0xFF,0x50, 0, + 0, 0, 0,0xB1,0xFF,0xFF,0xFF,0xE4,0x17, 0, 0, 0, 0,0x19,0xD6,0x50, 0, + 0, 0,0x1A,0xFC,0xFF,0xFF,0xFF,0x60, 0, 0, 0, 0, 0, 0,0x24,0x40, 0, + 0, 0,0x62,0xFF,0xFF,0xFF,0xF7,0x09, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x95,0xFF,0xFF,0xFF,0xC1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xBA,0xFF,0xFF,0xFF,0x9C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xC9,0xFF,0xFF,0xFF,0x8A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xD4,0xFF,0xFF,0xFF,0x82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xC9,0xFF,0xFF,0xFF,0x8A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xBA,0xFF,0xFF,0xFF,0x9C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x96,0xFF,0xFF,0xFF,0xC1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x62,0xFF,0xFF,0xFF,0xF7,0x09, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x1A,0xFC,0xFF,0xFF,0xFF,0x5F, 0, 0, 0, 0, 0, 0,0x24,0x40, 0, + 0, 0, 0,0xB2,0xFF,0xFF,0xFF,0xE4,0x17, 0, 0, 0, 0,0x19,0xD5,0x50, 0, + 0, 0, 0,0x28,0xF8,0xFF,0xFF,0xFF,0xDE,0x55,0x11,0x10,0x58,0xE1,0xFF,0x50, 0, + 0, 0, 0, 0,0x62,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x50, 0, + 0, 0, 0, 0, 0,0x54,0xE8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x50, 0, + 0, 0, 0, 0, 0, 0,0x0C,0x6C,0xB6,0xE2,0xF7,0xF1,0xD5,0xA6,0x4B,0x04, 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, 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, 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, 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, +// 'D' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0xFD,0xED,0xDC,0xB0,0x77,0x1D, 0, 0, 0, 0, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0x9A,0x0A, 0, 0, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xCE,0x0C, 0, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20,0x07,0x29,0x8A,0xFC,0xFF,0xFF,0xFF,0x9B, 0, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0,0x6B,0xFF,0xFF,0xFF,0xFD,0x1F, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0,0x02,0xDE,0xFF,0xFF,0xFF,0x80, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0x93,0xFF,0xFF,0xFF,0xBD, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0x64,0xFF,0xFF,0xFF,0xEE, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0x46,0xFF,0xFF,0xFF,0xFF,0x0B, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0x39,0xFF,0xFF,0xFF,0xFF,0x19, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0x32,0xFF,0xFF,0xFF,0xFF,0x24, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0x39,0xFF,0xFF,0xFF,0xFF,0x19, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0x46,0xFF,0xFF,0xFF,0xFF,0x0B, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0x64,0xFF,0xFF,0xFF,0xED, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0x95,0xFF,0xFF,0xFF,0xBC, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0,0x02,0xDE,0xFF,0xFF,0xFF,0x7E, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0,0x6A,0xFF,0xFF,0xFF,0xFD,0x1E, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20,0x06,0x28,0x8A,0xFC,0xFF,0xFF,0xFF,0x97, 0, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xCB,0x0B, 0, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFA,0x9A,0x09, 0, 0, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0xFD,0xEF,0xDD,0xB2,0x77,0x1D, 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, 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, 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, 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, +// 'E' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xA0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8C, 0, + 0, 0,0xA0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8C, 0, + 0, 0,0xA0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8C, 0, + 0, 0,0xA0,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xA0,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xA0,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xA0,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xA0,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xA0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xB4, 0, 0, + 0, 0,0xA0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xB4, 0, 0, + 0, 0,0xA0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xB4, 0, 0, + 0, 0,0xA0,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xA0,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xA0,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xA0,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xA0,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xA0,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xA0,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xA0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8C, 0, + 0, 0,0xA0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8C, 0, + 0, 0,0xA0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8C, 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, 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, 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, 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, +// 'F' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x6C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0, 0, + 0, 0,0x6C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0, 0, + 0, 0,0x6C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0, 0, + 0, 0,0x6C,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x6C,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x6C,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x6C,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x6C,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x6C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF0, 0, 0, + 0, 0,0x6C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF0, 0, 0, + 0, 0,0x6C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF0, 0, 0, + 0, 0,0x6C,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x6C,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x6C,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x6C,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x6C,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x6C,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x6C,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x6C,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x6C,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x6C,0xFF,0xFF,0xFF,0xC0, 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, 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, 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, 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, 0, 0, 0, 0, 0, +// 'G' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x37,0x8F,0xD0,0xEB,0xFB,0xF0,0xCD,0x8D,0x3C,0x02, 0, + 0, 0, 0, 0,0x0E,0xA8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x40, 0, + 0, 0, 0,0x0F,0xCC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x40, 0, + 0, 0, 0,0x9F,0xFF,0xFF,0xFF,0xFF,0x97,0x2D,0x08,0x1D,0x6A,0xE6,0xFF,0x40, 0, + 0, 0,0x31,0xFF,0xFF,0xFF,0xFF,0x77, 0, 0, 0, 0, 0,0x1B,0xD5,0x40, 0, + 0, 0,0x96,0xFF,0xFF,0xFF,0xD9,0x02, 0, 0, 0, 0, 0, 0,0x28,0x35, 0, + 0, 0,0xE2,0xFF,0xFF,0xFF,0x7D, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x15,0xFF,0xFF,0xFF,0xFF,0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x3A,0xFF,0xFF,0xFF,0xFF,0x1B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x49,0xFF,0xFF,0xFF,0xFF,0x0A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x54,0xFF,0xFF,0xFF,0xFF,0x02, 0, 0,0x84,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0, + 0,0x49,0xFF,0xFF,0xFF,0xFF,0x0A, 0, 0,0x84,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0, + 0,0x3A,0xFF,0xFF,0xFF,0xFF,0x1C, 0, 0,0x84,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0, + 0,0x15,0xFF,0xFF,0xFF,0xFF,0x40, 0, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x7D, 0, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF, 0, + 0, 0,0x93,0xFF,0xFF,0xFF,0xD8,0x01, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF, 0, + 0, 0,0x2F,0xFF,0xFF,0xFF,0xFF,0x6F, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF, 0, + 0, 0, 0,0x9C,0xFF,0xFF,0xFF,0xFD,0x89,0x21,0x06,0x27,0xCE,0xFF,0xFF,0xFF, 0, + 0, 0, 0,0x0E,0xCC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0, + 0, 0, 0, 0,0x0F,0xAD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0x9E, 0, + 0, 0, 0, 0, 0, 0,0x3D,0x97,0xD7,0xF0,0xFA,0xEA,0xC2,0x82,0x25, 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, 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, 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, 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, +// 'H' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x84, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x84, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x84, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 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, 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, 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, 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, +// 'I' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x08, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x08, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x08, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x08, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x08, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x08, 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, 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, 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, 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, +// 'J' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0x04,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x48, 0, 0, + 0, 0, 0, 0,0x04,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x48, 0, 0, + 0, 0, 0, 0,0x04,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xE8,0xFF,0xFF,0xFF,0x48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xE8,0xFF,0xFF,0xFF,0x48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xE8,0xFF,0xFF,0xFF,0x48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xE8,0xFF,0xFF,0xFF,0x48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xE8,0xFF,0xFF,0xFF,0x48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xE8,0xFF,0xFF,0xFF,0x48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xE8,0xFF,0xFF,0xFF,0x48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xE8,0xFF,0xFF,0xFF,0x48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xE8,0xFF,0xFF,0xFF,0x48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xE8,0xFF,0xFF,0xFF,0x48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xE8,0xFF,0xFF,0xFF,0x48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xED,0xFF,0xFF,0xFF,0x41, 0, 0, + 0,0x58,0x23, 0, 0, 0, 0, 0, 0,0x0B,0xFE,0xFF,0xFF,0xFF,0x31, 0, 0, + 0,0x74,0xE3,0x3A, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xFD,0x0B, 0, 0, + 0,0x74,0xFF,0xFC,0x9E,0x3B,0x0E,0x18,0x60,0xF0,0xFF,0xFF,0xFF,0xC5, 0, 0, 0, + 0,0x74,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x4F, 0, 0, 0, + 0,0x74,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0x7D, 0, 0, 0, 0, + 0,0x06,0x3E,0x7F,0xBB,0xD7,0xEE,0xFB,0xEF,0xCE,0x94,0x30, 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, 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, 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, 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, +// 'K' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0x58,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, 0, 0,0x1C,0xE9,0xFF,0xFF,0xFF,0xB2,0x01, +0x58,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, 0,0x06,0xC8,0xFF,0xFF,0xFF,0xD7,0x0E, 0, +0x58,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, 0,0x9A,0xFF,0xFF,0xFF,0xF0,0x26, 0, 0, +0x58,0xFF,0xFF,0xFF,0xD4, 0, 0, 0,0x63,0xFF,0xFF,0xFF,0xFD,0x4B, 0, 0, 0, +0x58,0xFF,0xFF,0xFF,0xD4, 0, 0,0x35,0xF8,0xFF,0xFF,0xFF,0x79, 0, 0, 0, 0, +0x58,0xFF,0xFF,0xFF,0xD4, 0,0x15,0xE2,0xFF,0xFF,0xFF,0xAA, 0, 0, 0, 0, 0, +0x58,0xFF,0xFF,0xFF,0xD4,0x03,0xBD,0xFF,0xFF,0xFF,0xD1,0x0B, 0, 0, 0, 0, 0, +0x58,0xFF,0xFF,0xFF,0xD4,0x8C,0xFF,0xFF,0xFF,0xEC,0x21, 0, 0, 0, 0, 0, 0, +0x58,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0xFF,0x9C, 0, 0, 0, 0, 0, 0, 0, +0x58,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF9,0x21, 0, 0, 0, 0, 0, 0, +0x58,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA5, 0, 0, 0, 0, 0, 0, +0x58,0xFF,0xFF,0xFF,0xFF,0xFF,0xDD,0xFF,0xFF,0xFF,0xFE,0x32, 0, 0, 0, 0, 0, +0x58,0xFF,0xFF,0xFF,0xFF,0xDC,0x12,0xCD,0xFF,0xFF,0xFF,0xBB, 0, 0, 0, 0, 0, +0x58,0xFF,0xFF,0xFF,0xF5,0x2C, 0,0x47,0xFF,0xFF,0xFF,0xFF,0x46, 0, 0, 0, 0, +0x58,0xFF,0xFF,0xFF,0xD4, 0, 0, 0,0xBF,0xFF,0xFF,0xFF,0xCF,0x01, 0, 0, 0, +0x58,0xFF,0xFF,0xFF,0xD4, 0, 0, 0,0x37,0xFF,0xFF,0xFF,0xFF,0x5B, 0, 0, 0, +0x58,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0xDF,0x07, 0, 0, +0x58,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, 0,0x2A,0xFD,0xFF,0xFF,0xFF,0x71, 0, 0, +0x58,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, 0, 0,0xA0,0xFF,0xFF,0xFF,0xEC,0x0F, 0, +0x58,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, 0, 0,0x1F,0xF8,0xFF,0xFF,0xFF,0x87, 0, +0x58,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, 0, 0, 0,0x90,0xFF,0xFF,0xFF,0xF6,0x1B, + 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, 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, 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, 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, +// 'L' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x4C, + 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x4C, + 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x4C, + 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, 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, 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, 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, +// 'M' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0xC8,0xFF,0xFF,0xFF,0xFF,0x57, 0, 0, 0, 0,0xE7,0xFF,0xFF,0xFF,0xFF,0x3C, + 0,0xC8,0xFF,0xFF,0xFF,0xFF,0x9F, 0, 0, 0,0x30,0xFF,0xFF,0xFF,0xFF,0xFF,0x3C, + 0,0xC8,0xFF,0xFF,0xFF,0xFF,0xE6, 0, 0, 0,0x78,0xFF,0xFF,0xFF,0xFF,0xFF,0x3C, + 0,0xC8,0xFF,0xFF,0xFF,0xFF,0xFF,0x2F, 0, 0,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0x3C, + 0,0xC8,0xFF,0xFF,0xE4,0xFE,0xFF,0x77, 0,0x0D,0xFA,0xFF,0xE3,0xFF,0xFF,0xFF,0x3C, + 0,0xC8,0xFF,0xFF,0xD0,0xD3,0xFF,0xBE, 0,0x4F,0xFF,0xFF,0xA3,0xFF,0xFF,0xFF,0x3C, + 0,0xC8,0xFF,0xFF,0xD0,0x92,0xFF,0xF9,0x0C,0x97,0xFF,0xFB,0x68,0xFF,0xFF,0xFF,0x3C, + 0,0xC8,0xFF,0xFF,0xD0,0x51,0xFF,0xFF,0x4E,0xDE,0xFF,0xC7,0x5C,0xFF,0xFF,0xFF,0x3C, + 0,0xC8,0xFF,0xFF,0xD0,0x12,0xFE,0xFF,0xBC,0xFF,0xFF,0x87,0x5C,0xFF,0xFF,0xFF,0x3C, + 0,0xC8,0xFF,0xFF,0xD0, 0,0xCF,0xFF,0xFF,0xFF,0xFF,0x47,0x5C,0xFF,0xFF,0xFF,0x3C, + 0,0xC8,0xFF,0xFF,0xD0, 0,0x8E,0xFF,0xFF,0xFF,0xFB,0x0C,0x5C,0xFF,0xFF,0xFF,0x3C, + 0,0xC8,0xFF,0xFF,0xD0, 0,0x4D,0xFF,0xFF,0xFF,0xC7, 0,0x5C,0xFF,0xFF,0xFF,0x3C, + 0,0xC8,0xFF,0xFF,0xD0, 0,0x0F,0xFC,0xFF,0xFF,0x87, 0,0x5C,0xFF,0xFF,0xFF,0x3C, + 0,0xC8,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0x3C, + 0,0xC8,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0x3C, + 0,0xC8,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0x3C, + 0,0xC8,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0x3C, + 0,0xC8,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0x3C, + 0,0xC8,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0x3C, + 0,0xC8,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0x3C, + 0,0xC8,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0x3C, + 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, 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, 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, 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, +// 'N' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x50,0xFF,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0,0xF0,0xFF,0xFF,0xC0, 0, + 0,0x50,0xFF,0xFF,0xFF,0xFF,0xBF, 0, 0, 0, 0, 0,0xF0,0xFF,0xFF,0xC0, 0, + 0,0x50,0xFF,0xFF,0xFF,0xFF,0xFE,0x23, 0, 0, 0, 0,0xF0,0xFF,0xFF,0xC0, 0, + 0,0x50,0xFF,0xFF,0xFF,0xFF,0xFF,0x85, 0, 0, 0, 0,0xF0,0xFF,0xFF,0xC0, 0, + 0,0x50,0xFF,0xFF,0xFF,0xFF,0xFF,0xE5,0x03, 0, 0, 0,0xF0,0xFF,0xFF,0xC0, 0, + 0,0x50,0xFF,0xFF,0xFF,0xFC,0xFF,0xFF,0x4A, 0, 0, 0,0xF0,0xFF,0xFF,0xC0, 0, + 0,0x50,0xFF,0xFF,0xFF,0xB4,0xFF,0xFF,0xAD, 0, 0, 0,0xF0,0xFF,0xFF,0xC0, 0, + 0,0x50,0xFF,0xFF,0xFF,0x63,0xED,0xFF,0xFA,0x16, 0, 0,0xF0,0xFF,0xFF,0xC0, 0, + 0,0x50,0xFF,0xFF,0xFF,0x5C,0x92,0xFF,0xFF,0x73, 0, 0,0xF0,0xFF,0xFF,0xC0, 0, + 0,0x50,0xFF,0xFF,0xFF,0x5C,0x2E,0xFF,0xFF,0xD6, 0, 0,0xF0,0xFF,0xFF,0xC0, 0, + 0,0x50,0xFF,0xFF,0xFF,0x5C, 0,0xCB,0xFF,0xFF,0x38, 0,0xF0,0xFF,0xFF,0xC0, 0, + 0,0x50,0xFF,0xFF,0xFF,0x5C, 0,0x68,0xFF,0xFF,0x9B, 0,0xF0,0xFF,0xFF,0xC0, 0, + 0,0x50,0xFF,0xFF,0xFF,0x5C, 0,0x0E,0xF5,0xFF,0xF2,0x0B,0xF0,0xFF,0xFF,0xC0, 0, + 0,0x50,0xFF,0xFF,0xFF,0x5C, 0, 0,0xA1,0xFF,0xFF,0x61,0xF0,0xFF,0xFF,0xC0, 0, + 0,0x50,0xFF,0xFF,0xFF,0x5C, 0, 0,0x3E,0xFF,0xFF,0xC3,0xF0,0xFF,0xFF,0xC0, 0, + 0,0x50,0xFF,0xFF,0xFF,0x5C, 0, 0, 0,0xD9,0xFF,0xFF,0xFD,0xFF,0xFF,0xC0, 0, + 0,0x50,0xFF,0xFF,0xFF,0x5C, 0, 0, 0,0x77,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0, 0, + 0,0x50,0xFF,0xFF,0xFF,0x5C, 0, 0, 0,0x18,0xFB,0xFF,0xFF,0xFF,0xFF,0xC0, 0, + 0,0x50,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0xFF,0xC0, 0, + 0,0x50,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0,0x4D,0xFF,0xFF,0xFF,0xFF,0xC0, 0, + 0,0x50,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0,0x03,0xE5,0xFF,0xFF,0xFF,0xC0, 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, 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, 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, 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, +// 'O' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x4B,0xAA,0xE1,0xF8,0xEC,0xCA,0x7B,0x12, 0, 0, 0, 0, + 0, 0, 0,0x07,0xAD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE8,0x3F, 0, 0, 0, + 0, 0, 0,0xAA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF1,0x2C, 0, 0, + 0, 0,0x4B,0xFF,0xFF,0xFF,0xFB,0x65,0x0C,0x2A,0xC7,0xFF,0xFF,0xFF,0xBE, 0, 0, + 0, 0,0xC3,0xFF,0xFF,0xFF,0x8C, 0, 0, 0,0x1C,0xF8,0xFF,0xFF,0xFF,0x36, 0, + 0,0x18,0xFD,0xFF,0xFF,0xFF,0x2A, 0, 0, 0, 0,0xB3,0xFF,0xFF,0xFF,0x8A, 0, + 0,0x54,0xFF,0xFF,0xFF,0xF0, 0, 0, 0, 0, 0,0x7A,0xFF,0xFF,0xFF,0xC7, 0, + 0,0x7E,0xFF,0xFF,0xFF,0xCD, 0, 0, 0, 0, 0,0x56,0xFF,0xFF,0xFF,0xF1, 0, + 0,0x9B,0xFF,0xFF,0xFF,0xB7, 0, 0, 0, 0, 0,0x40,0xFF,0xFF,0xFF,0xFF,0x0F, + 0,0xA8,0xFF,0xFF,0xFF,0xAD, 0, 0, 0, 0, 0,0x37,0xFF,0xFF,0xFF,0xFF,0x1B, + 0,0xB1,0xFF,0xFF,0xFF,0xA9, 0, 0, 0, 0, 0,0x32,0xFF,0xFF,0xFF,0xFF,0x24, + 0,0xA8,0xFF,0xFF,0xFF,0xAD, 0, 0, 0, 0, 0,0x37,0xFF,0xFF,0xFF,0xFF,0x1B, + 0,0x9B,0xFF,0xFF,0xFF,0xB7, 0, 0, 0, 0, 0,0x40,0xFF,0xFF,0xFF,0xFF,0x0F, + 0,0x7E,0xFF,0xFF,0xFF,0xCD, 0, 0, 0, 0, 0,0x56,0xFF,0xFF,0xFF,0xF1, 0, + 0,0x54,0xFF,0xFF,0xFF,0xF0, 0, 0, 0, 0, 0,0x7A,0xFF,0xFF,0xFF,0xC7, 0, + 0,0x19,0xFD,0xFF,0xFF,0xFF,0x28, 0, 0, 0, 0,0xB2,0xFF,0xFF,0xFF,0x8A, 0, + 0, 0,0xC3,0xFF,0xFF,0xFF,0x8A, 0, 0, 0,0x1B,0xF7,0xFF,0xFF,0xFF,0x37, 0, + 0, 0,0x4C,0xFF,0xFF,0xFF,0xFA,0x64,0x0B,0x28,0xC6,0xFF,0xFF,0xFF,0xBF, 0, 0, + 0, 0, 0,0xAA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF2,0x2C, 0, 0, + 0, 0, 0,0x08,0xAD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE8,0x40, 0, 0, 0, + 0, 0, 0, 0, 0,0x4C,0xAC,0xE3,0xF9,0xED,0xCB,0x7C,0x12, 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, 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, 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, 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, +// 'P' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFA,0xED,0xD4,0xA9,0x5F,0x0C, 0, 0, 0, + 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE6,0x47, 0, 0, + 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0x30, 0, + 0, 0,0xB4,0xFF,0xFF,0xFF,0x78, 0,0x04,0x1E,0x71,0xF7,0xFF,0xFF,0xFF,0xB3, 0, + 0, 0,0xB4,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0,0x7B,0xFF,0xFF,0xFF,0xF8,0x09, + 0, 0,0xB4,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0,0x32,0xFF,0xFF,0xFF,0xFF,0x28, + 0, 0,0xB4,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0,0x20,0xFF,0xFF,0xFF,0xFF,0x37, + 0, 0,0xB4,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0,0x32,0xFF,0xFF,0xFF,0xFF,0x28, + 0, 0,0xB4,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0,0x7B,0xFF,0xFF,0xFF,0xF8,0x09, + 0, 0,0xB4,0xFF,0xFF,0xFF,0x78, 0,0x04,0x1D,0x70,0xF7,0xFF,0xFF,0xFF,0xB4, 0, + 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF8,0x31, 0, + 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE7,0x47, 0, 0, + 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFA,0xEF,0xD5,0xA9,0x61,0x0D, 0, 0, 0, + 0, 0,0xB4,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xB4,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xB4,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xB4,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xB4,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xB4,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xB4,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xB4,0xFF,0xFF,0xFF,0x78, 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, 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, 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, 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, 0, 0, 0, 0, 0, +// 'Q' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x4B,0xAA,0xE1,0xF8,0xEC,0xCA,0x7A,0x11, 0, 0, 0, 0, + 0, 0, 0,0x07,0xAD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE6,0x3C, 0, 0, 0, + 0, 0, 0,0xAA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0x28, 0, 0, + 0, 0,0x4B,0xFF,0xFF,0xFF,0xFB,0x65,0x0C,0x2A,0xC7,0xFF,0xFF,0xFF,0xB9, 0, 0, + 0, 0,0xC3,0xFF,0xFF,0xFF,0x8C, 0, 0, 0,0x1C,0xF8,0xFF,0xFF,0xFF,0x32, 0, + 0,0x18,0xFD,0xFF,0xFF,0xFF,0x2A, 0, 0, 0, 0,0xB3,0xFF,0xFF,0xFF,0x86, 0, + 0,0x54,0xFF,0xFF,0xFF,0xF0, 0, 0, 0, 0, 0,0x7A,0xFF,0xFF,0xFF,0xC4, 0, + 0,0x7E,0xFF,0xFF,0xFF,0xCD, 0, 0, 0, 0, 0,0x56,0xFF,0xFF,0xFF,0xEE, 0, + 0,0x9B,0xFF,0xFF,0xFF,0xB7, 0, 0, 0, 0, 0,0x40,0xFF,0xFF,0xFF,0xFF,0x0D, + 0,0xA8,0xFF,0xFF,0xFF,0xAD, 0, 0, 0, 0, 0,0x37,0xFF,0xFF,0xFF,0xFF,0x1A, + 0,0xB1,0xFF,0xFF,0xFF,0xA9, 0, 0, 0, 0, 0,0x32,0xFF,0xFF,0xFF,0xFF,0x24, + 0,0xA8,0xFF,0xFF,0xFF,0xAD, 0, 0, 0, 0, 0,0x37,0xFF,0xFF,0xFF,0xFF,0x1F, + 0,0x9B,0xFF,0xFF,0xFF,0xB7, 0, 0, 0, 0, 0,0x40,0xFF,0xFF,0xFF,0xFF,0x13, + 0,0x7E,0xFF,0xFF,0xFF,0xCD, 0, 0, 0, 0, 0,0x56,0xFF,0xFF,0xFF,0xF8, 0, + 0,0x54,0xFF,0xFF,0xFF,0xF0, 0, 0, 0, 0, 0,0x7A,0xFF,0xFF,0xFF,0xD1, 0, + 0,0x19,0xFD,0xFF,0xFF,0xFF,0x28, 0, 0, 0, 0,0xB2,0xFF,0xFF,0xFF,0x99, 0, + 0, 0,0xC3,0xFF,0xFF,0xFF,0x8A, 0, 0, 0,0x1B,0xF7,0xFF,0xFF,0xFF,0x4A, 0, + 0, 0,0x4C,0xFF,0xFF,0xFF,0xFA,0x64,0x0B,0x28,0xC6,0xFF,0xFF,0xFF,0xDC,0x02, 0, + 0, 0, 0,0xAA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x4A, 0, 0, + 0, 0, 0,0x07,0xAC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0x6B, 0, 0, 0, + 0, 0, 0, 0, 0,0x4C,0xAB,0xE3,0xFA,0xFF,0xFF,0xFF,0xEC,0x2E, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0x50,0xFE,0xFF,0xFF,0xEE,0x35, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x86,0xFF,0xFF,0xFF,0xEF,0x16, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x02,0xB9,0xFF,0xF3,0x4F, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x12,0xBE,0x2D, 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, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 'R' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0x1C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF8,0xEB,0xC8,0x94,0x3B, 0, 0, 0, 0, 0, +0x1C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA7,0x06, 0, 0, 0, +0x1C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x94, 0, 0, 0, +0x1C,0xFF,0xFF,0xFF,0xFF,0x10, 0,0x10,0x42,0xD1,0xFF,0xFF,0xFF,0xFB,0x19, 0, 0, +0x1C,0xFF,0xFF,0xFF,0xFF,0x10, 0, 0, 0,0x1E,0xFD,0xFF,0xFF,0xFF,0x5A, 0, 0, +0x1C,0xFF,0xFF,0xFF,0xFF,0x10, 0, 0, 0, 0,0xD8,0xFF,0xFF,0xFF,0x7B, 0, 0, +0x1C,0xFF,0xFF,0xFF,0xFF,0x10, 0, 0, 0, 0,0xC7,0xFF,0xFF,0xFF,0x87, 0, 0, +0x1C,0xFF,0xFF,0xFF,0xFF,0x10, 0, 0, 0, 0,0xD9,0xFF,0xFF,0xFF,0x74, 0, 0, +0x1C,0xFF,0xFF,0xFF,0xFF,0x10, 0, 0, 0,0x20,0xFD,0xFF,0xFF,0xFF,0x3C, 0, 0, +0x1C,0xFF,0xFF,0xFF,0xFF,0x10, 0,0x10,0x42,0xD2,0xFF,0xFF,0xFF,0xCA,0x01, 0, 0, +0x1C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD5,0x1E, 0, 0, 0, +0x1C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE9,0x60,0x06, 0, 0, 0, 0, +0x1C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC7,0x07, 0, 0, 0, 0, +0x1C,0xFF,0xFF,0xFF,0xFF,0x10,0x09,0x64,0xFB,0xFF,0xFF,0xFF,0x7F, 0, 0, 0, 0, +0x1C,0xFF,0xFF,0xFF,0xFF,0x10, 0, 0,0x73,0xFF,0xFF,0xFF,0xF4,0x17, 0, 0, 0, +0x1C,0xFF,0xFF,0xFF,0xFF,0x10, 0, 0,0x04,0xDA,0xFF,0xFF,0xFF,0x92, 0, 0, 0, +0x1C,0xFF,0xFF,0xFF,0xFF,0x10, 0, 0, 0,0x5F,0xFF,0xFF,0xFF,0xF9,0x1F, 0, 0, +0x1C,0xFF,0xFF,0xFF,0xFF,0x10, 0, 0, 0,0x03,0xDB,0xFF,0xFF,0xFF,0x9E, 0, 0, +0x1C,0xFF,0xFF,0xFF,0xFF,0x10, 0, 0, 0, 0,0x5F,0xFF,0xFF,0xFF,0xFC,0x27, 0, +0x1C,0xFF,0xFF,0xFF,0xFF,0x10, 0, 0, 0, 0,0x03,0xDB,0xFF,0xFF,0xFF,0xAA, 0, +0x1C,0xFF,0xFF,0xFF,0xFF,0x10, 0, 0, 0, 0, 0,0x60,0xFF,0xFF,0xFF,0xFE,0x32, + 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, 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, 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, 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, +// 'S' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0x10,0x73,0xBE,0xEA,0xFA,0xEE,0xD8,0xC0,0x86,0x44,0x09, 0, 0, + 0, 0, 0,0x42,0xE8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x88, 0, 0, + 0, 0,0x2C,0xF5,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x88, 0, 0, + 0, 0,0xB3,0xFF,0xFF,0xFF,0xD9,0x4A,0x12,0x10,0x40,0xA6,0xFE,0xFF,0x88, 0, 0, + 0,0x09,0xF9,0xFF,0xFF,0xFF,0x2F, 0, 0, 0, 0, 0,0x41,0xE4,0x88, 0, 0, + 0,0x22,0xFF,0xFF,0xFF,0xF6, 0, 0, 0, 0, 0, 0, 0,0x20,0x65, 0, 0, + 0,0x22,0xFF,0xFF,0xFF,0xFF,0x1F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x04,0xF4,0xFF,0xFF,0xFF,0xC4,0x1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x98,0xFF,0xFF,0xFF,0xFF,0xF6,0x94,0x35,0x01, 0, 0, 0, 0, 0, 0, + 0, 0,0x0F,0xCB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE3,0x85,0x17, 0, 0, 0, 0, + 0, 0, 0,0x07,0x82,0xF4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF4,0x6A, 0, 0, 0, + 0, 0, 0, 0, 0,0x14,0x77,0xD6,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x79, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,0x28,0x87,0xF5,0xFF,0xFF,0xFF,0xFC,0x26, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x37,0xFA,0xFF,0xFF,0xFF,0x81, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0xAC, 0, + 0,0x17,0x85,0x02, 0, 0, 0, 0, 0, 0, 0,0x92,0xFF,0xFF,0xFF,0xAE, 0, + 0,0x18,0xFF,0xBA,0x23, 0, 0, 0, 0, 0,0x04,0xD2,0xFF,0xFF,0xFF,0x91, 0, + 0,0x18,0xFF,0xFF,0xF8,0x9B,0x43,0x16,0x0A,0x32,0xB0,0xFF,0xFF,0xFF,0xFF,0x49, 0, + 0,0x18,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBF, 0, 0, + 0,0x18,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xB8,0x10, 0, 0, + 0, 0,0x25,0x64,0xA3,0xCB,0xE0,0xF4,0xFA,0xEE,0xCE,0x99,0x42, 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, 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, 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, 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, +// 'T' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0xB8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x30, + 0,0xB8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x30, + 0,0xB8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x30, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 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, 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, 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, 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, 0, +// 'U' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x80,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF,0xF0, 0, + 0,0x80,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF,0xF0, 0, + 0,0x80,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF,0xF0, 0, + 0,0x80,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF,0xF0, 0, + 0,0x80,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF,0xF0, 0, + 0,0x80,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF,0xF0, 0, + 0,0x80,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF,0xF0, 0, + 0,0x80,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF,0xF0, 0, + 0,0x80,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF,0xF0, 0, + 0,0x80,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF,0xF0, 0, + 0,0x80,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF,0xF0, 0, + 0,0x80,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF,0xF0, 0, + 0,0x80,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF,0xF0, 0, + 0,0x7E,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF,0xEE, 0, + 0,0x72,0xFF,0xFF,0xFF,0xAF, 0, 0, 0, 0, 0,0x3F,0xFF,0xFF,0xFF,0xE0, 0, + 0,0x5A,0xFF,0xFF,0xFF,0xCC, 0, 0, 0, 0, 0,0x5E,0xFF,0xFF,0xFF,0xC9, 0, + 0,0x27,0xFF,0xFF,0xFF,0xFB,0x27, 0, 0, 0, 0,0xB6,0xFF,0xFF,0xFF,0x96, 0, + 0, 0,0xD2,0xFF,0xFF,0xFF,0xD9,0x43,0x0D,0x23,0x95,0xFF,0xFF,0xFF,0xFF,0x41, 0, + 0, 0,0x4E,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBC, 0, 0, + 0, 0, 0,0x6E,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC4,0x15, 0, 0, + 0, 0, 0, 0,0x24,0x8B,0xCA,0xED,0xFB,0xF4,0xDE,0xAA,0x54,0x03, 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, 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, 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, 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, +// 'V' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0x13,0xFE,0xFF,0xFF,0xFF,0x1E, 0, 0, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x88, + 0,0xD4,0xFF,0xFF,0xFF,0x55, 0, 0, 0, 0, 0, 0,0xDE,0xFF,0xFF,0xFF,0x4B, + 0,0x97,0xFF,0xFF,0xFF,0x8B, 0, 0, 0, 0, 0,0x14,0xFF,0xFF,0xFF,0xFD,0x10, + 0,0x5A,0xFF,0xFF,0xFF,0xC1, 0, 0, 0, 0, 0,0x4B,0xFF,0xFF,0xFF,0xD0, 0, + 0,0x1D,0xFF,0xFF,0xFF,0xF3,0x02, 0, 0, 0, 0,0x81,0xFF,0xFF,0xFF,0x93, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x2D, 0, 0, 0, 0,0xB8,0xFF,0xFF,0xFF,0x56, 0, + 0, 0,0xA3,0xFF,0xFF,0xFF,0x63, 0, 0, 0, 0,0xED,0xFF,0xFF,0xFF,0x19, 0, + 0, 0,0x66,0xFF,0xFF,0xFF,0x99, 0, 0, 0,0x25,0xFF,0xFF,0xFF,0xDB, 0, 0, + 0, 0,0x28,0xFF,0xFF,0xFF,0xCF, 0, 0, 0,0x5B,0xFF,0xFF,0xFF,0x9E, 0, 0, + 0, 0, 0,0xEA,0xFF,0xFF,0xFB,0x09, 0, 0,0x92,0xFF,0xFF,0xFF,0x60, 0, 0, + 0, 0, 0,0xAE,0xFF,0xFF,0xFF,0x3B, 0, 0,0xC8,0xFF,0xFF,0xFF,0x23, 0, 0, + 0, 0, 0,0x71,0xFF,0xFF,0xFF,0x71, 0,0x06,0xF8,0xFF,0xFF,0xE6, 0, 0, 0, + 0, 0, 0,0x34,0xFF,0xFF,0xFF,0xA7, 0,0x35,0xFF,0xFF,0xFF,0xA8, 0, 0, 0, + 0, 0, 0,0x03,0xF3,0xFF,0xFF,0xDD, 0,0x6C,0xFF,0xFF,0xFF,0x6B, 0, 0, 0, + 0, 0, 0, 0,0xBA,0xFF,0xFF,0xFF,0x13,0xA2,0xFF,0xFF,0xFF,0x2E, 0, 0, 0, + 0, 0, 0, 0,0x7C,0xFF,0xFF,0xFF,0x49,0xD9,0xFF,0xFF,0xEF,0x01, 0, 0, 0, + 0, 0, 0, 0,0x3F,0xFF,0xFF,0xFF,0x8F,0xFE,0xFF,0xFF,0xB3, 0, 0, 0, 0, + 0, 0, 0, 0,0x08,0xF9,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0x76, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0xC5,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x38, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x88,0xFF,0xFF,0xFF,0xFF,0xFF,0xF6,0x05, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x4B,0xFF,0xFF,0xFF,0xFF,0xFF,0xBE, 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, 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, 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, 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, +// 'W' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0xF0,0xFF,0xFF,0xB4, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x42,0xFF,0xFF,0xFF, +0xD1,0xFF,0xFF,0xCD, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x56,0xFF,0xFF,0xFF, +0xB1,0xFF,0xFF,0xE7, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x6A,0xFF,0xFF,0xFF, +0x91,0xFF,0xFF,0xFD,0x03, 0, 0, 0, 0, 0, 0, 0, 0,0x7E,0xFF,0xFF,0xFF, +0x71,0xFF,0xFF,0xFF,0x1A, 0, 0, 0, 0, 0, 0, 0, 0,0x92,0xFF,0xFF,0xEE, +0x51,0xFF,0xFF,0xFF,0x33, 0,0x16,0xFF,0xFF,0xFF,0x92, 0, 0,0xA6,0xFF,0xFF,0xD1, +0x32,0xFF,0xFF,0xFF,0x4D, 0,0x45,0xFF,0xFF,0xFF,0xC7, 0, 0,0xBA,0xFF,0xFF,0xB3, +0x12,0xFF,0xFF,0xFF,0x66, 0,0x72,0xFF,0xFF,0xFF,0xF7,0x04, 0,0xCE,0xFF,0xFF,0x96, + 0,0xF1,0xFF,0xFF,0x7F, 0,0xA0,0xFF,0xFF,0xFF,0xFF,0x31, 0,0xE2,0xFF,0xFF,0x78, + 0,0xD2,0xFF,0xFF,0x99, 0,0xCE,0xFF,0xF9,0xFF,0xFF,0x66, 0,0xF6,0xFF,0xFF,0x5B, + 0,0xB2,0xFF,0xFF,0xB2,0x03,0xF7,0xFF,0xA7,0xFF,0xFF,0x9B,0x09,0xFF,0xFF,0xFF,0x3D, + 0,0x93,0xFF,0xFF,0xCC,0x29,0xFF,0xFF,0x59,0xE4,0xFF,0xD0,0x1E,0xFF,0xFF,0xFF,0x20, + 0,0x73,0xFF,0xFF,0xE5,0x57,0xFF,0xFF,0x27,0xAE,0xFF,0xFB,0x3B,0xFF,0xFF,0xFD,0x05, + 0,0x53,0xFF,0xFF,0xFC,0x87,0xFF,0xF2,0x01,0x78,0xFF,0xFF,0x80,0xFF,0xFF,0xE5, 0, + 0,0x33,0xFF,0xFF,0xFF,0xCA,0xFF,0xC1, 0,0x41,0xFF,0xFF,0xC9,0xFF,0xFF,0xC7, 0, + 0,0x13,0xFF,0xFF,0xFF,0xFD,0xFF,0x8E, 0,0x0D,0xFD,0xFF,0xFD,0xFF,0xFF,0xAA, 0, + 0, 0,0xF3,0xFF,0xFF,0xFF,0xFF,0x5C, 0, 0,0xD5,0xFF,0xFF,0xFF,0xFF,0x8C, 0, + 0, 0,0xD4,0xFF,0xFF,0xFF,0xFF,0x29, 0, 0,0x9E,0xFF,0xFF,0xFF,0xFF,0x6F, 0, + 0, 0,0xB4,0xFF,0xFF,0xFF,0xF4,0x02, 0, 0,0x68,0xFF,0xFF,0xFF,0xFF,0x51, 0, + 0, 0,0x94,0xFF,0xFF,0xFF,0xC3, 0, 0, 0,0x32,0xFF,0xFF,0xFF,0xFF,0x34, 0, + 0, 0,0x74,0xFF,0xFF,0xFF,0x91, 0, 0, 0,0x04,0xF6,0xFF,0xFF,0xFF,0x16, 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, 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, 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, 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, +// 'X' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0x2D,0xFC,0xFF,0xFF,0xFC,0x2C, 0, 0, 0, 0, 0, 0,0xB3,0xFF,0xFF,0xFF,0x9D, + 0,0x94,0xFF,0xFF,0xFF,0xBC, 0, 0, 0, 0, 0,0x46,0xFF,0xFF,0xFF,0xF1,0x17, + 0,0x12,0xEC,0xFF,0xFF,0xFF,0x4F, 0, 0, 0,0x04,0xD6,0xFF,0xFF,0xFF,0x74, 0, + 0, 0,0x6A,0xFF,0xFF,0xFF,0xDB,0x06, 0, 0,0x70,0xFF,0xFF,0xFF,0xDA,0x06, 0, + 0, 0,0x03,0xD1,0xFF,0xFF,0xFF,0x75, 0,0x14,0xEF,0xFF,0xFF,0xFF,0x4B, 0, 0, + 0, 0, 0,0x3F,0xFF,0xFF,0xFF,0xF1,0x17,0x98,0xFF,0xFF,0xFF,0xB7, 0, 0, 0, + 0, 0, 0, 0,0xAA,0xFF,0xFF,0xFF,0xBC,0xFD,0xFF,0xFF,0xFA,0x28, 0, 0, 0, + 0, 0, 0, 0,0x1E,0xF6,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8E, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xEA,0x0F, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x09,0xE1,0xFF,0xFF,0xFF,0xFF,0x65, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x95,0xFF,0xFF,0xFF,0xFC,0x14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x20,0xF7,0xFF,0xFF,0xFF,0xFF,0x93, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0xAD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0x2B, 0, 0, 0, 0, + 0, 0, 0, 0,0x42,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBB, 0, 0, 0, 0, + 0, 0, 0,0x03,0xD3,0xFF,0xFF,0xFF,0x89,0xEF,0xFF,0xFF,0xFF,0x50, 0, 0, 0, + 0, 0, 0,0x6C,0xFF,0xFF,0xFF,0xDA,0x06,0x6F,0xFF,0xFF,0xFF,0xDC,0x07, 0, 0, + 0, 0,0x13,0xEE,0xFF,0xFF,0xFF,0x4D, 0,0x04,0xD6,0xFF,0xFF,0xFF,0x78, 0, 0, + 0, 0,0x96,0xFF,0xFF,0xFF,0xB9, 0, 0, 0,0x45,0xFF,0xFF,0xFF,0xF3,0x19, 0, + 0,0x2E,0xFC,0xFF,0xFF,0xFB,0x2A, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0xA1, 0, + 0,0xBF,0xFF,0xFF,0xFF,0x91, 0, 0, 0, 0, 0,0x23,0xF8,0xFF,0xFF,0xFE,0x36, +0x55,0xFF,0xFF,0xFF,0xEC,0x11, 0, 0, 0, 0, 0, 0,0x86,0xFF,0xFF,0xFF,0xC8, + 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, 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, 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, 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, +// 'Y' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0xA3,0xFF,0xFF,0xFF,0xD7,0x02, 0, 0, 0, 0, 0, 0,0x67,0xFF,0xFF,0xFF,0xF8, +0x23,0xFB,0xFF,0xFF,0xFF,0x56, 0, 0, 0, 0, 0,0x04,0xDF,0xFF,0xFF,0xFF,0x92, + 0,0x9C,0xFF,0xFF,0xFF,0xD2,0x01, 0, 0, 0, 0,0x61,0xFF,0xFF,0xFF,0xF6,0x19, + 0,0x1F,0xF9,0xFF,0xFF,0xFF,0x50, 0, 0, 0,0x03,0xDA,0xFF,0xFF,0xFF,0x8C, 0, + 0, 0,0x95,0xFF,0xFF,0xFF,0xCC, 0, 0, 0,0x5B,0xFF,0xFF,0xFF,0xF3,0x15, 0, + 0, 0,0x1A,0xF7,0xFF,0xFF,0xFF,0x49, 0,0x02,0xD6,0xFF,0xFF,0xFF,0x85, 0, 0, + 0, 0, 0,0x8F,0xFF,0xFF,0xFF,0xC6, 0,0x56,0xFF,0xFF,0xFF,0xF0,0x11, 0, 0, + 0, 0, 0,0x16,0xF4,0xFF,0xFF,0xFF,0x43,0xD1,0xFF,0xFF,0xFF,0x7E, 0, 0, 0, + 0, 0, 0, 0,0x88,0xFF,0xFF,0xFF,0xE8,0xFF,0xFF,0xFF,0xED,0x0E, 0, 0, 0, + 0, 0, 0, 0,0x13,0xF2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x82,0xFF,0xFF,0xFF,0xFF,0xFF,0xE9,0x0B, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x0F,0xEE,0xFF,0xFF,0xFF,0xFF,0x71, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x7F,0xFF,0xFF,0xFF,0xEA,0x08, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 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, 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, 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, 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, 0, +// 'Z' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3C, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3C, + 0,0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3C, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x37,0xFD,0xFF,0xFF,0xFF,0xFF,0x2C, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0x07,0xD5,0xFF,0xFF,0xFF,0xFF,0x98, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0x85,0xFF,0xFF,0xFF,0xFF,0xDE,0x0C, 0, + 0, 0, 0, 0, 0, 0, 0, 0,0x32,0xFB,0xFF,0xFF,0xFF,0xFE,0x3F, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x05,0xD0,0xFF,0xFF,0xFF,0xFF,0x8F, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x7F,0xFF,0xFF,0xFF,0xFF,0xD8,0x09, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x2D,0xF9,0xFF,0xFF,0xFF,0xFC,0x37, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x03,0xCB,0xFF,0xFF,0xFF,0xFF,0x86, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x78,0xFF,0xFF,0xFF,0xFF,0xD2,0x06, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0x28,0xF8,0xFF,0xFF,0xFF,0xFA,0x31, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0x02,0xC6,0xFF,0xFF,0xFF,0xFF,0x7D, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0x71,0xFF,0xFF,0xFF,0xFF,0xCB,0x04, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x23,0xF5,0xFF,0xFF,0xFF,0xF8,0x2A, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x01,0xC0,0xFF,0xFF,0xFF,0xFF,0x74, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x50,0xFF,0xFF,0xFF,0xFF,0xC4,0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x60,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x70, + 0,0x60,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x70, + 0,0x60,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x70, + 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, 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, 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, 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, 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, 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x2C, 0, 0, 0, + 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x2C, 0, 0, 0, + 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x2C, 0, 0, 0, + 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x2C, 0, 0, 0, + 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x2C, 0, 0, 0, + 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x2C, 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, 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, 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, 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, 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, 0, + 0,0x31,0xFF,0xFF,0xEC,0x0A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xBA,0xFF,0xFF,0x6D, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x44,0xFF,0xFF,0xE0,0x04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0xCC,0xFF,0xFF,0x5A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0x56,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0x03,0xDC,0xFF,0xFF,0x48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0x69,0xFF,0xFF,0xBE, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0x08,0xE9,0xFF,0xFF,0x35, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x7C,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x11,0xF3,0xFF,0xFD,0x25, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x8E,0xFF,0xFF,0x99, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x1D,0xFA,0xFF,0xF8,0x17, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xA1,0xFF,0xFF,0x86, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x2B,0xFE,0xFF,0xEF,0x0D, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,0xB4,0xFF,0xFF,0x74, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,0x3D,0xFF,0xFF,0xE4,0x06, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0xC6,0xFF,0xFF,0x61, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0x50,0xFF,0xFF,0xD6,0x01, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0x01,0xD7,0xFF,0xFF,0x4E, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x62,0xFF,0xFF,0xC5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x06,0xE5,0xFF,0xFF,0x3C, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x75,0xFF,0xFF,0xB2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x0E,0xF0,0xFF,0xFE,0x2B, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x87,0xFF,0xFF,0xA0, 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, 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, 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, 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, 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, 0, 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7C, 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, 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, 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, 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, + 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, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x63,0xFF,0xFF,0xFF,0xD0,0x09, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x31,0xF7,0xFF,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0x11,0xDE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x66, 0, 0, 0, 0, + 0, 0, 0,0x01,0xB3,0xFF,0xFF,0xFF,0xE3,0xFF,0xFF,0xFF,0xF8,0x33, 0, 0, 0, + 0, 0, 0,0x7C,0xFF,0xFF,0xFF,0xCA,0x11,0x6D,0xFE,0xFF,0xFF,0xDF,0x12, 0, 0, + 0, 0,0x44,0xFD,0xFF,0xFF,0xC4,0x0E, 0, 0,0x64,0xFD,0xFF,0xFF,0xB6,0x01, 0, + 0,0x1C,0xEA,0xFF,0xFF,0xBE,0x0B, 0, 0, 0, 0,0x5B,0xFC,0xFF,0xFF,0x7E, 0, +0x05,0xC7,0xFF,0xFF,0xB7,0x09, 0, 0, 0, 0, 0, 0,0x53,0xFA,0xFF,0xFD,0x47, + 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, + 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, +0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +// '`' + 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, 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, 0, 0, 0, 0, 0, 0, + 0, 0,0x04,0xA7,0xFF,0xFF,0xFA,0x3B, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0x02,0x9E,0xFF,0xFF,0xE7,0x1A, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0x01,0x95,0xFF,0xFF,0xC8,0x07, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x8B,0xFF,0xFF,0x9C, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x82,0xFF,0xFF,0x69, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, +// 'a' + 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, 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, 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, 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, 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, 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, 0, + 0, 0, 0,0x30,0x7C,0xB3,0xD0,0xE6,0xFA,0xF3,0xE0,0xB1,0x60,0x07, 0, 0, 0, + 0, 0,0x18,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD0,0x1A, 0, 0, + 0, 0,0x18,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xB7, 0, 0, + 0, 0,0x17,0xD3,0x8A,0x51,0x31,0x1B,0x06,0x13,0x59,0xF0,0xFF,0xFF,0xFF,0x27, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x83,0xFF,0xFF,0xFF,0x69, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x70,0xFF,0xFF,0xFF,0x93, 0, + 0, 0, 0,0x0D,0x6A,0xB1,0xDB,0xF2,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA3, 0, + 0, 0,0x40,0xEB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xAE, 0, + 0,0x18,0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xB0, 0, + 0,0x75,0xFF,0xFF,0xFF,0xFF,0xAA,0x38,0x11,0x03, 0,0x7B,0xFF,0xFF,0xFF,0xB0, 0, + 0,0xA0,0xFF,0xFF,0xFF,0xE4,0x01, 0, 0, 0, 0,0xA0,0xFF,0xFF,0xFF,0xB0, 0, + 0,0xA2,0xFF,0xFF,0xFF,0xD5, 0, 0, 0, 0,0x19,0xF3,0xFF,0xFF,0xFF,0xB0, 0, + 0,0x77,0xFF,0xFF,0xFF,0xFF,0x7E,0x14,0x11,0x48,0xD7,0xFF,0xFF,0xFF,0xFF,0xB0, 0, + 0,0x1C,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xB0, 0, + 0, 0,0x57,0xF9,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD6,0x87,0xFF,0xFF,0xFF,0xB0, 0, + 0, 0, 0,0x29,0x99,0xDB,0xF7,0xF4,0xCF,0x77,0x08,0x70,0xFF,0xFF,0xFF,0xB0, 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, 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, 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, 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, +// 'b' + 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, 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, 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,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x44,0x1A,0x9B,0xE6,0xF8,0xDE,0x94,0x19, 0, 0, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x6B,0xEA,0xFF,0xFF,0xFF,0xFF,0xFF,0xED,0x2E, 0, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDE,0x08, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0xFF,0xB7,0x21,0x0E,0x7D,0xFF,0xFF,0xFF,0xFF,0x6A, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0xEA,0x0C, 0, 0, 0,0xAB,0xFF,0xFF,0xFF,0xC1, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x92, 0, 0, 0, 0,0x47,0xFF,0xFF,0xFF,0xF5,0x02, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x5E, 0, 0, 0, 0,0x13,0xFF,0xFF,0xFF,0xFF,0x1A, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x49, 0, 0, 0, 0, 0,0xFD,0xFF,0xFF,0xFF,0x29, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x48, 0, 0, 0, 0, 0,0xFD,0xFF,0xFF,0xFF,0x28, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x5E, 0, 0, 0, 0,0x13,0xFF,0xFF,0xFF,0xFF,0x1B, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x92, 0, 0, 0, 0,0x46,0xFF,0xFF,0xFF,0xF5,0x02, + 0, 0,0xE0,0xFF,0xFF,0xFF,0xEA,0x0C, 0, 0, 0,0xAB,0xFF,0xFF,0xFF,0xC2, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0xFF,0xB7,0x20,0x0D,0x7C,0xFF,0xFF,0xFF,0xFF,0x6C, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0xF3,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE1,0x09, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x6A,0xEB,0xFF,0xFF,0xFF,0xFF,0xFF,0xF0,0x33, 0, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x44,0x1D,0x9B,0xE3,0xF9,0xE3,0x9B,0x1E, 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, 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, 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, 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, +// 'c' + 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, 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, 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, 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, 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, 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, 0, + 0, 0, 0, 0, 0, 0,0x3F,0x9C,0xD8,0xF1,0xF7,0xDE,0xC2,0x88,0x33, 0, 0, + 0, 0, 0, 0,0x0F,0xB2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x08, 0, + 0, 0, 0,0x08,0xCD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x08, 0, + 0, 0, 0,0x8A,0xFF,0xFF,0xFF,0xFF,0xA0,0x2F,0x07,0x0B,0x2C,0x70,0xCF,0x07, 0, + 0, 0,0x0F,0xF4,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x50,0xFF,0xFF,0xFF,0xF4,0x0D, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x82,0xFF,0xFF,0xFF,0xB9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x97,0xFF,0xFF,0xFF,0x9B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x97,0xFF,0xFF,0xFF,0x9A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x83,0xFF,0xFF,0xFF,0xB7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x52,0xFF,0xFF,0xFF,0xF2,0x0B, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x11,0xF6,0xFF,0xFF,0xFF,0x8A, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0x8F,0xFF,0xFF,0xFF,0xFF,0x9B,0x2D,0x06,0x13,0x30,0x6B,0xCC,0x07, 0, + 0, 0, 0,0x0A,0xD2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x08, 0, + 0, 0, 0, 0,0x13,0xBA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x08, 0, + 0, 0, 0, 0, 0, 0,0x45,0xA0,0xDB,0xF3,0xF7,0xE0,0xC5,0x83,0x2E, 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, 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, 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, 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, +// 'd' + 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, 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, 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, 0, 0, 0,0xCC,0xFF,0xFF,0xFF,0x54, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xCC,0xFF,0xFF,0xFF,0x54, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xCC,0xFF,0xFF,0xFF,0x54, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xCC,0xFF,0xFF,0xFF,0x54, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xCC,0xFF,0xFF,0xFF,0x54, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xCC,0xFF,0xFF,0xFF,0x54, 0, + 0, 0, 0, 0,0x5D,0xC1,0xEF,0xF4,0xC6,0x55, 0,0xCC,0xFF,0xFF,0xFF,0x54, 0, + 0, 0,0x02,0xA5,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x88,0xCC,0xFF,0xFF,0xFF,0x54, 0, + 0, 0,0x72,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0x54, 0, + 0,0x06,0xEE,0xFF,0xFF,0xFF,0xD0,0x2D,0x0A,0x62,0xFA,0xFF,0xFF,0xFF,0xFF,0x54, 0, + 0,0x4B,0xFF,0xFF,0xFF,0xFB,0x23, 0, 0, 0,0x83,0xFF,0xFF,0xFF,0xFF,0x54, 0, + 0,0x81,0xFF,0xFF,0xFF,0xBA, 0, 0, 0, 0,0x1D,0xFF,0xFF,0xFF,0xFF,0x54, 0, + 0,0xA3,0xFF,0xFF,0xFF,0x86, 0, 0, 0, 0, 0,0xE8,0xFF,0xFF,0xFF,0x54, 0, + 0,0xB1,0xFF,0xFF,0xFF,0x71, 0, 0, 0, 0, 0,0xD2,0xFF,0xFF,0xFF,0x54, 0, + 0,0xB2,0xFF,0xFF,0xFF,0x70, 0, 0, 0, 0, 0,0xD2,0xFF,0xFF,0xFF,0x54, 0, + 0,0xA3,0xFF,0xFF,0xFF,0x86, 0, 0, 0, 0, 0,0xE8,0xFF,0xFF,0xFF,0x54, 0, + 0,0x80,0xFF,0xFF,0xFF,0xBA, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x54, 0, + 0,0x4A,0xFF,0xFF,0xFF,0xFB,0x23, 0, 0, 0,0x83,0xFF,0xFF,0xFF,0xFF,0x54, 0, + 0,0x06,0xEE,0xFF,0xFF,0xFF,0xCF,0x2C,0x09,0x61,0xFA,0xFF,0xFF,0xFF,0xFF,0x54, 0, + 0, 0,0x73,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF4,0xFF,0xFF,0xFF,0x54, 0, + 0, 0,0x02,0xAA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x87,0xCC,0xFF,0xFF,0xFF,0x54, 0, + 0, 0, 0,0x01,0x64,0xC9,0xF3,0xF2,0xC5,0x57, 0,0xCC,0xFF,0xFF,0xFF,0x54, 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, 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, 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, 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, +// 'e' + 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, 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, 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, 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, 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, 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, 0, + 0, 0, 0, 0,0x01,0x55,0xAC,0xE2,0xF8,0xF1,0xD5,0x94,0x2C, 0, 0, 0, 0, + 0, 0, 0,0x1A,0xC8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0x83, 0, 0, 0, + 0, 0,0x10,0xDD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x83, 0, 0, + 0, 0,0x9F,0xFF,0xFF,0xFF,0xEC,0x53,0x0A,0x13,0x6B,0xF9,0xFF,0xFF,0xFD,0x30, 0, + 0,0x1B,0xFB,0xFF,0xFF,0xFF,0x52, 0, 0, 0, 0,0x83,0xFF,0xFF,0xFF,0xA0, 0, + 0,0x64,0xFF,0xFF,0xFF,0xDE, 0, 0, 0, 0, 0,0x1D,0xFF,0xFF,0xFF,0xEB, 0, + 0,0x96,0xFF,0xFF,0xFF,0xA9, 0, 0, 0, 0, 0,0x01,0xF7,0xFF,0xFF,0xFF,0x1F, + 0,0xAA,0xFF,0xFF,0xFF,0xFE,0xFC,0xFC,0xFD,0xFE,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0x34, + 0,0xAB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x42, + 0,0x99,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x44, + 0,0x6B,0xFF,0xFF,0xFF,0x93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x24,0xFE,0xFF,0xFF,0xE2,0x0D, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xAC,0xFF,0xFF,0xFF,0xD2,0x56,0x19,0x04,0x0C,0x22,0x39,0x68,0xA9,0x8D, 0, + 0, 0,0x17,0xE2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x9C, 0, + 0, 0, 0,0x1D,0xC5,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x9C, 0, + 0, 0, 0, 0, 0,0x46,0x9D,0xD6,0xEF,0xFB,0xEC,0xD8,0xC0,0x89,0x48,0x0C, 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, 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, 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, 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, +// 'f' + 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, 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, 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,0x0D,0x7D,0xC7,0xEC,0xFA,0xFF,0xFF,0xFF,0x54, 0, + 0, 0, 0, 0, 0, 0,0x06,0xCF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x54, 0, + 0, 0, 0, 0, 0, 0,0x58,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x54, 0, + 0, 0, 0, 0, 0, 0,0x94,0xFF,0xFF,0xFF,0xC5,0x16, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xAA,0xFF,0xFF,0xFF,0x7E, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0, + 0, 0,0x88,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x54, 0, + 0, 0,0x88,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x54, 0, + 0, 0,0x88,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x54, 0, + 0, 0, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0x78, 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, 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, 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, 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, 0, +// 'g' + 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, 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, 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, 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, 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, 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, 0, + 0, 0, 0, 0,0x36,0xAD,0xE9,0xF7,0xD9,0x86,0x0D,0xA0,0xFF,0xFF,0xFF,0x84, 0, + 0, 0, 0,0x60,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xD8,0xB2,0xFF,0xFF,0xFF,0x84, 0, + 0, 0,0x33,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x84, 0, + 0, 0,0xBC,0xFF,0xFF,0xFF,0xE6,0x40,0x09,0x4F,0xF2,0xFF,0xFF,0xFF,0xFF,0x84, 0, + 0,0x1C,0xFE,0xFF,0xFF,0xFF,0x4C, 0, 0, 0,0x6A,0xFF,0xFF,0xFF,0xFF,0x84, 0, + 0,0x59,0xFF,0xFF,0xFF,0xE3,0x02, 0, 0, 0,0x0D,0xF4,0xFF,0xFF,0xFF,0x84, 0, + 0,0x82,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0xC7,0xFF,0xFF,0xFF,0x84, 0, + 0,0x93,0xFF,0xFF,0xFF,0x94, 0, 0, 0, 0, 0,0xAD,0xFF,0xFF,0xFF,0x84, 0, + 0,0x96,0xFF,0xFF,0xFF,0x93, 0, 0, 0, 0, 0,0xAD,0xFF,0xFF,0xFF,0x84, 0, + 0,0x88,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0xC6,0xFF,0xFF,0xFF,0x84, 0, + 0,0x63,0xFF,0xFF,0xFF,0xE3,0x02, 0, 0, 0,0x0C,0xF4,0xFF,0xFF,0xFF,0x84, 0, + 0,0x28,0xFF,0xFF,0xFF,0xFF,0x4C, 0, 0, 0,0x68,0xFF,0xFF,0xFF,0xFF,0x84, 0, + 0, 0,0xCB,0xFF,0xFF,0xFF,0xE5,0x3F,0x08,0x4E,0xF1,0xFF,0xFF,0xFF,0xFF,0x84, 0, + 0, 0,0x41,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x84, 0, + 0, 0, 0,0x70,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xDD,0xB2,0xFF,0xFF,0xFF,0x84, 0, + 0, 0, 0, 0,0x3C,0xB1,0xEB,0xF9,0xDF,0x92,0x12,0xA4,0xFF,0xFF,0xFF,0x7D, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xC2,0xFF,0xFF,0xFF,0x6B, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x1F,0xF6,0xFF,0xFF,0xFF,0x3F, 0, + 0, 0, 0,0xC7,0x7B,0x3E,0x22,0x0A,0x13,0x47,0xD3,0xFF,0xFF,0xFF,0xED,0x09, 0, + 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x76, 0, 0, + 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x93,0x01, 0, 0, + 0, 0, 0,0x28,0x7B,0xB9,0xD8,0xEF,0xFB,0xEE,0xCD,0x94,0x34, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 'h' + 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, 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, 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,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0x90,0x0E,0x89,0xDC,0xF8,0xE9,0xA6,0x23, 0, 0, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0x97,0xD0,0xFF,0xFF,0xFF,0xFF,0xFF,0xEB,0x1F, 0, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0xF2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA1, 0, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0xFF,0xA6,0x15,0x1B,0xB5,0xFF,0xFF,0xFF,0xF1,0x01, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0xF3,0x0C, 0, 0,0x2C,0xFF,0xFF,0xFF,0xFF,0x1A, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0xB2, 0, 0, 0,0x04,0xFE,0xFF,0xFF,0xFF,0x29, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0x98, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 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, 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, 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, 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, +// 'i' + 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, 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,0xD0,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x58, 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, 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,0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0, + 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0, + 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0, + 0, 0,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80, + 0, 0,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80, + 0, 0,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80, + 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, 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, 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, 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, +// 'j' + 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, 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,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 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, 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,0x50,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0, + 0, 0, 0,0x50,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0, + 0, 0, 0,0x50,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x1D,0xFF,0xFF,0xFF,0xFF,0x05, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x2D,0xFF,0xFF,0xFF,0xFA, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x61,0xFF,0xFF,0xFF,0xE0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x09,0x42,0xE3,0xFF,0xFF,0xFF,0xAE, 0, 0, 0, 0, 0, + 0, 0,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x53, 0, 0, 0, 0, 0, + 0, 0,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xAE, 0, 0, 0, 0, 0, 0, + 0, 0,0xF8,0xFF,0xFF,0xFF,0xFE,0xEE,0xC2,0x67,0x03, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 'k' + 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, 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, 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,0x88,0xFF,0xFF,0xFF,0x9C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x88,0xFF,0xFF,0xFF,0x9C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x88,0xFF,0xFF,0xFF,0x9C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x88,0xFF,0xFF,0xFF,0x9C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x88,0xFF,0xFF,0xFF,0x9C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x88,0xFF,0xFF,0xFF,0x9C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x88,0xFF,0xFF,0xFF,0x9C, 0, 0, 0,0x0E,0xCF,0xFF,0xFF,0xFF,0xED,0x31, + 0, 0,0x88,0xFF,0xFF,0xFF,0x9C, 0, 0,0x07,0xBF,0xFF,0xFF,0xFF,0xED,0x30, 0, + 0, 0,0x88,0xFF,0xFF,0xFF,0x9C, 0,0x03,0xAF,0xFF,0xFF,0xFF,0xEC,0x30, 0, 0, + 0, 0,0x88,0xFF,0xFF,0xFF,0x9C, 0,0x9C,0xFF,0xFF,0xFF,0xEC,0x2F, 0, 0, 0, + 0, 0,0x88,0xFF,0xFF,0xFF,0x9C,0x88,0xFF,0xFF,0xFF,0xEB,0x2E, 0, 0, 0, 0, + 0, 0,0x88,0xFF,0xFF,0xFF,0xE9,0xFF,0xFF,0xFF,0xEB,0x2D, 0, 0, 0, 0, 0, + 0, 0,0x88,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE6,0x0F, 0, 0, 0, 0, 0, + 0, 0,0x88,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x97, 0, 0, 0, 0, 0, + 0, 0,0x88,0xFF,0xFF,0xFF,0xFF,0xE4,0xEB,0xFF,0xFF,0xFE,0x3B, 0, 0, 0, 0, + 0, 0,0x88,0xFF,0xFF,0xFF,0xE2,0x22,0x66,0xFF,0xFF,0xFF,0xD5,0x06, 0, 0, 0, + 0, 0,0x88,0xFF,0xFF,0xFF,0x9C, 0,0x02,0xCE,0xFF,0xFF,0xFF,0x7D, 0, 0, 0, + 0, 0,0x88,0xFF,0xFF,0xFF,0x9C, 0, 0,0x3D,0xFF,0xFF,0xFF,0xF8,0x26, 0, 0, + 0, 0,0x88,0xFF,0xFF,0xFF,0x9C, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0xBF, 0, 0, + 0, 0,0x88,0xFF,0xFF,0xFF,0x9C, 0, 0, 0,0x1D,0xF6,0xFF,0xFF,0xFF,0x63, 0, + 0, 0,0x88,0xFF,0xFF,0xFF,0x9C, 0, 0, 0, 0,0x7F,0xFF,0xFF,0xFF,0xEE,0x16, + 0, 0,0x88,0xFF,0xFF,0xFF,0x9C, 0, 0, 0, 0,0x09,0xE1,0xFF,0xFF,0xFF,0xA7, + 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, 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, 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, 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, +// 'l' + 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, 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, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0xB8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, 0, + 0,0xB8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, 0, + 0,0xB8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x84,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x84,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x84,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x84,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x84,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x84,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x84,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x84,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x84,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x84,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x84,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x84,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x82,0xFF,0xFF,0xFF,0xA1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x78,0xFF,0xFF,0xFF,0xAF, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x5F,0xFF,0xFF,0xFF,0xE1,0x01, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x2C,0xFF,0xFF,0xFF,0xFF,0x95,0x1C, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0xD2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7C, 0, + 0, 0, 0, 0, 0, 0,0x38,0xF3,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7C, 0, + 0, 0, 0, 0, 0, 0, 0,0x25,0x9A,0xDC,0xF7,0xFF,0xFF,0xFF,0xFF,0x7C, 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, 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, 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, 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, +// 'm' + 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, 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, 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, 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, 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, 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, 0, + 0,0xD8,0xFF,0xFF,0x35,0x95,0xEC,0xEF,0x9D,0x0D,0x38,0xC6,0xF7,0xE9,0x96,0x0A, 0, + 0,0xD8,0xFF,0xFF,0xCC,0xFF,0xFF,0xFF,0xFF,0xB9,0xF1,0xFF,0xFF,0xFF,0xFF,0x93, 0, + 0,0xD8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF0,0x01, + 0,0xD8,0xFF,0xFF,0xE2,0x1B,0x5D,0xFF,0xFF,0xFF,0xD1,0x14,0x76,0xFF,0xFF,0xFF,0x24, + 0,0xD8,0xFF,0xFF,0xA2, 0,0x04,0xFC,0xFF,0xFF,0x83, 0,0x1F,0xFF,0xFF,0xFF,0x3F, + 0,0xD8,0xFF,0xFF,0x92, 0, 0,0xEE,0xFF,0xFF,0x72, 0,0x0E,0xFF,0xFF,0xFF,0x50, + 0,0xD8,0xFF,0xFF,0x90, 0, 0,0xEC,0xFF,0xFF,0x70, 0,0x0C,0xFF,0xFF,0xFF,0x57, + 0,0xD8,0xFF,0xFF,0x90, 0, 0,0xEC,0xFF,0xFF,0x70, 0,0x0C,0xFF,0xFF,0xFF,0x5B, + 0,0xD8,0xFF,0xFF,0x90, 0, 0,0xEC,0xFF,0xFF,0x70, 0,0x0C,0xFF,0xFF,0xFF,0x5C, + 0,0xD8,0xFF,0xFF,0x90, 0, 0,0xEC,0xFF,0xFF,0x70, 0,0x0C,0xFF,0xFF,0xFF,0x5C, + 0,0xD8,0xFF,0xFF,0x90, 0, 0,0xEC,0xFF,0xFF,0x70, 0,0x0C,0xFF,0xFF,0xFF,0x5C, + 0,0xD8,0xFF,0xFF,0x90, 0, 0,0xEC,0xFF,0xFF,0x70, 0,0x0C,0xFF,0xFF,0xFF,0x5C, + 0,0xD8,0xFF,0xFF,0x90, 0, 0,0xEC,0xFF,0xFF,0x70, 0,0x0C,0xFF,0xFF,0xFF,0x5C, + 0,0xD8,0xFF,0xFF,0x90, 0, 0,0xEC,0xFF,0xFF,0x70, 0,0x0C,0xFF,0xFF,0xFF,0x5C, + 0,0xD8,0xFF,0xFF,0x90, 0, 0,0xEC,0xFF,0xFF,0x70, 0,0x0C,0xFF,0xFF,0xFF,0x5C, + 0,0xD8,0xFF,0xFF,0x90, 0, 0,0xEC,0xFF,0xFF,0x70, 0,0x0C,0xFF,0xFF,0xFF,0x5C, + 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, 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, 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, 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, +// 'n' + 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, 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, 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, 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, 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, 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, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0x90,0x10,0x8C,0xDD,0xF8,0xE9,0xA6,0x23, 0, 0, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0x99,0xD5,0xFF,0xFF,0xFF,0xFF,0xFF,0xEB,0x1E, 0, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0xF4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA0, 0, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0xFF,0xA8,0x15,0x1B,0xB5,0xFF,0xFF,0xFF,0xF0,0x01, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0xF4,0x0E, 0, 0,0x2C,0xFF,0xFF,0xFF,0xFF,0x1A, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0xB3, 0, 0, 0,0x04,0xFF,0xFF,0xFF,0xFF,0x29, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0x98, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0, + 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 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, 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, 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, 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, +// 'o' + 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, 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, 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, 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, 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, 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, 0, + 0, 0, 0, 0,0x01,0x55,0xAE,0xE4,0xF8,0xEF,0xCD,0x85,0x18, 0, 0, 0, 0, + 0, 0, 0,0x16,0xC4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF4,0x5A, 0, 0, 0, + 0, 0,0x0A,0xD5,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x55, 0, 0, + 0, 0,0x8E,0xFF,0xFF,0xFF,0xED,0x51,0x09,0x23,0xB0,0xFF,0xFF,0xFF,0xF0,0x12, 0, + 0,0x0F,0xF4,0xFF,0xFF,0xFF,0x4D, 0, 0, 0,0x06,0xD6,0xFF,0xFF,0xFF,0x7A, 0, + 0,0x4F,0xFF,0xFF,0xFF,0xDD, 0, 0, 0, 0, 0,0x6B,0xFF,0xFF,0xFF,0xC5, 0, + 0,0x80,0xFF,0xFF,0xFF,0xA4, 0, 0, 0, 0, 0,0x32,0xFF,0xFF,0xFF,0xF6, 0, + 0,0x93,0xFF,0xFF,0xFF,0x8D, 0, 0, 0, 0, 0,0x1A,0xFF,0xFF,0xFF,0xFF,0x0A, + 0,0x94,0xFF,0xFF,0xFF,0x8D, 0, 0, 0, 0, 0,0x1B,0xFF,0xFF,0xFF,0xFF,0x0A, + 0,0x80,0xFF,0xFF,0xFF,0xA4, 0, 0, 0, 0, 0,0x32,0xFF,0xFF,0xFF,0xF7, 0, + 0,0x4F,0xFF,0xFF,0xFF,0xDD, 0, 0, 0, 0, 0,0x6B,0xFF,0xFF,0xFF,0xC5, 0, + 0,0x0F,0xF4,0xFF,0xFF,0xFF,0x4B, 0, 0, 0,0x05,0xD5,0xFF,0xFF,0xFF,0x7A, 0, + 0, 0,0x8F,0xFF,0xFF,0xFF,0xEB,0x4F,0x08,0x22,0xAE,0xFF,0xFF,0xFF,0xF1,0x12, 0, + 0, 0,0x0B,0xD5,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x55, 0, 0, + 0, 0, 0,0x16,0xC5,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF5,0x5A, 0, 0, 0, + 0, 0, 0, 0,0x01,0x56,0xB0,0xE5,0xF9,0xF0,0xCE,0x86,0x19, 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, 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, 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, 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, +// 'p' + 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, 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, 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, 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, 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, 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, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x44,0x1D,0x9A,0xE3,0xF8,0xE2,0x9A,0x1D, 0, 0, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x6A,0xEB,0xFF,0xFF,0xFF,0xFF,0xFF,0xF0,0x33, 0, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0xF3,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE1,0x09, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0xFF,0xB7,0x21,0x0E,0x7D,0xFF,0xFF,0xFF,0xFF,0x6B, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0xEA,0x0C, 0, 0, 0,0xAB,0xFF,0xFF,0xFF,0xC2, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x92, 0, 0, 0, 0,0x47,0xFF,0xFF,0xFF,0xF5,0x02, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x5E, 0, 0, 0, 0,0x13,0xFF,0xFF,0xFF,0xFF,0x1A, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x49, 0, 0, 0, 0, 0,0xFD,0xFF,0xFF,0xFF,0x29, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x48, 0, 0, 0, 0, 0,0xFD,0xFF,0xFF,0xFF,0x28, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x5E, 0, 0, 0, 0,0x13,0xFF,0xFF,0xFF,0xFF,0x1A, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x92, 0, 0, 0, 0,0x46,0xFF,0xFF,0xFF,0xF5,0x02, + 0, 0,0xE0,0xFF,0xFF,0xFF,0xEA,0x0C, 0, 0, 0,0xAB,0xFF,0xFF,0xFF,0xC2, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0xFF,0xB7,0x20,0x0D,0x7C,0xFF,0xFF,0xFF,0xFF,0x6B, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0xF6,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x08, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x6A,0xEA,0xFF,0xFF,0xFF,0xFF,0xFF,0xEE,0x31, 0, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x44,0x1C,0x9E,0xE7,0xF9,0xDF,0x95,0x1A, 0, 0, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 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, +// 'q' + 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, 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, 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, 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, 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, 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, 0, + 0, 0, 0,0x01,0x63,0xC8,0xF2,0xF1,0xC4,0x56, 0,0xCC,0xFF,0xFF,0xFF,0x54, 0, + 0, 0,0x02,0xA9,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x87,0xCC,0xFF,0xFF,0xFF,0x54, 0, + 0, 0,0x72,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF4,0xFF,0xFF,0xFF,0x54, 0, + 0,0x06,0xED,0xFF,0xFF,0xFF,0xD0,0x2D,0x0A,0x62,0xFA,0xFF,0xFF,0xFF,0xFF,0x54, 0, + 0,0x4A,0xFF,0xFF,0xFF,0xFB,0x23, 0, 0, 0,0x83,0xFF,0xFF,0xFF,0xFF,0x54, 0, + 0,0x80,0xFF,0xFF,0xFF,0xBA, 0, 0, 0, 0,0x1D,0xFF,0xFF,0xFF,0xFF,0x54, 0, + 0,0xA3,0xFF,0xFF,0xFF,0x86, 0, 0, 0, 0, 0,0xE8,0xFF,0xFF,0xFF,0x54, 0, + 0,0xB1,0xFF,0xFF,0xFF,0x71, 0, 0, 0, 0, 0,0xD2,0xFF,0xFF,0xFF,0x54, 0, + 0,0xB2,0xFF,0xFF,0xFF,0x70, 0, 0, 0, 0, 0,0xD2,0xFF,0xFF,0xFF,0x54, 0, + 0,0xA3,0xFF,0xFF,0xFF,0x86, 0, 0, 0, 0, 0,0xE8,0xFF,0xFF,0xFF,0x54, 0, + 0,0x81,0xFF,0xFF,0xFF,0xBA, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x54, 0, + 0,0x4B,0xFF,0xFF,0xFF,0xFB,0x23, 0, 0, 0,0x83,0xFF,0xFF,0xFF,0xFF,0x54, 0, + 0,0x07,0xEF,0xFF,0xFF,0xFF,0xCF,0x2C,0x09,0x61,0xFA,0xFF,0xFF,0xFF,0xFF,0x54, 0, + 0, 0,0x74,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0x54, 0, + 0, 0,0x02,0xA8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x87,0xCC,0xFF,0xFF,0xFF,0x54, 0, + 0, 0, 0, 0,0x5E,0xC3,0xF0,0xF5,0xC8,0x58, 0,0xCC,0xFF,0xFF,0xFF,0x54, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xCC,0xFF,0xFF,0xFF,0x54, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xCC,0xFF,0xFF,0xFF,0x54, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xCC,0xFF,0xFF,0xFF,0x54, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xCC,0xFF,0xFF,0xFF,0x54, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xCC,0xFF,0xFF,0xFF,0x54, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xCC,0xFF,0xFF,0xFF,0x54, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 'r' + 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, 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, 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, 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, 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, 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, 0, + 0, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0x44,0x0B,0x79,0xCD,0xF0,0xF7,0xC9,0x60,0x05, + 0, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0x5B,0xD8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x4C, + 0, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0xE7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x4C, + 0, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0xFF,0xF8,0x80,0x27,0x08,0x1B,0x6F,0xF2,0x4C, + 0, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0xFC,0x42, 0, 0, 0, 0, 0,0x2F,0x3E, + 0, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0xA8, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0x66, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0x4E, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0x46, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 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, 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, 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, + 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, 0, 0, 0, +// 's' + 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, 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, 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, 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, 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, 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, 0, + 0, 0, 0, 0,0x12,0x79,0xC3,0xEC,0xFB,0xEE,0xD6,0xB5,0x70,0x26, 0, 0, 0, + 0, 0, 0,0x3A,0xEB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, + 0, 0,0x10,0xEA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, + 0, 0,0x63,0xFF,0xFF,0xFF,0xD0,0x3A,0x0C,0x09,0x23,0x40,0x85,0xD6,0x07, 0, 0, + 0, 0,0x88,0xFF,0xFF,0xFF,0x73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x7F,0xFF,0xFF,0xFF,0xF3,0x7B,0x22, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x3D,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE1,0xA2,0x5B,0x0A, 0, 0, 0, 0, + 0, 0, 0,0xA6,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xED,0x5B, 0, 0, 0, + 0, 0, 0,0x03,0x78,0xEC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x52, 0, 0, + 0, 0, 0, 0, 0,0x06,0x46,0x88,0xC5,0xF9,0xFF,0xFF,0xFF,0xFF,0xD3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0x0C,0x6F,0xFE,0xFF,0xFF,0xFF,0x0C, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xDC,0xFF,0xFF,0xFF,0x14, 0, + 0, 0,0x4C,0xC7,0x83,0x44,0x27,0x10,0x05,0x1D,0x76,0xFE,0xFF,0xFF,0xF1,0x02, 0, + 0, 0,0x50,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x95, 0, 0, + 0, 0,0x50,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC1,0x0E, 0, 0, + 0, 0,0x03,0x33,0x72,0xAF,0xD1,0xE7,0xFA,0xF6,0xDE,0xAE,0x58,0x02, 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, 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, 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, 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, +// 't' + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x60,0xFF,0xFF,0xFF,0xC4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x60,0xFF,0xFF,0xFF,0xC4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x60,0xFF,0xFF,0xFF,0xC4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x60,0xFF,0xFF,0xFF,0xC4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x60,0xFF,0xFF,0xFF,0xC4, 0, 0, 0, 0, 0, 0, 0, + 0,0x6C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x30, 0, + 0,0x6C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x30, 0, + 0,0x6C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x30, 0, + 0, 0, 0, 0, 0,0x60,0xFF,0xFF,0xFF,0xC4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x60,0xFF,0xFF,0xFF,0xC4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x60,0xFF,0xFF,0xFF,0xC4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x60,0xFF,0xFF,0xFF,0xC4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x60,0xFF,0xFF,0xFF,0xC4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x60,0xFF,0xFF,0xFF,0xC4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x60,0xFF,0xFF,0xFF,0xC4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x5F,0xFF,0xFF,0xFF,0xC4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x55,0xFF,0xFF,0xFF,0xD9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x37,0xFF,0xFF,0xFF,0xFF,0x6A,0x0F, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x07,0xED,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x30, 0, + 0, 0, 0, 0, 0, 0,0x6A,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x30, 0, + 0, 0, 0, 0, 0, 0, 0,0x41,0xA4,0xD8,0xF3,0xFD,0xFF,0xFF,0xFF,0x30, 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, 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, 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, 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, +// 'u' + 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, 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, 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, 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, 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, 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, 0, + 0, 0,0xBC,0xFF,0xFF,0xFF,0x6C, 0, 0, 0,0x20,0xFF,0xFF,0xFF,0xFF,0x08, 0, + 0, 0,0xBC,0xFF,0xFF,0xFF,0x6C, 0, 0, 0,0x20,0xFF,0xFF,0xFF,0xFF,0x08, 0, + 0, 0,0xBC,0xFF,0xFF,0xFF,0x6C, 0, 0, 0,0x20,0xFF,0xFF,0xFF,0xFF,0x08, 0, + 0, 0,0xBC,0xFF,0xFF,0xFF,0x6C, 0, 0, 0,0x20,0xFF,0xFF,0xFF,0xFF,0x08, 0, + 0, 0,0xBC,0xFF,0xFF,0xFF,0x6C, 0, 0, 0,0x20,0xFF,0xFF,0xFF,0xFF,0x08, 0, + 0, 0,0xBC,0xFF,0xFF,0xFF,0x6C, 0, 0, 0,0x20,0xFF,0xFF,0xFF,0xFF,0x08, 0, + 0, 0,0xBC,0xFF,0xFF,0xFF,0x6C, 0, 0, 0,0x20,0xFF,0xFF,0xFF,0xFF,0x08, 0, + 0, 0,0xBC,0xFF,0xFF,0xFF,0x6C, 0, 0, 0,0x20,0xFF,0xFF,0xFF,0xFF,0x08, 0, + 0, 0,0xBC,0xFF,0xFF,0xFF,0x6C, 0, 0, 0,0x20,0xFF,0xFF,0xFF,0xFF,0x08, 0, + 0, 0,0xBC,0xFF,0xFF,0xFF,0x6C, 0, 0, 0,0x28,0xFF,0xFF,0xFF,0xFF,0x08, 0, + 0, 0,0xB9,0xFF,0xFF,0xFF,0x7A, 0, 0, 0,0x43,0xFF,0xFF,0xFF,0xFF,0x08, 0, + 0, 0,0xAC,0xFF,0xFF,0xFF,0xA3, 0, 0, 0,0x91,0xFF,0xFF,0xFF,0xFF,0x08, 0, + 0, 0,0x83,0xFF,0xFF,0xFF,0xF5,0x4A,0x0E,0x59,0xF8,0xFF,0xFF,0xFF,0xFF,0x08, 0, + 0, 0,0x32,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF6,0xFF,0xFF,0xFF,0xFF,0x08, 0, + 0, 0, 0,0x9B,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0x75,0xFF,0xFF,0xFF,0xFF,0x08, 0, + 0, 0, 0,0x02,0x72,0xD4,0xF8,0xEE,0xBA,0x44,0x20,0xFF,0xFF,0xFF,0xFF,0x08, 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, 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, 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, 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, +// 'v' + 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, 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, 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, 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, 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, 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, 0, + 0,0xB4,0xFF,0xFF,0xFF,0x7A, 0, 0, 0, 0, 0,0x0A,0xF8,0xFF,0xFF,0xFF,0x2B, + 0,0x64,0xFF,0xFF,0xFF,0xBF, 0, 0, 0, 0, 0,0x49,0xFF,0xFF,0xFF,0xDA, 0, + 0,0x16,0xFD,0xFF,0xFF,0xF9,0x0B, 0, 0, 0, 0,0x8F,0xFF,0xFF,0xFF,0x89, 0, + 0, 0,0xC3,0xFF,0xFF,0xFF,0x49, 0, 0, 0, 0,0xD5,0xFF,0xFF,0xFF,0x38, 0, + 0, 0,0x72,0xFF,0xFF,0xFF,0x8F, 0, 0, 0,0x1B,0xFF,0xFF,0xFF,0xE6,0x01, 0, + 0, 0,0x21,0xFF,0xFF,0xFF,0xD4, 0, 0, 0,0x61,0xFF,0xFF,0xFF,0x97, 0, 0, + 0, 0, 0,0xD1,0xFF,0xFF,0xFF,0x1A, 0, 0,0xA6,0xFF,0xFF,0xFF,0x46, 0, 0, + 0, 0, 0,0x81,0xFF,0xFF,0xFF,0x5E, 0,0x01,0xEA,0xFF,0xFF,0xF0,0x05, 0, 0, + 0, 0, 0,0x30,0xFF,0xFF,0xFF,0xA3, 0,0x32,0xFF,0xFF,0xFF,0xA5, 0, 0, 0, + 0, 0, 0, 0,0xDF,0xFF,0xFF,0xE7,0x01,0x78,0xFF,0xFF,0xFF,0x54, 0, 0, 0, + 0, 0, 0, 0,0x8F,0xFF,0xFF,0xFF,0x2E,0xBE,0xFF,0xFF,0xF7,0x0C, 0, 0, 0, + 0, 0, 0, 0,0x3F,0xFF,0xFF,0xFF,0x7E,0xF8,0xFF,0xFF,0xB2, 0, 0, 0, 0, + 0, 0, 0, 0,0x03,0xEA,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0x62, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x9E,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,0x14, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x4D,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x08,0xF4,0xFF,0xFF,0xFF,0xFF,0x70, 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, 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, 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, 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, +// 'w' + 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, 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, 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, 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, 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, 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, 0, +0xE9,0xFF,0xFF,0x87, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x13,0xFF,0xFF,0xFF, +0xBC,0xFF,0xFF,0xAF, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF, +0x8E,0xFF,0xFF,0xD6, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x64,0xFF,0xFF,0xFA, +0x60,0xFF,0xFF,0xFA,0x04, 0, 0, 0, 0, 0, 0, 0, 0,0x8C,0xFF,0xFF,0xD2, +0x32,0xFF,0xFF,0xFF,0x26, 0,0x10,0xFE,0xFF,0xFF,0x81, 0, 0,0xB4,0xFF,0xFF,0xA4, +0x07,0xFB,0xFF,0xFF,0x4D, 0,0x44,0xFF,0xFF,0xFF,0xB6, 0, 0,0xDC,0xFF,0xFF,0x76, + 0,0xD6,0xFF,0xFF,0x75, 0,0x79,0xFF,0xFF,0xFF,0xEB, 0,0x07,0xFC,0xFF,0xFF,0x48, + 0,0xA8,0xFF,0xFF,0x9D, 0,0xAE,0xFF,0xF4,0xFF,0xFF,0x1F,0x2C,0xFF,0xFF,0xFF,0x1A, + 0,0x7A,0xFF,0xFF,0xC4, 0,0xE3,0xFF,0x93,0xFE,0xFF,0x54,0x54,0xFF,0xFF,0xEC, 0, + 0,0x4C,0xFF,0xFF,0xEC,0x18,0xFF,0xFF,0x47,0xD6,0xFF,0x89,0x7C,0xFF,0xFF,0xBE, 0, + 0,0x1E,0xFF,0xFF,0xFF,0x62,0xFF,0xFE,0x10,0x9B,0xFF,0xBD,0xA4,0xFF,0xFF,0x90, 0, + 0, 0,0xEF,0xFF,0xFF,0xBF,0xFF,0xD4, 0,0x61,0xFF,0xF1,0xCD,0xFF,0xFF,0x62, 0, + 0, 0,0xC2,0xFF,0xFF,0xFE,0xFF,0x9A, 0,0x26,0xFF,0xFF,0xFE,0xFF,0xFF,0x34, 0, + 0, 0,0x94,0xFF,0xFF,0xFF,0xFF,0x60, 0, 0,0xEA,0xFF,0xFF,0xFF,0xFD,0x09, 0, + 0, 0,0x66,0xFF,0xFF,0xFF,0xFF,0x26, 0, 0,0xB0,0xFF,0xFF,0xFF,0xD8, 0, 0, + 0, 0,0x37,0xFF,0xFF,0xFF,0xEC, 0, 0, 0,0x75,0xFF,0xFF,0xFF,0xAA, 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, 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, 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, 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, +// 'x' + 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, 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, 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, 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, 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, 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, 0, + 0,0x66,0xFF,0xFF,0xFF,0xFF,0x5E, 0, 0, 0,0x07,0xDF,0xFF,0xFF,0xFF,0xD5,0x08, + 0, 0,0xB1,0xFF,0xFF,0xFF,0xE2,0x08, 0, 0,0x76,0xFF,0xFF,0xFF,0xFA,0x31, 0, + 0, 0,0x15,0xE8,0xFF,0xFF,0xFF,0x78, 0,0x14,0xF0,0xFF,0xFF,0xFF,0x78, 0, 0, + 0, 0, 0,0x4A,0xFF,0xFF,0xFF,0xF1,0x14,0x94,0xFF,0xFF,0xFF,0xC3,0x02, 0, 0, + 0, 0, 0, 0,0x95,0xFF,0xFF,0xFF,0xB1,0xFB,0xFF,0xFF,0xF2,0x21, 0, 0, 0, + 0, 0, 0, 0,0x09,0xD7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x60, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x32,0xFA,0xFF,0xFF,0xFF,0xFF,0xAE, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x8D,0xFF,0xFF,0xFF,0xFA,0x16, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x10,0xE2,0xFF,0xFF,0xFF,0xFF,0x76, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0xA7,0xFF,0xFF,0xFF,0xFF,0xFF,0xF9,0x2E, 0, 0, 0, 0, + 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xE9,0xFF,0xFF,0xFF,0xD3,0x07, 0, 0, 0, + 0, 0, 0,0x1E,0xF0,0xFF,0xFF,0xFE,0x37,0xC3,0xFF,0xFF,0xFF,0x8D, 0, 0, 0, + 0, 0,0x02,0xC0,0xFF,0xFF,0xFF,0xA1, 0,0x32,0xFD,0xFF,0xFF,0xFE,0x41, 0, 0, + 0, 0,0x77,0xFF,0xFF,0xFF,0xF4,0x1A, 0, 0,0x9B,0xFF,0xFF,0xFF,0xE1,0x0F, 0, + 0,0x30,0xF9,0xFF,0xFF,0xFF,0x7B, 0, 0, 0,0x16,0xF0,0xFF,0xFF,0xFF,0xA4, 0, +0x08,0xD5,0xFF,0xFF,0xFF,0xE0,0x08, 0, 0, 0, 0,0x72,0xFF,0xFF,0xFF,0xFF,0x56, + 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, 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, 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, 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, +// 'y' + 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, 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, 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, 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, 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, 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, 0, +0x0A,0xF0,0xFF,0xFF,0xFF,0x60, 0, 0, 0, 0, 0, 0,0xDE,0xFF,0xFF,0xFF,0x78, + 0,0x97,0xFF,0xFF,0xFF,0xB9, 0, 0, 0, 0, 0,0x34,0xFF,0xFF,0xFF,0xFD,0x1C, + 0,0x34,0xFF,0xFF,0xFF,0xFC,0x16, 0, 0, 0, 0,0x8A,0xFF,0xFF,0xFF,0xBB, 0, + 0, 0,0xD0,0xFF,0xFF,0xFF,0x6C, 0, 0, 0, 0,0xDE,0xFF,0xFF,0xFF,0x5C, 0, + 0, 0,0x6D,0xFF,0xFF,0xFF,0xC5, 0, 0, 0,0x35,0xFF,0xFF,0xFF,0xF3,0x0A, 0, + 0, 0,0x11,0xF7,0xFF,0xFF,0xFE,0x1F, 0, 0,0x8A,0xFF,0xFF,0xFF,0x9F, 0, 0, + 0, 0, 0,0xA6,0xFF,0xFF,0xFF,0x78, 0, 0,0xDE,0xFF,0xFF,0xFF,0x40, 0, 0, + 0, 0, 0,0x43,0xFF,0xFF,0xFF,0xD1, 0,0x35,0xFF,0xFF,0xFF,0xE0,0x01, 0, 0, + 0, 0, 0,0x01,0xDE,0xFF,0xFF,0xFF,0x2A,0x8B,0xFF,0xFF,0xFF,0x83, 0, 0, 0, + 0, 0, 0, 0,0x7C,0xFF,0xFF,0xFF,0x84,0xDF,0xFF,0xFF,0xFF,0x25, 0, 0, 0, + 0, 0, 0, 0,0x1C,0xFC,0xFF,0xFF,0xF2,0xFF,0xFF,0xFF,0xC6, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0xB5,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x67, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x52,0xFF,0xFF,0xFF,0xFF,0xFF,0xF8,0x10, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x05,0xE9,0xFF,0xFF,0xFF,0xFF,0xAA, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x8B,0xFF,0xFF,0xFF,0xFF,0x4C, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x39,0xFF,0xFF,0xFF,0xE9,0x04, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x77,0xFF,0xFF,0xFF,0x8E, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x06,0xE0,0xFF,0xFF,0xFF,0x30, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0x03,0x21,0xA3,0xFF,0xFF,0xFF,0xC6, 0, 0, 0, 0, 0, 0, 0, + 0,0x34,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, + 0,0x34,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8B, 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x34,0xFF,0xFF,0xFF,0xF3,0xC9,0x56, 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, +// 'z' + 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, 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, 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, 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, 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, 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, 0, + 0, 0,0x5C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x50, 0, + 0, 0,0x5C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x50, 0, + 0, 0,0x5C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x50, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0x06,0xC0,0xFF,0xFF,0xFF,0xF3,0x26, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0xA2,0xFF,0xFF,0xFF,0xFC,0x4A, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,0x80,0xFF,0xFF,0xFF,0xFF,0x6B, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xFF,0x8E, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x3E,0xF9,0xFF,0xFF,0xFF,0xB0,0x02, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x27,0xED,0xFF,0xFF,0xFF,0xCB,0x0A, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0x14,0xDC,0xFF,0xFF,0xFF,0xE1,0x18, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0x08,0xC5,0xFF,0xFF,0xFF,0xF1,0x2C, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x01,0xA9,0xFF,0xFF,0xFF,0xFB,0x46, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x7D,0xFF,0xFF,0xFF,0xFF,0x66, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x50, 0, + 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x50, 0, + 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x50, 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, 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, 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, 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, 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, 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, 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,0x31,0x9C,0xD3,0xF1,0xFC,0xFF,0xE8, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x40,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xE8, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xBC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE8, 0, 0, + 0, 0, 0, 0, 0, 0,0x02,0xF6,0xFF,0xFF,0xFF,0x6D,0x15, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x14,0xFF,0xFF,0xFF,0xD8, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x1E,0xFF,0xFF,0xFF,0xB9, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x20,0xFF,0xFF,0xFF,0xB4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x20,0xFF,0xFF,0xFF,0xB4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x22,0xFF,0xFF,0xFF,0xB3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x36,0xFF,0xFF,0xFF,0xAD, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x77,0xFF,0xFF,0xFF,0x97, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0x02,0x17,0x63,0xF3,0xFF,0xFF,0xFF,0x5A, 0, 0, 0, 0, 0, 0, + 0, 0,0x80,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xB6,0x04, 0, 0, 0, 0, 0, 0, + 0, 0,0x80,0xFF,0xFF,0xFF,0xFF,0xF3,0x7E,0x01, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x80,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xB3,0x03, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0x02,0x18,0x66,0xF4,0xFF,0xFF,0xFF,0x56, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x79,0xFF,0xFF,0xFF,0x96, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x36,0xFF,0xFF,0xFF,0xAD, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x22,0xFF,0xFF,0xFF,0xB3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x20,0xFF,0xFF,0xFF,0xB4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x20,0xFF,0xFF,0xFF,0xB4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x1E,0xFF,0xFF,0xFF,0xBA, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x14,0xFF,0xFF,0xFF,0xD8, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x02,0xF5,0xFF,0xFF,0xFF,0x6D,0x14, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xBB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE8, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x40,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xE8, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,0x32,0x9D,0xD5,0xF2,0xFC,0xFF,0xE8, 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, 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, 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, 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, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 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, 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, 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,0x74,0xFF,0xFF,0xF6,0xE4,0xB9,0x66,0x03, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x74,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA8, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x74,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x28, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0x08,0x35,0xD4,0xFF,0xFF,0xFF,0x64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x65,0xFF,0xFF,0xFF,0x7F, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x46,0xFF,0xFF,0xFF,0x8A, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x40,0xFF,0xFF,0xFF,0x8C, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x40,0xFF,0xFF,0xFF,0x8C, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x40,0xFF,0xFF,0xFF,0x8E, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x3B,0xFF,0xFF,0xFF,0xA1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x24,0xFF,0xFF,0xFF,0xE0,0x04, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x01,0xE6,0xFF,0xFF,0xFF,0xAA,0x30,0x08, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x54,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF,0xF8, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,0x33,0xD0,0xFF,0xFF,0xFF,0xFF,0xF8, 0, 0, + 0, 0, 0, 0, 0, 0, 0,0x4F,0xF6,0xFF,0xFF,0xFF,0xFF,0xFF,0xF8, 0, 0, + 0, 0, 0, 0, 0, 0,0x01,0xE4,0xFF,0xFF,0xFF,0xAD,0x32,0x09, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x23,0xFF,0xFF,0xFF,0xE1,0x04, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x3B,0xFF,0xFF,0xFF,0xA1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x40,0xFF,0xFF,0xFF,0x8E, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x40,0xFF,0xFF,0xFF,0x8C, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x40,0xFF,0xFF,0xFF,0x8C, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x47,0xFF,0xFF,0xFF,0x8A, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,0x67,0xFF,0xFF,0xFF,0x7F, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0x08,0x34,0xD5,0xFF,0xFF,0xFF,0x63, 0, 0, 0, 0, 0, 0, + 0, 0,0x74,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x27, 0, 0, 0, 0, 0, 0, + 0, 0,0x74,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA8, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x74,0xFF,0xFF,0xF7,0xE5,0xBA,0x68,0x03, 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, 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, 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, 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, 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, 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, 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, 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, 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, + 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, 0, 0, 0, + 0, 0,0x1B,0x93,0xDF,0xF8,0xE1,0xAA,0x46, 0, 0, 0, 0, 0, 0,0x65,0x34, + 0,0x50,0xF2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xCC,0x5F,0x1D,0x09,0x3A,0xAD,0xFF,0x38, + 0,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x38, + 0,0xC0,0xE5,0x69,0x1C,0x08,0x28,0x6E,0xDA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xB3,0x0C, + 0,0x7C,0x0F, 0, 0, 0, 0, 0,0x02,0x51,0xB7,0xEC,0xF3,0xC3,0x5B,0x01, 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, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, +// Small +// ' ' + 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, + 0, 0, 0,0xB4,0xFF,0x20, 0, 0, + 0, 0, 0,0xB4,0xFF,0x20, 0, 0, + 0, 0, 0,0xB4,0xFF,0x20, 0, 0, + 0, 0, 0,0xB4,0xFF,0x20, 0, 0, + 0, 0, 0,0xB1,0xFF,0x1D, 0, 0, + 0, 0, 0,0x9B,0xFF,0x09, 0, 0, + 0, 0, 0,0x81,0xF3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0xB4,0xFF,0x20, 0, 0, + 0, 0, 0,0xB4,0xFF,0x20, 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, 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,0x6C,0xFF,0x54, 0,0xEC,0xD4, 0, + 0,0x6C,0xFF,0x54, 0,0xEC,0xD4, 0, + 0,0x6C,0xFF,0x54, 0,0xEC,0xD4, 0, + 0,0x6C,0xFF,0x54, 0,0xEC,0xD4, 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, 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, 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, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0xCC,0xB8, 0,0xE4,0xA2, + 0, 0,0x08,0xFA,0x81,0x1A,0xFF,0x69, + 0, 0,0x39,0xFF,0x4B,0x51,0xFF,0x30, +0x34,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0, 0,0xD5,0xAE,0x01,0xEB,0x97, 0, + 0,0x15,0xFE,0x6C,0x2C,0xFF,0x57, 0, +0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x9C, + 0,0xB0,0xD4, 0,0xC4,0xBF, 0, 0, + 0,0xE6,0x9D,0x04,0xF5,0x87, 0, 0, +0x1D,0xFF,0x67,0x31,0xFF,0x4F, 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, 0, 0, 0, +// '$' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0x38,0xC0, 0, 0, 0, + 0, 0, 0,0x38,0xC0, 0, 0, 0, + 0,0x18,0xAB,0xF0,0xFF,0xFF,0xD4, 0, + 0,0xAB,0xFD,0x66,0xC2,0x38,0x95, 0, + 0,0xD3,0xFD,0x55,0xC0, 0, 0, 0, + 0,0x81,0xFF,0xFB,0xE9,0x76,0x0E, 0, + 0, 0,0x56,0xBA,0xFF,0xFF,0xD7,0x09, + 0, 0, 0,0x38,0xC1,0xA5,0xFF,0x59, + 0,0x68, 0,0x38,0xC0,0x67,0xFF,0x6A, + 0,0xD4,0x95,0x4A,0xC3,0xAB,0xFB,0x29, + 0,0x2F,0xAC,0xEE,0xFE,0xD6,0x51, 0, + 0, 0, 0,0x38,0xC0, 0, 0, 0, + 0, 0, 0,0x38,0xC0, 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, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +0x20,0xC4,0xF4,0xAD,0x0B, 0, 0, 0, +0xA9,0xAA,0x11,0xD3,0x79, 0, 0, 0, +0xAA,0xA9,0x10,0xD2,0x79, 0, 0, 0, +0x21,0xC6,0xF4,0xAF,0x0C,0x0A,0x6F,0x8F, + 0, 0, 0,0x0D,0x77,0x9D,0x37, 0, + 0,0x11,0x7D,0x99,0x2F, 0, 0, 0, +0x2F,0x94,0x28, 0,0x47,0xDD,0xEE,0x7C, + 0, 0, 0, 0,0xE9,0x6A,0x2A,0xFB, + 0, 0, 0, 0,0xEA,0x68,0x28,0xFB, + 0, 0, 0, 0,0x49,0xDE,0xEF,0x80, + 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, 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,0x02,0x89,0xE4,0xF6,0x9A,0x09, 0, + 0,0x59,0xFF,0x9A,0x0C,0x5D,0x45, 0, + 0,0x6E,0xFF,0x9F, 0, 0, 0, 0, + 0,0x1B,0xF7,0xF7,0x1F, 0, 0, 0, + 0,0x8A,0xFF,0xFF,0xB2, 0, 0, 0, +0x5B,0xFF,0xA9,0xBF,0xFF,0x55,0x45,0xFF, +0xAF,0xFF,0x2E,0x2B,0xFB,0xE7,0x65,0xFF, +0xA6,0xFF,0x36, 0,0x8D,0xFF,0xF7,0xEF, +0x47,0xFE,0xC1,0x1C,0x2D,0xFC,0xFF,0x85, + 0,0x51,0xCD,0xF6,0xF1,0xC4,0xF5,0xE5, + 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, 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,0xAC,0xFF,0x14, 0, 0, + 0, 0, 0,0xAC,0xFF,0x14, 0, 0, + 0, 0, 0,0xAC,0xFF,0x14, 0, 0, + 0, 0, 0,0xAC,0xFF,0x14, 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, 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, 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, 0, 0, 0, 0, 0, + 0, 0, 0, 0,0x8D,0xF6,0x18, 0, + 0, 0, 0,0x2B,0xFC,0x92, 0, 0, + 0, 0, 0,0xA0,0xFF,0x2F, 0, 0, + 0, 0,0x06,0xF5,0xE1, 0, 0, 0, + 0, 0,0x39,0xFF,0xAD, 0, 0, 0, + 0, 0,0x55,0xFF,0x95, 0, 0, 0, + 0, 0,0x56,0xFF,0x95, 0, 0, 0, + 0, 0,0x3A,0xFF,0xAE, 0, 0, 0, + 0, 0,0x07,0xF7,0xE2, 0, 0, 0, + 0, 0, 0,0xA3,0xFF,0x30, 0, 0, + 0, 0, 0,0x2D,0xFC,0x93, 0, 0, + 0, 0, 0, 0,0x8D,0xF6,0x18, 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, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0xA3,0xE9,0x12, 0, 0, 0, + 0, 0,0x25,0xFE,0x97, 0, 0, 0, + 0, 0, 0,0xC0,0xF8,0x17, 0, 0, + 0, 0, 0,0x72,0xFF,0x6B, 0, 0, + 0, 0, 0,0x3D,0xFF,0xA8, 0, 0, + 0, 0, 0,0x25,0xFF,0xC4, 0, 0, + 0, 0, 0,0x26,0xFF,0xC4, 0, 0, + 0, 0, 0,0x3E,0xFF,0xA8, 0, 0, + 0, 0, 0,0x73,0xFF,0x6B, 0, 0, + 0, 0, 0,0xC1,0xF8,0x17, 0, 0, + 0, 0,0x26,0xFE,0x98, 0, 0, 0, + 0, 0,0xA3,0xEA,0x12, 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, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0x64,0xC8, 0, 0, 0, +0x08,0xC9,0x68,0x69,0xC8,0x35,0xB6,0x55, + 0,0x38,0xB6,0xF9,0xFA,0xE1,0x6B,0x07, + 0,0x38,0xB5,0xF8,0xF9,0xE1,0x6A,0x07, +0x08,0xC9,0x67,0x69,0xC8,0x33,0xB6,0x55, + 0, 0, 0,0x64,0xC8, 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, 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, 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, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0x98,0xFF,0x08, 0, 0, + 0, 0, 0,0x98,0xFF,0x08, 0, 0, + 0, 0, 0,0x98,0xFF,0x08, 0, 0, +0x8C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF8, +0x8C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF8, + 0, 0, 0,0x98,0xFF,0x08, 0, 0, + 0, 0, 0,0x98,0xFF,0x08, 0, 0, + 0, 0, 0,0x98,0xFF,0x08, 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, 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, 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, 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, 0,0xD8,0xFF,0x4C, 0, 0, + 0, 0, 0,0xDC,0xFF,0x43, 0, 0, + 0, 0,0x18,0xFE,0xCD,0x02, 0, 0, + 0, 0,0x62,0xFF,0x3D, 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, 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, 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,0xF0,0xFF,0xFF,0xFF,0x60, 0, + 0, 0,0xF0,0xFF,0xFF,0xFF,0x60, 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, 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, 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, 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, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0xF0,0xFF,0x58, 0, 0, + 0, 0, 0,0xF0,0xFF,0x58, 0, 0, + 0, 0, 0,0xF0,0xFF,0x58, 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, 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, 0,0x1B,0xFA,0x6E, + 0, 0, 0, 0, 0,0x88,0xEF,0x0C, + 0, 0, 0, 0,0x0C,0xEF,0x88, 0, + 0, 0, 0, 0,0x6E,0xFA,0x1B, 0, + 0, 0, 0,0x02,0xDD,0xA3, 0, 0, + 0, 0, 0,0x53,0xFF,0x31, 0, 0, + 0, 0, 0,0xC6,0xBE, 0, 0, 0, + 0, 0,0x38,0xFF,0x4B, 0, 0, 0, + 0, 0,0xAB,0xD7,0x01, 0, 0, 0, + 0,0x20,0xFC,0x66, 0, 0, 0, 0, + 0,0x90,0xEA,0x08, 0, 0, 0, 0, +0x0F,0xF3,0x81, 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, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x01,0x81,0xE7,0xF7,0xBD,0x25, 0, + 0,0x6F,0xFF,0x80,0x26,0xF0,0xD9,0x04, + 0,0xD9,0xFF,0x10, 0,0xA3,0xFF,0x48, +0x0D,0xFF,0xEE, 0, 0,0x80,0xFF,0x7C, +0x22,0xFF,0xE2,0x6B,0xD3,0x74,0xFF,0x92, +0x23,0xFF,0xE2,0x6D,0xD5,0x74,0xFF,0x91, +0x0D,0xFF,0xEE, 0, 0,0x80,0xFF,0x7C, + 0,0xD9,0xFF,0x10, 0,0xA3,0xFF,0x49, + 0,0x6F,0xFF,0x80,0x26,0xF0,0xDB,0x05, + 0,0x01,0x82,0xE8,0xF8,0xBE,0x26, 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, 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,0x13,0x80,0xED,0xFF,0x80, 0, 0, + 0,0x7C,0x7F,0x86,0xFF,0x80, 0, 0, + 0, 0, 0,0x74,0xFF,0x80, 0, 0, + 0, 0, 0,0x74,0xFF,0x80, 0, 0, + 0, 0, 0,0x74,0xFF,0x80, 0, 0, + 0, 0, 0,0x74,0xFF,0x80, 0, 0, + 0, 0, 0,0x74,0xFF,0x80, 0, 0, + 0, 0, 0,0x74,0xFF,0x80, 0, 0, + 0, 0, 0,0x74,0xFF,0x80, 0, 0, + 0,0xB8,0xFF,0xFF,0xFF,0xFF,0xFF,0xC4, + 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, 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,0x41,0xBA,0xF6,0xE6,0xA2,0x1A, 0, + 0,0xBD,0x41,0x08,0x49,0xFC,0xCF,0x02, + 0, 0, 0, 0, 0,0xD8,0xFF,0x29, + 0, 0, 0, 0,0x0C,0xF8,0xFF,0x27, + 0, 0, 0, 0,0x8A,0xFF,0xD9,0x02, + 0, 0, 0,0x4D,0xFE,0xFA,0x3D, 0, + 0, 0,0x2B,0xF2,0xFD,0x59, 0, 0, + 0,0x13,0xDD,0xFF,0x67, 0, 0, 0, +0x05,0xC1,0xFF,0x72, 0, 0, 0, 0, +0x37,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x44, + 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, 0, +// '3' + 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,0x30,0xAF,0xF4,0xED,0xBB,0x38, 0, + 0,0xA7,0x4D,0x09,0x32,0xF0,0xF2,0x12, + 0, 0, 0, 0, 0,0xB6,0xFF,0x3B, + 0, 0, 0,0x01,0x2F,0xEC,0xDF,0x0C, + 0, 0,0x54,0xFF,0xFF,0xD7,0x29, 0, + 0, 0, 0,0x01,0x33,0xE7,0xE9,0x18, + 0, 0, 0, 0, 0,0x85,0xFF,0x6E, + 0, 0, 0, 0, 0,0x7B,0xFF,0x6E, +0x22,0xA6,0x37,0x0D,0x2B,0xDF,0xF5,0x25, +0x01,0x57,0xC5,0xF2,0xEC,0xBC,0x3E, 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, 0, 0, +// '4' + 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,0x04,0xC8,0xFF,0xAC, 0, + 0, 0, 0,0x88,0xFF,0xFF,0xAC, 0, + 0, 0,0x44,0xFE,0xC0,0xFF,0xAC, 0, + 0,0x15,0xE7,0xD1,0x45,0xFF,0xAC, 0, +0x01,0xB6,0xFB,0x31,0x40,0xFF,0xAC, 0, +0x43,0xFF,0x81, 0,0x40,0xFF,0xAC, 0, +0x4C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xCC, + 0, 0, 0, 0,0x40,0xFF,0xAC, 0, + 0, 0, 0, 0,0x40,0xFF,0xAC, 0, + 0, 0, 0, 0,0x40,0xFF,0xAC, 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, 0, 0, +// '5' + 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,0xB0,0xFF,0xFF,0xFF,0xFF,0xDC, 0, + 0,0xB0,0xF4, 0, 0, 0, 0, 0, + 0,0xB0,0xF4, 0, 0, 0, 0, 0, + 0,0xB0,0xFE,0xF4,0xEC,0xAC,0x1C, 0, + 0,0x86,0x44,0x0E,0x5A,0xFC,0xD7,0x07, + 0, 0, 0, 0, 0,0xAA,0xFF,0x50, + 0, 0, 0, 0, 0,0x85,0xFF,0x73, + 0, 0, 0, 0, 0,0xA7,0xFF,0x57, +0x03,0xAA,0x2D,0x0C,0x57,0xFA,0xDB,0x08, + 0,0x49,0xC2,0xF3,0xE1,0x9B,0x17, 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, 0, 0, +// '6' + 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,0x43,0xC2,0xF4,0xE1,0x65, 0, + 0,0x3E,0xFB,0x9E,0x18,0x1E,0x9C,0x0B, + 0,0xBB,0xF3,0x09, 0, 0, 0, 0, +0x03,0xF7,0xEB,0xC6,0xF5,0xDF,0x6D, 0, +0x15,0xFF,0xFF,0x90,0x13,0xC1,0xFF,0x40, +0x17,0xFF,0xFF,0x26, 0,0x5C,0xFF,0x8E, +0x06,0xFD,0xFF,0x11, 0,0x45,0xFF,0xA2, + 0,0xD3,0xFF,0x26, 0,0x5B,0xFF,0x83, + 0,0x6F,0xFF,0x90,0x12,0xC0,0xFB,0x26, + 0,0x01,0x7E,0xE3,0xF7,0xCE,0x48, 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, 0, 0, +// '7' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +0x14,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x60, + 0, 0, 0, 0,0x0B,0xF4,0xFF,0x4D, + 0, 0, 0, 0,0x5E,0xFF,0xE9,0x05, + 0, 0, 0, 0,0xBD,0xFF,0x88, 0, + 0, 0, 0,0x1D,0xFD,0xFE,0x23, 0, + 0, 0, 0,0x7A,0xFF,0xBA, 0, 0, + 0, 0, 0,0xD8,0xFF,0x53, 0, 0, + 0, 0,0x38,0xFF,0xE7,0x05, 0, 0, + 0, 0,0x96,0xFF,0x85, 0, 0, 0, + 0,0x06,0xED,0xFE,0x21, 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, 0, 0, 0, 0, +// '8' + 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,0x0D,0x99,0xE7,0xF4,0xC7,0x40, 0, + 0,0x9A,0xFF,0x4D,0x15,0xCD,0xF4,0x15, + 0,0xD1,0xF4, 0, 0,0x89,0xFF,0x40, + 0,0x8B,0xFF,0x4C,0x14,0xCE,0xEA,0x10, + 0,0x08,0xC3,0xFF,0xFF,0xF8,0x47, 0, + 0,0xA7,0xFC,0x46,0x15,0xC4,0xF2,0x22, +0x0F,0xFF,0xC5, 0, 0,0x56,0xFF,0x7A, +0x0B,0xFE,0xC5, 0, 0,0x57,0xFF,0x74, + 0,0xBB,0xFC,0x46,0x15,0xC6,0xFA,0x2B, + 0,0x18,0xA2,0xE7,0xF4,0xCA,0x4A, 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, 0, 0, +// '9' + 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,0x13,0xA4,0xEA,0xF3,0xB4,0x21, 0, + 0,0xB5,0xFB,0x3B,0x32,0xF7,0xD5,0x03, +0x15,0xFF,0xC6, 0, 0,0xBA,0xFF,0x3E, +0x33,0xFF,0xB1, 0, 0,0xA5,0xFF,0x6E, +0x1F,0xFF,0xC6, 0, 0,0xBA,0xFF,0x82, +0x01,0xCE,0xFB,0x3A,0x31,0xF7,0xFF,0x80, + 0,0x26,0xBF,0xF5,0xE7,0xC8,0xFF,0x66, + 0, 0, 0, 0, 0,0x8D,0xFF,0x27, + 0,0x73,0x3F,0x0C,0x4B,0xF2,0xA5, 0, + 0,0x23,0xBC,0xF7,0xDF,0x85,0x06, 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, 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, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0xF0,0xFF,0x58, 0, 0, + 0, 0, 0,0xF0,0xFF,0x58, 0, 0, + 0, 0, 0,0xF0,0xFF,0x58, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0xF0,0xFF,0x58, 0, 0, + 0, 0, 0,0xF0,0xFF,0x58, 0, 0, + 0, 0, 0,0xF0,0xFF,0x58, 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, 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, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0xF0,0xFF,0x58, 0, 0, + 0, 0, 0,0xF0,0xFF,0x58, 0, 0, + 0, 0, 0,0xF0,0xFF,0x58, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0xF0,0xFF,0x58, 0, 0, + 0, 0, 0,0xF3,0xFF,0x4F, 0, 0, + 0, 0,0x21,0xFF,0xD7,0x04, 0, 0, + 0, 0,0x5B,0xFF,0x49, 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, 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, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x1F,0x7E,0xB2, + 0, 0,0x09,0x5B,0xBC,0xFE,0xFE,0xA6, +0x21,0x99,0xF1,0xFF,0xCA,0x72,0x1B, 0, +0x64,0xFF,0xDF,0x3F, 0, 0, 0, 0, +0x23,0x9E,0xF3,0xFE,0xC4,0x6D,0x19, 0, + 0, 0,0x0B,0x5F,0xBF,0xFE,0xFD,0xA5, + 0, 0, 0, 0, 0,0x21,0x80,0xB3, + 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, 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, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +0x64,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD4, +0x64,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD4, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +0x64,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD4, +0x64,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD4, + 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, 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, 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, +0x5C,0xA9,0x48,0x02, 0, 0, 0, 0, +0x46,0xED,0xFF,0xE4,0x86,0x26, 0, 0, + 0,0x05,0x4C,0xA4,0xF3,0xFF,0xC4,0x59, + 0, 0, 0, 0,0x10,0xA3,0xFF,0xD4, + 0,0x04,0x48,0x9F,0xEF,0xFF,0xC8,0x5C, +0x46,0xEC,0xFF,0xE6,0x89,0x28, 0, 0, +0x5C,0xAA,0x4A,0x03, 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, 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, 0, 0, 0, 0, 0, 0, + 0,0x0B,0x7F,0xD9,0xF6,0xD4,0x5A, 0, + 0,0x5B,0x79,0x1F,0x12,0xD2,0xFE,0x23, + 0, 0, 0, 0,0x06,0xDB,0xFF,0x29, + 0, 0, 0,0x04,0xAE,0xFF,0x86, 0, + 0, 0, 0,0x90,0xFF,0x83, 0, 0, + 0, 0, 0,0xE7,0xE9,0x01, 0, 0, + 0, 0, 0,0xFC,0xD4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0xFC,0xD4, 0, 0, 0, + 0, 0, 0,0xFC,0xD4, 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, 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,0x65,0xD1,0xF7,0xDD,0x75,0x01, + 0,0x8B,0xE9,0x4B,0x09,0x3F,0xEF,0x69, +0x36,0xFE,0x45, 0, 0, 0,0x8D,0xC9, +0x9B,0xD2, 0,0x4F,0xDE,0xEF,0xCF,0xE9, +0xD4,0x91,0x16,0xF4,0x80,0x12,0xC5,0xEC, +0xEC,0x74,0x4E,0xFF,0x1A, 0,0x66,0xEC, +0xEB,0x6F,0x4E,0xFF,0x19, 0,0x67,0xEC, +0xCF,0x8E,0x15,0xF4,0x80,0x12,0xC5,0xEC, +0x8E,0xD6, 0,0x4F,0xDE,0xF2,0xD2,0xEC, +0x24,0xF8,0x5F, 0, 0, 0, 0, 0, + 0,0x61,0xF6,0x74,0x16,0x13,0x72,0x71, + 0, 0,0x3C,0xB3,0xED,0xF8,0xDD,0x78, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +// 'A' + 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,0x28,0xFF,0xFF,0x96, 0, 0, + 0, 0,0x6E,0xFF,0xFE,0xDD, 0, 0, + 0, 0,0xB5,0xFE,0xB4,0xFF,0x23, 0, + 0,0x07,0xF5,0xD6,0x67,0xFF,0x6A, 0, + 0,0x43,0xFF,0x9B,0x2C,0xFF,0xB0, 0, + 0,0x8A,0xFF,0x61,0x01,0xEF,0xF1,0x04, + 0,0xD0,0xFF,0xFF,0xFF,0xFF,0xFF,0x3D, +0x18,0xFE,0xC1, 0, 0,0x56,0xFF,0x83, +0x5E,0xFF,0x8D, 0, 0,0x20,0xFF,0xCA, +0xA5,0xFF,0x59, 0, 0, 0,0xEA,0xFD, + 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, 0, +// 'B' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +0x24,0xFF,0xFF,0xFF,0xF6,0xD6,0x71, 0, +0x24,0xFF,0xCC, 0,0x10,0xBD,0xFF,0x54, +0x24,0xFF,0xCC, 0, 0,0x78,0xFF,0x84, +0x24,0xFF,0xCC, 0,0x0E,0xB8,0xFE,0x45, +0x24,0xFF,0xFF,0xFF,0xFF,0xF5,0x75, 0, +0x24,0xFF,0xCC, 0,0x0E,0x9E,0xFF,0x6A, +0x24,0xFF,0xCC, 0, 0,0x30,0xFF,0xD3, +0x24,0xFF,0xCC, 0, 0,0x2C,0xFF,0xDC, +0x24,0xFF,0xCC, 0,0x0C,0x93,0xFF,0x9A, +0x24,0xFF,0xFF,0xFF,0xFC,0xE3,0x99,0x0D, + 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, 0, +// 'C' + 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,0x22,0xA9,0xEC,0xEF,0xA0,0x0E, + 0,0x17,0xE8,0xF1,0x3F,0x0F,0x5A,0x53, + 0,0x8B,0xFF,0x89, 0, 0, 0, 0, + 0,0xD0,0xFF,0x44, 0, 0, 0, 0, + 0,0xED,0xFF,0x2E, 0, 0, 0, 0, + 0,0xED,0xFF,0x2D, 0, 0, 0, 0, + 0,0xD0,0xFF,0x44, 0, 0, 0, 0, + 0,0x8B,0xFF,0x89, 0, 0, 0, 0, + 0,0x17,0xE9,0xF3,0x4A,0x10,0x57,0x52, + 0, 0,0x23,0xAA,0xED,0xF0,0x9F,0x0E, + 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, 0, +// 'D' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +0x10,0xFF,0xFF,0xF9,0xDD,0x94,0x16, 0, +0x10,0xFF,0xF4,0x07,0x51,0xF6,0xDB,0x0C, +0x10,0xFF,0xF4, 0, 0,0x98,0xFF,0x6C, +0x10,0xFF,0xF4, 0, 0,0x62,0xFF,0xAB, +0x10,0xFF,0xF4, 0, 0,0x50,0xFF,0xC4, +0x10,0xFF,0xF4, 0, 0,0x51,0xFF,0xC4, +0x10,0xFF,0xF4, 0, 0,0x63,0xFF,0xAB, +0x10,0xFF,0xF4, 0, 0,0x98,0xFF,0x6C, +0x10,0xFF,0xF4,0x07,0x50,0xF6,0xDC,0x0C, +0x10,0xFF,0xFF,0xF9,0xDE,0x95,0x17, 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, 0, 0, +// 'E' + 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,0xD8,0xFF,0xFF,0xFF,0xFF,0xFF,0x80, + 0,0xD8,0xFF,0x2C, 0, 0, 0, 0, + 0,0xD8,0xFF,0x2C, 0, 0, 0, 0, + 0,0xD8,0xFF,0x2C, 0, 0, 0, 0, + 0,0xD8,0xFF,0xFF,0xFF,0xFF,0xFF,0x18, + 0,0xD8,0xFF,0x2C, 0, 0, 0, 0, + 0,0xD8,0xFF,0x2C, 0, 0, 0, 0, + 0,0xD8,0xFF,0x2C, 0, 0, 0, 0, + 0,0xD8,0xFF,0x2C, 0, 0, 0, 0, + 0,0xD8,0xFF,0xFF,0xFF,0xFF,0xFF,0x80, + 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, 0, +// 'F' + 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,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0x9C, + 0,0xC0,0xFF,0x44, 0, 0, 0, 0, + 0,0xC0,0xFF,0x44, 0, 0, 0, 0, + 0,0xC0,0xFF,0x44, 0, 0, 0, 0, + 0,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0x38, + 0,0xC0,0xFF,0x44, 0, 0, 0, 0, + 0,0xC0,0xFF,0x44, 0, 0, 0, 0, + 0,0xC0,0xFF,0x44, 0, 0, 0, 0, + 0,0xC0,0xFF,0x44, 0, 0, 0, 0, + 0,0xC0,0xFF,0x44, 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, 0, 0, 0, 0, 0, +// 'G' + 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,0x40,0xC0,0xF4,0xEF,0x8E,0x0A, + 0,0x41,0xFB,0xDA,0x2F,0x13,0x60,0x4F, + 0,0xC9,0xFF,0x43, 0, 0, 0, 0, +0x10,0xFF,0xFD,0x06, 0, 0, 0, 0, +0x2D,0xFF,0xEC, 0, 0, 0, 0, 0, +0x2D,0xFF,0xF1, 0,0x6C,0xFF,0xFF,0xB8, +0x10,0xFE,0xFF,0x09, 0,0x08,0xFF,0xB8, + 0,0xC8,0xFF,0x4B, 0,0x08,0xFF,0xB8, + 0,0x41,0xFB,0xCE,0x1F,0x20,0xFF,0xB8, + 0, 0,0x43,0xC4,0xF6,0xF3,0xD1,0x66, + 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, 0, +// 'H' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +0x10,0xFF,0xF4, 0, 0,0x88,0xFF,0x80, +0x10,0xFF,0xF4, 0, 0,0x88,0xFF,0x80, +0x10,0xFF,0xF4, 0, 0,0x88,0xFF,0x80, +0x10,0xFF,0xF4, 0, 0,0x88,0xFF,0x80, +0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80, +0x10,0xFF,0xF4, 0, 0,0x88,0xFF,0x80, +0x10,0xFF,0xF4, 0, 0,0x88,0xFF,0x80, +0x10,0xFF,0xF4, 0, 0,0x88,0xFF,0x80, +0x10,0xFF,0xF4, 0, 0,0x88,0xFF,0x80, +0x10,0xFF,0xF4, 0, 0,0x88,0xFF,0x80, + 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, 0, +// 'I' + 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,0xD4,0xFF,0xFF,0xFF,0xFF,0xFF,0x40, + 0, 0, 0,0xCC,0xFF,0x38, 0, 0, + 0, 0, 0,0xCC,0xFF,0x38, 0, 0, + 0, 0, 0,0xCC,0xFF,0x38, 0, 0, + 0, 0, 0,0xCC,0xFF,0x38, 0, 0, + 0, 0, 0,0xCC,0xFF,0x38, 0, 0, + 0, 0, 0,0xCC,0xFF,0x38, 0, 0, + 0, 0, 0,0xCC,0xFF,0x38, 0, 0, + 0, 0, 0,0xCC,0xFF,0x38, 0, 0, + 0,0xD4,0xFF,0xFF,0xFF,0xFF,0xFF,0x40, + 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, 0, +// 'J' + 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,0x98,0xFF,0xFF,0xFF,0xE4, 0, + 0, 0, 0, 0,0x20,0xFF,0xE4, 0, + 0, 0, 0, 0,0x20,0xFF,0xE4, 0, + 0, 0, 0, 0,0x20,0xFF,0xE4, 0, + 0, 0, 0, 0,0x20,0xFF,0xE4, 0, + 0, 0, 0, 0,0x20,0xFF,0xE4, 0, + 0, 0, 0, 0,0x20,0xFF,0xE4, 0, + 0, 0, 0, 0,0x25,0xFF,0xDD, 0, +0x3B,0x8C,0x28,0x09,0x7E,0xFF,0xAD, 0, +0x04,0x65,0xCE,0xF8,0xEF,0xB5,0x1D, 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, 0, 0, +// 'K' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +0x34,0xFF,0xD0, 0, 0,0x6B,0xFF,0xCF, +0x34,0xFF,0xD0, 0,0x3D,0xFA,0xE9,0x1E, +0x34,0xFF,0xD0,0x1C,0xE8,0xF9,0x3C, 0, +0x34,0xFF,0xD7,0xCA,0xFF,0x64, 0, 0, +0x34,0xFF,0xFF,0xFF,0xFF,0x57, 0, 0, +0x34,0xFF,0xFF,0xD4,0xFF,0xDD,0x06, 0, +0x34,0xFF,0xE7,0x0F,0xBF,0xFF,0x71, 0, +0x34,0xFF,0xD0, 0,0x37,0xFF,0xED,0x10, +0x34,0xFF,0xD0, 0, 0,0xAD,0xFF,0x8B, +0x34,0xFF,0xD0, 0, 0,0x28,0xFC,0xF8, + 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, 0, +// 'L' + 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,0x78,0xFF,0x90, 0, 0, 0, 0, + 0,0x78,0xFF,0x90, 0, 0, 0, 0, + 0,0x78,0xFF,0x90, 0, 0, 0, 0, + 0,0x78,0xFF,0x90, 0, 0, 0, 0, + 0,0x78,0xFF,0x90, 0, 0, 0, 0, + 0,0x78,0xFF,0x90, 0, 0, 0, 0, + 0,0x78,0xFF,0x90, 0, 0, 0, 0, + 0,0x78,0xFF,0x90, 0, 0, 0, 0, + 0,0x78,0xFF,0x90, 0, 0, 0, 0, + 0,0x78,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0, + 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, 0, +// 'M' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +0x68,0xFF,0xFF,0x25, 0,0xBA,0xFF,0xD8, +0x68,0xFF,0xFF,0x70,0x0B,0xF8,0xFF,0xD8, +0x68,0xFF,0xD6,0xBC,0x4E,0xEF,0xE6,0xD8, +0x68,0xFF,0x92,0xFA,0xA6,0xAE,0xE4,0xD8, +0x68,0xFF,0x59,0xF4,0xFE,0x6B,0xE4,0xD8, +0x68,0xFF,0x54,0xB6,0xFF,0x29,0xE4,0xD8, +0x68,0xFF,0x54, 0, 0, 0,0xE4,0xD8, +0x68,0xFF,0x54, 0, 0, 0,0xE4,0xD8, +0x68,0xFF,0x54, 0, 0, 0,0xE4,0xD8, +0x68,0xFF,0x54, 0, 0, 0,0xE4,0xD8, + 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, 0, +// 'N' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +0x30,0xFF,0xFF,0x2D, 0,0x2C,0xFF,0x9C, +0x30,0xFF,0xFF,0x92, 0,0x2C,0xFF,0x9C, +0x30,0xFF,0xFC,0xEE,0x08,0x2C,0xFF,0x9C, +0x30,0xFF,0xB6,0xFD,0x5A,0x2C,0xFF,0x9C, +0x30,0xFF,0x98,0xB6,0xBE,0x2C,0xFF,0x9C, +0x30,0xFF,0x98,0x51,0xFE,0x50,0xFF,0x9C, +0x30,0xFF,0x98,0x04,0xE8,0xB3,0xFF,0x9C, +0x30,0xFF,0x98, 0,0x88,0xFC,0xFF,0x9C, +0x30,0xFF,0x98, 0,0x24,0xFE,0xFF,0x9C, +0x30,0xFF,0x98, 0, 0,0xBE,0xFF,0x9C, + 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, 0, +// 'O' + 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,0x07,0x90,0xE9,0xF6,0xC2,0x31, 0, + 0,0x96,0xFF,0x6D,0x1F,0xE4,0xED,0x14, +0x0F,0xF9,0xEE,0x01, 0,0x83,0xFF,0x74, +0x42,0xFF,0xCB, 0, 0,0x5D,0xFF,0xAD, +0x5A,0xFF,0xBE, 0, 0,0x4F,0xFF,0xC5, +0x5A,0xFF,0xBE, 0, 0,0x4F,0xFF,0xC5, +0x43,0xFF,0xCB, 0, 0,0x5D,0xFF,0xAE, +0x0F,0xFA,0xEE,0x01, 0,0x83,0xFF,0x75, + 0,0x96,0xFF,0x6B,0x1F,0xE2,0xED,0x14, + 0,0x07,0x91,0xEB,0xF8,0xC3,0x32, 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, 0, 0, +// 'P' + 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,0xE4,0xFF,0xFF,0xF7,0xD8,0x81,0x02, + 0,0xE4,0xFF,0x20,0x15,0xB3,0xFF,0x78, + 0,0xE4,0xFF,0x20, 0,0x4D,0xFF,0xC2, + 0,0xE4,0xFF,0x20, 0,0x4E,0xFF,0xC1, + 0,0xE4,0xFF,0x20,0x14,0xB1,0xFF,0x78, + 0,0xE4,0xFF,0xFF,0xF8,0xD9,0x82,0x02, + 0,0xE4,0xFF,0x20, 0, 0, 0, 0, + 0,0xE4,0xFF,0x20, 0, 0, 0, 0, + 0,0xE4,0xFF,0x20, 0, 0, 0, 0, + 0,0xE4,0xFF,0x20, 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, 0, 0, 0, 0, 0, +// 'Q' + 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,0x07,0x90,0xE9,0xF6,0xC1,0x2E, 0, + 0,0x96,0xFF,0x6D,0x1F,0xE4,0xEA,0x11, +0x0F,0xF9,0xEE,0x01, 0,0x83,0xFF,0x70, +0x42,0xFF,0xCB, 0, 0,0x5D,0xFF,0xAA, +0x5A,0xFF,0xBE, 0, 0,0x4F,0xFF,0xC3, +0x5A,0xFF,0xBE, 0, 0,0x4F,0xFF,0xC4, +0x43,0xFF,0xCB, 0, 0,0x5D,0xFF,0xB1, +0x0F,0xFA,0xEE,0x01, 0,0x83,0xFF,0x7D, + 0,0x96,0xFF,0x6B,0x1F,0xE2,0xFA,0x22, + 0,0x07,0x91,0xEB,0xFF,0xFF,0x70, 0, + 0, 0, 0, 0,0x2C,0xF5,0xDF,0x1E, + 0, 0, 0, 0, 0,0x5E,0x95,0x03, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +// 'R' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +0x18,0xFF,0xFF,0xFF,0xF5,0xCC,0x55, 0, +0x18,0xFF,0xEC, 0,0x27,0xE7,0xFA,0x2A, +0x18,0xFF,0xEC, 0, 0,0xA0,0xFF,0x6A, +0x18,0xFF,0xEC, 0, 0,0xA1,0xFF,0x70, +0x18,0xFF,0xEC, 0,0x26,0xE7,0xF6,0x23, +0x18,0xFF,0xFF,0xFF,0xFF,0xEB,0x37, 0, +0x18,0xFF,0xEC,0x05,0x99,0xFF,0xA2, 0, +0x18,0xFF,0xEC, 0,0x0D,0xEE,0xFD,0x29, +0x18,0xFF,0xEC, 0, 0,0x81,0xFF,0xA9, +0x18,0xFF,0xEC, 0, 0,0x12,0xF3,0xFE, + 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, 0, +// 'S' + 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,0x15,0x9E,0xE6,0xF0,0xBD,0x46, 0, + 0,0xBA,0xFA,0x3D,0x07,0x38,0xB7,0x03, +0x0C,0xFE,0xEA,0x02, 0, 0, 0, 0, +0x0C,0xFE,0xFF,0xB1,0x2E, 0, 0, 0, + 0,0x9B,0xFF,0xFF,0xFF,0xBB,0x31, 0, + 0,0x01,0x5F,0xD4,0xFF,0xFF,0xF5,0x26, + 0, 0, 0, 0,0x4F,0xEB,0xFF,0x82, + 0, 0, 0, 0, 0,0x82,0xFF,0x83, +0x13,0xB8,0x48,0x14,0x17,0xC4,0xFD,0x3B, + 0,0x4C,0xBD,0xEE,0xF0,0xC9,0x53, 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, 0, 0, +// 'T' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +0x64,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD0, + 0, 0, 0,0xCC,0xFF,0x38, 0, 0, + 0, 0, 0,0xCC,0xFF,0x38, 0, 0, + 0, 0, 0,0xCC,0xFF,0x38, 0, 0, + 0, 0, 0,0xCC,0xFF,0x38, 0, 0, + 0, 0, 0,0xCC,0xFF,0x38, 0, 0, + 0, 0, 0,0xCC,0xFF,0x38, 0, 0, + 0, 0, 0,0xCC,0xFF,0x38, 0, 0, + 0, 0, 0,0xCC,0xFF,0x38, 0, 0, + 0, 0, 0,0xCC,0xFF,0x38, 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, 0, 0, 0, +// 'U' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +0x48,0xFF,0xBC, 0, 0,0x50,0xFF,0xB4, +0x48,0xFF,0xBC, 0, 0,0x50,0xFF,0xB4, +0x48,0xFF,0xBC, 0, 0,0x50,0xFF,0xB4, +0x48,0xFF,0xBC, 0, 0,0x50,0xFF,0xB4, +0x48,0xFF,0xBC, 0, 0,0x50,0xFF,0xB4, +0x48,0xFF,0xBC, 0, 0,0x50,0xFF,0xB4, +0x47,0xFF,0xBC, 0, 0,0x50,0xFF,0xB2, +0x2E,0xFF,0xC4, 0, 0,0x58,0xFF,0x99, +0x06,0xDE,0xF9,0x3B,0x11,0xB9,0xFF,0x50, + 0,0x2D,0xB6,0xEA,0xFB,0xDC,0x77, 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, 0, 0, +// 'V' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +0x7E,0xFF,0x87, 0, 0,0x18,0xFF,0xEB, +0x40,0xFF,0xBE, 0, 0,0x4F,0xFF,0xAE, +0x08,0xF9,0xF2,0x02, 0,0x86,0xFF,0x6F, + 0,0xC4,0xFF,0x2C, 0,0xBD,0xFF,0x31, + 0,0x86,0xFF,0x63,0x02,0xF1,0xF0,0x02, + 0,0x48,0xFF,0x9A,0x2B,0xFF,0xB4, 0, + 0,0x0D,0xFC,0xD1,0x62,0xFF,0x76, 0, + 0, 0,0xCC,0xFC,0xA5,0xFF,0x37, 0, + 0, 0,0x8E,0xFF,0xF8,0xF4,0x04, 0, + 0, 0,0x4F,0xFF,0xFF,0xBB, 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, 0, 0, 0, +// 'W' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +0xF0,0xD0, 0, 0, 0, 0,0x62,0xFF, +0xD0,0xE9, 0, 0, 0, 0,0x76,0xFF, +0xAF,0xFE,0x04, 0, 0, 0,0x8A,0xFF, +0x8F,0xFF,0x1B,0xB9,0xFF,0x28,0x9E,0xFD, +0x6F,0xFF,0x34,0xEA,0xFF,0x63,0xB1,0xE4, +0x4E,0xFF,0x6A,0xFF,0xC9,0x9E,0xC5,0xC6, +0x2E,0xFF,0xB5,0xE5,0x71,0xD9,0xD9,0xA8, +0x0D,0xFF,0xF7,0xAC,0x35,0xFF,0xF7,0x8A, + 0,0xED,0xFF,0x74,0x04,0xF5,0xFF,0x6C, + 0,0xCC,0xFF,0x3C, 0,0xBE,0xFF,0x4E, + 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, 0, +// 'X' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +0x71,0xFF,0xA6, 0, 0,0x38,0xFE,0xD7, +0x04,0xD5,0xFF,0x3C,0x01,0xCA,0xFF,0x46, + 0,0x42,0xFF,0xCE,0x64,0xFF,0xAF, 0, + 0, 0,0xAB,0xFF,0xFA,0xF7,0x21, 0, + 0, 0,0x1E,0xF6,0xFF,0x84, 0, 0, + 0, 0,0x2E,0xFC,0xFF,0x9A, 0, 0, + 0, 0,0xC1,0xFF,0xF1,0xFD,0x33, 0, + 0,0x58,0xFF,0xBC,0x4F,0xFF,0xC6,0x01, +0x0A,0xE3,0xFB,0x2A, 0,0xB8,0xFF,0x5E, +0x85,0xFF,0x8F, 0, 0,0x28,0xFA,0xE6, + 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, 0, +// 'Y' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +0xAE,0xFF,0x7A, 0, 0,0x15,0xF5,0xFA, +0x2B,0xFD,0xEC,0x0C, 0,0x8A,0xFF,0x97, + 0,0xA5,0xFF,0x78,0x14,0xF4,0xF7,0x1B, + 0,0x24,0xFB,0xEB,0x92,0xFF,0x8D, 0, + 0, 0,0x9B,0xFF,0xFF,0xF3,0x14, 0, + 0, 0,0x1D,0xF8,0xFF,0x82, 0, 0, + 0, 0, 0,0xCC,0xFF,0x38, 0, 0, + 0, 0, 0,0xCC,0xFF,0x38, 0, 0, + 0, 0, 0,0xCC,0xFF,0x38, 0, 0, + 0, 0, 0,0xCC,0xFF,0x38, 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, 0, 0, 0, +// 'Z' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD8, + 0, 0, 0, 0,0x0D,0xE3,0xFF,0xD3, + 0, 0, 0, 0,0x94,0xFF,0xFF,0x5F, + 0, 0, 0,0x39,0xFD,0xFF,0xB7, 0, + 0, 0,0x05,0xD4,0xFF,0xF1,0x1D, 0, + 0, 0,0x7D,0xFF,0xFF,0x67, 0, 0, + 0,0x27,0xF8,0xFF,0xBE,0x01, 0, 0, +0x01,0xC1,0xFF,0xF5,0x22, 0, 0, 0, +0x34,0xFF,0xFF,0x6F, 0, 0, 0, 0, +0x38,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF0, + 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, 0, +// '[' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x1C,0xFF,0xFF,0xFF,0x5C, 0, + 0, 0,0x1C,0xFF,0xB4, 0, 0, 0, + 0, 0,0x1C,0xFF,0xB4, 0, 0, 0, + 0, 0,0x1C,0xFF,0xB4, 0, 0, 0, + 0, 0,0x1C,0xFF,0xB4, 0, 0, 0, + 0, 0,0x1C,0xFF,0xB4, 0, 0, 0, + 0, 0,0x1C,0xFF,0xB4, 0, 0, 0, + 0, 0,0x1C,0xFF,0xB4, 0, 0, 0, + 0, 0,0x1C,0xFF,0xB4, 0, 0, 0, + 0, 0,0x1C,0xFF,0xB4, 0, 0, 0, + 0, 0,0x1C,0xFF,0xB4, 0, 0, 0, + 0, 0,0x1C,0xFF,0xFF,0xFF,0x5C, 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, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +0x10,0xF3,0x80, 0, 0, 0, 0, 0, + 0,0x91,0xEA,0x08, 0, 0, 0, 0, + 0,0x21,0xFC,0x66, 0, 0, 0, 0, + 0, 0,0xAC,0xD7,0x01, 0, 0, 0, + 0, 0,0x3A,0xFF,0x4B, 0, 0, 0, + 0, 0, 0,0xC7,0xBE, 0, 0, 0, + 0, 0, 0,0x55,0xFF,0x31, 0, 0, + 0, 0, 0,0x03,0xDF,0xA3, 0, 0, + 0, 0, 0, 0,0x71,0xFA,0x1B, 0, + 0, 0, 0, 0,0x0D,0xF0,0x88, 0, + 0, 0, 0, 0, 0,0x8C,0xEF,0x0C, + 0, 0, 0, 0, 0,0x1D,0xFB,0x6E, + 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, 0, + 0, 0,0xEC,0xFF,0xFF,0x8C, 0, 0, + 0, 0, 0,0x48,0xFF,0x8C, 0, 0, + 0, 0, 0,0x48,0xFF,0x8C, 0, 0, + 0, 0, 0,0x48,0xFF,0x8C, 0, 0, + 0, 0, 0,0x48,0xFF,0x8C, 0, 0, + 0, 0, 0,0x48,0xFF,0x8C, 0, 0, + 0, 0, 0,0x48,0xFF,0x8C, 0, 0, + 0, 0, 0,0x48,0xFF,0x8C, 0, 0, + 0, 0, 0,0x48,0xFF,0x8C, 0, 0, + 0, 0, 0,0x48,0xFF,0x8C, 0, 0, + 0, 0, 0,0x48,0xFF,0x8C, 0, 0, + 0, 0,0xEC,0xFF,0xFF,0x8C, 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, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x17,0xE8,0xFF,0x6E, 0, 0, + 0,0x02,0xBC,0xFF,0xF9,0xF9,0x34, 0, + 0,0x7E,0xFF,0x8E,0x32,0xED,0xDD,0x0F, +0x3F,0xFC,0x8C, 0, 0,0x30,0xEC,0xAB, + 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, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0, 0, 0, 0, 0, 0, 0, 0, +// '`' + 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x3F,0xFA,0x9A, 0, 0, 0, 0, + 0, 0,0x62,0xFE,0x40, 0, 0, 0, + 0, 0, 0,0x8B,0xDB,0x09, 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, 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, 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, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +// 'a' + 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x1D,0xA0,0xE1,0xF9,0xDB,0x6F, 0, + 0,0x7C,0x65,0x21,0x10,0xBA,0xFF,0x3F, + 0, 0, 0, 0, 0,0x6F,0xFF,0x80, + 0,0x4F,0xC6,0xEE,0xFF,0xFF,0xFF,0x92, +0x23,0xFB,0xF8,0x44,0x07,0x74,0xFF,0x94, +0x50,0xFF,0xD1, 0, 0,0x99,0xFF,0x94, +0x26,0xFD,0xF3,0x25,0x35,0xF0,0xFF,0x94, + 0,0x60,0xDC,0xF6,0xCE,0xAD,0xFF,0x94, + 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, 0, +// 'b' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0,0xF8,0xFF,0x04, 0, 0, 0, 0, + 0,0xF8,0xFF,0x04, 0, 0, 0, 0, + 0,0xF8,0xFF,0x04, 0, 0, 0, 0, + 0,0xF8,0xFF,0x91,0xEA,0xED,0x80, 0, + 0,0xF8,0xFF,0xA2,0x16,0xC5,0xFF,0x48, + 0,0xF8,0xFF,0x30, 0,0x5C,0xFF,0xA2, + 0,0xF8,0xFF,0x0D, 0,0x3A,0xFF,0xC2, + 0,0xF8,0xFF,0x0D, 0,0x3A,0xFF,0xC1, + 0,0xF8,0xFF,0x30, 0,0x5C,0xFF,0xA2, + 0,0xF8,0xFF,0xA2,0x16,0xC5,0xFF,0x46, + 0,0xF8,0xFF,0x92,0xEB,0xF0,0x82, 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, 0, 0, +// 'c' + 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,0x3C,0xC2,0xF6,0xE0,0x87,0x06, + 0,0x22,0xF7,0xE0,0x32,0x0D,0x72,0x3A, + 0,0x98,0xFF,0x67, 0, 0, 0, 0, + 0,0xC5,0xFF,0x39, 0, 0, 0, 0, + 0,0xC5,0xFF,0x38, 0, 0, 0, 0, + 0,0x98,0xFF,0x66, 0, 0, 0, 0, + 0,0x22,0xF7,0xDF,0x30,0x13,0x70,0x39, + 0, 0,0x3D,0xC3,0xF7,0xE2,0x82,0x05, + 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, 0, +// 'd' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,0x98,0xFF,0x68, + 0, 0, 0, 0, 0,0x98,0xFF,0x68, + 0, 0, 0, 0, 0,0x98,0xFF,0x68, + 0,0x34,0xD1,0xF6,0xC4,0xBE,0xFF,0x68, +0x01,0xDA,0xFD,0x44,0x40,0xFC,0xFF,0x68, +0x37,0xFF,0xCA, 0, 0,0xC4,0xFF,0x68, +0x56,0xFF,0xA9, 0, 0,0xA2,0xFF,0x68, +0x57,0xFF,0xA8, 0, 0,0xA2,0xFF,0x68, +0x37,0xFF,0xCA, 0, 0,0xC4,0xFF,0x68, +0x01,0xDB,0xFD,0x44,0x40,0xFC,0xFF,0x68, + 0,0x36,0xD4,0xF6,0xC5,0xBD,0xFF,0x68, + 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, 0, +// 'e' + 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x0B,0x94,0xE9,0xF4,0xCE,0x57, 0, + 0,0xA5,0xFE,0x50,0x0F,0xA7,0xFF,0x4D, +0x21,0xFE,0xC9, 0, 0,0x39,0xFF,0xB4, +0x4C,0xFF,0xFE,0xFC,0xFD,0xFF,0xFF,0xD7, +0x57,0xFF,0xB8, 0, 0, 0, 0, 0, +0x2B,0xFF,0xE2,0x02, 0, 0, 0, 0, + 0,0xB6,0xFF,0x83,0x10,0x1F,0x69,0x71, + 0,0x0B,0x8F,0xE3,0xF9,0xDA,0x8A,0x12, + 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, 0, +// 'f' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0x4E,0xD8,0xF8,0xFF,0x68, + 0, 0, 0,0xD8,0xFF,0x2E, 0, 0, + 0, 0, 0,0xF2,0xFF,0x0C, 0, 0, + 0,0xD0,0xFF,0xFF,0xFF,0xFF,0xFF,0x68, + 0, 0, 0,0xF4,0xFF,0x0C, 0, 0, + 0, 0, 0,0xF4,0xFF,0x0C, 0, 0, + 0, 0, 0,0xF4,0xFF,0x0C, 0, 0, + 0, 0, 0,0xF4,0xFF,0x0C, 0, 0, + 0, 0, 0,0xF4,0xFF,0x0C, 0, 0, + 0, 0, 0,0xF4,0xFF,0x0C, 0, 0, + 0, 0, 0,0xF4,0xFF,0x0C, 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, 0, 0, 0, +// 'g' + 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x1F,0xC1,0xF7,0xD3,0xBF,0xFF,0x80, + 0,0xBC,0xFF,0x54,0x38,0xF9,0xFF,0x80, +0x1F,0xFF,0xD9, 0, 0,0xB4,0xFF,0x80, +0x43,0xFF,0xB5, 0, 0,0x8E,0xFF,0x80, +0x47,0xFF,0xB5, 0, 0,0x8F,0xFF,0x80, +0x25,0xFF,0xD9, 0, 0,0xB4,0xFF,0x80, + 0,0xC5,0xFF,0x54,0x37,0xF8,0xFF,0x80, + 0,0x24,0xC5,0xF8,0xD6,0xBF,0xFF,0x7E, + 0, 0, 0, 0, 0,0x97,0xFF,0x63, + 0,0x6B,0x52,0x11,0x2B,0xE8,0xF8,0x22, + 0,0x19,0xA3,0xE9,0xF8,0xCF,0x53, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +// 'h' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0,0xD4,0xFF,0x2C, 0, 0, 0, 0, + 0,0xD4,0xFF,0x2C, 0, 0, 0, 0, + 0,0xD4,0xFF,0x2C, 0, 0, 0, 0, + 0,0xD4,0xFF,0xA4,0xE2,0xEF,0x89, 0, + 0,0xD4,0xFF,0x93,0x15,0xE1,0xFF,0x2E, + 0,0xD4,0xFF,0x39, 0,0xB1,0xFF,0x51, + 0,0xD4,0xFF,0x2C, 0,0xAC,0xFF,0x54, + 0,0xD4,0xFF,0x2C, 0,0xAC,0xFF,0x54, + 0,0xD4,0xFF,0x2C, 0,0xAC,0xFF,0x54, + 0,0xD4,0xFF,0x2C, 0,0xAC,0xFF,0x54, + 0,0xD4,0xFF,0x2C, 0,0xAC,0xFF,0x54, + 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, 0, +// 'i' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0x88,0xFF,0x78, 0, 0, + 0, 0, 0,0x88,0xFF,0x78, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x7C,0xFF,0xFF,0xFF,0x78, 0, 0, + 0, 0, 0,0x88,0xFF,0x78, 0, 0, + 0, 0, 0,0x88,0xFF,0x78, 0, 0, + 0, 0, 0,0x88,0xFF,0x78, 0, 0, + 0, 0, 0,0x88,0xFF,0x78, 0, 0, + 0, 0, 0,0x88,0xFF,0x78, 0, 0, + 0, 0, 0,0x88,0xFF,0x78, 0, 0, +0x04,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF8, + 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, 0, +// 'j' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0x30,0xFF,0xD0, 0, 0, + 0, 0, 0,0x30,0xFF,0xD0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x38,0xFF,0xFF,0xFF,0xD0, 0, 0, + 0, 0, 0,0x30,0xFF,0xD0, 0, 0, + 0, 0, 0,0x30,0xFF,0xD0, 0, 0, + 0, 0, 0,0x30,0xFF,0xD0, 0, 0, + 0, 0, 0,0x30,0xFF,0xD0, 0, 0, + 0, 0, 0,0x30,0xFF,0xD0, 0, 0, + 0, 0, 0,0x30,0xFF,0xD0, 0, 0, + 0, 0, 0,0x30,0xFF,0xD0, 0, 0, + 0, 0, 0,0x39,0xFF,0xC1, 0, 0, + 0, 0,0x04,0x8A,0xFF,0x91, 0, 0, +0x04,0xFF,0xFF,0xF3,0xB6,0x18, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +// 'k' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +0xD0,0xFF,0x30, 0, 0, 0, 0, 0, +0xD0,0xFF,0x30, 0, 0, 0, 0, 0, +0xD0,0xFF,0x30, 0, 0, 0, 0, 0, +0xD0,0xFF,0x30,0x0C,0xCD,0xFF,0x8B, 0, +0xD0,0xFF,0x34,0xB7,0xFF,0x91, 0, 0, +0xD0,0xFF,0xC5,0xFF,0x97, 0, 0, 0, +0xD0,0xFF,0xFF,0xFF,0x70, 0, 0, 0, +0xD0,0xFF,0xA4,0xEC,0xF2,0x1A, 0, 0, +0xD0,0xFF,0x30,0x6D,0xFF,0xA9, 0, 0, +0xD0,0xFF,0x30,0x05,0xD9,0xFF,0x45, 0, +0xD0,0xFF,0x30, 0,0x4F,0xFF,0xDA,0x07, + 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, 0, +// 'l' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +0x64,0xFF,0xFF,0xFF,0xA8, 0, 0, 0, + 0, 0,0x5C,0xFF,0xA8, 0, 0, 0, + 0, 0,0x5C,0xFF,0xA8, 0, 0, 0, + 0, 0,0x5C,0xFF,0xA8, 0, 0, 0, + 0, 0,0x5C,0xFF,0xA8, 0, 0, 0, + 0, 0,0x5C,0xFF,0xA8, 0, 0, 0, + 0, 0,0x5C,0xFF,0xA8, 0, 0, 0, + 0, 0,0x5C,0xFF,0xA8, 0, 0, 0, + 0, 0,0x4E,0xFF,0xB1, 0, 0, 0, + 0, 0,0x21,0xFD,0xE8,0x1B, 0, 0, + 0, 0, 0,0x6C,0xE2,0xFE,0xFF,0x7C, + 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, 0, +// 'm' + 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +0x70,0xFF,0xBA,0xF2,0xAC,0xDE,0xED,0x56, +0x70,0xFF,0x57,0xB7,0xFF,0x32,0xDF,0xC4, +0x70,0xFF,0x35,0x96,0xFF,0x09,0xC2,0xDD, +0x70,0xFF,0x34,0x94,0xFF,0x08,0xC0,0xE3, +0x70,0xFF,0x34,0x94,0xFF,0x08,0xC0,0xE4, +0x70,0xFF,0x34,0x94,0xFF,0x08,0xC0,0xE4, +0x70,0xFF,0x34,0x94,0xFF,0x08,0xC0,0xE4, +0x70,0xFF,0x34,0x94,0xFF,0x08,0xC0,0xE4, + 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, 0, +// 'n' + 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0,0xD4,0xFF,0xA5,0xE2,0xEF,0x89, 0, + 0,0xD4,0xFF,0x97,0x15,0xE2,0xFF,0x2D, + 0,0xD4,0xFF,0x3A, 0,0xB1,0xFF,0x51, + 0,0xD4,0xFF,0x2C, 0,0xAC,0xFF,0x54, + 0,0xD4,0xFF,0x2C, 0,0xAC,0xFF,0x54, + 0,0xD4,0xFF,0x2C, 0,0xAC,0xFF,0x54, + 0,0xD4,0xFF,0x2C, 0,0xAC,0xFF,0x54, + 0,0xD4,0xFF,0x2C, 0,0xAC,0xFF,0x54, + 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, 0, +// 'o' + 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x09,0x93,0xE9,0xF8,0xC4,0x36, 0, + 0,0x9C,0xFF,0x5E,0x1D,0xDA,0xF1,0x17, +0x18,0xFD,0xDB, 0, 0,0x70,0xFF,0x84, +0x42,0xFF,0xB6, 0, 0,0x4A,0xFF,0xB1, +0x42,0xFF,0xB5, 0, 0,0x4B,0xFF,0xB0, +0x19,0xFD,0xDB, 0, 0,0x6F,0xFF,0x84, + 0,0x9C,0xFF,0x5C,0x1C,0xD8,0xF1,0x17, + 0,0x09,0x93,0xEB,0xF8,0xC5,0x37, 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, 0, 0, +// 'p' + 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0,0xF8,0xFF,0x90,0xE7,0xEF,0x81, 0, + 0,0xF8,0xFF,0xA2,0x16,0xC5,0xFF,0x46, + 0,0xF8,0xFF,0x30, 0,0x5C,0xFF,0xA2, + 0,0xF8,0xFF,0x0D, 0,0x3A,0xFF,0xC2, + 0,0xF8,0xFF,0x0D, 0,0x3A,0xFF,0xC1, + 0,0xF8,0xFF,0x30, 0,0x5C,0xFF,0xA2, + 0,0xF8,0xFF,0xA2,0x16,0xC5,0xFF,0x48, + 0,0xF8,0xFF,0x91,0xEB,0xEE,0x81, 0, + 0,0xF8,0xFF,0x04, 0, 0, 0, 0, + 0,0xF8,0xFF,0x04, 0, 0, 0, 0, + 0,0xF8,0xFF,0x04, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +// 'q' + 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x35,0xD3,0xF5,0xC1,0xBD,0xFF,0x68, +0x01,0xDB,0xFD,0x44,0x40,0xFC,0xFF,0x68, +0x37,0xFF,0xCA, 0, 0,0xC4,0xFF,0x68, +0x56,0xFF,0xA9, 0, 0,0xA2,0xFF,0x68, +0x57,0xFF,0xA8, 0, 0,0xA2,0xFF,0x68, +0x37,0xFF,0xCA, 0, 0,0xC4,0xFF,0x68, +0x01,0xDA,0xFD,0x44,0x40,0xFC,0xFF,0x68, + 0,0x34,0xD2,0xF7,0xC4,0xBE,0xFF,0x68, + 0, 0, 0, 0, 0,0x98,0xFF,0x68, + 0, 0, 0, 0, 0,0x98,0xFF,0x68, + 0, 0, 0, 0, 0,0x98,0xFF,0x68, + 0, 0, 0, 0, 0, 0, 0, 0, +// 'r' + 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x04,0xFF,0xFF,0x97,0xE1,0xFD,0xE0, + 0,0x04,0xFF,0xFF,0xC5,0x1E,0x18,0x81, + 0,0x04,0xFF,0xFF,0x2A, 0, 0, 0, + 0,0x04,0xFF,0xFF,0x04, 0, 0, 0, + 0,0x04,0xFF,0xFF, 0, 0, 0, 0, + 0,0x04,0xFF,0xFF, 0, 0, 0, 0, + 0,0x04,0xFF,0xFF, 0, 0, 0, 0, + 0,0x04,0xFF,0xFF, 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, 0, 0, 0, 0, 0, +// 's' + 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0,0x11,0xA1,0xE9,0xEF,0xB4,0x2E, 0, + 0,0x9C,0xFF,0x4B,0x0B,0x41,0x95, 0, + 0,0xC8,0xFF,0x79,0x08, 0, 0, 0, + 0,0x84,0xFF,0xFF,0xF3,0xAE,0x32, 0, + 0,0x01,0x61,0xBA,0xF9,0xFF,0xF2,0x13, + 0, 0, 0, 0,0x14,0xCD,0xFF,0x40, + 0,0x90,0x59,0x16,0x12,0xC6,0xFB,0x1D, + 0,0x20,0x9B,0xE1,0xF6,0xD2,0x56, 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, 0, 0, +// 't' + 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,0x48,0xFF,0xB8, 0, 0, 0, + 0, 0,0x48,0xFF,0xB8, 0, 0, 0, +0x3C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x54, + 0, 0,0x48,0xFF,0xB8, 0, 0, 0, + 0, 0,0x48,0xFF,0xB8, 0, 0, 0, + 0, 0,0x48,0xFF,0xB8, 0, 0, 0, + 0, 0,0x48,0xFF,0xB8, 0, 0, 0, + 0, 0,0x45,0xFF,0xB8, 0, 0, 0, + 0, 0,0x27,0xFF,0xDF,0x11, 0, 0, + 0, 0, 0,0x89,0xE9,0xFE,0xFF,0x54, + 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, 0, +// 'u' + 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0,0xE8,0xFF,0x18, 0,0xC0,0xFF,0x40, + 0,0xE8,0xFF,0x18, 0,0xC0,0xFF,0x40, + 0,0xE8,0xFF,0x18, 0,0xC0,0xFF,0x40, + 0,0xE8,0xFF,0x18, 0,0xC0,0xFF,0x40, + 0,0xE8,0xFF,0x18, 0,0xC0,0xFF,0x40, + 0,0xE5,0xFF,0x1C, 0,0xCE,0xFF,0x40, + 0,0xC3,0xFF,0x5D,0x30,0xFB,0xFF,0x40, + 0,0x3B,0xD9,0xF4,0xC1,0xD7,0xFF,0x40, + 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, 0, +// 'v' + 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +0x4E,0xFF,0xB5, 0, 0,0x46,0xFF,0xB8, +0x09,0xF6,0xF3,0x05, 0,0x89,0xFF,0x6B, + 0,0xB2,0xFF,0x3B, 0,0xCC,0xFF,0x1E, + 0,0x64,0xFF,0x7E,0x11,0xFD,0xD0, 0, + 0,0x17,0xFE,0xC1,0x53,0xFF,0x82, 0, + 0, 0,0xC8,0xF9,0xA1,0xFF,0x35, 0, + 0, 0,0x7A,0xFF,0xFB,0xE6,0x01, 0, + 0, 0,0x2B,0xFF,0xFF,0x9A, 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, 0, 0, 0, +// 'w' + 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +0xEA,0xBE, 0, 0, 0, 0,0x50,0xFF, +0xBE,0xE5, 0, 0, 0, 0,0x76,0xFF, +0x91,0xFF,0x0B,0xB2,0xFF,0x20,0x9D,0xF9, +0x65,0xFF,0x31,0xE6,0xFD,0x53,0xC4,0xD1, +0x38,0xFF,0x70,0xFE,0xB0,0x86,0xEA,0xA5, +0x0C,0xFE,0xCB,0xD5,0x68,0xCA,0xFF,0x79, + 0,0xDF,0xFF,0x9C,0x30,0xFF,0xFF,0x4D, + 0,0xB2,0xFF,0x64,0x03,0xF4,0xFF,0x21, + 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, 0, +// 'x' + 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +0x1D,0xF0,0xFF,0x35, 0,0xC7,0xFF,0x7D, + 0,0x60,0xFF,0xBD,0x50,0xFF,0xCC,0x04, + 0, 0,0xB2,0xFF,0xEB,0xF8,0x2B, 0, + 0, 0,0x18,0xF1,0xFF,0x7D, 0, 0, + 0, 0,0x42,0xFE,0xFF,0xB2, 0, 0, + 0,0x0D,0xE0,0xF9,0xC2,0xFF,0x5E, 0, + 0,0x9C,0xFF,0x8D,0x24,0xFA,0xEF,0x1A, +0x49,0xFF,0xEE,0x11, 0,0x8F,0xFF,0xB5, + 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, 0, +// 'y' + 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +0x69,0xFF,0xAE, 0, 0,0x3A,0xFF,0xDF, +0x11,0xF8,0xF7,0x0D, 0,0x8C,0xFF,0x89, + 0,0xAB,0xFF,0x5B, 0,0xDE,0xFF,0x32, + 0,0x4C,0xFF,0xB2,0x31,0xFF,0xDB, 0, + 0,0x04,0xE9,0xF8,0x93,0xFF,0x84, 0, + 0, 0,0x8E,0xFF,0xFD,0xFF,0x2D, 0, + 0, 0,0x30,0xFF,0xFF,0xD6, 0, 0, + 0, 0, 0,0xD2,0xFF,0x7F, 0, 0, + 0, 0,0x01,0xE4,0xFF,0x29, 0, 0, + 0,0x01,0x5D,0xFF,0xC5, 0, 0, 0, +0x20,0xFF,0xFC,0xC9,0x23, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +// 'z' + 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0,0xBC,0xFF,0xFF,0xFF,0xFF,0xFF,0x64, + 0, 0, 0, 0,0x42,0xFC,0xFF,0x5F, + 0, 0, 0,0x1B,0xE9,0xFF,0xCD,0x08, + 0, 0,0x05,0xC5,0xFF,0xEE,0x21, 0, + 0, 0,0x90,0xFF,0xFE,0x4C, 0, 0, + 0,0x56,0xFF,0xFF,0x84, 0, 0, 0, + 0,0xDF,0xFF,0xBC,0x02, 0, 0, 0, + 0,0xE4,0xFF,0xFF,0xFF,0xFF,0xFF,0x64, + 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, 0, +// '{' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,0x26,0xCB,0xF7,0xFF,0x34, + 0, 0, 0,0x93,0xFF,0x6B,0x02, 0, + 0, 0, 0,0xAE,0xFF,0x30, 0, 0, + 0, 0, 0,0xB0,0xFF,0x2C, 0, 0, + 0, 0, 0,0xBD,0xFF,0x26, 0, 0, + 0,0x02,0x32,0xF4,0xF2,0x09, 0, 0, + 0,0xCC,0xFF,0xF6,0x58, 0, 0, 0, + 0,0x02,0x36,0xF6,0xEF,0x08, 0, 0, + 0, 0, 0,0xBE,0xFF,0x26, 0, 0, + 0, 0, 0,0xB0,0xFF,0x2C, 0, 0, + 0, 0, 0,0xAE,0xFF,0x30, 0, 0, + 0, 0, 0,0x93,0xFF,0x6A,0x02, 0, + 0, 0, 0,0x26,0xCC,0xF8,0xFF,0x34, + 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, 0, + 0, 0, 0,0x90,0xFC, 0, 0, 0, + 0, 0, 0,0x90,0xFC, 0, 0, 0, + 0, 0, 0,0x90,0xFC, 0, 0, 0, + 0, 0, 0,0x90,0xFC, 0, 0, 0, + 0, 0, 0,0x90,0xFC, 0, 0, 0, + 0, 0, 0,0x90,0xFC, 0, 0, 0, + 0, 0, 0,0x90,0xFC, 0, 0, 0, + 0, 0, 0,0x90,0xFC, 0, 0, 0, + 0, 0, 0,0x90,0xFC, 0, 0, 0, + 0, 0, 0,0x90,0xFC, 0, 0, 0, + 0, 0, 0,0x90,0xFC, 0, 0, 0, + 0, 0, 0,0x90,0xFC, 0, 0, 0, + 0, 0, 0,0x90,0xFC, 0, 0, 0, + 0, 0, 0,0x90,0xFC, 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,0xC4,0xFC,0xE5,0x6E, 0, 0, 0, + 0, 0,0x17,0xE9,0xF8,0x02, 0, 0, + 0, 0, 0,0xC1,0xFF,0x16, 0, 0, + 0, 0, 0,0xBC,0xFF,0x18, 0, 0, + 0, 0, 0,0xB7,0xFF,0x24, 0, 0, + 0, 0, 0,0x8E,0xFF,0x89,0x0A, 0, + 0, 0, 0,0x11,0xD1,0xFF,0xFF,0x38, + 0, 0, 0,0x8B,0xFF,0x8C,0x0B, 0, + 0, 0, 0,0xB6,0xFF,0x25, 0, 0, + 0, 0, 0,0xBC,0xFF,0x18, 0, 0, + 0, 0, 0,0xC1,0xFF,0x16, 0, 0, + 0, 0,0x17,0xE9,0xF8,0x02, 0, 0, + 0,0xC4,0xFD,0xE6,0x6F, 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, 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, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +0x16,0xAC,0xF1,0xD8,0x72,0x14,0x28,0x8A, +0x64,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD4, +0x51,0x53,0x0D,0x31,0x9D,0xF1,0xD7,0x4C, + 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, 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, + + // clang-format on +}; +} // anonymous namespace + +const uint8_t *OverlayState::getFontData() const +{ + return kFontData; +} +#else +const uint8_t *OverlayState::getFontData() const +{ + return nullptr; +} +#endif +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/Overlay_font_autogen.h b/gfx/angle/checkout/src/libANGLE/Overlay_font_autogen.h new file mode 100644 index 0000000000..333c0ee3c6 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Overlay_font_autogen.h @@ -0,0 +1,27 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_overlay_fonts.py using overlay/DejaVuSansMono-Bold.ttf. +// +// Copyright 2022 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Overlay_font_autogen.h: +// Autogenerated overlay font data. + +#include "libANGLE/Overlay.h" + +namespace gl +{ +namespace overlay +{ +constexpr uint32_t kFontMipCount = 2; +constexpr uint32_t kFontCharacters = 95; +constexpr uint32_t kFontGlyphWidth = 17; +constexpr uint32_t kFontGlyphHeight = 34; +constexpr uint32_t kFontMipDataSize[kFontMipCount] = {54910, 12920}; +constexpr uint32_t kFontMipDataOffset[kFontMipCount] = {0, 54910}; +constexpr uint32_t kFontTotalDataSize = 67830; +constexpr uint32_t kFontMipLarge = 0; +constexpr uint32_t kFontMipSmall = 1; +} // namespace overlay +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/PixelLocalStorage.cpp b/gfx/angle/checkout/src/libANGLE/PixelLocalStorage.cpp new file mode 100644 index 0000000000..e5e560af5f --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/PixelLocalStorage.cpp @@ -0,0 +1,826 @@ +// +// Copyright 2022 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// PixelLocalStorage.cpp: Defines the renderer-agnostic container classes +// gl::PixelLocalStorage and gl::PixelLocalStoragePlane for +// ANGLE_shader_pixel_local_storage. + +#include "libANGLE/PixelLocalStorage.h" + +#include +#include "libANGLE/Context.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/Texture.h" +#include "libANGLE/renderer/ContextImpl.h" + +namespace gl +{ +// RAII utilities for working with GL state. +namespace +{ +class ScopedBindTexture2D +{ + public: + ScopedBindTexture2D(Context *context, TextureID texture) + : mContext(context), + mSavedTexBinding2D( + mContext->getState().getSamplerTextureId(mContext->getState().getActiveSampler(), + TextureType::_2D)) + { + mContext->bindTexture(TextureType::_2D, texture); + } + + ~ScopedBindTexture2D() { mContext->bindTexture(TextureType::_2D, mSavedTexBinding2D); } + + private: + Context *const mContext; + TextureID mSavedTexBinding2D; +}; + +class ScopedRestoreDrawFramebuffer +{ + public: + ScopedRestoreDrawFramebuffer(Context *context) + : mContext(context), mSavedFramebuffer(mContext->getState().getDrawFramebuffer()) + { + ASSERT(mSavedFramebuffer); + } + + ~ScopedRestoreDrawFramebuffer() { mContext->bindDrawFramebuffer(mSavedFramebuffer->id()); } + + private: + Context *const mContext; + Framebuffer *const mSavedFramebuffer; +}; + +class ScopedDisableScissor +{ + public: + ScopedDisableScissor(Context *context) + : mContext(context), mScissorTestEnabled(mContext->getState().isScissorTestEnabled()) + { + if (mScissorTestEnabled) + { + mContext->disable(GL_SCISSOR_TEST); + } + } + + ~ScopedDisableScissor() + { + if (mScissorTestEnabled) + { + mContext->enable(GL_SCISSOR_TEST); + } + } + + private: + Context *const mContext; + const GLint mScissorTestEnabled; +}; +} // namespace + +PixelLocalStoragePlane::~PixelLocalStoragePlane() +{ + // Call deinitialize or onContextObjectsLost first! + ASSERT(mMemorylessTextureID.value == 0); + // Call deinitialize or onFramebufferDestroyed first! + ASSERT(mTextureRef == nullptr); +} + +void PixelLocalStoragePlane::onContextObjectsLost() +{ + // We normally call deleteTexture on the memoryless plane texture ID, since we own it, but in + // this case we can let it go. + mMemorylessTextureID = TextureID(); +} + +void PixelLocalStoragePlane::onFramebufferDestroyed(const Context *context) +{ + if (mTextureRef != nullptr) + { + mTextureRef->release(context); + mTextureRef = nullptr; + } +} + +void PixelLocalStoragePlane::deinitialize(Context *context) +{ + mInternalformat = GL_NONE; + mMemoryless = false; + if (mMemorylessTextureID.value != 0) + { + // The app could have technically deleted mMemorylessTextureID by guessing its value and + // calling glDeleteTextures, but it seems unnecessary to worry about that here. (Worst case + // we delete one of their textures.) This also isn't a problem in WebGL. + context->deleteTexture(mMemorylessTextureID); + mMemorylessTextureID = TextureID(); + } + if (mTextureRef != nullptr) + { + mTextureRef->release(context); + mTextureRef = nullptr; + } +} + +void PixelLocalStoragePlane::setMemoryless(Context *context, GLenum internalformat) +{ + deinitialize(context); + mInternalformat = internalformat; + mMemoryless = true; + mTextureImageIndex = ImageIndex::MakeFromType(TextureType::_2D, 0, 0); + // The backing texture will get allocated lazily, once we know what dimensions it should be. + ASSERT(mMemorylessTextureID.value == 0); + ASSERT(mTextureRef == nullptr); +} + +void PixelLocalStoragePlane::setTextureBacked(Context *context, Texture *tex, int level, int layer) +{ + deinitialize(context); + ASSERT(tex->getImmutableFormat()); + mInternalformat = tex->getState().getBaseLevelDesc().format.info->internalFormat; + mMemoryless = false; + mTextureImageIndex = ImageIndex::MakeFromType(tex->getType(), level, layer); + mTextureRef = tex; + mTextureRef->addRef(); +} + +bool PixelLocalStoragePlane::isTextureIDDeleted(const Context *context) const +{ + // We can tell if the texture has been deleted by looking up mTextureRef's ID on the Context. If + // they don't match, it's been deleted. + ASSERT(!isDeinitialized() || mTextureRef == nullptr); + return mTextureRef != nullptr && context->getTexture(mTextureRef->id()) != mTextureRef; +} + +GLint PixelLocalStoragePlane::getIntegeri(const Context *context, GLenum target, GLuint index) const +{ + if (!isDeinitialized()) + { + bool memoryless = isMemoryless() || isTextureIDDeleted(context); + switch (target) + { + case GL_PIXEL_LOCAL_FORMAT_ANGLE: + return mInternalformat; + case GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE: + return memoryless ? 0 : mTextureRef->id().value; + case GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE: + return memoryless ? 0 : mTextureImageIndex.getLevelIndex(); + case GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE: + return memoryless ? 0 : mTextureImageIndex.getLayerIndex(); + } + } + // Since GL_NONE == 0, PLS queries all return 0 when the plane is deinitialized. + static_assert(GL_NONE == 0, "Expecting GL_NONE to be zero."); + return 0; +} + +bool PixelLocalStoragePlane::getTextureImageExtents(const Context *context, Extents *extents) const +{ + if (isDeinitialized() || isMemoryless() || isTextureIDDeleted(context)) + { + return false; + } + ASSERT(mTextureRef != nullptr); + *extents = + mTextureRef->getExtents(mTextureImageIndex.getTarget(), mTextureImageIndex.getLevelIndex()); + extents->depth = 0; + return true; +} + +void PixelLocalStoragePlane::ensureBackingIfMemoryless(Context *context, Extents plsExtents) +{ + ASSERT(!isDeinitialized()); + ASSERT(!isTextureIDDeleted(context)); // Convert to memoryless first in this case. + if (!isMemoryless()) + { + ASSERT(mTextureRef != nullptr); + return; + } + + // Internal textures backing memoryless planes are always 2D and not mipmapped. + ASSERT(mTextureImageIndex.getType() == TextureType::_2D); + ASSERT(mTextureImageIndex.getLevelIndex() == 0); + ASSERT(mTextureImageIndex.getLayerIndex() == 0); + const bool hasMemorylessTextureId = mMemorylessTextureID.value != 0; + const bool hasTextureRef = mTextureRef != nullptr; + ASSERT(hasMemorylessTextureId == hasTextureRef); + + // Do we need to allocate a new backing texture? + if (mTextureRef == nullptr || + static_cast(mTextureRef->getWidth(TextureTarget::_2D, 0)) != plsExtents.width || + static_cast(mTextureRef->getHeight(TextureTarget::_2D, 0)) != plsExtents.height) + { + // Call setMemoryless() to release our current data. + setMemoryless(context, mInternalformat); + ASSERT(mTextureRef == nullptr); + ASSERT(mMemorylessTextureID.value == 0); + + // Create a new texture that backs the memoryless plane. + context->genTextures(1, &mMemorylessTextureID); + { + ScopedBindTexture2D scopedBindTexture2D(context, mMemorylessTextureID); + context->bindTexture(TextureType::_2D, mMemorylessTextureID); + context->texStorage2D(TextureType::_2D, 1, mInternalformat, plsExtents.width, + plsExtents.height); + } + + mTextureRef = context->getTexture(mMemorylessTextureID); + ASSERT(mTextureRef != nullptr); + ASSERT(mTextureRef->id() == mMemorylessTextureID); + mTextureRef->addRef(); + } +} + +void PixelLocalStoragePlane::attachToDrawFramebuffer(Context *context, + Extents plsExtents, + GLenum colorAttachment) +{ + ASSERT(!isDeinitialized()); + ensureBackingIfMemoryless(context, plsExtents); + ASSERT(mTextureRef != nullptr); + if (mTextureImageIndex.usesTex3D()) // GL_TEXTURE_3D or GL_TEXTURE_2D_ARRAY. + { + context->framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, colorAttachment, mTextureRef->id(), + mTextureImageIndex.getLevelIndex(), + mTextureImageIndex.getLayerIndex()); + } + else + { + context->framebufferTexture2D(GL_DRAW_FRAMEBUFFER, colorAttachment, + mTextureImageIndex.getTarget(), mTextureRef->id(), + mTextureImageIndex.getLevelIndex()); + } +} + +void PixelLocalStoragePlane::performLoadOperationClear(Context *context, + GLint drawBuffer, + GLenum loadop, + const void *data) +{ + // The GL scissor test must be disabled, since the intention is to clear the entire surface. + ASSERT(!context->getState().isScissorTestEnabled()); + switch (mInternalformat) + { + case GL_RGBA8: + case GL_R32F: + { + GLfloat clearValue[4]{}; + if (loadop == GL_CLEAR_ANGLE) + { + memcpy(clearValue, data, sizeof(clearValue)); + } + context->clearBufferfv(GL_COLOR, drawBuffer, clearValue); + break; + } + case GL_RGBA8I: + { + GLint clearValue[4]{}; + if (loadop == GL_CLEAR_ANGLE) + { + memcpy(clearValue, data, sizeof(clearValue)); + } + context->clearBufferiv(GL_COLOR, drawBuffer, clearValue); + break; + } + case GL_RGBA8UI: + case GL_R32UI: + { + GLuint clearValue[4]{}; + if (loadop == GL_CLEAR_ANGLE) + { + memcpy(clearValue, data, sizeof(clearValue)); + } + context->clearBufferuiv(GL_COLOR, drawBuffer, clearValue); + break; + } + default: + // Invalid PLS internalformats should not have made it this far. + UNREACHABLE(); + } +} + +void PixelLocalStoragePlane::bindToImage(Context *context, + Extents plsExtents, + GLuint unit, + bool needsR32Packing) +{ + ASSERT(!isDeinitialized()); + ensureBackingIfMemoryless(context, plsExtents); + ASSERT(mTextureRef != nullptr); + GLenum imageBindingFormat = mInternalformat; + if (needsR32Packing) + { + // D3D and ES require us to pack all PLS formats into r32f, r32i, or r32ui images. + switch (imageBindingFormat) + { + case GL_RGBA8: + case GL_RGBA8UI: + imageBindingFormat = GL_R32UI; + break; + case GL_RGBA8I: + imageBindingFormat = GL_R32I; + break; + } + } + if (mTextureRef->getType() != TextureType::_2D) + { + // TODO(anglebug.com/7279): Texture types other than GL_TEXTURE_2D will take a lot of + // consideration to support on all backends. Hold of on fully implementing them until the + // other backends are in place. + UNIMPLEMENTED(); + } + context->bindImageTexture(unit, mTextureRef->id(), mTextureImageIndex.getLevelIndex(), GL_FALSE, + mTextureImageIndex.getLayerIndex(), GL_READ_WRITE, + imageBindingFormat); +} + +PixelLocalStorage::PixelLocalStorage() {} +PixelLocalStorage::~PixelLocalStorage() {} + +void PixelLocalStorage::onFramebufferDestroyed(const Context *context) +{ + if (context->getRefCount() == 0) + { + // If the Context's refcount is zero, we know it's in a teardown state and we can just let + // go of our GL objects -- they get cleaned up as part of context teardown. Otherwise, the + // Context should have called deleteContextObjects before reaching this point. + onContextObjectsLost(); + for (PixelLocalStoragePlane &plane : mPlanes) + { + plane.onContextObjectsLost(); + } + } + for (PixelLocalStoragePlane &plane : mPlanes) + { + plane.onFramebufferDestroyed(context); + } +} + +void PixelLocalStorage::deleteContextObjects(Context *context) +{ + onDeleteContextObjects(context); + for (PixelLocalStoragePlane &plane : mPlanes) + { + plane.deinitialize(context); + } +} + +void PixelLocalStorage::begin(Context *context, + GLsizei n, + const GLenum loadops[], + const void *cleardata) +{ + // Convert planes whose backing texture has been deleted to memoryless, and find the pixel local + // storage rendering dimensions. + Extents plsExtents; + bool hasPLSExtents = false; + for (int i = 0; i < n; ++i) + { + if (loadops[i] == GL_DISABLE_ANGLE) + { + continue; + } + PixelLocalStoragePlane &plane = mPlanes[i]; + if (plane.isTextureIDDeleted(context)) + { + // [ANGLE_shader_pixel_local_storage] Section 4.4.2.X "Configuring Pixel Local Storage + // on a Framebuffer": When a texture object is deleted, any pixel local storage plane to + // which it was bound is automatically converted to a memoryless plane of matching + // internalformat. + plane.setMemoryless(context, plane.getInternalformat()); + } + if (!hasPLSExtents && plane.getTextureImageExtents(context, &plsExtents)) + { + hasPLSExtents = true; + } + } + if (!hasPLSExtents) + { + // All PLS planes are memoryless. Use the rendering area of the framebuffer instead. + plsExtents = + context->getState().getDrawFramebuffer()->getState().getAttachmentExtentsIntersection(); + ASSERT(plsExtents.depth == 0); + } + + onBegin(context, n, loadops, reinterpret_cast(cleardata), plsExtents); + mNumActivePLSPlanes = n; +} + +void PixelLocalStorage::end(Context *context) +{ + onEnd(context, mNumActivePLSPlanes); + mNumActivePLSPlanes = 0; +} + +void PixelLocalStorage::barrier(Context *context) +{ + ASSERT(!context->getExtensions().shaderPixelLocalStorageCoherentANGLE); + onBarrier(context); +} + +namespace +{ +// Implements pixel local storage with image load/store shader operations. +class PixelLocalStorageImageLoadStore : public PixelLocalStorage +{ + public: + PixelLocalStorageImageLoadStore(bool needsR32Packing) : mNeedsR32Packing(needsR32Packing) {} + + // Call deleteContextObjects or onContextObjectsLost first! + ~PixelLocalStorageImageLoadStore() override + { + ASSERT(mScratchFramebufferForClearing.value == 0); + } + + void onContextObjectsLost() override + { + mScratchFramebufferForClearing = FramebufferID(); // Let go of GL objects. + } + + void onDeleteContextObjects(Context *context) override + { + if (mScratchFramebufferForClearing.value != 0) + { + context->deleteFramebuffer(mScratchFramebufferForClearing); + mScratchFramebufferForClearing = FramebufferID(); + } + } + + void onBegin(Context *context, + GLsizei n, + const GLenum loadops[], + const char *cleardata, + Extents plsExtents) override + { + // Save the image bindings so we can restore them during onEnd(). + const State &state = context->getState(); + ASSERT(static_cast(n) <= state.getImageUnits().size()); + mSavedImageBindings.clear(); + mSavedImageBindings.reserve(n); + for (int i = 0; i < n; ++i) + { + mSavedImageBindings.emplace_back(state.getImageUnit(i)); + } + + // Save the default framebuffer width/height so we can restore it during onEnd(). + Framebuffer *framebuffer = state.getDrawFramebuffer(); + mSavedFramebufferDefaultWidth = framebuffer->getDefaultWidth(); + mSavedFramebufferDefaultHeight = framebuffer->getDefaultHeight(); + + // Specify the framebuffer width/height explicitly in case we end up rendering exclusively + // to shader images. + context->framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, + plsExtents.width); + context->framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, + plsExtents.height); + + // Guard GL state and bind a scratch framebuffer in case we need to reallocate or clear any + // PLS planes. + const size_t maxDrawBuffers = context->getCaps().maxDrawBuffers; + ScopedRestoreDrawFramebuffer ScopedRestoreDrawFramebuffer(context); + if (mScratchFramebufferForClearing.value == 0) + { + context->genFramebuffers(1, &mScratchFramebufferForClearing); + context->bindFramebuffer(GL_DRAW_FRAMEBUFFER, mScratchFramebufferForClearing); + // Turn on all draw buffers on the scratch framebuffer for clearing. + DrawBuffersVector drawBuffers(maxDrawBuffers); + std::iota(drawBuffers.begin(), drawBuffers.end(), GL_COLOR_ATTACHMENT0); + context->drawBuffers(static_cast(drawBuffers.size()), drawBuffers.data()); + } + else + { + context->bindFramebuffer(GL_DRAW_FRAMEBUFFER, mScratchFramebufferForClearing); + } + ScopedDisableScissor scopedDisableScissor(context); + + // Bind and clear the PLS planes. + size_t maxClearedAttachments = 0; + for (int i = 0; i < n;) + { + angle::FixedVector pendingClears; + for (; pendingClears.size() < maxDrawBuffers && i < n; ++i) + { + GLenum loadop = loadops[i]; + if (loadop == GL_DISABLE_ANGLE) + { + continue; + } + PixelLocalStoragePlane &plane = getPlane(i); + ASSERT(!plane.isDeinitialized()); + plane.bindToImage(context, plsExtents, i, mNeedsR32Packing); + if (loadop == GL_ZERO || loadop == GL_CLEAR_ANGLE) + { + plane.attachToDrawFramebuffer( + context, plsExtents, + GL_COLOR_ATTACHMENT0 + static_cast(pendingClears.size())); + pendingClears.push_back(i); // Defer the clear for later. + } + } + // Clear in batches to be more efficient with GL state. + for (size_t drawBufferIdx = 0; drawBufferIdx < pendingClears.size(); ++drawBufferIdx) + { + int plsIdx = pendingClears[drawBufferIdx]; + getPlane(plsIdx).performLoadOperationClear( + context, static_cast(drawBufferIdx), loadops[plsIdx], + cleardata + plsIdx * 4 * 4); + } + maxClearedAttachments = std::max(maxClearedAttachments, pendingClears.size()); + } + + // Detach the cleared PLS textures from the scratch framebuffer. + for (size_t i = 0; i < maxClearedAttachments; ++i) + { + context->framebufferTexture2D(GL_DRAW_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0 + static_cast(i), + TextureTarget::_2D, TextureID(), 0); + } + + // Unlike other barriers, GL_SHADER_IMAGE_ACCESS_BARRIER_BIT also synchronizes all types of + // memory accesses that happened before the barrier: + // + // SHADER_IMAGE_ACCESS_BARRIER_BIT: Memory accesses using shader built-in image load and + // store functions issued after the barrier will reflect data written by shaders prior to + // the barrier. Additionally, image stores issued after the barrier will not execute until + // all memory accesses (e.g., loads, stores, texture fetches, vertex fetches) initiated + // prior to the barrier complete. + // + // So we don't any barriers other than GL_SHADER_IMAGE_ACCESS_BARRIER_BIT during begin(). + context->memoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); + } + + void onEnd(Context *context, GLsizei numActivePLSPlanes) override + { + // Restore the image bindings. Since glBindImageTexture and any commands that modify + // textures are banned while PLS is active, these will all still be alive and valid. + ASSERT(mSavedImageBindings.size() == static_cast(numActivePLSPlanes)); + for (GLuint unit = 0; unit < mSavedImageBindings.size(); ++unit) + { + ImageUnit &binding = mSavedImageBindings[unit]; + context->bindImageTexture(unit, binding.texture.id(), binding.level, binding.layered, + binding.layer, binding.access, binding.format); + + // BindingPointers have to be explicitly cleaned up. + binding.texture.set(context, nullptr); + } + mSavedImageBindings.clear(); + + // Restore the default framebuffer width/height. + context->framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, + mSavedFramebufferDefaultWidth); + context->framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, + mSavedFramebufferDefaultHeight); + + // We need ALL_BARRIER_BITS during end() because GL_SHADER_IMAGE_ACCESS_BARRIER_BIT doesn't + // synchronize all types of memory accesses that can happen after the barrier. + context->memoryBarrier(GL_ALL_BARRIER_BITS); + } + + void onBarrier(Context *context) override + { + context->memoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); + } + + private: + // D3D and ES require us to pack all PLS formats into r32f, r32i, or r32ui images. + const bool mNeedsR32Packing; + FramebufferID mScratchFramebufferForClearing{}; + + // Saved values to restore during onEnd(). + GLint mSavedFramebufferDefaultWidth; + GLint mSavedFramebufferDefaultHeight; + std::vector mSavedImageBindings; +}; + +// Implements pixel local storage via framebuffer fetch. +class PixelLocalStorageFramebufferFetch : public PixelLocalStorage +{ + public: + void onContextObjectsLost() override {} + + void onDeleteContextObjects(Context *) override {} + + void onBegin(Context *context, + GLsizei n, + const GLenum loadops[], + const char *cleardata, + Extents plsExtents) override + { + const State &state = context->getState(); + const Caps &caps = context->getCaps(); + Framebuffer *framebuffer = context->getState().getDrawFramebuffer(); + const DrawBuffersVector &appDrawBuffers = framebuffer->getDrawBufferStates(); + + // Remember the current draw buffer state so we can restore it during onEnd(). + mSavedDrawBuffers.resize(appDrawBuffers.size()); + std::copy(appDrawBuffers.begin(), appDrawBuffers.end(), mSavedDrawBuffers.begin()); + + // Set up new draw buffers for PLS. + int firstPLSDrawBuffer = caps.maxCombinedDrawBuffersAndPixelLocalStoragePlanes - n; + int numAppDrawBuffers = + std::min(static_cast(appDrawBuffers.size()), firstPLSDrawBuffer); + DrawBuffersArray plsDrawBuffers; + std::copy(appDrawBuffers.begin(), appDrawBuffers.begin() + numAppDrawBuffers, + plsDrawBuffers.begin()); + std::fill(plsDrawBuffers.begin() + numAppDrawBuffers, + plsDrawBuffers.begin() + firstPLSDrawBuffer, GL_NONE); + + mBlendsToReEnable.reset(); + mColorMasksToRestore.reset(); + mInvalidateList.clear(); + bool needsClear = false; + + bool hasIndexedBlendAndColorMask = context->getExtensions().drawBuffersIndexedAny(); + if (!hasIndexedBlendAndColorMask) + { + // We don't have indexed blend and color mask control. Disable them globally. (This also + // means the app can't have its own draw buffers while PLS is active.) + ASSERT(caps.maxColorAttachmentsWithActivePixelLocalStorage == 0); + if (state.isBlendEnabled()) + { + context->disable(GL_BLEND); + mBlendsToReEnable.set(0); + } + std::array &mask = mSavedColorMasks[0]; + state.getBlendStateExt().getColorMaskIndexed(0, &mask[0], &mask[1], &mask[2], &mask[3]); + if (!(mask[0] && mask[1] && mask[2] && mask[3])) + { + context->colorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + mColorMasksToRestore.set(0); + } + } + + for (GLsizei i = 0; i < n; ++i) + { + GLuint drawBufferIdx = getDrawBufferIdx(caps, i); + GLenum loadop = loadops[i]; + if (loadop == GL_DISABLE_ANGLE) + { + plsDrawBuffers[drawBufferIdx] = GL_NONE; + continue; + } + + PixelLocalStoragePlane &plane = getPlane(i); + ASSERT(!plane.isDeinitialized()); + + // Attach our PLS texture to the framebuffer. Validation should have already ensured + // nothing else was attached at this point. + GLenum colorAttachment = GL_COLOR_ATTACHMENT0 + drawBufferIdx; + ASSERT(!framebuffer->getAttachment(context, colorAttachment)); + plane.attachToDrawFramebuffer(context, plsExtents, colorAttachment); + plsDrawBuffers[drawBufferIdx] = colorAttachment; + + if (hasIndexedBlendAndColorMask) + { + // Ensure blend and color mask are disabled for this draw buffer. + if (state.isBlendEnabledIndexed(drawBufferIdx)) + { + context->disablei(GL_BLEND, drawBufferIdx); + mBlendsToReEnable.set(drawBufferIdx); + } + std::array &mask = mSavedColorMasks[drawBufferIdx]; + state.getBlendStateExt().getColorMaskIndexed(drawBufferIdx, &mask[0], &mask[1], + &mask[2], &mask[3]); + if (!(mask[0] && mask[1] && mask[2] && mask[3])) + { + context->colorMaski(drawBufferIdx, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + mColorMasksToRestore.set(drawBufferIdx); + } + } + + if (plane.isMemoryless()) + { + // Memoryless planes don't need to be preserved after glEndPixelLocalStorageANGLE(). + mInvalidateList.push_back(colorAttachment); + } + + needsClear = needsClear || (loadop != GL_KEEP); + } + + // Turn on the PLS draw buffers. + context->drawBuffers(caps.maxCombinedDrawBuffersAndPixelLocalStoragePlanes, + plsDrawBuffers.data()); + + // Clear the non-KEEP PLS planes now that their draw buffers are turned on. + if (needsClear) + { + ScopedDisableScissor scopedDisableScissor(context); + for (GLsizei i = 0; i < n; ++i) + { + GLenum loadop = loadops[i]; + if (loadop != GL_DISABLE_ANGLE && loadop != GL_KEEP) + { + GLuint drawBufferIdx = getDrawBufferIdx(caps, i); + getPlane(i).performLoadOperationClear(context, drawBufferIdx, loadop, + cleardata + i * 4 * 4); + } + } + } + + if (!context->getExtensions().shaderPixelLocalStorageCoherentANGLE) + { + // Insert a barrier if we aren't coherent, since the textures may have been rendered to + // previously. + barrier(context); + } + } + + void onEnd(Context *context, GLint numActivePLSPlanes) override + { + + const Caps &caps = context->getCaps(); + + // Invalidate the memoryless PLS attachments. + if (!mInvalidateList.empty()) + { + context->invalidateFramebuffer(GL_DRAW_FRAMEBUFFER, + static_cast(mInvalidateList.size()), + mInvalidateList.data()); + mInvalidateList.clear(); + } + + bool hasIndexedBlendAndColorMask = context->getExtensions().drawBuffersIndexedAny(); + if (!hasIndexedBlendAndColorMask) + { + // Restore global blend and color mask. Validation should have ensured these didn't + // change while pixel local storage was active. + if (mBlendsToReEnable[0]) + { + context->enable(GL_BLEND); + } + if (mColorMasksToRestore[0]) + { + const std::array &mask = mSavedColorMasks[0]; + context->colorMask(mask[0], mask[1], mask[2], mask[3]); + } + } + + for (GLsizei i = 0; i < numActivePLSPlanes; ++i) + { + // Reset color attachments where PLS was attached. Validation should have already + // ensured nothing was attached at these points when we activated pixel local storage, + // and that nothing got attached during. + GLuint drawBufferIdx = getDrawBufferIdx(caps, i); + GLenum colorAttachment = GL_COLOR_ATTACHMENT0 + drawBufferIdx; + context->framebufferTexture2D(GL_DRAW_FRAMEBUFFER, colorAttachment, TextureTarget::_2D, + TextureID(), 0); + + if (hasIndexedBlendAndColorMask) + { + // Restore this draw buffer's blend and color mask. Validation should have ensured + // these did not change while pixel local storage was active. + if (mBlendsToReEnable[drawBufferIdx]) + { + context->enablei(GL_BLEND, drawBufferIdx); + } + if (mColorMasksToRestore[drawBufferIdx]) + { + const std::array &mask = mSavedColorMasks[drawBufferIdx]; + context->colorMaski(drawBufferIdx, mask[0], mask[1], mask[2], mask[3]); + } + } + } + + // Restore the draw buffer state from before PLS was enabled. + context->drawBuffers(static_cast(mSavedDrawBuffers.size()), + mSavedDrawBuffers.data()); + mSavedDrawBuffers.clear(); + } + + void onBarrier(Context *context) override { context->framebufferFetchBarrier(); } + + private: + GLuint getDrawBufferIdx(const Caps &caps, GLuint plsPlaneIdx) + { + // Bind the PLS attachments in reverse order from the rear. This way, the shader translator + // doesn't need to know how many planes are going to be active in order to figure out plane + // indices. + return caps.maxCombinedDrawBuffersAndPixelLocalStoragePlanes - plsPlaneIdx - 1; + } + + DrawBuffersVector mSavedDrawBuffers; + DrawBufferMask mBlendsToReEnable; + DrawBufferMask mColorMasksToRestore; + DrawBuffersArray> mSavedColorMasks; + DrawBuffersVector mInvalidateList; +}; +} // namespace + +std::unique_ptr PixelLocalStorage::Make(const Context *context) +{ + switch (context->getImplementation()->getNativePixelLocalStorageType()) + { + case ShPixelLocalStorageType::ImageStoreR32PackedFormats: + return std::make_unique(true); + case ShPixelLocalStorageType::ImageStoreNativeFormats: + return std::make_unique(false); + case ShPixelLocalStorageType::FramebufferFetch: + return std::make_unique(); + default: + UNREACHABLE(); + return nullptr; + } +} +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/PixelLocalStorage.h b/gfx/angle/checkout/src/libANGLE/PixelLocalStorage.h new file mode 100644 index 0000000000..f60ab7443d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/PixelLocalStorage.h @@ -0,0 +1,177 @@ +// +// Copyright 2022 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// PixelLocalStorage.h: Defines the renderer-agnostic container classes +// gl::PixelLocalStorage and gl::PixelLocalStoragePlane for +// ANGLE_shader_pixel_local_storage. + +#ifndef LIBANGLE_PIXEL_LOCAL_STORAGE_H_ +#define LIBANGLE_PIXEL_LOCAL_STORAGE_H_ + +#include "angle_gl.h" +#include "libANGLE/ImageIndex.h" +#include "libANGLE/angletypes.h" + +namespace gl +{ + +class Context; +class Texture; + +// Holds the configuration of an ANGLE_shader_pixel_local_storage plane. +// +// Unlike normal framebuffer attachments, pixel local storage planes don't take effect until the +// application calls glBeginPixelLocalStorageANGLE, and the manner in which they take effect is +// highly dependent on the backend implementation. A PixelLocalStoragePlane is just a plain data +// description what to set up later once PLS is enabled. +class PixelLocalStoragePlane : angle::NonCopyable +{ + public: + ~PixelLocalStoragePlane(); + + // Called when the context is lost or destroyed. Causes this class to clear its GL object + // handles. + void onContextObjectsLost(); + + // Called when the owning framebuffer is being destroyed. Causes this class to release its + // texture object reference. + void onFramebufferDestroyed(const Context *); + + void deinitialize(Context *); + void setMemoryless(Context *, GLenum internalformat); + void setTextureBacked(Context *, Texture *, int level, int layer); + + bool isDeinitialized() const { return mInternalformat == GL_NONE; } + + // Returns true if the texture ID bound to this plane has been deleted. + // + // [ANGLE_shader_pixel_local_storage] Section 4.4.2.X "Configuring Pixel Local Storage + // on a Framebuffer": When a texture object is deleted, any pixel local storage plane to + // which it was bound is automatically converted to a memoryless plane of matching + // internalformat. + bool isTextureIDDeleted(const Context *) const; + + bool isMemoryless() const + { + // isMemoryless() should be false if the plane is deinitialized. + ASSERT(!(isDeinitialized() && mMemoryless)); + return mMemoryless; + } + + GLenum getInternalformat() const { return mInternalformat; } + + // Implements glGetIntegeri_v() for GL_PIXEL_LOCAL_FORMAT_ANGLE, + // GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE, and + // GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE + GLint getIntegeri(const Context *, GLenum target, GLuint index) const; + + // If this plane is texture backed, stores the bound texture image's {width, height, 0} to + // Extents and returns true. Otherwise returns false, meaning the plane is either deinitialized + // or memoryless. + bool getTextureImageExtents(const Context *, Extents *extents) const; + + // Attaches this plane to the specified color attachment point on the current draw framebuffer. + void attachToDrawFramebuffer(Context *, Extents plsExtents, GLenum colorAttachment); + + // Clears the draw buffer at 0-based index 'drawbuffer' on the current framebuffer. Reads the + // clear value from 'data' if 'loadop' is GL_CLEAR_ANGLE, otherwise clears to zero. + // + // 'data' is interpereted as either 4 GLfloats, 4 GLints, or 4 GLuints, depending on + // mInternalFormat. + // + // The context must internally disable the scissor test before calling this method, since the + // intention is to clear the entire surface. + void performLoadOperationClear(Context *, GLint drawbuffer, GLenum loadop, const void *data); + + // Binds this PLS plane to a texture image unit for image load/store shader operations. + void bindToImage(Context *, Extents plsExtents, GLuint unit, bool needsR32Packing); + + private: + // Ensures we have an internal backing texture for memoryless planes. In GL, we need a backing + // texture even if the plane is memoryless; glInvalidateFramebuffer() will ideally prevent the + // driver from writing out data where possible. + void ensureBackingIfMemoryless(Context *, Extents plsSize); + + GLenum mInternalformat = GL_NONE; // GL_NONE if this plane is in a deinitialized state. + bool mMemoryless = false; + TextureID mMemorylessTextureID{}; // We own memoryless backing textures and must delete them. + ImageIndex mTextureImageIndex; + Texture *mTextureRef = nullptr; +}; + +// Manages a collection of PixelLocalStoragePlanes and applies them to ANGLE's GL state. +// +// The main magic of ANGLE_shader_pixel_local_storage happens inside shaders, so we just emulate the +// client API on top of ANGLE's OpenGL ES API for simplicity. +class PixelLocalStorage +{ + public: + static std::unique_ptr Make(const Context *); + + PixelLocalStorage(); + virtual ~PixelLocalStorage(); + + // Called when the owning framebuffer is being destroyed. + void onFramebufferDestroyed(const Context *); + + // Deletes any GL objects that have been allocated for pixel local storage. These can't be + // cleaned up in the destructor because they require a non-const Context object. + void deleteContextObjects(Context *); + + const PixelLocalStoragePlane &getPlane(GLint plane) const + { + ASSERT(0 <= plane && plane < IMPLEMENTATION_MAX_PIXEL_LOCAL_STORAGE_PLANES); + return mPlanes[plane]; + } + + PixelLocalStoragePlane &getPlane(GLint plane) + { + ASSERT(0 <= plane && plane < IMPLEMENTATION_MAX_PIXEL_LOCAL_STORAGE_PLANES); + return mPlanes[plane]; + } + + // ANGLE_shader_pixel_local_storage API. + void deinitialize(Context *context, GLint plane) { mPlanes[plane].deinitialize(context); } + void setMemoryless(Context *context, GLint plane, GLenum internalformat) + { + mPlanes[plane].setMemoryless(context, internalformat); + } + void setTextureBacked(Context *context, GLint plane, Texture *tex, int level, int layer) + { + mPlanes[plane].setTextureBacked(context, tex, level, layer); + } + void begin(Context *, GLsizei n, const GLenum loadops[], const void *cleardata); + void end(Context *); + void barrier(Context *); + + protected: + // Called when the context is lost or destroyed. Causes the subclass to clear its GL object + // handles. + virtual void onContextObjectsLost() = 0; + + // Called when the framebuffer is being destroyed. Causes the subclass to delete its frontend GL + // object handles. + virtual void onDeleteContextObjects(Context *) = 0; + + // ANGLE_shader_pixel_local_storage API. + virtual void onBegin(Context *, + GLsizei n, + const GLenum loadops[], + const char *cleardata, + Extents plsSize) = 0; + virtual void onEnd(Context *, GLsizei numActivePLSPlanes) = 0; + virtual void onBarrier(Context *) = 0; + + private: + std::array mPlanes; + + // "n" from the last call to begin(), or 0 if pixel local storage is not active. + GLsizei mNumActivePLSPlanes = 0; +}; + +} // namespace gl + +#endif // LIBANGLE_PIXEL_LOCAL_STORAGE_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Platform.cpp b/gfx/angle/checkout/src/libANGLE/Platform.cpp new file mode 100644 index 0000000000..d798fd4e86 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Platform.cpp @@ -0,0 +1,76 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Platform.cpp: Implementation methods for angle::Platform. + +#include + +#include + +#include "common/debug.h" + +namespace +{ +// TODO(jmadill): Make methods owned by egl::Display. +angle::PlatformMethods &PlatformMethods() +{ + static angle::PlatformMethods platformMethods; + return platformMethods; +} +} // anonymous namespace + +angle::PlatformMethods *ANGLEPlatformCurrent() +{ + return &PlatformMethods(); +} + +bool ANGLE_APIENTRY ANGLEGetDisplayPlatform(angle::EGLDisplayType display, + const char *const methodNames[], + unsigned int methodNameCount, + void *context, + void *platformMethods) +{ + angle::PlatformMethods **platformMethodsOut = + reinterpret_cast(platformMethods); + + // We allow for a lower input count of impl platform methods if the subset is correct. + if (methodNameCount > angle::g_NumPlatformMethods) + { + ERR() << "Invalid platform method count: " << methodNameCount << ", expected " + << angle::g_NumPlatformMethods << "."; + return false; + } + + for (unsigned int nameIndex = 0; nameIndex < methodNameCount; ++nameIndex) + { + const char *expectedName = angle::g_PlatformMethodNames[nameIndex]; + const char *actualName = methodNames[nameIndex]; + + // Skip deprecated methods. The names of these methods start with |placeholder|. + constexpr char kPlaceholder[] = "placeholder"; + if (strncmp(expectedName, kPlaceholder, sizeof(kPlaceholder) - 1) == 0) + { + continue; + } + if (strcmp(expectedName, actualName) != 0) + { + ERR() << "Invalid platform method name: " << actualName << ", expected " << expectedName + << "."; + return false; + } + } + + // TODO(jmadill): Store platform methods in display. + PlatformMethods().context = context; + *platformMethodsOut = &PlatformMethods(); + return true; +} + +void ANGLE_APIENTRY ANGLEResetDisplayPlatform(angle::EGLDisplayType display) +{ + // TODO(jmadill): Store platform methods in display. + PlatformMethods() = angle::PlatformMethods(); +} diff --git a/gfx/angle/checkout/src/libANGLE/Program.cpp b/gfx/angle/checkout/src/libANGLE/Program.cpp new file mode 100644 index 0000000000..3191a43ff3 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Program.cpp @@ -0,0 +1,3810 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Program.cpp: Implements the gl::Program class. Implements GL program objects +// and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28. + +#include "libANGLE/Program.h" + +#include +#include + +#include "common/angle_version_info.h" +#include "common/bitset_utils.h" +#include "common/debug.h" +#include "common/platform.h" +#include "common/string_utils.h" +#include "common/utilities.h" +#include "compiler/translator/blocklayout.h" +#include "libANGLE/Context.h" +#include "libANGLE/ErrorStrings.h" +#include "libANGLE/MemoryProgramCache.h" +#include "libANGLE/ProgramLinkedResources.h" +#include "libANGLE/ResourceManager.h" +#include "libANGLE/Uniform.h" +#include "libANGLE/VaryingPacking.h" +#include "libANGLE/Version.h" +#include "libANGLE/capture/FrameCapture.h" +#include "libANGLE/features.h" +#include "libANGLE/histogram_macros.h" +#include "libANGLE/queryconversions.h" +#include "libANGLE/renderer/GLImplFactory.h" +#include "libANGLE/renderer/ProgramImpl.h" +#include "platform/FrontendFeatures_autogen.h" +#include "platform/PlatformMethods.h" + +namespace gl +{ + +namespace +{ + +// This simplified cast function doesn't need to worry about advanced concepts like +// depth range values, or casting to bool. +template +DestT UniformStateQueryCast(SrcT value); + +// From-Float-To-Integer Casts +template <> +GLint UniformStateQueryCast(GLfloat value) +{ + return clampCast(roundf(value)); +} + +template <> +GLuint UniformStateQueryCast(GLfloat value) +{ + return clampCast(roundf(value)); +} + +// From-Integer-to-Integer Casts +template <> +GLint UniformStateQueryCast(GLuint value) +{ + return clampCast(value); +} + +template <> +GLuint UniformStateQueryCast(GLint value) +{ + return clampCast(value); +} + +// From-Boolean-to-Anything Casts +template <> +GLfloat UniformStateQueryCast(GLboolean value) +{ + return (ConvertToBool(value) ? 1.0f : 0.0f); +} + +template <> +GLint UniformStateQueryCast(GLboolean value) +{ + return (ConvertToBool(value) ? 1 : 0); +} + +template <> +GLuint UniformStateQueryCast(GLboolean value) +{ + return (ConvertToBool(value) ? 1u : 0u); +} + +// Default to static_cast +template +DestT UniformStateQueryCast(SrcT value) +{ + return static_cast(value); +} + +template +void UniformStateQueryCastLoop(DestT *dataOut, const uint8_t *srcPointer, int components) +{ + for (int comp = 0; comp < components; ++comp) + { + // We only work with strides of 4 bytes for uniform components. (GLfloat/GLint) + // Don't use SrcT stride directly since GLboolean has a stride of 1 byte. + size_t offset = comp * 4; + const SrcT *typedSrcPointer = reinterpret_cast(&srcPointer[offset]); + dataOut[comp] = UniformStateQueryCast(*typedSrcPointer); + } +} + +template +GLuint GetResourceIndexFromName(const std::vector &list, const std::string &name) +{ + std::string nameAsArrayName = name + "[0]"; + for (size_t index = 0; index < list.size(); index++) + { + const VarT &resource = list[index]; + if (resource.name == name || (resource.isArray() && resource.name == nameAsArrayName)) + { + return static_cast(index); + } + } + + return GL_INVALID_INDEX; +} + +GLint GetVariableLocation(const std::vector &list, + const std::vector &locationList, + const std::string &name) +{ + size_t nameLengthWithoutArrayIndex; + unsigned int arrayIndex = ParseArrayIndex(name, &nameLengthWithoutArrayIndex); + + for (size_t location = 0u; location < locationList.size(); ++location) + { + const VariableLocation &variableLocation = locationList[location]; + if (!variableLocation.used()) + { + continue; + } + + const sh::ShaderVariable &variable = list[variableLocation.index]; + + // Array output variables may be bound out of order, so we need to ensure we only pick the + // first element if given the base name. + if ((variable.name == name) && (variableLocation.arrayIndex == 0)) + { + return static_cast(location); + } + if (variable.isArray() && variableLocation.arrayIndex == arrayIndex && + angle::BeginsWith(variable.name, name, nameLengthWithoutArrayIndex)) + { + return static_cast(location); + } + } + + return -1; +} + +GLint GetVariableLocation(const std::vector &list, + const std::vector &locationList, + const std::string &name) +{ + size_t nameLengthWithoutArrayIndex; + unsigned int arrayIndex = ParseArrayIndex(name, &nameLengthWithoutArrayIndex); + + for (size_t location = 0u; location < locationList.size(); ++location) + { + const VariableLocation &variableLocation = locationList[location]; + if (!variableLocation.used()) + { + continue; + } + + const LinkedUniform &variable = list[variableLocation.index]; + + // Array output variables may be bound out of order, so we need to ensure we only pick the + // first element if given the base name. Uniforms don't allow this behavior and some code + // seemingly depends on the opposite behavior, so only enable it for output variables. + if (angle::BeginsWith(variable.name, name) && (variableLocation.arrayIndex == 0)) + { + if (name.length() == variable.name.length()) + { + ASSERT(name == variable.name); + // GLES 3.1 November 2016 page 87. + // The string exactly matches the name of the active variable. + return static_cast(location); + } + if (name.length() + 3u == variable.name.length() && variable.isArray()) + { + ASSERT(name + "[0]" == variable.name); + // The string identifies the base name of an active array, where the string would + // exactly match the name of the variable if the suffix "[0]" were appended to the + // string. + return static_cast(location); + } + } + if (variable.isArray() && variableLocation.arrayIndex == arrayIndex && + nameLengthWithoutArrayIndex + 3u == variable.name.length() && + angle::BeginsWith(variable.name, name, nameLengthWithoutArrayIndex)) + { + ASSERT(name.substr(0u, nameLengthWithoutArrayIndex) + "[0]" == variable.name); + // The string identifies an active element of the array, where the string ends with the + // concatenation of the "[" character, an integer (with no "+" sign, extra leading + // zeroes, or whitespace) identifying an array element, and the "]" character, the + // integer is less than the number of active elements of the array variable, and where + // the string would exactly match the enumerated name of the array if the decimal + // integer were replaced with zero. + return static_cast(location); + } + } + + return -1; +} + +void CopyStringToBuffer(GLchar *buffer, + const std::string &string, + GLsizei bufSize, + GLsizei *lengthOut) +{ + ASSERT(bufSize > 0); + size_t length = std::min(bufSize - 1, string.length()); + memcpy(buffer, string.c_str(), length); + buffer[length] = '\0'; + + if (lengthOut) + { + *lengthOut = static_cast(length); + } +} + +GLuint GetInterfaceBlockIndex(const std::vector &list, const std::string &name) +{ + std::vector subscripts; + std::string baseName = ParseResourceName(name, &subscripts); + + unsigned int numBlocks = static_cast(list.size()); + for (unsigned int blockIndex = 0; blockIndex < numBlocks; blockIndex++) + { + const auto &block = list[blockIndex]; + if (block.name == baseName) + { + const bool arrayElementZero = + (subscripts.empty() && (!block.isArray || block.arrayElement == 0)); + const bool arrayElementMatches = + (subscripts.size() == 1 && subscripts[0] == block.arrayElement); + if (arrayElementMatches || arrayElementZero) + { + return blockIndex; + } + } + } + + return GL_INVALID_INDEX; +} + +void GetInterfaceBlockName(const UniformBlockIndex index, + const std::vector &list, + GLsizei bufSize, + GLsizei *length, + GLchar *name) +{ + ASSERT(index.value < list.size()); + + const auto &block = list[index.value]; + + if (bufSize > 0) + { + std::string blockName = block.name; + + if (block.isArray) + { + blockName += ArrayString(block.arrayElement); + } + CopyStringToBuffer(name, blockName, bufSize, length); + } +} + +void InitUniformBlockLinker(const Context *context, + const ProgramState &state, + UniformBlockLinker *blockLinker) +{ + for (ShaderType shaderType : AllShaderTypes()) + { + Shader *shader = state.getAttachedShader(shaderType); + if (shader) + { + blockLinker->addShaderBlocks(shaderType, &shader->getUniformBlocks(context)); + } + } +} + +void InitShaderStorageBlockLinker(const Context *context, + const ProgramState &state, + ShaderStorageBlockLinker *blockLinker) +{ + for (ShaderType shaderType : AllShaderTypes()) + { + Shader *shader = state.getAttachedShader(shaderType); + if (shader != nullptr) + { + blockLinker->addShaderBlocks(shaderType, &shader->getShaderStorageBlocks(context)); + } + } +} +} // anonymous namespace + +const char *GetLinkMismatchErrorString(LinkMismatchError linkError) +{ + switch (linkError) + { + case LinkMismatchError::TYPE_MISMATCH: + return "Type"; + case LinkMismatchError::ARRAYNESS_MISMATCH: + return "Array-ness"; + case LinkMismatchError::ARRAY_SIZE_MISMATCH: + return "Array size"; + case LinkMismatchError::PRECISION_MISMATCH: + return "Precision"; + case LinkMismatchError::STRUCT_NAME_MISMATCH: + return "Structure name"; + case LinkMismatchError::FIELD_NUMBER_MISMATCH: + return "Field number"; + case LinkMismatchError::FIELD_NAME_MISMATCH: + return "Field name"; + + case LinkMismatchError::INTERPOLATION_TYPE_MISMATCH: + return "Interpolation type"; + case LinkMismatchError::INVARIANCE_MISMATCH: + return "Invariance"; + + case LinkMismatchError::BINDING_MISMATCH: + return "Binding layout qualifier"; + case LinkMismatchError::LOCATION_MISMATCH: + return "Location layout qualifier"; + case LinkMismatchError::OFFSET_MISMATCH: + return "Offset layout qualifier"; + case LinkMismatchError::INSTANCE_NAME_MISMATCH: + return "Instance name qualifier"; + case LinkMismatchError::FORMAT_MISMATCH: + return "Format qualifier"; + + case LinkMismatchError::LAYOUT_QUALIFIER_MISMATCH: + return "Layout qualifier"; + case LinkMismatchError::MATRIX_PACKING_MISMATCH: + return "Matrix Packing"; + + case LinkMismatchError::FIELD_LOCATION_MISMATCH: + return "Field location"; + case LinkMismatchError::FIELD_STRUCT_NAME_MISMATCH: + return "Field structure name"; + default: + UNREACHABLE(); + return ""; + } +} + +void UpdateInterfaceVariable(std::vector *block, const sh::ShaderVariable &var) +{ + if (!var.isStruct()) + { + block->emplace_back(var); + block->back().resetEffectiveLocation(); + } + + for (const sh::ShaderVariable &field : var.fields) + { + ASSERT(!var.name.empty() || var.isShaderIOBlock); + + // Shader I/O block naming is similar to UBOs and SSBOs: + // + // in Block + // { + // type field; // produces "field" + // }; + // + // in Block2 + // { + // type field; // produces "Block2.field" + // } block2; + // + const std::string &baseName = var.isShaderIOBlock ? var.structOrBlockName : var.name; + const std::string prefix = var.name.empty() ? "" : baseName + "."; + + if (!field.isStruct()) + { + sh::ShaderVariable fieldCopy = field; + fieldCopy.updateEffectiveLocation(var); + fieldCopy.name = prefix + field.name; + block->emplace_back(fieldCopy); + } + + for (const sh::ShaderVariable &nested : field.fields) + { + sh::ShaderVariable nestedCopy = nested; + nestedCopy.updateEffectiveLocation(field); + nestedCopy.name = prefix + field.name + "." + nested.name; + block->emplace_back(nestedCopy); + } + } +} + +void WriteShaderVariableBuffer(BinaryOutputStream *stream, const ShaderVariableBuffer &var) +{ + stream->writeInt(var.binding); + stream->writeInt(var.dataSize); + + for (ShaderType shaderType : AllShaderTypes()) + { + stream->writeBool(var.isActive(shaderType)); + } + + stream->writeInt(var.memberIndexes.size()); + for (unsigned int memberCounterIndex : var.memberIndexes) + { + stream->writeInt(memberCounterIndex); + } +} + +void LoadShaderVariableBuffer(BinaryInputStream *stream, ShaderVariableBuffer *var) +{ + var->binding = stream->readInt(); + var->dataSize = stream->readInt(); + + for (ShaderType shaderType : AllShaderTypes()) + { + var->setActive(shaderType, stream->readBool()); + } + + size_t numMembers = stream->readInt(); + for (size_t blockMemberIndex = 0; blockMemberIndex < numMembers; blockMemberIndex++) + { + var->memberIndexes.push_back(stream->readInt()); + } +} + +void WriteBufferVariable(BinaryOutputStream *stream, const BufferVariable &var) +{ + WriteShaderVar(stream, var); + + stream->writeInt(var.bufferIndex); + WriteBlockMemberInfo(stream, var.blockInfo); + stream->writeInt(var.topLevelArraySize); + + for (ShaderType shaderType : AllShaderTypes()) + { + stream->writeBool(var.isActive(shaderType)); + } +} + +void LoadBufferVariable(BinaryInputStream *stream, BufferVariable *var) +{ + LoadShaderVar(stream, var); + + var->bufferIndex = stream->readInt(); + LoadBlockMemberInfo(stream, &var->blockInfo); + var->topLevelArraySize = stream->readInt(); + + for (ShaderType shaderType : AllShaderTypes()) + { + var->setActive(shaderType, stream->readBool()); + } +} + +void WriteInterfaceBlock(BinaryOutputStream *stream, const InterfaceBlock &block) +{ + stream->writeString(block.name); + stream->writeString(block.mappedName); + stream->writeBool(block.isArray); + stream->writeInt(block.arrayElement); + + WriteShaderVariableBuffer(stream, block); +} + +void LoadInterfaceBlock(BinaryInputStream *stream, InterfaceBlock *block) +{ + block->name = stream->readString(); + block->mappedName = stream->readString(); + block->isArray = stream->readBool(); + block->arrayElement = stream->readInt(); + + LoadShaderVariableBuffer(stream, block); +} + +void WriteShInterfaceBlock(BinaryOutputStream *stream, const sh::InterfaceBlock &block) +{ + stream->writeString(block.name); + stream->writeString(block.mappedName); + stream->writeString(block.instanceName); + stream->writeInt(block.arraySize); + stream->writeEnum(block.layout); + stream->writeBool(block.isRowMajorLayout); + stream->writeInt(block.binding); + stream->writeBool(block.staticUse); + stream->writeBool(block.active); + stream->writeEnum(block.blockType); + + stream->writeInt(block.fields.size()); + for (const sh::ShaderVariable &shaderVariable : block.fields) + { + WriteShaderVar(stream, shaderVariable); + } +} + +void LoadShInterfaceBlock(BinaryInputStream *stream, sh::InterfaceBlock *block) +{ + block->name = stream->readString(); + block->mappedName = stream->readString(); + block->instanceName = stream->readString(); + block->arraySize = stream->readInt(); + block->layout = stream->readEnum(); + block->isRowMajorLayout = stream->readBool(); + block->binding = stream->readInt(); + block->staticUse = stream->readBool(); + block->active = stream->readBool(); + block->blockType = stream->readEnum(); + + block->fields.resize(stream->readInt()); + for (sh::ShaderVariable &variable : block->fields) + { + LoadShaderVar(stream, &variable); + } +} + +// Saves the linking context for later use in resolveLink(). +struct Program::LinkingState +{ + std::shared_ptr linkedExecutable; + ProgramLinkedResources resources; + egl::BlobCache::Key programHash; + std::unique_ptr linkEvent; + bool linkingFromBinary; +}; + +const char *const g_fakepath = "C:\\fakepath"; + +// InfoLog implementation. +InfoLog::InfoLog() : mLazyStream(nullptr) {} + +InfoLog::~InfoLog() {} + +size_t InfoLog::getLength() const +{ + if (!mLazyStream) + { + return 0; + } + + const std::string &logString = mLazyStream->str(); + return logString.empty() ? 0 : logString.length() + 1; +} + +void InfoLog::getLog(GLsizei bufSize, GLsizei *length, char *infoLog) const +{ + size_t index = 0; + + if (bufSize > 0) + { + const std::string logString(str()); + + if (!logString.empty()) + { + index = std::min(static_cast(bufSize) - 1, logString.length()); + memcpy(infoLog, logString.c_str(), index); + } + + infoLog[index] = '\0'; + } + + if (length) + { + *length = static_cast(index); + } +} + +// append a sanitized message to the program info log. +// The D3D compiler includes a fake file path in some of the warning or error +// messages, so lets remove all occurrences of this fake file path from the log. +void InfoLog::appendSanitized(const char *message) +{ + ensureInitialized(); + + std::string msg(message); + + size_t found; + do + { + found = msg.find(g_fakepath); + if (found != std::string::npos) + { + msg.erase(found, strlen(g_fakepath)); + } + } while (found != std::string::npos); + + if (!msg.empty()) + { + *mLazyStream << message << std::endl; + } +} + +void InfoLog::reset() +{ + if (mLazyStream) + { + mLazyStream.reset(nullptr); + } +} + +bool InfoLog::empty() const +{ + if (!mLazyStream) + { + return true; + } + + return mLazyStream->rdbuf()->in_avail() == 0; +} + +void LogLinkMismatch(InfoLog &infoLog, + const std::string &variableName, + const char *variableType, + LinkMismatchError linkError, + const std::string &mismatchedStructOrBlockFieldName, + ShaderType shaderType1, + ShaderType shaderType2) +{ + std::ostringstream stream; + stream << GetLinkMismatchErrorString(linkError) << "s of " << variableType << " '" + << variableName; + + if (!mismatchedStructOrBlockFieldName.empty()) + { + stream << "' member '" << variableName << "." << mismatchedStructOrBlockFieldName; + } + + stream << "' differ between " << GetShaderTypeString(shaderType1) << " and " + << GetShaderTypeString(shaderType2) << " shaders."; + + infoLog << stream.str(); +} + +bool IsActiveInterfaceBlock(const sh::InterfaceBlock &interfaceBlock) +{ + // Only 'packed' blocks are allowed to be considered inactive. + return interfaceBlock.active || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED; +} + +void WriteBlockMemberInfo(BinaryOutputStream *stream, const sh::BlockMemberInfo &var) +{ + stream->writeInt(var.arrayStride); + stream->writeBool(var.isRowMajorMatrix); + stream->writeInt(var.matrixStride); + stream->writeInt(var.offset); + stream->writeInt(var.topLevelArrayStride); +} + +void LoadBlockMemberInfo(BinaryInputStream *stream, sh::BlockMemberInfo *var) +{ + var->arrayStride = stream->readInt(); + var->isRowMajorMatrix = stream->readBool(); + var->matrixStride = stream->readInt(); + var->offset = stream->readInt(); + var->topLevelArrayStride = stream->readInt(); +} + +void WriteShaderVar(BinaryOutputStream *stream, const sh::ShaderVariable &var) +{ + stream->writeInt(var.type); + stream->writeInt(var.precision); + stream->writeString(var.name); + stream->writeString(var.mappedName); + stream->writeIntVector(var.arraySizes); + stream->writeBool(var.staticUse); + stream->writeBool(var.active); + stream->writeInt(var.fields.size()); + for (const sh::ShaderVariable &shaderVariable : var.fields) + { + WriteShaderVar(stream, shaderVariable); + } + stream->writeString(var.structOrBlockName); + stream->writeString(var.mappedStructOrBlockName); + stream->writeBool(var.isRowMajorLayout); + stream->writeInt(var.location); + stream->writeBool(var.hasImplicitLocation); + stream->writeInt(var.binding); + stream->writeInt(var.imageUnitFormat); + stream->writeInt(var.offset); + stream->writeBool(var.rasterOrdered); + stream->writeBool(var.readonly); + stream->writeBool(var.writeonly); + stream->writeBool(var.isFragmentInOut); + stream->writeInt(var.index); + stream->writeBool(var.yuv); + stream->writeEnum(var.interpolation); + stream->writeBool(var.isInvariant); + stream->writeBool(var.isShaderIOBlock); + stream->writeBool(var.isPatch); + stream->writeBool(var.texelFetchStaticUse); + stream->writeInt(var.getFlattenedOffsetInParentArrays()); +} + +void LoadShaderVar(gl::BinaryInputStream *stream, sh::ShaderVariable *var) +{ + var->type = stream->readInt(); + var->precision = stream->readInt(); + stream->readString(&var->name); + stream->readString(&var->mappedName); + stream->readIntVector(&var->arraySizes); + var->staticUse = stream->readBool(); + var->active = stream->readBool(); + size_t elementCount = stream->readInt(); + var->fields.resize(elementCount); + for (sh::ShaderVariable &variable : var->fields) + { + LoadShaderVar(stream, &variable); + } + stream->readString(&var->structOrBlockName); + stream->readString(&var->mappedStructOrBlockName); + var->isRowMajorLayout = stream->readBool(); + var->location = stream->readInt(); + var->hasImplicitLocation = stream->readBool(); + var->binding = stream->readInt(); + var->imageUnitFormat = stream->readInt(); + var->offset = stream->readInt(); + var->rasterOrdered = stream->readBool(); + var->readonly = stream->readBool(); + var->writeonly = stream->readBool(); + var->isFragmentInOut = stream->readBool(); + var->index = stream->readInt(); + var->yuv = stream->readBool(); + var->interpolation = stream->readEnum(); + var->isInvariant = stream->readBool(); + var->isShaderIOBlock = stream->readBool(); + var->isPatch = stream->readBool(); + var->texelFetchStaticUse = stream->readBool(); + var->setParentArrayIndex(stream->readInt()); +} + +// VariableLocation implementation. +VariableLocation::VariableLocation() : arrayIndex(0), index(kUnused), ignored(false) {} + +VariableLocation::VariableLocation(unsigned int arrayIndex, unsigned int index) + : arrayIndex(arrayIndex), index(index), ignored(false) +{ + ASSERT(arrayIndex != GL_INVALID_INDEX); +} + +// SamplerBindings implementation. +SamplerBinding::SamplerBinding(TextureType textureTypeIn, + GLenum samplerTypeIn, + SamplerFormat formatIn, + size_t elementCount) + : textureType(textureTypeIn), + samplerType(samplerTypeIn), + format(formatIn), + boundTextureUnits(elementCount, 0) +{} + +SamplerBinding::SamplerBinding(const SamplerBinding &other) = default; + +SamplerBinding::~SamplerBinding() = default; + +// ProgramBindings implementation. +ProgramBindings::ProgramBindings() {} + +ProgramBindings::~ProgramBindings() {} + +void ProgramBindings::bindLocation(GLuint index, const std::string &name) +{ + mBindings[name] = index; +} + +int ProgramBindings::getBindingByName(const std::string &name) const +{ + auto iter = mBindings.find(name); + return (iter != mBindings.end()) ? iter->second : -1; +} + +int ProgramBindings::getBinding(const sh::ShaderVariable &variable) const +{ + return getBindingByName(variable.name); +} + +ProgramBindings::const_iterator ProgramBindings::begin() const +{ + return mBindings.begin(); +} + +ProgramBindings::const_iterator ProgramBindings::end() const +{ + return mBindings.end(); +} + +std::map ProgramBindings::getStableIterationMap() const +{ + return std::map(mBindings.begin(), mBindings.end()); +} + +// ProgramAliasedBindings implementation. +ProgramAliasedBindings::ProgramAliasedBindings() {} + +ProgramAliasedBindings::~ProgramAliasedBindings() {} + +void ProgramAliasedBindings::bindLocation(GLuint index, const std::string &name) +{ + mBindings[name] = ProgramBinding(index); + + // EXT_blend_func_extended spec: "If it specifies the base name of an array, + // it identifies the resources associated with the first element of the array." + // + // Normalize array bindings so that "name" and "name[0]" map to the same entry. + // If this binding is of the form "name[0]", then mark the "name" binding as + // aliased but do not update it yet in case "name" is not actually an array. + size_t nameLengthWithoutArrayIndex; + unsigned int arrayIndex = ParseArrayIndex(name, &nameLengthWithoutArrayIndex); + if (arrayIndex == 0) + { + std::string baseName = name.substr(0u, nameLengthWithoutArrayIndex); + auto iter = mBindings.find(baseName); + if (iter != mBindings.end()) + { + iter->second.aliased = true; + } + } +} + +int ProgramAliasedBindings::getBindingByName(const std::string &name) const +{ + auto iter = mBindings.find(name); + return (iter != mBindings.end()) ? iter->second.location : -1; +} + +int ProgramAliasedBindings::getBindingByLocation(GLuint location) const +{ + for (const auto &iter : mBindings) + { + if (iter.second.location == location) + { + return iter.second.location; + } + } + return -1; +} + +int ProgramAliasedBindings::getBinding(const sh::ShaderVariable &variable) const +{ + const std::string &name = variable.name; + + // Check with the normalized array name if applicable. + if (variable.isArray()) + { + size_t nameLengthWithoutArrayIndex; + unsigned int arrayIndex = ParseArrayIndex(name, &nameLengthWithoutArrayIndex); + if (arrayIndex == 0) + { + std::string baseName = name.substr(0u, nameLengthWithoutArrayIndex); + auto iter = mBindings.find(baseName); + // If "name" exists and is not aliased, that means it was modified more + // recently than its "name[0]" form and should be used instead of that. + if (iter != mBindings.end() && !iter->second.aliased) + { + return iter->second.location; + } + } + else if (arrayIndex == GL_INVALID_INDEX) + { + auto iter = mBindings.find(variable.name); + // If "name" exists and is not aliased, that means it was modified more + // recently than its "name[0]" form and should be used instead of that. + if (iter != mBindings.end() && !iter->second.aliased) + { + return iter->second.location; + } + // The base name was aliased, so use the name with the array notation. + return getBindingByName(name + "[0]"); + } + } + + return getBindingByName(name); +} + +ProgramAliasedBindings::const_iterator ProgramAliasedBindings::begin() const +{ + return mBindings.begin(); +} + +ProgramAliasedBindings::const_iterator ProgramAliasedBindings::end() const +{ + return mBindings.end(); +} + +std::map ProgramAliasedBindings::getStableIterationMap() const +{ + return std::map(mBindings.begin(), mBindings.end()); +} + +// ImageBinding implementation. +ImageBinding::ImageBinding(size_t count, TextureType textureTypeIn) + : textureType(textureTypeIn), boundImageUnits(count, 0) +{} +ImageBinding::ImageBinding(GLuint imageUnit, size_t count, TextureType textureTypeIn) + : textureType(textureTypeIn) +{ + for (size_t index = 0; index < count; ++index) + { + boundImageUnits.push_back(imageUnit + static_cast(index)); + } +} + +ImageBinding::ImageBinding(const ImageBinding &other) = default; + +ImageBinding::~ImageBinding() = default; + +// ProgramState implementation. +ProgramState::ProgramState() + : mLabel(), + mAttachedShaders{}, + mLocationsUsedForXfbExtension(0), + mBinaryRetrieveableHint(false), + mSeparable(false), + mNumViews(-1), + mDrawIDLocation(-1), + mBaseVertexLocation(-1), + mBaseInstanceLocation(-1), + mCachedBaseVertex(0), + mCachedBaseInstance(0), + mExecutable(new ProgramExecutable()) +{ + mComputeShaderLocalSize.fill(1); +} + +ProgramState::~ProgramState() +{ + ASSERT(!hasAttachedShader()); +} + +const std::string &ProgramState::getLabel() +{ + return mLabel; +} + +Shader *ProgramState::getAttachedShader(ShaderType shaderType) const +{ + ASSERT(shaderType != ShaderType::InvalidEnum); + return mAttachedShaders[shaderType]; +} + +GLuint ProgramState::getUniformIndexFromName(const std::string &name) const +{ + return GetResourceIndexFromName(mExecutable->mUniforms, name); +} + +GLuint ProgramState::getBufferVariableIndexFromName(const std::string &name) const +{ + return GetResourceIndexFromName(mBufferVariables, name); +} + +GLuint ProgramState::getUniformIndexFromLocation(UniformLocation location) const +{ + ASSERT(location.value >= 0 && static_cast(location.value) < mUniformLocations.size()); + return mUniformLocations[location.value].index; +} + +Optional ProgramState::getSamplerIndex(UniformLocation location) const +{ + GLuint index = getUniformIndexFromLocation(location); + if (!isSamplerUniformIndex(index)) + { + return Optional::Invalid(); + } + + return getSamplerIndexFromUniformIndex(index); +} + +bool ProgramState::isSamplerUniformIndex(GLuint index) const +{ + return mExecutable->mSamplerUniformRange.contains(index); +} + +GLuint ProgramState::getSamplerIndexFromUniformIndex(GLuint uniformIndex) const +{ + ASSERT(isSamplerUniformIndex(uniformIndex)); + return uniformIndex - mExecutable->mSamplerUniformRange.low(); +} + +GLuint ProgramState::getUniformIndexFromSamplerIndex(GLuint samplerIndex) const +{ + return mExecutable->getUniformIndexFromSamplerIndex(samplerIndex); +} + +bool ProgramState::isImageUniformIndex(GLuint index) const +{ + return mExecutable->mImageUniformRange.contains(index); +} + +GLuint ProgramState::getImageIndexFromUniformIndex(GLuint uniformIndex) const +{ + ASSERT(isImageUniformIndex(uniformIndex)); + return uniformIndex - mExecutable->mImageUniformRange.low(); +} + +GLuint ProgramState::getAttributeLocation(const std::string &name) const +{ + for (const sh::ShaderVariable &attribute : mExecutable->mProgramInputs) + { + if (attribute.name == name) + { + return attribute.location; + } + } + + return static_cast(-1); +} + +bool ProgramState::hasAttachedShader() const +{ + for (const Shader *shader : mAttachedShaders) + { + if (shader) + { + return true; + } + } + return false; +} + +ShaderType ProgramState::getFirstAttachedShaderStageType() const +{ + const ShaderBitSet linkedStages = mExecutable->getLinkedShaderStages(); + if (linkedStages.none()) + { + return ShaderType::InvalidEnum; + } + + return linkedStages.first(); +} + +ShaderType ProgramState::getLastAttachedShaderStageType() const +{ + const ShaderBitSet linkedStages = mExecutable->getLinkedShaderStages(); + if (linkedStages.none()) + { + return ShaderType::InvalidEnum; + } + + return linkedStages.last(); +} + +ShaderType ProgramState::getAttachedTransformFeedbackStage() const +{ + if (mAttachedShaders[ShaderType::Geometry]) + { + return ShaderType::Geometry; + } + if (mAttachedShaders[ShaderType::TessEvaluation]) + { + return ShaderType::TessEvaluation; + } + return ShaderType::Vertex; +} + +Program::Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, ShaderProgramID handle) + : mSerial(factory->generateSerial()), + mProgram(factory->createProgram(mState)), + mValidated(false), + mLinked(false), + mDeleteStatus(false), + mRefCount(0), + mResourceManager(manager), + mHandle(handle) +{ + ASSERT(mProgram); + + unlink(); +} + +Program::~Program() +{ + ASSERT(!mProgram); +} + +void Program::onDestroy(const Context *context) +{ + resolveLink(context); + for (ShaderType shaderType : AllShaderTypes()) + { + if (mState.mAttachedShaders[shaderType]) + { + mState.mAttachedShaders[shaderType]->release(context); + mState.mAttachedShaders[shaderType] = nullptr; + } + } + + mProgram->destroy(context); + + ASSERT(!mState.hasAttachedShader()); + SafeDelete(mProgram); + + delete this; +} +ShaderProgramID Program::id() const +{ + ASSERT(!mLinkingState); + return mHandle; +} + +angle::Result Program::setLabel(const Context *context, const std::string &label) +{ + ASSERT(!mLinkingState); + mState.mLabel = label; + + if (mProgram) + { + return mProgram->onLabelUpdate(context); + } + return angle::Result::Continue; +} + +const std::string &Program::getLabel() const +{ + ASSERT(!mLinkingState); + return mState.mLabel; +} + +void Program::attachShader(Shader *shader) +{ + ShaderType shaderType = shader->getType(); + ASSERT(shaderType != ShaderType::InvalidEnum); + + mState.mAttachedShaders[shaderType] = shader; + mState.mAttachedShaders[shaderType]->addRef(); +} + +void Program::detachShader(const Context *context, Shader *shader) +{ + resolveLink(context); + ShaderType shaderType = shader->getType(); + ASSERT(shaderType != ShaderType::InvalidEnum); + + ASSERT(mState.mAttachedShaders[shaderType] == shader); + shader->release(context); + mState.mAttachedShaders[shaderType] = nullptr; +} + +int Program::getAttachedShadersCount() const +{ + ASSERT(!mLinkingState); + int numAttachedShaders = 0; + for (const Shader *shader : mState.mAttachedShaders) + { + if (shader) + { + ++numAttachedShaders; + } + } + + return numAttachedShaders; +} + +Shader *Program::getAttachedShader(ShaderType shaderType) const +{ + ASSERT(!mLinkingState); + return mState.getAttachedShader(shaderType); +} + +void Program::bindAttributeLocation(GLuint index, const char *name) +{ + ASSERT(!mLinkingState); + mAttributeBindings.bindLocation(index, name); +} + +void Program::bindUniformLocation(UniformLocation location, const char *name) +{ + ASSERT(!mLinkingState); + mState.mUniformLocationBindings.bindLocation(location.value, name); +} + +void Program::bindFragmentOutputLocation(GLuint index, const char *name) +{ + mFragmentOutputLocations.bindLocation(index, name); +} + +void Program::bindFragmentOutputIndex(GLuint index, const char *name) +{ + mFragmentOutputIndexes.bindLocation(index, name); +} + +angle::Result Program::link(const Context *context) +{ + angle::Result result = linkImpl(context); + + // Avoid having two ProgramExecutables if the link failed and the Program had successfully + // linked previously. + if (mLinkingState && mLinkingState->linkedExecutable) + { + mState.mExecutable = mLinkingState->linkedExecutable; + } + + return result; +} + +// The attached shaders are checked for linking errors by matching up their variables. +// Uniform, input and output variables get collected. +// The code gets compiled into binaries. +angle::Result Program::linkImpl(const Context *context) +{ + ASSERT(!mLinkingState); + // Don't make any local variables pointing to anything within the ProgramExecutable, since + // unlink() could make a new ProgramExecutable making any references/pointers invalid. + auto *platform = ANGLEPlatformCurrent(); + double startTime = platform->currentTime(platform); + + // Unlink the program, but do not clear the validation-related caching yet, since we can still + // use the previously linked program if linking the shaders fails. + mLinked = false; + + mState.mExecutable->resetInfoLog(); + + // Validate we have properly attached shaders before checking the cache. + if (!linkValidateShaders(context, mState.mExecutable->getInfoLog())) + { + return angle::Result::Continue; + } + + egl::BlobCache::Key programHash = {0}; + MemoryProgramCache *cache = context->getMemoryProgramCache(); + + // TODO: http://anglebug.com/4530: Enable program caching for separable programs + if (cache && !isSeparable()) + { + std::lock_guard cacheLock(context->getProgramCacheMutex()); + angle::Result cacheResult = cache->getProgram(context, this, &programHash); + ANGLE_TRY(cacheResult); + + // Check explicitly for Continue, Incomplete means a cache miss + if (cacheResult == angle::Result::Continue) + { + std::scoped_lock lock(mHistogramMutex); + // Succeeded in loading the binaries in the front-end, back end may still be loading + // asynchronously + double delta = platform->currentTime(platform) - startTime; + int us = static_cast(delta * 1000000.0); + ANGLE_HISTOGRAM_COUNTS("GPU.ANGLE.ProgramCache.ProgramCacheHitTimeUS", us); + return angle::Result::Continue; + } + } + + // Cache load failed, fall through to normal linking. + unlink(); + InfoLog &infoLog = mState.mExecutable->getInfoLog(); + + // Re-link shaders after the unlink call. + bool result = linkValidateShaders(context, infoLog); + ASSERT(result); + + std::unique_ptr linkingState(new LinkingState()); + ProgramMergedVaryings mergedVaryings; + LinkingVariables linkingVariables(context, mState); + ProgramLinkedResources &resources = linkingState->resources; + + resources.init(&mState.mExecutable->mUniformBlocks, &mState.mExecutable->mUniforms, + &mState.mExecutable->mShaderStorageBlocks, &mState.mBufferVariables, + &mState.mExecutable->mAtomicCounterBuffers); + + // TODO: Fix incomplete linking. http://anglebug.com/6358 + updateLinkedShaderStages(); + + InitUniformBlockLinker(context, mState, &resources.uniformBlockLinker); + InitShaderStorageBlockLinker(context, mState, &resources.shaderStorageBlockLinker); + + if (mState.mAttachedShaders[ShaderType::Compute]) + { + GLuint combinedImageUniforms = 0; + if (!linkUniforms(context, &resources.unusedUniforms, &combinedImageUniforms, infoLog)) + { + return angle::Result::Continue; + } + + GLuint combinedShaderStorageBlocks = 0u; + if (!LinkValidateProgramInterfaceBlocks(context, + mState.mExecutable->getLinkedShaderStages(), + resources, infoLog, &combinedShaderStorageBlocks)) + { + return angle::Result::Continue; + } + + // [OpenGL ES 3.1] Chapter 8.22 Page 203: + // A link error will be generated if the sum of the number of active image uniforms used in + // all shaders, the number of active shader storage blocks, and the number of active + // fragment shader outputs exceeds the implementation-dependent value of + // MAX_COMBINED_SHADER_OUTPUT_RESOURCES. + if (combinedImageUniforms + combinedShaderStorageBlocks > + static_cast(context->getCaps().maxCombinedShaderOutputResources)) + { + infoLog + << "The sum of the number of active image uniforms, active shader storage blocks " + "and active fragment shader outputs exceeds " + "MAX_COMBINED_SHADER_OUTPUT_RESOURCES (" + << context->getCaps().maxCombinedShaderOutputResources << ")"; + return angle::Result::Continue; + } + } + else + { + if (!linkAttributes(context, infoLog)) + { + return angle::Result::Continue; + } + + if (!linkVaryings(context, infoLog)) + { + return angle::Result::Continue; + } + + GLuint combinedImageUniforms = 0; + if (!linkUniforms(context, &resources.unusedUniforms, &combinedImageUniforms, infoLog)) + { + return angle::Result::Continue; + } + + GLuint combinedShaderStorageBlocks = 0u; + if (!LinkValidateProgramInterfaceBlocks(context, + mState.mExecutable->getLinkedShaderStages(), + resources, infoLog, &combinedShaderStorageBlocks)) + { + return angle::Result::Continue; + } + + if (!LinkValidateProgramGlobalNames(infoLog, getExecutable(), linkingVariables)) + { + return angle::Result::Continue; + } + + gl::Shader *vertexShader = mState.mAttachedShaders[ShaderType::Vertex]; + if (vertexShader) + { + mState.mNumViews = vertexShader->getNumViews(context); + mState.mSpecConstUsageBits |= vertexShader->getSpecConstUsageBits(); + } + + gl::Shader *fragmentShader = mState.mAttachedShaders[ShaderType::Fragment]; + if (fragmentShader) + { + if (!mState.mExecutable->linkValidateOutputVariables( + context->getCaps(), context->getExtensions(), context->getClientVersion(), + combinedImageUniforms, combinedShaderStorageBlocks, + fragmentShader->getActiveOutputVariables(context), + fragmentShader->getShaderVersion(context), mFragmentOutputLocations, + mFragmentOutputIndexes)) + { + return angle::Result::Continue; + } + + mState.mExecutable->mHasDiscard = fragmentShader->hasDiscard(); + mState.mExecutable->mEnablesPerSampleShading = + fragmentShader->enablesPerSampleShading(); + mState.mExecutable->mAdvancedBlendEquations = + fragmentShader->getAdvancedBlendEquations(); + mState.mSpecConstUsageBits |= fragmentShader->getSpecConstUsageBits(); + } + + mergedVaryings = GetMergedVaryingsFromLinkingVariables(linkingVariables); + if (!mState.mExecutable->linkMergedVaryings( + context, mergedVaryings, mState.mTransformFeedbackVaryingNames, linkingVariables, + isSeparable(), &resources.varyingPacking)) + { + return angle::Result::Continue; + } + } + + mState.mExecutable->saveLinkedStateInfo(context, mState); + + mLinkingState = std::move(linkingState); + mLinkingState->linkingFromBinary = false; + mLinkingState->programHash = programHash; + mLinkingState->linkEvent = mProgram->link(context, resources, infoLog, mergedVaryings); + + // Must be after mProgram->link() to avoid misleading the linker about output variables. + mState.updateProgramInterfaceInputs(context); + mState.updateProgramInterfaceOutputs(context); + + if (mState.mSeparable) + { + mLinkingState->linkedExecutable = mState.mExecutable; + } + + return angle::Result::Continue; +} + +bool Program::isLinking() const +{ + return (mLinkingState.get() && mLinkingState->linkEvent && + mLinkingState->linkEvent->isLinking()); +} + +void Program::resolveLinkImpl(const Context *context) +{ + ASSERT(mLinkingState.get()); + + angle::Result result = mLinkingState->linkEvent->wait(context); + + mLinked = result == angle::Result::Continue; + std::unique_ptr linkingState = std::move(mLinkingState); + if (!mLinked) + { + mState.mExecutable->reset(false); + return; + } + + if (linkingState->linkingFromBinary) + { + // All internal Program state is already loaded from the binary. + return; + } + + initInterfaceBlockBindings(); + + // According to GLES 3.0/3.1 spec for LinkProgram and UseProgram, + // Only successfully linked program can replace the executables. + ASSERT(mLinked); + + // Mark implementation-specific unreferenced uniforms as ignored. + std::vector *imageBindings = getExecutable().getImageBindings(); + mProgram->markUnusedUniformLocations(&mState.mUniformLocations, + &mState.mExecutable->mSamplerBindings, imageBindings); + + // Must be called after markUnusedUniformLocations. + postResolveLink(context); + + // Save to the program cache. + std::lock_guard cacheLock(context->getProgramCacheMutex()); + MemoryProgramCache *cache = context->getMemoryProgramCache(); + // TODO: http://anglebug.com/4530: Enable program caching for separable programs + if (cache && !isSeparable() && + (mState.mExecutable->mLinkedTransformFeedbackVaryings.empty() || + !context->getFrontendFeatures().disableProgramCachingForTransformFeedback.enabled)) + { + if (cache->putProgram(linkingState->programHash, context, this) == angle::Result::Stop) + { + // Don't fail linking if putting the program binary into the cache fails, the program is + // still usable. + ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_LOW, + "Failed to save linked program to memory program cache."); + } + } +} + +void Program::updateLinkedShaderStages() +{ + mState.mExecutable->resetLinkedShaderStages(); + + for (const Shader *shader : mState.mAttachedShaders) + { + if (shader) + { + mState.mExecutable->setLinkedShaderStages(shader->getType()); + } + } +} + +void ProgramState::updateActiveSamplers() +{ + mExecutable->mActiveSamplerRefCounts.fill(0); + mExecutable->updateActiveSamplers(*this); +} + +void ProgramState::updateProgramInterfaceInputs(const Context *context) +{ + const ShaderType firstAttachedShaderType = getFirstAttachedShaderStageType(); + + if (firstAttachedShaderType == ShaderType::Vertex) + { + // Vertex attributes are already what we need, so nothing to do + return; + } + + Shader *shader = getAttachedShader(firstAttachedShaderType); + ASSERT(shader); + + // Copy over each input varying, since the Shader could go away + if (shader->getType() == ShaderType::Compute) + { + for (const sh::ShaderVariable &attribute : shader->getAllAttributes(context)) + { + // Compute Shaders have the following built-in input variables. + // + // in uvec3 gl_NumWorkGroups; + // in uvec3 gl_WorkGroupID; + // in uvec3 gl_LocalInvocationID; + // in uvec3 gl_GlobalInvocationID; + // in uint gl_LocalInvocationIndex; + // They are all vecs or uints, so no special handling is required. + mExecutable->mProgramInputs.emplace_back(attribute); + } + } + else + { + for (const sh::ShaderVariable &varying : shader->getInputVaryings(context)) + { + UpdateInterfaceVariable(&mExecutable->mProgramInputs, varying); + } + } +} + +void ProgramState::updateProgramInterfaceOutputs(const Context *context) +{ + const ShaderType lastAttachedShaderType = getLastAttachedShaderStageType(); + + if (lastAttachedShaderType == ShaderType::Fragment) + { + // Fragment outputs are already what we need, so nothing to do + return; + } + if (lastAttachedShaderType == ShaderType::Compute) + { + // If the program only contains a Compute Shader, then there are no user-defined outputs. + return; + } + + Shader *shader = getAttachedShader(lastAttachedShaderType); + ASSERT(shader); + + // Copy over each output varying, since the Shader could go away + for (const sh::ShaderVariable &varying : shader->getOutputVaryings(context)) + { + UpdateInterfaceVariable(&mExecutable->mOutputVariables, varying); + } +} + +// Returns the program object to an unlinked state, before re-linking, or at destruction +void Program::unlink() +{ + if (mLinkingState && mLinkingState->linkedExecutable) + { + // The new ProgramExecutable that we'll attempt to link with needs to start from a copy of + // the last successfully linked ProgramExecutable, so we don't lose any state information. + mState.mExecutable.reset(new ProgramExecutable(*mLinkingState->linkedExecutable)); + } + mState.mExecutable->reset(true); + + mState.mUniformLocations.clear(); + mState.mBufferVariables.clear(); + mState.mComputeShaderLocalSize.fill(1); + mState.mNumViews = -1; + mState.mDrawIDLocation = -1; + mState.mBaseVertexLocation = -1; + mState.mBaseInstanceLocation = -1; + mState.mCachedBaseVertex = 0; + mState.mCachedBaseInstance = 0; + mState.mSpecConstUsageBits.reset(); + + mValidated = false; + + mLinked = false; +} + +angle::Result Program::loadBinary(const Context *context, + GLenum binaryFormat, + const void *binary, + GLsizei length) +{ + ASSERT(!mLinkingState); + unlink(); + InfoLog &infoLog = mState.mExecutable->getInfoLog(); + + if (!angle::GetANGLEHasBinaryLoading()) + { + return angle::Result::Incomplete; + } + + ASSERT(binaryFormat == GL_PROGRAM_BINARY_ANGLE); + if (binaryFormat != GL_PROGRAM_BINARY_ANGLE) + { + infoLog << "Invalid program binary format."; + return angle::Result::Incomplete; + } + + BinaryInputStream stream(binary, length); + ANGLE_TRY(deserialize(context, stream, infoLog)); + // Currently we require the full shader text to compute the program hash. + // We could also store the binary in the internal program cache. + + for (size_t uniformBlockIndex = 0; + uniformBlockIndex < mState.mExecutable->getActiveUniformBlockCount(); ++uniformBlockIndex) + { + mDirtyBits.set(uniformBlockIndex); + } + + // The rx::LinkEvent returned from ProgramImpl::load is a base class with multiple + // implementations. In some implementations, a background thread is used to compile the + // shaders. Any calls to the LinkEvent object, therefore, are racy and may interfere with + // the operation. + + // We do not want to call LinkEvent::wait because that will cause the background thread + // to finish its task before returning, thus defeating the purpose of background compilation. + // We need to defer waiting on background compilation until the very last minute when we + // absolutely need the results, such as when the developer binds the program or queries + // for the completion status. + + // If load returns nullptr, we know for sure that the binary is not compatible with the backend. + // The loaded binary could have been read from the on-disk shader cache and be corrupted or + // serialized with different revision and subsystem id than the currently loaded backend. + // Returning 'Incomplete' to the caller results in link happening using the original shader + // sources. + angle::Result result; + std::unique_ptr linkingState; + std::unique_ptr linkEvent = mProgram->load(context, &stream, infoLog); + if (linkEvent) + { + linkingState = std::make_unique(); + linkingState->linkingFromBinary = true; + linkingState->linkEvent = std::move(linkEvent); + result = angle::Result::Continue; + } + else + { + result = angle::Result::Incomplete; + } + mLinkingState = std::move(linkingState); + + return result; +} + +angle::Result Program::saveBinary(Context *context, + GLenum *binaryFormat, + void *binary, + GLsizei bufSize, + GLsizei *length) const +{ + ASSERT(!mLinkingState); + if (binaryFormat) + { + *binaryFormat = GL_PROGRAM_BINARY_ANGLE; + } + + angle::MemoryBuffer memoryBuf; + ANGLE_TRY(serialize(context, &memoryBuf)); + + GLsizei streamLength = static_cast(memoryBuf.size()); + const uint8_t *streamState = memoryBuf.data(); + + if (streamLength > bufSize) + { + if (length) + { + *length = 0; + } + + // TODO: This should be moved to the validation layer but computing the size of the binary + // before saving it causes the save to happen twice. It may be possible to write the binary + // to a separate buffer, validate sizes and then copy it. + ANGLE_CHECK(context, false, "Insufficient buffer size", GL_INVALID_OPERATION); + } + + if (binary) + { + char *ptr = reinterpret_cast(binary); + + memcpy(ptr, streamState, streamLength); + ptr += streamLength; + + ASSERT(ptr - streamLength == binary); + } + + if (length) + { + *length = streamLength; + } + + return angle::Result::Continue; +} + +GLint Program::getBinaryLength(Context *context) const +{ + ASSERT(!mLinkingState); + if (!mLinked) + { + return 0; + } + + GLint length; + angle::Result result = + saveBinary(context, nullptr, nullptr, std::numeric_limits::max(), &length); + if (result != angle::Result::Continue) + { + return 0; + } + + return length; +} + +void Program::setBinaryRetrievableHint(bool retrievable) +{ + ASSERT(!mLinkingState); + // TODO(jmadill) : replace with dirty bits + mProgram->setBinaryRetrievableHint(retrievable); + mState.mBinaryRetrieveableHint = retrievable; +} + +bool Program::getBinaryRetrievableHint() const +{ + ASSERT(!mLinkingState); + return mState.mBinaryRetrieveableHint; +} + +void Program::setSeparable(bool separable) +{ + ASSERT(!mLinkingState); + // TODO(yunchao) : replace with dirty bits + if (mState.mSeparable != separable) + { + mProgram->setSeparable(separable); + mState.mSeparable = separable; + } +} + +bool Program::isSeparable() const +{ + ASSERT(!mLinkingState); + return mState.mSeparable; +} + +void Program::deleteSelf(const Context *context) +{ + ASSERT(mRefCount == 0 && mDeleteStatus); + mResourceManager->deleteProgram(context, mHandle); +} + +unsigned int Program::getRefCount() const +{ + return mRefCount; +} + +void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, ShaderProgramID *shaders) const +{ + ASSERT(!mLinkingState); + int total = 0; + + for (const Shader *shader : mState.mAttachedShaders) + { + if (shader && (total < maxCount)) + { + shaders[total] = shader->getHandle(); + ++total; + } + } + + if (count) + { + *count = total; + } +} + +GLuint Program::getAttributeLocation(const std::string &name) const +{ + ASSERT(!mLinkingState); + return mState.getAttributeLocation(name); +} + +void Program::getActiveAttribute(GLuint index, + GLsizei bufsize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name) const +{ + ASSERT(!mLinkingState); + if (!mLinked) + { + if (bufsize > 0) + { + name[0] = '\0'; + } + + if (length) + { + *length = 0; + } + + *type = GL_NONE; + *size = 1; + return; + } + + ASSERT(index < mState.mExecutable->getProgramInputs().size()); + const sh::ShaderVariable &attrib = mState.mExecutable->getProgramInputs()[index]; + + if (bufsize > 0) + { + CopyStringToBuffer(name, attrib.name, bufsize, length); + } + + // Always a single 'type' instance + *size = 1; + *type = attrib.type; +} + +GLint Program::getActiveAttributeCount() const +{ + ASSERT(!mLinkingState); + if (!mLinked) + { + return 0; + } + + return static_cast(mState.mExecutable->getProgramInputs().size()); +} + +GLint Program::getActiveAttributeMaxLength() const +{ + ASSERT(!mLinkingState); + if (!mLinked) + { + return 0; + } + + size_t maxLength = 0; + + for (const sh::ShaderVariable &attrib : mState.mExecutable->getProgramInputs()) + { + maxLength = std::max(attrib.name.length() + 1, maxLength); + } + + return static_cast(maxLength); +} + +const std::vector &Program::getAttributes() const +{ + ASSERT(!mLinkingState); + return mState.mExecutable->getProgramInputs(); +} + +const sh::WorkGroupSize &Program::getComputeShaderLocalSize() const +{ + ASSERT(!mLinkingState); + return mState.mComputeShaderLocalSize; +} + +PrimitiveMode Program::getGeometryShaderInputPrimitiveType() const +{ + ASSERT(!mLinkingState && mState.mExecutable); + return mState.mExecutable->getGeometryShaderInputPrimitiveType(); +} +PrimitiveMode Program::getGeometryShaderOutputPrimitiveType() const +{ + ASSERT(!mLinkingState && mState.mExecutable); + return mState.mExecutable->getGeometryShaderOutputPrimitiveType(); +} +GLint Program::getGeometryShaderInvocations() const +{ + ASSERT(!mLinkingState && mState.mExecutable); + return mState.mExecutable->getGeometryShaderInvocations(); +} +GLint Program::getGeometryShaderMaxVertices() const +{ + ASSERT(!mLinkingState && mState.mExecutable); + return mState.mExecutable->getGeometryShaderMaxVertices(); +} + +GLint Program::getTessControlShaderVertices() const +{ + ASSERT(!mLinkingState && mState.mExecutable); + return mState.mExecutable->mTessControlShaderVertices; +} + +GLenum Program::getTessGenMode() const +{ + ASSERT(!mLinkingState && mState.mExecutable); + return mState.mExecutable->mTessGenMode; +} + +GLenum Program::getTessGenPointMode() const +{ + ASSERT(!mLinkingState && mState.mExecutable); + return mState.mExecutable->mTessGenPointMode; +} + +GLenum Program::getTessGenSpacing() const +{ + ASSERT(!mLinkingState && mState.mExecutable); + return mState.mExecutable->mTessGenSpacing; +} + +GLenum Program::getTessGenVertexOrder() const +{ + ASSERT(!mLinkingState && mState.mExecutable); + return mState.mExecutable->mTessGenVertexOrder; +} + +const sh::ShaderVariable &Program::getInputResource(size_t index) const +{ + ASSERT(!mLinkingState); + ASSERT(index < mState.mExecutable->getProgramInputs().size()); + return mState.mExecutable->getProgramInputs()[index]; +} + +GLuint Program::getInputResourceIndex(const GLchar *name) const +{ + ASSERT(!mLinkingState); + const std::string nameString = StripLastArrayIndex(name); + + for (size_t index = 0; index < mState.mExecutable->getProgramInputs().size(); index++) + { + sh::ShaderVariable resource = getInputResource(index); + if (resource.name == nameString) + { + return static_cast(index); + } + } + + return GL_INVALID_INDEX; +} + +GLuint Program::getResourceMaxNameSize(const sh::ShaderVariable &resource, GLint max) const +{ + if (resource.isArray()) + { + return std::max(max, clampCast((resource.name + "[0]").size())); + } + else + { + return std::max(max, clampCast((resource.name).size())); + } +} + +GLuint Program::getInputResourceMaxNameSize() const +{ + GLint max = 0; + + for (const sh::ShaderVariable &resource : mState.mExecutable->getProgramInputs()) + { + max = getResourceMaxNameSize(resource, max); + } + + return max; +} + +GLuint Program::getOutputResourceMaxNameSize() const +{ + GLint max = 0; + + for (const sh::ShaderVariable &resource : mState.mExecutable->getOutputVariables()) + { + max = getResourceMaxNameSize(resource, max); + } + + return max; +} + +GLuint Program::getResourceLocation(const GLchar *name, const sh::ShaderVariable &variable) const +{ + if (variable.isBuiltIn()) + { + return GL_INVALID_INDEX; + } + + GLint location = variable.location; + if (variable.isArray()) + { + size_t nameLengthWithoutArrayIndexOut; + size_t arrayIndex = ParseArrayIndex(name, &nameLengthWithoutArrayIndexOut); + // The 'name' string may not contain the array notation "[0]" + if (arrayIndex != GL_INVALID_INDEX) + { + location += arrayIndex; + } + } + + return location; +} + +GLuint Program::getInputResourceLocation(const GLchar *name) const +{ + const GLuint index = getInputResourceIndex(name); + if (index == GL_INVALID_INDEX) + { + return index; + } + + const sh::ShaderVariable &variable = getInputResource(index); + + return getResourceLocation(name, variable); +} + +GLuint Program::getOutputResourceLocation(const GLchar *name) const +{ + const GLuint index = getOutputResourceIndex(name); + if (index == GL_INVALID_INDEX) + { + return index; + } + + const sh::ShaderVariable &variable = getOutputResource(index); + + return getResourceLocation(name, variable); +} + +GLuint Program::getOutputResourceIndex(const GLchar *name) const +{ + ASSERT(!mLinkingState); + const std::string nameString = StripLastArrayIndex(name); + + for (size_t index = 0; index < mState.mExecutable->getOutputVariables().size(); index++) + { + sh::ShaderVariable resource = getOutputResource(index); + if (resource.name == nameString) + { + return static_cast(index); + } + } + + return GL_INVALID_INDEX; +} + +size_t Program::getOutputResourceCount() const +{ + ASSERT(!mLinkingState); + return (mLinked ? mState.mExecutable->getOutputVariables().size() : 0); +} + +void Program::getResourceName(const std::string name, + GLsizei bufSize, + GLsizei *length, + GLchar *dest) const +{ + if (length) + { + *length = 0; + } + + if (!mLinked) + { + if (bufSize > 0) + { + dest[0] = '\0'; + } + return; + } + + if (bufSize > 0) + { + CopyStringToBuffer(dest, name, bufSize, length); + } +} + +void Program::getInputResourceName(GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name) const +{ + ASSERT(!mLinkingState); + getResourceName(getInputResourceName(index), bufSize, length, name); +} + +void Program::getOutputResourceName(GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name) const +{ + ASSERT(!mLinkingState); + getResourceName(getOutputResourceName(index), bufSize, length, name); +} + +void Program::getUniformResourceName(GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name) const +{ + ASSERT(!mLinkingState); + ASSERT(index < mState.mExecutable->getUniforms().size()); + getResourceName(mState.mExecutable->getUniforms()[index].name, bufSize, length, name); +} + +void Program::getBufferVariableResourceName(GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name) const +{ + ASSERT(!mLinkingState); + ASSERT(index < mState.mBufferVariables.size()); + getResourceName(mState.mBufferVariables[index].name, bufSize, length, name); +} + +const std::string Program::getResourceName(const sh::ShaderVariable &resource) const +{ + std::string resourceName = resource.name; + + if (resource.isArray()) + { + resourceName += "[0]"; + } + + return resourceName; +} + +const std::string Program::getInputResourceName(GLuint index) const +{ + ASSERT(!mLinkingState); + const sh::ShaderVariable &resource = getInputResource(index); + + return getResourceName(resource); +} + +const std::string Program::getOutputResourceName(GLuint index) const +{ + ASSERT(!mLinkingState); + const sh::ShaderVariable &resource = getOutputResource(index); + + return getResourceName(resource); +} + +const sh::ShaderVariable &Program::getOutputResource(size_t index) const +{ + ASSERT(!mLinkingState); + ASSERT(index < mState.mExecutable->getOutputVariables().size()); + return mState.mExecutable->getOutputVariables()[index]; +} + +const ProgramBindings &Program::getAttributeBindings() const +{ + ASSERT(!mLinkingState); + return mAttributeBindings; +} +const ProgramAliasedBindings &Program::getUniformLocationBindings() const +{ + ASSERT(!mLinkingState); + return mState.mUniformLocationBindings; +} + +const gl::ProgramAliasedBindings &Program::getFragmentOutputLocations() const +{ + ASSERT(!mLinkingState); + return mFragmentOutputLocations; +} + +const gl::ProgramAliasedBindings &Program::getFragmentOutputIndexes() const +{ + ASSERT(!mLinkingState); + return mFragmentOutputIndexes; +} + +const std::vector &Program::getTransformFeedbackStrides() const +{ + ASSERT(!mLinkingState); + return mState.mExecutable->getTransformFeedbackStrides(); +} + +GLint Program::getFragDataLocation(const std::string &name) const +{ + ASSERT(!mLinkingState); + GLint primaryLocation = GetVariableLocation(mState.mExecutable->getOutputVariables(), + mState.mExecutable->getOutputLocations(), name); + if (primaryLocation != -1) + { + return primaryLocation; + } + return GetVariableLocation(mState.mExecutable->getOutputVariables(), + mState.mExecutable->getSecondaryOutputLocations(), name); +} + +GLint Program::getFragDataIndex(const std::string &name) const +{ + ASSERT(!mLinkingState); + if (GetVariableLocation(mState.mExecutable->getOutputVariables(), + mState.mExecutable->getOutputLocations(), name) != -1) + { + return 0; + } + if (GetVariableLocation(mState.mExecutable->getOutputVariables(), + mState.mExecutable->getSecondaryOutputLocations(), name) != -1) + { + return 1; + } + return -1; +} + +void Program::getActiveUniform(GLuint index, + GLsizei bufsize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name) const +{ + ASSERT(!mLinkingState); + if (mLinked) + { + // index must be smaller than getActiveUniformCount() + ASSERT(index < mState.mExecutable->getUniforms().size()); + const LinkedUniform &uniform = mState.mExecutable->getUniforms()[index]; + + if (bufsize > 0) + { + std::string string = uniform.name; + CopyStringToBuffer(name, string, bufsize, length); + } + + *size = clampCast(uniform.getBasicTypeElementCount()); + *type = uniform.type; + } + else + { + if (bufsize > 0) + { + name[0] = '\0'; + } + + if (length) + { + *length = 0; + } + + *size = 0; + *type = GL_NONE; + } +} + +GLint Program::getActiveUniformCount() const +{ + ASSERT(!mLinkingState); + if (mLinked) + { + return static_cast(mState.mExecutable->getUniforms().size()); + } + else + { + return 0; + } +} + +size_t Program::getActiveBufferVariableCount() const +{ + ASSERT(!mLinkingState); + return mLinked ? mState.mBufferVariables.size() : 0; +} + +GLint Program::getActiveUniformMaxLength() const +{ + ASSERT(!mLinkingState); + size_t maxLength = 0; + + if (mLinked) + { + for (const LinkedUniform &uniform : mState.mExecutable->getUniforms()) + { + if (!uniform.name.empty()) + { + size_t length = uniform.name.length() + 1u; + if (uniform.isArray()) + { + length += 3; // Counting in "[0]". + } + maxLength = std::max(length, maxLength); + } + } + } + + return static_cast(maxLength); +} + +bool Program::isValidUniformLocation(UniformLocation location) const +{ + ASSERT(!mLinkingState); + ASSERT(angle::IsValueInRangeForNumericType(mState.mUniformLocations.size())); + return (location.value >= 0 && + static_cast(location.value) < mState.mUniformLocations.size() && + mState.mUniformLocations[static_cast(location.value)].used()); +} + +const LinkedUniform &Program::getUniformByLocation(UniformLocation location) const +{ + ASSERT(!mLinkingState); + ASSERT(location.value >= 0 && + static_cast(location.value) < mState.mUniformLocations.size()); + return mState.mExecutable->getUniforms()[mState.getUniformIndexFromLocation(location)]; +} + +const VariableLocation &Program::getUniformLocation(UniformLocation location) const +{ + ASSERT(!mLinkingState); + ASSERT(location.value >= 0 && + static_cast(location.value) < mState.mUniformLocations.size()); + return mState.mUniformLocations[location.value]; +} + +const BufferVariable &Program::getBufferVariableByIndex(GLuint index) const +{ + ASSERT(!mLinkingState); + ASSERT(index < static_cast(mState.mBufferVariables.size())); + return mState.mBufferVariables[index]; +} + +UniformLocation Program::getUniformLocation(const std::string &name) const +{ + ASSERT(!mLinkingState); + return {GetVariableLocation(mState.mExecutable->getUniforms(), mState.mUniformLocations, name)}; +} + +GLuint Program::getUniformIndex(const std::string &name) const +{ + ASSERT(!mLinkingState); + return mState.getUniformIndexFromName(name); +} + +bool Program::shouldIgnoreUniform(UniformLocation location) const +{ + if (location.value == -1) + { + return true; + } + + if (mState.mUniformLocations[static_cast(location.value)].ignored) + { + return true; + } + + return false; +} + +template +void Program::setUniformGeneric(UniformLocation location, GLsizei count, const UniformT *v) +{ + ASSERT(!mLinkingState); + if (shouldIgnoreUniform(location)) + { + return; + } + + const VariableLocation &locationInfo = mState.mUniformLocations[location.value]; + GLsizei clampedCount = clampUniformCount(locationInfo, count, UniformSize, v); + (mProgram->*SetUniformFunc)(location.value, clampedCount, v); + onStateChange(angle::SubjectMessage::ProgramUniformUpdated); +} + +void Program::setUniform1fv(UniformLocation location, GLsizei count, const GLfloat *v) +{ + setUniformGeneric(location, count, v); +} + +void Program::setUniform2fv(UniformLocation location, GLsizei count, const GLfloat *v) +{ + setUniformGeneric(location, count, v); +} + +void Program::setUniform3fv(UniformLocation location, GLsizei count, const GLfloat *v) +{ + setUniformGeneric(location, count, v); +} + +void Program::setUniform4fv(UniformLocation location, GLsizei count, const GLfloat *v) +{ + setUniformGeneric(location, count, v); +} + +void Program::setUniform1iv(Context *context, + UniformLocation location, + GLsizei count, + const GLint *v) +{ + ASSERT(!mLinkingState); + if (shouldIgnoreUniform(location)) + { + return; + } + + const VariableLocation &locationInfo = mState.mUniformLocations[location.value]; + GLsizei clampedCount = clampUniformCount(locationInfo, count, 1, v); + + mProgram->setUniform1iv(location.value, clampedCount, v); + + if (mState.isSamplerUniformIndex(locationInfo.index)) + { + updateSamplerUniform(context, locationInfo, clampedCount, v); + } + else + { + onStateChange(angle::SubjectMessage::ProgramUniformUpdated); + } +} + +void Program::setUniform2iv(UniformLocation location, GLsizei count, const GLint *v) +{ + setUniformGeneric(location, count, v); +} + +void Program::setUniform3iv(UniformLocation location, GLsizei count, const GLint *v) +{ + setUniformGeneric(location, count, v); +} + +void Program::setUniform4iv(UniformLocation location, GLsizei count, const GLint *v) +{ + setUniformGeneric(location, count, v); +} + +void Program::setUniform1uiv(UniformLocation location, GLsizei count, const GLuint *v) +{ + setUniformGeneric(location, count, v); +} + +void Program::setUniform2uiv(UniformLocation location, GLsizei count, const GLuint *v) +{ + setUniformGeneric(location, count, v); +} + +void Program::setUniform3uiv(UniformLocation location, GLsizei count, const GLuint *v) +{ + setUniformGeneric(location, count, v); +} + +void Program::setUniform4uiv(UniformLocation location, GLsizei count, const GLuint *v) +{ + setUniformGeneric(location, count, v); +} + +template < + typename UniformT, + GLint MatrixC, + GLint MatrixR, + void (rx::ProgramImpl::*SetUniformMatrixFunc)(GLint, GLsizei, GLboolean, const UniformT *)> +void Program::setUniformMatrixGeneric(UniformLocation location, + GLsizei count, + GLboolean transpose, + const UniformT *v) +{ + ASSERT(!mLinkingState); + if (shouldIgnoreUniform(location)) + { + return; + } + + GLsizei clampedCount = clampMatrixUniformCount(location, count, transpose, v); + (mProgram->*SetUniformMatrixFunc)(location.value, clampedCount, transpose, v); + onStateChange(angle::SubjectMessage::ProgramUniformUpdated); +} + +void Program::setUniformMatrix2fv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *v) +{ + setUniformMatrixGeneric(location, count, + transpose, v); +} + +void Program::setUniformMatrix3fv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *v) +{ + setUniformMatrixGeneric(location, count, + transpose, v); +} + +void Program::setUniformMatrix4fv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *v) +{ + setUniformMatrixGeneric(location, count, + transpose, v); +} + +void Program::setUniformMatrix2x3fv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *v) +{ + setUniformMatrixGeneric(location, count, + transpose, v); +} + +void Program::setUniformMatrix2x4fv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *v) +{ + setUniformMatrixGeneric(location, count, + transpose, v); +} + +void Program::setUniformMatrix3x2fv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *v) +{ + setUniformMatrixGeneric(location, count, + transpose, v); +} + +void Program::setUniformMatrix3x4fv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *v) +{ + setUniformMatrixGeneric(location, count, + transpose, v); +} + +void Program::setUniformMatrix4x2fv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *v) +{ + setUniformMatrixGeneric(location, count, + transpose, v); +} + +void Program::setUniformMatrix4x3fv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *v) +{ + setUniformMatrixGeneric(location, count, + transpose, v); +} + +GLuint Program::getSamplerUniformBinding(const VariableLocation &uniformLocation) const +{ + ASSERT(!mLinkingState); + GLuint samplerIndex = mState.getSamplerIndexFromUniformIndex(uniformLocation.index); + const std::vector &boundTextureUnits = + mState.mExecutable->mSamplerBindings[samplerIndex].boundTextureUnits; + return (uniformLocation.arrayIndex < boundTextureUnits.size()) + ? boundTextureUnits[uniformLocation.arrayIndex] + : 0; +} + +GLuint Program::getImageUniformBinding(const VariableLocation &uniformLocation) const +{ + ASSERT(!mLinkingState); + GLuint imageIndex = mState.getImageIndexFromUniformIndex(uniformLocation.index); + + const std::vector &imageBindings = getExecutable().getImageBindings(); + const std::vector &boundImageUnits = imageBindings[imageIndex].boundImageUnits; + return boundImageUnits[uniformLocation.arrayIndex]; +} + +void Program::getUniformfv(const Context *context, UniformLocation location, GLfloat *v) const +{ + ASSERT(!mLinkingState); + const VariableLocation &uniformLocation = mState.getUniformLocations()[location.value]; + const LinkedUniform &uniform = mState.getUniforms()[uniformLocation.index]; + + if (uniform.isSampler()) + { + *v = static_cast(getSamplerUniformBinding(uniformLocation)); + return; + } + else if (uniform.isImage()) + { + *v = static_cast(getImageUniformBinding(uniformLocation)); + return; + } + + const GLenum nativeType = gl::VariableComponentType(uniform.type); + if (nativeType == GL_FLOAT) + { + mProgram->getUniformfv(context, location.value, v); + } + else + { + getUniformInternal(context, v, location, nativeType, VariableComponentCount(uniform.type)); + } +} + +void Program::getUniformiv(const Context *context, UniformLocation location, GLint *v) const +{ + ASSERT(!mLinkingState); + const VariableLocation &uniformLocation = mState.getUniformLocations()[location.value]; + const LinkedUniform &uniform = mState.getUniforms()[uniformLocation.index]; + + if (uniform.isSampler()) + { + *v = static_cast(getSamplerUniformBinding(uniformLocation)); + return; + } + else if (uniform.isImage()) + { + *v = static_cast(getImageUniformBinding(uniformLocation)); + return; + } + + const GLenum nativeType = gl::VariableComponentType(uniform.type); + if (nativeType == GL_INT || nativeType == GL_BOOL) + { + mProgram->getUniformiv(context, location.value, v); + } + else + { + getUniformInternal(context, v, location, nativeType, VariableComponentCount(uniform.type)); + } +} + +void Program::getUniformuiv(const Context *context, UniformLocation location, GLuint *v) const +{ + ASSERT(!mLinkingState); + const VariableLocation &uniformLocation = mState.getUniformLocations()[location.value]; + const LinkedUniform &uniform = mState.getUniforms()[uniformLocation.index]; + + if (uniform.isSampler()) + { + *v = getSamplerUniformBinding(uniformLocation); + return; + } + else if (uniform.isImage()) + { + *v = getImageUniformBinding(uniformLocation); + return; + } + + const GLenum nativeType = VariableComponentType(uniform.type); + if (nativeType == GL_UNSIGNED_INT) + { + mProgram->getUniformuiv(context, location.value, v); + } + else + { + getUniformInternal(context, v, location, nativeType, VariableComponentCount(uniform.type)); + } +} + +void Program::flagForDeletion() +{ + ASSERT(!mLinkingState); + mDeleteStatus = true; +} + +bool Program::isFlaggedForDeletion() const +{ + ASSERT(!mLinkingState); + return mDeleteStatus; +} + +void Program::validate(const Caps &caps) +{ + ASSERT(!mLinkingState); + mState.mExecutable->resetInfoLog(); + InfoLog &infoLog = mState.mExecutable->getInfoLog(); + + if (mLinked) + { + mValidated = ConvertToBool(mProgram->validate(caps, &infoLog)); + } + else + { + infoLog << "Program has not been successfully linked."; + } +} + +bool Program::isValidated() const +{ + ASSERT(!mLinkingState); + return mValidated; +} + +void Program::getActiveUniformBlockName(const Context *context, + const UniformBlockIndex blockIndex, + GLsizei bufSize, + GLsizei *length, + GLchar *blockName) const +{ + ASSERT(!mLinkingState); + GetInterfaceBlockName(blockIndex, mState.mExecutable->getUniformBlocks(), bufSize, length, + blockName); +} + +void Program::getActiveShaderStorageBlockName(const GLuint blockIndex, + GLsizei bufSize, + GLsizei *length, + GLchar *blockName) const +{ + ASSERT(!mLinkingState); + GetInterfaceBlockName({blockIndex}, mState.mExecutable->getShaderStorageBlocks(), bufSize, + length, blockName); +} + +template +GLint Program::getActiveInterfaceBlockMaxNameLength(const std::vector &resources) const +{ + int maxLength = 0; + + if (mLinked) + { + for (const T &resource : resources) + { + if (!resource.name.empty()) + { + int length = static_cast(resource.nameWithArrayIndex().length()); + maxLength = std::max(length + 1, maxLength); + } + } + } + + return maxLength; +} + +GLint Program::getActiveUniformBlockMaxNameLength() const +{ + ASSERT(!mLinkingState); + return getActiveInterfaceBlockMaxNameLength(mState.mExecutable->getUniformBlocks()); +} + +GLint Program::getActiveShaderStorageBlockMaxNameLength() const +{ + ASSERT(!mLinkingState); + return getActiveInterfaceBlockMaxNameLength(mState.mExecutable->getShaderStorageBlocks()); +} + +GLuint Program::getUniformBlockIndex(const std::string &name) const +{ + ASSERT(!mLinkingState); + return GetInterfaceBlockIndex(mState.mExecutable->getUniformBlocks(), name); +} + +GLuint Program::getShaderStorageBlockIndex(const std::string &name) const +{ + ASSERT(!mLinkingState); + return GetInterfaceBlockIndex(mState.mExecutable->getShaderStorageBlocks(), name); +} + +const InterfaceBlock &Program::getUniformBlockByIndex(GLuint index) const +{ + ASSERT(!mLinkingState); + ASSERT(index < static_cast(mState.mExecutable->getActiveUniformBlockCount())); + return mState.mExecutable->getUniformBlocks()[index]; +} + +const InterfaceBlock &Program::getShaderStorageBlockByIndex(GLuint index) const +{ + ASSERT(!mLinkingState); + ASSERT(index < static_cast(mState.mExecutable->getActiveShaderStorageBlockCount())); + return mState.mExecutable->getShaderStorageBlocks()[index]; +} + +void Program::bindUniformBlock(UniformBlockIndex uniformBlockIndex, GLuint uniformBlockBinding) +{ + ASSERT(!mLinkingState); + mState.mExecutable->mUniformBlocks[uniformBlockIndex.value].binding = uniformBlockBinding; + mState.mExecutable->mActiveUniformBlockBindings.set(uniformBlockIndex.value, + uniformBlockBinding != 0); + mDirtyBits.set(DIRTY_BIT_UNIFORM_BLOCK_BINDING_0 + uniformBlockIndex.value); +} + +GLuint Program::getUniformBlockBinding(GLuint uniformBlockIndex) const +{ + ASSERT(!mLinkingState); + return mState.getUniformBlockBinding(uniformBlockIndex); +} + +GLuint Program::getShaderStorageBlockBinding(GLuint shaderStorageBlockIndex) const +{ + ASSERT(!mLinkingState); + return mState.getShaderStorageBlockBinding(shaderStorageBlockIndex); +} + +void Program::setTransformFeedbackVaryings(GLsizei count, + const GLchar *const *varyings, + GLenum bufferMode) +{ + ASSERT(!mLinkingState); + mState.mTransformFeedbackVaryingNames.resize(count); + for (GLsizei i = 0; i < count; i++) + { + mState.mTransformFeedbackVaryingNames[i] = varyings[i]; + } + + mState.mExecutable->mTransformFeedbackBufferMode = bufferMode; +} + +void Program::getTransformFeedbackVarying(GLuint index, + GLsizei bufSize, + GLsizei *length, + GLsizei *size, + GLenum *type, + GLchar *name) const +{ + ASSERT(!mLinkingState); + if (mLinked) + { + ASSERT(index < mState.mExecutable->mLinkedTransformFeedbackVaryings.size()); + const auto &var = mState.mExecutable->mLinkedTransformFeedbackVaryings[index]; + std::string varName = var.nameWithArrayIndex(); + GLsizei lastNameIdx = std::min(bufSize - 1, static_cast(varName.length())); + if (length) + { + *length = lastNameIdx; + } + if (size) + { + *size = var.size(); + } + if (type) + { + *type = var.type; + } + if (name) + { + memcpy(name, varName.c_str(), lastNameIdx); + name[lastNameIdx] = '\0'; + } + } +} + +GLsizei Program::getTransformFeedbackVaryingCount() const +{ + ASSERT(!mLinkingState); + if (mLinked) + { + return static_cast(mState.mExecutable->mLinkedTransformFeedbackVaryings.size()); + } + else + { + return 0; + } +} + +GLsizei Program::getTransformFeedbackVaryingMaxLength() const +{ + ASSERT(!mLinkingState); + if (mLinked) + { + GLsizei maxSize = 0; + for (const auto &var : mState.mExecutable->mLinkedTransformFeedbackVaryings) + { + maxSize = + std::max(maxSize, static_cast(var.nameWithArrayIndex().length() + 1)); + } + + return maxSize; + } + else + { + return 0; + } +} + +GLenum Program::getTransformFeedbackBufferMode() const +{ + ASSERT(!mLinkingState); + return mState.mExecutable->getTransformFeedbackBufferMode(); +} + +bool Program::linkValidateShaders(const Context *context, InfoLog &infoLog) +{ + const ShaderMap &shaders = mState.mAttachedShaders; + + bool isComputeShaderAttached = shaders[ShaderType::Compute] != nullptr; + bool isGraphicsShaderAttached = shaders[ShaderType::Vertex] || + shaders[ShaderType::TessControl] || + shaders[ShaderType::TessEvaluation] || + shaders[ShaderType::Geometry] || shaders[ShaderType::Fragment]; + // Check whether we both have a compute and non-compute shaders attached. + // If there are of both types attached, then linking should fail. + // OpenGL ES 3.10, 7.3 Program Objects, under LinkProgram + if (isComputeShaderAttached && isGraphicsShaderAttached) + { + infoLog << "Both compute and graphics shaders are attached to the same program."; + return false; + } + + Optional version; + for (ShaderType shaderType : kAllGraphicsShaderTypes) + { + Shader *shader = shaders[shaderType]; + ASSERT(!shader || shader->getType() == shaderType); + if (!shader) + { + continue; + } + + if (!shader->isCompiled(context)) + { + infoLog << ShaderTypeToString(shaderType) << " shader is not compiled."; + return false; + } + + if (!version.valid()) + { + version = shader->getShaderVersion(context); + } + else if (version != shader->getShaderVersion(context)) + { + infoLog << ShaderTypeToString(shaderType) + << " shader version does not match other shader versions."; + return false; + } + } + + if (isComputeShaderAttached) + { + ASSERT(shaders[ShaderType::Compute]->getType() == ShaderType::Compute); + + mState.mComputeShaderLocalSize = shaders[ShaderType::Compute]->getWorkGroupSize(context); + + // GLSL ES 3.10, 4.4.1.1 Compute Shader Inputs + // If the work group size is not specified, a link time error should occur. + if (!mState.mComputeShaderLocalSize.isDeclared()) + { + infoLog << "Work group size is not specified."; + return false; + } + } + else + { + if (!isGraphicsShaderAttached) + { + infoLog << "No compiled shaders."; + return false; + } + + bool hasVertex = shaders[ShaderType::Vertex] != nullptr; + bool hasFragment = shaders[ShaderType::Fragment] != nullptr; + if (!isSeparable() && (!hasVertex || !hasFragment)) + { + infoLog + << "The program must contain objects to form both a vertex and fragment shader."; + return false; + } + + bool hasTessControl = shaders[ShaderType::TessControl] != nullptr; + bool hasTessEvaluation = shaders[ShaderType::TessEvaluation] != nullptr; + if (!isSeparable() && (hasTessControl != hasTessEvaluation)) + { + infoLog << "Tessellation control and evaluation shaders must be specified together."; + return false; + } + + Shader *geometryShader = shaders[ShaderType::Geometry]; + if (shaders[ShaderType::Geometry]) + { + // [GL_EXT_geometry_shader] Chapter 7 + // Linking can fail for a variety of reasons as specified in the OpenGL ES Shading + // Language Specification, as well as any of the following reasons: + // * One or more of the shader objects attached to are not compiled + // successfully. + // * The shaders do not use the same shader language version. + // * contains objects to form a geometry shader, and + // - is not separable and contains no objects to form a vertex shader; or + // - the input primitive type, output primitive type, or maximum output vertex count + // is not specified in the compiled geometry shader object. + ASSERT(geometryShader->getType() == ShaderType::Geometry); + + Optional inputPrimitive = + geometryShader->getGeometryShaderInputPrimitiveType(context); + if (!inputPrimitive.valid()) + { + infoLog << "Input primitive type is not specified in the geometry shader."; + return false; + } + + Optional outputPrimitive = + geometryShader->getGeometryShaderOutputPrimitiveType(context); + if (!outputPrimitive.valid()) + { + infoLog << "Output primitive type is not specified in the geometry shader."; + return false; + } + + Optional maxVertices = geometryShader->getGeometryShaderMaxVertices(context); + if (!maxVertices.valid()) + { + infoLog << "'max_vertices' is not specified in the geometry shader."; + return false; + } + + mState.mExecutable->mGeometryShaderInputPrimitiveType = inputPrimitive.value(); + mState.mExecutable->mGeometryShaderOutputPrimitiveType = outputPrimitive.value(); + mState.mExecutable->mGeometryShaderMaxVertices = maxVertices.value(); + mState.mExecutable->mGeometryShaderInvocations = + geometryShader->getGeometryShaderInvocations(context); + } + + Shader *tessControlShader = shaders[ShaderType::TessControl]; + if (tessControlShader) + { + int tcsShaderVertices = tessControlShader->getTessControlShaderVertices(context); + if (tcsShaderVertices == 0) + { + // In tessellation control shader, output vertices should be specified at least + // once. + // > GLSL ES Version 3.20.6 spec: + // > 4.4.2. Output Layout Qualifiers + // > Tessellation Control Outputs + // > ... + // > There must be at least one layout qualifier specifying an output patch vertex + // > count in any program containing a tessellation control shader. + infoLog << "In Tessellation Control Shader, at least one layout qualifier " + "specifying an output patch vertex count must exist."; + return false; + } + + mState.mExecutable->mTessControlShaderVertices = tcsShaderVertices; + } + + Shader *tessEvaluationShader = shaders[ShaderType::TessEvaluation]; + if (tessEvaluationShader) + { + GLenum tesPrimitiveMode = tessEvaluationShader->getTessGenMode(context); + if (tesPrimitiveMode == 0) + { + // In tessellation evaluation shader, a primitive mode should be specified at least + // once. + // > GLSL ES Version 3.20.6 spec: + // > 4.4.1. Input Layout Qualifiers + // > Tessellation Evaluation Inputs + // > ... + // > The tessellation evaluation shader object in a program must declare a primitive + // > mode in its input layout. Declaring vertex spacing, ordering, or point mode + // > identifiers is optional. + infoLog << "The Tessellation Evaluation Shader object in a program must declare a " + "primitive mode in its input layout."; + return false; + } + + mState.mExecutable->mTessGenMode = tesPrimitiveMode; + mState.mExecutable->mTessGenSpacing = tessEvaluationShader->getTessGenSpacing(context); + mState.mExecutable->mTessGenVertexOrder = + tessEvaluationShader->getTessGenVertexOrder(context); + mState.mExecutable->mTessGenPointMode = + tessEvaluationShader->getTessGenPointMode(context); + } + } + + return true; +} + +GLuint Program::getTransformFeedbackVaryingResourceIndex(const GLchar *name) const +{ + ASSERT(!mLinkingState); + for (GLuint tfIndex = 0; tfIndex < mState.mExecutable->mLinkedTransformFeedbackVaryings.size(); + ++tfIndex) + { + const auto &tf = mState.mExecutable->mLinkedTransformFeedbackVaryings[tfIndex]; + if (tf.nameWithArrayIndex() == name) + { + return tfIndex; + } + } + return GL_INVALID_INDEX; +} + +const TransformFeedbackVarying &Program::getTransformFeedbackVaryingResource(GLuint index) const +{ + ASSERT(!mLinkingState); + ASSERT(index < mState.mExecutable->mLinkedTransformFeedbackVaryings.size()); + return mState.mExecutable->mLinkedTransformFeedbackVaryings[index]; +} + +bool Program::hasDrawIDUniform() const +{ + ASSERT(!mLinkingState); + return mState.mDrawIDLocation >= 0; +} + +void Program::setDrawIDUniform(GLint drawid) +{ + ASSERT(!mLinkingState); + ASSERT(mState.mDrawIDLocation >= 0); + mProgram->setUniform1iv(mState.mDrawIDLocation, 1, &drawid); +} + +bool Program::hasBaseVertexUniform() const +{ + ASSERT(!mLinkingState); + return mState.mBaseVertexLocation >= 0; +} + +void Program::setBaseVertexUniform(GLint baseVertex) +{ + ASSERT(!mLinkingState); + ASSERT(mState.mBaseVertexLocation >= 0); + if (baseVertex == mState.mCachedBaseVertex) + { + return; + } + mState.mCachedBaseVertex = baseVertex; + mProgram->setUniform1iv(mState.mBaseVertexLocation, 1, &baseVertex); +} + +bool Program::hasBaseInstanceUniform() const +{ + ASSERT(!mLinkingState); + return mState.mBaseInstanceLocation >= 0; +} + +void Program::setBaseInstanceUniform(GLuint baseInstance) +{ + ASSERT(!mLinkingState); + ASSERT(mState.mBaseInstanceLocation >= 0); + if (baseInstance == mState.mCachedBaseInstance) + { + return; + } + mState.mCachedBaseInstance = baseInstance; + GLint baseInstanceInt = baseInstance; + mProgram->setUniform1iv(mState.mBaseInstanceLocation, 1, &baseInstanceInt); +} + +bool Program::linkVaryings(const Context *context, InfoLog &infoLog) const +{ + ShaderType previousShaderType = ShaderType::InvalidEnum; + for (ShaderType shaderType : kAllGraphicsShaderTypes) + { + Shader *currentShader = mState.mAttachedShaders[shaderType]; + if (!currentShader) + { + continue; + } + + if (previousShaderType != ShaderType::InvalidEnum) + { + Shader *previousShader = mState.mAttachedShaders[previousShaderType]; + const std::vector &outputVaryings = + previousShader->getOutputVaryings(context); + + if (!LinkValidateShaderInterfaceMatching( + outputVaryings, currentShader->getInputVaryings(context), previousShaderType, + currentShader->getType(), previousShader->getShaderVersion(context), + currentShader->getShaderVersion(context), isSeparable(), infoLog)) + { + return false; + } + } + previousShaderType = currentShader->getType(); + } + + // TODO: http://anglebug.com/3571 and http://anglebug.com/3572 + // Need to move logic of validating builtin varyings inside the for-loop above. + // This is because the built-in symbols `gl_ClipDistance` and `gl_CullDistance` + // can be redeclared in Geometry or Tessellation shaders as well. + Shader *vertexShader = mState.mAttachedShaders[ShaderType::Vertex]; + Shader *fragmentShader = mState.mAttachedShaders[ShaderType::Fragment]; + if (vertexShader && fragmentShader && + !LinkValidateBuiltInVaryings(vertexShader->getOutputVaryings(context), + fragmentShader->getInputVaryings(context), + vertexShader->getType(), fragmentShader->getType(), + vertexShader->getShaderVersion(context), + fragmentShader->getShaderVersion(context), infoLog)) + { + return false; + } + + return true; +} + +bool Program::linkUniforms(const Context *context, + std::vector *unusedUniformsOutOrNull, + GLuint *combinedImageUniformsOut, + InfoLog &infoLog) +{ + // Initialize executable shader map. + ShaderMap> shaderUniforms; + for (Shader *shader : mState.mAttachedShaders) + { + if (shader) + { + shaderUniforms[shader->getType()] = shader->getUniforms(context); + } + } + + if (!mState.mExecutable->linkUniforms(context, shaderUniforms, infoLog, + mState.mUniformLocationBindings, combinedImageUniformsOut, + unusedUniformsOutOrNull, &mState.mUniformLocations)) + { + return false; + } + + if (context->getClientVersion() >= Version(3, 1)) + { + GLint locationSize = static_cast(mState.getUniformLocations().size()); + + if (locationSize > context->getCaps().maxUniformLocations) + { + infoLog << "Exceeded maximum uniform location size"; + return false; + } + } + + return true; +} + +// Assigns locations to all attributes (except built-ins) from the bindings and program locations. +bool Program::linkAttributes(const Context *context, InfoLog &infoLog) +{ + const Caps &caps = context->getCaps(); + const Limitations &limitations = context->getLimitations(); + bool webglCompatibility = context->isWebGL(); + int shaderVersion = -1; + unsigned int usedLocations = 0; + + Shader *vertexShader = mState.getAttachedShader(gl::ShaderType::Vertex); + + if (!vertexShader) + { + // No vertex shader, so no attributes, so nothing to do + return true; + } + + shaderVersion = vertexShader->getShaderVersion(context); + if (shaderVersion >= 300) + { + // In GLSL ES 3.00.6, aliasing checks should be done with all declared attributes - + // see GLSL ES 3.00.6 section 12.46. Inactive attributes will be pruned after + // aliasing checks. + mState.mExecutable->mProgramInputs = vertexShader->getAllAttributes(context); + } + else + { + // In GLSL ES 1.00.17 we only do aliasing checks for active attributes. + mState.mExecutable->mProgramInputs = vertexShader->getActiveAttributes(context); + } + + GLuint maxAttribs = static_cast(caps.maxVertexAttributes); + std::vector usedAttribMap(maxAttribs, nullptr); + + // Assign locations to attributes that have a binding location and check for attribute aliasing. + for (sh::ShaderVariable &attribute : mState.mExecutable->mProgramInputs) + { + // GLSL ES 3.10 January 2016 section 4.3.4: Vertex shader inputs can't be arrays or + // structures, so we don't need to worry about adjusting their names or generating entries + // for each member/element (unlike uniforms for example). + ASSERT(!attribute.isArray() && !attribute.isStruct()); + + int bindingLocation = mAttributeBindings.getBinding(attribute); + if (attribute.location == -1 && bindingLocation != -1) + { + attribute.location = bindingLocation; + } + + if (attribute.location != -1) + { + // Location is set by glBindAttribLocation or by location layout qualifier + const int regs = VariableRegisterCount(attribute.type); + + if (static_cast(regs + attribute.location) > maxAttribs) + { + infoLog << "Attribute (" << attribute.name << ") at location " << attribute.location + << " is too big to fit"; + + return false; + } + + for (int reg = 0; reg < regs; reg++) + { + const int regLocation = attribute.location + reg; + sh::ShaderVariable *linkedAttribute = usedAttribMap[regLocation]; + + // In GLSL ES 3.00.6 and in WebGL, attribute aliasing produces a link error. + // In non-WebGL GLSL ES 1.00.17, attribute aliasing is allowed with some + // restrictions - see GLSL ES 1.00.17 section 2.10.4, but ANGLE currently has a bug. + // In D3D 9 and 11, aliasing is not supported, so check a limitation. + if (linkedAttribute) + { + if (shaderVersion >= 300 || webglCompatibility || + limitations.noVertexAttributeAliasing) + { + infoLog << "Attribute '" << attribute.name << "' aliases attribute '" + << linkedAttribute->name << "' at location " << regLocation; + return false; + } + } + else + { + usedAttribMap[regLocation] = &attribute; + } + + usedLocations |= 1 << regLocation; + } + } + } + + // Assign locations to attributes that don't have a binding location. + for (sh::ShaderVariable &attribute : mState.mExecutable->mProgramInputs) + { + // Not set by glBindAttribLocation or by location layout qualifier + if (attribute.location == -1) + { + int regs = VariableRegisterCount(attribute.type); + int availableIndex = AllocateFirstFreeBits(&usedLocations, regs, maxAttribs); + + if (availableIndex == -1 || static_cast(availableIndex + regs) > maxAttribs) + { + infoLog << "Too many attributes (" << attribute.name << ")"; + return false; + } + + attribute.location = availableIndex; + } + } + + ASSERT(mState.mExecutable->mAttributesTypeMask.none()); + ASSERT(mState.mExecutable->mAttributesMask.none()); + + // Prune inactive attributes. This step is only needed on shaderVersion >= 300 since on earlier + // shader versions we're only processing active attributes to begin with. + if (shaderVersion >= 300) + { + for (auto attributeIter = mState.mExecutable->getProgramInputs().begin(); + attributeIter != mState.mExecutable->getProgramInputs().end();) + { + if (attributeIter->active) + { + ++attributeIter; + } + else + { + attributeIter = mState.mExecutable->mProgramInputs.erase(attributeIter); + } + } + } + + for (const sh::ShaderVariable &attribute : mState.mExecutable->getProgramInputs()) + { + ASSERT(attribute.active); + ASSERT(attribute.location != -1); + unsigned int regs = static_cast(VariableRegisterCount(attribute.type)); + + unsigned int location = static_cast(attribute.location); + for (unsigned int r = 0; r < regs; r++) + { + // Built-in active program inputs don't have a bound attribute. + if (!attribute.isBuiltIn()) + { + mState.mExecutable->mActiveAttribLocationsMask.set(location); + mState.mExecutable->mMaxActiveAttribLocation = + std::max(mState.mExecutable->mMaxActiveAttribLocation, location + 1); + + ComponentType componentType = + GLenumToComponentType(VariableComponentType(attribute.type)); + + SetComponentTypeMask(componentType, location, + &mState.mExecutable->mAttributesTypeMask); + mState.mExecutable->mAttributesMask.set(location); + + location++; + } + } + } + + return true; +} + +void Program::setUniformValuesFromBindingQualifiers() +{ + for (unsigned int samplerIndex : mState.mExecutable->getSamplerUniformRange()) + { + const auto &samplerUniform = mState.mExecutable->getUniforms()[samplerIndex]; + if (samplerUniform.binding != -1) + { + UniformLocation location = getUniformLocation(samplerUniform.name); + ASSERT(location.value != -1); + std::vector boundTextureUnits; + for (unsigned int elementIndex = 0; + elementIndex < samplerUniform.getBasicTypeElementCount(); ++elementIndex) + { + boundTextureUnits.push_back(samplerUniform.binding + elementIndex); + } + + // Here we pass nullptr to avoid a large chain of calls that need a non-const Context. + // We know it's safe not to notify the Context because this is only called after link. + setUniform1iv(nullptr, location, static_cast(boundTextureUnits.size()), + boundTextureUnits.data()); + } + } +} + +void Program::initInterfaceBlockBindings() +{ + // Set initial bindings from shader. + for (unsigned int blockIndex = 0; blockIndex < mState.mExecutable->getActiveUniformBlockCount(); + blockIndex++) + { + InterfaceBlock &uniformBlock = mState.mExecutable->mUniformBlocks[blockIndex]; + bindUniformBlock({blockIndex}, uniformBlock.binding); + } +} + +void Program::updateSamplerUniform(Context *context, + const VariableLocation &locationInfo, + GLsizei clampedCount, + const GLint *v) +{ + ASSERT(mState.isSamplerUniformIndex(locationInfo.index)); + GLuint samplerIndex = mState.getSamplerIndexFromUniformIndex(locationInfo.index); + SamplerBinding &samplerBinding = mState.mExecutable->mSamplerBindings[samplerIndex]; + std::vector &boundTextureUnits = samplerBinding.boundTextureUnits; + + if (locationInfo.arrayIndex >= boundTextureUnits.size()) + { + return; + } + GLsizei safeUniformCount = std::min( + clampedCount, static_cast(boundTextureUnits.size() - locationInfo.arrayIndex)); + + // Update the sampler uniforms. + for (GLsizei arrayIndex = 0; arrayIndex < safeUniformCount; ++arrayIndex) + { + GLint oldTextureUnit = boundTextureUnits[arrayIndex + locationInfo.arrayIndex]; + GLint newTextureUnit = v[arrayIndex]; + + if (oldTextureUnit == newTextureUnit) + { + continue; + } + + // Update sampler's bound textureUnit + boundTextureUnits[arrayIndex + locationInfo.arrayIndex] = newTextureUnit; + + // Update the reference counts. + uint32_t &oldRefCount = mState.mExecutable->mActiveSamplerRefCounts[oldTextureUnit]; + uint32_t &newRefCount = mState.mExecutable->mActiveSamplerRefCounts[newTextureUnit]; + ASSERT(oldRefCount > 0); + ASSERT(newRefCount < std::numeric_limits::max()); + oldRefCount--; + newRefCount++; + + // Check for binding type change. + TextureType newSamplerType = mState.mExecutable->mActiveSamplerTypes[newTextureUnit]; + TextureType oldSamplerType = mState.mExecutable->mActiveSamplerTypes[oldTextureUnit]; + SamplerFormat newSamplerFormat = mState.mExecutable->mActiveSamplerFormats[newTextureUnit]; + SamplerFormat oldSamplerFormat = mState.mExecutable->mActiveSamplerFormats[oldTextureUnit]; + bool newSamplerYUV = mState.mExecutable->mActiveSamplerYUV.test(newTextureUnit); + + if (newRefCount == 1) + { + mState.mExecutable->setActive(newTextureUnit, samplerBinding, + mState.mExecutable->getUniforms()[locationInfo.index]); + } + else + { + if (newSamplerType != samplerBinding.textureType || + newSamplerYUV != IsSamplerYUVType(samplerBinding.samplerType)) + { + mState.mExecutable->hasSamplerTypeConflict(newTextureUnit); + } + + if (newSamplerFormat != samplerBinding.format) + { + mState.mExecutable->hasSamplerFormatConflict(newTextureUnit); + } + } + + // Unset previously active sampler. + if (oldRefCount == 0) + { + mState.mExecutable->setInactive(oldTextureUnit); + } + else + { + if (oldSamplerType == TextureType::InvalidEnum || + oldSamplerFormat == SamplerFormat::InvalidEnum) + { + // Previous conflict. Check if this new change fixed the conflict. + mState.setSamplerUniformTextureTypeAndFormat(oldTextureUnit); + } + } + + // Update the observing PPO's executable, if any. + // Do this before any of the Context work, since that uses the current ProgramExecutable, + // which will be the PPO's if this Program is bound to it, rather than this Program's. + if (isSeparable()) + { + onStateChange(angle::SubjectMessage::ProgramTextureOrImageBindingChanged); + } + + // Notify context. + if (context) + { + context->onSamplerUniformChange(newTextureUnit); + context->onSamplerUniformChange(oldTextureUnit); + } + } + + // Invalidate the validation cache. + getExecutable().resetCachedValidateSamplersResult(); + // Inform any PPOs this Program may be bound to. + onStateChange(angle::SubjectMessage::SamplerUniformsUpdated); +} + +void ProgramState::setSamplerUniformTextureTypeAndFormat(size_t textureUnitIndex) +{ + mExecutable->setSamplerUniformTextureTypeAndFormat(textureUnitIndex, + mExecutable->mSamplerBindings); +} + +template +GLsizei Program::clampUniformCount(const VariableLocation &locationInfo, + GLsizei count, + int vectorSize, + const T *v) +{ + if (count == 1) + return 1; + + const LinkedUniform &linkedUniform = mState.mExecutable->getUniforms()[locationInfo.index]; + + // OpenGL ES 3.0.4 spec pg 67: "Values for any array element that exceeds the highest array + // element index used, as reported by GetActiveUniform, will be ignored by the GL." + unsigned int remainingElements = + linkedUniform.getBasicTypeElementCount() - locationInfo.arrayIndex; + GLsizei maxElementCount = + static_cast(remainingElements * linkedUniform.getElementComponents()); + + if (count * vectorSize > maxElementCount) + { + return maxElementCount / vectorSize; + } + + return count; +} + +template +GLsizei Program::clampMatrixUniformCount(UniformLocation location, + GLsizei count, + GLboolean transpose, + const T *v) +{ + const VariableLocation &locationInfo = mState.mUniformLocations[location.value]; + + if (!transpose) + { + return clampUniformCount(locationInfo, count, cols * rows, v); + } + + const LinkedUniform &linkedUniform = mState.mExecutable->getUniforms()[locationInfo.index]; + + // OpenGL ES 3.0.4 spec pg 67: "Values for any array element that exceeds the highest array + // element index used, as reported by GetActiveUniform, will be ignored by the GL." + unsigned int remainingElements = + linkedUniform.getBasicTypeElementCount() - locationInfo.arrayIndex; + return std::min(count, static_cast(remainingElements)); +} + +// Driver differences mean that doing the uniform value cast ourselves gives consistent results. +// EG: on NVIDIA drivers, it was observed that getUniformi for MAX_INT+1 returned MIN_INT. +template +void Program::getUniformInternal(const Context *context, + DestT *dataOut, + UniformLocation location, + GLenum nativeType, + int components) const +{ + switch (nativeType) + { + case GL_BOOL: + { + GLint tempValue[16] = {0}; + mProgram->getUniformiv(context, location.value, tempValue); + UniformStateQueryCastLoop( + dataOut, reinterpret_cast(tempValue), components); + break; + } + case GL_INT: + { + GLint tempValue[16] = {0}; + mProgram->getUniformiv(context, location.value, tempValue); + UniformStateQueryCastLoop(dataOut, reinterpret_cast(tempValue), + components); + break; + } + case GL_UNSIGNED_INT: + { + GLuint tempValue[16] = {0}; + mProgram->getUniformuiv(context, location.value, tempValue); + UniformStateQueryCastLoop(dataOut, reinterpret_cast(tempValue), + components); + break; + } + case GL_FLOAT: + { + GLfloat tempValue[16] = {0}; + mProgram->getUniformfv(context, location.value, tempValue); + UniformStateQueryCastLoop( + dataOut, reinterpret_cast(tempValue), components); + break; + } + default: + UNREACHABLE(); + break; + } +} + +angle::Result Program::syncState(const Context *context) +{ + if (mDirtyBits.any()) + { + ASSERT(!mLinkingState); + ANGLE_TRY(mProgram->syncState(context, mDirtyBits)); + mDirtyBits.reset(); + } + + return angle::Result::Continue; +} + +angle::Result Program::serialize(const Context *context, angle::MemoryBuffer *binaryOut) const +{ + BinaryOutputStream stream; + + stream.writeBytes(reinterpret_cast(angle::GetANGLECommitHash()), + angle::GetANGLECommitHashSize()); + + // nullptr context is supported when computing binary length. + if (context) + { + stream.writeInt(context->getClientVersion().major); + stream.writeInt(context->getClientVersion().minor); + } + else + { + stream.writeInt(2); + stream.writeInt(0); + } + + // Must be before mExecutable->save(), since it uses the value. + stream.writeBool(mState.mSeparable); + + mState.mExecutable->save(mState.mSeparable, &stream); + + const auto &computeLocalSize = mState.getComputeShaderLocalSize(); + + stream.writeInt(computeLocalSize[0]); + stream.writeInt(computeLocalSize[1]); + stream.writeInt(computeLocalSize[2]); + + stream.writeInt(mState.mNumViews); + stream.writeInt(mState.mSpecConstUsageBits.bits()); + + stream.writeInt(mState.getUniformLocations().size()); + for (const auto &variable : mState.getUniformLocations()) + { + stream.writeInt(variable.arrayIndex); + stream.writeIntOrNegOne(variable.index); + stream.writeBool(variable.ignored); + } + + stream.writeInt(mState.getBufferVariables().size()); + for (const BufferVariable &bufferVariable : mState.getBufferVariables()) + { + WriteBufferVariable(&stream, bufferVariable); + } + + // Warn the app layer if saving a binary with unsupported transform feedback. + if (!mState.getLinkedTransformFeedbackVaryings().empty() && + context->getFrontendFeatures().disableProgramCachingForTransformFeedback.enabled) + { + ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_LOW, + "Saving program binary with transform feedback, which is not supported " + "on this driver."); + } + + if (context->getShareGroup()->getFrameCaptureShared()->enabled()) + { + // Serialize the source for each stage for re-use during capture + for (ShaderType shaderType : mState.mExecutable->getLinkedShaderStages()) + { + gl::Shader *shader = getAttachedShader(shaderType); + if (shader) + { + stream.writeString(shader->getSourceString()); + } + else + { + // If we don't have an attached shader, which would occur if this program was + // created via glProgramBinary, pull from our cached copy + const angle::ProgramSources &cachedLinkedSources = + context->getShareGroup()->getFrameCaptureShared()->getProgramSources(id()); + const std::string &cachedSourceString = cachedLinkedSources[shaderType]; + ASSERT(!cachedSourceString.empty()); + stream.writeString(cachedSourceString.c_str()); + } + } + } + + mProgram->save(context, &stream); + + ASSERT(binaryOut); + if (!binaryOut->resize(stream.length())) + { + std::stringstream sstream; + sstream << "Failed to allocate enough memory to serialize a program. (" << stream.length() + << " bytes )"; + ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_LOW, + sstream.str().c_str()); + return angle::Result::Incomplete; + } + memcpy(binaryOut->data(), stream.data(), stream.length()); + return angle::Result::Continue; +} + +angle::Result Program::deserialize(const Context *context, + BinaryInputStream &stream, + InfoLog &infoLog) +{ + std::vector commitString(angle::GetANGLECommitHashSize(), 0); + stream.readBytes(commitString.data(), commitString.size()); + if (memcmp(commitString.data(), angle::GetANGLECommitHash(), commitString.size()) != 0) + { + infoLog << "Invalid program binary version."; + return angle::Result::Stop; + } + + int majorVersion = stream.readInt(); + int minorVersion = stream.readInt(); + if (majorVersion != context->getClientMajorVersion() || + minorVersion != context->getClientMinorVersion()) + { + infoLog << "Cannot load program binaries across different ES context versions."; + return angle::Result::Stop; + } + + // Must be before mExecutable->load(), since it uses the value. + mState.mSeparable = stream.readBool(); + + mState.mExecutable->load(mState.mSeparable, &stream); + + mState.mComputeShaderLocalSize[0] = stream.readInt(); + mState.mComputeShaderLocalSize[1] = stream.readInt(); + mState.mComputeShaderLocalSize[2] = stream.readInt(); + + mState.mNumViews = stream.readInt(); + + static_assert(sizeof(mState.mSpecConstUsageBits.bits()) == sizeof(uint32_t)); + mState.mSpecConstUsageBits = rx::SpecConstUsageBits(stream.readInt()); + + const size_t uniformIndexCount = stream.readInt(); + ASSERT(mState.mUniformLocations.empty()); + for (size_t uniformIndexIndex = 0; uniformIndexIndex < uniformIndexCount; ++uniformIndexIndex) + { + VariableLocation variable; + stream.readInt(&variable.arrayIndex); + stream.readInt(&variable.index); + stream.readBool(&variable.ignored); + + mState.mUniformLocations.push_back(variable); + } + + size_t bufferVariableCount = stream.readInt(); + ASSERT(mState.mBufferVariables.empty()); + for (size_t bufferVarIndex = 0; bufferVarIndex < bufferVariableCount; ++bufferVarIndex) + { + BufferVariable bufferVariable; + LoadBufferVariable(&stream, &bufferVariable); + mState.mBufferVariables.push_back(bufferVariable); + } + + static_assert(static_cast(ShaderType::EnumCount) <= sizeof(unsigned long) * 8, + "Too many shader types"); + + // Reject programs that use transform feedback varyings if the hardware cannot support them. + if (mState.mExecutable->getLinkedTransformFeedbackVaryings().size() > 0 && + context->getFrontendFeatures().disableProgramCachingForTransformFeedback.enabled) + { + infoLog << "Current driver does not support transform feedback in binary programs."; + return angle::Result::Stop; + } + + if (!mState.mAttachedShaders[ShaderType::Compute]) + { + mState.mExecutable->updateTransformFeedbackStrides(); + } + + postResolveLink(context); + mState.mExecutable->updateCanDrawWith(); + + if (context->getShareGroup()->getFrameCaptureShared()->enabled()) + { + // Extract the source for each stage from the program binary + angle::ProgramSources sources; + + for (ShaderType shaderType : mState.mExecutable->getLinkedShaderStages()) + { + std::string shaderSource = stream.readString(); + ASSERT(shaderSource.length() > 0); + sources[shaderType] = std::move(shaderSource); + } + + // Store it for use during mid-execution capture + context->getShareGroup()->getFrameCaptureShared()->setProgramSources(id(), + std::move(sources)); + } + + return angle::Result::Continue; +} + +void Program::postResolveLink(const gl::Context *context) +{ + mState.updateActiveSamplers(); + mState.mExecutable->mActiveImageShaderBits.fill({}); + mState.mExecutable->updateActiveImages(getExecutable()); + + setUniformValuesFromBindingQualifiers(); + + if (context->getExtensions().multiDrawANGLE) + { + mState.mDrawIDLocation = getUniformLocation("gl_DrawID").value; + } + + if (context->getExtensions().baseVertexBaseInstanceShaderBuiltinANGLE) + { + mState.mBaseVertexLocation = getUniformLocation("gl_BaseVertex").value; + mState.mBaseInstanceLocation = getUniformLocation("gl_BaseInstance").value; + } +} +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/Program.h b/gfx/angle/checkout/src/libANGLE/Program.h new file mode 100644 index 0000000000..0b7b62480b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Program.h @@ -0,0 +1,897 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Program.h: Defines the gl::Program class. Implements GL program objects +// and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28. + +#ifndef LIBANGLE_PROGRAM_H_ +#define LIBANGLE_PROGRAM_H_ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "common/Optional.h" +#include "common/angleutils.h" +#include "common/mathutil.h" +#include "common/utilities.h" + +#include "libANGLE/Constants.h" +#include "libANGLE/Debug.h" +#include "libANGLE/Error.h" +#include "libANGLE/InfoLog.h" +#include "libANGLE/ProgramExecutable.h" +#include "libANGLE/ProgramLinkedResources.h" +#include "libANGLE/RefCountObject.h" +#include "libANGLE/Uniform.h" +#include "libANGLE/angletypes.h" + +namespace rx +{ +class GLImplFactory; +class ProgramImpl; +struct TranslatedAttribute; +} // namespace rx + +namespace gl +{ +class Buffer; +class BinaryInputStream; +class BinaryOutputStream; +struct Caps; +class Context; +struct Extensions; +class Framebuffer; +class ProgramExecutable; +class Shader; +class ShaderProgramManager; +class State; +struct UnusedUniform; +struct Version; + +extern const char *const g_fakepath; + +enum class LinkMismatchError +{ + // Shared + NO_MISMATCH, + TYPE_MISMATCH, + ARRAYNESS_MISMATCH, + ARRAY_SIZE_MISMATCH, + PRECISION_MISMATCH, + STRUCT_NAME_MISMATCH, + FIELD_NUMBER_MISMATCH, + FIELD_NAME_MISMATCH, + + // Varying specific + INTERPOLATION_TYPE_MISMATCH, + INVARIANCE_MISMATCH, + + // Uniform specific + BINDING_MISMATCH, + LOCATION_MISMATCH, + OFFSET_MISMATCH, + INSTANCE_NAME_MISMATCH, + FORMAT_MISMATCH, + + // Interface block specific + LAYOUT_QUALIFIER_MISMATCH, + MATRIX_PACKING_MISMATCH, + + // I/O block specific + FIELD_LOCATION_MISMATCH, + FIELD_STRUCT_NAME_MISMATCH, +}; + +void LogLinkMismatch(InfoLog &infoLog, + const std::string &variableName, + const char *variableType, + LinkMismatchError linkError, + const std::string &mismatchedStructOrBlockFieldName, + ShaderType shaderType1, + ShaderType shaderType2); + +bool IsActiveInterfaceBlock(const sh::InterfaceBlock &interfaceBlock); + +void WriteBlockMemberInfo(BinaryOutputStream *stream, const sh::BlockMemberInfo &var); +void LoadBlockMemberInfo(BinaryInputStream *stream, sh::BlockMemberInfo *var); + +void WriteShaderVar(BinaryOutputStream *stream, const sh::ShaderVariable &var); +void LoadShaderVar(BinaryInputStream *stream, sh::ShaderVariable *var); + +void WriteInterfaceBlock(BinaryOutputStream *stream, const InterfaceBlock &block); +void LoadInterfaceBlock(BinaryInputStream *stream, InterfaceBlock *block); + +void WriteShInterfaceBlock(BinaryOutputStream *stream, const sh::InterfaceBlock &block); +void LoadShInterfaceBlock(BinaryInputStream *stream, sh::InterfaceBlock *block); + +void WriteShaderVariableBuffer(BinaryOutputStream *stream, const ShaderVariableBuffer &var); +void LoadShaderVariableBuffer(BinaryInputStream *stream, ShaderVariableBuffer *var); + +// Struct used for correlating uniforms/elements of uniform arrays to handles +struct VariableLocation +{ + static constexpr unsigned int kUnused = GL_INVALID_INDEX; + + VariableLocation(); + VariableLocation(unsigned int arrayIndex, unsigned int index); + + // If used is false, it means this location is only used to fill an empty space in an array, + // and there is no corresponding uniform variable for this location. It can also mean the + // uniform was optimized out by the implementation. + bool used() const { return (index != kUnused); } + void markUnused() { index = kUnused; } + void markIgnored() { ignored = true; } + + bool operator==(const VariableLocation &other) const + { + return arrayIndex == other.arrayIndex && index == other.index; + } + + // "arrayIndex" stores the index of the innermost GLSL array. It's zero for non-arrays. + unsigned int arrayIndex; + // "index" is an index of the variable. The variable contains the indices for other than the + // innermost GLSL arrays. + unsigned int index; + + // If this location was bound to an unreferenced uniform. Setting data on this uniform is a + // no-op. + bool ignored; +}; + +// Information about a variable binding. +// Currently used by CHROMIUM_path_rendering +struct BindingInfo +{ + // The type of binding, for example GL_FLOAT_VEC3. + // This can be GL_NONE if the variable is optimized away. + GLenum type; + + // This is the name of the variable in + // the translated shader program. Note that + // this can be empty in the case where the + // variable has been optimized away. + std::string name; + + // True if the binding is valid, otherwise false. + bool valid; +}; + +struct ProgramBinding +{ + ProgramBinding() : location(GL_INVALID_INDEX), aliased(false) {} + ProgramBinding(GLuint index) : location(index), aliased(false) {} + + GLuint location; + // Whether another binding was set that may potentially alias this. + bool aliased; +}; + +class ProgramBindings final : angle::NonCopyable +{ + public: + ProgramBindings(); + ~ProgramBindings(); + + void bindLocation(GLuint index, const std::string &name); + int getBindingByName(const std::string &name) const; + int getBinding(const sh::ShaderVariable &variable) const; + + using const_iterator = angle::HashMap::const_iterator; + const_iterator begin() const; + const_iterator end() const; + + std::map getStableIterationMap() const; + + private: + angle::HashMap mBindings; +}; + +// Uniforms and Fragment Outputs require special treatment due to array notation (e.g., "[0]") +class ProgramAliasedBindings final : angle::NonCopyable +{ + public: + ProgramAliasedBindings(); + ~ProgramAliasedBindings(); + + void bindLocation(GLuint index, const std::string &name); + int getBindingByName(const std::string &name) const; + int getBindingByLocation(GLuint location) const; + int getBinding(const sh::ShaderVariable &variable) const; + + using const_iterator = angle::HashMap::const_iterator; + const_iterator begin() const; + const_iterator end() const; + + std::map getStableIterationMap() const; + + private: + angle::HashMap mBindings; +}; + +class ProgramState final : angle::NonCopyable +{ + public: + ProgramState(); + ~ProgramState(); + + const std::string &getLabel(); + + Shader *getAttachedShader(ShaderType shaderType) const; + const gl::ShaderMap &getAttachedShaders() const { return mAttachedShaders; } + const std::vector &getTransformFeedbackVaryingNames() const + { + return mTransformFeedbackVaryingNames; + } + GLint getTransformFeedbackBufferMode() const + { + return mExecutable->getTransformFeedbackBufferMode(); + } + GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const + { + return mExecutable->getUniformBlockBinding(uniformBlockIndex); + } + GLuint getShaderStorageBlockBinding(GLuint blockIndex) const + { + return mExecutable->getShaderStorageBlockBinding(blockIndex); + } + const UniformBlockBindingMask &getActiveUniformBlockBindingsMask() const + { + return mExecutable->getActiveUniformBlockBindings(); + } + const std::vector &getProgramInputs() const + { + return mExecutable->getProgramInputs(); + } + const std::vector &getOutputVariables() const + { + return mExecutable->getOutputVariables(); + } + const std::vector &getOutputLocations() const + { + return mExecutable->getOutputLocations(); + } + const std::vector &getSecondaryOutputLocations() const + { + return mExecutable->getSecondaryOutputLocations(); + } + const std::vector &getUniforms() const { return mExecutable->getUniforms(); } + const std::vector &getUniformLocations() const { return mUniformLocations; } + const std::vector &getUniformBlocks() const + { + return mExecutable->getUniformBlocks(); + } + const std::vector &getShaderStorageBlocks() const + { + return mExecutable->getShaderStorageBlocks(); + } + const std::vector &getBufferVariables() const { return mBufferVariables; } + const std::vector &getSamplerBindings() const + { + return mExecutable->getSamplerBindings(); + } + const std::vector &getImageBindings() const + { + return getExecutable().getImageBindings(); + } + const sh::WorkGroupSize &getComputeShaderLocalSize() const { return mComputeShaderLocalSize; } + const RangeUI &getDefaultUniformRange() const { return mExecutable->getDefaultUniformRange(); } + const RangeUI &getSamplerUniformRange() const { return mExecutable->getSamplerUniformRange(); } + const RangeUI &getImageUniformRange() const { return mExecutable->getImageUniformRange(); } + const RangeUI &getAtomicCounterUniformRange() const + { + return mExecutable->getAtomicCounterUniformRange(); + } + const RangeUI &getFragmentInoutRange() const { return mExecutable->getFragmentInoutRange(); } + + const std::vector &getLinkedTransformFeedbackVaryings() const + { + return mExecutable->getLinkedTransformFeedbackVaryings(); + } + const std::vector &getTransformFeedbackStrides() const + { + return mExecutable->getTransformFeedbackStrides(); + } + const std::vector &getAtomicCounterBuffers() const + { + return mExecutable->getAtomicCounterBuffers(); + } + + GLuint getUniformIndexFromName(const std::string &name) const; + GLuint getUniformIndexFromLocation(UniformLocation location) const; + Optional getSamplerIndex(UniformLocation location) const; + bool isSamplerUniformIndex(GLuint index) const; + GLuint getSamplerIndexFromUniformIndex(GLuint uniformIndex) const; + GLuint getUniformIndexFromSamplerIndex(GLuint samplerIndex) const; + bool isImageUniformIndex(GLuint index) const; + GLuint getImageIndexFromUniformIndex(GLuint uniformIndex) const; + GLuint getAttributeLocation(const std::string &name) const; + + GLuint getBufferVariableIndexFromName(const std::string &name) const; + + int getNumViews() const { return mNumViews; } + bool usesMultiview() const { return mNumViews != -1; } + + bool hasAttachedShader() const; + + ShaderType getFirstAttachedShaderStageType() const; + ShaderType getLastAttachedShaderStageType() const; + + const ProgramAliasedBindings &getUniformLocationBindings() const + { + return mUniformLocationBindings; + } + + const ProgramExecutable &getExecutable() const + { + ASSERT(mExecutable); + return *mExecutable; + } + ProgramExecutable &getExecutable() + { + ASSERT(mExecutable); + return *mExecutable; + } + + bool hasImages() const { return !getImageBindings().empty(); } + rx::SpecConstUsageBits getSpecConstUsageBits() const { return mSpecConstUsageBits; } + + // A Program can only either be graphics or compute, but never both, so it + // can answer isCompute() based on which shaders it has. + bool isCompute() const { return mExecutable->hasLinkedShaderStage(ShaderType::Compute); } + + const std::string &getLabel() const { return mLabel; } + + uint32_t getLocationsUsedForXfbExtension() const { return mLocationsUsedForXfbExtension; } + + bool hasBinaryRetrieveableHint() const { return mBinaryRetrieveableHint; } + + bool isSeparable() const { return mSeparable; } + + int getDrawIDLocation() const { return mDrawIDLocation; } + + int getBaseVertexLocation() const { return mBaseVertexLocation; } + + int getBaseInstanceLocation() const { return mBaseInstanceLocation; } + + ShaderType getAttachedTransformFeedbackStage() const; + + private: + friend class MemoryProgramCache; + friend class Program; + + void updateActiveSamplers(); + void updateProgramInterfaceInputs(const Context *context); + void updateProgramInterfaceOutputs(const Context *context); + + // Scans the sampler bindings for type conflicts with sampler 'textureUnitIndex'. + void setSamplerUniformTextureTypeAndFormat(size_t textureUnitIndex); + + std::string mLabel; + + sh::WorkGroupSize mComputeShaderLocalSize; + + ShaderMap mAttachedShaders; + + uint32_t mLocationsUsedForXfbExtension; + std::vector mTransformFeedbackVaryingNames; + + std::vector mUniformLocations; + std::vector mBufferVariables; + + bool mBinaryRetrieveableHint; + bool mSeparable; + rx::SpecConstUsageBits mSpecConstUsageBits; + + // ANGLE_multiview. + int mNumViews; + + // GL_ANGLE_multi_draw + int mDrawIDLocation; + + // GL_ANGLE_base_vertex_base_instance_shader_builtin + int mBaseVertexLocation; + int mBaseInstanceLocation; + // Cached value of base vertex and base instance + // need to reset them to zero if using non base vertex or base instance draw calls. + GLint mCachedBaseVertex; + GLuint mCachedBaseInstance; + + // Note that this has nothing to do with binding layout qualifiers that can be set for some + // uniforms in GLES3.1+. It is used to pre-set the location of uniforms. + ProgramAliasedBindings mUniformLocationBindings; + + std::shared_ptr mExecutable; +}; + +struct ProgramVaryingRef +{ + const sh::ShaderVariable *get(ShaderType stage) const + { + ASSERT(stage == frontShaderStage || stage == backShaderStage); + const sh::ShaderVariable *ref = stage == frontShaderStage ? frontShader : backShader; + ASSERT(ref); + return ref; + } + + const sh::ShaderVariable *frontShader = nullptr; + const sh::ShaderVariable *backShader = nullptr; + ShaderType frontShaderStage = ShaderType::InvalidEnum; + ShaderType backShaderStage = ShaderType::InvalidEnum; +}; + +using ProgramMergedVaryings = std::vector; + +class Program final : public LabeledObject, public angle::Subject +{ + public: + Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, ShaderProgramID handle); + void onDestroy(const Context *context); + + ShaderProgramID id() const; + + angle::Result setLabel(const Context *context, const std::string &label) override; + const std::string &getLabel() const override; + + ANGLE_INLINE rx::ProgramImpl *getImplementation() const + { + ASSERT(!mLinkingState); + return mProgram; + } + + void attachShader(Shader *shader); + void detachShader(const Context *context, Shader *shader); + int getAttachedShadersCount() const; + + Shader *getAttachedShader(ShaderType shaderType) const; + + void bindAttributeLocation(GLuint index, const char *name); + void bindUniformLocation(UniformLocation location, const char *name); + + // EXT_blend_func_extended + void bindFragmentOutputLocation(GLuint index, const char *name); + void bindFragmentOutputIndex(GLuint index, const char *name); + + // KHR_parallel_shader_compile + // Try to link the program asynchronously. As a result, background threads may be launched to + // execute the linking tasks concurrently. + angle::Result link(const Context *context); + + // Peek whether there is any running linking tasks. + bool isLinking() const; + bool hasLinkingState() const { return mLinkingState != nullptr; } + + bool isLinked() const + { + ASSERT(!mLinkingState); + return mLinked; + } + + angle::Result loadBinary(const Context *context, + GLenum binaryFormat, + const void *binary, + GLsizei length); + angle::Result saveBinary(Context *context, + GLenum *binaryFormat, + void *binary, + GLsizei bufSize, + GLsizei *length) const; + GLint getBinaryLength(Context *context) const; + void setBinaryRetrievableHint(bool retrievable); + bool getBinaryRetrievableHint() const; + + void setSeparable(bool separable); + bool isSeparable() const; + + void getAttachedShaders(GLsizei maxCount, GLsizei *count, ShaderProgramID *shaders) const; + + GLuint getAttributeLocation(const std::string &name) const; + + void getActiveAttribute(GLuint index, + GLsizei bufsize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name) const; + GLint getActiveAttributeCount() const; + GLint getActiveAttributeMaxLength() const; + const std::vector &getAttributes() const; + + GLint getFragDataLocation(const std::string &name) const; + size_t getOutputResourceCount() const; + + // EXT_blend_func_extended + GLint getFragDataIndex(const std::string &name) const; + + void getActiveUniform(GLuint index, + GLsizei bufsize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name) const; + GLint getActiveUniformCount() const; + size_t getActiveBufferVariableCount() const; + GLint getActiveUniformMaxLength() const; + bool isValidUniformLocation(UniformLocation location) const; + const LinkedUniform &getUniformByLocation(UniformLocation location) const; + const VariableLocation &getUniformLocation(UniformLocation location) const; + + const std::vector &getUniformLocations() const + { + ASSERT(!mLinkingState); + return mState.mUniformLocations; + } + + const LinkedUniform &getUniformByIndex(GLuint index) const + { + ASSERT(!mLinkingState); + return mState.mExecutable->getUniformByIndex(index); + } + + const BufferVariable &getBufferVariableByIndex(GLuint index) const; + + enum SetUniformResult + { + SamplerChanged, + NoSamplerChange, + }; + + UniformLocation getUniformLocation(const std::string &name) const; + GLuint getUniformIndex(const std::string &name) const; + void setUniform1fv(UniformLocation location, GLsizei count, const GLfloat *v); + void setUniform2fv(UniformLocation location, GLsizei count, const GLfloat *v); + void setUniform3fv(UniformLocation location, GLsizei count, const GLfloat *v); + void setUniform4fv(UniformLocation location, GLsizei count, const GLfloat *v); + void setUniform1iv(Context *context, UniformLocation location, GLsizei count, const GLint *v); + void setUniform2iv(UniformLocation location, GLsizei count, const GLint *v); + void setUniform3iv(UniformLocation location, GLsizei count, const GLint *v); + void setUniform4iv(UniformLocation location, GLsizei count, const GLint *v); + void setUniform1uiv(UniformLocation location, GLsizei count, const GLuint *v); + void setUniform2uiv(UniformLocation location, GLsizei count, const GLuint *v); + void setUniform3uiv(UniformLocation location, GLsizei count, const GLuint *v); + void setUniform4uiv(UniformLocation location, GLsizei count, const GLuint *v); + void setUniformMatrix2fv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + void setUniformMatrix3fv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + void setUniformMatrix4fv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + void setUniformMatrix2x3fv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + void setUniformMatrix3x2fv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + void setUniformMatrix2x4fv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + void setUniformMatrix4x2fv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + void setUniformMatrix3x4fv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + void setUniformMatrix4x3fv(UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + + void getUniformfv(const Context *context, UniformLocation location, GLfloat *params) const; + void getUniformiv(const Context *context, UniformLocation location, GLint *params) const; + void getUniformuiv(const Context *context, UniformLocation location, GLuint *params) const; + + void getActiveUniformBlockName(const Context *context, + const UniformBlockIndex blockIndex, + GLsizei bufSize, + GLsizei *length, + GLchar *blockName) const; + void getActiveShaderStorageBlockName(const GLuint blockIndex, + GLsizei bufSize, + GLsizei *length, + GLchar *blockName) const; + + ANGLE_INLINE GLuint getActiveUniformBlockCount() const + { + ASSERT(!mLinkingState); + return static_cast(mState.mExecutable->getActiveUniformBlockCount()); + } + + ANGLE_INLINE GLuint getActiveAtomicCounterBufferCount() const + { + ASSERT(!mLinkingState); + return static_cast(mState.mExecutable->getActiveAtomicCounterBufferCount()); + } + + ANGLE_INLINE GLuint getActiveShaderStorageBlockCount() const + { + ASSERT(!mLinkingState); + return static_cast(mState.mExecutable->getActiveShaderStorageBlockCount()); + } + + GLint getActiveUniformBlockMaxNameLength() const; + GLint getActiveShaderStorageBlockMaxNameLength() const; + + const std::vector &getUniforms() const { return mState.getUniforms(); } + GLuint getUniformBlockIndex(const std::string &name) const; + GLuint getShaderStorageBlockIndex(const std::string &name) const; + + void bindUniformBlock(UniformBlockIndex uniformBlockIndex, GLuint uniformBlockBinding); + GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const; + GLuint getShaderStorageBlockBinding(GLuint shaderStorageBlockIndex) const; + + const InterfaceBlock &getUniformBlockByIndex(GLuint index) const; + const InterfaceBlock &getShaderStorageBlockByIndex(GLuint index) const; + + void setTransformFeedbackVaryings(GLsizei count, + const GLchar *const *varyings, + GLenum bufferMode); + void getTransformFeedbackVarying(GLuint index, + GLsizei bufSize, + GLsizei *length, + GLsizei *size, + GLenum *type, + GLchar *name) const; + GLsizei getTransformFeedbackVaryingCount() const; + GLsizei getTransformFeedbackVaryingMaxLength() const; + GLenum getTransformFeedbackBufferMode() const; + GLuint getTransformFeedbackVaryingResourceIndex(const GLchar *name) const; + const TransformFeedbackVarying &getTransformFeedbackVaryingResource(GLuint index) const; + + bool hasDrawIDUniform() const; + void setDrawIDUniform(GLint drawid); + + bool hasBaseVertexUniform() const; + void setBaseVertexUniform(GLint baseVertex); + bool hasBaseInstanceUniform() const; + void setBaseInstanceUniform(GLuint baseInstance); + + ANGLE_INLINE void addRef() + { + ASSERT(!mLinkingState); + mRefCount++; + } + + ANGLE_INLINE void release(const Context *context) + { + ASSERT(!mLinkingState); + mRefCount--; + + if (mRefCount == 0 && mDeleteStatus) + { + deleteSelf(context); + } + } + + unsigned int getRefCount() const; + bool isInUse() const { return getRefCount() != 0; } + void flagForDeletion(); + bool isFlaggedForDeletion() const; + + void validate(const Caps &caps); + bool isValidated() const; + + const std::vector &getImageBindings() const + { + ASSERT(!mLinkingState); + return getExecutable().getImageBindings(); + } + const sh::WorkGroupSize &getComputeShaderLocalSize() const; + PrimitiveMode getGeometryShaderInputPrimitiveType() const; + PrimitiveMode getGeometryShaderOutputPrimitiveType() const; + GLint getGeometryShaderInvocations() const; + GLint getGeometryShaderMaxVertices() const; + + GLint getTessControlShaderVertices() const; + GLenum getTessGenMode() const; + GLenum getTessGenPointMode() const; + GLenum getTessGenSpacing() const; + GLenum getTessGenVertexOrder() const; + + const ProgramState &getState() const + { + ASSERT(!mLinkingState); + return mState; + } + + GLuint getInputResourceIndex(const GLchar *name) const; + GLuint getOutputResourceIndex(const GLchar *name) const; + void getInputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const; + void getOutputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const; + void getUniformResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const; + void getBufferVariableResourceName(GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name) const; + const sh::ShaderVariable &getInputResource(size_t index) const; + GLuint getResourceMaxNameSize(const sh::ShaderVariable &resource, GLint max) const; + GLuint getInputResourceMaxNameSize() const; + GLuint getOutputResourceMaxNameSize() const; + GLuint getResourceLocation(const GLchar *name, const sh::ShaderVariable &variable) const; + GLuint getInputResourceLocation(const GLchar *name) const; + GLuint getOutputResourceLocation(const GLchar *name) const; + const std::string getResourceName(const sh::ShaderVariable &resource) const; + const std::string getInputResourceName(GLuint index) const; + const std::string getOutputResourceName(GLuint index) const; + const sh::ShaderVariable &getOutputResource(size_t index) const; + + const ProgramBindings &getAttributeBindings() const; + const ProgramAliasedBindings &getUniformLocationBindings() const; + const ProgramAliasedBindings &getFragmentOutputLocations() const; + const ProgramAliasedBindings &getFragmentOutputIndexes() const; + + int getNumViews() const + { + ASSERT(!mLinkingState); + return mState.getNumViews(); + } + + bool usesMultiview() const { return mState.usesMultiview(); } + + const std::vector &getTransformFeedbackStrides() const; + + // Program dirty bits. + enum DirtyBitType + { + DIRTY_BIT_UNIFORM_BLOCK_BINDING_0, + DIRTY_BIT_UNIFORM_BLOCK_BINDING_MAX = + DIRTY_BIT_UNIFORM_BLOCK_BINDING_0 + IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS, + + DIRTY_BIT_COUNT = DIRTY_BIT_UNIFORM_BLOCK_BINDING_MAX, + }; + + using DirtyBits = angle::BitSet; + + angle::Result syncState(const Context *context); + + // Try to resolve linking. Inlined to make sure its overhead is as low as possible. + void resolveLink(const Context *context) + { + if (mLinkingState) + { + resolveLinkImpl(context); + } + } + + ANGLE_INLINE bool hasAnyDirtyBit() const { return mDirtyBits.any(); } + + // Writes a program's binary to the output memory buffer. + angle::Result serialize(const Context *context, angle::MemoryBuffer *binaryOut) const; + + rx::Serial serial() const { return mSerial; } + + const ProgramExecutable &getExecutable() const { return mState.getExecutable(); } + ProgramExecutable &getExecutable() { return mState.getExecutable(); } + + private: + struct LinkingState; + + ~Program() override; + + // Loads program state according to the specified binary blob. + angle::Result deserialize(const Context *context, BinaryInputStream &stream, InfoLog &infoLog); + + void unlink(); + void deleteSelf(const Context *context); + + angle::Result linkImpl(const Context *context); + + bool linkValidateShaders(const Context *context, InfoLog &infoLog); + bool linkAttributes(const Context *context, InfoLog &infoLog); + bool linkVaryings(const Context *context, InfoLog &infoLog) const; + + bool linkUniforms(const Context *context, + std::vector *unusedUniformsOutOrNull, + GLuint *combinedImageUniformsOut, + InfoLog &infoLog); + + void updateLinkedShaderStages(); + + void setUniformValuesFromBindingQualifiers(); + bool shouldIgnoreUniform(UniformLocation location) const; + + void initInterfaceBlockBindings(); + + // Both these function update the cached uniform values and return a modified "count" + // so that the uniform update doesn't overflow the uniform. + template + GLsizei clampUniformCount(const VariableLocation &locationInfo, + GLsizei count, + int vectorSize, + const T *v); + template + GLsizei clampMatrixUniformCount(UniformLocation location, + GLsizei count, + GLboolean transpose, + const T *v); + + void updateSamplerUniform(Context *context, + const VariableLocation &locationInfo, + GLsizei clampedCount, + const GLint *v); + + template + void getUniformInternal(const Context *context, + DestT *dataOut, + UniformLocation location, + GLenum nativeType, + int components) const; + + void getResourceName(const std::string name, + GLsizei bufSize, + GLsizei *length, + GLchar *dest) const; + + template + GLint getActiveInterfaceBlockMaxNameLength(const std::vector &resources) const; + + GLuint getSamplerUniformBinding(const VariableLocation &uniformLocation) const; + GLuint getImageUniformBinding(const VariableLocation &uniformLocation) const; + + // Block until linking is finished and resolve it. + void resolveLinkImpl(const gl::Context *context); + + void postResolveLink(const gl::Context *context); + + template + void setUniformGeneric(UniformLocation location, GLsizei count, const UniformT *v); + + template < + typename UniformT, + GLint MatrixC, + GLint MatrixR, + void (rx::ProgramImpl::*SetUniformMatrixFunc)(GLint, GLsizei, GLboolean, const UniformT *)> + void setUniformMatrixGeneric(UniformLocation location, + GLsizei count, + GLboolean transpose, + const UniformT *v); + + rx::Serial mSerial; + ProgramState mState; + rx::ProgramImpl *mProgram; + + bool mValidated; + + ProgramBindings mAttributeBindings; + + // EXT_blend_func_extended + ProgramAliasedBindings mFragmentOutputLocations; + ProgramAliasedBindings mFragmentOutputIndexes; + + bool mLinked; + std::unique_ptr mLinkingState; + bool mDeleteStatus; // Flag to indicate that the program can be deleted when no longer in use + + unsigned int mRefCount; + + ShaderProgramManager *mResourceManager; + const ShaderProgramID mHandle; + + DirtyBits mDirtyBits; + + std::mutex mHistogramMutex; +}; +} // namespace gl + +#endif // LIBANGLE_PROGRAM_H_ diff --git a/gfx/angle/checkout/src/libANGLE/ProgramExecutable.cpp b/gfx/angle/checkout/src/libANGLE/ProgramExecutable.cpp new file mode 100644 index 0000000000..6005519347 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/ProgramExecutable.cpp @@ -0,0 +1,1785 @@ +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ProgramExecutable.cpp: Collects the interfaces common to both Programs and +// ProgramPipelines in order to execute/draw with either. + +#include "libANGLE/ProgramExecutable.h" + +#include "common/string_utils.h" +#include "libANGLE/Context.h" +#include "libANGLE/Program.h" +#include "libANGLE/Shader.h" + +namespace gl +{ +namespace +{ +bool IncludeSameArrayElement(const std::set &nameSet, const std::string &name) +{ + std::vector subscripts; + std::string baseName = ParseResourceName(name, &subscripts); + for (const std::string &nameInSet : nameSet) + { + std::vector arrayIndices; + std::string arrayName = ParseResourceName(nameInSet, &arrayIndices); + if (baseName == arrayName && + (subscripts.empty() || arrayIndices.empty() || subscripts == arrayIndices)) + { + return true; + } + } + return false; +} + +// Find the matching varying or field by name. +const sh::ShaderVariable *FindOutputVaryingOrField(const ProgramMergedVaryings &varyings, + ShaderType stage, + const std::string &name) +{ + const sh::ShaderVariable *var = nullptr; + for (const ProgramVaryingRef &ref : varyings) + { + if (ref.frontShaderStage != stage) + { + continue; + } + + const sh::ShaderVariable *varying = ref.get(stage); + if (varying->name == name) + { + var = varying; + break; + } + GLuint fieldIndex = 0; + var = varying->findField(name, &fieldIndex); + if (var != nullptr) + { + break; + } + } + return var; +} + +bool FindUsedOutputLocation(std::vector &outputLocations, + unsigned int baseLocation, + unsigned int elementCount, + const std::vector &reservedLocations, + unsigned int variableIndex) +{ + if (baseLocation + elementCount > outputLocations.size()) + { + elementCount = baseLocation < outputLocations.size() + ? static_cast(outputLocations.size() - baseLocation) + : 0; + } + for (unsigned int elementIndex = 0; elementIndex < elementCount; elementIndex++) + { + const unsigned int location = baseLocation + elementIndex; + if (outputLocations[location].used()) + { + VariableLocation locationInfo(elementIndex, variableIndex); + if (std::find(reservedLocations.begin(), reservedLocations.end(), locationInfo) == + reservedLocations.end()) + { + return true; + } + } + } + return false; +} + +void AssignOutputLocations(std::vector &outputLocations, + unsigned int baseLocation, + unsigned int elementCount, + const std::vector &reservedLocations, + unsigned int variableIndex, + sh::ShaderVariable &outputVariable) +{ + if (baseLocation + elementCount > outputLocations.size()) + { + outputLocations.resize(baseLocation + elementCount); + } + for (unsigned int elementIndex = 0; elementIndex < elementCount; elementIndex++) + { + VariableLocation locationInfo(elementIndex, variableIndex); + if (std::find(reservedLocations.begin(), reservedLocations.end(), locationInfo) == + reservedLocations.end()) + { + outputVariable.location = baseLocation; + const unsigned int location = baseLocation + elementIndex; + outputLocations[location] = locationInfo; + } + } +} + +int GetOutputLocationForLink(const ProgramAliasedBindings &fragmentOutputLocations, + const sh::ShaderVariable &outputVariable) +{ + if (outputVariable.location != -1) + { + return outputVariable.location; + } + int apiLocation = fragmentOutputLocations.getBinding(outputVariable); + if (apiLocation != -1) + { + return apiLocation; + } + return -1; +} + +bool IsOutputSecondaryForLink(const ProgramAliasedBindings &fragmentOutputIndexes, + const sh::ShaderVariable &outputVariable) +{ + if (outputVariable.index != -1) + { + ASSERT(outputVariable.index == 0 || outputVariable.index == 1); + return (outputVariable.index == 1); + } + int apiIndex = fragmentOutputIndexes.getBinding(outputVariable); + if (apiIndex != -1) + { + // Index layout qualifier from the shader takes precedence, so the index from the API is + // checked only if the index was not set in the shader. This is not specified in the EXT + // spec, but is specified in desktop OpenGL specs. + return (apiIndex == 1); + } + // EXT_blend_func_extended: Outputs get index 0 by default. + return false; +} + +RangeUI AddUniforms(const ShaderMap &programs, + ShaderBitSet activeShaders, + std::vector &outputUniforms, + const std::function &getRange) +{ + unsigned int startRange = static_cast(outputUniforms.size()); + for (ShaderType shaderType : activeShaders) + { + const ProgramState &programState = programs[shaderType]->getState(); + const std::vector &programUniforms = programState.getUniforms(); + const RangeUI uniformRange = getRange(programState); + + outputUniforms.insert(outputUniforms.end(), programUniforms.begin() + uniformRange.low(), + programUniforms.begin() + uniformRange.high()); + } + return RangeUI(startRange, static_cast(outputUniforms.size())); +} + +template +void AppendActiveBlocks(ShaderType shaderType, + const std::vector &blocksIn, + std::vector &blocksOut) +{ + for (const BlockT &block : blocksIn) + { + if (block.isActive(shaderType)) + { + blocksOut.push_back(block); + } + } +} +} // anonymous namespace + +ProgramExecutable::ProgramExecutable() + : mMaxActiveAttribLocation(0), + mAttributesTypeMask(0), + mAttributesMask(0), + mActiveSamplerRefCounts{}, + mCanDrawWith(false), + mYUVOutput(false), + mTransformFeedbackBufferMode(GL_INTERLEAVED_ATTRIBS), + mDefaultUniformRange(0, 0), + mSamplerUniformRange(0, 0), + mImageUniformRange(0, 0), + mAtomicCounterUniformRange(0, 0), + mFragmentInoutRange(0, 0), + mHasDiscard(false), + mEnablesPerSampleShading(false), + // [GL_EXT_geometry_shader] Table 20.22 + mGeometryShaderInputPrimitiveType(PrimitiveMode::Triangles), + mGeometryShaderOutputPrimitiveType(PrimitiveMode::TriangleStrip), + mGeometryShaderInvocations(1), + mGeometryShaderMaxVertices(0), + mTessControlShaderVertices(0), + mTessGenMode(GL_NONE), + mTessGenSpacing(GL_NONE), + mTessGenVertexOrder(GL_NONE), + mTessGenPointMode(GL_NONE) +{ + reset(true); +} + +ProgramExecutable::ProgramExecutable(const ProgramExecutable &other) + : mLinkedShaderStages(other.mLinkedShaderStages), + mActiveAttribLocationsMask(other.mActiveAttribLocationsMask), + mMaxActiveAttribLocation(other.mMaxActiveAttribLocation), + mAttributesTypeMask(other.mAttributesTypeMask), + mAttributesMask(other.mAttributesMask), + mActiveSamplersMask(other.mActiveSamplersMask), + mActiveSamplerRefCounts(other.mActiveSamplerRefCounts), + mActiveSamplerTypes(other.mActiveSamplerTypes), + mActiveSamplerYUV(other.mActiveSamplerYUV), + mActiveSamplerFormats(other.mActiveSamplerFormats), + mActiveSamplerShaderBits(other.mActiveSamplerShaderBits), + mActiveImagesMask(other.mActiveImagesMask), + mActiveImageShaderBits(other.mActiveImageShaderBits), + mCanDrawWith(other.mCanDrawWith), + mOutputVariables(other.mOutputVariables), + mOutputLocations(other.mOutputLocations), + mSecondaryOutputLocations(other.mSecondaryOutputLocations), + mYUVOutput(other.mYUVOutput), + mProgramInputs(other.mProgramInputs), + mLinkedTransformFeedbackVaryings(other.mLinkedTransformFeedbackVaryings), + mTransformFeedbackStrides(other.mTransformFeedbackStrides), + mTransformFeedbackBufferMode(other.mTransformFeedbackBufferMode), + mUniforms(other.mUniforms), + mDefaultUniformRange(other.mDefaultUniformRange), + mSamplerUniformRange(other.mSamplerUniformRange), + mImageUniformRange(other.mImageUniformRange), + mAtomicCounterUniformRange(other.mAtomicCounterUniformRange), + mUniformBlocks(other.mUniformBlocks), + mActiveUniformBlockBindings(other.mActiveUniformBlockBindings), + mAtomicCounterBuffers(other.mAtomicCounterBuffers), + mShaderStorageBlocks(other.mShaderStorageBlocks), + mFragmentInoutRange(other.mFragmentInoutRange), + mHasDiscard(other.mHasDiscard), + mEnablesPerSampleShading(other.mEnablesPerSampleShading), + mAdvancedBlendEquations(other.mAdvancedBlendEquations) +{ + reset(true); +} + +ProgramExecutable::~ProgramExecutable() = default; + +void ProgramExecutable::reset(bool clearInfoLog) +{ + if (clearInfoLog) + { + resetInfoLog(); + } + mActiveAttribLocationsMask.reset(); + mAttributesTypeMask.reset(); + mAttributesMask.reset(); + mMaxActiveAttribLocation = 0; + + mActiveSamplersMask.reset(); + mActiveSamplerRefCounts = {}; + mActiveSamplerTypes.fill(TextureType::InvalidEnum); + mActiveSamplerYUV.reset(); + mActiveSamplerFormats.fill(SamplerFormat::InvalidEnum); + + mActiveImagesMask.reset(); + + mProgramInputs.clear(); + mLinkedTransformFeedbackVaryings.clear(); + mTransformFeedbackStrides.clear(); + mUniforms.clear(); + mUniformBlocks.clear(); + mActiveUniformBlockBindings.reset(); + mShaderStorageBlocks.clear(); + mAtomicCounterBuffers.clear(); + mOutputVariables.clear(); + mOutputLocations.clear(); + mActiveOutputVariablesMask.reset(); + mSecondaryOutputLocations.clear(); + mYUVOutput = false; + mSamplerBindings.clear(); + mImageBindings.clear(); + + mDefaultUniformRange = RangeUI(0, 0); + mSamplerUniformRange = RangeUI(0, 0); + mImageUniformRange = RangeUI(0, 0); + mAtomicCounterUniformRange = RangeUI(0, 0); + + mFragmentInoutRange = RangeUI(0, 0); + mHasDiscard = false; + mEnablesPerSampleShading = false; + mAdvancedBlendEquations.reset(); + + mGeometryShaderInputPrimitiveType = PrimitiveMode::Triangles; + mGeometryShaderOutputPrimitiveType = PrimitiveMode::TriangleStrip; + mGeometryShaderInvocations = 1; + mGeometryShaderMaxVertices = 0; + + mTessControlShaderVertices = 0; + mTessGenMode = GL_NONE; + mTessGenSpacing = GL_NONE; + mTessGenVertexOrder = GL_NONE; + mTessGenPointMode = GL_NONE; + + mOutputVariableTypes.clear(); + mDrawBufferTypeMask.reset(); +} + +void ProgramExecutable::load(bool isSeparable, gl::BinaryInputStream *stream) +{ + static_assert(MAX_VERTEX_ATTRIBS * 2 <= sizeof(uint32_t) * 8, + "Too many vertex attribs for mask: All bits of mAttributesTypeMask types and " + "mask fit into 32 bits each"); + mAttributesTypeMask = gl::ComponentTypeMask(stream->readInt()); + mAttributesMask = gl::AttributesMask(stream->readInt()); + mActiveAttribLocationsMask = gl::AttributesMask(stream->readInt()); + mMaxActiveAttribLocation = stream->readInt(); + + unsigned int fragmentInoutRangeLow = stream->readInt(); + unsigned int fragmentInoutRangeHigh = stream->readInt(); + mFragmentInoutRange = RangeUI(fragmentInoutRangeLow, fragmentInoutRangeHigh); + + mHasDiscard = stream->readBool(); + mEnablesPerSampleShading = stream->readBool(); + + static_assert(sizeof(mAdvancedBlendEquations.bits()) == sizeof(uint32_t)); + mAdvancedBlendEquations = BlendEquationBitSet(stream->readInt()); + + mLinkedShaderStages = ShaderBitSet(stream->readInt()); + + mGeometryShaderInputPrimitiveType = stream->readEnum(); + mGeometryShaderOutputPrimitiveType = stream->readEnum(); + mGeometryShaderInvocations = stream->readInt(); + mGeometryShaderMaxVertices = stream->readInt(); + + mTessControlShaderVertices = stream->readInt(); + mTessGenMode = stream->readInt(); + mTessGenSpacing = stream->readInt(); + mTessGenVertexOrder = stream->readInt(); + mTessGenPointMode = stream->readInt(); + + size_t attribCount = stream->readInt(); + ASSERT(getProgramInputs().empty()); + for (size_t attribIndex = 0; attribIndex < attribCount; ++attribIndex) + { + sh::ShaderVariable attrib; + LoadShaderVar(stream, &attrib); + attrib.location = stream->readInt(); + mProgramInputs.push_back(attrib); + } + + size_t uniformCount = stream->readInt(); + ASSERT(getUniforms().empty()); + for (size_t uniformIndex = 0; uniformIndex < uniformCount; ++uniformIndex) + { + LinkedUniform uniform; + LoadShaderVar(stream, &uniform); + + uniform.bufferIndex = stream->readInt(); + LoadBlockMemberInfo(stream, &uniform.blockInfo); + + stream->readIntVector(&uniform.outerArraySizes); + uniform.outerArrayOffset = stream->readInt(); + + uniform.typeInfo = &GetUniformTypeInfo(uniform.type); + + // Active shader info + for (ShaderType shaderType : gl::AllShaderTypes()) + { + uniform.setActive(shaderType, stream->readBool()); + } + + mUniforms.push_back(uniform); + } + + size_t uniformBlockCount = stream->readInt(); + ASSERT(getUniformBlocks().empty()); + for (size_t uniformBlockIndex = 0; uniformBlockIndex < uniformBlockCount; ++uniformBlockIndex) + { + InterfaceBlock uniformBlock; + LoadInterfaceBlock(stream, &uniformBlock); + mUniformBlocks.push_back(uniformBlock); + + mActiveUniformBlockBindings.set(uniformBlockIndex, uniformBlock.binding != 0); + } + + size_t shaderStorageBlockCount = stream->readInt(); + ASSERT(getShaderStorageBlocks().empty()); + for (size_t shaderStorageBlockIndex = 0; shaderStorageBlockIndex < shaderStorageBlockCount; + ++shaderStorageBlockIndex) + { + InterfaceBlock shaderStorageBlock; + LoadInterfaceBlock(stream, &shaderStorageBlock); + mShaderStorageBlocks.push_back(shaderStorageBlock); + } + + size_t atomicCounterBufferCount = stream->readInt(); + ASSERT(getAtomicCounterBuffers().empty()); + for (size_t bufferIndex = 0; bufferIndex < atomicCounterBufferCount; ++bufferIndex) + { + AtomicCounterBuffer atomicCounterBuffer; + LoadShaderVariableBuffer(stream, &atomicCounterBuffer); + + mAtomicCounterBuffers.push_back(atomicCounterBuffer); + } + + size_t transformFeedbackVaryingCount = stream->readInt(); + ASSERT(mLinkedTransformFeedbackVaryings.empty()); + for (size_t transformFeedbackVaryingIndex = 0; + transformFeedbackVaryingIndex < transformFeedbackVaryingCount; + ++transformFeedbackVaryingIndex) + { + sh::ShaderVariable varying; + stream->readIntVector(&varying.arraySizes); + stream->readInt(&varying.type); + stream->readString(&varying.name); + + GLuint arrayIndex = stream->readInt(); + + mLinkedTransformFeedbackVaryings.emplace_back(varying, arrayIndex); + } + + mTransformFeedbackBufferMode = stream->readInt(); + + size_t outputCount = stream->readInt(); + ASSERT(getOutputVariables().empty()); + for (size_t outputIndex = 0; outputIndex < outputCount; ++outputIndex) + { + sh::ShaderVariable output; + LoadShaderVar(stream, &output); + output.location = stream->readInt(); + output.index = stream->readInt(); + mOutputVariables.push_back(output); + } + + size_t outputVarCount = stream->readInt(); + ASSERT(getOutputLocations().empty()); + for (size_t outputIndex = 0; outputIndex < outputVarCount; ++outputIndex) + { + VariableLocation locationData; + stream->readInt(&locationData.arrayIndex); + stream->readInt(&locationData.index); + stream->readBool(&locationData.ignored); + mOutputLocations.push_back(locationData); + } + + mActiveOutputVariablesMask = + gl::DrawBufferMask(stream->readInt()); + + size_t outputTypeCount = stream->readInt(); + for (size_t outputIndex = 0; outputIndex < outputTypeCount; ++outputIndex) + { + mOutputVariableTypes.push_back(stream->readInt()); + } + + static_assert(IMPLEMENTATION_MAX_DRAW_BUFFERS * 2 <= 8 * sizeof(uint32_t), + "All bits of mDrawBufferTypeMask and mActiveOutputVariables types and mask fit " + "into 32 bits each"); + mDrawBufferTypeMask = gl::ComponentTypeMask(stream->readInt()); + + stream->readBool(&mYUVOutput); + + size_t secondaryOutputVarCount = stream->readInt(); + ASSERT(getSecondaryOutputLocations().empty()); + for (size_t outputIndex = 0; outputIndex < secondaryOutputVarCount; ++outputIndex) + { + VariableLocation locationData; + stream->readInt(&locationData.arrayIndex); + stream->readInt(&locationData.index); + stream->readBool(&locationData.ignored); + mSecondaryOutputLocations.push_back(locationData); + } + + unsigned int defaultUniformRangeLow = stream->readInt(); + unsigned int defaultUniformRangeHigh = stream->readInt(); + mDefaultUniformRange = RangeUI(defaultUniformRangeLow, defaultUniformRangeHigh); + + unsigned int samplerRangeLow = stream->readInt(); + unsigned int samplerRangeHigh = stream->readInt(); + mSamplerUniformRange = RangeUI(samplerRangeLow, samplerRangeHigh); + + size_t samplerCount = stream->readInt(); + for (size_t samplerIndex = 0; samplerIndex < samplerCount; ++samplerIndex) + { + TextureType textureType = stream->readEnum(); + GLenum samplerType = stream->readInt(); + SamplerFormat format = stream->readEnum(); + size_t bindingCount = stream->readInt(); + mSamplerBindings.emplace_back(textureType, samplerType, format, bindingCount); + } + + unsigned int imageRangeLow = stream->readInt(); + unsigned int imageRangeHigh = stream->readInt(); + mImageUniformRange = RangeUI(imageRangeLow, imageRangeHigh); + + size_t imageBindingCount = stream->readInt(); + for (size_t imageIndex = 0; imageIndex < imageBindingCount; ++imageIndex) + { + size_t elementCount = stream->readInt(); + TextureType textureType = static_cast(stream->readInt()); + ImageBinding imageBinding(elementCount, textureType); + for (size_t elementIndex = 0; elementIndex < elementCount; ++elementIndex) + { + imageBinding.boundImageUnits[elementIndex] = stream->readInt(); + } + mImageBindings.emplace_back(imageBinding); + } + + unsigned int atomicCounterRangeLow = stream->readInt(); + unsigned int atomicCounterRangeHigh = stream->readInt(); + mAtomicCounterUniformRange = RangeUI(atomicCounterRangeLow, atomicCounterRangeHigh); + + // These values are currently only used by PPOs, so only load them when the program is marked + // separable to save memory. + if (isSeparable) + { + for (ShaderType shaderType : mLinkedShaderStages) + { + mLinkedOutputVaryings[shaderType].resize(stream->readInt()); + for (sh::ShaderVariable &variable : mLinkedOutputVaryings[shaderType]) + { + LoadShaderVar(stream, &variable); + } + mLinkedInputVaryings[shaderType].resize(stream->readInt()); + for (sh::ShaderVariable &variable : mLinkedInputVaryings[shaderType]) + { + LoadShaderVar(stream, &variable); + } + mLinkedUniforms[shaderType].resize(stream->readInt()); + for (sh::ShaderVariable &variable : mLinkedUniforms[shaderType]) + { + LoadShaderVar(stream, &variable); + } + mLinkedUniformBlocks[shaderType].resize(stream->readInt()); + for (sh::InterfaceBlock &shaderStorageBlock : mLinkedUniformBlocks[shaderType]) + { + LoadShInterfaceBlock(stream, &shaderStorageBlock); + } + mLinkedShaderVersions[shaderType] = stream->readInt(); + } + } +} + +void ProgramExecutable::save(bool isSeparable, gl::BinaryOutputStream *stream) const +{ + static_assert(MAX_VERTEX_ATTRIBS * 2 <= sizeof(uint32_t) * 8, + "All bits of mAttributesTypeMask types and mask fit into 32 bits each"); + stream->writeInt(static_cast(mAttributesTypeMask.to_ulong())); + stream->writeInt(static_cast(mAttributesMask.to_ulong())); + stream->writeInt(static_cast(mActiveAttribLocationsMask.to_ulong())); + stream->writeInt(mMaxActiveAttribLocation); + + stream->writeInt(mFragmentInoutRange.low()); + stream->writeInt(mFragmentInoutRange.high()); + + stream->writeBool(mHasDiscard); + stream->writeBool(mEnablesPerSampleShading); + stream->writeInt(mAdvancedBlendEquations.bits()); + + stream->writeInt(mLinkedShaderStages.bits()); + + ASSERT(mGeometryShaderInvocations >= 1 && mGeometryShaderMaxVertices >= 0); + stream->writeEnum(mGeometryShaderInputPrimitiveType); + stream->writeEnum(mGeometryShaderOutputPrimitiveType); + stream->writeInt(mGeometryShaderInvocations); + stream->writeInt(mGeometryShaderMaxVertices); + + stream->writeInt(mTessControlShaderVertices); + stream->writeInt(mTessGenMode); + stream->writeInt(mTessGenSpacing); + stream->writeInt(mTessGenVertexOrder); + stream->writeInt(mTessGenPointMode); + + stream->writeInt(getProgramInputs().size()); + for (const sh::ShaderVariable &attrib : getProgramInputs()) + { + WriteShaderVar(stream, attrib); + stream->writeInt(attrib.location); + } + + stream->writeInt(getUniforms().size()); + for (const LinkedUniform &uniform : getUniforms()) + { + WriteShaderVar(stream, uniform); + + stream->writeInt(uniform.bufferIndex); + WriteBlockMemberInfo(stream, uniform.blockInfo); + + stream->writeIntVector(uniform.outerArraySizes); + stream->writeInt(uniform.outerArrayOffset); + + // Active shader info + for (ShaderType shaderType : gl::AllShaderTypes()) + { + stream->writeBool(uniform.isActive(shaderType)); + } + } + + stream->writeInt(getUniformBlocks().size()); + for (const InterfaceBlock &uniformBlock : getUniformBlocks()) + { + WriteInterfaceBlock(stream, uniformBlock); + } + + stream->writeInt(getShaderStorageBlocks().size()); + for (const InterfaceBlock &shaderStorageBlock : getShaderStorageBlocks()) + { + WriteInterfaceBlock(stream, shaderStorageBlock); + } + + stream->writeInt(mAtomicCounterBuffers.size()); + for (const AtomicCounterBuffer &atomicCounterBuffer : getAtomicCounterBuffers()) + { + WriteShaderVariableBuffer(stream, atomicCounterBuffer); + } + + stream->writeInt(getLinkedTransformFeedbackVaryings().size()); + for (const auto &var : getLinkedTransformFeedbackVaryings()) + { + stream->writeIntVector(var.arraySizes); + stream->writeInt(var.type); + stream->writeString(var.name); + + stream->writeIntOrNegOne(var.arrayIndex); + } + + stream->writeInt(getTransformFeedbackBufferMode()); + + stream->writeInt(getOutputVariables().size()); + for (const sh::ShaderVariable &output : getOutputVariables()) + { + WriteShaderVar(stream, output); + stream->writeInt(output.location); + stream->writeInt(output.index); + } + + stream->writeInt(getOutputLocations().size()); + for (const auto &outputVar : getOutputLocations()) + { + stream->writeInt(outputVar.arrayIndex); + stream->writeIntOrNegOne(outputVar.index); + stream->writeBool(outputVar.ignored); + } + + stream->writeInt(static_cast(mActiveOutputVariablesMask.to_ulong())); + + stream->writeInt(mOutputVariableTypes.size()); + for (const auto &outputVariableType : mOutputVariableTypes) + { + stream->writeInt(outputVariableType); + } + + static_assert( + IMPLEMENTATION_MAX_DRAW_BUFFERS * 2 <= 8 * sizeof(uint32_t), + "All bits of mDrawBufferTypeMask and mActiveOutputVariables can be contained in 32 bits"); + stream->writeInt(static_cast(mDrawBufferTypeMask.to_ulong())); + + stream->writeBool(mYUVOutput); + + stream->writeInt(getSecondaryOutputLocations().size()); + for (const auto &outputVar : getSecondaryOutputLocations()) + { + stream->writeInt(outputVar.arrayIndex); + stream->writeIntOrNegOne(outputVar.index); + stream->writeBool(outputVar.ignored); + } + + stream->writeInt(getDefaultUniformRange().low()); + stream->writeInt(getDefaultUniformRange().high()); + + stream->writeInt(getSamplerUniformRange().low()); + stream->writeInt(getSamplerUniformRange().high()); + + stream->writeInt(getSamplerBindings().size()); + for (const auto &samplerBinding : getSamplerBindings()) + { + stream->writeEnum(samplerBinding.textureType); + stream->writeInt(samplerBinding.samplerType); + stream->writeEnum(samplerBinding.format); + stream->writeInt(samplerBinding.boundTextureUnits.size()); + } + + stream->writeInt(getImageUniformRange().low()); + stream->writeInt(getImageUniformRange().high()); + + stream->writeInt(getImageBindings().size()); + for (const auto &imageBinding : getImageBindings()) + { + stream->writeInt(imageBinding.boundImageUnits.size()); + stream->writeInt(static_cast(imageBinding.textureType)); + for (size_t i = 0; i < imageBinding.boundImageUnits.size(); ++i) + { + stream->writeInt(imageBinding.boundImageUnits[i]); + } + } + + stream->writeInt(getAtomicCounterUniformRange().low()); + stream->writeInt(getAtomicCounterUniformRange().high()); + + // These values are currently only used by PPOs, so only save them when the program is marked + // separable to save memory. + if (isSeparable) + { + for (ShaderType shaderType : mLinkedShaderStages) + { + stream->writeInt(mLinkedOutputVaryings[shaderType].size()); + for (const sh::ShaderVariable &shaderVariable : mLinkedOutputVaryings[shaderType]) + { + WriteShaderVar(stream, shaderVariable); + } + stream->writeInt(mLinkedInputVaryings[shaderType].size()); + for (const sh::ShaderVariable &shaderVariable : mLinkedInputVaryings[shaderType]) + { + WriteShaderVar(stream, shaderVariable); + } + stream->writeInt(mLinkedUniforms[shaderType].size()); + for (const sh::ShaderVariable &shaderVariable : mLinkedUniforms[shaderType]) + { + WriteShaderVar(stream, shaderVariable); + } + stream->writeInt(mLinkedUniformBlocks[shaderType].size()); + for (const sh::InterfaceBlock &shaderStorageBlock : mLinkedUniformBlocks[shaderType]) + { + WriteShInterfaceBlock(stream, shaderStorageBlock); + } + stream->writeInt(mLinkedShaderVersions[shaderType]); + } + } +} + +int ProgramExecutable::getInfoLogLength() const +{ + return static_cast(mInfoLog.getLength()); +} + +void ProgramExecutable::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const +{ + return mInfoLog.getLog(bufSize, length, infoLog); +} + +std::string ProgramExecutable::getInfoLogString() const +{ + return mInfoLog.str(); +} + +bool ProgramExecutable::isAttribLocationActive(size_t attribLocation) const +{ + ASSERT(attribLocation < mActiveAttribLocationsMask.size()); + return mActiveAttribLocationsMask[attribLocation]; +} + +AttributesMask ProgramExecutable::getAttributesMask() const +{ + return mAttributesMask; +} + +bool ProgramExecutable::hasDefaultUniforms() const +{ + return !getDefaultUniformRange().empty(); +} + +bool ProgramExecutable::hasTextures() const +{ + return !getSamplerBindings().empty(); +} + +bool ProgramExecutable::hasUniformBuffers() const +{ + return !mUniformBlocks.empty(); +} + +bool ProgramExecutable::hasStorageBuffers() const +{ + return !mShaderStorageBlocks.empty(); +} + +bool ProgramExecutable::hasAtomicCounterBuffers() const +{ + return !mAtomicCounterBuffers.empty(); +} + +bool ProgramExecutable::hasImages() const +{ + return !mImageBindings.empty(); +} + +bool ProgramExecutable::usesFramebufferFetch() const +{ + return (mFragmentInoutRange.length() > 0); +} + +GLuint ProgramExecutable::getUniformIndexFromImageIndex(GLuint imageIndex) const +{ + ASSERT(imageIndex < mImageUniformRange.length()); + return imageIndex + mImageUniformRange.low(); +} + +GLuint ProgramExecutable::getUniformIndexFromSamplerIndex(GLuint samplerIndex) const +{ + ASSERT(samplerIndex < mSamplerUniformRange.length()); + return samplerIndex + mSamplerUniformRange.low(); +} + +void ProgramExecutable::setActive(size_t textureUnit, + const SamplerBinding &samplerBinding, + const gl::LinkedUniform &samplerUniform) +{ + mActiveSamplersMask.set(textureUnit); + mActiveSamplerTypes[textureUnit] = samplerBinding.textureType; + mActiveSamplerYUV[textureUnit] = IsSamplerYUVType(samplerBinding.samplerType); + mActiveSamplerFormats[textureUnit] = samplerBinding.format; + mActiveSamplerShaderBits[textureUnit] = samplerUniform.activeShaders(); +} + +void ProgramExecutable::setInactive(size_t textureUnit) +{ + mActiveSamplersMask.reset(textureUnit); + mActiveSamplerTypes[textureUnit] = TextureType::InvalidEnum; + mActiveSamplerYUV.reset(textureUnit); + mActiveSamplerFormats[textureUnit] = SamplerFormat::InvalidEnum; + mActiveSamplerShaderBits[textureUnit].reset(); +} + +void ProgramExecutable::hasSamplerTypeConflict(size_t textureUnit) +{ + // Conflicts are marked with InvalidEnum + mActiveSamplerYUV.reset(textureUnit); + mActiveSamplerTypes[textureUnit] = TextureType::InvalidEnum; +} + +void ProgramExecutable::hasSamplerFormatConflict(size_t textureUnit) +{ + // Conflicts are marked with InvalidEnum + mActiveSamplerFormats[textureUnit] = SamplerFormat::InvalidEnum; +} + +void ProgramExecutable::updateActiveSamplers(const ProgramState &programState) +{ + const std::vector &samplerBindings = programState.getSamplerBindings(); + + for (uint32_t samplerIndex = 0; samplerIndex < samplerBindings.size(); ++samplerIndex) + { + const SamplerBinding &samplerBinding = samplerBindings[samplerIndex]; + + for (GLint textureUnit : samplerBinding.boundTextureUnits) + { + if (++mActiveSamplerRefCounts[textureUnit] == 1) + { + uint32_t uniformIndex = programState.getUniformIndexFromSamplerIndex(samplerIndex); + setActive(textureUnit, samplerBinding, programState.getUniforms()[uniformIndex]); + } + else + { + if (mActiveSamplerTypes[textureUnit] != samplerBinding.textureType || + mActiveSamplerYUV.test(textureUnit) != + IsSamplerYUVType(samplerBinding.samplerType)) + { + hasSamplerTypeConflict(textureUnit); + } + + if (mActiveSamplerFormats[textureUnit] != samplerBinding.format) + { + hasSamplerFormatConflict(textureUnit); + } + } + mActiveSamplersMask.set(textureUnit); + } + } + + // Invalidate the validation cache. + resetCachedValidateSamplersResult(); +} + +void ProgramExecutable::updateActiveImages(const ProgramExecutable &executable) +{ + const std::vector &imageBindings = executable.getImageBindings(); + for (uint32_t imageIndex = 0; imageIndex < imageBindings.size(); ++imageIndex) + { + const gl::ImageBinding &imageBinding = imageBindings.at(imageIndex); + + uint32_t uniformIndex = executable.getUniformIndexFromImageIndex(imageIndex); + const gl::LinkedUniform &imageUniform = executable.getUniforms()[uniformIndex]; + const ShaderBitSet shaderBits = imageUniform.activeShaders(); + for (GLint imageUnit : imageBinding.boundImageUnits) + { + mActiveImagesMask.set(imageUnit); + mActiveImageShaderBits[imageUnit] |= shaderBits; + } + } +} + +void ProgramExecutable::setSamplerUniformTextureTypeAndFormat( + size_t textureUnitIndex, + std::vector &samplerBindings) +{ + bool foundBinding = false; + TextureType foundType = TextureType::InvalidEnum; + bool foundYUV = false; + SamplerFormat foundFormat = SamplerFormat::InvalidEnum; + + for (uint32_t samplerIndex = 0; samplerIndex < samplerBindings.size(); ++samplerIndex) + { + const SamplerBinding &binding = samplerBindings[samplerIndex]; + + // A conflict exists if samplers of different types are sourced by the same texture unit. + // We need to check all bound textures to detect this error case. + for (GLuint textureUnit : binding.boundTextureUnits) + { + if (textureUnit != textureUnitIndex) + { + continue; + } + + if (!foundBinding) + { + foundBinding = true; + foundType = binding.textureType; + foundYUV = IsSamplerYUVType(binding.samplerType); + foundFormat = binding.format; + uint32_t uniformIndex = getUniformIndexFromSamplerIndex(samplerIndex); + setActive(textureUnit, binding, mUniforms[uniformIndex]); + } + else + { + if (foundType != binding.textureType || + foundYUV != IsSamplerYUVType(binding.samplerType)) + { + hasSamplerTypeConflict(textureUnit); + } + + if (foundFormat != binding.format) + { + hasSamplerFormatConflict(textureUnit); + } + } + } + } +} + +void ProgramExecutable::updateCanDrawWith() +{ + mCanDrawWith = hasLinkedShaderStage(ShaderType::Vertex); +} + +void ProgramExecutable::saveLinkedStateInfo(const Context *context, const ProgramState &state) +{ + for (ShaderType shaderType : getLinkedShaderStages()) + { + Shader *shader = state.getAttachedShader(shaderType); + ASSERT(shader); + mLinkedOutputVaryings[shaderType] = shader->getOutputVaryings(context); + mLinkedInputVaryings[shaderType] = shader->getInputVaryings(context); + mLinkedShaderVersions[shaderType] = shader->getShaderVersion(context); + mLinkedUniforms[shaderType] = shader->getUniforms(context); + mLinkedUniformBlocks[shaderType] = shader->getUniformBlocks(context); + } +} + +bool ProgramExecutable::isYUVOutput() const +{ + return mYUVOutput; +} + +ShaderType ProgramExecutable::getLinkedTransformFeedbackStage() const +{ + return GetLastPreFragmentStage(mLinkedShaderStages); +} + +bool ProgramExecutable::linkMergedVaryings( + const Context *context, + const ProgramMergedVaryings &mergedVaryings, + const std::vector &transformFeedbackVaryingNames, + const LinkingVariables &linkingVariables, + bool isSeparable, + ProgramVaryingPacking *varyingPacking) +{ + ShaderType tfStage = GetLastPreFragmentStage(linkingVariables.isShaderStageUsedBitset); + + if (!linkValidateTransformFeedback(context, mergedVaryings, tfStage, + transformFeedbackVaryingNames)) + { + return false; + } + + // Map the varyings to the register file + // In WebGL, we use a slightly different handling for packing variables. + gl::PackMode packMode = PackMode::ANGLE_RELAXED; + if (context->getLimitations().noFlexibleVaryingPacking) + { + // D3D9 pack mode is strictly more strict than WebGL, so takes priority. + packMode = PackMode::ANGLE_NON_CONFORMANT_D3D9; + } + else if (context->isWebGL()) + { + packMode = PackMode::WEBGL_STRICT; + } + + // Build active shader stage map. + ShaderBitSet activeShadersMask; + for (ShaderType shaderType : kAllGraphicsShaderTypes) + { + // - Check for attached shaders to handle the case of a Program linking the currently + // attached shaders. + // - Check for linked shaders to handle the case of a PPO linking separable programs before + // drawing. + if (linkingVariables.isShaderStageUsedBitset[shaderType] || + getLinkedShaderStages().test(shaderType)) + { + activeShadersMask[shaderType] = true; + } + } + + if (!varyingPacking->collectAndPackUserVaryings(mInfoLog, context->getCaps(), packMode, + activeShadersMask, mergedVaryings, + transformFeedbackVaryingNames, isSeparable)) + { + return false; + } + + gatherTransformFeedbackVaryings(mergedVaryings, tfStage, transformFeedbackVaryingNames); + updateTransformFeedbackStrides(); + + return true; +} + +bool ProgramExecutable::linkValidateTransformFeedback( + const Context *context, + const ProgramMergedVaryings &varyings, + ShaderType stage, + const std::vector &transformFeedbackVaryingNames) +{ + const Version &version = context->getClientVersion(); + + // Validate the tf names regardless of the actual program varyings. + std::set uniqueNames; + for (const std::string &tfVaryingName : transformFeedbackVaryingNames) + { + if (version < Version(3, 1) && tfVaryingName.find('[') != std::string::npos) + { + mInfoLog << "Capture of array elements is undefined and not supported."; + return false; + } + if (version >= Version(3, 1)) + { + if (IncludeSameArrayElement(uniqueNames, tfVaryingName)) + { + mInfoLog << "Two transform feedback varyings include the same array element (" + << tfVaryingName << ")."; + return false; + } + } + else + { + if (uniqueNames.count(tfVaryingName) > 0) + { + mInfoLog << "Two transform feedback varyings specify the same output variable (" + << tfVaryingName << ")."; + return false; + } + } + uniqueNames.insert(tfVaryingName); + } + + // From OpneGLES spec. 11.1.2.1: A program will fail to link if: + // the count specified by TransformFeedbackVaryings is non-zero, but the + // program object has no vertex, tessellation evaluation, or geometry shader + if (transformFeedbackVaryingNames.size() > 0 && + !gl::ShaderTypeSupportsTransformFeedback(getLinkedTransformFeedbackStage())) + { + mInfoLog << "Linked transform feedback stage " << getLinkedTransformFeedbackStage() + << " does not support transform feedback varying."; + return false; + } + + // Validate against program varyings. + size_t totalComponents = 0; + for (const std::string &tfVaryingName : transformFeedbackVaryingNames) + { + std::vector subscripts; + std::string baseName = ParseResourceName(tfVaryingName, &subscripts); + + const sh::ShaderVariable *var = FindOutputVaryingOrField(varyings, stage, baseName); + if (var == nullptr) + { + mInfoLog << "Transform feedback varying " << tfVaryingName + << " does not exist in the vertex shader."; + return false; + } + + // Validate the matching variable. + if (var->isStruct()) + { + mInfoLog << "Struct cannot be captured directly (" << baseName << ")."; + return false; + } + + size_t elementCount = 0; + size_t componentCount = 0; + + if (var->isArray()) + { + if (version < Version(3, 1)) + { + mInfoLog << "Capture of arrays is undefined and not supported."; + return false; + } + + // GLSL ES 3.10 section 4.3.6: A vertex output can't be an array of arrays. + ASSERT(!var->isArrayOfArrays()); + + if (!subscripts.empty() && subscripts[0] >= var->getOutermostArraySize()) + { + mInfoLog << "Cannot capture outbound array element '" << tfVaryingName << "'."; + return false; + } + elementCount = (subscripts.empty() ? var->getOutermostArraySize() : 1); + } + else + { + if (!subscripts.empty()) + { + mInfoLog << "Varying '" << baseName + << "' is not an array to be captured by element."; + return false; + } + elementCount = 1; + } + + const Caps &caps = context->getCaps(); + + // TODO(jmadill): Investigate implementation limits on D3D11 + componentCount = VariableComponentCount(var->type) * elementCount; + if (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS && + componentCount > static_cast(caps.maxTransformFeedbackSeparateComponents)) + { + mInfoLog << "Transform feedback varying " << tfVaryingName << " components (" + << componentCount << ") exceed the maximum separate components (" + << caps.maxTransformFeedbackSeparateComponents << ")."; + return false; + } + + totalComponents += componentCount; + if (mTransformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS && + totalComponents > static_cast(caps.maxTransformFeedbackInterleavedComponents)) + { + mInfoLog << "Transform feedback varying total components (" << totalComponents + << ") exceed the maximum interleaved components (" + << caps.maxTransformFeedbackInterleavedComponents << ")."; + return false; + } + } + return true; +} + +void ProgramExecutable::gatherTransformFeedbackVaryings( + const ProgramMergedVaryings &varyings, + ShaderType stage, + const std::vector &transformFeedbackVaryingNames) +{ + // Gather the linked varyings that are used for transform feedback, they should all exist. + mLinkedTransformFeedbackVaryings.clear(); + for (const std::string &tfVaryingName : transformFeedbackVaryingNames) + { + std::vector subscripts; + std::string baseName = ParseResourceName(tfVaryingName, &subscripts); + size_t subscript = GL_INVALID_INDEX; + if (!subscripts.empty()) + { + subscript = subscripts.back(); + } + for (const ProgramVaryingRef &ref : varyings) + { + if (ref.frontShaderStage != stage) + { + continue; + } + + const sh::ShaderVariable *varying = ref.get(stage); + if (baseName == varying->name) + { + mLinkedTransformFeedbackVaryings.emplace_back(*varying, + static_cast(subscript)); + break; + } + else if (varying->isStruct()) + { + GLuint fieldIndex = 0; + const auto *field = varying->findField(tfVaryingName, &fieldIndex); + if (field != nullptr) + { + mLinkedTransformFeedbackVaryings.emplace_back(*field, *varying); + break; + } + } + } + } +} + +void ProgramExecutable::updateTransformFeedbackStrides() +{ + if (mLinkedTransformFeedbackVaryings.empty()) + { + return; + } + + if (mTransformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS) + { + mTransformFeedbackStrides.resize(1); + size_t totalSize = 0; + for (const TransformFeedbackVarying &varying : mLinkedTransformFeedbackVaryings) + { + totalSize += varying.size() * VariableExternalSize(varying.type); + } + mTransformFeedbackStrides[0] = static_cast(totalSize); + } + else + { + mTransformFeedbackStrides.resize(mLinkedTransformFeedbackVaryings.size()); + for (size_t i = 0; i < mLinkedTransformFeedbackVaryings.size(); i++) + { + TransformFeedbackVarying &varying = mLinkedTransformFeedbackVaryings[i]; + mTransformFeedbackStrides[i] = + static_cast(varying.size() * VariableExternalSize(varying.type)); + } + } +} + +bool ProgramExecutable::validateSamplersImpl(InfoLog *infoLog, const Caps &caps) const +{ + // if any two active samplers in a program are of different types, but refer to the same + // texture image unit, and this is the current program, then ValidateProgram will fail, and + // DrawArrays and DrawElements will issue the INVALID_OPERATION error. + for (size_t textureUnit : mActiveSamplersMask) + { + if (mActiveSamplerTypes[textureUnit] == TextureType::InvalidEnum) + { + if (infoLog) + { + (*infoLog) << "Samplers of conflicting types refer to the same texture " + "image unit (" + << textureUnit << ")."; + } + + mCachedValidateSamplersResult = false; + return false; + } + + if (mActiveSamplerFormats[textureUnit] == SamplerFormat::InvalidEnum) + { + if (infoLog) + { + (*infoLog) << "Samplers of conflicting formats refer to the same texture " + "image unit (" + << textureUnit << ")."; + } + + mCachedValidateSamplersResult = false; + return false; + } + } + + mCachedValidateSamplersResult = true; + return true; +} + +bool ProgramExecutable::linkValidateOutputVariables( + const Caps &caps, + const Extensions &extensions, + const Version &version, + GLuint combinedImageUniformsCount, + GLuint combinedShaderStorageBlocksCount, + const std::vector &outputVariables, + int fragmentShaderVersion, + const ProgramAliasedBindings &fragmentOutputLocations, + const ProgramAliasedBindings &fragmentOutputIndices) +{ + ASSERT(mOutputVariableTypes.empty()); + ASSERT(mActiveOutputVariablesMask.none()); + ASSERT(mDrawBufferTypeMask.none()); + ASSERT(!mYUVOutput); + + // Gather output variable types + for (const sh::ShaderVariable &outputVariable : outputVariables) + { + if (outputVariable.isBuiltIn() && outputVariable.name != "gl_FragColor" && + outputVariable.name != "gl_FragData") + { + continue; + } + + unsigned int baseLocation = + (outputVariable.location == -1 ? 0u + : static_cast(outputVariable.location)); + + // GLSL ES 3.10 section 4.3.6: Output variables cannot be arrays of arrays or arrays of + // structures, so we may use getBasicTypeElementCount(). + unsigned int elementCount = outputVariable.getBasicTypeElementCount(); + for (unsigned int elementIndex = 0; elementIndex < elementCount; elementIndex++) + { + const unsigned int location = baseLocation + elementIndex; + if (location >= mOutputVariableTypes.size()) + { + mOutputVariableTypes.resize(location + 1, GL_NONE); + } + ASSERT(location < mActiveOutputVariablesMask.size()); + mActiveOutputVariablesMask.set(location); + mOutputVariableTypes[location] = VariableComponentType(outputVariable.type); + ComponentType componentType = GLenumToComponentType(mOutputVariableTypes[location]); + SetComponentTypeMask(componentType, location, &mDrawBufferTypeMask); + } + + if (outputVariable.yuv) + { + ASSERT(outputVariables.size() == 1); + mYUVOutput = true; + } + } + + if (version >= ES_3_1) + { + // [OpenGL ES 3.1] Chapter 8.22 Page 203: + // A link error will be generated if the sum of the number of active image uniforms used in + // all shaders, the number of active shader storage blocks, and the number of active + // fragment shader outputs exceeds the implementation-dependent value of + // MAX_COMBINED_SHADER_OUTPUT_RESOURCES. + if (combinedImageUniformsCount + combinedShaderStorageBlocksCount + + mActiveOutputVariablesMask.count() > + static_cast(caps.maxCombinedShaderOutputResources)) + { + mInfoLog + << "The sum of the number of active image uniforms, active shader storage blocks " + "and active fragment shader outputs exceeds " + "MAX_COMBINED_SHADER_OUTPUT_RESOURCES (" + << caps.maxCombinedShaderOutputResources << ")"; + return false; + } + } + + mOutputVariables = outputVariables; + + if (fragmentShaderVersion == 100) + { + return true; + } + + // EXT_blend_func_extended doesn't specify anything related to binding specific elements of an + // output array in explicit terms. + // + // Assuming fragData is an output array, you can defend the position that: + // P1) you must support binding "fragData" because it's specified + // P2) you must support querying "fragData[x]" because it's specified + // P3) you must support binding "fragData[0]" because it's a frequently used pattern + // + // Then you can make the leap of faith: + // P4) you must support binding "fragData[x]" because you support "fragData[0]" + // P5) you must support binding "fragData[x]" because you support querying "fragData[x]" + // + // The spec brings in the "world of arrays" when it mentions binding the arrays and the + // automatic binding. Thus it must be interpreted that the thing is not undefined, rather you + // must infer the only possible interpretation (?). Note again: this need of interpretation + // might be completely off of what GL spec logic is. + // + // The other complexity is that unless you implement this feature, it's hard to understand what + // should happen when the client invokes the feature. You cannot add an additional error as it + // is not specified. One can ignore it, but obviously it creates the discrepancies... + + std::vector reservedLocations; + + // Process any output API bindings for arrays that don't alias to the first element. + for (const auto &bindingPair : fragmentOutputLocations) + { + const std::string &name = bindingPair.first; + const ProgramBinding &binding = bindingPair.second; + + size_t nameLengthWithoutArrayIndex; + unsigned int arrayIndex = ParseArrayIndex(name, &nameLengthWithoutArrayIndex); + if (arrayIndex == 0 || arrayIndex == GL_INVALID_INDEX) + { + continue; + } + for (unsigned int outputVariableIndex = 0; outputVariableIndex < mOutputVariables.size(); + outputVariableIndex++) + { + const sh::ShaderVariable &outputVariable = mOutputVariables[outputVariableIndex]; + // Check that the binding corresponds to an output array and its array index fits. + if (outputVariable.isBuiltIn() || !outputVariable.isArray() || + !angle::BeginsWith(outputVariable.name, name, nameLengthWithoutArrayIndex) || + arrayIndex >= outputVariable.getOutermostArraySize()) + { + continue; + } + + // Get the API index that corresponds to this exact binding. + // This index may differ from the index used for the array's base. + std::vector &outputLocations = + fragmentOutputIndices.getBindingByName(name) == 1 ? mSecondaryOutputLocations + : mOutputLocations; + unsigned int location = binding.location; + VariableLocation locationInfo(arrayIndex, outputVariableIndex); + if (location >= outputLocations.size()) + { + outputLocations.resize(location + 1); + } + if (outputLocations[location].used()) + { + mInfoLog << "Location of variable " << outputVariable.name + << " conflicts with another variable."; + return false; + } + outputLocations[location] = locationInfo; + + // Note the array binding location so that it can be skipped later. + reservedLocations.push_back(locationInfo); + } + } + + // Reserve locations for output variables whose location is fixed in the shader or through the + // API. Otherwise, the remaining unallocated outputs will be processed later. + for (unsigned int outputVariableIndex = 0; outputVariableIndex < mOutputVariables.size(); + outputVariableIndex++) + { + const sh::ShaderVariable &outputVariable = mOutputVariables[outputVariableIndex]; + + // Don't store outputs for gl_FragDepth, gl_FragColor, etc. + if (outputVariable.isBuiltIn()) + continue; + + int fixedLocation = GetOutputLocationForLink(fragmentOutputLocations, outputVariable); + if (fixedLocation == -1) + { + // Here we're only reserving locations for variables whose location is fixed. + continue; + } + unsigned int baseLocation = static_cast(fixedLocation); + + std::vector &outputLocations = + IsOutputSecondaryForLink(fragmentOutputIndices, outputVariable) + ? mSecondaryOutputLocations + : mOutputLocations; + + // GLSL ES 3.10 section 4.3.6: Output variables cannot be arrays of arrays or arrays of + // structures, so we may use getBasicTypeElementCount(). + unsigned int elementCount = outputVariable.getBasicTypeElementCount(); + if (FindUsedOutputLocation(outputLocations, baseLocation, elementCount, reservedLocations, + outputVariableIndex)) + { + mInfoLog << "Location of variable " << outputVariable.name + << " conflicts with another variable."; + return false; + } + AssignOutputLocations(outputLocations, baseLocation, elementCount, reservedLocations, + outputVariableIndex, mOutputVariables[outputVariableIndex]); + } + + // Here we assign locations for the output variables that don't yet have them. Note that we're + // not necessarily able to fit the variables optimally, since then we might have to try + // different arrangements of output arrays. Now we just assign the locations in the order that + // we got the output variables. The spec isn't clear on what kind of algorithm is required for + // finding locations for the output variables, so this should be acceptable at least for now. + GLuint maxLocation = static_cast(caps.maxDrawBuffers); + if (!mSecondaryOutputLocations.empty()) + { + // EXT_blend_func_extended: Program outputs will be validated against + // MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT if there's even one output with index one. + maxLocation = caps.maxDualSourceDrawBuffers; + } + + for (unsigned int outputVariableIndex = 0; outputVariableIndex < mOutputVariables.size(); + outputVariableIndex++) + { + const sh::ShaderVariable &outputVariable = mOutputVariables[outputVariableIndex]; + + // Don't store outputs for gl_FragDepth, gl_FragColor, etc. + if (outputVariable.isBuiltIn()) + continue; + + int fixedLocation = GetOutputLocationForLink(fragmentOutputLocations, outputVariable); + std::vector &outputLocations = + IsOutputSecondaryForLink(fragmentOutputIndices, outputVariable) + ? mSecondaryOutputLocations + : mOutputLocations; + unsigned int baseLocation = 0; + unsigned int elementCount = outputVariable.getBasicTypeElementCount(); + if (fixedLocation != -1) + { + // Secondary inputs might have caused the max location to drop below what has already + // been explicitly assigned locations. Check for any fixed locations above the max + // that should cause linking to fail. + baseLocation = static_cast(fixedLocation); + } + else + { + // No fixed location, so try to fit the output in unassigned locations. + // Try baseLocations starting from 0 one at a time and see if the variable fits. + while (FindUsedOutputLocation(outputLocations, baseLocation, elementCount, + reservedLocations, outputVariableIndex)) + { + baseLocation++; + } + AssignOutputLocations(outputLocations, baseLocation, elementCount, reservedLocations, + outputVariableIndex, mOutputVariables[outputVariableIndex]); + } + + // Check for any elements assigned above the max location that are actually used. + if (baseLocation + elementCount > maxLocation && + (baseLocation >= maxLocation || + FindUsedOutputLocation(outputLocations, maxLocation, + baseLocation + elementCount - maxLocation, reservedLocations, + outputVariableIndex))) + { + // EXT_blend_func_extended: Linking can fail: + // "if the explicit binding assignments do not leave enough space for the linker to + // automatically assign a location for a varying out array, which requires multiple + // contiguous locations." + mInfoLog << "Could not fit output variable into available locations: " + << outputVariable.name; + return false; + } + } + + return true; +} + +bool ProgramExecutable::linkUniforms( + const Context *context, + const ShaderMap> &shaderUniforms, + InfoLog &infoLog, + const ProgramAliasedBindings &uniformLocationBindings, + GLuint *combinedImageUniformsCountOut, + std::vector *unusedUniformsOutOrNull, + std::vector *uniformLocationsOutOrNull) +{ + UniformLinker linker(mLinkedShaderStages, shaderUniforms); + if (!linker.link(context->getCaps(), infoLog, uniformLocationBindings)) + { + return false; + } + + linker.getResults(&mUniforms, unusedUniformsOutOrNull, uniformLocationsOutOrNull); + + linkSamplerAndImageBindings(combinedImageUniformsCountOut); + + if (!linkAtomicCounterBuffers(context, infoLog)) + { + return false; + } + + return true; +} + +void ProgramExecutable::linkSamplerAndImageBindings(GLuint *combinedImageUniforms) +{ + ASSERT(combinedImageUniforms); + + // Iterate over mExecutable->mUniforms from the back, and find the range of subpass inputs, + // atomic counters, images and samplers in that order. + auto highIter = mUniforms.rbegin(); + auto lowIter = highIter; + + unsigned int high = static_cast(mUniforms.size()); + unsigned int low = high; + + // Note that uniform block uniforms are not yet appended to this list. + ASSERT(mUniforms.empty() || highIter->isAtomicCounter() || highIter->isImage() || + highIter->isSampler() || highIter->isInDefaultBlock() || highIter->isFragmentInOut); + + for (; lowIter != mUniforms.rend() && lowIter->isFragmentInOut; ++lowIter) + { + --low; + } + + mFragmentInoutRange = RangeUI(low, high); + + highIter = lowIter; + high = low; + + for (; lowIter != mUniforms.rend() && lowIter->isAtomicCounter(); ++lowIter) + { + --low; + } + + mAtomicCounterUniformRange = RangeUI(low, high); + + highIter = lowIter; + high = low; + + for (; lowIter != mUniforms.rend() && lowIter->isImage(); ++lowIter) + { + --low; + } + + mImageUniformRange = RangeUI(low, high); + *combinedImageUniforms = 0u; + // If uniform is a image type, insert it into the mImageBindings array. + for (unsigned int imageIndex : mImageUniformRange) + { + // ES3.1 (section 7.6.1) and GLSL ES3.1 (section 4.4.5), Uniform*i{v} commands + // cannot load values into a uniform defined as an image. if declare without a + // binding qualifier, any uniform image variable (include all elements of + // unbound image array) should be bound to unit zero. + auto &imageUniform = mUniforms[imageIndex]; + TextureType textureType = ImageTypeToTextureType(imageUniform.type); + const GLuint arraySize = imageUniform.isArray() ? imageUniform.arraySizes[0] : 1u; + + if (imageUniform.binding == -1) + { + mImageBindings.emplace_back( + ImageBinding(imageUniform.getBasicTypeElementCount(), textureType)); + } + else + { + // The arrays of arrays are flattened to arrays, it needs to record the array offset for + // the correct binding image unit. + mImageBindings.emplace_back( + ImageBinding(imageUniform.binding + imageUniform.parentArrayIndex() * arraySize, + imageUniform.getBasicTypeElementCount(), textureType)); + } + + *combinedImageUniforms += imageUniform.activeShaderCount() * arraySize; + } + + highIter = lowIter; + high = low; + + for (; lowIter != mUniforms.rend() && lowIter->isSampler(); ++lowIter) + { + --low; + } + + mSamplerUniformRange = RangeUI(low, high); + + // If uniform is a sampler type, insert it into the mSamplerBindings array. + for (unsigned int samplerIndex : mSamplerUniformRange) + { + const auto &samplerUniform = mUniforms[samplerIndex]; + TextureType textureType = SamplerTypeToTextureType(samplerUniform.type); + GLenum samplerType = samplerUniform.typeInfo->type; + unsigned int elementCount = samplerUniform.getBasicTypeElementCount(); + SamplerFormat format = samplerUniform.typeInfo->samplerFormat; + mSamplerBindings.emplace_back(textureType, samplerType, format, elementCount); + } + + // Whatever is left constitutes the default uniforms. + mDefaultUniformRange = RangeUI(0, low); +} + +bool ProgramExecutable::linkAtomicCounterBuffers(const Context *context, InfoLog &infoLog) +{ + for (unsigned int index : mAtomicCounterUniformRange) + { + auto &uniform = mUniforms[index]; + uniform.blockInfo.offset = uniform.offset; + uniform.blockInfo.arrayStride = (uniform.isArray() ? 4 : 0); + uniform.blockInfo.matrixStride = 0; + uniform.blockInfo.isRowMajorMatrix = false; + + bool found = false; + for (unsigned int bufferIndex = 0; bufferIndex < getActiveAtomicCounterBufferCount(); + ++bufferIndex) + { + auto &buffer = mAtomicCounterBuffers[bufferIndex]; + if (buffer.binding == uniform.binding) + { + buffer.memberIndexes.push_back(index); + uniform.bufferIndex = bufferIndex; + found = true; + buffer.unionReferencesWith(uniform); + break; + } + } + if (!found) + { + AtomicCounterBuffer atomicCounterBuffer; + atomicCounterBuffer.binding = uniform.binding; + atomicCounterBuffer.memberIndexes.push_back(index); + atomicCounterBuffer.unionReferencesWith(uniform); + mAtomicCounterBuffers.push_back(atomicCounterBuffer); + uniform.bufferIndex = static_cast(getActiveAtomicCounterBufferCount() - 1); + } + } + + // Count each atomic counter buffer to validate against + // per-stage and combined gl_Max*AtomicCounterBuffers. + GLint combinedShaderACBCount = 0; + gl::ShaderMap perShaderACBCount = {}; + for (unsigned int bufferIndex = 0; bufferIndex < getActiveAtomicCounterBufferCount(); + ++bufferIndex) + { + AtomicCounterBuffer &acb = mAtomicCounterBuffers[bufferIndex]; + const ShaderBitSet shaderStages = acb.activeShaders(); + for (gl::ShaderType shaderType : shaderStages) + { + ++perShaderACBCount[shaderType]; + } + ++combinedShaderACBCount; + } + const Caps &caps = context->getCaps(); + if (combinedShaderACBCount > caps.maxCombinedAtomicCounterBuffers) + { + infoLog << " combined AtomicCounterBuffers count exceeds limit"; + return false; + } + for (gl::ShaderType stage : gl::AllShaderTypes()) + { + if (perShaderACBCount[stage] > caps.maxShaderAtomicCounterBuffers[stage]) + { + infoLog << GetShaderTypeString(stage) + << " shader AtomicCounterBuffers count exceeds limit"; + return false; + } + } + return true; +} + +void ProgramExecutable::copyInputsFromProgram(const ProgramState &programState) +{ + mProgramInputs = programState.getProgramInputs(); +} + +void ProgramExecutable::copyShaderBuffersFromProgram(const ProgramState &programState, + ShaderType shaderType) +{ + AppendActiveBlocks(shaderType, programState.getUniformBlocks(), mUniformBlocks); + AppendActiveBlocks(shaderType, programState.getShaderStorageBlocks(), mShaderStorageBlocks); + AppendActiveBlocks(shaderType, programState.getAtomicCounterBuffers(), mAtomicCounterBuffers); +} + +void ProgramExecutable::clearSamplerBindings() +{ + mSamplerBindings.clear(); +} + +void ProgramExecutable::copySamplerBindingsFromProgram(const ProgramState &programState) +{ + const std::vector &bindings = programState.getSamplerBindings(); + mSamplerBindings.insert(mSamplerBindings.end(), bindings.begin(), bindings.end()); +} + +void ProgramExecutable::copyImageBindingsFromProgram(const ProgramState &programState) +{ + const std::vector &bindings = programState.getImageBindings(); + mImageBindings.insert(mImageBindings.end(), bindings.begin(), bindings.end()); +} + +void ProgramExecutable::copyOutputsFromProgram(const ProgramState &programState) +{ + mOutputVariables = programState.getOutputVariables(); + mOutputLocations = programState.getOutputLocations(); + mSecondaryOutputLocations = programState.getSecondaryOutputLocations(); +} + +void ProgramExecutable::copyUniformsFromProgramMap(const ShaderMap &programs) +{ + // Merge default uniforms. + auto getDefaultRange = [](const ProgramState &state) { return state.getDefaultUniformRange(); }; + mDefaultUniformRange = AddUniforms(programs, mLinkedShaderStages, mUniforms, getDefaultRange); + + // Merge sampler uniforms. + auto getSamplerRange = [](const ProgramState &state) { return state.getSamplerUniformRange(); }; + mSamplerUniformRange = AddUniforms(programs, mLinkedShaderStages, mUniforms, getSamplerRange); + + // Merge image uniforms. + auto getImageRange = [](const ProgramState &state) { return state.getImageUniformRange(); }; + mImageUniformRange = AddUniforms(programs, mLinkedShaderStages, mUniforms, getImageRange); + + // Merge atomic counter uniforms. + auto getAtomicRange = [](const ProgramState &state) { + return state.getAtomicCounterUniformRange(); + }; + mAtomicCounterUniformRange = + AddUniforms(programs, mLinkedShaderStages, mUniforms, getAtomicRange); + + // Merge fragment in/out uniforms. + auto getInoutRange = [](const ProgramState &state) { return state.getFragmentInoutRange(); }; + mFragmentInoutRange = AddUniforms(programs, mLinkedShaderStages, mUniforms, getInoutRange); +} +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/ProgramExecutable.h b/gfx/angle/checkout/src/libANGLE/ProgramExecutable.h new file mode 100644 index 0000000000..4344ef4b5a --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/ProgramExecutable.h @@ -0,0 +1,517 @@ +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ProgramExecutable.h: Collects the information and interfaces common to both Programs and +// ProgramPipelines in order to execute/draw with either. + +#ifndef LIBANGLE_PROGRAMEXECUTABLE_H_ +#define LIBANGLE_PROGRAMEXECUTABLE_H_ + +#include "BinaryStream.h" +#include "libANGLE/Caps.h" +#include "libANGLE/InfoLog.h" +#include "libANGLE/ProgramLinkedResources.h" +#include "libANGLE/Shader.h" +#include "libANGLE/Uniform.h" +#include "libANGLE/VaryingPacking.h" +#include "libANGLE/angletypes.h" + +namespace gl +{ + +// This small structure encapsulates binding sampler uniforms to active GL textures. +struct SamplerBinding +{ + SamplerBinding(TextureType textureTypeIn, + GLenum samplerTypeIn, + SamplerFormat formatIn, + size_t elementCount); + SamplerBinding(const SamplerBinding &other); + ~SamplerBinding(); + + // Necessary for retrieving active textures from the GL state. + TextureType textureType; + + GLenum samplerType; + + SamplerFormat format; + + // List of all textures bound to this sampler, of type textureType. + // Cropped by the amount of unused elements reported by the driver. + std::vector boundTextureUnits; +}; + +struct ImageBinding +{ + ImageBinding(size_t count, TextureType textureTypeIn); + ImageBinding(GLuint imageUnit, size_t count, TextureType textureTypeIn); + ImageBinding(const ImageBinding &other); + ~ImageBinding(); + + // Necessary for distinguishing between textures with images and texture buffers. + TextureType textureType; + + // List of all textures bound. + // Cropped by the amount of unused elements reported by the driver. + std::vector boundImageUnits; +}; + +// A varying with transform feedback enabled. If it's an array, either the whole array or one of its +// elements specified by 'arrayIndex' can set to be enabled. +struct TransformFeedbackVarying : public sh::ShaderVariable +{ + TransformFeedbackVarying(const sh::ShaderVariable &varyingIn, GLuint arrayIndexIn) + : sh::ShaderVariable(varyingIn), arrayIndex(arrayIndexIn) + { + ASSERT(!isArrayOfArrays()); + } + + TransformFeedbackVarying(const sh::ShaderVariable &field, const sh::ShaderVariable &parent) + : arrayIndex(GL_INVALID_INDEX) + { + sh::ShaderVariable *thisVar = this; + *thisVar = field; + interpolation = parent.interpolation; + isInvariant = parent.isInvariant; + ASSERT(parent.isShaderIOBlock || !parent.name.empty()); + if (!parent.name.empty()) + { + name = parent.name + "." + name; + mappedName = parent.mappedName + "." + mappedName; + } + structOrBlockName = parent.structOrBlockName; + mappedStructOrBlockName = parent.mappedStructOrBlockName; + } + + std::string nameWithArrayIndex() const + { + std::stringstream fullNameStr; + fullNameStr << name; + if (arrayIndex != GL_INVALID_INDEX) + { + fullNameStr << "[" << arrayIndex << "]"; + } + return fullNameStr.str(); + } + GLsizei size() const + { + return (isArray() && arrayIndex == GL_INVALID_INDEX ? getOutermostArraySize() : 1); + } + + GLuint arrayIndex; +}; + +class ProgramState; +class ProgramPipelineState; + +class ProgramExecutable final : public angle::Subject +{ + public: + ProgramExecutable(); + ProgramExecutable(const ProgramExecutable &other); + ~ProgramExecutable() override; + + void reset(bool clearInfoLog); + + void save(bool isSeparable, gl::BinaryOutputStream *stream) const; + void load(bool isSeparable, gl::BinaryInputStream *stream); + + int getInfoLogLength() const; + InfoLog &getInfoLog() { return mInfoLog; } + void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const; + std::string getInfoLogString() const; + void resetInfoLog() { mInfoLog.reset(); } + + void resetLinkedShaderStages() { mLinkedShaderStages.reset(); } + const ShaderBitSet &getLinkedShaderStages() const { return mLinkedShaderStages; } + void setLinkedShaderStages(ShaderType shaderType) + { + mLinkedShaderStages.set(shaderType); + updateCanDrawWith(); + } + bool hasLinkedShaderStage(ShaderType shaderType) const + { + ASSERT(shaderType != ShaderType::InvalidEnum); + return mLinkedShaderStages[shaderType]; + } + size_t getLinkedShaderStageCount() const { return mLinkedShaderStages.count(); } + bool hasLinkedGraphicsShader() const + { + return mLinkedShaderStages.any() && + mLinkedShaderStages != gl::ShaderBitSet{gl::ShaderType::Compute}; + } + bool hasLinkedTessellationShader() const + { + return mLinkedShaderStages[ShaderType::TessEvaluation]; + } + + ShaderType getLinkedTransformFeedbackStage() const; + + const AttributesMask &getActiveAttribLocationsMask() const + { + return mActiveAttribLocationsMask; + } + bool isAttribLocationActive(size_t attribLocation) const; + const AttributesMask &getNonBuiltinAttribLocationsMask() const { return mAttributesMask; } + unsigned int getMaxActiveAttribLocation() const { return mMaxActiveAttribLocation; } + const ComponentTypeMask &getAttributesTypeMask() const { return mAttributesTypeMask; } + AttributesMask getAttributesMask() const; + + const ActiveTextureMask &getActiveSamplersMask() const { return mActiveSamplersMask; } + void setActiveTextureMask(ActiveTextureMask mask) { mActiveSamplersMask = mask; } + SamplerFormat getSamplerFormatForTextureUnitIndex(size_t textureUnitIndex) const + { + return mActiveSamplerFormats[textureUnitIndex]; + } + const ShaderBitSet getSamplerShaderBitsForTextureUnitIndex(size_t textureUnitIndex) const + { + return mActiveSamplerShaderBits[textureUnitIndex]; + } + const ActiveTextureMask &getActiveImagesMask() const { return mActiveImagesMask; } + void setActiveImagesMask(ActiveTextureMask mask) { mActiveImagesMask = mask; } + const ActiveTextureArray &getActiveImageShaderBits() const + { + return mActiveImageShaderBits; + } + + const ActiveTextureMask &getActiveYUVSamplers() const { return mActiveSamplerYUV; } + + const ActiveTextureArray &getActiveSamplerTypes() const + { + return mActiveSamplerTypes; + } + + void setActive(size_t textureUnit, + const SamplerBinding &samplerBinding, + const gl::LinkedUniform &samplerUniform); + void setInactive(size_t textureUnit); + void hasSamplerTypeConflict(size_t textureUnit); + void hasSamplerFormatConflict(size_t textureUnit); + + void updateActiveSamplers(const ProgramState &programState); + + bool hasDefaultUniforms() const; + bool hasTextures() const; + bool hasUniformBuffers() const; + bool hasStorageBuffers() const; + bool hasAtomicCounterBuffers() const; + bool hasImages() const; + bool hasTransformFeedbackOutput() const + { + return !getLinkedTransformFeedbackVaryings().empty(); + } + bool usesFramebufferFetch() const; + + // Count the number of uniform and storage buffer declarations, counting arrays as one. + size_t getTransformFeedbackBufferCount() const { return mTransformFeedbackStrides.size(); } + + void updateCanDrawWith(); + bool hasVertexShader() const { return mCanDrawWith; } + + const std::vector &getProgramInputs() const { return mProgramInputs; } + const std::vector &getOutputVariables() const { return mOutputVariables; } + const std::vector &getOutputLocations() const { return mOutputLocations; } + const std::vector &getSecondaryOutputLocations() const + { + return mSecondaryOutputLocations; + } + const std::vector &getUniforms() const { return mUniforms; } + const std::vector &getUniformBlocks() const { return mUniformBlocks; } + const UniformBlockBindingMask &getActiveUniformBlockBindings() const + { + return mActiveUniformBlockBindings; + } + const std::vector &getSamplerBindings() const { return mSamplerBindings; } + const std::vector &getImageBindings() const { return mImageBindings; } + std::vector *getImageBindings() { return &mImageBindings; } + const RangeUI &getDefaultUniformRange() const { return mDefaultUniformRange; } + const RangeUI &getSamplerUniformRange() const { return mSamplerUniformRange; } + const RangeUI &getImageUniformRange() const { return mImageUniformRange; } + const RangeUI &getAtomicCounterUniformRange() const { return mAtomicCounterUniformRange; } + const RangeUI &getFragmentInoutRange() const { return mFragmentInoutRange; } + bool hasDiscard() const { return mHasDiscard; } + bool enablesPerSampleShading() const { return mEnablesPerSampleShading; } + BlendEquationBitSet getAdvancedBlendEquations() const { return mAdvancedBlendEquations; } + const std::vector &getLinkedTransformFeedbackVaryings() const + { + return mLinkedTransformFeedbackVaryings; + } + GLint getTransformFeedbackBufferMode() const { return mTransformFeedbackBufferMode; } + GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const + { + ASSERT(uniformBlockIndex < mUniformBlocks.size()); + return mUniformBlocks[uniformBlockIndex].binding; + } + GLuint getShaderStorageBlockBinding(GLuint blockIndex) const + { + ASSERT(blockIndex < mShaderStorageBlocks.size()); + return mShaderStorageBlocks[blockIndex].binding; + } + const std::vector &getTransformFeedbackStrides() const + { + return mTransformFeedbackStrides; + } + const std::vector &getAtomicCounterBuffers() const + { + return mAtomicCounterBuffers; + } + const std::vector &getShaderStorageBlocks() const + { + return mShaderStorageBlocks; + } + const LinkedUniform &getUniformByIndex(GLuint index) const + { + ASSERT(index < static_cast(mUniforms.size())); + return mUniforms[index]; + } + + ANGLE_INLINE GLuint getActiveUniformBlockCount() const + { + return static_cast(mUniformBlocks.size()); + } + + ANGLE_INLINE GLuint getActiveAtomicCounterBufferCount() const + { + return static_cast(mAtomicCounterBuffers.size()); + } + + ANGLE_INLINE GLuint getActiveShaderStorageBlockCount() const + { + size_t shaderStorageBlocksSize = mShaderStorageBlocks.size(); + return static_cast(shaderStorageBlocksSize); + } + + GLuint getUniformIndexFromImageIndex(GLuint imageIndex) const; + + GLuint getUniformIndexFromSamplerIndex(GLuint samplerIndex) const; + + void saveLinkedStateInfo(const Context *context, const ProgramState &state); + const std::vector &getLinkedOutputVaryings(ShaderType shaderType) const + { + return mLinkedOutputVaryings[shaderType]; + } + const std::vector &getLinkedInputVaryings(ShaderType shaderType) const + { + return mLinkedInputVaryings[shaderType]; + } + + const std::vector &getLinkedUniforms(ShaderType shaderType) const + { + return mLinkedUniforms[shaderType]; + } + + const std::vector &getLinkedUniformBlocks(ShaderType shaderType) const + { + return mLinkedUniformBlocks[shaderType]; + } + + int getLinkedShaderVersion(ShaderType shaderType) const + { + return mLinkedShaderVersions[shaderType]; + } + + bool isYUVOutput() const; + + PrimitiveMode getGeometryShaderInputPrimitiveType() const + { + return mGeometryShaderInputPrimitiveType; + } + + PrimitiveMode getGeometryShaderOutputPrimitiveType() const + { + return mGeometryShaderOutputPrimitiveType; + } + + int getGeometryShaderInvocations() const { return mGeometryShaderInvocations; } + + int getGeometryShaderMaxVertices() const { return mGeometryShaderMaxVertices; } + + GLenum getTessGenMode() const { return mTessGenMode; } + + void resetCachedValidateSamplersResult() { mCachedValidateSamplersResult.reset(); } + bool validateSamplers(InfoLog *infoLog, const Caps &caps) const + { + // Use the cache if: + // - we aren't using an info log (which gives the full error). + // - The sample mapping hasn't changed and we've already validated. + if (infoLog == nullptr && mCachedValidateSamplersResult.valid()) + { + return mCachedValidateSamplersResult.value(); + } + + return validateSamplersImpl(infoLog, caps); + } + + ComponentTypeMask getFragmentOutputsTypeMask() const { return mDrawBufferTypeMask; } + DrawBufferMask getActiveOutputVariablesMask() const { return mActiveOutputVariablesMask; } + + bool linkUniforms(const Context *context, + const ShaderMap> &shaderUniforms, + InfoLog &infoLog, + const ProgramAliasedBindings &uniformLocationBindings, + GLuint *combinedImageUniformsCount, + std::vector *unusedUniforms, + std::vector *uniformLocationsOutOrNull); + + void copyInputsFromProgram(const ProgramState &programState); + void copyShaderBuffersFromProgram(const ProgramState &programState, ShaderType shaderType); + void clearSamplerBindings(); + void copySamplerBindingsFromProgram(const ProgramState &programState); + void copyImageBindingsFromProgram(const ProgramState &programState); + void copyOutputsFromProgram(const ProgramState &programState); + void copyUniformsFromProgramMap(const ShaderMap &programs); + + private: + friend class Program; + friend class ProgramPipeline; + friend class ProgramState; + + void updateActiveImages(const ProgramExecutable &executable); + + // Scans the sampler bindings for type conflicts with sampler 'textureUnitIndex'. + void setSamplerUniformTextureTypeAndFormat(size_t textureUnitIndex, + std::vector &samplerBindings); + + bool linkMergedVaryings(const Context *context, + const ProgramMergedVaryings &mergedVaryings, + const std::vector &transformFeedbackVaryingNames, + const LinkingVariables &linkingVariables, + bool isSeparable, + ProgramVaryingPacking *varyingPacking); + + bool linkValidateTransformFeedback( + const Context *context, + const ProgramMergedVaryings &varyings, + ShaderType stage, + const std::vector &transformFeedbackVaryingNames); + + void gatherTransformFeedbackVaryings( + const ProgramMergedVaryings &varyings, + ShaderType stage, + const std::vector &transformFeedbackVaryingNames); + + void updateTransformFeedbackStrides(); + + bool validateSamplersImpl(InfoLog *infoLog, const Caps &caps) const; + + bool linkValidateOutputVariables(const Caps &caps, + const Extensions &extensions, + const Version &version, + GLuint combinedImageUniformsCount, + GLuint combinedShaderStorageBlocksCount, + const std::vector &outputVariables, + int fragmentShaderVersion, + const ProgramAliasedBindings &fragmentOutputLocations, + const ProgramAliasedBindings &fragmentOutputIndices); + + void linkSamplerAndImageBindings(GLuint *combinedImageUniformsCount); + bool linkAtomicCounterBuffers(const Context *context, InfoLog &infoLog); + + InfoLog mInfoLog; + + ShaderBitSet mLinkedShaderStages; + + angle::BitSet mActiveAttribLocationsMask; + unsigned int mMaxActiveAttribLocation; + ComponentTypeMask mAttributesTypeMask; + // mAttributesMask is identical to mActiveAttribLocationsMask with built-in attributes removed. + AttributesMask mAttributesMask; + + // Cached mask of active samplers and sampler types. + ActiveTextureMask mActiveSamplersMask; + ActiveTextureArray mActiveSamplerRefCounts; + ActiveTextureArray mActiveSamplerTypes; + ActiveTextureMask mActiveSamplerYUV; + ActiveTextureArray mActiveSamplerFormats; + ActiveTextureArray mActiveSamplerShaderBits; + + // Cached mask of active images. + ActiveTextureMask mActiveImagesMask; + ActiveTextureArray mActiveImageShaderBits; + + bool mCanDrawWith; + + // Names and mapped names of output variables that are arrays include [0] in the end, similarly + // to uniforms. + std::vector mOutputVariables; + std::vector mOutputLocations; + DrawBufferMask mActiveOutputVariablesMask; + // EXT_blend_func_extended secondary outputs (ones with index 1) + std::vector mSecondaryOutputLocations; + bool mYUVOutput; + // Vertex attributes, Fragment input varyings, etc. + std::vector mProgramInputs; + std::vector mLinkedTransformFeedbackVaryings; + // The size of the data written to each transform feedback buffer per vertex. + std::vector mTransformFeedbackStrides; + GLenum mTransformFeedbackBufferMode; + // Uniforms are sorted in order: + // 1. Non-opaque uniforms + // 2. Sampler uniforms + // 3. Image uniforms + // 4. Atomic counter uniforms + // 5. Subpass Input uniforms (Only for Vulkan) + // 6. Uniform block uniforms + // This makes opaque uniform validation easier, since we don't need a separate list. + // For generating the entries and naming them we follow the spec: GLES 3.1 November 2016 section + // 7.3.1.1 Naming Active Resources. There's a separate entry for each struct member and each + // inner array of an array of arrays. Names and mapped names of uniforms that are arrays include + // [0] in the end. This makes implementation of queries simpler. + std::vector mUniforms; + RangeUI mDefaultUniformRange; + RangeUI mSamplerUniformRange; + RangeUI mImageUniformRange; + RangeUI mAtomicCounterUniformRange; + std::vector mUniformBlocks; + + // For faster iteration on the blocks currently being bound. + UniformBlockBindingMask mActiveUniformBlockBindings; + + std::vector mAtomicCounterBuffers; + std::vector mShaderStorageBlocks; + + RangeUI mFragmentInoutRange; + bool mHasDiscard; + bool mEnablesPerSampleShading; + + // KHR_blend_equation_advanced supported equation list + BlendEquationBitSet mAdvancedBlendEquations; + + // An array of the samplers that are used by the program + std::vector mSamplerBindings; + + // An array of the images that are used by the program + std::vector mImageBindings; + + ShaderMap> mLinkedOutputVaryings; + ShaderMap> mLinkedInputVaryings; + ShaderMap> mLinkedUniforms; + ShaderMap> mLinkedUniformBlocks; + + ShaderMap mLinkedShaderVersions; + + // GL_EXT_geometry_shader. + PrimitiveMode mGeometryShaderInputPrimitiveType; + PrimitiveMode mGeometryShaderOutputPrimitiveType; + int mGeometryShaderInvocations; + int mGeometryShaderMaxVertices; + + // GL_EXT_tessellation_shader + int mTessControlShaderVertices; + GLenum mTessGenMode; + GLenum mTessGenSpacing; + GLenum mTessGenVertexOrder; + GLenum mTessGenPointMode; + + // Fragment output variable base types: FLOAT, INT, or UINT. Ordered by location. + std::vector mOutputVariableTypes; + ComponentTypeMask mDrawBufferTypeMask; + + // Cache for sampler validation + mutable Optional mCachedValidateSamplersResult; +}; +} // namespace gl + +#endif // LIBANGLE_PROGRAMEXECUTABLE_H_ diff --git a/gfx/angle/checkout/src/libANGLE/ProgramLinkedResources.cpp b/gfx/angle/checkout/src/libANGLE/ProgramLinkedResources.cpp new file mode 100644 index 0000000000..11000fdabc --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/ProgramLinkedResources.cpp @@ -0,0 +1,2377 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ProgramLinkedResources.cpp: implements link-time checks for default block uniforms, and generates +// uniform locations. Populates data structures related to uniforms so that they can be stored in +// program state. + +#include "libANGLE/ProgramLinkedResources.h" + +#include "common/string_utils.h" +#include "common/utilities.h" +#include "libANGLE/Caps.h" +#include "libANGLE/Context.h" +#include "libANGLE/Shader.h" +#include "libANGLE/features.h" + +namespace gl +{ +namespace +{ +LinkedUniform *FindUniform(std::vector &list, const std::string &name) +{ + for (LinkedUniform &uniform : list) + { + if (uniform.name == name) + return &uniform; + } + + return nullptr; +} + +template +void SetActive(std::vector *list, const std::string &name, ShaderType shaderType, bool active) +{ + for (auto &variable : *list) + { + if (variable.name == name) + { + variable.setActive(shaderType, active); + return; + } + } +} + +// GLSL ES Spec 3.00.3, section 4.3.5. +LinkMismatchError LinkValidateUniforms(const sh::ShaderVariable &uniform1, + const sh::ShaderVariable &uniform2, + std::string *mismatchedStructFieldName) +{ +#if ANGLE_PROGRAM_LINK_VALIDATE_UNIFORM_PRECISION == ANGLE_ENABLED + const bool validatePrecisionFeature = true; +#else + const bool validatePrecisionFeature = false; +#endif + + // Validate precision match of uniforms iff they are statically used + bool validatePrecision = uniform1.staticUse && uniform2.staticUse && validatePrecisionFeature; + LinkMismatchError linkError = LinkValidateProgramVariables( + uniform1, uniform2, validatePrecision, false, false, mismatchedStructFieldName); + if (linkError != LinkMismatchError::NO_MISMATCH) + { + return linkError; + } + + // GLSL ES Spec 3.10.4, section 4.4.5. + if (uniform1.binding != -1 && uniform2.binding != -1 && uniform1.binding != uniform2.binding) + { + return LinkMismatchError::BINDING_MISMATCH; + } + + // GLSL ES Spec 3.10.4, section 9.2.1. + if (uniform1.location != -1 && uniform2.location != -1 && + uniform1.location != uniform2.location) + { + return LinkMismatchError::LOCATION_MISMATCH; + } + if (uniform1.offset != uniform2.offset) + { + return LinkMismatchError::OFFSET_MISMATCH; + } + + return LinkMismatchError::NO_MISMATCH; +} + +GLuint GetMaximumShaderUniformVectors(ShaderType shaderType, const Caps &caps) +{ + switch (shaderType) + { + case ShaderType::Vertex: + return static_cast(caps.maxVertexUniformVectors); + case ShaderType::Fragment: + return static_cast(caps.maxFragmentUniformVectors); + + case ShaderType::Compute: + case ShaderType::Geometry: + case ShaderType::TessControl: + case ShaderType::TessEvaluation: + return static_cast(caps.maxShaderUniformComponents[shaderType]) / 4; + + default: + UNREACHABLE(); + return 0u; + } +} + +enum class UniformType : uint8_t +{ + Variable = 0, + Sampler = 1, + Image = 2, + AtomicCounter = 3, + + InvalidEnum = 4, + EnumCount = 4, +}; + +const char *GetUniformResourceNameString(UniformType uniformType) +{ + switch (uniformType) + { + case UniformType::Variable: + return "uniform"; + case UniformType::Sampler: + return "texture image unit"; + case UniformType::Image: + return "image uniform"; + case UniformType::AtomicCounter: + return "atomic counter"; + default: + UNREACHABLE(); + return ""; + } +} + +std::string GetUniformResourceLimitName(ShaderType shaderType, UniformType uniformType) +{ + // Special case: MAX_TEXTURE_IMAGE_UNITS (no "MAX_FRAGMENT_TEXTURE_IMAGE_UNITS") + if (shaderType == ShaderType::Fragment && uniformType == UniformType::Sampler) + { + return "MAX_TEXTURE_IMAGE_UNITS"; + } + + std::ostringstream ostream; + ostream << "MAX_" << GetShaderTypeString(shaderType) << "_"; + + switch (uniformType) + { + case UniformType::Variable: + // For vertex and fragment shaders, ES 2.0 only defines MAX_VERTEX_UNIFORM_VECTORS and + // MAX_FRAGMENT_UNIFORM_VECTORS ([OpenGL ES 2.0] Table 6.20). + if (shaderType == ShaderType::Vertex || shaderType == ShaderType::Fragment) + { + ostream << "UNIFORM_VECTORS"; + break; + } + // For compute and geometry shaders, there are no definitions on + // "MAX_COMPUTE_UNIFORM_VECTORS" or "MAX_GEOMETRY_UNIFORM_VECTORS_EXT" + // ([OpenGL ES 3.1] Table 20.45, [EXT_geometry_shader] Table 20.43gs). + else + { + ostream << "UNIFORM_COMPONENTS"; + } + break; + case UniformType::Sampler: + ostream << "TEXTURE_IMAGE_UNITS"; + break; + case UniformType::Image: + ostream << "IMAGE_UNIFORMS"; + break; + case UniformType::AtomicCounter: + ostream << "ATOMIC_COUNTERS"; + break; + default: + UNREACHABLE(); + return ""; + } + + if (shaderType == ShaderType::Geometry) + { + ostream << "_EXT"; + } + + return ostream.str(); +} + +void LogUniformsExceedLimit(ShaderType shaderType, + UniformType uniformType, + GLuint limit, + InfoLog &infoLog) +{ + infoLog << GetShaderTypeString(shaderType) << " shader " + << GetUniformResourceNameString(uniformType) << "s count exceeds " + << GetUniformResourceLimitName(shaderType, uniformType) << "(" << limit << ")"; +} + +// The purpose of this visitor is to capture the uniforms in a uniform block. Each new uniform is +// added to "uniformsOut". +class UniformBlockEncodingVisitor : public sh::VariableNameVisitor +{ + public: + UniformBlockEncodingVisitor(const GetBlockMemberInfoFunc &getMemberInfo, + const std::string &namePrefix, + const std::string &mappedNamePrefix, + std::vector *uniformsOut, + ShaderType shaderType, + int blockIndex) + : sh::VariableNameVisitor(namePrefix, mappedNamePrefix), + mGetMemberInfo(getMemberInfo), + mUniformsOut(uniformsOut), + mShaderType(shaderType), + mBlockIndex(blockIndex) + {} + + void visitNamedVariable(const sh::ShaderVariable &variable, + bool isRowMajor, + const std::string &name, + const std::string &mappedName, + const std::vector &arraySizes) override + { + // If getBlockMemberInfo returns false, the variable is optimized out. + sh::BlockMemberInfo variableInfo; + if (!mGetMemberInfo(name, mappedName, &variableInfo)) + return; + + std::string nameWithArrayIndex = name; + std::string mappedNameWithArrayIndex = mappedName; + + if (variable.isArray()) + { + nameWithArrayIndex += "[0]"; + mappedNameWithArrayIndex += "[0]"; + } + + if (mBlockIndex == -1) + { + SetActive(mUniformsOut, nameWithArrayIndex, mShaderType, variable.active); + return; + } + + LinkedUniform newUniform(variable.type, variable.precision, nameWithArrayIndex, + variable.arraySizes, -1, -1, -1, mBlockIndex, variableInfo); + newUniform.mappedName = mappedNameWithArrayIndex; + newUniform.setActive(mShaderType, variable.active); + + // Since block uniforms have no location, we don't need to store them in the uniform + // locations list. + mUniformsOut->push_back(newUniform); + } + + private: + const GetBlockMemberInfoFunc &mGetMemberInfo; + std::vector *mUniformsOut; + const ShaderType mShaderType; + const int mBlockIndex; +}; + +// The purpose of this visitor is to capture the buffer variables in a shader storage block. Each +// new buffer variable is stored in "bufferVariablesOut". +class ShaderStorageBlockVisitor : public sh::BlockEncoderVisitor +{ + public: + ShaderStorageBlockVisitor(const GetBlockMemberInfoFunc &getMemberInfo, + const std::string &namePrefix, + const std::string &mappedNamePrefix, + std::vector *bufferVariablesOut, + ShaderType shaderType, + int blockIndex) + : sh::BlockEncoderVisitor(namePrefix, mappedNamePrefix, &mStubEncoder), + mGetMemberInfo(getMemberInfo), + mBufferVariablesOut(bufferVariablesOut), + mShaderType(shaderType), + mBlockIndex(blockIndex) + {} + + void visitNamedVariable(const sh::ShaderVariable &variable, + bool isRowMajor, + const std::string &name, + const std::string &mappedName, + const std::vector &arraySizes) override + { + if (mSkipEnabled) + return; + + // If getBlockMemberInfo returns false, the variable is optimized out. + sh::BlockMemberInfo variableInfo; + if (!mGetMemberInfo(name, mappedName, &variableInfo)) + return; + + std::string nameWithArrayIndex = name; + std::string mappedNameWithArrayIndex = mappedName; + + if (variable.isArray()) + { + nameWithArrayIndex += "[0]"; + mappedNameWithArrayIndex += "[0]"; + } + + if (mBlockIndex == -1) + { + SetActive(mBufferVariablesOut, nameWithArrayIndex, mShaderType, variable.active); + return; + } + + BufferVariable newBufferVariable(variable.type, variable.precision, nameWithArrayIndex, + variable.arraySizes, mBlockIndex, variableInfo); + newBufferVariable.mappedName = mappedNameWithArrayIndex; + newBufferVariable.setActive(mShaderType, variable.active); + + newBufferVariable.topLevelArraySize = mTopLevelArraySize; + + mBufferVariablesOut->push_back(newBufferVariable); + } + + private: + const GetBlockMemberInfoFunc &mGetMemberInfo; + std::vector *mBufferVariablesOut; + const ShaderType mShaderType; + const int mBlockIndex; + sh::StubBlockEncoder mStubEncoder; +}; + +struct ShaderUniformCount +{ + unsigned int vectorCount = 0; + unsigned int samplerCount = 0; + unsigned int imageCount = 0; + unsigned int atomicCounterCount = 0; + unsigned int fragmentInOutCount = 0; +}; + +ShaderUniformCount &operator+=(ShaderUniformCount &lhs, const ShaderUniformCount &rhs) +{ + lhs.vectorCount += rhs.vectorCount; + lhs.samplerCount += rhs.samplerCount; + lhs.imageCount += rhs.imageCount; + lhs.atomicCounterCount += rhs.atomicCounterCount; + lhs.fragmentInOutCount += rhs.fragmentInOutCount; + return lhs; +} + +// The purpose of this visitor is to flatten struct and array uniforms into a list of singleton +// uniforms. They are stored in separate lists by uniform type so they can be sorted in order. +// Counts for each uniform category are stored and can be queried with "getCounts". +class FlattenUniformVisitor : public sh::VariableNameVisitor +{ + public: + FlattenUniformVisitor(ShaderType shaderType, + const sh::ShaderVariable &uniform, + std::vector *uniforms, + std::vector *samplerUniforms, + std::vector *imageUniforms, + std::vector *atomicCounterUniforms, + std::vector *inputAttachmentUniforms, + std::vector *unusedUniforms) + : sh::VariableNameVisitor("", ""), + mShaderType(shaderType), + mMarkActive(uniform.active), + mMarkStaticUse(uniform.staticUse), + mBinding(uniform.binding), + mOffset(uniform.offset), + mLocation(uniform.location), + mUniforms(uniforms), + mSamplerUniforms(samplerUniforms), + mImageUniforms(imageUniforms), + mAtomicCounterUniforms(atomicCounterUniforms), + mInputAttachmentUniforms(inputAttachmentUniforms), + mUnusedUniforms(unusedUniforms) + {} + + void visitNamedOpaqueObject(const sh::ShaderVariable &variable, + const std::string &name, + const std::string &mappedName, + const std::vector &arraySizes) override + { + visitNamedVariable(variable, false, name, mappedName, arraySizes); + } + + void visitNamedVariable(const sh::ShaderVariable &variable, + bool isRowMajor, + const std::string &name, + const std::string &mappedName, + const std::vector &arraySizes) override + { + bool isSampler = IsSamplerType(variable.type); + bool isImage = IsImageType(variable.type); + bool isAtomicCounter = IsAtomicCounterType(variable.type); + bool isFragmentInOut = variable.isFragmentInOut; + std::vector *uniformList = mUniforms; + if (isSampler) + { + uniformList = mSamplerUniforms; + } + else if (isImage) + { + uniformList = mImageUniforms; + } + else if (isAtomicCounter) + { + uniformList = mAtomicCounterUniforms; + } + else if (isFragmentInOut) + { + uniformList = mInputAttachmentUniforms; + } + + std::string fullNameWithArrayIndex(name); + std::string fullMappedNameWithArrayIndex(mappedName); + + if (variable.isArray()) + { + // We're following the GLES 3.1 November 2016 spec section 7.3.1.1 Naming Active + // Resources and including [0] at the end of array variable names. + fullNameWithArrayIndex += "[0]"; + fullMappedNameWithArrayIndex += "[0]"; + } + + LinkedUniform *existingUniform = FindUniform(*uniformList, fullNameWithArrayIndex); + if (existingUniform) + { + if (getBinding() != -1) + { + existingUniform->binding = getBinding(); + } + if (getOffset() != -1) + { + existingUniform->offset = getOffset(); + } + if (mLocation != -1) + { + existingUniform->location = mLocation; + } + if (mMarkActive) + { + existingUniform->active = true; + existingUniform->setActive(mShaderType, true); + } + if (mMarkStaticUse) + { + existingUniform->staticUse = true; + } + } + else + { + LinkedUniform linkedUniform(variable.type, variable.precision, fullNameWithArrayIndex, + variable.arraySizes, getBinding(), getOffset(), mLocation, + -1, sh::kDefaultBlockMemberInfo); + linkedUniform.mappedName = fullMappedNameWithArrayIndex; + linkedUniform.active = mMarkActive; + linkedUniform.staticUse = mMarkStaticUse; + linkedUniform.outerArraySizes = arraySizes; + linkedUniform.texelFetchStaticUse = variable.texelFetchStaticUse; + linkedUniform.imageUnitFormat = variable.imageUnitFormat; + linkedUniform.isFragmentInOut = variable.isFragmentInOut; + if (variable.hasParentArrayIndex()) + { + linkedUniform.setParentArrayIndex(variable.parentArrayIndex()); + } + + std::vector arrayDims = arraySizes; + ASSERT(variable.arraySizes.size() == 1 || variable.arraySizes.size() == 0); + arrayDims.push_back(variable.arraySizes.empty() ? 1 : variable.arraySizes[0]); + + size_t numDimensions = arraySizes.size(); + uint32_t arrayStride = 1; + for (size_t dimension = numDimensions; dimension > 0;) + { + --dimension; + arrayStride *= arrayDims[dimension + 1]; + linkedUniform.outerArrayOffset += arrayStride * mArrayElementStack[dimension]; + } + + if (mMarkActive) + { + linkedUniform.setActive(mShaderType, true); + } + else + { + mUnusedUniforms->emplace_back( + linkedUniform.name, linkedUniform.isSampler(), linkedUniform.isImage(), + linkedUniform.isAtomicCounter(), linkedUniform.isFragmentInOut); + } + + uniformList->push_back(linkedUniform); + } + + unsigned int elementCount = variable.getBasicTypeElementCount(); + + // Samplers and images aren't "real" uniforms, so they don't count towards register usage. + // Likewise, don't count "real" uniforms towards opaque count. + + if (!IsOpaqueType(variable.type) && !isFragmentInOut) + { + mUniformCount.vectorCount += VariableRegisterCount(variable.type) * elementCount; + } + + mUniformCount.samplerCount += (isSampler ? elementCount : 0); + mUniformCount.imageCount += (isImage ? elementCount : 0); + mUniformCount.atomicCounterCount += (isAtomicCounter ? elementCount : 0); + mUniformCount.fragmentInOutCount += (isFragmentInOut ? elementCount : 0); + + if (mLocation != -1) + { + mLocation += elementCount; + } + } + + void enterStructAccess(const sh::ShaderVariable &structVar, bool isRowMajor) override + { + mStructStackSize++; + sh::VariableNameVisitor::enterStructAccess(structVar, isRowMajor); + } + + void exitStructAccess(const sh::ShaderVariable &structVar, bool isRowMajor) override + { + mStructStackSize--; + sh::VariableNameVisitor::exitStructAccess(structVar, isRowMajor); + } + + void enterArrayElement(const sh::ShaderVariable &arrayVar, unsigned int arrayElement) override + { + mArrayElementStack.push_back(arrayElement); + sh::VariableNameVisitor::enterArrayElement(arrayVar, arrayElement); + } + + void exitArrayElement(const sh::ShaderVariable &arrayVar, unsigned int arrayElement) override + { + mArrayElementStack.pop_back(); + sh::VariableNameVisitor::exitArrayElement(arrayVar, arrayElement); + } + + ShaderUniformCount getCounts() const { return mUniformCount; } + + private: + int getBinding() const { return mStructStackSize == 0 ? mBinding : -1; } + int getOffset() const { return mStructStackSize == 0 ? mOffset : -1; } + + ShaderType mShaderType; + + // Active and StaticUse are given separately because they are tracked at struct granularity. + bool mMarkActive; + bool mMarkStaticUse; + int mBinding; + int mOffset; + int mLocation; + std::vector *mUniforms; + std::vector *mSamplerUniforms; + std::vector *mImageUniforms; + std::vector *mAtomicCounterUniforms; + std::vector *mInputAttachmentUniforms; + std::vector *mUnusedUniforms; + std::vector mArrayElementStack; + ShaderUniformCount mUniformCount; + unsigned int mStructStackSize = 0; +}; + +class InterfaceBlockInfo final : angle::NonCopyable +{ + public: + InterfaceBlockInfo(CustomBlockLayoutEncoderFactory *customEncoderFactory) + : mCustomEncoderFactory(customEncoderFactory) + {} + + void getShaderBlockInfo(const std::vector &interfaceBlocks); + + bool getBlockSize(const std::string &name, const std::string &mappedName, size_t *sizeOut); + bool getBlockMemberInfo(const std::string &name, + const std::string &mappedName, + sh::BlockMemberInfo *infoOut); + + private: + size_t getBlockInfo(const sh::InterfaceBlock &interfaceBlock); + + std::map mBlockSizes; + sh::BlockLayoutMap mBlockLayout; + // Based on the interface block layout, the std140 or std430 encoders are used. On some + // platforms (currently only D3D), there could be another non-standard encoder used. + CustomBlockLayoutEncoderFactory *mCustomEncoderFactory; +}; + +void InterfaceBlockInfo::getShaderBlockInfo(const std::vector &interfaceBlocks) +{ + for (const sh::InterfaceBlock &interfaceBlock : interfaceBlocks) + { + if (!IsActiveInterfaceBlock(interfaceBlock)) + continue; + + if (mBlockSizes.count(interfaceBlock.name) > 0) + continue; + + size_t dataSize = getBlockInfo(interfaceBlock); + mBlockSizes[interfaceBlock.name] = dataSize; + } +} + +size_t InterfaceBlockInfo::getBlockInfo(const sh::InterfaceBlock &interfaceBlock) +{ + ASSERT(IsActiveInterfaceBlock(interfaceBlock)); + + // define member uniforms + sh::Std140BlockEncoder std140Encoder; + sh::Std430BlockEncoder std430Encoder; + sh::BlockLayoutEncoder *customEncoder = nullptr; + sh::BlockLayoutEncoder *encoder = nullptr; + + if (interfaceBlock.layout == sh::BLOCKLAYOUT_STD140) + { + encoder = &std140Encoder; + } + else if (interfaceBlock.layout == sh::BLOCKLAYOUT_STD430) + { + encoder = &std430Encoder; + } + else if (mCustomEncoderFactory) + { + encoder = customEncoder = mCustomEncoderFactory->makeEncoder(); + } + else + { + UNREACHABLE(); + return 0; + } + + sh::GetInterfaceBlockInfo(interfaceBlock.fields, interfaceBlock.fieldPrefix(), encoder, + &mBlockLayout); + + size_t offset = encoder->getCurrentOffset(); + + SafeDelete(customEncoder); + + return offset; +} + +bool InterfaceBlockInfo::getBlockSize(const std::string &name, + const std::string &mappedName, + size_t *sizeOut) +{ + size_t nameLengthWithoutArrayIndex; + ParseArrayIndex(name, &nameLengthWithoutArrayIndex); + std::string baseName = name.substr(0u, nameLengthWithoutArrayIndex); + auto sizeIter = mBlockSizes.find(baseName); + if (sizeIter == mBlockSizes.end()) + { + *sizeOut = 0; + return false; + } + + *sizeOut = sizeIter->second; + return true; +} + +bool InterfaceBlockInfo::getBlockMemberInfo(const std::string &name, + const std::string &mappedName, + sh::BlockMemberInfo *infoOut) +{ + auto infoIter = mBlockLayout.find(name); + if (infoIter == mBlockLayout.end()) + { + *infoOut = sh::kDefaultBlockMemberInfo; + return false; + } + + *infoOut = infoIter->second; + return true; +} + +void GetFilteredVaryings(const std::vector &varyings, + std::vector *filteredVaryingsOut) +{ + for (const sh::ShaderVariable &varying : varyings) + { + // Built-in varyings obey special rules + if (varying.isBuiltIn()) + { + continue; + } + + filteredVaryingsOut->push_back(&varying); + } +} + +LinkMismatchError LinkValidateVaryings(const sh::ShaderVariable &outputVarying, + const sh::ShaderVariable &inputVarying, + int shaderVersion, + ShaderType frontShaderType, + ShaderType backShaderType, + bool isSeparable, + std::string *mismatchedStructFieldName) +{ + // [ES 3.2 spec] 7.4.1 Shader Interface Matching: + // Tessellation control shader per-vertex output variables and blocks and tessellation control, + // tessellation evaluation, and geometry shader per-vertex input variables and blocks are + // required to be declared as arrays, with each element representing input or output values for + // a single vertex of a multi-vertex primitive. For the purposes of interface matching, such + // variables and blocks are treated as though they were not declared as arrays. + bool treatOutputAsNonArray = + (frontShaderType == ShaderType::TessControl && !outputVarying.isPatch); + bool treatInputAsNonArray = + ((backShaderType == ShaderType::TessControl || + backShaderType == ShaderType::TessEvaluation || backShaderType == ShaderType::Geometry) && + !inputVarying.isPatch); + + // Skip the validation on the array sizes between a vertex output varying and a geometry input + // varying as it has been done before. + bool validatePrecision = isSeparable && (shaderVersion > 100); + LinkMismatchError linkError = LinkValidateProgramVariables( + outputVarying, inputVarying, validatePrecision, treatOutputAsNonArray, treatInputAsNonArray, + mismatchedStructFieldName); + if (linkError != LinkMismatchError::NO_MISMATCH) + { + return linkError; + } + + // Explicit locations must match if the names match. + if (outputVarying.isSameNameAtLinkTime(inputVarying) && + outputVarying.location != inputVarying.location) + { + return LinkMismatchError::LOCATION_MISMATCH; + } + + if (!sh::InterpolationTypesMatch(outputVarying.interpolation, inputVarying.interpolation)) + { + return LinkMismatchError::INTERPOLATION_TYPE_MISMATCH; + } + + if (shaderVersion == 100 && outputVarying.isInvariant != inputVarying.isInvariant) + { + return LinkMismatchError::INVARIANCE_MISMATCH; + } + + return LinkMismatchError::NO_MISMATCH; +} + +bool DoShaderVariablesMatch(int frontShaderVersion, + ShaderType frontShaderType, + ShaderType backShaderType, + const sh::ShaderVariable &input, + const sh::ShaderVariable &output, + bool isSeparable, + gl::InfoLog &infoLog) +{ + bool namesMatch = input.isSameNameAtLinkTime(output); + bool locationsMatch = input.location != -1 && input.location == output.location; + + // An output block is considered to match an input block in the subsequent + // shader if the two blocks have the same block name, and the members of the + // block match exactly in name, type, qualification, and declaration order. + // + // - For the purposes of shader interface matching, the gl_PointSize + // member of the intrinsically declared gl_PerVertex shader interface + // block is ignored. + // - Output blocks that do not match in name, but have a location and match + // in every other way listed above may be considered to match by some + // implementations, but not all - so this behaviour should not be relied + // upon. + + // An output variable is considered to match an input variable in the subsequent + // shader if: + // + // - the two variables match in name, type, and qualification; or + // - the two variables are declared with the same location qualifier and + // match in type and qualification. + + if (namesMatch || locationsMatch) + { + std::string mismatchedStructFieldName; + LinkMismatchError linkError = + LinkValidateVaryings(output, input, frontShaderVersion, frontShaderType, backShaderType, + isSeparable, &mismatchedStructFieldName); + if (linkError != LinkMismatchError::NO_MISMATCH) + { + LogLinkMismatch(infoLog, input.name, "varying", linkError, mismatchedStructFieldName, + frontShaderType, backShaderType); + return false; + } + + return true; + } + + return false; +} + +const char *GetInterfaceBlockTypeString(sh::BlockType blockType) +{ + switch (blockType) + { + case sh::BlockType::BLOCK_UNIFORM: + return "uniform block"; + case sh::BlockType::BLOCK_BUFFER: + return "shader storage block"; + default: + UNREACHABLE(); + return ""; + } +} + +std::string GetInterfaceBlockLimitName(ShaderType shaderType, sh::BlockType blockType) +{ + std::ostringstream stream; + stream << "GL_MAX_" << GetShaderTypeString(shaderType) << "_"; + + switch (blockType) + { + case sh::BlockType::BLOCK_UNIFORM: + stream << "UNIFORM_BUFFERS"; + break; + case sh::BlockType::BLOCK_BUFFER: + stream << "SHADER_STORAGE_BLOCKS"; + break; + default: + UNREACHABLE(); + return ""; + } + + if (shaderType == ShaderType::Geometry) + { + stream << "_EXT"; + } + + return stream.str(); +} + +void LogInterfaceBlocksExceedLimit(InfoLog &infoLog, + ShaderType shaderType, + sh::BlockType blockType, + GLuint limit) +{ + infoLog << GetShaderTypeString(shaderType) << " shader " + << GetInterfaceBlockTypeString(blockType) << " count exceeds " + << GetInterfaceBlockLimitName(shaderType, blockType) << " (" << limit << ")"; +} + +bool ValidateInterfaceBlocksCount(GLuint maxInterfaceBlocks, + const std::vector &interfaceBlocks, + ShaderType shaderType, + sh::BlockType blockType, + GLuint *combinedInterfaceBlocksCount, + InfoLog &infoLog) +{ + GLuint blockCount = 0; + for (const sh::InterfaceBlock &block : interfaceBlocks) + { + if (IsActiveInterfaceBlock(block)) + { + blockCount += std::max(block.arraySize, 1u); + if (blockCount > maxInterfaceBlocks) + { + LogInterfaceBlocksExceedLimit(infoLog, shaderType, blockType, maxInterfaceBlocks); + return false; + } + } + } + + // [OpenGL ES 3.1] Chapter 7.6.2 Page 105: + // If a uniform block is used by multiple shader stages, each such use counts separately + // against this combined limit. + // [OpenGL ES 3.1] Chapter 7.8 Page 111: + // If a shader storage block in a program is referenced by multiple shaders, each such + // reference counts separately against this combined limit. + if (combinedInterfaceBlocksCount) + { + *combinedInterfaceBlocksCount += blockCount; + } + + return true; +} +} // anonymous namespace + +UniformLinker::UniformLinker(const ShaderBitSet &activeShaderStages, + const ShaderMap> &shaderUniforms) + : mActiveShaderStages(activeShaderStages), mShaderUniforms(shaderUniforms) +{} + +UniformLinker::~UniformLinker() = default; + +void UniformLinker::getResults(std::vector *uniforms, + std::vector *unusedUniformsOutOrNull, + std::vector *uniformLocationsOutOrNull) +{ + uniforms->swap(mUniforms); + + if (unusedUniformsOutOrNull) + { + unusedUniformsOutOrNull->swap(mUnusedUniforms); + } + + if (uniformLocationsOutOrNull) + { + uniformLocationsOutOrNull->swap(mUniformLocations); + } +} + +bool UniformLinker::link(const Caps &caps, + InfoLog &infoLog, + const ProgramAliasedBindings &uniformLocationBindings) +{ + if (mActiveShaderStages[ShaderType::Vertex] && mActiveShaderStages[ShaderType::Fragment]) + { + if (!validateGraphicsUniforms(infoLog)) + { + return false; + } + } + + // Flatten the uniforms list (nested fields) into a simple list (no nesting). + // Also check the maximum uniform vector and sampler counts. + if (!flattenUniformsAndCheckCaps(caps, infoLog)) + { + return false; + } + + if (!checkMaxCombinedAtomicCounters(caps, infoLog)) + { + return false; + } + + if (!indexUniforms(infoLog, uniformLocationBindings)) + { + return false; + } + + return true; +} + +bool UniformLinker::validateGraphicsUniforms(InfoLog &infoLog) const +{ + // Check that uniforms defined in the graphics shaders are identical + std::map linkedUniforms; + + for (const ShaderType shaderType : mActiveShaderStages) + { + if (shaderType == ShaderType::Vertex) + { + for (const sh::ShaderVariable &vertexUniform : mShaderUniforms[ShaderType::Vertex]) + { + linkedUniforms[vertexUniform.name] = + std::make_pair(ShaderType::Vertex, &vertexUniform); + } + } + else + { + bool isLastShader = (shaderType == ShaderType::Fragment); + if (!validateGraphicsUniformsPerShader(shaderType, !isLastShader, &linkedUniforms, + infoLog)) + { + return false; + } + } + } + + return true; +} + +bool UniformLinker::validateGraphicsUniformsPerShader( + ShaderType shaderToLink, + bool extendLinkedUniforms, + std::map *linkedUniforms, + InfoLog &infoLog) const +{ + ASSERT(mActiveShaderStages[shaderToLink] && linkedUniforms); + + for (const sh::ShaderVariable &uniform : mShaderUniforms[shaderToLink]) + { + const auto &entry = linkedUniforms->find(uniform.name); + if (entry != linkedUniforms->end()) + { + const sh::ShaderVariable &linkedUniform = *(entry->second.second); + std::string mismatchedStructFieldName; + LinkMismatchError linkError = + LinkValidateUniforms(uniform, linkedUniform, &mismatchedStructFieldName); + if (linkError != LinkMismatchError::NO_MISMATCH) + { + LogLinkMismatch(infoLog, uniform.name, "uniform", linkError, + mismatchedStructFieldName, entry->second.first, shaderToLink); + return false; + } + } + else if (extendLinkedUniforms) + { + (*linkedUniforms)[uniform.name] = std::make_pair(shaderToLink, &uniform); + } + } + + return true; +} + +bool UniformLinker::indexUniforms(InfoLog &infoLog, + const ProgramAliasedBindings &uniformLocationBindings) +{ + // Locations which have been allocated for an unused uniform. + std::set ignoredLocations; + + int maxUniformLocation = -1; + + // Gather uniform locations that have been set either using the bindUniformLocationCHROMIUM API + // or by using a location layout qualifier and check conflicts between them. + if (!gatherUniformLocationsAndCheckConflicts(infoLog, uniformLocationBindings, + &ignoredLocations, &maxUniformLocation)) + { + return false; + } + + // Conflicts have been checked, now we can prune non-statically used uniforms. Code further down + // the line relies on only having statically used uniforms in mUniforms. + pruneUnusedUniforms(); + + // Gather uniforms that have their location pre-set and uniforms that don't yet have a location. + std::vector unlocatedUniforms; + std::map preLocatedUniforms; + + for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) + { + const LinkedUniform &uniform = mUniforms[uniformIndex]; + + if ((uniform.isBuiltIn() && !uniform.isEmulatedBuiltIn()) || + IsAtomicCounterType(uniform.type) || uniform.isFragmentInOut) + { + continue; + } + + int preSetLocation = uniformLocationBindings.getBinding(uniform); + int shaderLocation = uniform.location; + + if (shaderLocation != -1) + { + preSetLocation = shaderLocation; + } + + unsigned int elementCount = uniform.getBasicTypeElementCount(); + for (unsigned int arrayIndex = 0; arrayIndex < elementCount; arrayIndex++) + { + VariableLocation location(arrayIndex, static_cast(uniformIndex)); + + if ((arrayIndex == 0 && preSetLocation != -1) || shaderLocation != -1) + { + int elementLocation = preSetLocation + arrayIndex; + preLocatedUniforms[elementLocation] = location; + } + else + { + unlocatedUniforms.push_back(location); + } + } + } + + // Make enough space for all uniforms, with pre-set locations or not. + mUniformLocations.resize( + std::max(unlocatedUniforms.size() + preLocatedUniforms.size() + ignoredLocations.size(), + static_cast(maxUniformLocation + 1))); + + // Assign uniforms with pre-set locations + for (const auto &uniform : preLocatedUniforms) + { + mUniformLocations[uniform.first] = uniform.second; + } + + // Assign ignored uniforms + for (const auto &ignoredLocation : ignoredLocations) + { + mUniformLocations[ignoredLocation].markIgnored(); + } + + // Automatically assign locations for the rest of the uniforms + size_t nextUniformLocation = 0; + for (const auto &unlocatedUniform : unlocatedUniforms) + { + while (mUniformLocations[nextUniformLocation].used() || + mUniformLocations[nextUniformLocation].ignored) + { + nextUniformLocation++; + } + + ASSERT(nextUniformLocation < mUniformLocations.size()); + mUniformLocations[nextUniformLocation] = unlocatedUniform; + nextUniformLocation++; + } + + return true; +} + +bool UniformLinker::gatherUniformLocationsAndCheckConflicts( + InfoLog &infoLog, + const ProgramAliasedBindings &uniformLocationBindings, + std::set *ignoredLocations, + int *maxUniformLocation) +{ + // All the locations where another uniform can't be located. + std::set reservedLocations; + + for (const LinkedUniform &uniform : mUniforms) + { + if ((uniform.isBuiltIn() && !uniform.isEmulatedBuiltIn()) || uniform.isFragmentInOut) + { + // The uniform of the fragment inout is not a normal uniform type. So, in the case of + // the fragment inout, this routine should be skipped. + continue; + } + + int apiBoundLocation = uniformLocationBindings.getBinding(uniform); + int shaderLocation = uniform.location; + + if (shaderLocation != -1) + { + unsigned int elementCount = uniform.getBasicTypeElementCount(); + + for (unsigned int arrayIndex = 0; arrayIndex < elementCount; arrayIndex++) + { + // GLSL ES 3.10 section 4.4.3 + int elementLocation = shaderLocation + arrayIndex; + *maxUniformLocation = std::max(*maxUniformLocation, elementLocation); + if (reservedLocations.find(elementLocation) != reservedLocations.end()) + { + infoLog << "Multiple uniforms bound to location " << elementLocation << "."; + return false; + } + reservedLocations.insert(elementLocation); + if (!uniform.active) + { + ignoredLocations->insert(elementLocation); + } + } + } + else if (apiBoundLocation != -1 && uniform.staticUse) + { + // Only the first location is reserved even if the uniform is an array. + *maxUniformLocation = std::max(*maxUniformLocation, apiBoundLocation); + if (reservedLocations.find(apiBoundLocation) != reservedLocations.end()) + { + infoLog << "Multiple uniforms bound to location " << apiBoundLocation << "."; + return false; + } + reservedLocations.insert(apiBoundLocation); + if (!uniform.active) + { + ignoredLocations->insert(apiBoundLocation); + } + } + } + + // Record the uniform locations that were bound using the API for uniforms that were not found + // from the shader. Other uniforms should not be assigned to those locations. + for (const auto &locationBinding : uniformLocationBindings) + { + GLuint location = locationBinding.second.location; + if (reservedLocations.find(location) == reservedLocations.end()) + { + ignoredLocations->insert(location); + *maxUniformLocation = std::max(*maxUniformLocation, static_cast(location)); + } + } + + return true; +} + +void UniformLinker::pruneUnusedUniforms() +{ + auto uniformIter = mUniforms.begin(); + while (uniformIter != mUniforms.end()) + { + if (uniformIter->active) + { + ++uniformIter; + } + else + { + mUnusedUniforms.emplace_back(uniformIter->name, uniformIter->isSampler(), + uniformIter->isImage(), uniformIter->isAtomicCounter(), + uniformIter->isFragmentInOut); + uniformIter = mUniforms.erase(uniformIter); + } + } +} + +bool UniformLinker::flattenUniformsAndCheckCapsForShader( + ShaderType shaderType, + const Caps &caps, + std::vector &samplerUniforms, + std::vector &imageUniforms, + std::vector &atomicCounterUniforms, + std::vector &inputAttachmentUniforms, + std::vector &unusedUniforms, + InfoLog &infoLog) +{ + ShaderUniformCount shaderUniformCount; + for (const sh::ShaderVariable &uniform : mShaderUniforms[shaderType]) + { + FlattenUniformVisitor flattener(shaderType, uniform, &mUniforms, &samplerUniforms, + &imageUniforms, &atomicCounterUniforms, + &inputAttachmentUniforms, &unusedUniforms); + sh::TraverseShaderVariable(uniform, false, &flattener); + + if (uniform.active) + { + shaderUniformCount += flattener.getCounts(); + } + else + { + unusedUniforms.emplace_back(uniform.name, IsSamplerType(uniform.type), + IsImageType(uniform.type), + IsAtomicCounterType(uniform.type), uniform.isFragmentInOut); + } + } + + // This code does not do fine-grained component counting. + GLuint maxUniformVectorsCount = GetMaximumShaderUniformVectors(shaderType, caps); + if (shaderUniformCount.vectorCount > maxUniformVectorsCount) + { + GLuint maxUniforms = 0u; + + // See comments in GetUniformResourceLimitName() + if (shaderType == ShaderType::Vertex || shaderType == ShaderType::Fragment) + { + maxUniforms = maxUniformVectorsCount; + } + else + { + maxUniforms = maxUniformVectorsCount * 4; + } + + LogUniformsExceedLimit(shaderType, UniformType::Variable, maxUniforms, infoLog); + return false; + } + + if (shaderUniformCount.samplerCount > + static_cast(caps.maxShaderTextureImageUnits[shaderType])) + { + LogUniformsExceedLimit(shaderType, UniformType::Sampler, + caps.maxShaderTextureImageUnits[shaderType], infoLog); + return false; + } + + if (shaderUniformCount.imageCount > + static_cast(caps.maxShaderImageUniforms[shaderType])) + { + LogUniformsExceedLimit(shaderType, UniformType::Image, + caps.maxShaderImageUniforms[shaderType], infoLog); + return false; + } + + if (shaderUniformCount.atomicCounterCount > + static_cast(caps.maxShaderAtomicCounters[shaderType])) + { + LogUniformsExceedLimit(shaderType, UniformType::AtomicCounter, + caps.maxShaderAtomicCounters[shaderType], infoLog); + return false; + } + + return true; +} + +bool UniformLinker::flattenUniformsAndCheckCaps(const Caps &caps, InfoLog &infoLog) +{ + std::vector samplerUniforms; + std::vector imageUniforms; + std::vector atomicCounterUniforms; + std::vector inputAttachmentUniforms; + std::vector unusedUniforms; + + for (const ShaderType shaderType : mActiveShaderStages) + { + if (!flattenUniformsAndCheckCapsForShader(shaderType, caps, samplerUniforms, imageUniforms, + atomicCounterUniforms, inputAttachmentUniforms, + unusedUniforms, infoLog)) + { + return false; + } + } + + mUniforms.insert(mUniforms.end(), samplerUniforms.begin(), samplerUniforms.end()); + mUniforms.insert(mUniforms.end(), imageUniforms.begin(), imageUniforms.end()); + mUniforms.insert(mUniforms.end(), atomicCounterUniforms.begin(), atomicCounterUniforms.end()); + mUniforms.insert(mUniforms.end(), inputAttachmentUniforms.begin(), + inputAttachmentUniforms.end()); + mUnusedUniforms.insert(mUnusedUniforms.end(), unusedUniforms.begin(), unusedUniforms.end()); + return true; +} + +bool UniformLinker::checkMaxCombinedAtomicCounters(const Caps &caps, InfoLog &infoLog) +{ + unsigned int atomicCounterCount = 0; + for (const auto &uniform : mUniforms) + { + if (IsAtomicCounterType(uniform.type) && uniform.active) + { + atomicCounterCount += uniform.getBasicTypeElementCount(); + if (atomicCounterCount > static_cast(caps.maxCombinedAtomicCounters)) + { + infoLog << "atomic counter count exceeds MAX_COMBINED_ATOMIC_COUNTERS" + << caps.maxCombinedAtomicCounters << ")."; + return false; + } + } + } + return true; +} + +// InterfaceBlockLinker implementation. +InterfaceBlockLinker::InterfaceBlockLinker() = default; + +InterfaceBlockLinker::~InterfaceBlockLinker() = default; + +void InterfaceBlockLinker::init(std::vector *blocksOut, + std::vector *unusedInterfaceBlocksOut) +{ + mBlocksOut = blocksOut; + mUnusedInterfaceBlocksOut = unusedInterfaceBlocksOut; +} + +void InterfaceBlockLinker::addShaderBlocks(ShaderType shaderType, + const std::vector *blocks) +{ + mShaderBlocks[shaderType] = blocks; +} + +void InterfaceBlockLinker::linkBlocks(const GetBlockSizeFunc &getBlockSize, + const GetBlockMemberInfoFunc &getMemberInfo) const +{ + ASSERT(mBlocksOut->empty()); + + std::set visitedList; + + for (const ShaderType shaderType : AllShaderTypes()) + { + if (!mShaderBlocks[shaderType]) + { + continue; + } + + for (const sh::InterfaceBlock &block : *mShaderBlocks[shaderType]) + { + if (!IsActiveInterfaceBlock(block)) + { + mUnusedInterfaceBlocksOut->push_back(block.name); + continue; + } + + if (visitedList.count(block.name) == 0) + { + defineInterfaceBlock(getBlockSize, getMemberInfo, block, shaderType); + visitedList.insert(block.name); + continue; + } + + if (!block.active) + { + mUnusedInterfaceBlocksOut->push_back(block.name); + continue; + } + + for (InterfaceBlock &priorBlock : *mBlocksOut) + { + if (block.name == priorBlock.name) + { + priorBlock.setActive(shaderType, true); + + std::unique_ptr visitor( + getVisitor(getMemberInfo, block.fieldPrefix(), block.fieldMappedPrefix(), + shaderType, -1)); + + sh::TraverseShaderVariables(block.fields, false, visitor.get()); + } + } + } + } +} + +void InterfaceBlockLinker::defineInterfaceBlock(const GetBlockSizeFunc &getBlockSize, + const GetBlockMemberInfoFunc &getMemberInfo, + const sh::InterfaceBlock &interfaceBlock, + ShaderType shaderType) const +{ + size_t blockSize = 0; + std::vector blockIndexes; + + int blockIndex = static_cast(mBlocksOut->size()); + // Track the first and last block member index to determine the range of active block members in + // the block. + size_t firstBlockMemberIndex = getCurrentBlockMemberIndex(); + + std::unique_ptr visitor( + getVisitor(getMemberInfo, interfaceBlock.fieldPrefix(), interfaceBlock.fieldMappedPrefix(), + shaderType, blockIndex)); + sh::TraverseShaderVariables(interfaceBlock.fields, false, visitor.get()); + + size_t lastBlockMemberIndex = getCurrentBlockMemberIndex(); + + for (size_t blockMemberIndex = firstBlockMemberIndex; blockMemberIndex < lastBlockMemberIndex; + ++blockMemberIndex) + { + blockIndexes.push_back(static_cast(blockMemberIndex)); + } + + unsigned int firstFieldArraySize = interfaceBlock.fields[0].getArraySizeProduct(); + + for (unsigned int arrayElement = 0; arrayElement < interfaceBlock.elementCount(); + ++arrayElement) + { + std::string blockArrayName = interfaceBlock.name; + std::string blockMappedArrayName = interfaceBlock.mappedName; + if (interfaceBlock.isArray()) + { + blockArrayName += ArrayString(arrayElement); + blockMappedArrayName += ArrayString(arrayElement); + } + + // Don't define this block at all if it's not active in the implementation. + if (!getBlockSize(blockArrayName, blockMappedArrayName, &blockSize)) + { + continue; + } + + // ESSL 3.10 section 4.4.4 page 58: + // Any uniform or shader storage block declared without a binding qualifier is initially + // assigned to block binding point zero. + int blockBinding = + (interfaceBlock.binding == -1 ? 0 : interfaceBlock.binding + arrayElement); + InterfaceBlock block(interfaceBlock.name, interfaceBlock.mappedName, + interfaceBlock.isArray(), arrayElement, firstFieldArraySize, + blockBinding); + block.memberIndexes = blockIndexes; + block.setActive(shaderType, interfaceBlock.active); + + // Since all block elements in an array share the same active interface blocks, they + // will all be active once any block member is used. So, since interfaceBlock.name[0] + // was active, here we will add every block element in the array. + block.dataSize = static_cast(blockSize); + mBlocksOut->push_back(block); + } +} + +// UniformBlockLinker implementation. +UniformBlockLinker::UniformBlockLinker() = default; + +UniformBlockLinker::~UniformBlockLinker() {} + +void UniformBlockLinker::init(std::vector *blocksOut, + std::vector *uniformsOut, + std::vector *unusedInterfaceBlocksOut) +{ + InterfaceBlockLinker::init(blocksOut, unusedInterfaceBlocksOut); + mUniformsOut = uniformsOut; +} + +size_t UniformBlockLinker::getCurrentBlockMemberIndex() const +{ + return mUniformsOut->size(); +} + +sh::ShaderVariableVisitor *UniformBlockLinker::getVisitor( + const GetBlockMemberInfoFunc &getMemberInfo, + const std::string &namePrefix, + const std::string &mappedNamePrefix, + ShaderType shaderType, + int blockIndex) const +{ + return new UniformBlockEncodingVisitor(getMemberInfo, namePrefix, mappedNamePrefix, + mUniformsOut, shaderType, blockIndex); +} + +// ShaderStorageBlockLinker implementation. +ShaderStorageBlockLinker::ShaderStorageBlockLinker() = default; + +ShaderStorageBlockLinker::~ShaderStorageBlockLinker() = default; + +void ShaderStorageBlockLinker::init(std::vector *blocksOut, + std::vector *bufferVariablesOut, + std::vector *unusedInterfaceBlocksOut) +{ + InterfaceBlockLinker::init(blocksOut, unusedInterfaceBlocksOut); + mBufferVariablesOut = bufferVariablesOut; +} + +size_t ShaderStorageBlockLinker::getCurrentBlockMemberIndex() const +{ + return mBufferVariablesOut->size(); +} + +sh::ShaderVariableVisitor *ShaderStorageBlockLinker::getVisitor( + const GetBlockMemberInfoFunc &getMemberInfo, + const std::string &namePrefix, + const std::string &mappedNamePrefix, + ShaderType shaderType, + int blockIndex) const +{ + return new ShaderStorageBlockVisitor(getMemberInfo, namePrefix, mappedNamePrefix, + mBufferVariablesOut, shaderType, blockIndex); +} + +// AtomicCounterBufferLinker implementation. +AtomicCounterBufferLinker::AtomicCounterBufferLinker() = default; + +AtomicCounterBufferLinker::~AtomicCounterBufferLinker() = default; + +void AtomicCounterBufferLinker::init(std::vector *atomicCounterBuffersOut) +{ + mAtomicCounterBuffersOut = atomicCounterBuffersOut; +} + +void AtomicCounterBufferLinker::link(const std::map &sizeMap) const +{ + for (auto &atomicCounterBuffer : *mAtomicCounterBuffersOut) + { + auto bufferSize = sizeMap.find(atomicCounterBuffer.binding); + ASSERT(bufferSize != sizeMap.end()); + atomicCounterBuffer.dataSize = bufferSize->second; + } +} + +ProgramLinkedResources::ProgramLinkedResources() = default; + +ProgramLinkedResources::~ProgramLinkedResources() = default; + +LinkingVariables::LinkingVariables(const Context *context, const ProgramState &state) +{ + for (ShaderType shaderType : kAllGraphicsShaderTypes) + { + Shader *shader = state.getAttachedShader(shaderType); + if (shader) + { + outputVaryings[shaderType] = shader->getOutputVaryings(context); + inputVaryings[shaderType] = shader->getInputVaryings(context); + uniforms[shaderType] = shader->getUniforms(context); + uniformBlocks[shaderType] = shader->getUniformBlocks(context); + isShaderStageUsedBitset.set(shaderType); + } + } +} + +LinkingVariables::LinkingVariables(const ProgramPipelineState &state) +{ + for (ShaderType shaderType : state.getExecutable().getLinkedShaderStages()) + { + const Program *program = state.getShaderProgram(shaderType); + ASSERT(program); + outputVaryings[shaderType] = program->getExecutable().getLinkedOutputVaryings(shaderType); + inputVaryings[shaderType] = program->getExecutable().getLinkedInputVaryings(shaderType); + uniforms[shaderType] = program->getState().getExecutable().getLinkedUniforms(shaderType); + uniformBlocks[shaderType] = + program->getState().getExecutable().getLinkedUniformBlocks(shaderType); + isShaderStageUsedBitset.set(shaderType); + } +} + +LinkingVariables::~LinkingVariables() = default; + +void ProgramLinkedResources::init(std::vector *uniformBlocksOut, + std::vector *uniformsOut, + std::vector *shaderStorageBlocksOut, + std::vector *bufferVariablesOut, + std::vector *atomicCounterBuffersOut) +{ + uniformBlockLinker.init(uniformBlocksOut, uniformsOut, &unusedInterfaceBlocks); + shaderStorageBlockLinker.init(shaderStorageBlocksOut, bufferVariablesOut, + &unusedInterfaceBlocks); + atomicCounterBufferLinker.init(atomicCounterBuffersOut); +} + +void ProgramLinkedResourcesLinker::linkResources(const Context *context, + const ProgramState &programState, + const ProgramLinkedResources &resources) const +{ + // Gather uniform interface block info. + InterfaceBlockInfo uniformBlockInfo(mCustomEncoderFactory); + for (const ShaderType shaderType : AllShaderTypes()) + { + Shader *shader = programState.getAttachedShader(shaderType); + if (shader) + { + uniformBlockInfo.getShaderBlockInfo(shader->getUniformBlocks(context)); + } + } + + auto getUniformBlockSize = [&uniformBlockInfo](const std::string &name, + const std::string &mappedName, size_t *sizeOut) { + return uniformBlockInfo.getBlockSize(name, mappedName, sizeOut); + }; + + auto getUniformBlockMemberInfo = [&uniformBlockInfo](const std::string &name, + const std::string &mappedName, + sh::BlockMemberInfo *infoOut) { + return uniformBlockInfo.getBlockMemberInfo(name, mappedName, infoOut); + }; + + // Link uniform interface blocks. + resources.uniformBlockLinker.linkBlocks(getUniformBlockSize, getUniformBlockMemberInfo); + + // Gather storage buffer interface block info. + InterfaceBlockInfo shaderStorageBlockInfo(mCustomEncoderFactory); + for (const ShaderType shaderType : AllShaderTypes()) + { + Shader *shader = programState.getAttachedShader(shaderType); + if (shader) + { + shaderStorageBlockInfo.getShaderBlockInfo(shader->getShaderStorageBlocks(context)); + } + } + auto getShaderStorageBlockSize = [&shaderStorageBlockInfo](const std::string &name, + const std::string &mappedName, + size_t *sizeOut) { + return shaderStorageBlockInfo.getBlockSize(name, mappedName, sizeOut); + }; + + auto getShaderStorageBlockMemberInfo = [&shaderStorageBlockInfo](const std::string &name, + const std::string &mappedName, + sh::BlockMemberInfo *infoOut) { + return shaderStorageBlockInfo.getBlockMemberInfo(name, mappedName, infoOut); + }; + + // Link storage buffer interface blocks. + resources.shaderStorageBlockLinker.linkBlocks(getShaderStorageBlockSize, + getShaderStorageBlockMemberInfo); + + // Gather and link atomic counter buffer interface blocks. + std::map sizeMap; + getAtomicCounterBufferSizeMap(programState, sizeMap); + resources.atomicCounterBufferLinker.link(sizeMap); +} + +void ProgramLinkedResourcesLinker::getAtomicCounterBufferSizeMap( + const ProgramState &programState, + std::map &sizeMapOut) const +{ + for (unsigned int index : programState.getAtomicCounterUniformRange()) + { + const LinkedUniform &glUniform = programState.getUniforms()[index]; + + auto &bufferDataSize = sizeMapOut[glUniform.binding]; + + // Calculate the size of the buffer by finding the end of the last uniform with the same + // binding. The end of the uniform is calculated by finding the initial offset of the + // uniform and adding size of the uniform. For arrays, the size is the number of elements + // times the element size (should always by 4 for atomic_units). + unsigned dataOffset = + glUniform.offset + static_cast(glUniform.getBasicTypeElementCount() * + glUniform.getElementSize()); + if (dataOffset > bufferDataSize) + { + bufferDataSize = dataOffset; + } + } +} + +bool LinkValidateProgramGlobalNames(InfoLog &infoLog, + const ProgramExecutable &executable, + const LinkingVariables &linkingVariables) +{ + angle::HashMap uniformMap; + using BlockAndFieldPair = std::pair; + angle::HashMap> uniformBlockFieldMap; + + for (ShaderType shaderType : kAllGraphicsShaderTypes) + { + if (!linkingVariables.isShaderStageUsedBitset[shaderType]) + { + continue; + } + + // Build a map of Uniforms + const std::vector &uniforms = linkingVariables.uniforms[shaderType]; + for (const auto &uniform : uniforms) + { + uniformMap[uniform.name] = &uniform; + } + + // Build a map of Uniform Blocks + // This will also detect any field name conflicts between Uniform Blocks without instance + // names + const std::vector &uniformBlocks = + linkingVariables.uniformBlocks[shaderType]; + + for (const auto &uniformBlock : uniformBlocks) + { + // Only uniform blocks without an instance name can create a conflict with their field + // names + if (!uniformBlock.instanceName.empty()) + { + continue; + } + + for (const auto &field : uniformBlock.fields) + { + if (!uniformBlockFieldMap.count(field.name)) + { + // First time we've seen this uniform block field name, so add the + // (Uniform Block, Field) pair immediately since there can't be a conflict yet + BlockAndFieldPair blockAndFieldPair(&uniformBlock, &field); + std::vector newUniformBlockList; + newUniformBlockList.push_back(blockAndFieldPair); + uniformBlockFieldMap[field.name] = newUniformBlockList; + continue; + } + + // We've seen this name before. + // We need to check each of the uniform blocks that contain a field with this name + // to see if there's a conflict or not. + std::vector prevBlockFieldPairs = + uniformBlockFieldMap[field.name]; + for (const auto &prevBlockFieldPair : prevBlockFieldPairs) + { + const sh::InterfaceBlock *prevUniformBlock = prevBlockFieldPair.first; + const sh::ShaderVariable *prevUniformBlockField = prevBlockFieldPair.second; + + if (uniformBlock.isSameInterfaceBlockAtLinkTime(*prevUniformBlock)) + { + // The same uniform block should, by definition, contain the same field name + continue; + } + + // The uniform blocks don't match, so check if the necessary field properties + // also match + if ((field.name == prevUniformBlockField->name) && + (field.type == prevUniformBlockField->type) && + (field.precision == prevUniformBlockField->precision)) + { + infoLog << "Name conflicts between uniform block field names: " + << field.name; + return false; + } + } + + // No conflict, so record this pair + BlockAndFieldPair blockAndFieldPair(&uniformBlock, &field); + uniformBlockFieldMap[field.name].push_back(blockAndFieldPair); + } + } + } + + // Validate no uniform names conflict with attribute names + if (linkingVariables.isShaderStageUsedBitset[ShaderType::Vertex]) + { + // ESSL 3.00.6 section 4.3.5: + // If a uniform variable name is declared in one stage (e.g., a vertex shader) + // but not in another (e.g., a fragment shader), then that name is still + // available in the other stage for a different use. + std::unordered_set uniforms; + for (const sh::ShaderVariable &uniform : linkingVariables.uniforms[ShaderType::Vertex]) + { + uniforms.insert(uniform.name); + } + for (const auto &attrib : executable.getProgramInputs()) + { + if (uniforms.count(attrib.name)) + { + infoLog << "Name conflicts between a uniform and an attribute: " << attrib.name; + return false; + } + } + } + + // Validate no Uniform Block fields conflict with other Uniforms + for (const auto &uniformBlockField : uniformBlockFieldMap) + { + const std::string &fieldName = uniformBlockField.first; + if (uniformMap.count(fieldName)) + { + infoLog << "Name conflicts between a uniform and a uniform block field: " << fieldName; + return false; + } + } + + return true; +} + +// [OpenGL ES 3.2] Chapter 7.4.1 "Shader Interface Matching" +bool LinkValidateShaderInterfaceMatching(const std::vector &outputVaryings, + const std::vector &inputVaryings, + ShaderType frontShaderType, + ShaderType backShaderType, + int frontShaderVersion, + int backShaderVersion, + bool isSeparable, + gl::InfoLog &infoLog) +{ + ASSERT(frontShaderVersion == backShaderVersion); + + std::vector filteredInputVaryings; + std::vector filteredOutputVaryings; + + GetFilteredVaryings(inputVaryings, &filteredInputVaryings); + GetFilteredVaryings(outputVaryings, &filteredOutputVaryings); + + // Separable programs require the number of inputs and outputs match + if (isSeparable && filteredInputVaryings.size() < filteredOutputVaryings.size()) + { + infoLog << GetShaderTypeString(backShaderType) + << " does not consume all varyings generated by " + << GetShaderTypeString(frontShaderType); + return false; + } + if (isSeparable && filteredInputVaryings.size() > filteredOutputVaryings.size()) + { + infoLog << GetShaderTypeString(frontShaderType) + << " does not generate all varyings consumed by " + << GetShaderTypeString(backShaderType); + return false; + } + + // All inputs must match all outputs + for (const sh::ShaderVariable *input : filteredInputVaryings) + { + bool match = false; + for (const sh::ShaderVariable *output : filteredOutputVaryings) + { + if (DoShaderVariablesMatch(frontShaderVersion, frontShaderType, backShaderType, *input, + *output, isSeparable, infoLog)) + { + match = true; + break; + } + } + + // We permit unmatched, unreferenced varyings. Note that this specifically depends on + // whether the input is statically used - a statically used input should fail this test even + // if it is not active. GLSL ES 3.00.6 section 4.3.10. + if (!match && input->staticUse) + { + const std::string &name = + input->isShaderIOBlock ? input->structOrBlockName : input->name; + infoLog << GetShaderTypeString(backShaderType) << " varying " << name + << " does not match any " << GetShaderTypeString(frontShaderType) << " varying"; + return false; + } + } + + return true; +} + +LinkMismatchError LinkValidateProgramVariables(const sh::ShaderVariable &variable1, + const sh::ShaderVariable &variable2, + bool validatePrecision, + bool treatVariable1AsNonArray, + bool treatVariable2AsNonArray, + std::string *mismatchedStructOrBlockMemberName) +{ + if (variable1.type != variable2.type) + { + return LinkMismatchError::TYPE_MISMATCH; + } + + bool variable1IsArray = variable1.isArray(); + bool variable2IsArray = variable2.isArray(); + if (treatVariable1AsNonArray) + { + ASSERT(variable1IsArray); + variable1IsArray = false; + } + if (treatVariable2AsNonArray) + { + ASSERT(variable2IsArray); + variable2IsArray = false; + } + // TODO(anglebug.com/5557): Investigate interactions with arrays-of-arrays. + if (variable1IsArray != variable2IsArray) + { + return LinkMismatchError::ARRAYNESS_MISMATCH; + } + if (!treatVariable1AsNonArray && !treatVariable2AsNonArray && + variable1.arraySizes != variable2.arraySizes) + { + return LinkMismatchError::ARRAY_SIZE_MISMATCH; + } + if (validatePrecision && variable1.precision != variable2.precision) + { + return LinkMismatchError::PRECISION_MISMATCH; + } + if (!variable1.isShaderIOBlock && !variable2.isShaderIOBlock && + variable1.structOrBlockName != variable2.structOrBlockName) + { + return LinkMismatchError::STRUCT_NAME_MISMATCH; + } + if (variable1.imageUnitFormat != variable2.imageUnitFormat) + { + return LinkMismatchError::FORMAT_MISMATCH; + } + + if (variable1.fields.size() != variable2.fields.size()) + { + return LinkMismatchError::FIELD_NUMBER_MISMATCH; + } + const unsigned int numMembers = static_cast(variable1.fields.size()); + for (unsigned int memberIndex = 0; memberIndex < numMembers; memberIndex++) + { + const sh::ShaderVariable &member1 = variable1.fields[memberIndex]; + const sh::ShaderVariable &member2 = variable2.fields[memberIndex]; + + if (member1.name != member2.name) + { + return LinkMismatchError::FIELD_NAME_MISMATCH; + } + + if (member1.interpolation != member2.interpolation) + { + return LinkMismatchError::INTERPOLATION_TYPE_MISMATCH; + } + + if (variable1.isShaderIOBlock && variable2.isShaderIOBlock) + { + if (member1.location != member2.location) + { + return LinkMismatchError::FIELD_LOCATION_MISMATCH; + } + + if (member1.structOrBlockName != member2.structOrBlockName) + { + return LinkMismatchError::FIELD_STRUCT_NAME_MISMATCH; + } + } + + LinkMismatchError linkErrorOnField = LinkValidateProgramVariables( + member1, member2, validatePrecision, false, false, mismatchedStructOrBlockMemberName); + if (linkErrorOnField != LinkMismatchError::NO_MISMATCH) + { + AddProgramVariableParentPrefix(member1.name, mismatchedStructOrBlockMemberName); + return linkErrorOnField; + } + } + + return LinkMismatchError::NO_MISMATCH; +} + +void AddProgramVariableParentPrefix(const std::string &parentName, std::string *mismatchedFieldName) +{ + ASSERT(mismatchedFieldName); + if (mismatchedFieldName->empty()) + { + *mismatchedFieldName = parentName; + } + else + { + std::ostringstream stream; + stream << parentName << "." << *mismatchedFieldName; + *mismatchedFieldName = stream.str(); + } +} + +bool LinkValidateBuiltInVaryingsInvariant(const std::vector &vertexVaryings, + const std::vector &fragmentVaryings, + int vertexShaderVersion, + InfoLog &infoLog) +{ + bool glPositionIsInvariant = false; + bool glPointSizeIsInvariant = false; + bool glFragCoordIsInvariant = false; + bool glPointCoordIsInvariant = false; + + for (const sh::ShaderVariable &varying : vertexVaryings) + { + if (!varying.isBuiltIn()) + { + continue; + } + if (varying.name.compare("gl_Position") == 0) + { + glPositionIsInvariant = varying.isInvariant; + } + else if (varying.name.compare("gl_PointSize") == 0) + { + glPointSizeIsInvariant = varying.isInvariant; + } + } + + for (const sh::ShaderVariable &varying : fragmentVaryings) + { + if (!varying.isBuiltIn()) + { + continue; + } + if (varying.name.compare("gl_FragCoord") == 0) + { + glFragCoordIsInvariant = varying.isInvariant; + } + else if (varying.name.compare("gl_PointCoord") == 0) + { + glPointCoordIsInvariant = varying.isInvariant; + } + } + + // There is some ambiguity in ESSL 1.00.17 paragraph 4.6.4 interpretation, + // for example, https://cvs.khronos.org/bugzilla/show_bug.cgi?id=13842. + // Not requiring invariance to match is supported by: + // dEQP, WebGL CTS, Nexus 5X GLES + if (glFragCoordIsInvariant && !glPositionIsInvariant) + { + infoLog << "gl_FragCoord can only be declared invariant if and only if gl_Position is " + "declared invariant."; + return false; + } + if (glPointCoordIsInvariant && !glPointSizeIsInvariant) + { + infoLog << "gl_PointCoord can only be declared invariant if and only if gl_PointSize is " + "declared invariant."; + return false; + } + + return true; +} + +bool LinkValidateBuiltInVaryings(const std::vector &outputVaryings, + const std::vector &inputVaryings, + ShaderType outputShaderType, + ShaderType inputShaderType, + int outputShaderVersion, + int inputShaderVersion, + InfoLog &infoLog) +{ + ASSERT(outputShaderVersion == inputShaderVersion); + + // Only ESSL 1.0 has restrictions on matching input and output invariance + if (inputShaderVersion == 100 && outputShaderType == ShaderType::Vertex && + inputShaderType == ShaderType::Fragment) + { + return LinkValidateBuiltInVaryingsInvariant(outputVaryings, inputVaryings, + outputShaderVersion, infoLog); + } + + uint32_t sizeClipDistance = 0; + uint32_t sizeCullDistance = 0; + + for (const sh::ShaderVariable &varying : outputVaryings) + { + if (!varying.isBuiltIn()) + { + continue; + } + if (varying.name.compare("gl_ClipDistance") == 0) + { + sizeClipDistance = varying.getOutermostArraySize(); + } + else if (varying.name.compare("gl_CullDistance") == 0) + { + sizeCullDistance = varying.getOutermostArraySize(); + } + } + + for (const sh::ShaderVariable &varying : inputVaryings) + { + if (!varying.isBuiltIn()) + { + continue; + } + if (varying.name.compare("gl_ClipDistance") == 0) + { + if (sizeClipDistance != varying.getOutermostArraySize()) + { + infoLog << "If either shader redeclares the built-in arrays gl_ClipDistance[] the " + "array must have the same size in both shaders."; + return false; + } + } + else if (varying.name.compare("gl_CullDistance") == 0) + { + if (sizeCullDistance != varying.getOutermostArraySize()) + { + infoLog << "If either shader redeclares the built-in arrays gl_CullDistance[] the " + "array must have the same size in both shaders."; + return false; + } + } + } + return true; +} + +void LogAmbiguousFieldLinkMismatch(InfoLog &infoLog, + const std::string &blockName1, + const std::string &blockName2, + const std::string &fieldName, + ShaderType shaderType1, + ShaderType shaderType2) +{ + infoLog << "Ambiguous field '" << fieldName << "' in blocks '" << blockName1 << "' (" + << GetShaderTypeString(shaderType1) << " shader) and '" << blockName2 << "' (" + << GetShaderTypeString(shaderType2) << " shader) which don't have instance names."; +} + +bool ValidateInstancelessGraphicsInterfaceBlocksPerShader( + const std::vector &interfaceBlocks, + ShaderType shaderType, + InterfaceBlockMap *instancelessBlocksFields, + InfoLog &infoLog) +{ + ASSERT(instancelessBlocksFields); + + for (const sh::InterfaceBlock &block : interfaceBlocks) + { + if (!block.instanceName.empty()) + { + continue; + } + + for (const sh::ShaderVariable &field : block.fields) + { + const auto &entry = instancelessBlocksFields->find(field.name); + if (entry != instancelessBlocksFields->end()) + { + const sh::InterfaceBlock &linkedBlock = *(entry->second.second); + if (block.name != linkedBlock.name) + { + LogAmbiguousFieldLinkMismatch(infoLog, block.name, linkedBlock.name, field.name, + entry->second.first, shaderType); + return false; + } + } + else + { + (*instancelessBlocksFields)[field.name] = std::make_pair(shaderType, &block); + } + } + } + + return true; +} + +LinkMismatchError LinkValidateInterfaceBlockFields(const sh::ShaderVariable &blockField1, + const sh::ShaderVariable &blockField2, + bool webglCompatibility, + std::string *mismatchedBlockFieldName) +{ + if (blockField1.name != blockField2.name) + { + return LinkMismatchError::FIELD_NAME_MISMATCH; + } + + // If webgl, validate precision of UBO fields, otherwise don't. See Khronos bug 10287. + LinkMismatchError linkError = LinkValidateProgramVariables( + blockField1, blockField2, webglCompatibility, false, false, mismatchedBlockFieldName); + if (linkError != LinkMismatchError::NO_MISMATCH) + { + AddProgramVariableParentPrefix(blockField1.name, mismatchedBlockFieldName); + return linkError; + } + + if (blockField1.isRowMajorLayout != blockField2.isRowMajorLayout) + { + AddProgramVariableParentPrefix(blockField1.name, mismatchedBlockFieldName); + return LinkMismatchError::MATRIX_PACKING_MISMATCH; + } + + return LinkMismatchError::NO_MISMATCH; +} + +LinkMismatchError AreMatchingInterfaceBlocks(const sh::InterfaceBlock &interfaceBlock1, + const sh::InterfaceBlock &interfaceBlock2, + bool webglCompatibility, + std::string *mismatchedBlockFieldName) +{ + // validate blocks for the same member types + if (interfaceBlock1.fields.size() != interfaceBlock2.fields.size()) + { + return LinkMismatchError::FIELD_NUMBER_MISMATCH; + } + if (interfaceBlock1.arraySize != interfaceBlock2.arraySize) + { + return LinkMismatchError::ARRAY_SIZE_MISMATCH; + } + if (interfaceBlock1.layout != interfaceBlock2.layout || + interfaceBlock1.binding != interfaceBlock2.binding) + { + return LinkMismatchError::LAYOUT_QUALIFIER_MISMATCH; + } + if (interfaceBlock1.instanceName.empty() != interfaceBlock2.instanceName.empty()) + { + return LinkMismatchError::INSTANCE_NAME_MISMATCH; + } + const unsigned int numBlockMembers = static_cast(interfaceBlock1.fields.size()); + for (unsigned int blockMemberIndex = 0; blockMemberIndex < numBlockMembers; blockMemberIndex++) + { + const sh::ShaderVariable &member1 = interfaceBlock1.fields[blockMemberIndex]; + const sh::ShaderVariable &member2 = interfaceBlock2.fields[blockMemberIndex]; + + LinkMismatchError linkError = LinkValidateInterfaceBlockFields( + member1, member2, webglCompatibility, mismatchedBlockFieldName); + if (linkError != LinkMismatchError::NO_MISMATCH) + { + return linkError; + } + } + return LinkMismatchError::NO_MISMATCH; +} + +void InitializeInterfaceBlockMap(const std::vector &interfaceBlocks, + ShaderType shaderType, + InterfaceBlockMap *linkedInterfaceBlocks) +{ + ASSERT(linkedInterfaceBlocks); + + for (const sh::InterfaceBlock &interfaceBlock : interfaceBlocks) + { + (*linkedInterfaceBlocks)[interfaceBlock.name] = std::make_pair(shaderType, &interfaceBlock); + } +} + +bool ValidateGraphicsInterfaceBlocksPerShader( + const std::vector &interfaceBlocksToLink, + ShaderType shaderType, + bool webglCompatibility, + InterfaceBlockMap *linkedBlocks, + InfoLog &infoLog) +{ + ASSERT(linkedBlocks); + + for (const sh::InterfaceBlock &block : interfaceBlocksToLink) + { + const auto &entry = linkedBlocks->find(block.name); + if (entry != linkedBlocks->end()) + { + const sh::InterfaceBlock &linkedBlock = *(entry->second.second); + std::string mismatchedStructFieldName; + LinkMismatchError linkError = AreMatchingInterfaceBlocks( + block, linkedBlock, webglCompatibility, &mismatchedStructFieldName); + if (linkError != LinkMismatchError::NO_MISMATCH) + { + LogLinkMismatch(infoLog, block.name, GetInterfaceBlockTypeString(block.blockType), + linkError, mismatchedStructFieldName, entry->second.first, + shaderType); + return false; + } + } + else + { + (*linkedBlocks)[block.name] = std::make_pair(shaderType, &block); + } + } + + return true; +} + +bool ValidateInterfaceBlocksMatch( + GLuint numShadersHasInterfaceBlocks, + const ShaderMap *> &shaderInterfaceBlocks, + InfoLog &infoLog, + bool webglCompatibility, + InterfaceBlockMap *instancelessInterfaceBlocksFields) +{ + for (ShaderType shaderType : kAllGraphicsShaderTypes) + { + // Validate that instanceless blocks of different names don't have fields of the same name. + if (shaderInterfaceBlocks[shaderType] && + !ValidateInstancelessGraphicsInterfaceBlocksPerShader( + *shaderInterfaceBlocks[shaderType], shaderType, instancelessInterfaceBlocksFields, + infoLog)) + { + return false; + } + } + + if (numShadersHasInterfaceBlocks < 2u) + { + return true; + } + + ASSERT(!shaderInterfaceBlocks[ShaderType::Compute]); + + // Check that interface blocks defined in the graphics shaders are identical + + InterfaceBlockMap linkedInterfaceBlocks; + + bool interfaceBlockMapInitialized = false; + for (ShaderType shaderType : kAllGraphicsShaderTypes) + { + if (!shaderInterfaceBlocks[shaderType]) + { + continue; + } + + if (!interfaceBlockMapInitialized) + { + InitializeInterfaceBlockMap(*shaderInterfaceBlocks[shaderType], shaderType, + &linkedInterfaceBlocks); + interfaceBlockMapInitialized = true; + } + else if (!ValidateGraphicsInterfaceBlocksPerShader(*shaderInterfaceBlocks[shaderType], + shaderType, webglCompatibility, + &linkedInterfaceBlocks, infoLog)) + { + return false; + } + } + + return true; +} + +bool LinkValidateProgramInterfaceBlocks(const Context *context, + ShaderBitSet activeProgramStages, + const ProgramLinkedResources &resources, + InfoLog &infoLog, + GLuint *combinedShaderStorageBlocksCountOut) +{ + ASSERT(combinedShaderStorageBlocksCountOut); + + const Caps &caps = context->getCaps(); + const bool webglCompatibility = context->isWebGL(); + const Version &version = context->getClientVersion(); + + GLuint combinedUniformBlocksCount = 0u; + GLuint numShadersHasUniformBlocks = 0u; + ShaderMap *> allShaderUniformBlocks = {}; + InterfaceBlockMap instancelessInterfaceBlocksFields; + + for (ShaderType shaderType : activeProgramStages) + { + const std::vector &uniformBlocks = + resources.uniformBlockLinker.getShaderBlocks(shaderType); + if (!uniformBlocks.empty()) + { + if (!ValidateInterfaceBlocksCount( + static_cast(caps.maxShaderUniformBlocks[shaderType]), uniformBlocks, + shaderType, sh::BlockType::BLOCK_UNIFORM, &combinedUniformBlocksCount, infoLog)) + { + return false; + } + + allShaderUniformBlocks[shaderType] = &uniformBlocks; + ++numShadersHasUniformBlocks; + } + } + + if (combinedUniformBlocksCount > static_cast(caps.maxCombinedUniformBlocks)) + { + infoLog << "The sum of the number of active uniform blocks exceeds " + "MAX_COMBINED_UNIFORM_BLOCKS (" + << caps.maxCombinedUniformBlocks << ")."; + return false; + } + + if (!ValidateInterfaceBlocksMatch(numShadersHasUniformBlocks, allShaderUniformBlocks, infoLog, + webglCompatibility, &instancelessInterfaceBlocksFields)) + { + return false; + } + + if (version >= Version(3, 1)) + { + *combinedShaderStorageBlocksCountOut = 0u; + GLuint numShadersHasShaderStorageBlocks = 0u; + ShaderMap *> allShaderStorageBlocks = {}; + for (ShaderType shaderType : activeProgramStages) + { + const std::vector &shaderStorageBlocks = + resources.shaderStorageBlockLinker.getShaderBlocks(shaderType); + if (!shaderStorageBlocks.empty()) + { + if (!ValidateInterfaceBlocksCount( + static_cast(caps.maxShaderStorageBlocks[shaderType]), + shaderStorageBlocks, shaderType, sh::BlockType::BLOCK_BUFFER, + combinedShaderStorageBlocksCountOut, infoLog)) + { + return false; + } + + allShaderStorageBlocks[shaderType] = &shaderStorageBlocks; + ++numShadersHasShaderStorageBlocks; + } + } + + if (*combinedShaderStorageBlocksCountOut > + static_cast(caps.maxCombinedShaderStorageBlocks)) + { + infoLog << "The sum of the number of active shader storage blocks exceeds " + "MAX_COMBINED_SHADER_STORAGE_BLOCKS (" + << caps.maxCombinedShaderStorageBlocks << ")."; + return false; + } + + if (!ValidateInterfaceBlocksMatch(numShadersHasShaderStorageBlocks, allShaderStorageBlocks, + infoLog, webglCompatibility, + &instancelessInterfaceBlocksFields)) + { + return false; + } + } + + return true; +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/ProgramLinkedResources.h b/gfx/angle/checkout/src/libANGLE/ProgramLinkedResources.h new file mode 100644 index 0000000000..0bb6cbb96f --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/ProgramLinkedResources.h @@ -0,0 +1,333 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ProgramLinkedResources.h: implements link-time checks for default block uniforms, and generates +// uniform locations. Populates data structures related to uniforms so that they can be stored in +// program state. + +#ifndef LIBANGLE_UNIFORMLINKER_H_ +#define LIBANGLE_UNIFORMLINKER_H_ + +#include "angle_gl.h" +#include "common/PackedEnums.h" +#include "common/angleutils.h" +#include "libANGLE/VaryingPacking.h" + +#include + +namespace sh +{ +class BlockLayoutEncoder; +struct BlockMemberInfo; +struct InterfaceBlock; +struct ShaderVariable; +class BlockEncoderVisitor; +class ShaderVariableVisitor; +struct ShaderVariable; +} // namespace sh + +namespace gl +{ +struct BufferVariable; +struct Caps; +class Context; +class InfoLog; +struct InterfaceBlock; +enum class LinkMismatchError; +struct LinkedUniform; +class ProgramState; +class ProgramPipelineState; +class ProgramBindings; +class ProgramAliasedBindings; +class Shader; +struct ShaderVariableBuffer; +struct UnusedUniform; +struct VariableLocation; + +using AtomicCounterBuffer = ShaderVariableBuffer; +using ShaderUniform = std::pair; + +class UniformLinker final : angle::NonCopyable +{ + public: + UniformLinker(const ShaderBitSet &activeShaderStages, + const ShaderMap> &shaderUniforms); + ~UniformLinker(); + + bool link(const Caps &caps, + InfoLog &infoLog, + const ProgramAliasedBindings &uniformLocationBindings); + + void getResults(std::vector *uniforms, + std::vector *unusedUniformsOutOrNull, + std::vector *uniformLocationsOutOrNull); + + private: + bool validateGraphicsUniforms(InfoLog &infoLog) const; + bool validateGraphicsUniformsPerShader(ShaderType shaderToLink, + bool extendLinkedUniforms, + std::map *linkedUniforms, + InfoLog &infoLog) const; + bool flattenUniformsAndCheckCapsForShader(ShaderType shaderType, + const Caps &caps, + std::vector &samplerUniforms, + std::vector &imageUniforms, + std::vector &atomicCounterUniforms, + std::vector &inputAttachmentUniforms, + std::vector &unusedUniforms, + InfoLog &infoLog); + + bool flattenUniformsAndCheckCaps(const Caps &caps, InfoLog &infoLog); + bool checkMaxCombinedAtomicCounters(const Caps &caps, InfoLog &infoLog); + + bool indexUniforms(InfoLog &infoLog, const ProgramAliasedBindings &uniformLocationBindings); + bool gatherUniformLocationsAndCheckConflicts( + InfoLog &infoLog, + const ProgramAliasedBindings &uniformLocationBindings, + std::set *ignoredLocations, + int *maxUniformLocation); + void pruneUnusedUniforms(); + + ShaderBitSet mActiveShaderStages; + const ShaderMap> &mShaderUniforms; + std::vector mUniforms; + std::vector mUnusedUniforms; + std::vector mUniformLocations; +}; + +using GetBlockSizeFunc = std::function< + bool(const std::string &blockName, const std::string &blockMappedName, size_t *sizeOut)>; +using GetBlockMemberInfoFunc = std::function< + bool(const std::string &name, const std::string &mappedName, sh::BlockMemberInfo *infoOut)>; + +// This class is intended to be used during the link step to store interface block information. +// It is called by the Impl class during ProgramImpl::link so that it has access to the +// real block size and layout. +class InterfaceBlockLinker : angle::NonCopyable +{ + public: + virtual ~InterfaceBlockLinker(); + + // This is called once per shader stage. It stores a pointer to the block vector, so it's + // important that this class does not persist longer than the duration of Program::link. + void addShaderBlocks(ShaderType shader, const std::vector *blocks); + + // This is called once during a link operation, after all shader blocks are added. + void linkBlocks(const GetBlockSizeFunc &getBlockSize, + const GetBlockMemberInfoFunc &getMemberInfo) const; + + const std::vector &getShaderBlocks(ShaderType shaderType) const + { + ASSERT(mShaderBlocks[shaderType]); + return *mShaderBlocks[shaderType]; + } + + protected: + InterfaceBlockLinker(); + void init(std::vector *blocksOut, + std::vector *unusedInterfaceBlocksOut); + void defineInterfaceBlock(const GetBlockSizeFunc &getBlockSize, + const GetBlockMemberInfoFunc &getMemberInfo, + const sh::InterfaceBlock &interfaceBlock, + ShaderType shaderType) const; + + virtual size_t getCurrentBlockMemberIndex() const = 0; + + virtual sh::ShaderVariableVisitor *getVisitor(const GetBlockMemberInfoFunc &getMemberInfo, + const std::string &namePrefix, + const std::string &mappedNamePrefix, + ShaderType shaderType, + int blockIndex) const = 0; + + ShaderMap *> mShaderBlocks = {}; + + std::vector *mBlocksOut = nullptr; + std::vector *mUnusedInterfaceBlocksOut = nullptr; +}; + +class UniformBlockLinker final : public InterfaceBlockLinker +{ + public: + UniformBlockLinker(); + ~UniformBlockLinker() override; + + void init(std::vector *blocksOut, + std::vector *uniformsOut, + std::vector *unusedInterfaceBlocksOut); + + private: + size_t getCurrentBlockMemberIndex() const override; + + sh::ShaderVariableVisitor *getVisitor(const GetBlockMemberInfoFunc &getMemberInfo, + const std::string &namePrefix, + const std::string &mappedNamePrefix, + ShaderType shaderType, + int blockIndex) const override; + + std::vector *mUniformsOut = nullptr; +}; + +class ShaderStorageBlockLinker final : public InterfaceBlockLinker +{ + public: + ShaderStorageBlockLinker(); + ~ShaderStorageBlockLinker() override; + + void init(std::vector *blocksOut, + std::vector *bufferVariablesOut, + std::vector *unusedInterfaceBlocksOut); + + private: + size_t getCurrentBlockMemberIndex() const override; + + sh::ShaderVariableVisitor *getVisitor(const GetBlockMemberInfoFunc &getMemberInfo, + const std::string &namePrefix, + const std::string &mappedNamePrefix, + ShaderType shaderType, + int blockIndex) const override; + + std::vector *mBufferVariablesOut = nullptr; +}; + +class AtomicCounterBufferLinker final : angle::NonCopyable +{ + public: + AtomicCounterBufferLinker(); + ~AtomicCounterBufferLinker(); + + void init(std::vector *atomicCounterBuffersOut); + void link(const std::map &sizeMap) const; + + private: + std::vector *mAtomicCounterBuffersOut = nullptr; +}; + +// The link operation is responsible for finishing the link of uniform and interface blocks. +// This way it can filter out unreferenced resources and still have access to the info. +// TODO(jmadill): Integrate uniform linking/filtering as well as interface blocks. +struct UnusedUniform +{ + UnusedUniform(std::string name, + bool isSampler, + bool isImage, + bool isAtomicCounter, + bool isFragmentInOut) + { + this->name = name; + this->isSampler = isSampler; + this->isImage = isImage; + this->isAtomicCounter = isAtomicCounter; + this->isFragmentInOut = isFragmentInOut; + } + + std::string name; + bool isSampler; + bool isImage; + bool isAtomicCounter; + bool isFragmentInOut; +}; + +struct ProgramLinkedResources +{ + ProgramLinkedResources(); + ~ProgramLinkedResources(); + + void init(std::vector *uniformBlocksOut, + std::vector *uniformsOut, + std::vector *shaderStorageBlocksOut, + std::vector *bufferVariablesOut, + std::vector *atomicCounterBuffersOut); + + ProgramVaryingPacking varyingPacking; + UniformBlockLinker uniformBlockLinker; + ShaderStorageBlockLinker shaderStorageBlockLinker; + AtomicCounterBufferLinker atomicCounterBufferLinker; + std::vector unusedUniforms; + std::vector unusedInterfaceBlocks; +}; + +struct LinkingVariables final : private angle::NonCopyable +{ + LinkingVariables(const Context *context, const ProgramState &state); + LinkingVariables(const ProgramPipelineState &state); + ~LinkingVariables(); + + ShaderMap> outputVaryings; + ShaderMap> inputVaryings; + ShaderMap> uniforms; + ShaderMap> uniformBlocks; + ShaderBitSet isShaderStageUsedBitset; +}; + +class CustomBlockLayoutEncoderFactory : angle::NonCopyable +{ + public: + virtual ~CustomBlockLayoutEncoderFactory() {} + + virtual sh::BlockLayoutEncoder *makeEncoder() = 0; +}; + +// Used by the backends in Program*::linkResources to parse interface blocks and provide +// information to ProgramLinkedResources' linkers. +class ProgramLinkedResourcesLinker final : angle::NonCopyable +{ + public: + ProgramLinkedResourcesLinker(CustomBlockLayoutEncoderFactory *customEncoderFactory) + : mCustomEncoderFactory(customEncoderFactory) + {} + + void linkResources(const Context *context, + const ProgramState &programState, + const ProgramLinkedResources &resources) const; + + private: + void getAtomicCounterBufferSizeMap(const ProgramState &programState, + std::map &sizeMapOut) const; + + CustomBlockLayoutEncoderFactory *mCustomEncoderFactory; +}; + +using ShaderInterfaceBlock = std::pair; +using InterfaceBlockMap = std::map; + +bool LinkValidateProgramGlobalNames(InfoLog &infoLog, + const ProgramExecutable &executable, + const LinkingVariables &linkingVariables); +bool LinkValidateShaderInterfaceMatching(const std::vector &outputVaryings, + const std::vector &inputVaryings, + ShaderType frontShaderType, + ShaderType backShaderType, + int frontShaderVersion, + int backShaderVersion, + bool isSeparable, + InfoLog &infoLog); +bool LinkValidateBuiltInVaryingsInvariant(const std::vector &vertexVaryings, + const std::vector &fragmentVaryings, + int vertexShaderVersion, + InfoLog &infoLog); +bool LinkValidateBuiltInVaryings(const std::vector &inputVaryings, + const std::vector &outputVaryings, + ShaderType inputShaderType, + ShaderType outputShaderType, + int inputShaderVersion, + int outputShaderVersion, + InfoLog &infoLog); +LinkMismatchError LinkValidateProgramVariables(const sh::ShaderVariable &variable1, + const sh::ShaderVariable &variable2, + bool validatePrecision, + bool treatVariable1AsNonArray, + bool treatVariable2AsNonArray, + std::string *mismatchedStructOrBlockMemberName); +void AddProgramVariableParentPrefix(const std::string &parentName, + std::string *mismatchedFieldName); +bool LinkValidateProgramInterfaceBlocks(const Context *context, + ShaderBitSet activeProgramStages, + const ProgramLinkedResources &resources, + InfoLog &infoLog, + GLuint *combinedShaderStorageBlocksCountOut); +} // namespace gl + +#endif // LIBANGLE_UNIFORMLINKER_H_ diff --git a/gfx/angle/checkout/src/libANGLE/ProgramPipeline.cpp b/gfx/angle/checkout/src/libANGLE/ProgramPipeline.cpp new file mode 100644 index 0000000000..1675b06705 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/ProgramPipeline.cpp @@ -0,0 +1,721 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ProgramPipeline.cpp: Implements the gl::ProgramPipeline class. +// Implements GL program pipeline objects and related functionality. +// [OpenGL ES 3.1] section 7.4 page 105. + +#include "libANGLE/ProgramPipeline.h" + +#include + +#include "libANGLE/Context.h" +#include "libANGLE/Program.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/renderer/GLImplFactory.h" +#include "libANGLE/renderer/ProgramPipelineImpl.h" + +namespace gl +{ + +enum SubjectIndexes : angle::SubjectIndex +{ + kExecutableSubjectIndex = 0 +}; + +ProgramPipelineState::ProgramPipelineState() + : mLabel(), + mActiveShaderProgram(nullptr), + mValid(false), + mExecutable(new ProgramExecutable()), + mIsLinked(false) +{ + for (const ShaderType shaderType : gl::AllShaderTypes()) + { + mPrograms[shaderType] = nullptr; + } +} + +ProgramPipelineState::~ProgramPipelineState() +{ + SafeDelete(mExecutable); +} + +const std::string &ProgramPipelineState::getLabel() const +{ + return mLabel; +} + +void ProgramPipelineState::activeShaderProgram(Program *shaderProgram) +{ + mActiveShaderProgram = shaderProgram; +} + +void ProgramPipelineState::useProgramStage(const Context *context, + const ShaderType shaderType, + Program *shaderProgram, + angle::ObserverBinding *programObserverBindings) +{ + Program *oldProgram = mPrograms[shaderType]; + if (oldProgram) + { + oldProgram->release(context); + } + + // If program refers to a program object with a valid shader attached for the indicated shader + // stage, glUseProgramStages installs the executable code for that stage in the indicated + // program pipeline object pipeline. + if (shaderProgram && (shaderProgram->id().value != 0) && + shaderProgram->getExecutable().hasLinkedShaderStage(shaderType)) + { + mPrograms[shaderType] = shaderProgram; + shaderProgram->addRef(); + } + else + { + // If program is zero, or refers to a program object with no valid shader executable for the + // given stage, it is as if the pipeline object has no programmable stage configured for the + // indicated shader stage. + mPrograms[shaderType] = nullptr; + } + + Program *program = mPrograms[shaderType]; + programObserverBindings->bind(program); +} + +void ProgramPipelineState::useProgramStages( + const Context *context, + const gl::ShaderBitSet &shaderTypes, + Program *shaderProgram, + std::vector *programObserverBindings) +{ + for (ShaderType shaderType : shaderTypes) + { + useProgramStage(context, shaderType, shaderProgram, + &programObserverBindings->at(static_cast(shaderType))); + } +} + +bool ProgramPipelineState::usesShaderProgram(ShaderProgramID programId) const +{ + for (const Program *program : mPrograms) + { + if (program && (program->id() == programId)) + { + return true; + } + } + + return false; +} + +void ProgramPipelineState::updateExecutableTextures() +{ + for (const ShaderType shaderType : mExecutable->getLinkedShaderStages()) + { + const Program *program = getShaderProgram(shaderType); + ASSERT(program); + mExecutable->setActiveTextureMask(mExecutable->getActiveSamplersMask() | + program->getExecutable().getActiveSamplersMask()); + mExecutable->setActiveImagesMask(mExecutable->getActiveImagesMask() | + program->getExecutable().getActiveImagesMask()); + // Updates mActiveSamplerRefCounts, mActiveSamplerTypes, and mActiveSamplerFormats + mExecutable->updateActiveSamplers(program->getState()); + } +} + +rx::SpecConstUsageBits ProgramPipelineState::getSpecConstUsageBits() const +{ + rx::SpecConstUsageBits specConstUsageBits; + for (const ShaderType shaderType : mExecutable->getLinkedShaderStages()) + { + const Program *program = getShaderProgram(shaderType); + ASSERT(program); + specConstUsageBits |= program->getState().getSpecConstUsageBits(); + } + return specConstUsageBits; +} + +ProgramPipeline::ProgramPipeline(rx::GLImplFactory *factory, ProgramPipelineID handle) + : RefCountObject(factory->generateSerial(), handle), + mProgramPipelineImpl(factory->createProgramPipeline(mState)), + mExecutableObserverBinding(this, kExecutableSubjectIndex) +{ + ASSERT(mProgramPipelineImpl); + + for (const ShaderType shaderType : gl::AllShaderTypes()) + { + mProgramObserverBindings.emplace_back(this, static_cast(shaderType)); + } + mExecutableObserverBinding.bind(mState.mExecutable); +} + +ProgramPipeline::~ProgramPipeline() +{ + mProgramPipelineImpl.reset(nullptr); +} + +void ProgramPipeline::onDestroy(const Context *context) +{ + for (Program *program : mState.mPrograms) + { + if (program) + { + ASSERT(program->getRefCount()); + program->release(context); + } + } + + getImplementation()->destroy(context); +} + +angle::Result ProgramPipeline::setLabel(const Context *context, const std::string &label) +{ + mState.mLabel = label; + + if (mProgramPipelineImpl) + { + return mProgramPipelineImpl->onLabelUpdate(context); + } + return angle::Result::Continue; +} + +const std::string &ProgramPipeline::getLabel() const +{ + return mState.mLabel; +} + +rx::ProgramPipelineImpl *ProgramPipeline::getImplementation() const +{ + return mProgramPipelineImpl.get(); +} + +void ProgramPipeline::activeShaderProgram(Program *shaderProgram) +{ + mState.activeShaderProgram(shaderProgram); +} + +angle::Result ProgramPipeline::useProgramStages(const Context *context, + GLbitfield stages, + Program *shaderProgram) +{ + bool needToUpdatePipelineState = false; + gl::ShaderBitSet shaderTypes; + if (stages != GL_ALL_SHADER_BITS) + { + ASSERT(stages < 256u); + for (size_t singleShaderBit : angle::BitSet<8>(stages)) + { + // Cast back to a bit after the iterator returns an index. + ShaderType shaderType = GetShaderTypeFromBitfield(angle::Bit(singleShaderBit)); + ASSERT(shaderType != ShaderType::InvalidEnum); + shaderTypes.set(shaderType); + } + } + else + { + shaderTypes.set(); + } + ASSERT(shaderTypes.any()); + + for (ShaderType shaderType : shaderTypes) + { + if (mState.getShaderProgram(shaderType) != shaderProgram || + (shaderProgram && shaderProgram->hasAnyDirtyBit())) + { + needToUpdatePipelineState = true; + break; + } + } + + if (!needToUpdatePipelineState) + { + return angle::Result::Continue; + } + + mState.useProgramStages(context, shaderTypes, shaderProgram, &mProgramObserverBindings); + updateLinkedShaderStages(); + + mState.mIsLinked = false; + onStateChange(angle::SubjectMessage::SubjectChanged); + + return angle::Result::Continue; +} + +void ProgramPipeline::updateLinkedShaderStages() +{ + mState.mExecutable->resetLinkedShaderStages(); + + for (const ShaderType shaderType : gl::AllShaderTypes()) + { + Program *program = mState.mPrograms[shaderType]; + if (program) + { + mState.mExecutable->setLinkedShaderStages(shaderType); + } + } + + mState.mExecutable->updateCanDrawWith(); +} + +void ProgramPipeline::updateExecutableAttributes() +{ + Program *vertexProgram = getShaderProgram(gl::ShaderType::Vertex); + + if (!vertexProgram) + { + return; + } + + const ProgramExecutable &vertexExecutable = vertexProgram->getExecutable(); + mState.mExecutable->mActiveAttribLocationsMask = vertexExecutable.mActiveAttribLocationsMask; + mState.mExecutable->mMaxActiveAttribLocation = vertexExecutable.mMaxActiveAttribLocation; + mState.mExecutable->mAttributesTypeMask = vertexExecutable.mAttributesTypeMask; + mState.mExecutable->mAttributesMask = vertexExecutable.mAttributesMask; + mState.mExecutable->mProgramInputs = vertexExecutable.mProgramInputs; +} + +void ProgramPipeline::updateTransformFeedbackMembers() +{ + ShaderType lastVertexProcessingStage = + gl::GetLastPreFragmentStage(getExecutable().getLinkedShaderStages()); + if (lastVertexProcessingStage == ShaderType::InvalidEnum) + { + return; + } + + Program *shaderProgram = getShaderProgram(lastVertexProcessingStage); + ASSERT(shaderProgram); + + const ProgramExecutable &lastPreFragmentExecutable = shaderProgram->getExecutable(); + mState.mExecutable->mTransformFeedbackStrides = + lastPreFragmentExecutable.mTransformFeedbackStrides; + mState.mExecutable->mLinkedTransformFeedbackVaryings = + lastPreFragmentExecutable.mLinkedTransformFeedbackVaryings; +} + +void ProgramPipeline::updateShaderStorageBlocks() +{ + mState.mExecutable->mShaderStorageBlocks.clear(); + + // Only copy the storage blocks from each Program in the PPO once, since each Program could + // contain multiple shader stages. + ShaderBitSet handledStages; + + for (const gl::ShaderType shaderType : gl::AllShaderTypes()) + { + const Program *shaderProgram = getShaderProgram(shaderType); + if (shaderProgram && !handledStages.test(shaderType)) + { + // Only add each Program's blocks once. + handledStages |= shaderProgram->getExecutable().getLinkedShaderStages(); + + for (const InterfaceBlock &block : + shaderProgram->getExecutable().getShaderStorageBlocks()) + { + mState.mExecutable->mShaderStorageBlocks.emplace_back(block); + } + } + } +} + +void ProgramPipeline::updateImageBindings() +{ + mState.mExecutable->mImageBindings.clear(); + mState.mExecutable->mActiveImageShaderBits.fill({}); + + // Only copy the storage blocks from each Program in the PPO once, since each Program could + // contain multiple shader stages. + ShaderBitSet handledStages; + + for (const gl::ShaderType shaderType : gl::AllShaderTypes()) + { + const Program *shaderProgram = getShaderProgram(shaderType); + if (shaderProgram && !handledStages.test(shaderType)) + { + // Only add each Program's blocks once. + handledStages |= shaderProgram->getExecutable().getLinkedShaderStages(); + + for (const ImageBinding &imageBinding : shaderProgram->getState().getImageBindings()) + { + mState.mExecutable->mImageBindings.emplace_back(imageBinding); + } + + mState.mExecutable->updateActiveImages(shaderProgram->getExecutable()); + } + } +} + +void ProgramPipeline::updateExecutableGeometryProperties() +{ + Program *geometryProgram = getShaderProgram(gl::ShaderType::Geometry); + + if (!geometryProgram) + { + return; + } + + const ProgramExecutable &geometryExecutable = geometryProgram->getExecutable(); + mState.mExecutable->mGeometryShaderInputPrimitiveType = + geometryExecutable.mGeometryShaderInputPrimitiveType; + mState.mExecutable->mGeometryShaderOutputPrimitiveType = + geometryExecutable.mGeometryShaderOutputPrimitiveType; + mState.mExecutable->mGeometryShaderInvocations = geometryExecutable.mGeometryShaderInvocations; + mState.mExecutable->mGeometryShaderMaxVertices = geometryExecutable.mGeometryShaderMaxVertices; +} + +void ProgramPipeline::updateExecutableTessellationProperties() +{ + Program *tessControlProgram = getShaderProgram(gl::ShaderType::TessControl); + Program *tessEvalProgram = getShaderProgram(gl::ShaderType::TessEvaluation); + + if (tessControlProgram) + { + const ProgramExecutable &tessControlExecutable = tessControlProgram->getExecutable(); + mState.mExecutable->mTessControlShaderVertices = + tessControlExecutable.mTessControlShaderVertices; + } + + if (tessEvalProgram) + { + const ProgramExecutable &tessEvalExecutable = tessEvalProgram->getExecutable(); + mState.mExecutable->mTessGenMode = tessEvalExecutable.mTessGenMode; + mState.mExecutable->mTessGenSpacing = tessEvalExecutable.mTessGenSpacing; + mState.mExecutable->mTessGenVertexOrder = tessEvalExecutable.mTessGenVertexOrder; + mState.mExecutable->mTessGenPointMode = tessEvalExecutable.mTessGenPointMode; + } +} + +void ProgramPipeline::updateFragmentInoutRangeAndEnablesPerSampleShading() +{ + Program *fragmentProgram = getShaderProgram(gl::ShaderType::Fragment); + + if (!fragmentProgram) + { + return; + } + + const ProgramExecutable &fragmentExecutable = fragmentProgram->getExecutable(); + mState.mExecutable->mFragmentInoutRange = fragmentExecutable.mFragmentInoutRange; + mState.mExecutable->mHasDiscard = fragmentExecutable.mHasDiscard; + mState.mExecutable->mEnablesPerSampleShading = fragmentExecutable.mEnablesPerSampleShading; +} + +void ProgramPipeline::updateLinkedVaryings() +{ + // Need to check all of the shader stages, not just linked, so we handle Compute correctly. + for (const gl::ShaderType shaderType : kAllGraphicsShaderTypes) + { + const Program *shaderProgram = getShaderProgram(shaderType); + if (shaderProgram && shaderProgram->isLinked()) + { + const ProgramExecutable &executable = shaderProgram->getExecutable(); + mState.mExecutable->mLinkedOutputVaryings[shaderType] = + executable.getLinkedOutputVaryings(shaderType); + mState.mExecutable->mLinkedInputVaryings[shaderType] = + executable.getLinkedInputVaryings(shaderType); + } + } + + const Program *computeProgram = getShaderProgram(ShaderType::Compute); + if (computeProgram && computeProgram->isLinked()) + { + const ProgramExecutable &executable = computeProgram->getExecutable(); + mState.mExecutable->mLinkedOutputVaryings[ShaderType::Compute] = + executable.getLinkedOutputVaryings(ShaderType::Compute); + mState.mExecutable->mLinkedInputVaryings[ShaderType::Compute] = + executable.getLinkedInputVaryings(ShaderType::Compute); + } +} + +void ProgramPipeline::updateExecutable() +{ + // Vertex Shader ProgramExecutable properties + updateExecutableAttributes(); + updateTransformFeedbackMembers(); + updateShaderStorageBlocks(); + updateImageBindings(); + + // Geometry Shader ProgramExecutable properties + updateExecutableGeometryProperties(); + + // Tessellation Shaders ProgramExecutable properties + updateExecutableTessellationProperties(); + + // Fragment Shader ProgramExecutable properties + updateFragmentInoutRangeAndEnablesPerSampleShading(); + + // All Shader ProgramExecutable properties + mState.updateExecutableTextures(); + updateLinkedVaryings(); +} + +// The attached shaders are checked for linking errors by matching up their variables. +// Uniform, input and output variables get collected. +// The code gets compiled into binaries. +angle::Result ProgramPipeline::link(const Context *context) +{ + ASSERT(!mState.mIsLinked); + + ProgramMergedVaryings mergedVaryings; + ProgramVaryingPacking varyingPacking; + LinkingVariables linkingVariables(mState); + + mState.mExecutable->reset(true); + + InfoLog &infoLog = mState.mExecutable->getInfoLog(); + infoLog.reset(); + + // Build shader variable uniforms map for gl::UniformLinker. + ShaderMap> shaderUniforms; + for (ShaderType shaderType : mState.mExecutable->mLinkedShaderStages) + { + for (const LinkedUniform &uniform : mState.mPrograms[shaderType]->getUniforms()) + { + shaderUniforms[shaderType].push_back(uniform); + } + } + + if (mState.mExecutable->hasLinkedShaderStage(gl::ShaderType::Vertex)) + { + if (!linkVaryings(infoLog)) + { + return angle::Result::Stop; + } + + if (!LinkValidateProgramGlobalNames(infoLog, getExecutable(), linkingVariables)) + { + return angle::Result::Stop; + } + + Program *fragmentShaderProgram = getShaderProgram(ShaderType::Fragment); + if (fragmentShaderProgram) + { + // We should also be validating SSBO and image uniform counts. + const GLuint combinedImageUniforms = 0; + const GLuint combinedShaderStorageBlocks = 0; + const ProgramExecutable &fragmentExecutable = fragmentShaderProgram->getExecutable(); + if (!mState.mExecutable->linkValidateOutputVariables( + context->getCaps(), context->getExtensions(), context->getClientVersion(), + combinedImageUniforms, combinedShaderStorageBlocks, + fragmentExecutable.getOutputVariables(), + fragmentExecutable.getLinkedShaderVersion(ShaderType::Fragment), + ProgramAliasedBindings(), ProgramAliasedBindings())) + { + return angle::Result::Continue; + } + } + mergedVaryings = GetMergedVaryingsFromLinkingVariables(linkingVariables); + // If separable program objects are in use, the set of attributes captured is taken + // from the program object active on the last vertex processing stage. + ShaderType lastVertexProcessingStage = + gl::GetLastPreFragmentStage(getExecutable().getLinkedShaderStages()); + if (lastVertexProcessingStage == ShaderType::InvalidEnum) + { + // If there is no active program for the vertex or fragment shader stages, the results + // of vertex and fragment shader execution will respectively be undefined. However, + // this is not an error. + return angle::Result::Continue; + } + + Program *tfProgram = getShaderProgram(lastVertexProcessingStage); + ASSERT(tfProgram); + + if (!tfProgram) + { + tfProgram = mState.mPrograms[ShaderType::Vertex]; + } + + const std::vector &transformFeedbackVaryingNames = + tfProgram->getState().getTransformFeedbackVaryingNames(); + + if (!mState.mExecutable->linkMergedVaryings(context, mergedVaryings, + transformFeedbackVaryingNames, linkingVariables, + false, &varyingPacking)) + { + return angle::Result::Stop; + } + } + + // Merge uniforms. + mState.mExecutable->copyUniformsFromProgramMap(mState.mPrograms); + + if (mState.mExecutable->hasLinkedShaderStage(gl::ShaderType::Vertex)) + { + const ProgramState &programState = mState.mPrograms[gl::ShaderType::Vertex]->getState(); + mState.mExecutable->copyInputsFromProgram(programState); + } + + // Merge shader buffers (UBOs, SSBOs, and atomic counter buffers) into the executable. + // Also copy over image and sampler bindings. + for (ShaderType shaderType : mState.mExecutable->getLinkedShaderStages()) + { + const ProgramState &programState = mState.mPrograms[shaderType]->getState(); + mState.mExecutable->copyShaderBuffersFromProgram(programState, shaderType); + mState.mExecutable->copySamplerBindingsFromProgram(programState); + mState.mExecutable->copyImageBindingsFromProgram(programState); + } + + if (mState.mExecutable->hasLinkedShaderStage(gl::ShaderType::Fragment)) + { + const ProgramState &programState = mState.mPrograms[gl::ShaderType::Fragment]->getState(); + mState.mExecutable->copyOutputsFromProgram(programState); + } + + if (mState.mExecutable->hasLinkedShaderStage(gl::ShaderType::Vertex) || + mState.mExecutable->hasLinkedShaderStage(gl::ShaderType::Compute)) + { + ANGLE_TRY(getImplementation()->link(context, mergedVaryings, varyingPacking)); + } + + mState.mExecutable->mActiveSamplerRefCounts.fill(0); + updateExecutable(); + + mState.mIsLinked = true; + onStateChange(angle::SubjectMessage::SubjectChanged); + + return angle::Result::Continue; +} + +bool ProgramPipeline::linkVaryings(InfoLog &infoLog) const +{ + ShaderType previousShaderType = ShaderType::InvalidEnum; + for (ShaderType shaderType : kAllGraphicsShaderTypes) + { + Program *program = getShaderProgram(shaderType); + if (!program) + { + continue; + } + ProgramExecutable &executable = program->getExecutable(); + + if (previousShaderType != ShaderType::InvalidEnum) + { + Program *previousProgram = getShaderProgram(previousShaderType); + ASSERT(previousProgram); + const ProgramExecutable &previousExecutable = previousProgram->getExecutable(); + + if (!LinkValidateShaderInterfaceMatching( + previousExecutable.getLinkedOutputVaryings(previousShaderType), + executable.getLinkedInputVaryings(shaderType), previousShaderType, shaderType, + previousExecutable.getLinkedShaderVersion(previousShaderType), + executable.getLinkedShaderVersion(shaderType), true, infoLog)) + { + return false; + } + } + previousShaderType = shaderType; + } + + // TODO: http://anglebug.com/3571 and http://anglebug.com/3572 + // Need to move logic of validating builtin varyings inside the for-loop above. + // This is because the built-in symbols `gl_ClipDistance` and `gl_CullDistance` + // can be redeclared in Geometry or Tessellation shaders as well. + Program *vertexProgram = mState.mPrograms[ShaderType::Vertex]; + Program *fragmentProgram = mState.mPrograms[ShaderType::Fragment]; + if (!vertexProgram || !fragmentProgram) + { + return true; + } + ProgramExecutable &vertexExecutable = vertexProgram->getExecutable(); + ProgramExecutable &fragmentExecutable = fragmentProgram->getExecutable(); + return LinkValidateBuiltInVaryings( + vertexExecutable.getLinkedOutputVaryings(ShaderType::Vertex), + fragmentExecutable.getLinkedInputVaryings(ShaderType::Fragment), ShaderType::Vertex, + ShaderType::Fragment, vertexExecutable.getLinkedShaderVersion(ShaderType::Vertex), + fragmentExecutable.getLinkedShaderVersion(ShaderType::Fragment), infoLog); +} + +void ProgramPipeline::validate(const gl::Context *context) +{ + const Caps &caps = context->getCaps(); + mState.mValid = true; + InfoLog &infoLog = mState.mExecutable->getInfoLog(); + infoLog.reset(); + + for (const ShaderType shaderType : mState.mExecutable->getLinkedShaderStages()) + { + Program *shaderProgram = mState.mPrograms[shaderType]; + if (shaderProgram) + { + shaderProgram->resolveLink(context); + shaderProgram->validate(caps); + std::string shaderInfoString = shaderProgram->getExecutable().getInfoLogString(); + if (shaderInfoString.length()) + { + mState.mValid = false; + infoLog << shaderInfoString << "\n"; + return; + } + if (!shaderProgram->isSeparable()) + { + mState.mValid = false; + infoLog << GetShaderTypeString(shaderType) << " is not marked separable." + << "\n"; + return; + } + } + } + + intptr_t programPipelineError = context->getStateCache().getProgramPipelineError(context); + if (programPipelineError) + { + mState.mValid = false; + const char *errorMessage = reinterpret_cast(programPipelineError); + infoLog << errorMessage << "\n"; + return; + } + + if (!linkVaryings(infoLog)) + { + mState.mValid = false; + + for (const ShaderType shaderType : mState.mExecutable->getLinkedShaderStages()) + { + Program *shaderProgram = mState.mPrograms[shaderType]; + ASSERT(shaderProgram); + shaderProgram->validate(caps); + std::string shaderInfoString = shaderProgram->getExecutable().getInfoLogString(); + if (shaderInfoString.length()) + { + infoLog << shaderInfoString << "\n"; + } + } + } +} + +void ProgramPipeline::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) +{ + switch (message) + { + case angle::SubjectMessage::ProgramTextureOrImageBindingChanged: + mState.mExecutable->mActiveSamplerRefCounts.fill(0); + mState.updateExecutableTextures(); + break; + + case angle::SubjectMessage::ProgramRelinked: + mState.mIsLinked = false; + onStateChange(angle::SubjectMessage::ProgramRelinked); + break; + case angle::SubjectMessage::SamplerUniformsUpdated: + mState.mExecutable->clearSamplerBindings(); + for (ShaderType shaderType : mState.mExecutable->getLinkedShaderStages()) + { + const ProgramState &programState = mState.mPrograms[shaderType]->getState(); + mState.mExecutable->copySamplerBindingsFromProgram(programState); + } + mState.mExecutable->mActiveSamplerRefCounts.fill(0); + mState.updateExecutableTextures(); + break; + case angle::SubjectMessage::ProgramUniformUpdated: + mProgramPipelineImpl->onProgramUniformUpdate(static_cast(index)); + break; + default: + UNREACHABLE(); + break; + } +} +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/ProgramPipeline.h b/gfx/angle/checkout/src/libANGLE/ProgramPipeline.h new file mode 100644 index 0000000000..4b394ca3e7 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/ProgramPipeline.h @@ -0,0 +1,176 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ProgramPipeline.h: Defines the gl::ProgramPipeline class. +// Implements GL program pipeline objects and related functionality. +// [OpenGL ES 3.1] section 7.4 page 105. + +#ifndef LIBANGLE_PROGRAMPIPELINE_H_ +#define LIBANGLE_PROGRAMPIPELINE_H_ + +#include + +#include "common/angleutils.h" +#include "libANGLE/Debug.h" +#include "libANGLE/Program.h" +#include "libANGLE/ProgramExecutable.h" +#include "libANGLE/RefCountObject.h" + +namespace rx +{ +class GLImplFactory; +class ProgramPipelineImpl; +} // namespace rx + +namespace gl +{ +class Context; +class ProgramPipeline; + +class ProgramPipelineState final : angle::NonCopyable +{ + public: + ProgramPipelineState(); + ~ProgramPipelineState(); + + const std::string &getLabel() const; + + ProgramExecutable &getExecutable() const + { + ASSERT(mExecutable); + return *mExecutable; + } + + void activeShaderProgram(Program *shaderProgram); + void useProgramStages(const Context *context, + const gl::ShaderBitSet &shaderTypes, + Program *shaderProgram, + std::vector *programObserverBindings); + + Program *getActiveShaderProgram() { return mActiveShaderProgram; } + + GLboolean isValid() const { return mValid; } + + const Program *getShaderProgram(ShaderType shaderType) const { return mPrograms[shaderType]; } + + bool usesShaderProgram(ShaderProgramID program) const; + + void updateExecutableTextures(); + + rx::SpecConstUsageBits getSpecConstUsageBits() const; + + private: + void useProgramStage(const Context *context, + ShaderType shaderType, + Program *shaderProgram, + angle::ObserverBinding *programObserverBindings); + + friend class ProgramPipeline; + + std::string mLabel; + + // The active shader program + Program *mActiveShaderProgram; + // The shader programs for each stage. + ShaderMap mPrograms; + + GLboolean mValid; + + ProgramExecutable *mExecutable; + + bool mIsLinked; +}; + +class ProgramPipeline final : public RefCountObject, + public LabeledObject, + public angle::ObserverInterface, + public angle::Subject +{ + public: + ProgramPipeline(rx::GLImplFactory *factory, ProgramPipelineID handle); + ~ProgramPipeline() override; + + void onDestroy(const Context *context) override; + + angle::Result setLabel(const Context *context, const std::string &label) override; + const std::string &getLabel() const override; + + const ProgramPipelineState &getState() const { return mState; } + ProgramPipelineState &getState() { return mState; } + + ProgramExecutable &getExecutable() const { return mState.getExecutable(); } + + rx::ProgramPipelineImpl *getImplementation() const; + + Program *getActiveShaderProgram() { return mState.getActiveShaderProgram(); } + void activeShaderProgram(Program *shaderProgram); + Program *getLinkedActiveShaderProgram(const Context *context) + { + Program *program = mState.getActiveShaderProgram(); + if (program) + { + program->resolveLink(context); + } + return program; + } + + angle::Result useProgramStages(const Context *context, + GLbitfield stages, + Program *shaderProgram); + + Program *getShaderProgram(ShaderType shaderType) const { return mState.mPrograms[shaderType]; } + + void resetIsLinked() { mState.mIsLinked = false; } + angle::Result link(const gl::Context *context); + + // Ensure program pipeline is linked. Inlined to make sure its overhead is as low as possible. + void resolveLink(const Context *context) + { + if (mState.mIsLinked) + { + // Already linked, nothing to do. + return; + } + + angle::Result linkResult = link(context); + if (linkResult != angle::Result::Continue) + { + // If the link failed then log a warning, swallow the error and move on. + WARN() << "ProgramPipeline link failed" << std::endl; + } + return; + } + + void validate(const gl::Context *context); + GLboolean isValid() const { return mState.isValid(); } + bool isLinked() const { return mState.mIsLinked; } + + // ObserverInterface implementation. + void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; + + private: + bool linkVaryings(InfoLog &infoLog) const; + void updateLinkedShaderStages(); + void updateExecutableAttributes(); + void updateTransformFeedbackMembers(); + void updateShaderStorageBlocks(); + void updateImageBindings(); + void updateExecutableGeometryProperties(); + void updateExecutableTessellationProperties(); + void updateFragmentInoutRangeAndEnablesPerSampleShading(); + void updateLinkedVaryings(); + void updateExecutable(); + + std::unique_ptr mProgramPipelineImpl; + + ProgramPipelineState mState; + + std::vector mProgramObserverBindings; + angle::ObserverBinding mExecutableObserverBinding; +}; +} // namespace gl + +#endif // LIBANGLE_PROGRAMPIPELINE_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Query.cpp b/gfx/angle/checkout/src/libANGLE/Query.cpp new file mode 100644 index 0000000000..1e56221077 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Query.cpp @@ -0,0 +1,96 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Query.cpp: Implements the gl::Query class + +#include "libANGLE/Query.h" + +#include "libANGLE/renderer/GLImplFactory.h" +#include "libANGLE/renderer/QueryImpl.h" + +namespace gl +{ +Query::Query(rx::GLImplFactory *factory, QueryType type, QueryID id) + : RefCountObject(factory->generateSerial(), id), mQuery(factory->createQuery(type)), mLabel() +{} + +Query::~Query() +{ + SafeDelete(mQuery); +} + +void Query::onDestroy(const Context *context) +{ + ASSERT(mQuery); + mQuery->onDestroy(context); +} + +angle::Result Query::setLabel(const Context *context, const std::string &label) +{ + mLabel = label; + + if (mQuery) + { + return mQuery->onLabelUpdate(context); + } + return angle::Result::Continue; +} + +const std::string &Query::getLabel() const +{ + return mLabel; +} + +angle::Result Query::begin(const Context *context) +{ + return mQuery->begin(context); +} + +angle::Result Query::end(const Context *context) +{ + return mQuery->end(context); +} + +angle::Result Query::queryCounter(const Context *context) +{ + return mQuery->queryCounter(context); +} + +angle::Result Query::getResult(const Context *context, GLint *params) +{ + return mQuery->getResult(context, params); +} + +angle::Result Query::getResult(const Context *context, GLuint *params) +{ + return mQuery->getResult(context, params); +} + +angle::Result Query::getResult(const Context *context, GLint64 *params) +{ + return mQuery->getResult(context, params); +} + +angle::Result Query::getResult(const Context *context, GLuint64 *params) +{ + return mQuery->getResult(context, params); +} + +angle::Result Query::isResultAvailable(const Context *context, bool *available) +{ + return mQuery->isResultAvailable(context, available); +} + +QueryType Query::getType() const +{ + return mQuery->getType(); +} + +rx::QueryImpl *Query::getImplementation() const +{ + return mQuery; +} +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/Query.h b/gfx/angle/checkout/src/libANGLE/Query.h new file mode 100644 index 0000000000..8d8692b5e8 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Query.h @@ -0,0 +1,60 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Query.h: Defines the gl::Query class + +#ifndef LIBANGLE_QUERY_H_ +#define LIBANGLE_QUERY_H_ + +#include "common/PackedEnums.h" +#include "libANGLE/Debug.h" +#include "libANGLE/Error.h" +#include "libANGLE/RefCountObject.h" + +#include "common/angleutils.h" + +#include "angle_gl.h" + +namespace rx +{ +class GLImplFactory; +class QueryImpl; +} // namespace rx + +namespace gl +{ + +class Query final : public RefCountObject, public LabeledObject +{ + public: + Query(rx::GLImplFactory *factory, QueryType type, QueryID id); + ~Query() override; + void onDestroy(const Context *context) override; + + angle::Result setLabel(const Context *context, const std::string &label) override; + const std::string &getLabel() const override; + + angle::Result begin(const Context *context); + angle::Result end(const Context *context); + angle::Result queryCounter(const Context *context); + angle::Result getResult(const Context *context, GLint *params); + angle::Result getResult(const Context *context, GLuint *params); + angle::Result getResult(const Context *context, GLint64 *params); + angle::Result getResult(const Context *context, GLuint64 *params); + angle::Result isResultAvailable(const Context *context, bool *available); + + QueryType getType() const; + + rx::QueryImpl *getImplementation() const; + + private: + rx::QueryImpl *mQuery; + + std::string mLabel; +}; +} // namespace gl + +#endif // LIBANGLE_QUERY_H_ diff --git a/gfx/angle/checkout/src/libANGLE/RefCountObject.h b/gfx/angle/checkout/src/libANGLE/RefCountObject.h new file mode 100644 index 0000000000..f19b8c434a --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/RefCountObject.h @@ -0,0 +1,327 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// RefCountObject.h: Defines the gl::RefCountObject base class that provides +// lifecycle support for GL objects using the traditional BindObject scheme, but +// that need to be reference counted for correct cross-context deletion. +// (Concretely, textures, buffers and renderbuffers.) + +#ifndef LIBANGLE_REFCOUNTOBJECT_H_ +#define LIBANGLE_REFCOUNTOBJECT_H_ + +#include "angle_gl.h" +#include "common/PackedEnums.h" +#include "common/debug.h" +#include "libANGLE/Error.h" +#include "libANGLE/Observer.h" +#include "libANGLE/renderer/serial_utils.h" + +#include + +namespace angle +{ + +template +class RefCountObject : angle::NonCopyable +{ + public: + using ContextType = ContextT; + using ErrorType = ErrorT; + + RefCountObject() : mRefCount(0) {} + + virtual void onDestroy(const ContextType *context) {} + + void addRef() const { ++mRefCount; } + + ANGLE_INLINE void release(const ContextType *context) + { + ASSERT(mRefCount > 0); + if (--mRefCount == 0) + { + onDestroy(context); + delete this; + } + } + + size_t getRefCount() const { return mRefCount; } + + protected: + virtual ~RefCountObject() { ASSERT(mRefCount == 0); } + + mutable size_t mRefCount; +}; + +template +class RefCountObjectReleaser : angle::NonCopyable +{ + public: + using ContextType = ContextT; + using ErrorType = ErrorT; + + RefCountObjectReleaser() {} + RefCountObjectReleaser(const ContextType *context, ObjectType *object) + : mContext(context), mObject(object) + {} + + RefCountObjectReleaser(RefCountObjectReleaser &&other) + : mContext(other.mContext), mObject(other.mObject) + { + other.mContext = nullptr; + other.mObject = nullptr; + } + + RefCountObjectReleaser &operator=(RefCountObjectReleaser &&other) + { + mContext = other.mContext; + mObject = other.mObject; + + other.mContext = nullptr; + other.mObject = nullptr; + + return *this; + } + + ~RefCountObjectReleaser() + { + if (mObject) + { + reinterpret_cast *>(mObject)->release(mContext); + mObject = nullptr; + } + } + + private: + const ContextType *mContext = nullptr; + ObjectType *mObject = nullptr; +}; + +template +class BindingPointer +{ + public: + using ContextType = ContextT; + using ErrorType = ErrorT; + + BindingPointer() : mObject(nullptr) {} + + BindingPointer(ObjectType *object) : mObject(object) + { + if (mObject) + { + mObject->addRef(); + } + } + + BindingPointer(const BindingPointer &other) : mObject(other.mObject) + { + if (mObject) + { + mObject->addRef(); + } + } + + BindingPointer &operator=(BindingPointer &&other) + { + std::swap(mObject, other.mObject); + return *this; + } + + virtual ~BindingPointer() + { + // Objects have to be released before the resource manager is destroyed, so they must be + // explicitly cleaned up. + ASSERT(mObject == nullptr); + } + + RefCountObjectReleaser set(const ContextType *context, + ObjectType *newObject) + { + // addRef first in case newObject == mObject and this is the last reference to it. + if (newObject != nullptr) + { + reinterpret_cast *>(newObject)->addRef(); + } + + // Store the old pointer in a temporary so we can set the pointer before calling release. + // Otherwise the object could still be referenced when its destructor is called. + ObjectType *oldObject = mObject; + mObject = newObject; + return RefCountObjectReleaser(context, oldObject); + } + + void assign(ObjectType *object) { mObject = object; } + + ObjectType *get() const { return mObject; } + ObjectType *operator->() const { return mObject; } + + bool operator==(const BindingPointer &other) const { return mObject == other.mObject; } + + bool operator!=(const BindingPointer &other) const { return !(*this == other); } + + protected: + ANGLE_INLINE void setImpl(ObjectType *obj) { mObject = obj; } + + private: + ObjectType *mObject; +}; +} // namespace angle + +namespace gl +{ +class Context; + +template +class BindingPointer; + +using RefCountObjectNoID = angle::RefCountObject; + +template +class RefCountObject : public gl::RefCountObjectNoID +{ + public: + explicit RefCountObject(rx::Serial serial, IDType id) : mSerial(serial), mId(id) {} + + rx::Serial serial() const { return mSerial; } + IDType id() const { return mId; } + + protected: + ~RefCountObject() override {} + + private: + // Unique serials are used to identify resources for frame capture. + rx::Serial mSerial; + IDType mId; +}; + +template +class BindingPointer : public angle::BindingPointer +{ + public: + using ContextType = typename angle::BindingPointer::ContextType; + using ErrorType = typename angle::BindingPointer::ErrorType; + + BindingPointer() {} + + BindingPointer(ObjectType *object) : angle::BindingPointer(object) {} + + typename ResourceTypeToID::IDType id() const + { + ObjectType *obj = this->get(); + if (obj) + return obj->id(); + return {0}; + } +}; + +template +class OffsetBindingPointer : public BindingPointer +{ + public: + using ContextType = typename BindingPointer::ContextType; + using ErrorType = typename BindingPointer::ErrorType; + + OffsetBindingPointer() : mOffset(0), mSize(0) {} + + void set(const ContextType *context, ObjectType *newObject, GLintptr offset, GLsizeiptr size) + { + set(context, newObject); + updateOffsetAndSize(newObject, offset, size); + } + + GLintptr getOffset() const { return mOffset; } + GLsizeiptr getSize() const { return mSize; } + + bool operator==(const OffsetBindingPointer &other) const + { + return this->get() == other.get() && mOffset == other.mOffset && mSize == other.mSize; + } + + bool operator!=(const OffsetBindingPointer &other) const + { + return !(*this == other); + } + + void assign(ObjectType *newObject, GLintptr offset, GLsizeiptr size) + { + assign(newObject); + updateOffsetAndSize(newObject, offset, size); + } + + private: + ANGLE_INLINE void updateOffsetAndSize(ObjectType *newObject, GLintptr offset, GLsizeiptr size) + { + if (newObject) + { + mOffset = offset; + mSize = size; + } + else + { + mOffset = 0; + mSize = 0; + } + } + + // Delete the unparameterized functions. This forces an explicit offset and size. + using BindingPointer::set; + using BindingPointer::assign; + + GLintptr mOffset; + GLsizeiptr mSize; +}; + +template +class SubjectBindingPointer : protected BindingPointer, public angle::ObserverBindingBase +{ + public: + SubjectBindingPointer(angle::ObserverInterface *observer, angle::SubjectIndex index) + : ObserverBindingBase(observer, index) + {} + ~SubjectBindingPointer() override {} + SubjectBindingPointer(const SubjectBindingPointer &other) = default; + SubjectBindingPointer &operator=(const SubjectBindingPointer &other) = default; + + void bind(const Context *context, SubjectT *subject) + { + // AddRef first in case subject == get() + if (subject) + { + subject->addObserver(this); + subject->addRef(); + } + + if (get()) + { + get()->removeObserver(this); + get()->release(context); + } + + this->setImpl(subject); + } + + using BindingPointer::get; + using BindingPointer::operator->; + + friend class State; +}; +} // namespace gl + +namespace egl +{ +class Display; + +using RefCountObject = angle::RefCountObject; + +template +using RefCountObjectReleaser = angle::RefCountObjectReleaser; + +template +using BindingPointer = angle::BindingPointer; + +} // namespace egl + +#endif // LIBANGLE_REFCOUNTOBJECT_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Renderbuffer.cpp b/gfx/angle/checkout/src/libANGLE/Renderbuffer.cpp new file mode 100644 index 0000000000..ce2445c31e --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Renderbuffer.cpp @@ -0,0 +1,423 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Renderbuffer.cpp: Implements the renderer-agnostic gl::Renderbuffer class, +// GL renderbuffer objects and related functionality. +// [OpenGL ES 2.0.24] section 4.4.3 page 108. + +#include "libANGLE/Renderbuffer.h" + +#include "common/utilities.h" +#include "libANGLE/Context.h" +#include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/Image.h" +#include "libANGLE/Renderbuffer.h" +#include "libANGLE/Texture.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/GLImplFactory.h" +#include "libANGLE/renderer/d3d/RenderTargetD3D.h" + +namespace gl +{ +namespace +{ +angle::SubjectIndex kRenderbufferImplSubjectIndex = 0; + +InitState DetermineInitState(const Context *context) +{ + return (context && context->isRobustResourceInitEnabled()) ? InitState::MayNeedInit + : InitState::Initialized; +} +} // namespace + +// RenderbufferState implementation. +RenderbufferState::RenderbufferState() + : mWidth(0), + mHeight(0), + mFormat(GL_RGBA4), + mSamples(0), + mMultisamplingMode(MultisamplingMode::Regular), + mHasProtectedContent(false), + mInitState(InitState::Initialized) +{} + +RenderbufferState::~RenderbufferState() {} + +GLsizei RenderbufferState::getWidth() const +{ + return mWidth; +} + +GLsizei RenderbufferState::getHeight() const +{ + return mHeight; +} + +const Format &RenderbufferState::getFormat() const +{ + return mFormat; +} + +GLsizei RenderbufferState::getSamples() const +{ + return mSamples; +} + +MultisamplingMode RenderbufferState::getMultisamplingMode() const +{ + return mMultisamplingMode; +} + +InitState RenderbufferState::getInitState() const +{ + return mInitState; +} + +void RenderbufferState::update(GLsizei width, + GLsizei height, + const Format &format, + GLsizei samples, + MultisamplingMode multisamplingMode, + InitState initState) +{ + mWidth = width; + mHeight = height; + mFormat = format; + mSamples = samples; + mMultisamplingMode = multisamplingMode; + mInitState = initState; + mHasProtectedContent = false; +} + +void RenderbufferState::setProtectedContent(bool hasProtectedContent) +{ + mHasProtectedContent = hasProtectedContent; +} + +// Renderbuffer implementation. +Renderbuffer::Renderbuffer(rx::GLImplFactory *implFactory, RenderbufferID id) + : RefCountObject(implFactory->generateSerial(), id), + mState(), + mImplementation(implFactory->createRenderbuffer(mState)), + mLabel(), + mImplObserverBinding(this, kRenderbufferImplSubjectIndex) +{ + mImplObserverBinding.bind(mImplementation.get()); +} + +void Renderbuffer::onDestroy(const Context *context) +{ + egl::RefCountObjectReleaser releaseImage; + (void)orphanImages(context, &releaseImage); + + if (mImplementation) + { + mImplementation->onDestroy(context); + } +} + +Renderbuffer::~Renderbuffer() {} + +angle::Result Renderbuffer::setLabel(const Context *context, const std::string &label) +{ + mLabel = label; + + if (mImplementation) + { + return mImplementation->onLabelUpdate(context); + } + return angle::Result::Continue; +} + +const std::string &Renderbuffer::getLabel() const +{ + return mLabel; +} + +angle::Result Renderbuffer::setStorage(const Context *context, + GLenum internalformat, + GLsizei width, + GLsizei height) +{ + + egl::RefCountObjectReleaser releaseImage; + ANGLE_TRY(orphanImages(context, &releaseImage)); + + ANGLE_TRY(mImplementation->setStorage(context, internalformat, width, height)); + + mState.update(width, height, Format(internalformat), 0, MultisamplingMode::Regular, + DetermineInitState(context)); + onStateChange(angle::SubjectMessage::SubjectChanged); + + return angle::Result::Continue; +} + +angle::Result Renderbuffer::setStorageMultisample(const Context *context, + GLsizei samplesIn, + GLenum internalformat, + GLsizei width, + GLsizei height, + MultisamplingMode mode) +{ + egl::RefCountObjectReleaser releaseImage; + ANGLE_TRY(orphanImages(context, &releaseImage)); + + // Potentially adjust "samplesIn" to a supported value + const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat); + GLsizei samples = formatCaps.getNearestSamples(samplesIn); + + ANGLE_TRY(mImplementation->setStorageMultisample(context, samples, internalformat, width, + height, mode)); + + mState.update(width, height, Format(internalformat), samples, mode, + DetermineInitState(context)); + onStateChange(angle::SubjectMessage::SubjectChanged); + + return angle::Result::Continue; +} + +angle::Result Renderbuffer::setStorageEGLImageTarget(const Context *context, egl::Image *image) +{ + egl::RefCountObjectReleaser releaseImage; + ANGLE_TRY(orphanImages(context, &releaseImage)); + + ANGLE_TRY(mImplementation->setStorageEGLImageTarget(context, image)); + + setTargetImage(context, image); + + mState.update(static_cast(image->getWidth()), static_cast(image->getHeight()), + Format(image->getFormat()), 0, MultisamplingMode::Regular, + image->sourceInitState()); + mState.setProtectedContent(image->hasProtectedContent()); + + onStateChange(angle::SubjectMessage::SubjectChanged); + + return angle::Result::Continue; +} + +angle::Result Renderbuffer::copyRenderbufferSubData(Context *context, + const gl::Renderbuffer *srcBuffer, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth) +{ + ANGLE_TRY(mImplementation->copyRenderbufferSubData(context, srcBuffer, srcLevel, srcX, srcY, + srcZ, dstLevel, dstX, dstY, dstZ, srcWidth, + srcHeight, srcDepth)); + + return angle::Result::Continue; +} + +angle::Result Renderbuffer::copyTextureSubData(Context *context, + const gl::Texture *srcTexture, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth) +{ + ANGLE_TRY(mImplementation->copyTextureSubData(context, srcTexture, srcLevel, srcX, srcY, srcZ, + dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight, + srcDepth)); + + return angle::Result::Continue; +} + +rx::RenderbufferImpl *Renderbuffer::getImplementation() const +{ + ASSERT(mImplementation); + return mImplementation.get(); +} + +GLsizei Renderbuffer::getWidth() const +{ + return mState.mWidth; +} + +GLsizei Renderbuffer::getHeight() const +{ + return mState.mHeight; +} + +const Format &Renderbuffer::getFormat() const +{ + return mState.mFormat; +} + +GLsizei Renderbuffer::getSamples() const +{ + return mState.mMultisamplingMode == MultisamplingMode::Regular ? mState.mSamples : 0; +} + +MultisamplingMode Renderbuffer::getMultisamplingMode() const +{ + return mState.mMultisamplingMode; +} + +GLuint Renderbuffer::getRedSize() const +{ + return mState.mFormat.info->redBits; +} + +GLuint Renderbuffer::getGreenSize() const +{ + return mState.mFormat.info->greenBits; +} + +GLuint Renderbuffer::getBlueSize() const +{ + return mState.mFormat.info->blueBits; +} + +GLuint Renderbuffer::getAlphaSize() const +{ + return mState.mFormat.info->alphaBits; +} + +GLuint Renderbuffer::getDepthSize() const +{ + return mState.mFormat.info->depthBits; +} + +GLuint Renderbuffer::getStencilSize() const +{ + return mState.mFormat.info->stencilBits; +} + +const RenderbufferState &Renderbuffer::getState() const +{ + return mState; +} + +GLint Renderbuffer::getMemorySize() const +{ + GLint implSize = mImplementation->getMemorySize(); + if (implSize > 0) + { + return implSize; + } + + // Assume allocated size is around width * height * samples * pixelBytes + angle::CheckedNumeric size = 1; + size *= mState.mFormat.info->pixelBytes; + size *= mState.mWidth; + size *= mState.mHeight; + size *= std::max(mState.mSamples, 1); + return size.ValueOrDefault(std::numeric_limits::max()); +} + +void Renderbuffer::onAttach(const Context *context, rx::Serial framebufferSerial) +{ + addRef(); +} + +void Renderbuffer::onDetach(const Context *context, rx::Serial framebufferSerial) +{ + release(context); +} + +GLuint Renderbuffer::getId() const +{ + return id().value; +} + +Extents Renderbuffer::getAttachmentSize(const gl::ImageIndex & /*imageIndex*/) const +{ + return Extents(mState.mWidth, mState.mHeight, 1); +} + +Format Renderbuffer::getAttachmentFormat(GLenum /*binding*/, + const ImageIndex & /*imageIndex*/) const +{ + return getFormat(); +} +GLsizei Renderbuffer::getAttachmentSamples(const ImageIndex & /*imageIndex*/) const +{ + return getSamples(); +} + +bool Renderbuffer::isRenderable(const Context *context, + GLenum binding, + const ImageIndex &imageIndex) const +{ + if (isEGLImageTarget()) + { + return ImageSibling::isRenderable(context, binding, imageIndex); + } + return getFormat().info->renderbufferSupport(context->getClientVersion(), + context->getExtensions()); +} + +InitState Renderbuffer::initState(GLenum /*binding*/, const gl::ImageIndex & /*imageIndex*/) const +{ + if (isEGLImageTarget()) + { + return sourceEGLImageInitState(); + } + + return mState.mInitState; +} + +void Renderbuffer::setInitState(GLenum /*binding*/, + const gl::ImageIndex & /*imageIndex*/, + InitState initState) +{ + if (isEGLImageTarget()) + { + setSourceEGLImageInitState(initState); + } + else + { + mState.mInitState = initState; + } +} + +rx::FramebufferAttachmentObjectImpl *Renderbuffer::getAttachmentImpl() const +{ + return mImplementation.get(); +} + +GLenum Renderbuffer::getImplementationColorReadFormat(const Context *context) const +{ + return mImplementation->getColorReadFormat(context); +} + +GLenum Renderbuffer::getImplementationColorReadType(const Context *context) const +{ + return mImplementation->getColorReadType(context); +} + +angle::Result Renderbuffer::getRenderbufferImage(const Context *context, + const PixelPackState &packState, + Buffer *packBuffer, + GLenum format, + GLenum type, + void *pixels) const +{ + return mImplementation->getRenderbufferImage(context, packState, packBuffer, format, type, + pixels); +} + +void Renderbuffer::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) +{ + ASSERT(message == angle::SubjectMessage::SubjectChanged); + onStateChange(angle::SubjectMessage::ContentsChanged); +} +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/Renderbuffer.h b/gfx/angle/checkout/src/libANGLE/Renderbuffer.h new file mode 100644 index 0000000000..1f85afc5e5 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Renderbuffer.h @@ -0,0 +1,181 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Renderbuffer.h: Defines the renderer-agnostic container class gl::Renderbuffer. +// Implements GL renderbuffer objects and related functionality. +// [OpenGL ES 2.0.24] section 4.4.3 page 108. + +#ifndef LIBANGLE_RENDERBUFFER_H_ +#define LIBANGLE_RENDERBUFFER_H_ + +#include "angle_gl.h" +#include "common/angleutils.h" +#include "libANGLE/Debug.h" +#include "libANGLE/Error.h" +#include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/Image.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/RenderbufferImpl.h" + +namespace rx +{ +class GLImplFactory; +} // namespace rx + +namespace gl +{ +// A GL renderbuffer object is usually used as a depth or stencil buffer attachment +// for a framebuffer object. The renderbuffer itself is a distinct GL object, see +// FramebufferAttachment and Framebuffer for how they are applied to an FBO via an +// attachment point. + +class RenderbufferState final : angle::NonCopyable +{ + public: + RenderbufferState(); + ~RenderbufferState(); + + GLsizei getWidth() const; + GLsizei getHeight() const; + const Format &getFormat() const; + GLsizei getSamples() const; + MultisamplingMode getMultisamplingMode() const; + InitState getInitState() const; + void setProtectedContent(bool hasProtectedContent); + + private: + friend class Renderbuffer; + + void update(GLsizei width, + GLsizei height, + const Format &format, + GLsizei samples, + MultisamplingMode multisamplingMode, + InitState initState); + + GLsizei mWidth; + GLsizei mHeight; + Format mFormat; + GLsizei mSamples; + MultisamplingMode mMultisamplingMode; + bool mHasProtectedContent; + + // For robust resource init. + InitState mInitState; +}; + +class Renderbuffer final : public RefCountObject, + public egl::ImageSibling, + public LabeledObject +{ + public: + Renderbuffer(rx::GLImplFactory *implFactory, RenderbufferID id); + ~Renderbuffer() override; + + void onDestroy(const Context *context) override; + + angle::Result setLabel(const Context *context, const std::string &label) override; + const std::string &getLabel() const override; + + angle::Result setStorage(const Context *context, + GLenum internalformat, + GLsizei width, + GLsizei height); + angle::Result setStorageMultisample(const Context *context, + GLsizei samplesIn, + GLenum internalformat, + GLsizei width, + GLsizei height, + MultisamplingMode mode); + angle::Result setStorageEGLImageTarget(const Context *context, egl::Image *imageTarget); + + angle::Result copyRenderbufferSubData(Context *context, + const gl::Renderbuffer *srcBuffer, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth); + + angle::Result copyTextureSubData(Context *context, + const gl::Texture *srcTexture, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth); + + rx::RenderbufferImpl *getImplementation() const; + + GLsizei getWidth() const; + GLsizei getHeight() const; + const Format &getFormat() const; + GLsizei getSamples() const; + MultisamplingMode getMultisamplingMode() const; + GLuint getRedSize() const; + GLuint getGreenSize() const; + GLuint getBlueSize() const; + GLuint getAlphaSize() const; + GLuint getDepthSize() const; + GLuint getStencilSize() const; + const RenderbufferState &getState() const; + + GLint getMemorySize() const; + + // FramebufferAttachmentObject Impl + Extents getAttachmentSize(const ImageIndex &imageIndex) const override; + Format getAttachmentFormat(GLenum binding, const ImageIndex &imageIndex) const override; + GLsizei getAttachmentSamples(const ImageIndex &imageIndex) const override; + bool isRenderable(const Context *context, + GLenum binding, + const ImageIndex &imageIndex) const override; + + void onAttach(const Context *context, rx::Serial framebufferSerial) override; + void onDetach(const Context *context, rx::Serial framebufferSerial) override; + GLuint getId() const override; + + InitState initState(GLenum binding, const ImageIndex &imageIndex) const override; + void setInitState(GLenum binding, const ImageIndex &imageIndex, InitState initState) override; + + GLenum getImplementationColorReadFormat(const Context *context) const; + GLenum getImplementationColorReadType(const Context *context) const; + + // We pass the pack buffer and state explicitly so they can be overridden during capture. + angle::Result getRenderbufferImage(const Context *context, + const PixelPackState &packState, + Buffer *packBuffer, + GLenum format, + GLenum type, + void *pixels) const; + + private: + // ObserverInterface implementation. + void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; + + rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override; + + RenderbufferState mState; + std::unique_ptr mImplementation; + + std::string mLabel; + angle::ObserverBinding mImplObserverBinding; +}; + +} // namespace gl + +#endif // LIBANGLE_RENDERBUFFER_H_ diff --git a/gfx/angle/checkout/src/libANGLE/ResourceManager.cpp b/gfx/angle/checkout/src/libANGLE/ResourceManager.cpp new file mode 100644 index 0000000000..d5efce2319 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/ResourceManager.cpp @@ -0,0 +1,522 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ResourceManager.cpp: Implements the the ResourceManager classes, which handle allocation and +// lifetime of GL objects. + +#include "libANGLE/ResourceManager.h" + +#include "libANGLE/Buffer.h" +#include "libANGLE/Context.h" +#include "libANGLE/Fence.h" +#include "libANGLE/MemoryObject.h" +#include "libANGLE/Program.h" +#include "libANGLE/ProgramPipeline.h" +#include "libANGLE/Query.h" +#include "libANGLE/Renderbuffer.h" +#include "libANGLE/Sampler.h" +#include "libANGLE/Semaphore.h" +#include "libANGLE/Shader.h" +#include "libANGLE/Texture.h" +#include "libANGLE/renderer/ContextImpl.h" + +namespace gl +{ + +namespace +{ + +template +IDType AllocateEmptyObject(HandleAllocator *handleAllocator, + ResourceMap *objectMap) +{ + IDType handle = PackParam(handleAllocator->allocate()); + objectMap->assign(handle, nullptr); + return handle; +} + +} // anonymous namespace + +ResourceManagerBase::ResourceManagerBase() : mRefCount(1) {} + +ResourceManagerBase::~ResourceManagerBase() = default; + +void ResourceManagerBase::addRef() +{ + mRefCount++; +} + +void ResourceManagerBase::release(const Context *context) +{ + if (--mRefCount == 0) + { + reset(context); + delete this; + } +} + +template +TypedResourceManager::~TypedResourceManager() +{ + ASSERT(mObjectMap.empty()); +} + +template +void TypedResourceManager::reset(const Context *context) +{ + this->mHandleAllocator.reset(); + for (const auto &resource : mObjectMap) + { + if (resource.second) + { + ImplT::DeleteObject(context, resource.second); + } + } + mObjectMap.clear(); +} + +template +void TypedResourceManager::deleteObject(const Context *context, + IDType handle) +{ + ResourceType *resource = nullptr; + if (!mObjectMap.erase(handle, &resource)) + { + return; + } + + // Requires an explicit this-> because of C++ template rules. + this->mHandleAllocator.release(GetIDValue(handle)); + + if (resource) + { + ImplT::DeleteObject(context, resource); + } +} + +template class TypedResourceManager; +template class TypedResourceManager; +template class TypedResourceManager; +template class TypedResourceManager; +template class TypedResourceManager; +template class TypedResourceManager; +template class TypedResourceManager; + +// BufferManager Implementation. +BufferManager::~BufferManager() = default; + +// static +Buffer *BufferManager::AllocateNewObject(rx::GLImplFactory *factory, BufferID handle) +{ + Buffer *buffer = new Buffer(factory, handle); + buffer->addRef(); + return buffer; +} + +// static +void BufferManager::DeleteObject(const Context *context, Buffer *buffer) +{ + buffer->release(context); +} + +BufferID BufferManager::createBuffer() +{ + return AllocateEmptyObject(&mHandleAllocator, &mObjectMap); +} + +Buffer *BufferManager::getBuffer(BufferID handle) const +{ + return mObjectMap.query(handle); +} + +// ShaderProgramManager Implementation. + +ShaderProgramManager::ShaderProgramManager() {} + +ShaderProgramManager::~ShaderProgramManager() +{ + ASSERT(mPrograms.empty()); + ASSERT(mShaders.empty()); +} + +void ShaderProgramManager::reset(const Context *context) +{ + while (!mPrograms.empty()) + { + deleteProgram(context, {mPrograms.begin()->first}); + } + mPrograms.clear(); + while (!mShaders.empty()) + { + deleteShader(context, {mShaders.begin()->first}); + } + mShaders.clear(); +} + +ShaderProgramID ShaderProgramManager::createShader(rx::GLImplFactory *factory, + const gl::Limitations &rendererLimitations, + ShaderType type) +{ + ASSERT(type != ShaderType::InvalidEnum); + ShaderProgramID handle = ShaderProgramID{mHandleAllocator.allocate()}; + mShaders.assign(handle, new Shader(this, factory, rendererLimitations, type, handle)); + return handle; +} + +void ShaderProgramManager::deleteShader(const Context *context, ShaderProgramID shader) +{ + deleteObject(context, &mShaders, shader); +} + +Shader *ShaderProgramManager::getShader(ShaderProgramID handle) const +{ + return mShaders.query(handle); +} + +ShaderProgramID ShaderProgramManager::createProgram(rx::GLImplFactory *factory) +{ + ShaderProgramID handle = ShaderProgramID{mHandleAllocator.allocate()}; + mPrograms.assign(handle, new Program(factory, this, handle)); + return handle; +} + +void ShaderProgramManager::deleteProgram(const gl::Context *context, ShaderProgramID program) +{ + deleteObject(context, &mPrograms, program); +} + +template +void ShaderProgramManager::deleteObject(const Context *context, + ResourceMap *objectMap, + IDType id) +{ + ObjectType *object = objectMap->query(id); + if (!object) + { + return; + } + + if (object->getRefCount() == 0) + { + mHandleAllocator.release(id.value); + object->onDestroy(context); + objectMap->erase(id, &object); + } + else + { + object->flagForDeletion(); + } +} + +// TextureManager Implementation. + +TextureManager::~TextureManager() = default; + +// static +Texture *TextureManager::AllocateNewObject(rx::GLImplFactory *factory, + TextureID handle, + TextureType type) +{ + Texture *texture = new Texture(factory, handle, type); + texture->addRef(); + return texture; +} + +// static +void TextureManager::DeleteObject(const Context *context, Texture *texture) +{ + texture->release(context); +} + +TextureID TextureManager::createTexture() +{ + return AllocateEmptyObject(&mHandleAllocator, &mObjectMap); +} + +void TextureManager::signalAllTexturesDirty() const +{ + for (const auto &texture : mObjectMap) + { + if (texture.second) + { + // We don't know if the Texture needs init, but that's ok, since it will only force + // a re-check, and will not initialize the pixels if it's not needed. + texture.second->signalDirtyStorage(InitState::MayNeedInit); + } + } +} + +void TextureManager::enableHandleAllocatorLogging() +{ + mHandleAllocator.enableLogging(true); +} + +// RenderbufferManager Implementation. + +RenderbufferManager::~RenderbufferManager() = default; + +// static +Renderbuffer *RenderbufferManager::AllocateNewObject(rx::GLImplFactory *factory, + RenderbufferID handle) +{ + Renderbuffer *renderbuffer = new Renderbuffer(factory, handle); + renderbuffer->addRef(); + return renderbuffer; +} + +// static +void RenderbufferManager::DeleteObject(const Context *context, Renderbuffer *renderbuffer) +{ + renderbuffer->release(context); +} + +RenderbufferID RenderbufferManager::createRenderbuffer() +{ + return {AllocateEmptyObject(&mHandleAllocator, &mObjectMap)}; +} + +Renderbuffer *RenderbufferManager::getRenderbuffer(RenderbufferID handle) const +{ + return mObjectMap.query(handle); +} + +// SamplerManager Implementation. + +SamplerManager::~SamplerManager() = default; + +// static +Sampler *SamplerManager::AllocateNewObject(rx::GLImplFactory *factory, SamplerID handle) +{ + Sampler *sampler = new Sampler(factory, handle); + sampler->addRef(); + return sampler; +} + +// static +void SamplerManager::DeleteObject(const Context *context, Sampler *sampler) +{ + sampler->release(context); +} + +SamplerID SamplerManager::createSampler() +{ + return AllocateEmptyObject(&mHandleAllocator, &mObjectMap); +} + +Sampler *SamplerManager::getSampler(SamplerID handle) const +{ + return mObjectMap.query(handle); +} + +bool SamplerManager::isSampler(SamplerID sampler) const +{ + return mObjectMap.contains(sampler); +} + +// SyncManager Implementation. + +SyncManager::~SyncManager() = default; + +// static +void SyncManager::DeleteObject(const Context *context, Sync *sync) +{ + sync->release(context); +} + +GLuint SyncManager::createSync(rx::GLImplFactory *factory) +{ + GLuint handle = mHandleAllocator.allocate(); + Sync *sync = new Sync(factory, handle); + sync->addRef(); + mObjectMap.assign(handle, sync); + return handle; +} + +Sync *SyncManager::getSync(GLuint handle) const +{ + return mObjectMap.query(handle); +} + +// FramebufferManager Implementation. + +FramebufferManager::~FramebufferManager() = default; + +// static +Framebuffer *FramebufferManager::AllocateNewObject(rx::GLImplFactory *factory, + FramebufferID handle, + const Context *context) +{ + // Make sure the caller isn't using a reserved handle. + ASSERT(handle != Framebuffer::kDefaultDrawFramebufferHandle); + return new Framebuffer(context, factory, handle); +} + +// static +void FramebufferManager::DeleteObject(const Context *context, Framebuffer *framebuffer) +{ + framebuffer->onDestroy(context); + delete framebuffer; +} + +FramebufferID FramebufferManager::createFramebuffer() +{ + return AllocateEmptyObject(&mHandleAllocator, &mObjectMap); +} + +Framebuffer *FramebufferManager::getFramebuffer(FramebufferID handle) const +{ + return mObjectMap.query(handle); +} + +void FramebufferManager::setDefaultFramebuffer(Framebuffer *framebuffer) +{ + ASSERT(framebuffer == nullptr || framebuffer->isDefault()); + mObjectMap.assign(Framebuffer::kDefaultDrawFramebufferHandle, framebuffer); +} + +Framebuffer *FramebufferManager::getDefaultFramebuffer() const +{ + return getFramebuffer(Framebuffer::kDefaultDrawFramebufferHandle); +} + +void FramebufferManager::invalidateFramebufferCompletenessCache() const +{ + for (const auto &framebuffer : mObjectMap) + { + if (framebuffer.second) + { + framebuffer.second->invalidateCompletenessCache(); + } + } +} + +// ProgramPipelineManager Implementation. + +ProgramPipelineManager::~ProgramPipelineManager() = default; + +// static +ProgramPipeline *ProgramPipelineManager::AllocateNewObject(rx::GLImplFactory *factory, + ProgramPipelineID handle) +{ + ProgramPipeline *pipeline = new ProgramPipeline(factory, handle); + pipeline->addRef(); + return pipeline; +} + +// static +void ProgramPipelineManager::DeleteObject(const Context *context, ProgramPipeline *pipeline) +{ + pipeline->release(context); +} + +ProgramPipelineID ProgramPipelineManager::createProgramPipeline() +{ + return AllocateEmptyObject(&mHandleAllocator, &mObjectMap); +} + +ProgramPipeline *ProgramPipelineManager::getProgramPipeline(ProgramPipelineID handle) const +{ + return mObjectMap.query(handle); +} + +// MemoryObjectManager Implementation. + +MemoryObjectManager::MemoryObjectManager() {} + +MemoryObjectManager::~MemoryObjectManager() +{ + ASSERT(mMemoryObjects.empty()); +} + +void MemoryObjectManager::reset(const Context *context) +{ + while (!mMemoryObjects.empty()) + { + deleteMemoryObject(context, {mMemoryObjects.begin()->first}); + } + mMemoryObjects.clear(); +} + +MemoryObjectID MemoryObjectManager::createMemoryObject(rx::GLImplFactory *factory) +{ + MemoryObjectID handle = MemoryObjectID{mHandleAllocator.allocate()}; + MemoryObject *memoryObject = new MemoryObject(factory, handle); + memoryObject->addRef(); + mMemoryObjects.assign(handle, memoryObject); + return handle; +} + +void MemoryObjectManager::deleteMemoryObject(const Context *context, MemoryObjectID handle) +{ + MemoryObject *memoryObject = nullptr; + if (!mMemoryObjects.erase(handle, &memoryObject)) + { + return; + } + + // Requires an explicit this-> because of C++ template rules. + this->mHandleAllocator.release(handle.value); + + if (memoryObject) + { + memoryObject->release(context); + } +} + +MemoryObject *MemoryObjectManager::getMemoryObject(MemoryObjectID handle) const +{ + return mMemoryObjects.query(handle); +} + +// SemaphoreManager Implementation. + +SemaphoreManager::SemaphoreManager() {} + +SemaphoreManager::~SemaphoreManager() +{ + ASSERT(mSemaphores.empty()); +} + +void SemaphoreManager::reset(const Context *context) +{ + while (!mSemaphores.empty()) + { + deleteSemaphore(context, {mSemaphores.begin()->first}); + } + mSemaphores.clear(); +} + +SemaphoreID SemaphoreManager::createSemaphore(rx::GLImplFactory *factory) +{ + SemaphoreID handle = SemaphoreID{mHandleAllocator.allocate()}; + Semaphore *semaphore = new Semaphore(factory, handle); + semaphore->addRef(); + mSemaphores.assign(handle, semaphore); + return handle; +} + +void SemaphoreManager::deleteSemaphore(const Context *context, SemaphoreID handle) +{ + Semaphore *semaphore = nullptr; + if (!mSemaphores.erase(handle, &semaphore)) + { + return; + } + + // Requires an explicit this-> because of C++ template rules. + this->mHandleAllocator.release(handle.value); + + if (semaphore) + { + semaphore->release(context); + } +} + +Semaphore *SemaphoreManager::getSemaphore(SemaphoreID handle) const +{ + return mSemaphores.query(handle); +} +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/ResourceManager.h b/gfx/angle/checkout/src/libANGLE/ResourceManager.h new file mode 100644 index 0000000000..0f8447ed24 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/ResourceManager.h @@ -0,0 +1,353 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ResourceManager.h : Defines the ResourceManager classes, which handle allocation and lifetime of +// GL objects. + +#ifndef LIBANGLE_RESOURCEMANAGER_H_ +#define LIBANGLE_RESOURCEMANAGER_H_ + +#include "angle_gl.h" +#include "common/angleutils.h" +#include "libANGLE/Error.h" +#include "libANGLE/HandleAllocator.h" +#include "libANGLE/ResourceMap.h" + +namespace rx +{ +class GLImplFactory; +} // namespace rx + +namespace egl +{ +class ShareGroup; +} // namespace egl + +namespace gl +{ +class Buffer; +struct Caps; +class Context; +class Framebuffer; +struct Limitations; +class MemoryObject; +class Path; +class Program; +class ProgramPipeline; +class Renderbuffer; +class Sampler; +class Semaphore; +class Shader; +class Sync; +class Texture; + +class ResourceManagerBase : angle::NonCopyable +{ + public: + ResourceManagerBase(); + + void addRef(); + void release(const Context *context); + + protected: + virtual void reset(const Context *context) = 0; + virtual ~ResourceManagerBase(); + + HandleAllocator mHandleAllocator; + + private: + size_t mRefCount; +}; + +template +class TypedResourceManager : public ResourceManagerBase +{ + public: + TypedResourceManager() {} + + void deleteObject(const Context *context, IDType handle); + ANGLE_INLINE bool isHandleGenerated(IDType handle) const + { + // Zero is always assumed to have been generated implicitly. + return GetIDValue(handle) == 0 || mObjectMap.contains(handle); + } + + typename ResourceMap::Iterator begin() const + { + return mObjectMap.begin(); + } + typename ResourceMap::Iterator end() const { return mObjectMap.end(); } + + protected: + ~TypedResourceManager() override; + + // Inlined in the header for performance. + template + ANGLE_INLINE ResourceType *checkObjectAllocation(rx::GLImplFactory *factory, + IDType handle, + ArgTypes... args) + { + ResourceType *value = mObjectMap.query(handle); + if (value) + { + return value; + } + + if (GetIDValue(handle) == 0) + { + return nullptr; + } + + return checkObjectAllocationImpl(factory, handle, args...); + } + + void reset(const Context *context) override; + + ResourceMap mObjectMap; + + private: + template + ResourceType *checkObjectAllocationImpl(rx::GLImplFactory *factory, + IDType handle, + ArgTypes... args) + { + ResourceType *object = ImplT::AllocateNewObject(factory, handle, args...); + + if (!mObjectMap.contains(handle)) + { + this->mHandleAllocator.reserve(GetIDValue(handle)); + } + mObjectMap.assign(handle, object); + + return object; + } +}; + +class BufferManager : public TypedResourceManager +{ + public: + BufferID createBuffer(); + Buffer *getBuffer(BufferID handle) const; + + ANGLE_INLINE Buffer *checkBufferAllocation(rx::GLImplFactory *factory, BufferID handle) + { + return checkObjectAllocation(factory, handle); + } + + // TODO(jmadill): Investigate design which doesn't expose these methods publicly. + static Buffer *AllocateNewObject(rx::GLImplFactory *factory, BufferID handle); + static void DeleteObject(const Context *context, Buffer *buffer); + + protected: + ~BufferManager() override; +}; + +class ShaderProgramManager : public ResourceManagerBase +{ + public: + ShaderProgramManager(); + + ShaderProgramID createShader(rx::GLImplFactory *factory, + const Limitations &rendererLimitations, + ShaderType type); + void deleteShader(const Context *context, ShaderProgramID shader); + Shader *getShader(ShaderProgramID handle) const; + + ShaderProgramID createProgram(rx::GLImplFactory *factory); + void deleteProgram(const Context *context, ShaderProgramID program); + + ANGLE_INLINE Program *getProgram(ShaderProgramID handle) const + { + return mPrograms.query(handle); + } + + // For capture and performance counters only. + const ResourceMap &getShadersForCapture() const { return mShaders; } + const ResourceMap &getProgramsForCaptureAndPerf() const + { + return mPrograms; + } + + protected: + ~ShaderProgramManager() override; + + private: + template + void deleteObject(const Context *context, + ResourceMap *objectMap, + IDType id); + + void reset(const Context *context) override; + + ResourceMap mShaders; + ResourceMap mPrograms; +}; + +class TextureManager : public TypedResourceManager +{ + public: + TextureID createTexture(); + ANGLE_INLINE Texture *getTexture(TextureID handle) const + { + ASSERT(mObjectMap.query({0}) == nullptr); + return mObjectMap.query(handle); + } + + void signalAllTexturesDirty() const; + + ANGLE_INLINE Texture *checkTextureAllocation(rx::GLImplFactory *factory, + TextureID handle, + TextureType type) + { + return checkObjectAllocation(factory, handle, type); + } + + static Texture *AllocateNewObject(rx::GLImplFactory *factory, + TextureID handle, + TextureType type); + static void DeleteObject(const Context *context, Texture *texture); + + void enableHandleAllocatorLogging(); + + protected: + ~TextureManager() override; +}; + +class RenderbufferManager + : public TypedResourceManager +{ + public: + RenderbufferID createRenderbuffer(); + Renderbuffer *getRenderbuffer(RenderbufferID handle) const; + + Renderbuffer *checkRenderbufferAllocation(rx::GLImplFactory *factory, RenderbufferID handle) + { + return checkObjectAllocation(factory, handle); + } + + static Renderbuffer *AllocateNewObject(rx::GLImplFactory *factory, RenderbufferID handle); + static void DeleteObject(const Context *context, Renderbuffer *renderbuffer); + + protected: + ~RenderbufferManager() override; +}; + +class SamplerManager : public TypedResourceManager +{ + public: + SamplerID createSampler(); + Sampler *getSampler(SamplerID handle) const; + bool isSampler(SamplerID sampler) const; + + Sampler *checkSamplerAllocation(rx::GLImplFactory *factory, SamplerID handle) + { + return checkObjectAllocation(factory, handle); + } + + static Sampler *AllocateNewObject(rx::GLImplFactory *factory, SamplerID handle); + static void DeleteObject(const Context *context, Sampler *sampler); + + protected: + ~SamplerManager() override; +}; + +class SyncManager : public TypedResourceManager +{ + public: + GLuint createSync(rx::GLImplFactory *factory); + Sync *getSync(GLuint handle) const; + + static void DeleteObject(const Context *context, Sync *sync); + + protected: + ~SyncManager() override; +}; + +class FramebufferManager + : public TypedResourceManager +{ + public: + FramebufferID createFramebuffer(); + Framebuffer *getFramebuffer(FramebufferID handle) const; + void setDefaultFramebuffer(Framebuffer *framebuffer); + Framebuffer *getDefaultFramebuffer() const; + + void invalidateFramebufferCompletenessCache() const; + + Framebuffer *checkFramebufferAllocation(rx::GLImplFactory *factory, + const Context *context, + FramebufferID handle) + { + return checkObjectAllocation(factory, handle, context); + } + + static Framebuffer *AllocateNewObject(rx::GLImplFactory *factory, + FramebufferID handle, + const Context *context); + static void DeleteObject(const Context *context, Framebuffer *framebuffer); + + protected: + ~FramebufferManager() override; +}; + +class ProgramPipelineManager + : public TypedResourceManager +{ + public: + ProgramPipelineID createProgramPipeline(); + ProgramPipeline *getProgramPipeline(ProgramPipelineID handle) const; + + ProgramPipeline *checkProgramPipelineAllocation(rx::GLImplFactory *factory, + ProgramPipelineID handle) + { + return checkObjectAllocation(factory, handle); + } + + static ProgramPipeline *AllocateNewObject(rx::GLImplFactory *factory, ProgramPipelineID handle); + static void DeleteObject(const Context *context, ProgramPipeline *pipeline); + + protected: + ~ProgramPipelineManager() override; +}; + +class MemoryObjectManager : public ResourceManagerBase +{ + public: + MemoryObjectManager(); + + MemoryObjectID createMemoryObject(rx::GLImplFactory *factory); + void deleteMemoryObject(const Context *context, MemoryObjectID handle); + MemoryObject *getMemoryObject(MemoryObjectID handle) const; + + protected: + ~MemoryObjectManager() override; + + private: + void reset(const Context *context) override; + + ResourceMap mMemoryObjects; +}; + +class SemaphoreManager : public ResourceManagerBase +{ + public: + SemaphoreManager(); + + SemaphoreID createSemaphore(rx::GLImplFactory *factory); + void deleteSemaphore(const Context *context, SemaphoreID handle); + Semaphore *getSemaphore(SemaphoreID handle) const; + + protected: + ~SemaphoreManager() override; + + private: + void reset(const Context *context) override; + + ResourceMap mSemaphores; +}; +} // namespace gl + +#endif // LIBANGLE_RESOURCEMANAGER_H_ diff --git a/gfx/angle/checkout/src/libANGLE/ResourceMap.h b/gfx/angle/checkout/src/libANGLE/ResourceMap.h new file mode 100644 index 0000000000..b24c1e6240 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/ResourceMap.h @@ -0,0 +1,346 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ResourceMap: +// An optimized resource map which packs the first set of allocated objects into a +// flat array, and then falls back to an unordered map for the higher handle values. +// + +#ifndef LIBANGLE_RESOURCE_MAP_H_ +#define LIBANGLE_RESOURCE_MAP_H_ + +#include "libANGLE/angletypes.h" + +namespace gl +{ + +template +class ResourceMap final : angle::NonCopyable +{ + public: + ResourceMap(); + ~ResourceMap(); + + ANGLE_INLINE ResourceType *query(IDType id) const + { + GLuint handle = GetIDValue(id); + if (handle < mFlatResourcesSize) + { + ResourceType *value = mFlatResources[handle]; + return (value == InvalidPointer() ? nullptr : value); + } + auto it = mHashedResources.find(handle); + return (it == mHashedResources.end() ? nullptr : it->second); + } + + // Returns true if the handle was reserved. Not necessarily if the resource is created. + bool contains(IDType id) const; + + // Returns the element that was at this location. + bool erase(IDType id, ResourceType **resourceOut); + + void assign(IDType id, ResourceType *resource); + + // Clears the map. + void clear(); + + using IndexAndResource = std::pair; + using HashMap = angle::HashMap; + + class Iterator final + { + public: + bool operator==(const Iterator &other) const; + bool operator!=(const Iterator &other) const; + Iterator &operator++(); + const IndexAndResource *operator->() const; + const IndexAndResource &operator*() const; + + private: + friend class ResourceMap; + Iterator(const ResourceMap &origin, + GLuint flatIndex, + typename HashMap::const_iterator hashIndex, + bool skipNulls); + void updateValue(); + + const ResourceMap &mOrigin; + GLuint mFlatIndex; + typename HashMap::const_iterator mHashIndex; + IndexAndResource mValue; + bool mSkipNulls; + }; + + // null values represent reserved handles. + Iterator begin() const; + Iterator end() const; + Iterator find(IDType handle) const; + + Iterator beginWithNull() const; + Iterator endWithNull() const; + + // Not a constant-time operation, should only be used for verification. + bool empty() const; + + private: + friend class Iterator; + + GLuint nextResource(size_t flatIndex, bool skipNulls) const; + + // constexpr methods cannot contain reinterpret_cast, so we need a static method. + static ResourceType *InvalidPointer(); + static constexpr intptr_t kInvalidPointer = static_cast(-1); + + // Start with 32 maximum elements in the map, which can grow. + static constexpr size_t kInitialFlatResourcesSize = 0x20; + + // Experimental testing suggests that 16k is a reasonable upper limit. + static constexpr size_t kFlatResourcesLimit = 0x4000; + + // Size of one map element. + static constexpr size_t kElementSize = sizeof(ResourceType *); + + size_t mFlatResourcesSize; + ResourceType **mFlatResources; + + // A map of GL objects indexed by object ID. + HashMap mHashedResources; +}; + +template +ResourceMap::ResourceMap() + : mFlatResourcesSize(kInitialFlatResourcesSize), + mFlatResources(new ResourceType *[kInitialFlatResourcesSize]) +{ + memset(mFlatResources, kInvalidPointer, mFlatResourcesSize * kElementSize); +} + +template +ResourceMap::~ResourceMap() +{ + ASSERT(empty()); + delete[] mFlatResources; +} + +template +ANGLE_INLINE bool ResourceMap::contains(IDType id) const +{ + GLuint handle = GetIDValue(id); + if (handle < mFlatResourcesSize) + { + return (mFlatResources[handle] != InvalidPointer()); + } + return (mHashedResources.find(handle) != mHashedResources.end()); +} + +template +bool ResourceMap::erase(IDType id, ResourceType **resourceOut) +{ + GLuint handle = GetIDValue(id); + if (handle < mFlatResourcesSize) + { + auto &value = mFlatResources[handle]; + if (value == InvalidPointer()) + { + return false; + } + *resourceOut = value; + value = InvalidPointer(); + } + else + { + auto it = mHashedResources.find(handle); + if (it == mHashedResources.end()) + { + return false; + } + *resourceOut = it->second; + mHashedResources.erase(it); + } + return true; +} + +template +void ResourceMap::assign(IDType id, ResourceType *resource) +{ + GLuint handle = GetIDValue(id); + if (handle < kFlatResourcesLimit) + { + if (handle >= mFlatResourcesSize) + { + // Use power-of-two. + size_t newSize = mFlatResourcesSize; + while (newSize <= handle) + { + newSize *= 2; + } + + ResourceType **oldResources = mFlatResources; + + mFlatResources = new ResourceType *[newSize]; + memset(&mFlatResources[mFlatResourcesSize], kInvalidPointer, + (newSize - mFlatResourcesSize) * kElementSize); + memcpy(mFlatResources, oldResources, mFlatResourcesSize * kElementSize); + mFlatResourcesSize = newSize; + delete[] oldResources; + } + ASSERT(mFlatResourcesSize > handle); + mFlatResources[handle] = resource; + } + else + { + mHashedResources[handle] = resource; + } +} + +template +typename ResourceMap::Iterator ResourceMap::begin() + const +{ + return Iterator(*this, nextResource(0, true), mHashedResources.begin(), true); +} + +template +typename ResourceMap::Iterator ResourceMap::end() const +{ + return Iterator(*this, static_cast(mFlatResourcesSize), mHashedResources.end(), true); +} + +template +typename ResourceMap::Iterator +ResourceMap::beginWithNull() const +{ + return Iterator(*this, nextResource(0, false), mHashedResources.begin(), false); +} + +template +typename ResourceMap::Iterator +ResourceMap::endWithNull() const +{ + return Iterator(*this, static_cast(mFlatResourcesSize), mHashedResources.end(), false); +} + +template +typename ResourceMap::Iterator ResourceMap::find( + IDType handle) const +{ + if (handle < mFlatResourcesSize) + { + return (mFlatResources[handle] != InvalidPointer() + ? Iterator(handle, mHashedResources.begin()) + : end()); + } + else + { + return mHashedResources.find(handle); + } +} + +template +bool ResourceMap::empty() const +{ + return (begin() == end()); +} + +template +void ResourceMap::clear() +{ + memset(mFlatResources, kInvalidPointer, kInitialFlatResourcesSize * kElementSize); + mFlatResourcesSize = kInitialFlatResourcesSize; + mHashedResources.clear(); +} + +template +GLuint ResourceMap::nextResource(size_t flatIndex, bool skipNulls) const +{ + for (size_t index = flatIndex; index < mFlatResourcesSize; index++) + { + if ((mFlatResources[index] != nullptr || !skipNulls) && + mFlatResources[index] != InvalidPointer()) + { + return static_cast(index); + } + } + return static_cast(mFlatResourcesSize); +} + +template +// static +ResourceType *ResourceMap::InvalidPointer() +{ + return reinterpret_cast(kInvalidPointer); +} + +template +ResourceMap::Iterator::Iterator( + const ResourceMap &origin, + GLuint flatIndex, + typename ResourceMap::HashMap::const_iterator hashIndex, + bool skipNulls) + : mOrigin(origin), mFlatIndex(flatIndex), mHashIndex(hashIndex), mSkipNulls(skipNulls) +{ + updateValue(); +} + +template +bool ResourceMap::Iterator::operator==(const Iterator &other) const +{ + return (mFlatIndex == other.mFlatIndex && mHashIndex == other.mHashIndex); +} + +template +bool ResourceMap::Iterator::operator!=(const Iterator &other) const +{ + return !(*this == other); +} + +template +typename ResourceMap::Iterator & +ResourceMap::Iterator::operator++() +{ + if (mFlatIndex < static_cast(mOrigin.mFlatResourcesSize)) + { + mFlatIndex = mOrigin.nextResource(mFlatIndex + 1, mSkipNulls); + } + else + { + mHashIndex++; + } + updateValue(); + return *this; +} + +template +const typename ResourceMap::IndexAndResource * +ResourceMap::Iterator::operator->() const +{ + return &mValue; +} + +template +const typename ResourceMap::IndexAndResource & +ResourceMap::Iterator::operator*() const +{ + return mValue; +} + +template +void ResourceMap::Iterator::updateValue() +{ + if (mFlatIndex < static_cast(mOrigin.mFlatResourcesSize)) + { + mValue.first = mFlatIndex; + mValue.second = mOrigin.mFlatResources[mFlatIndex]; + } + else if (mHashIndex != mOrigin.mHashedResources.end()) + { + mValue.first = mHashIndex->first; + mValue.second = mHashIndex->second; + } +} + +} // namespace gl + +#endif // LIBANGLE_RESOURCE_MAP_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Sampler.cpp b/gfx/angle/checkout/src/libANGLE/Sampler.cpp new file mode 100644 index 0000000000..3cfdbbdf4f --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Sampler.cpp @@ -0,0 +1,211 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Sampler.cpp : Implements the Sampler class, which represents a GLES 3 +// sampler object. Sampler objects store some state needed to sample textures. + +#include "libANGLE/Sampler.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/renderer/GLImplFactory.h" +#include "libANGLE/renderer/SamplerImpl.h" + +namespace gl +{ + +Sampler::Sampler(rx::GLImplFactory *factory, SamplerID id) + : RefCountObject(factory->generateSerial(), id), + mState(), + mDirty(true), + mSampler(factory->createSampler(mState)), + mLabel() +{} + +Sampler::~Sampler() +{ + SafeDelete(mSampler); +} + +void Sampler::onDestroy(const Context *context) +{ + if (mSampler) + { + mSampler->onDestroy(context); + } +} + +angle::Result Sampler::setLabel(const Context *context, const std::string &label) +{ + mLabel = label; + + if (mSampler) + { + return mSampler->onLabelUpdate(context); + } + return angle::Result::Continue; +} + +const std::string &Sampler::getLabel() const +{ + return mLabel; +} + +void Sampler::setMinFilter(const Context *context, GLenum minFilter) +{ + mState.setMinFilter(minFilter); + signalDirtyState(); +} + +GLenum Sampler::getMinFilter() const +{ + return mState.getMinFilter(); +} + +void Sampler::setMagFilter(const Context *context, GLenum magFilter) +{ + mState.setMagFilter(magFilter); + signalDirtyState(); +} + +GLenum Sampler::getMagFilter() const +{ + return mState.getMagFilter(); +} + +void Sampler::setWrapS(const Context *context, GLenum wrapS) +{ + mState.setWrapS(wrapS); + signalDirtyState(); +} + +GLenum Sampler::getWrapS() const +{ + return mState.getWrapS(); +} + +void Sampler::setWrapT(const Context *context, GLenum wrapT) +{ + mState.setWrapT(wrapT); + signalDirtyState(); +} + +GLenum Sampler::getWrapT() const +{ + return mState.getWrapT(); +} + +void Sampler::setWrapR(const Context *context, GLenum wrapR) +{ + mState.setWrapR(wrapR); + signalDirtyState(); +} + +GLenum Sampler::getWrapR() const +{ + return mState.getWrapR(); +} + +void Sampler::setMaxAnisotropy(const Context *context, float maxAnisotropy) +{ + mState.setMaxAnisotropy(maxAnisotropy); + signalDirtyState(); +} + +float Sampler::getMaxAnisotropy() const +{ + return mState.getMaxAnisotropy(); +} + +void Sampler::setMinLod(const Context *context, GLfloat minLod) +{ + mState.setMinLod(minLod); + signalDirtyState(); +} + +GLfloat Sampler::getMinLod() const +{ + return mState.getMinLod(); +} + +void Sampler::setMaxLod(const Context *context, GLfloat maxLod) +{ + mState.setMaxLod(maxLod); + signalDirtyState(); +} + +GLfloat Sampler::getMaxLod() const +{ + return mState.getMaxLod(); +} + +void Sampler::setCompareMode(const Context *context, GLenum compareMode) +{ + mState.setCompareMode(compareMode); + signalDirtyState(); +} + +GLenum Sampler::getCompareMode() const +{ + return mState.getCompareMode(); +} + +void Sampler::setCompareFunc(const Context *context, GLenum compareFunc) +{ + mState.setCompareFunc(compareFunc); + signalDirtyState(); +} + +GLenum Sampler::getCompareFunc() const +{ + return mState.getCompareFunc(); +} + +void Sampler::setSRGBDecode(const Context *context, GLenum sRGBDecode) +{ + mState.setSRGBDecode(sRGBDecode); + signalDirtyState(); +} + +GLenum Sampler::getSRGBDecode() const +{ + return mState.getSRGBDecode(); +} + +void Sampler::setBorderColor(const Context *context, const ColorGeneric &color) +{ + mState.setBorderColor(color); + signalDirtyState(); +} + +const ColorGeneric &Sampler::getBorderColor() const +{ + return mState.getBorderColor(); +} + +const SamplerState &Sampler::getSamplerState() const +{ + return mState; +} + +rx::SamplerImpl *Sampler::getImplementation() const +{ + return mSampler; +} + +angle::Result Sampler::syncState(const Context *context) +{ + ASSERT(isDirty()); + angle::Result result = mSampler->syncState(context, mDirty); + mDirty = result != angle::Result::Continue; + return result; +} + +void Sampler::signalDirtyState() +{ + mDirty = true; + onStateChange(angle::SubjectMessage::DirtyBitsFlagged); +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/Sampler.h b/gfx/angle/checkout/src/libANGLE/Sampler.h new file mode 100644 index 0000000000..b483593780 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Sampler.h @@ -0,0 +1,92 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Sampler.h : Defines the Sampler class, which represents a GLES 3 +// sampler object. Sampler objects store some state needed to sample textures. + +#ifndef LIBANGLE_SAMPLER_H_ +#define LIBANGLE_SAMPLER_H_ + +#include "libANGLE/Debug.h" +#include "libANGLE/Observer.h" +#include "libANGLE/RefCountObject.h" +#include "libANGLE/angletypes.h" + +namespace rx +{ +class GLImplFactory; +class SamplerImpl; +} // namespace rx + +namespace gl +{ + +class Sampler final : public RefCountObject, public LabeledObject, public angle::Subject +{ + public: + Sampler(rx::GLImplFactory *factory, SamplerID id); + ~Sampler() override; + + void onDestroy(const Context *context) override; + + angle::Result setLabel(const Context *context, const std::string &label) override; + const std::string &getLabel() const override; + + void setMinFilter(const Context *context, GLenum minFilter); + GLenum getMinFilter() const; + + void setMagFilter(const Context *context, GLenum magFilter); + GLenum getMagFilter() const; + + void setWrapS(const Context *context, GLenum wrapS); + GLenum getWrapS() const; + + void setWrapT(const Context *context, GLenum wrapT); + GLenum getWrapT() const; + + void setWrapR(const Context *context, GLenum wrapR); + GLenum getWrapR() const; + + void setMaxAnisotropy(const Context *context, float maxAnisotropy); + float getMaxAnisotropy() const; + + void setMinLod(const Context *context, GLfloat minLod); + GLfloat getMinLod() const; + + void setMaxLod(const Context *context, GLfloat maxLod); + GLfloat getMaxLod() const; + + void setCompareMode(const Context *context, GLenum compareMode); + GLenum getCompareMode() const; + + void setCompareFunc(const Context *context, GLenum compareFunc); + GLenum getCompareFunc() const; + + void setSRGBDecode(const Context *context, GLenum sRGBDecode); + GLenum getSRGBDecode() const; + + void setBorderColor(const Context *context, const ColorGeneric &color); + const ColorGeneric &getBorderColor() const; + + const SamplerState &getSamplerState() const; + + rx::SamplerImpl *getImplementation() const; + + angle::Result syncState(const Context *context); + bool isDirty() const { return mDirty; } + + private: + void signalDirtyState(); + SamplerState mState; + bool mDirty; + rx::SamplerImpl *mSampler; + + std::string mLabel; +}; + +} // namespace gl + +#endif // LIBANGLE_SAMPLER_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Semaphore.cpp b/gfx/angle/checkout/src/libANGLE/Semaphore.cpp new file mode 100644 index 0000000000..45621653e3 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Semaphore.cpp @@ -0,0 +1,52 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Semaphore.h: Implements the gl::Semaphore class [EXT_external_objects] + +#include "libANGLE/Semaphore.h" + +#include "common/angleutils.h" +#include "libANGLE/renderer/GLImplFactory.h" +#include "libANGLE/renderer/SemaphoreImpl.h" + +namespace gl +{ + +Semaphore::Semaphore(rx::GLImplFactory *factory, SemaphoreID id) + : RefCountObject(factory->generateSerial(), id), mImplementation(factory->createSemaphore()) +{} + +Semaphore::~Semaphore() {} + +void Semaphore::onDestroy(const Context *context) +{ + mImplementation->onDestroy(context); +} + +angle::Result Semaphore::importFd(Context *context, HandleType handleType, GLint fd) +{ + return mImplementation->importFd(context, handleType, fd); +} + +angle::Result Semaphore::importZirconHandle(Context *context, HandleType handleType, GLuint handle) +{ + return mImplementation->importZirconHandle(context, handleType, handle); +} + +angle::Result Semaphore::wait(Context *context, + const BufferBarrierVector &bufferBarriers, + const TextureBarrierVector &textureBarriers) +{ + return mImplementation->wait(context, bufferBarriers, textureBarriers); +} + +angle::Result Semaphore::signal(Context *context, + const BufferBarrierVector &bufferBarriers, + const TextureBarrierVector &textureBarriers) +{ + return mImplementation->signal(context, bufferBarriers, textureBarriers); +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/Semaphore.h b/gfx/angle/checkout/src/libANGLE/Semaphore.h new file mode 100644 index 0000000000..02bdabedca --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Semaphore.h @@ -0,0 +1,57 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Semaphore.h: Defines the gl::Semaphore class [EXT_external_objects] + +#ifndef LIBANGLE_SEMAPHORE_H_ +#define LIBANGLE_SEMAPHORE_H_ + +#include + +#include "angle_gl.h" +#include "common/PackedEnums.h" +#include "common/angleutils.h" +#include "libANGLE/Error.h" +#include "libANGLE/RefCountObject.h" +#include "libANGLE/angletypes.h" + +namespace rx +{ +class GLImplFactory; +class SemaphoreImpl; +} // namespace rx + +namespace gl +{ +class Context; + +class Semaphore final : public RefCountObject +{ + public: + Semaphore(rx::GLImplFactory *factory, SemaphoreID id); + ~Semaphore() override; + + void onDestroy(const Context *context) override; + + rx::SemaphoreImpl *getImplementation() const { return mImplementation.get(); } + + angle::Result importFd(Context *context, HandleType handleType, GLint fd); + angle::Result importZirconHandle(Context *context, HandleType handleType, GLuint handle); + + angle::Result wait(Context *context, + const BufferBarrierVector &bufferBarriers, + const TextureBarrierVector &textureBarriers); + + angle::Result signal(Context *context, + const BufferBarrierVector &bufferBarriers, + const TextureBarrierVector &textureBarriers); + + private: + std::unique_ptr mImplementation; +}; + +} // namespace gl + +#endif // LIBANGLE_SEMAPHORE_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Shader.cpp b/gfx/angle/checkout/src/libANGLE/Shader.cpp new file mode 100644 index 0000000000..b1a718131a --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Shader.cpp @@ -0,0 +1,1331 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Shader.cpp: Implements the gl::Shader class and its derived classes +// VertexShader and FragmentShader. Implements GL shader objects and related +// functionality. [OpenGL ES 2.0.24] section 2.10 page 24 and section 3.8 page 84. + +#include "libANGLE/Shader.h" + +#include +#include + +#include "GLSLANG/ShaderLang.h" +#include "common/utilities.h" +#include "libANGLE/Caps.h" +#include "libANGLE/Compiler.h" +#include "libANGLE/Constants.h" +#include "libANGLE/Context.h" +#include "libANGLE/Display.h" +#include "libANGLE/MemoryShaderCache.h" +#include "libANGLE/Program.h" +#include "libANGLE/ResourceManager.h" +#include "libANGLE/renderer/GLImplFactory.h" +#include "libANGLE/renderer/ShaderImpl.h" +#include "platform/FrontendFeatures_autogen.h" + +namespace gl +{ + +namespace +{ +constexpr uint32_t kShaderCacheIdentifier = 0x12345678; + +template +std::vector GetActiveShaderVariables(const std::vector *variableList) +{ + ASSERT(variableList); + std::vector result; + for (size_t varIndex = 0; varIndex < variableList->size(); varIndex++) + { + const VarT &var = variableList->at(varIndex); + if (var.active) + { + result.push_back(var); + } + } + return result; +} + +template +const std::vector &GetShaderVariables(const std::vector *variableList) +{ + ASSERT(variableList); + return *variableList; +} + +void WriteInterfaceBlock(gl::BinaryOutputStream *stream, const sh::InterfaceBlock &block) +{ + stream->writeString(block.name); + stream->writeString(block.mappedName); + stream->writeString(block.instanceName); + stream->writeInt(block.arraySize); + stream->writeEnum(block.layout); + stream->writeBool(block.isRowMajorLayout); + stream->writeInt(block.binding); + stream->writeBool(block.staticUse); + stream->writeBool(block.active); + stream->writeEnum(block.blockType); + + stream->writeInt(block.fields.size()); + for (const sh::ShaderVariable &shaderVariable : block.fields) + { + WriteShaderVar(stream, shaderVariable); + } +} + +void LoadInterfaceBlock(gl::BinaryInputStream *stream, sh::InterfaceBlock &block) +{ + stream->readString(&block.name); + stream->readString(&block.mappedName); + stream->readString(&block.instanceName); + stream->readInt(&block.arraySize); + stream->readEnum(&block.layout); + stream->readBool(&block.isRowMajorLayout); + stream->readInt(&block.binding); + stream->readBool(&block.staticUse); + stream->readBool(&block.active); + stream->readEnum(&block.blockType); + + size_t size = stream->readInt(); + block.fields.resize(size); + for (sh::ShaderVariable &shaderVariable : block.fields) + { + LoadShaderVar(stream, &shaderVariable); + } +} +} // anonymous namespace + +// true if varying x has a higher priority in packing than y +bool CompareShaderVar(const sh::ShaderVariable &x, const sh::ShaderVariable &y) +{ + if (x.type == y.type) + { + return x.getArraySizeProduct() > y.getArraySizeProduct(); + } + + // Special case for handling structs: we sort these to the end of the list + if (x.type == GL_NONE) + { + return false; + } + + if (y.type == GL_NONE) + { + return true; + } + + return gl::VariableSortOrder(x.type) < gl::VariableSortOrder(y.type); +} + +const char *GetShaderTypeString(ShaderType type) +{ + switch (type) + { + case ShaderType::Vertex: + return "VERTEX"; + + case ShaderType::Fragment: + return "FRAGMENT"; + + case ShaderType::Compute: + return "COMPUTE"; + + case ShaderType::Geometry: + return "GEOMETRY"; + + case ShaderType::TessControl: + return "TESS_CONTROL"; + + case ShaderType::TessEvaluation: + return "TESS_EVALUATION"; + + default: + UNREACHABLE(); + return ""; + } +} + +class [[nodiscard]] ScopedExit final : angle::NonCopyable +{ + public: + ScopedExit(std::function exit) : mExit(exit) {} + ~ScopedExit() { mExit(); } + + private: + std::function mExit; +}; + +struct Shader::CompilingState +{ + std::shared_ptr compileEvent; + ShCompilerInstance shCompilerInstance; + egl::BlobCache::Key shaderHash; +}; + +ShaderState::ShaderState(ShaderType shaderType) + : mLabel(), + mShaderType(shaderType), + mShaderVersion(100), + mNumViews(-1), + mGeometryShaderInvocations(1), + mCompileStatus(CompileStatus::NOT_COMPILED) +{ + mLocalSize.fill(-1); +} + +ShaderState::~ShaderState() {} + +Shader::Shader(ShaderProgramManager *manager, + rx::GLImplFactory *implFactory, + const gl::Limitations &rendererLimitations, + ShaderType type, + ShaderProgramID handle) + : mState(type), + mImplementation(implFactory->createShader(mState)), + mRendererLimitations(rendererLimitations), + mHandle(handle), + mType(type), + mRefCount(0), + mDeleteStatus(false), + mResourceManager(manager), + mCurrentMaxComputeWorkGroupInvocations(0u) +{ + ASSERT(mImplementation); +} + +void Shader::onDestroy(const gl::Context *context) +{ + resolveCompile(context); + mImplementation->destroy(); + mBoundCompiler.set(context, nullptr); + mImplementation.reset(nullptr); + delete this; +} + +Shader::~Shader() +{ + ASSERT(!mImplementation); +} + +angle::Result Shader::setLabel(const Context *context, const std::string &label) +{ + mState.mLabel = label; + + if (mImplementation) + { + return mImplementation->onLabelUpdate(context); + } + return angle::Result::Continue; +} + +const std::string &Shader::getLabel() const +{ + return mState.mLabel; +} + +ShaderProgramID Shader::getHandle() const +{ + return mHandle; +} + +void Shader::setSource(GLsizei count, const char *const *string, const GLint *length) +{ + std::ostringstream stream; + + for (int i = 0; i < count; i++) + { + if (length == nullptr || length[i] < 0) + { + stream.write(string[i], strlen(string[i])); + } + else + { + stream.write(string[i], length[i]); + } + } + + mState.mSource = stream.str(); +} + +int Shader::getInfoLogLength(const Context *context) +{ + resolveCompile(context); + if (mInfoLog.empty()) + { + return 0; + } + + return (static_cast(mInfoLog.length()) + 1); +} + +void Shader::getInfoLog(const Context *context, GLsizei bufSize, GLsizei *length, char *infoLog) +{ + resolveCompile(context); + + int index = 0; + + if (bufSize > 0) + { + index = std::min(bufSize - 1, static_cast(mInfoLog.length())); + memcpy(infoLog, mInfoLog.c_str(), index); + + infoLog[index] = '\0'; + } + + if (length) + { + *length = index; + } +} + +int Shader::getSourceLength() const +{ + return mState.mSource.empty() ? 0 : (static_cast(mState.mSource.length()) + 1); +} + +int Shader::getTranslatedSourceLength(const Context *context) +{ + resolveCompile(context); + + if (mState.mTranslatedSource.empty()) + { + return 0; + } + + return (static_cast(mState.mTranslatedSource.length()) + 1); +} + +int Shader::getTranslatedSourceWithDebugInfoLength(const Context *context) +{ + resolveCompile(context); + + const std::string &debugInfo = mImplementation->getDebugInfo(); + if (debugInfo.empty()) + { + return 0; + } + + return (static_cast(debugInfo.length()) + 1); +} + +// static +void Shader::GetSourceImpl(const std::string &source, + GLsizei bufSize, + GLsizei *length, + char *buffer) +{ + int index = 0; + + if (bufSize > 0) + { + index = std::min(bufSize - 1, static_cast(source.length())); + memcpy(buffer, source.c_str(), index); + + buffer[index] = '\0'; + } + + if (length) + { + *length = index; + } +} + +void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer) const +{ + GetSourceImpl(mState.mSource, bufSize, length, buffer); +} + +void Shader::getTranslatedSource(const Context *context, + GLsizei bufSize, + GLsizei *length, + char *buffer) +{ + GetSourceImpl(getTranslatedSource(context), bufSize, length, buffer); +} + +const std::string &Shader::getTranslatedSource(const Context *context) +{ + resolveCompile(context); + return mState.mTranslatedSource; +} + +const sh::BinaryBlob &Shader::getCompiledBinary(const Context *context) +{ + resolveCompile(context); + return mState.mCompiledBinary; +} + +void Shader::getTranslatedSourceWithDebugInfo(const Context *context, + GLsizei bufSize, + GLsizei *length, + char *buffer) +{ + resolveCompile(context); + const std::string &debugInfo = mImplementation->getDebugInfo(); + GetSourceImpl(debugInfo, bufSize, length, buffer); +} + +void Shader::compile(const Context *context) +{ + resolveCompile(context); + + mState.mTranslatedSource.clear(); + mState.mCompiledBinary.clear(); + mInfoLog.clear(); + mState.mShaderVersion = 100; + mState.mInputVaryings.clear(); + mState.mOutputVaryings.clear(); + mState.mUniforms.clear(); + mState.mUniformBlocks.clear(); + mState.mShaderStorageBlocks.clear(); + mState.mActiveAttributes.clear(); + mState.mActiveOutputVariables.clear(); + mState.mNumViews = -1; + mState.mGeometryShaderInputPrimitiveType.reset(); + mState.mGeometryShaderOutputPrimitiveType.reset(); + mState.mGeometryShaderMaxVertices.reset(); + mState.mGeometryShaderInvocations = 1; + mState.mTessControlShaderVertices = 0; + mState.mTessGenMode = 0; + mState.mTessGenSpacing = 0; + mState.mTessGenVertexOrder = 0; + mState.mTessGenPointMode = 0; + mState.mAdvancedBlendEquations.reset(); + mState.mHasDiscard = false; + mState.mEnablesPerSampleShading = false; + mState.mSpecConstUsageBits.reset(); + + mCurrentMaxComputeWorkGroupInvocations = + static_cast(context->getCaps().maxComputeWorkGroupInvocations); + mMaxComputeSharedMemory = context->getCaps().maxComputeSharedMemorySize; + + ShCompileOptions options = {}; + options.objectCode = true; + options.variables = true; + options.emulateGLDrawID = true; + + // Add default options to WebGL shaders to prevent unexpected behavior during + // compilation. + if (context->isWebGL()) + { + options.initGLPosition = true; + options.limitCallStackDepth = true; + options.limitExpressionComplexity = true; + options.enforcePackingRestrictions = true; + options.initSharedVariables = true; + } + else + { + // Per https://github.com/KhronosGroup/WebGL/pull/3278 gl_BaseVertex/gl_BaseInstance are + // removed from WebGL + options.emulateGLBaseVertexBaseInstance = true; + } + + // Some targets (e.g. D3D11 Feature Level 9_3 and below) do not support non-constant loop + // indexes in fragment shaders. Shader compilation will fail. To provide a better error + // message we can instruct the compiler to pre-validate. + if (mRendererLimitations.shadersRequireIndexedLoopValidation) + { + options.validateLoopIndexing = true; + } + + if (context->getFrontendFeatures().scalarizeVecAndMatConstructorArgs.enabled) + { + options.scalarizeVecAndMatConstructorArgs = true; + } + + if (context->getFrontendFeatures().forceInitShaderVariables.enabled) + { + options.initOutputVariables = true; + options.initializeUninitializedLocals = true; + } + + mBoundCompiler.set(context, context->getCompiler()); + + ASSERT(mBoundCompiler.get()); + ShCompilerInstance compilerInstance = mBoundCompiler->getInstance(mState.mShaderType); + ShHandle compilerHandle = compilerInstance.getHandle(); + ASSERT(compilerHandle); + mCompilerResourcesString = compilerInstance.getBuiltinResourcesString(); + + // Find a shader in Blob Cache + egl::BlobCache::Key shaderHash = {0}; + MemoryShaderCache *shaderCache = context->getMemoryShaderCache(); + if (shaderCache) + { + angle::Result cacheResult = + shaderCache->getShader(context, this, options, compilerInstance, &shaderHash); + + if (cacheResult == angle::Result::Continue) + { + compilerInstance.destroy(); + return; + } + } + + // Cache load failed, fall through normal compiling. + mState.mCompileStatus = CompileStatus::COMPILE_REQUESTED; + mCompilingState.reset(new CompilingState()); + mCompilingState->shCompilerInstance = std::move(compilerInstance); + mCompilingState->shaderHash = shaderHash; + mCompilingState->compileEvent = + mImplementation->compile(context, &(mCompilingState->shCompilerInstance), &options); +} + +void Shader::resolveCompile(const Context *context) +{ + if (!mState.compilePending()) + { + return; + } + + ASSERT(mCompilingState.get()); + + mCompilingState->compileEvent->wait(); + + mInfoLog += mCompilingState->compileEvent->getInfoLog(); + + ScopedExit exit([this]() { + mBoundCompiler->putInstance(std::move(mCompilingState->shCompilerInstance)); + mCompilingState->compileEvent.reset(); + mCompilingState.reset(); + }); + + ShHandle compilerHandle = mCompilingState->shCompilerInstance.getHandle(); + if (!mCompilingState->compileEvent->getResult()) + { + mInfoLog += sh::GetInfoLog(compilerHandle); + INFO() << std::endl << mInfoLog; + mState.mCompileStatus = CompileStatus::NOT_COMPILED; + return; + } + + const ShShaderOutput outputType = mCompilingState->shCompilerInstance.getShaderOutputType(); + const bool isBinaryOutput = + outputType == SH_SPIRV_VULKAN_OUTPUT || outputType == SH_SPIRV_METAL_OUTPUT; + + if (isBinaryOutput) + { + mState.mCompiledBinary = sh::GetObjectBinaryBlob(compilerHandle); + } + else + { + mState.mTranslatedSource = sh::GetObjectCode(compilerHandle); + +#if !defined(NDEBUG) + // Prefix translated shader with commented out un-translated shader. + // Useful in diagnostics tools which capture the shader source. + std::ostringstream shaderStream; + shaderStream << "// GLSL\n"; + shaderStream << "//\n"; + + std::istringstream inputSourceStream(mState.mSource); + std::string line; + while (std::getline(inputSourceStream, line)) + { + // Remove null characters from the source line + line.erase(std::remove(line.begin(), line.end(), '\0'), line.end()); + + shaderStream << "// " << line; + + // glslang complains if a comment ends with backslash + if (!line.empty() && line.back() == '\\') + { + shaderStream << "\\"; + } + + shaderStream << std::endl; + } + shaderStream << "\n\n"; + shaderStream << mState.mTranslatedSource; + mState.mTranslatedSource = shaderStream.str(); +#endif // !defined(NDEBUG) + } + + // Gather the shader information + mState.mShaderVersion = sh::GetShaderVersion(compilerHandle); + + mState.mUniforms = GetShaderVariables(sh::GetUniforms(compilerHandle)); + mState.mUniformBlocks = GetShaderVariables(sh::GetUniformBlocks(compilerHandle)); + mState.mShaderStorageBlocks = GetShaderVariables(sh::GetShaderStorageBlocks(compilerHandle)); + mState.mSpecConstUsageBits = + rx::SpecConstUsageBits(sh::GetShaderSpecConstUsageBits(compilerHandle)); + + switch (mState.mShaderType) + { + case ShaderType::Compute: + { + mState.mAllAttributes = GetShaderVariables(sh::GetAttributes(compilerHandle)); + mState.mActiveAttributes = GetActiveShaderVariables(&mState.mAllAttributes); + mState.mLocalSize = sh::GetComputeShaderLocalGroupSize(compilerHandle); + if (mState.mLocalSize.isDeclared()) + { + angle::CheckedNumeric checked_local_size_product(mState.mLocalSize[0]); + checked_local_size_product *= mState.mLocalSize[1]; + checked_local_size_product *= mState.mLocalSize[2]; + + if (!checked_local_size_product.IsValid()) + { + WARN() << std::endl + << "Integer overflow when computing the product of local_size_x, " + << "local_size_y and local_size_z."; + mState.mCompileStatus = CompileStatus::NOT_COMPILED; + return; + } + if (checked_local_size_product.ValueOrDie() > + mCurrentMaxComputeWorkGroupInvocations) + { + WARN() << std::endl + << "The total number of invocations within a work group exceeds " + << "MAX_COMPUTE_WORK_GROUP_INVOCATIONS."; + mState.mCompileStatus = CompileStatus::NOT_COMPILED; + return; + } + } + + unsigned int sharedMemSize = sh::GetShaderSharedMemorySize(compilerHandle); + if (sharedMemSize > mMaxComputeSharedMemory) + { + WARN() << std::endl << "Exceeded maximum shared memory size"; + mState.mCompileStatus = CompileStatus::NOT_COMPILED; + return; + } + break; + } + case ShaderType::Vertex: + { + mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle)); + mState.mAllAttributes = GetShaderVariables(sh::GetAttributes(compilerHandle)); + mState.mActiveAttributes = GetActiveShaderVariables(&mState.mAllAttributes); + mState.mNumViews = sh::GetVertexShaderNumViews(compilerHandle); + break; + } + case ShaderType::Fragment: + { + mState.mAllAttributes = GetShaderVariables(sh::GetAttributes(compilerHandle)); + mState.mActiveAttributes = GetActiveShaderVariables(&mState.mAllAttributes); + mState.mInputVaryings = GetShaderVariables(sh::GetInputVaryings(compilerHandle)); + // TODO(jmadill): Figure out why we only sort in the FS, and if we need to. + std::sort(mState.mInputVaryings.begin(), mState.mInputVaryings.end(), CompareShaderVar); + mState.mActiveOutputVariables = + GetActiveShaderVariables(sh::GetOutputVariables(compilerHandle)); + mState.mHasDiscard = sh::HasDiscardInFragmentShader(compilerHandle); + mState.mEnablesPerSampleShading = sh::EnablesPerSampleShading(compilerHandle); + mState.mAdvancedBlendEquations = + BlendEquationBitSet(sh::GetAdvancedBlendEquations(compilerHandle)); + break; + } + case ShaderType::Geometry: + { + mState.mInputVaryings = GetShaderVariables(sh::GetInputVaryings(compilerHandle)); + mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle)); + + if (sh::HasValidGeometryShaderInputPrimitiveType(compilerHandle)) + { + mState.mGeometryShaderInputPrimitiveType = FromGLenum( + sh::GetGeometryShaderInputPrimitiveType(compilerHandle)); + } + if (sh::HasValidGeometryShaderOutputPrimitiveType(compilerHandle)) + { + mState.mGeometryShaderOutputPrimitiveType = FromGLenum( + sh::GetGeometryShaderOutputPrimitiveType(compilerHandle)); + } + if (sh::HasValidGeometryShaderMaxVertices(compilerHandle)) + { + mState.mGeometryShaderMaxVertices = + sh::GetGeometryShaderMaxVertices(compilerHandle); + } + mState.mGeometryShaderInvocations = sh::GetGeometryShaderInvocations(compilerHandle); + break; + } + case ShaderType::TessControl: + { + mState.mInputVaryings = GetShaderVariables(sh::GetInputVaryings(compilerHandle)); + mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle)); + mState.mTessControlShaderVertices = sh::GetTessControlShaderVertices(compilerHandle); + break; + } + case ShaderType::TessEvaluation: + { + mState.mInputVaryings = GetShaderVariables(sh::GetInputVaryings(compilerHandle)); + mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle)); + if (sh::HasValidTessGenMode(compilerHandle)) + { + mState.mTessGenMode = sh::GetTessGenMode(compilerHandle); + } + if (sh::HasValidTessGenSpacing(compilerHandle)) + { + mState.mTessGenSpacing = sh::GetTessGenSpacing(compilerHandle); + } + if (sh::HasValidTessGenVertexOrder(compilerHandle)) + { + mState.mTessGenVertexOrder = sh::GetTessGenVertexOrder(compilerHandle); + } + if (sh::HasValidTessGenPointMode(compilerHandle)) + { + mState.mTessGenPointMode = sh::GetTessGenPointMode(compilerHandle); + } + break; + } + + default: + UNREACHABLE(); + } + + ASSERT(!mState.mTranslatedSource.empty() || !mState.mCompiledBinary.empty()); + + bool success = mCompilingState->compileEvent->postTranslate(&mInfoLog); + mState.mCompileStatus = success ? CompileStatus::COMPILED : CompileStatus::NOT_COMPILED; + + MemoryShaderCache *shaderCache = context->getMemoryShaderCache(); + if (success && shaderCache) + { + // Save to the shader cache. + if (shaderCache->putShader(context, mCompilingState->shaderHash, this) != + angle::Result::Continue) + { + ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_LOW, + "Failed to save compiled shader to memory shader cache."); + } + } +} + +void Shader::addRef() +{ + mRefCount++; +} + +void Shader::release(const Context *context) +{ + mRefCount--; + + if (mRefCount == 0 && mDeleteStatus) + { + mResourceManager->deleteShader(context, mHandle); + } +} + +unsigned int Shader::getRefCount() const +{ + return mRefCount; +} + +bool Shader::isFlaggedForDeletion() const +{ + return mDeleteStatus; +} + +void Shader::flagForDeletion() +{ + mDeleteStatus = true; +} + +bool Shader::isCompiled(const Context *context) +{ + resolveCompile(context); + return mState.mCompileStatus == CompileStatus::COMPILED; +} + +bool Shader::isCompleted() +{ + return (!mState.compilePending() || mCompilingState->compileEvent->isReady()); +} + +int Shader::getShaderVersion(const Context *context) +{ + resolveCompile(context); + return mState.mShaderVersion; +} + +const std::vector &Shader::getInputVaryings(const Context *context) +{ + resolveCompile(context); + return mState.getInputVaryings(); +} + +const std::vector &Shader::getOutputVaryings(const Context *context) +{ + resolveCompile(context); + return mState.getOutputVaryings(); +} + +const std::vector &Shader::getUniforms(const Context *context) +{ + resolveCompile(context); + return mState.getUniforms(); +} + +const std::vector &Shader::getUniformBlocks(const Context *context) +{ + resolveCompile(context); + return mState.getUniformBlocks(); +} + +const std::vector &Shader::getShaderStorageBlocks(const Context *context) +{ + resolveCompile(context); + return mState.getShaderStorageBlocks(); +} + +const std::vector &Shader::getActiveAttributes(const Context *context) +{ + resolveCompile(context); + return mState.getActiveAttributes(); +} + +const std::vector &Shader::getAllAttributes(const Context *context) +{ + resolveCompile(context); + return mState.getAllAttributes(); +} + +const std::vector &Shader::getActiveOutputVariables(const Context *context) +{ + resolveCompile(context); + return mState.getActiveOutputVariables(); +} + +std::string Shader::getTransformFeedbackVaryingMappedName(const Context *context, + const std::string &tfVaryingName) +{ + ASSERT(mState.getShaderType() != ShaderType::Fragment && + mState.getShaderType() != ShaderType::Compute); + const auto &varyings = getOutputVaryings(context); + auto bracketPos = tfVaryingName.find("["); + if (bracketPos != std::string::npos) + { + auto tfVaryingBaseName = tfVaryingName.substr(0, bracketPos); + for (const auto &varying : varyings) + { + if (varying.name == tfVaryingBaseName) + { + std::string mappedNameWithArrayIndex = + varying.mappedName + tfVaryingName.substr(bracketPos); + return mappedNameWithArrayIndex; + } + } + } + else + { + for (const auto &varying : varyings) + { + if (varying.name == tfVaryingName) + { + return varying.mappedName; + } + else if (varying.isStruct()) + { + GLuint fieldIndex = 0; + const auto *field = varying.findField(tfVaryingName, &fieldIndex); + if (field == nullptr) + { + continue; + } + ASSERT(field != nullptr && !field->isStruct() && + (!field->isArray() || varying.isShaderIOBlock)); + std::string mappedName; + // If it's an I/O block without an instance name, don't include the block name. + if (!varying.isShaderIOBlock || !varying.name.empty()) + { + mappedName = varying.isShaderIOBlock ? varying.mappedStructOrBlockName + : varying.mappedName; + mappedName += '.'; + } + return mappedName + field->mappedName; + } + } + } + UNREACHABLE(); + return std::string(); +} + +const sh::WorkGroupSize &Shader::getWorkGroupSize(const Context *context) +{ + resolveCompile(context); + return mState.mLocalSize; +} + +int Shader::getNumViews(const Context *context) +{ + resolveCompile(context); + return mState.mNumViews; +} + +Optional Shader::getGeometryShaderInputPrimitiveType(const Context *context) +{ + resolveCompile(context); + return mState.mGeometryShaderInputPrimitiveType; +} + +Optional Shader::getGeometryShaderOutputPrimitiveType(const Context *context) +{ + resolveCompile(context); + return mState.mGeometryShaderOutputPrimitiveType; +} + +int Shader::getGeometryShaderInvocations(const Context *context) +{ + resolveCompile(context); + return mState.mGeometryShaderInvocations; +} + +Optional Shader::getGeometryShaderMaxVertices(const Context *context) +{ + resolveCompile(context); + return mState.mGeometryShaderMaxVertices; +} + +int Shader::getTessControlShaderVertices(const Context *context) +{ + resolveCompile(context); + return mState.mTessControlShaderVertices; +} + +GLenum Shader::getTessGenMode(const Context *context) +{ + resolveCompile(context); + return mState.mTessGenMode; +} + +GLenum Shader::getTessGenSpacing(const Context *context) +{ + resolveCompile(context); + return mState.mTessGenSpacing; +} + +GLenum Shader::getTessGenVertexOrder(const Context *context) +{ + resolveCompile(context); + return mState.mTessGenVertexOrder; +} + +GLenum Shader::getTessGenPointMode(const Context *context) +{ + resolveCompile(context); + return mState.mTessGenPointMode; +} + +const std::string &Shader::getCompilerResourcesString() const +{ + return mCompilerResourcesString; +} + +angle::Result Shader::serialize(const Context *context, angle::MemoryBuffer *binaryOut) const +{ + BinaryOutputStream stream; + + stream.writeInt(kShaderCacheIdentifier); + stream.writeString(mState.mLabel); + stream.writeInt(mState.mShaderVersion); + stream.writeString(mCompilerResourcesString); + + stream.writeInt(mState.mUniforms.size()); + for (const sh::ShaderVariable &shaderVariable : mState.mUniforms) + { + WriteShaderVar(&stream, shaderVariable); + } + + stream.writeInt(mState.mUniformBlocks.size()); + for (const sh::InterfaceBlock &interfaceBlock : mState.mUniformBlocks) + { + WriteInterfaceBlock(&stream, interfaceBlock); + } + + stream.writeInt(mState.mShaderStorageBlocks.size()); + for (const sh::InterfaceBlock &interfaceBlock : mState.mShaderStorageBlocks) + { + WriteInterfaceBlock(&stream, interfaceBlock); + } + + stream.writeInt(mState.mSpecConstUsageBits.bits()); + + switch (mType) + { + case ShaderType::Compute: + { + stream.writeInt(mState.mAllAttributes.size()); + for (const sh::ShaderVariable &shaderVariable : mState.mAllAttributes) + { + WriteShaderVar(&stream, shaderVariable); + } + stream.writeInt(mState.mActiveAttributes.size()); + for (const sh::ShaderVariable &shaderVariable : mState.mActiveAttributes) + { + WriteShaderVar(&stream, shaderVariable); + } + stream.writeInt(mState.mLocalSize[0]); + stream.writeInt(mState.mLocalSize[1]); + stream.writeInt(mState.mLocalSize[2]); + break; + } + + case ShaderType::Vertex: + { + stream.writeInt(mState.mOutputVaryings.size()); + for (const sh::ShaderVariable &shaderVariable : mState.mOutputVaryings) + { + WriteShaderVar(&stream, shaderVariable); + } + stream.writeInt(mState.mAllAttributes.size()); + for (const sh::ShaderVariable &shaderVariable : mState.mAllAttributes) + { + WriteShaderVar(&stream, shaderVariable); + } + stream.writeInt(mState.mActiveAttributes.size()); + for (const sh::ShaderVariable &shaderVariable : mState.mActiveAttributes) + { + WriteShaderVar(&stream, shaderVariable); + } + stream.writeInt(mState.mNumViews); + break; + } + case ShaderType::Fragment: + { + stream.writeInt(mState.mInputVaryings.size()); + for (const sh::ShaderVariable &shaderVariable : mState.mInputVaryings) + { + WriteShaderVar(&stream, shaderVariable); + } + stream.writeInt(mState.mActiveOutputVariables.size()); + for (const sh::ShaderVariable &shaderVariable : mState.mActiveOutputVariables) + { + WriteShaderVar(&stream, shaderVariable); + } + stream.writeBool(mState.mEnablesPerSampleShading); + stream.writeInt(mState.mAdvancedBlendEquations.bits()); + break; + } + case ShaderType::Geometry: + { + bool valid; + + stream.writeInt(mState.mInputVaryings.size()); + for (const sh::ShaderVariable &shaderVariable : mState.mInputVaryings) + { + WriteShaderVar(&stream, shaderVariable); + } + stream.writeInt(mState.mOutputVaryings.size()); + for (const sh::ShaderVariable &shaderVariable : mState.mOutputVaryings) + { + WriteShaderVar(&stream, shaderVariable); + } + + valid = (bool)mState.mGeometryShaderInputPrimitiveType.valid(); + stream.writeBool(valid); + if (valid) + { + unsigned char value = + (unsigned char)mState.mGeometryShaderInputPrimitiveType.value(); + stream.writeBytes(&value, 1); + } + valid = (bool)mState.mGeometryShaderOutputPrimitiveType.valid(); + stream.writeBool(valid); + if (valid) + { + unsigned char value = + (unsigned char)mState.mGeometryShaderOutputPrimitiveType.value(); + stream.writeBytes(&value, 1); + } + valid = mState.mGeometryShaderMaxVertices.valid(); + stream.writeBool(valid); + if (valid) + { + int value = (int)mState.mGeometryShaderMaxVertices.value(); + stream.writeInt(value); + } + + stream.writeInt(mState.mGeometryShaderInvocations); + break; + } + case ShaderType::TessControl: + { + stream.writeInt(mState.mInputVaryings.size()); + for (const sh::ShaderVariable &shaderVariable : mState.mInputVaryings) + { + WriteShaderVar(&stream, shaderVariable); + } + stream.writeInt(mState.mOutputVaryings.size()); + for (const sh::ShaderVariable &shaderVariable : mState.mOutputVaryings) + { + WriteShaderVar(&stream, shaderVariable); + } + stream.writeInt(mState.mTessControlShaderVertices); + break; + } + case ShaderType::TessEvaluation: + { + unsigned int value; + + stream.writeInt(mState.mInputVaryings.size()); + for (const sh::ShaderVariable &shaderVariable : mState.mInputVaryings) + { + WriteShaderVar(&stream, shaderVariable); + } + stream.writeInt(mState.mOutputVaryings.size()); + for (const sh::ShaderVariable &shaderVariable : mState.mOutputVaryings) + { + WriteShaderVar(&stream, shaderVariable); + } + + value = (unsigned int)(mState.mTessGenMode); + stream.writeInt(value); + + value = (unsigned int)mState.mTessGenSpacing; + stream.writeInt(value); + + value = (unsigned int)mState.mTessGenVertexOrder; + stream.writeInt(value); + + value = (unsigned int)mState.mTessGenPointMode; + stream.writeInt(value); + break; + } + default: + UNREACHABLE(); + } + + stream.writeIntVector(mState.mCompiledBinary); + stream.writeEnum(mState.mCompileStatus); + + ASSERT(binaryOut); + if (!binaryOut->resize(stream.length())) + { + std::stringstream sstream; + sstream << "Failed to allocate enough memory to serialize a shader. (" << stream.length() + << " bytes )"; + ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_LOW, + sstream.str().c_str()); + return angle::Result::Incomplete; + } + + memcpy(binaryOut->data(), stream.data(), stream.length()); + + return angle::Result::Continue; +} + +angle::Result Shader::deserialize(const Context *context, BinaryInputStream &stream) +{ + size_t size; + + if (stream.readInt() != kShaderCacheIdentifier) + { + return angle::Result::Stop; + } + + stream.readString(&mState.mLabel); + stream.readInt(&mState.mShaderVersion); + stream.readString(&mCompilerResourcesString); + + size = stream.readInt(); + mState.mUniforms.resize(size); + for (sh::ShaderVariable &shaderVariable : mState.mUniforms) + { + LoadShaderVar(&stream, &shaderVariable); + } + + size = stream.readInt(); + mState.mUniformBlocks.resize(size); + for (sh::InterfaceBlock &interfaceBlock : mState.mUniformBlocks) + { + LoadInterfaceBlock(&stream, interfaceBlock); + } + + size = stream.readInt(); + mState.mShaderStorageBlocks.resize(size); + for (sh::InterfaceBlock &interfaceBlock : mState.mShaderStorageBlocks) + { + LoadInterfaceBlock(&stream, interfaceBlock); + } + + mState.mSpecConstUsageBits = rx::SpecConstUsageBits(stream.readInt()); + + switch (mType) + { + case ShaderType::Compute: + { + size = stream.readInt(); + mState.mAllAttributes.resize(size); + for (sh::ShaderVariable &shaderVariable : mState.mAllAttributes) + { + LoadShaderVar(&stream, &shaderVariable); + } + size = stream.readInt(); + mState.mActiveAttributes.resize(size); + for (sh::ShaderVariable &shaderVariable : mState.mActiveAttributes) + { + LoadShaderVar(&stream, &shaderVariable); + } + stream.readInt(&mState.mLocalSize[0]); + stream.readInt(&mState.mLocalSize[1]); + stream.readInt(&mState.mLocalSize[2]); + break; + } + case ShaderType::Vertex: + { + size = stream.readInt(); + mState.mOutputVaryings.resize(size); + for (sh::ShaderVariable &shaderVariable : mState.mOutputVaryings) + { + LoadShaderVar(&stream, &shaderVariable); + } + size = stream.readInt(); + mState.mAllAttributes.resize(size); + for (sh::ShaderVariable &shaderVariable : mState.mAllAttributes) + { + LoadShaderVar(&stream, &shaderVariable); + } + size = stream.readInt(); + mState.mActiveAttributes.resize(size); + for (sh::ShaderVariable &shaderVariable : mState.mActiveAttributes) + { + LoadShaderVar(&stream, &shaderVariable); + } + stream.readInt(&mState.mNumViews); + break; + } + case ShaderType::Fragment: + { + size = stream.readInt(); + mState.mInputVaryings.resize(size); + for (sh::ShaderVariable &shaderVariable : mState.mInputVaryings) + { + LoadShaderVar(&stream, &shaderVariable); + } + size = stream.readInt(); + mState.mActiveOutputVariables.resize(size); + for (sh::ShaderVariable &shaderVariable : mState.mActiveOutputVariables) + { + LoadShaderVar(&stream, &shaderVariable); + } + stream.readBool(&mState.mEnablesPerSampleShading); + int advancedBlendEquationBits; + stream.readInt(&advancedBlendEquationBits); + mState.mAdvancedBlendEquations = BlendEquationBitSet(advancedBlendEquationBits); + break; + } + case ShaderType::Geometry: + { + bool valid; + + size = stream.readInt(); + mState.mInputVaryings.resize(size); + for (sh::ShaderVariable &shaderVariable : mState.mInputVaryings) + { + LoadShaderVar(&stream, &shaderVariable); + } + size = stream.readInt(); + mState.mOutputVaryings.resize(size); + for (sh::ShaderVariable &shaderVariable : mState.mOutputVaryings) + { + LoadShaderVar(&stream, &shaderVariable); + } + + stream.readBool(&valid); + if (valid) + { + unsigned char value; + stream.readBytes(&value, 1); + mState.mGeometryShaderInputPrimitiveType = static_cast(value); + } + else + { + mState.mGeometryShaderInputPrimitiveType.reset(); + } + + stream.readBool(&valid); + if (valid) + { + unsigned char value; + stream.readBytes(&value, 1); + mState.mGeometryShaderOutputPrimitiveType = static_cast(value); + } + else + { + mState.mGeometryShaderOutputPrimitiveType.reset(); + } + + stream.readBool(&valid); + if (valid) + { + int value; + stream.readInt(&value); + mState.mGeometryShaderMaxVertices = static_cast(value); + } + else + { + mState.mGeometryShaderMaxVertices.reset(); + } + + stream.readInt(&mState.mGeometryShaderInvocations); + break; + } + case ShaderType::TessControl: + { + size = stream.readInt(); + mState.mInputVaryings.resize(size); + for (sh::ShaderVariable &shaderVariable : mState.mInputVaryings) + { + LoadShaderVar(&stream, &shaderVariable); + } + size = stream.readInt(); + mState.mOutputVaryings.resize(size); + for (sh::ShaderVariable &shaderVariable : mState.mOutputVaryings) + { + LoadShaderVar(&stream, &shaderVariable); + } + stream.readInt(&mState.mTessControlShaderVertices); + break; + } + case ShaderType::TessEvaluation: + { + unsigned int value; + + size = stream.readInt(); + mState.mInputVaryings.resize(size); + for (sh::ShaderVariable &shaderVariable : mState.mInputVaryings) + { + LoadShaderVar(&stream, &shaderVariable); + } + size = stream.readInt(); + mState.mOutputVaryings.resize(size); + for (sh::ShaderVariable &shaderVariable : mState.mOutputVaryings) + { + LoadShaderVar(&stream, &shaderVariable); + } + + stream.readInt(&value); + mState.mTessGenMode = (GLenum)value; + + stream.readInt(&value); + mState.mTessGenSpacing = (GLenum)value; + + stream.readInt(&value); + mState.mTessGenVertexOrder = (GLenum)value; + + stream.readInt(&value); + mState.mTessGenPointMode = (GLenum)value; + break; + } + default: + UNREACHABLE(); + } + + stream.readIntVector(&mState.mCompiledBinary); + mState.mCompileStatus = stream.readEnum(); + + return angle::Result::Continue; +} + +angle::Result Shader::loadBinary(const Context *context, const void *binary, GLsizei length) +{ + BinaryInputStream stream(binary, length); + ANGLE_TRY(deserialize(context, stream)); + + return angle::Result::Continue; +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/Shader.h b/gfx/angle/checkout/src/libANGLE/Shader.h new file mode 100644 index 0000000000..59b1f3cc3e --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Shader.h @@ -0,0 +1,305 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Shader.h: Defines the abstract gl::Shader class and its concrete derived +// classes VertexShader and FragmentShader. Implements GL shader objects and +// related functionality. [OpenGL ES 2.0.24] section 2.10 page 24 and section +// 3.8 page 84. + +#ifndef LIBANGLE_SHADER_H_ +#define LIBANGLE_SHADER_H_ + +#include +#include +#include +#include + +#include +#include "angle_gl.h" + +#include "common/MemoryBuffer.h" +#include "common/Optional.h" +#include "common/angleutils.h" +#include "libANGLE/BinaryStream.h" +#include "libANGLE/Caps.h" +#include "libANGLE/Compiler.h" +#include "libANGLE/Debug.h" +#include "libANGLE/angletypes.h" + +namespace rx +{ +class GLImplFactory; +class ShaderImpl; +class ShaderSh; +class WaitableCompileEvent; +} // namespace rx + +namespace angle +{ +class WaitableEvent; +class WorkerThreadPool; +} // namespace angle + +namespace gl +{ +class CompileTask; +class Context; +class ShaderProgramManager; +class State; +class BinaryInputStream; +class BinaryOutputStream; + +// We defer the compile until link time, or until properties are queried. +enum class CompileStatus +{ + NOT_COMPILED, + COMPILE_REQUESTED, + COMPILED, +}; + +class ShaderState final : angle::NonCopyable +{ + public: + ShaderState(ShaderType shaderType); + ~ShaderState(); + + const std::string &getLabel() const { return mLabel; } + + const std::string &getSource() const { return mSource; } + bool isCompiledToBinary() const { return !mCompiledBinary.empty(); } + const std::string &getTranslatedSource() const { return mTranslatedSource; } + const sh::BinaryBlob &getCompiledBinary() const { return mCompiledBinary; } + + ShaderType getShaderType() const { return mShaderType; } + int getShaderVersion() const { return mShaderVersion; } + + const std::vector &getInputVaryings() const { return mInputVaryings; } + const std::vector &getOutputVaryings() const { return mOutputVaryings; } + const std::vector &getUniforms() const { return mUniforms; } + const std::vector &getUniformBlocks() const { return mUniformBlocks; } + const std::vector &getShaderStorageBlocks() const + { + return mShaderStorageBlocks; + } + const std::vector &getActiveAttributes() const { return mActiveAttributes; } + const std::vector &getAllAttributes() const { return mAllAttributes; } + const std::vector &getActiveOutputVariables() const + { + return mActiveOutputVariables; + } + + bool compilePending() const { return mCompileStatus == CompileStatus::COMPILE_REQUESTED; } + + const sh::WorkGroupSize &getLocalSize() const { return mLocalSize; } + + bool hasDiscard() const { return mHasDiscard; } + bool enablesPerSampleShading() const { return mEnablesPerSampleShading; } + rx::SpecConstUsageBits getSpecConstUsageBits() const { return mSpecConstUsageBits; } + + int getNumViews() const { return mNumViews; } + + Optional getGeometryShaderInputPrimitiveType() const + { + return mGeometryShaderInputPrimitiveType; + } + + Optional getGeometryShaderOutputPrimitiveType() const + { + return mGeometryShaderOutputPrimitiveType; + } + + Optional geoGeometryShaderMaxVertices() const { return mGeometryShaderMaxVertices; } + + Optional getGeometryShaderInvocations() const { return mGeometryShaderInvocations; } + + CompileStatus getCompileStatus() const { return mCompileStatus; } + + private: + friend class Shader; + + std::string mLabel; + + ShaderType mShaderType; + int mShaderVersion; + std::string mTranslatedSource; + sh::BinaryBlob mCompiledBinary; + std::string mSource; + + sh::WorkGroupSize mLocalSize; + + std::vector mInputVaryings; + std::vector mOutputVaryings; + std::vector mUniforms; + std::vector mUniformBlocks; + std::vector mShaderStorageBlocks; + std::vector mAllAttributes; + std::vector mActiveAttributes; + std::vector mActiveOutputVariables; + + bool mHasDiscard; + bool mEnablesPerSampleShading; + BlendEquationBitSet mAdvancedBlendEquations; + rx::SpecConstUsageBits mSpecConstUsageBits; + + // ANGLE_multiview. + int mNumViews; + + // Geometry Shader. + Optional mGeometryShaderInputPrimitiveType; + Optional mGeometryShaderOutputPrimitiveType; + Optional mGeometryShaderMaxVertices; + int mGeometryShaderInvocations; + + // Tessellation Shader + int mTessControlShaderVertices; + GLenum mTessGenMode; + GLenum mTessGenSpacing; + GLenum mTessGenVertexOrder; + GLenum mTessGenPointMode; + + // Indicates if this shader has been successfully compiled + CompileStatus mCompileStatus; +}; + +class Shader final : angle::NonCopyable, public LabeledObject +{ + public: + Shader(ShaderProgramManager *manager, + rx::GLImplFactory *implFactory, + const gl::Limitations &rendererLimitations, + ShaderType type, + ShaderProgramID handle); + + void onDestroy(const Context *context); + + angle::Result setLabel(const Context *context, const std::string &label) override; + const std::string &getLabel() const override; + + ShaderType getType() const { return mType; } + ShaderProgramID getHandle() const; + + rx::ShaderImpl *getImplementation() const { return mImplementation.get(); } + + void setSource(GLsizei count, const char *const *string, const GLint *length); + int getInfoLogLength(const Context *context); + void getInfoLog(const Context *context, GLsizei bufSize, GLsizei *length, char *infoLog); + std::string getInfoLogString() const { return mInfoLog; } + int getSourceLength() const; + const std::string &getSourceString() const { return mState.getSource(); } + void getSource(GLsizei bufSize, GLsizei *length, char *buffer) const; + int getTranslatedSourceLength(const Context *context); + int getTranslatedSourceWithDebugInfoLength(const Context *context); + const std::string &getTranslatedSource(const Context *context); + void getTranslatedSource(const Context *context, + GLsizei bufSize, + GLsizei *length, + char *buffer); + void getTranslatedSourceWithDebugInfo(const Context *context, + GLsizei bufSize, + GLsizei *length, + char *buffer); + const sh::BinaryBlob &getCompiledBinary(const Context *context); + + void compile(const Context *context); + bool isCompiled(const Context *context); + bool isCompleted(); + + void addRef(); + void release(const Context *context); + unsigned int getRefCount() const; + bool isFlaggedForDeletion() const; + void flagForDeletion(); + bool hasDiscard() const { return mState.mHasDiscard; } + bool enablesPerSampleShading() const { return mState.mEnablesPerSampleShading; } + BlendEquationBitSet getAdvancedBlendEquations() const { return mState.mAdvancedBlendEquations; } + rx::SpecConstUsageBits getSpecConstUsageBits() const { return mState.mSpecConstUsageBits; } + + int getShaderVersion(const Context *context); + + const std::vector &getInputVaryings(const Context *context); + const std::vector &getOutputVaryings(const Context *context); + const std::vector &getUniforms(const Context *context); + const std::vector &getUniformBlocks(const Context *context); + const std::vector &getShaderStorageBlocks(const Context *context); + const std::vector &getActiveAttributes(const Context *context); + const std::vector &getAllAttributes(const Context *context); + const std::vector &getActiveOutputVariables(const Context *context); + + // Returns mapped name of a transform feedback varying. The original name may contain array + // brackets with an index inside, which will get copied to the mapped name. The varying must be + // known to be declared in the shader. + std::string getTransformFeedbackVaryingMappedName(const Context *context, + const std::string &tfVaryingName); + + const sh::WorkGroupSize &getWorkGroupSize(const Context *context); + + int getNumViews(const Context *context); + + Optional getGeometryShaderInputPrimitiveType(const Context *context); + Optional getGeometryShaderOutputPrimitiveType(const Context *context); + int getGeometryShaderInvocations(const Context *context); + Optional getGeometryShaderMaxVertices(const Context *context); + int getTessControlShaderVertices(const Context *context); + GLenum getTessGenMode(const Context *context); + GLenum getTessGenSpacing(const Context *context); + GLenum getTessGenVertexOrder(const Context *context); + GLenum getTessGenPointMode(const Context *context); + + const std::string &getCompilerResourcesString() const; + + const ShaderState &getState() const { return mState; } + + GLuint getCurrentMaxComputeWorkGroupInvocations() const + { + return mCurrentMaxComputeWorkGroupInvocations; + } + + unsigned int getMaxComputeSharedMemory() const { return mMaxComputeSharedMemory; } + bool hasBeenDeleted() const { return mDeleteStatus; } + + // Block until compiling is finished and resolve it. + void resolveCompile(const Context *context); + + // Writes a shader's binary to the output memory buffer. + angle::Result serialize(const Context *context, angle::MemoryBuffer *binaryOut) const; + angle::Result deserialize(const Context *context, BinaryInputStream &stream); + angle::Result loadBinary(const Context *context, const void *binary, GLsizei length); + + private: + struct CompilingState; + + ~Shader() override; + static void GetSourceImpl(const std::string &source, + GLsizei bufSize, + GLsizei *length, + char *buffer); + + ShaderState mState; + std::unique_ptr mImplementation; + const gl::Limitations mRendererLimitations; + const ShaderProgramID mHandle; + const ShaderType mType; + unsigned int mRefCount; // Number of program objects this shader is attached to + bool mDeleteStatus; // Flag to indicate that the shader can be deleted when no longer in use + std::string mInfoLog; + + // We keep a reference to the translator in order to defer compiles while preserving settings. + BindingPointer mBoundCompiler; + std::unique_ptr mCompilingState; + std::string mCompilerResourcesString; + + ShaderProgramManager *mResourceManager; + + GLuint mCurrentMaxComputeWorkGroupInvocations; + unsigned int mMaxComputeSharedMemory; +}; + +bool CompareShaderVar(const sh::ShaderVariable &x, const sh::ShaderVariable &y); + +const char *GetShaderTypeString(ShaderType type); +} // namespace gl + +#endif // LIBANGLE_SHADER_H_ diff --git a/gfx/angle/checkout/src/libANGLE/SizedMRUCache.h b/gfx/angle/checkout/src/libANGLE/SizedMRUCache.h new file mode 100644 index 0000000000..b557e657ec --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/SizedMRUCache.h @@ -0,0 +1,156 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// SizedMRUCache.h: A hashing map that stores blobs of sized, untyped data. + +#ifndef LIBANGLE_SIZED_MRU_CACHE_H_ +#define LIBANGLE_SIZED_MRU_CACHE_H_ + +#include + +namespace angle +{ + +template +class SizedMRUCache final : angle::NonCopyable +{ + public: + SizedMRUCache(size_t maximumTotalSize) + : mMaximumTotalSize(maximumTotalSize), + mCurrentSize(0), + mStore(SizedMRUCacheStore::NO_AUTO_EVICT) + {} + + // Returns nullptr on failure. + const Value *put(const Key &key, Value &&value, size_t size) + { + if (size > mMaximumTotalSize) + { + return nullptr; + } + + // Check for existing key. + eraseByKey(key); + + auto retVal = mStore.Put(key, ValueAndSize(std::move(value), size)); + mCurrentSize += size; + + shrinkToSize(mMaximumTotalSize); + + return &retVal->second.value; + } + + bool get(const Key &key, const Value **valueOut) + { + const auto &iter = mStore.Get(key); + if (iter == mStore.end()) + { + return false; + } + *valueOut = &iter->second.value; + return true; + } + + bool getAt(size_t index, const Key **keyOut, const Value **valueOut) + { + if (index < mStore.size()) + { + auto it = mStore.begin(); + std::advance(it, index); + *keyOut = &it->first; + *valueOut = &it->second.value; + return true; + } + *valueOut = nullptr; + return false; + } + + bool empty() const { return mStore.empty(); } + + void clear() + { + mStore.Clear(); + mCurrentSize = 0; + } + + void eraseByKey(const Key &key) + { + // Check for existing key. + auto existing = mStore.Peek(key); + if (existing != mStore.end()) + { + mCurrentSize -= existing->second.size; + mStore.Erase(existing); + } + } + + size_t entryCount() const { return mStore.size(); } + + size_t size() const { return mCurrentSize; } + + // Also discards the cache contents. + void resize(size_t maximumTotalSize) + { + clear(); + mMaximumTotalSize = maximumTotalSize; + } + + // Reduce current memory usage. + size_t shrinkToSize(size_t limit) + { + size_t initialSize = mCurrentSize; + + while (mCurrentSize > limit) + { + ASSERT(!mStore.empty()); + auto iter = mStore.rbegin(); + mCurrentSize -= iter->second.size; + mStore.Erase(iter); + } + + return (initialSize - mCurrentSize); + } + + size_t maxSize() const { return mMaximumTotalSize; } + + private: + struct ValueAndSize + { + ValueAndSize() : value(), size(0) {} + ValueAndSize(Value &&value, size_t size) : value(std::move(value)), size(size) {} + ValueAndSize(ValueAndSize &&other) : ValueAndSize() { *this = std::move(other); } + ValueAndSize &operator=(ValueAndSize &&other) + { + std::swap(value, other.value); + std::swap(size, other.size); + return *this; + } + + Value value; + size_t size; + }; + + using SizedMRUCacheStore = base::HashingMRUCache; + + size_t mMaximumTotalSize; + size_t mCurrentSize; + SizedMRUCacheStore mStore; +}; + +// Helper function used in a few places. +template +void TrimCache(size_t maxStates, size_t gcLimit, const char *name, T *cache) +{ + const size_t kGarbageCollectionLimit = maxStates / 2 + gcLimit; + + if (cache->size() >= kGarbageCollectionLimit) + { + WARN() << "Overflowed the " << name << " cache limit of " << (maxStates / 2) + << " elements, removing the least recently used to make room."; + cache->ShrinkToSize(maxStates / 2); + } +} +} // namespace angle +#endif // LIBANGLE_SIZED_MRU_CACHE_H_ diff --git a/gfx/angle/checkout/src/libANGLE/State.cpp b/gfx/angle/checkout/src/libANGLE/State.cpp new file mode 100644 index 0000000000..8f99a238a6 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/State.cpp @@ -0,0 +1,3866 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// State.cpp: Implements the State class, encapsulating raw GL state. + +#include "libANGLE/State.h" + +#include +#include + +#include "common/bitset_utils.h" +#include "common/mathutil.h" +#include "common/matrix_utils.h" +#include "libANGLE/Buffer.h" +#include "libANGLE/Caps.h" +#include "libANGLE/Context.h" +#include "libANGLE/Debug.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/PixelLocalStorage.h" +#include "libANGLE/Query.h" +#include "libANGLE/VertexArray.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/queryconversions.h" +#include "libANGLE/queryutils.h" +#include "libANGLE/renderer/ContextImpl.h" +#include "libANGLE/renderer/TextureImpl.h" + +namespace gl +{ + +namespace +{ +bool GetAlternativeQueryType(QueryType type, QueryType *alternativeType) +{ + switch (type) + { + case QueryType::AnySamples: + *alternativeType = QueryType::AnySamplesConservative; + return true; + case QueryType::AnySamplesConservative: + *alternativeType = QueryType::AnySamples; + return true; + default: + return false; + } +} + +// Mapping from a buffer binding type to a dirty bit type. +constexpr angle::PackedEnumMap kBufferBindingDirtyBits = {{ + {BufferBinding::AtomicCounter, State::DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING}, + {BufferBinding::DispatchIndirect, State::DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING}, + {BufferBinding::DrawIndirect, State::DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING}, + {BufferBinding::PixelPack, State::DIRTY_BIT_PACK_BUFFER_BINDING}, + {BufferBinding::PixelUnpack, State::DIRTY_BIT_UNPACK_BUFFER_BINDING}, + {BufferBinding::ShaderStorage, State::DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING}, + {BufferBinding::Uniform, State::DIRTY_BIT_UNIFORM_BUFFER_BINDINGS}, +}}; + +// Returns a buffer binding function depending on if a dirty bit is set. +template +constexpr std::pair GetBufferBindingSetter() +{ + return std::make_pair(Target, kBufferBindingDirtyBits[Target] != 0 + ? &State::setGenericBufferBindingWithBit + : &State::setGenericBufferBinding); +} + +template +using ContextStateMember = T *(State::*); + +template +T *AllocateOrGetSharedResourceManager(const State *shareContextState, + ContextStateMember member, + T *shareResources = nullptr) +{ + if (shareContextState) + { + T *resourceManager = (*shareContextState).*member; + ASSERT(!resourceManager || resourceManager == shareResources || !shareResources); + resourceManager->addRef(); + return resourceManager; + } + else if (shareResources) + { + shareResources->addRef(); + return shareResources; + } + else + { + return new T(); + } +} + +// TODO(https://anglebug.com/3889): Remove this helper function after blink and chromium part +// refactory done. +bool IsTextureCompatibleWithSampler(TextureType texture, TextureType sampler) +{ + if (sampler == texture) + { + return true; + } + + if (sampler == TextureType::VideoImage) + { + if (texture == TextureType::VideoImage || texture == TextureType::_2D) + { + return true; + } + } + + return false; +} + +uint32_t gIDCounter = 1; +} // namespace + +template +ANGLE_INLINE void UpdateNonTFBufferBindingWebGL(const Context *context, + BindingT *binding, + Buffer *buffer, + ArgsT... args) +{ + Buffer *oldBuffer = binding->get(); + if (oldBuffer) + { + oldBuffer->onNonTFBindingChanged(-1); + oldBuffer->release(context); + } + binding->assign(buffer, args...); + if (buffer) + { + buffer->addRef(); + buffer->onNonTFBindingChanged(1); + } +} + +template +void UpdateTFBufferBindingWebGL(const Context *context, + BindingT *binding, + bool indexed, + ArgsT... args) +{ + if (binding->get()) + (*binding)->onTFBindingChanged(context, false, indexed); + binding->set(context, args...); + if (binding->get()) + (*binding)->onTFBindingChanged(context, true, indexed); +} + +void UpdateBufferBinding(const Context *context, + BindingPointer *binding, + Buffer *buffer, + BufferBinding target) +{ + if (context->isWebGL()) + { + if (target == BufferBinding::TransformFeedback) + { + UpdateTFBufferBindingWebGL(context, binding, false, buffer); + } + else + { + UpdateNonTFBufferBindingWebGL(context, binding, buffer); + } + } + else + { + binding->set(context, buffer); + } +} + +void UpdateIndexedBufferBinding(const Context *context, + OffsetBindingPointer *binding, + Buffer *buffer, + BufferBinding target, + GLintptr offset, + GLsizeiptr size) +{ + if (context->isWebGL()) + { + if (target == BufferBinding::TransformFeedback) + { + UpdateTFBufferBindingWebGL(context, binding, true, buffer, offset, size); + } + else + { + UpdateNonTFBufferBindingWebGL(context, binding, buffer, offset, size); + } + } + else + { + binding->set(context, buffer, offset, size); + } +} + +// These template functions must be defined before they are instantiated in kBufferSetters. +template +void State::setGenericBufferBindingWithBit(const Context *context, Buffer *buffer) +{ + if (context->isWebGL()) + { + UpdateNonTFBufferBindingWebGL(context, &mBoundBuffers[Target], buffer); + } + else + { + mBoundBuffers[Target].set(context, buffer); + } + mDirtyBits.set(kBufferBindingDirtyBits[Target]); +} + +template +void State::setGenericBufferBinding(const Context *context, Buffer *buffer) +{ + if (context->isWebGL()) + { + UpdateNonTFBufferBindingWebGL(context, &mBoundBuffers[Target], buffer); + } + else + { + mBoundBuffers[Target].set(context, buffer); + } +} + +template <> +void State::setGenericBufferBinding(const Context *context, + Buffer *buffer) +{ + if (context->isWebGL()) + { + UpdateTFBufferBindingWebGL(context, &mBoundBuffers[BufferBinding::TransformFeedback], false, + buffer); + } + else + { + mBoundBuffers[BufferBinding::TransformFeedback].set(context, buffer); + } +} + +template <> +void State::setGenericBufferBinding(const Context *context, + Buffer *buffer) +{ + Buffer *oldBuffer = mVertexArray->mState.mElementArrayBuffer.get(); + if (oldBuffer) + { + oldBuffer->removeObserver(&mVertexArray->mState.mElementArrayBuffer); + oldBuffer->removeContentsObserver(mVertexArray, kElementArrayBufferIndex); + if (context->isWebGL()) + { + oldBuffer->onNonTFBindingChanged(-1); + } + oldBuffer->release(context); + } + mVertexArray->mState.mElementArrayBuffer.assign(buffer); + if (buffer) + { + buffer->addObserver(&mVertexArray->mState.mElementArrayBuffer); + buffer->addContentsObserver(mVertexArray, kElementArrayBufferIndex); + if (context->isWebGL()) + { + buffer->onNonTFBindingChanged(1); + } + buffer->addRef(); + } + mVertexArray->mDirtyBits.set(VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER); + mVertexArray->mIndexRangeCache.invalidate(); + mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY); +} + +const angle::PackedEnumMap State::kBufferSetters = {{ + GetBufferBindingSetter(), + GetBufferBindingSetter(), + GetBufferBindingSetter(), + GetBufferBindingSetter(), + GetBufferBindingSetter(), + GetBufferBindingSetter(), + GetBufferBindingSetter(), + GetBufferBindingSetter(), + GetBufferBindingSetter(), + GetBufferBindingSetter(), + GetBufferBindingSetter(), + GetBufferBindingSetter(), + GetBufferBindingSetter(), +}}; + +ActiveTexturesCache::ActiveTexturesCache() : mTextures{} {} + +ActiveTexturesCache::~ActiveTexturesCache() +{ + ASSERT(empty()); +} + +void ActiveTexturesCache::clear() +{ + for (size_t textureIndex = 0; textureIndex < mTextures.size(); ++textureIndex) + { + reset(textureIndex); + } +} + +bool ActiveTexturesCache::empty() const +{ + for (Texture *texture : mTextures) + { + if (texture) + { + return false; + } + } + + return true; +} + +ANGLE_INLINE void ActiveTexturesCache::reset(size_t textureIndex) +{ + if (mTextures[textureIndex]) + { + mTextures[textureIndex] = nullptr; + } +} + +ANGLE_INLINE void ActiveTexturesCache::set(size_t textureIndex, Texture *texture) +{ + ASSERT(texture); + mTextures[textureIndex] = texture; +} + +State::State(const State *shareContextState, + egl::ShareGroup *shareGroup, + TextureManager *shareTextures, + SemaphoreManager *shareSemaphores, + const OverlayType *overlay, + const EGLenum clientType, + const Version &clientVersion, + EGLint profileMask, + bool debug, + bool bindGeneratesResourceCHROMIUM, + bool clientArraysEnabled, + bool robustResourceInit, + bool programBinaryCacheEnabled, + EGLenum contextPriority, + bool hasRobustAccess, + bool hasProtectedContent) + : mID({gIDCounter++}), + mClientType(clientType), + mProfileMask(profileMask), + mContextPriority(contextPriority), + mHasRobustAccess(hasRobustAccess), + mHasProtectedContent(hasProtectedContent), + mIsDebugContext(debug), + mClientVersion(clientVersion), + mShareGroup(shareGroup), + mBufferManager(AllocateOrGetSharedResourceManager(shareContextState, &State::mBufferManager)), + mShaderProgramManager( + AllocateOrGetSharedResourceManager(shareContextState, &State::mShaderProgramManager)), + mTextureManager(AllocateOrGetSharedResourceManager(shareContextState, + &State::mTextureManager, + shareTextures)), + mRenderbufferManager( + AllocateOrGetSharedResourceManager(shareContextState, &State::mRenderbufferManager)), + mSamplerManager( + AllocateOrGetSharedResourceManager(shareContextState, &State::mSamplerManager)), + mSyncManager(AllocateOrGetSharedResourceManager(shareContextState, &State::mSyncManager)), + mFramebufferManager(new FramebufferManager()), + mProgramPipelineManager(new ProgramPipelineManager()), + mMemoryObjectManager( + AllocateOrGetSharedResourceManager(shareContextState, &State::mMemoryObjectManager)), + mSemaphoreManager(AllocateOrGetSharedResourceManager(shareContextState, + &State::mSemaphoreManager, + shareSemaphores)), + mDepthClearValue(0), + mStencilClearValue(0), + mScissorTest(false), + mSampleAlphaToCoverage(false), + mSampleCoverage(false), + mSampleCoverageValue(0), + mSampleCoverageInvert(false), + mSampleMask(false), + mMaxSampleMaskWords(0), + mIsSampleShadingEnabled(false), + mMinSampleShading(0.0f), + mStencilRef(0), + mStencilBackRef(0), + mLineWidth(0), + mGenerateMipmapHint(GL_NONE), + mTextureFilteringHint(GL_NONE), + mFragmentShaderDerivativeHint(GL_NONE), + mBindGeneratesResource(bindGeneratesResourceCHROMIUM), + mClientArraysEnabled(clientArraysEnabled), + mNearZ(0), + mFarZ(0), + mReadFramebuffer(nullptr), + mDrawFramebuffer(nullptr), + mProgram(nullptr), + mExecutable(nullptr), + mProvokingVertex(gl::ProvokingVertexConvention::LastVertexConvention), + mVertexArray(nullptr), + mActiveSampler(0), + mPrimitiveRestart(false), + mDebug(debug), + mMultiSampling(false), + mSampleAlphaToOne(false), + mFramebufferSRGB(true), + mRobustResourceInit(robustResourceInit), + mProgramBinaryCacheEnabled(programBinaryCacheEnabled), + mTextureRectangleEnabled(true), + mLogicOpEnabled(false), + mLogicOp(LogicalOperation::Copy), + mMaxShaderCompilerThreads(std::numeric_limits::max()), + mPatchVertices(3), + mPixelLocalStorageActive(false), + mOverlay(overlay), + mNoSimultaneousConstantColorAndAlphaBlendFunc(false), + mSetBlendIndexedInvoked(false), + mSetBlendFactorsIndexedInvoked(false), + mSetBlendEquationsIndexedInvoked(false), + mDisplayTextureShareGroup(shareTextures != nullptr), + mBoundingBoxMinX(-1.0f), + mBoundingBoxMinY(-1.0f), + mBoundingBoxMinZ(-1.0f), + mBoundingBoxMinW(1.0f), + mBoundingBoxMaxX(1.0f), + mBoundingBoxMaxY(1.0f), + mBoundingBoxMaxZ(1.0f), + mBoundingBoxMaxW(1.0f), + mShadingRatePreserveAspectRatio(false), + mShadingRate(ShadingRate::Undefined) +{} + +State::~State() {} + +void State::initialize(Context *context) +{ + const Extensions &nativeExtensions = context->getImplementation()->getNativeExtensions(); + const Version &clientVersion = context->getClientVersion(); + + mBlendStateExt = BlendStateExt(mCaps.maxDrawBuffers); + + setColorClearValue(0.0f, 0.0f, 0.0f, 0.0f); + + mDepthClearValue = 1.0f; + mStencilClearValue = 0; + + mScissorTest = false; + mScissor.x = 0; + mScissor.y = 0; + mScissor.width = 0; + mScissor.height = 0; + + mBlendColor.red = 0; + mBlendColor.green = 0; + mBlendColor.blue = 0; + mBlendColor.alpha = 0; + + mStencilRef = 0; + mStencilBackRef = 0; + + mSampleCoverage = false; + mSampleCoverageValue = 1.0f; + mSampleCoverageInvert = false; + + mMaxSampleMaskWords = static_cast(mCaps.maxSampleMaskWords); + mSampleMask = false; + mSampleMaskValues.fill(~GLbitfield(0)); + + mGenerateMipmapHint = GL_DONT_CARE; + mTextureFilteringHint = GL_DONT_CARE; + mFragmentShaderDerivativeHint = GL_DONT_CARE; + + mLineWidth = 1.0f; + + mViewport.x = 0; + mViewport.y = 0; + mViewport.width = 0; + mViewport.height = 0; + mNearZ = 0.0f; + mFarZ = 1.0f; + + mClipControlOrigin = GL_LOWER_LEFT_EXT; + mClipControlDepth = GL_NEGATIVE_ONE_TO_ONE_EXT; + + mActiveSampler = 0; + + mVertexAttribCurrentValues.resize(mCaps.maxVertexAttributes); + + // Set all indexes in state attributes type mask to float (default) + for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) + { + SetComponentTypeMask(ComponentType::Float, i, &mCurrentValuesTypeMask); + } + + mUniformBuffers.resize(mCaps.maxUniformBufferBindings); + + mSamplerTextures[TextureType::_2D].resize(mCaps.maxCombinedTextureImageUnits); + mSamplerTextures[TextureType::CubeMap].resize(mCaps.maxCombinedTextureImageUnits); + if (clientVersion >= Version(3, 0) || nativeExtensions.texture3DOES) + { + mSamplerTextures[TextureType::_3D].resize(mCaps.maxCombinedTextureImageUnits); + } + if (clientVersion >= Version(3, 0)) + { + mSamplerTextures[TextureType::_2DArray].resize(mCaps.maxCombinedTextureImageUnits); + } + if (clientVersion >= Version(3, 1) || nativeExtensions.textureMultisampleANGLE) + { + mSamplerTextures[TextureType::_2DMultisample].resize(mCaps.maxCombinedTextureImageUnits); + } + if (clientVersion >= Version(3, 1)) + { + mSamplerTextures[TextureType::_2DMultisampleArray].resize( + mCaps.maxCombinedTextureImageUnits); + + mAtomicCounterBuffers.resize(mCaps.maxAtomicCounterBufferBindings); + mShaderStorageBuffers.resize(mCaps.maxShaderStorageBufferBindings); + } + if (clientVersion >= Version(3, 1) || + (mExtensions.shaderPixelLocalStorageANGLE && + ShPixelLocalStorageTypeUsesImages( + context->getImplementation()->getNativePixelLocalStorageType()))) + { + mImageUnits.resize(mCaps.maxImageUnits); + } + if (clientVersion >= Version(3, 2) || mExtensions.textureCubeMapArrayAny()) + { + mSamplerTextures[TextureType::CubeMapArray].resize(mCaps.maxCombinedTextureImageUnits); + } + if (clientVersion >= Version(3, 2) || mExtensions.textureBufferAny()) + { + mSamplerTextures[TextureType::Buffer].resize(mCaps.maxCombinedTextureImageUnits); + } + if (nativeExtensions.textureRectangleANGLE) + { + mSamplerTextures[TextureType::Rectangle].resize(mCaps.maxCombinedTextureImageUnits); + } + if (nativeExtensions.EGLImageExternalOES || nativeExtensions.EGLStreamConsumerExternalNV) + { + mSamplerTextures[TextureType::External].resize(mCaps.maxCombinedTextureImageUnits); + } + if (nativeExtensions.videoTextureWEBGL) + { + mSamplerTextures[TextureType::VideoImage].resize(mCaps.maxCombinedTextureImageUnits); + } + mCompleteTextureBindings.reserve(mCaps.maxCombinedTextureImageUnits); + for (int32_t textureIndex = 0; textureIndex < mCaps.maxCombinedTextureImageUnits; + ++textureIndex) + { + mCompleteTextureBindings.emplace_back(context, textureIndex); + } + + mSamplers.resize(mCaps.maxCombinedTextureImageUnits); + + for (QueryType type : angle::AllEnums()) + { + mActiveQueries[type].set(context, nullptr); + } + + mProgram = nullptr; + mExecutable = nullptr; + + mReadFramebuffer = nullptr; + mDrawFramebuffer = nullptr; + + mPrimitiveRestart = false; + + mDebug.setMaxLoggedMessages(mCaps.maxDebugLoggedMessages); + + mMultiSampling = true; + mSampleAlphaToOne = false; + + mCoverageModulation = GL_NONE; + + mNoSimultaneousConstantColorAndAlphaBlendFunc = + context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc || + context->getExtensions().webglCompatibilityANGLE; + + mNoUnclampedBlendColor = context->getLimitations().noUnclampedBlendColor; + + // GLES1 emulation: Initialize state for GLES1 if version applies + // TODO(http://anglebug.com/3745): When on desktop client only do this in compatibility profile + if (clientVersion < Version(2, 0) || mClientType == EGL_OPENGL_API) + { + mGLES1State.initialize(context, this); + } +} + +void State::reset(const Context *context) +{ + // Force a sync so clear doesn't end up dereferencing stale pointers. + (void)syncActiveTextures(context, Command::Other); + mActiveTexturesCache.clear(); + + for (TextureBindingVector &bindingVec : mSamplerTextures) + { + for (BindingPointer &texBinding : bindingVec) + { + texBinding.set(context, nullptr); + } + } + for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++) + { + mSamplers[samplerIdx].set(context, nullptr); + } + + for (ImageUnit &imageUnit : mImageUnits) + { + imageUnit.texture.set(context, nullptr); + imageUnit.level = 0; + imageUnit.layered = false; + imageUnit.layer = 0; + imageUnit.access = GL_READ_ONLY; + imageUnit.format = GL_R32UI; + } + + mRenderbuffer.set(context, nullptr); + + for (BufferBinding type : angle::AllEnums()) + { + UpdateBufferBinding(context, &mBoundBuffers[type], nullptr, type); + } + + if (mProgram) + { + mProgram->release(context); + } + mProgram = nullptr; + mProgramPipeline.set(context, nullptr); + mExecutable = nullptr; + + if (mTransformFeedback.get()) + { + mTransformFeedback->onBindingChanged(context, false); + } + mTransformFeedback.set(context, nullptr); + + for (QueryType type : angle::AllEnums()) + { + mActiveQueries[type].set(context, nullptr); + } + + for (OffsetBindingPointer &buf : mUniformBuffers) + { + UpdateIndexedBufferBinding(context, &buf, nullptr, BufferBinding::Uniform, 0, 0); + } + mBoundUniformBuffersMask.reset(); + + for (OffsetBindingPointer &buf : mAtomicCounterBuffers) + { + UpdateIndexedBufferBinding(context, &buf, nullptr, BufferBinding::AtomicCounter, 0, 0); + } + mBoundAtomicCounterBuffersMask.reset(); + + for (OffsetBindingPointer &buf : mShaderStorageBuffers) + { + UpdateIndexedBufferBinding(context, &buf, nullptr, BufferBinding::ShaderStorage, 0, 0); + } + mBoundShaderStorageBuffersMask.reset(); + + mClipDistancesEnabled.reset(); + + setAllDirtyBits(); +} + +ANGLE_INLINE void State::unsetActiveTextures(const ActiveTextureMask &textureMask) +{ + // Unset any relevant bound textures. + for (size_t textureIndex : textureMask) + { + mActiveTexturesCache.reset(textureIndex); + mCompleteTextureBindings[textureIndex].reset(); + } +} + +ANGLE_INLINE void State::updateActiveTextureStateOnSync(const Context *context, + size_t textureIndex, + const Sampler *sampler, + Texture *texture) +{ + if (!texture || !texture->isSamplerComplete(context, sampler)) + { + mActiveTexturesCache.reset(textureIndex); + } + else + { + mActiveTexturesCache.set(textureIndex, texture); + } + + mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS); +} + +ANGLE_INLINE void State::setActiveTextureDirty(size_t textureIndex, Texture *texture) +{ + mDirtyObjects.set(DIRTY_OBJECT_ACTIVE_TEXTURES); + mDirtyActiveTextures.set(textureIndex); + + if (!texture) + { + return; + } + + if (texture->hasAnyDirtyBit()) + { + setTextureDirty(textureIndex); + } + + if (mRobustResourceInit && texture->initState() == InitState::MayNeedInit) + { + mDirtyObjects.set(DIRTY_OBJECT_TEXTURES_INIT); + } + + // This cache is updated immediately because we use the cache in the validation layer. + // If we defer the update until syncState it's too late and we've already passed validation. + if (texture && mExecutable) + { + // It is invalid to try to sample a non-yuv texture with a yuv sampler. + mTexturesIncompatibleWithSamplers[textureIndex] = + mExecutable->getActiveYUVSamplers().test(textureIndex) && !texture->isYUV(); + + if (isWebGL()) + { + const Sampler *sampler = mSamplers[textureIndex].get(); + const SamplerState &samplerState = + sampler ? sampler->getSamplerState() : texture->getSamplerState(); + if (!texture->getTextureState().compatibleWithSamplerFormatForWebGL( + mExecutable->getSamplerFormatForTextureUnitIndex(textureIndex), samplerState)) + { + mTexturesIncompatibleWithSamplers[textureIndex] = true; + } + } + } + else + { + mTexturesIncompatibleWithSamplers[textureIndex] = false; + } +} + +ANGLE_INLINE void State::updateTextureBinding(const Context *context, + size_t textureIndex, + Texture *texture) +{ + mCompleteTextureBindings[textureIndex].bind(texture); + mActiveTexturesCache.reset(textureIndex); + setActiveTextureDirty(textureIndex, texture); +} + +ANGLE_INLINE bool State::hasConstantColor(GLenum sourceRGB, GLenum destRGB) const +{ + return sourceRGB == GL_CONSTANT_COLOR || sourceRGB == GL_ONE_MINUS_CONSTANT_COLOR || + destRGB == GL_CONSTANT_COLOR || destRGB == GL_ONE_MINUS_CONSTANT_COLOR; +} + +ANGLE_INLINE bool State::hasConstantAlpha(GLenum sourceRGB, GLenum destRGB) const +{ + return sourceRGB == GL_CONSTANT_ALPHA || sourceRGB == GL_ONE_MINUS_CONSTANT_ALPHA || + destRGB == GL_CONSTANT_ALPHA || destRGB == GL_ONE_MINUS_CONSTANT_ALPHA; +} + +const RasterizerState &State::getRasterizerState() const +{ + return mRasterizer; +} + +const DepthStencilState &State::getDepthStencilState() const +{ + return mDepthStencil; +} + +void State::setColorClearValue(float red, float green, float blue, float alpha) +{ + mColorClearValue.red = red; + mColorClearValue.green = green; + mColorClearValue.blue = blue; + mColorClearValue.alpha = alpha; + mDirtyBits.set(DIRTY_BIT_CLEAR_COLOR); +} + +void State::setDepthClearValue(float depth) +{ + mDepthClearValue = depth; + mDirtyBits.set(DIRTY_BIT_CLEAR_DEPTH); +} + +void State::setStencilClearValue(int stencil) +{ + mStencilClearValue = stencil; + mDirtyBits.set(DIRTY_BIT_CLEAR_STENCIL); +} + +void State::setColorMask(bool red, bool green, bool blue, bool alpha) +{ + mBlendState.colorMaskRed = red; + mBlendState.colorMaskGreen = green; + mBlendState.colorMaskBlue = blue; + mBlendState.colorMaskAlpha = alpha; + + mBlendStateExt.setColorMask(red, green, blue, alpha); + mDirtyBits.set(DIRTY_BIT_COLOR_MASK); +} + +void State::setColorMaskIndexed(bool red, bool green, bool blue, bool alpha, GLuint index) +{ + mBlendStateExt.setColorMaskIndexed(index, red, green, blue, alpha); + mDirtyBits.set(DIRTY_BIT_COLOR_MASK); +} + +bool State::allActiveDrawBufferChannelsMasked() const +{ + // Compare current color mask with all-disabled color mask, while ignoring disabled draw + // buffers. + return (mBlendStateExt.compareColorMask(0) & mDrawFramebuffer->getDrawBufferMask()).none(); +} + +bool State::anyActiveDrawBufferChannelMasked() const +{ + // Compare current color mask with all-enabled color mask, while ignoring disabled draw + // buffers. + return (mBlendStateExt.compareColorMask(mBlendStateExt.getAllColorMaskBits()) & + mDrawFramebuffer->getDrawBufferMask()) + .any(); +} + +void State::setDepthMask(bool mask) +{ + if (mDepthStencil.depthMask != mask) + { + mDepthStencil.depthMask = mask; + mDirtyBits.set(DIRTY_BIT_DEPTH_MASK); + } +} + +void State::setRasterizerDiscard(bool enabled) +{ + if (mRasterizer.rasterizerDiscard != enabled) + { + mRasterizer.rasterizerDiscard = enabled; + mDirtyBits.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED); + } +} + +void State::setCullFace(bool enabled) +{ + if (mRasterizer.cullFace != enabled) + { + mRasterizer.cullFace = enabled; + mDirtyBits.set(DIRTY_BIT_CULL_FACE_ENABLED); + } +} + +void State::setCullMode(CullFaceMode mode) +{ + if (mRasterizer.cullMode != mode) + { + mRasterizer.cullMode = mode; + mDirtyBits.set(DIRTY_BIT_CULL_FACE); + } +} + +void State::setFrontFace(GLenum front) +{ + if (mRasterizer.frontFace != front) + { + mRasterizer.frontFace = front; + mDirtyBits.set(DIRTY_BIT_FRONT_FACE); + } +} + +void State::setDepthTest(bool enabled) +{ + if (mDepthStencil.depthTest != enabled) + { + mDepthStencil.depthTest = enabled; + mDirtyBits.set(DIRTY_BIT_DEPTH_TEST_ENABLED); + } +} + +void State::setDepthFunc(GLenum depthFunc) +{ + if (mDepthStencil.depthFunc != depthFunc) + { + mDepthStencil.depthFunc = depthFunc; + mDirtyBits.set(DIRTY_BIT_DEPTH_FUNC); + } +} + +void State::setDepthRange(float zNear, float zFar) +{ + if (mNearZ != zNear || mFarZ != zFar) + { + mNearZ = zNear; + mFarZ = zFar; + mDirtyBits.set(DIRTY_BIT_DEPTH_RANGE); + } +} + +void State::setClipControl(GLenum origin, GLenum depth) +{ + bool updated = false; + if (mClipControlOrigin != origin) + { + mClipControlOrigin = origin; + updated = true; + } + + if (mClipControlDepth != depth) + { + mClipControlDepth = depth; + updated = true; + } + + if (updated) + { + mDirtyBits.set(DIRTY_BIT_EXTENDED); + mExtendedDirtyBits.set(EXTENDED_DIRTY_BIT_CLIP_CONTROL); + } +} + +void State::setBlend(bool enabled) +{ + if (mSetBlendIndexedInvoked || mBlendState.blend != enabled) + { + mBlendState.blend = enabled; + + mSetBlendIndexedInvoked = false; + mBlendStateExt.setEnabled(enabled); + mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED); + } +} + +void State::setBlendIndexed(bool enabled, GLuint index) +{ + mSetBlendIndexedInvoked = true; + mBlendStateExt.setEnabledIndexed(index, enabled); + mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED); +} + +void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha) +{ + if (!mSetBlendFactorsIndexedInvoked && mBlendState.sourceBlendRGB == sourceRGB && + mBlendState.destBlendRGB == destRGB && mBlendState.sourceBlendAlpha == sourceAlpha && + mBlendState.destBlendAlpha == destAlpha) + { + return; + } + + mBlendState.sourceBlendRGB = sourceRGB; + mBlendState.destBlendRGB = destRGB; + mBlendState.sourceBlendAlpha = sourceAlpha; + mBlendState.destBlendAlpha = destAlpha; + + if (mNoSimultaneousConstantColorAndAlphaBlendFunc) + { + if (hasConstantColor(sourceRGB, destRGB)) + { + mBlendFuncConstantColorDrawBuffers.set(); + } + else + { + mBlendFuncConstantColorDrawBuffers.reset(); + } + + if (hasConstantAlpha(sourceRGB, destRGB)) + { + mBlendFuncConstantAlphaDrawBuffers.set(); + } + else + { + mBlendFuncConstantAlphaDrawBuffers.reset(); + } + } + + mSetBlendFactorsIndexedInvoked = false; + mBlendStateExt.setFactors(sourceRGB, destRGB, sourceAlpha, destAlpha); + mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS); +} + +void State::setBlendFactorsIndexed(GLenum sourceRGB, + GLenum destRGB, + GLenum sourceAlpha, + GLenum destAlpha, + GLuint index) +{ + if (mNoSimultaneousConstantColorAndAlphaBlendFunc) + { + mBlendFuncConstantColorDrawBuffers.set(index, hasConstantColor(sourceRGB, destRGB)); + mBlendFuncConstantAlphaDrawBuffers.set(index, hasConstantAlpha(sourceRGB, destRGB)); + } + + mSetBlendFactorsIndexedInvoked = true; + mBlendStateExt.setFactorsIndexed(index, sourceRGB, destRGB, sourceAlpha, destAlpha); + mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS); +} + +void State::setBlendColor(float red, float green, float blue, float alpha) +{ + // In ES2 without render-to-float extensions, BlendColor clamps to [0,1] on store. + // On ES3+, or with render-to-float exts enabled, it does not clamp on store. + const bool isES2 = mClientVersion.major == 2; + const bool hasFloatBlending = + mExtensions.colorBufferFloatEXT || mExtensions.colorBufferHalfFloatEXT || + mExtensions.colorBufferFloatRgbCHROMIUM || mExtensions.colorBufferFloatRgbaCHROMIUM; + if ((isES2 && !hasFloatBlending) || mNoUnclampedBlendColor) + { + red = clamp01(red); + green = clamp01(green); + blue = clamp01(blue); + alpha = clamp01(alpha); + } + + if (mBlendColor.red != red || mBlendColor.green != green || mBlendColor.blue != blue || + mBlendColor.alpha != alpha) + { + mBlendColor.red = red; + mBlendColor.green = green; + mBlendColor.blue = blue; + mBlendColor.alpha = alpha; + mDirtyBits.set(DIRTY_BIT_BLEND_COLOR); + } +} + +void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation) +{ + if (mSetBlendEquationsIndexedInvoked || mBlendState.blendEquationRGB != rgbEquation || + mBlendState.blendEquationAlpha != alphaEquation) + { + mBlendState.blendEquationRGB = rgbEquation; + mBlendState.blendEquationAlpha = alphaEquation; + + mSetBlendEquationsIndexedInvoked = false; + mBlendStateExt.setEquations(rgbEquation, alphaEquation); + mDirtyBits.set(DIRTY_BIT_BLEND_EQUATIONS); + } +} + +void State::setBlendEquationIndexed(GLenum rgbEquation, GLenum alphaEquation, GLuint index) +{ + mSetBlendEquationsIndexedInvoked = true; + mBlendStateExt.setEquationsIndexed(index, rgbEquation, alphaEquation); + mDirtyBits.set(DIRTY_BIT_BLEND_EQUATIONS); +} + +void State::setStencilTest(bool enabled) +{ + if (mDepthStencil.stencilTest != enabled) + { + mDepthStencil.stencilTest = enabled; + mDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED); + } +} + +void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask) +{ + if (mDepthStencil.stencilFunc != stencilFunc || mStencilRef != stencilRef || + mDepthStencil.stencilMask != stencilMask) + { + mDepthStencil.stencilFunc = stencilFunc; + mStencilRef = stencilRef; + mDepthStencil.stencilMask = stencilMask; + mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT); + } +} + +void State::setStencilBackParams(GLenum stencilBackFunc, + GLint stencilBackRef, + GLuint stencilBackMask) +{ + if (mDepthStencil.stencilBackFunc != stencilBackFunc || mStencilBackRef != stencilBackRef || + mDepthStencil.stencilBackMask != stencilBackMask) + { + mDepthStencil.stencilBackFunc = stencilBackFunc; + mStencilBackRef = stencilBackRef; + mDepthStencil.stencilBackMask = stencilBackMask; + mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK); + } +} + +void State::setStencilWritemask(GLuint stencilWritemask) +{ + if (mDepthStencil.stencilWritemask != stencilWritemask) + { + mDepthStencil.stencilWritemask = stencilWritemask; + mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT); + } +} + +void State::setStencilBackWritemask(GLuint stencilBackWritemask) +{ + if (mDepthStencil.stencilBackWritemask != stencilBackWritemask) + { + mDepthStencil.stencilBackWritemask = stencilBackWritemask; + mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK); + } +} + +void State::setStencilOperations(GLenum stencilFail, + GLenum stencilPassDepthFail, + GLenum stencilPassDepthPass) +{ + if (mDepthStencil.stencilFail != stencilFail || + mDepthStencil.stencilPassDepthFail != stencilPassDepthFail || + mDepthStencil.stencilPassDepthPass != stencilPassDepthPass) + { + mDepthStencil.stencilFail = stencilFail; + mDepthStencil.stencilPassDepthFail = stencilPassDepthFail; + mDepthStencil.stencilPassDepthPass = stencilPassDepthPass; + mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT); + } +} + +void State::setStencilBackOperations(GLenum stencilBackFail, + GLenum stencilBackPassDepthFail, + GLenum stencilBackPassDepthPass) +{ + if (mDepthStencil.stencilBackFail != stencilBackFail || + mDepthStencil.stencilBackPassDepthFail != stencilBackPassDepthFail || + mDepthStencil.stencilBackPassDepthPass != stencilBackPassDepthPass) + { + mDepthStencil.stencilBackFail = stencilBackFail; + mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail; + mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass; + mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK); + } +} + +void State::setPolygonOffsetFill(bool enabled) +{ + if (mRasterizer.polygonOffsetFill != enabled) + { + mRasterizer.polygonOffsetFill = enabled; + mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED); + } +} + +void State::setPolygonOffsetParams(GLfloat factor, GLfloat units) +{ + // An application can pass NaN values here, so handle this gracefully + mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor; + mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units; + mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET); +} + +void State::setSampleAlphaToCoverage(bool enabled) +{ + if (mSampleAlphaToCoverage != enabled) + { + mSampleAlphaToCoverage = enabled; + mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED); + } +} + +void State::setSampleCoverage(bool enabled) +{ + if (mSampleCoverage != enabled) + { + mSampleCoverage = enabled; + mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE_ENABLED); + } +} + +void State::setSampleCoverageParams(GLclampf value, bool invert) +{ + mSampleCoverageValue = value; + mSampleCoverageInvert = invert; + mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE); +} + +void State::setSampleMaskEnabled(bool enabled) +{ + if (mSampleMask != enabled) + { + mSampleMask = enabled; + mDirtyBits.set(DIRTY_BIT_SAMPLE_MASK_ENABLED); + } +} + +void State::setSampleMaskParams(GLuint maskNumber, GLbitfield mask) +{ + ASSERT(maskNumber < mMaxSampleMaskWords); + mSampleMaskValues[maskNumber] = mask; + // TODO(jmadill): Use a child dirty bit if we ever use more than two words. + mDirtyBits.set(DIRTY_BIT_SAMPLE_MASK); +} + +void State::setSampleAlphaToOne(bool enabled) +{ + if (mSampleAlphaToOne != enabled) + { + mSampleAlphaToOne = enabled; + mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_ONE); + } +} + +void State::setMultisampling(bool enabled) +{ + if (mMultiSampling != enabled) + { + mMultiSampling = enabled; + mDirtyBits.set(DIRTY_BIT_MULTISAMPLING); + } +} + +void State::setSampleShading(bool enabled) +{ + if (mIsSampleShadingEnabled != enabled) + { + mIsSampleShadingEnabled = enabled; + mMinSampleShading = (enabled) ? 1.0f : mMinSampleShading; + mDirtyBits.set(DIRTY_BIT_SAMPLE_SHADING); + } +} + +void State::setMinSampleShading(float value) +{ + value = gl::clamp01(value); + + if (mMinSampleShading != value) + { + mMinSampleShading = value; + mDirtyBits.set(DIRTY_BIT_SAMPLE_SHADING); + } +} + +void State::setScissorTest(bool enabled) +{ + if (mScissorTest != enabled) + { + mScissorTest = enabled; + mDirtyBits.set(DIRTY_BIT_SCISSOR_TEST_ENABLED); + } +} + +void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height) +{ + // Skip if same scissor info + if (mScissor.x != x || mScissor.y != y || mScissor.width != width || mScissor.height != height) + { + mScissor.x = x; + mScissor.y = y; + mScissor.width = width; + mScissor.height = height; + mDirtyBits.set(DIRTY_BIT_SCISSOR); + } +} + +void State::setDither(bool enabled) +{ + if (mRasterizer.dither != enabled) + { + mRasterizer.dither = enabled; + mDirtyBits.set(DIRTY_BIT_DITHER_ENABLED); + } +} + +void State::setPrimitiveRestart(bool enabled) +{ + if (mPrimitiveRestart != enabled) + { + mPrimitiveRestart = enabled; + mDirtyBits.set(DIRTY_BIT_PRIMITIVE_RESTART_ENABLED); + } +} + +void State::setClipDistanceEnable(int idx, bool enable) +{ + if (enable) + { + mClipDistancesEnabled.set(idx); + } + else + { + mClipDistancesEnabled.reset(idx); + } + + mDirtyBits.set(DIRTY_BIT_EXTENDED); + mExtendedDirtyBits.set(EXTENDED_DIRTY_BIT_CLIP_DISTANCES); +} + +void State::setEnableFeature(GLenum feature, bool enabled) +{ + switch (feature) + { + case GL_MULTISAMPLE_EXT: + setMultisampling(enabled); + return; + case GL_SAMPLE_ALPHA_TO_ONE_EXT: + setSampleAlphaToOne(enabled); + return; + case GL_CULL_FACE: + setCullFace(enabled); + return; + case GL_POLYGON_OFFSET_FILL: + setPolygonOffsetFill(enabled); + return; + case GL_SAMPLE_ALPHA_TO_COVERAGE: + setSampleAlphaToCoverage(enabled); + return; + case GL_SAMPLE_COVERAGE: + setSampleCoverage(enabled); + return; + case GL_SCISSOR_TEST: + setScissorTest(enabled); + return; + case GL_STENCIL_TEST: + setStencilTest(enabled); + return; + case GL_DEPTH_TEST: + setDepthTest(enabled); + return; + case GL_BLEND: + setBlend(enabled); + return; + case GL_DITHER: + setDither(enabled); + return; + case GL_COLOR_LOGIC_OP: + if (mClientVersion.major == 1) + { + // Handle logicOp in GLES1 through the GLES1 state management and emulation. + // Otherwise this state could be set as part of ANGLE_logic_op. + break; + } + setLogicOpEnabled(enabled); + return; + case GL_PRIMITIVE_RESTART_FIXED_INDEX: + setPrimitiveRestart(enabled); + return; + case GL_RASTERIZER_DISCARD: + setRasterizerDiscard(enabled); + return; + case GL_SAMPLE_MASK: + setSampleMaskEnabled(enabled); + return; + case GL_DEBUG_OUTPUT_SYNCHRONOUS: + mDebug.setOutputSynchronous(enabled); + return; + case GL_DEBUG_OUTPUT: + mDebug.setOutputEnabled(enabled); + return; + case GL_FRAMEBUFFER_SRGB_EXT: + setFramebufferSRGB(enabled); + return; + case GL_TEXTURE_RECTANGLE_ANGLE: + mTextureRectangleEnabled = enabled; + return; + case GL_SAMPLE_SHADING: + setSampleShading(enabled); + return; + // GL_APPLE_clip_distance/GL_EXT_clip_cull_distance + case GL_CLIP_DISTANCE0_EXT: + case GL_CLIP_DISTANCE1_EXT: + case GL_CLIP_DISTANCE2_EXT: + case GL_CLIP_DISTANCE3_EXT: + case GL_CLIP_DISTANCE4_EXT: + case GL_CLIP_DISTANCE5_EXT: + case GL_CLIP_DISTANCE6_EXT: + case GL_CLIP_DISTANCE7_EXT: + // NOTE(hqle): These enums are conflicted with GLES1's enums, need + // to do additional check here: + if (mClientVersion.major >= 2) + { + setClipDistanceEnable(feature - GL_CLIP_DISTANCE0_EXT, enabled); + return; + } + break; + case GL_SHADING_RATE_PRESERVE_ASPECT_RATIO_QCOM: + mShadingRatePreserveAspectRatio = enabled; + return; + } + + ASSERT(mClientVersion.major == 1); + + // GLES1 emulation. Need to separate from main switch due to conflict enum between + // GL_CLIP_DISTANCE0_EXT & GL_CLIP_PLANE0 + switch (feature) + { + case GL_ALPHA_TEST: + mGLES1State.mAlphaTestEnabled = enabled; + break; + case GL_TEXTURE_2D: + mGLES1State.mTexUnitEnables[mActiveSampler].set(TextureType::_2D, enabled); + break; + case GL_TEXTURE_CUBE_MAP: + mGLES1State.mTexUnitEnables[mActiveSampler].set(TextureType::CubeMap, enabled); + break; + case GL_LIGHTING: + mGLES1State.mLightingEnabled = enabled; + break; + case GL_LIGHT0: + case GL_LIGHT1: + case GL_LIGHT2: + case GL_LIGHT3: + case GL_LIGHT4: + case GL_LIGHT5: + case GL_LIGHT6: + case GL_LIGHT7: + mGLES1State.mLights[feature - GL_LIGHT0].enabled = enabled; + break; + case GL_NORMALIZE: + mGLES1State.mNormalizeEnabled = enabled; + break; + case GL_RESCALE_NORMAL: + mGLES1State.mRescaleNormalEnabled = enabled; + break; + case GL_COLOR_MATERIAL: + mGLES1State.mColorMaterialEnabled = enabled; + break; + case GL_CLIP_PLANE0: + case GL_CLIP_PLANE1: + case GL_CLIP_PLANE2: + case GL_CLIP_PLANE3: + case GL_CLIP_PLANE4: + case GL_CLIP_PLANE5: + mGLES1State.mClipPlanes[feature - GL_CLIP_PLANE0].enabled = enabled; + break; + case GL_FOG: + mGLES1State.mFogEnabled = enabled; + break; + case GL_POINT_SMOOTH: + mGLES1State.mPointSmoothEnabled = enabled; + break; + case GL_LINE_SMOOTH: + mGLES1State.mLineSmoothEnabled = enabled; + break; + case GL_POINT_SPRITE_OES: + mGLES1State.mPointSpriteEnabled = enabled; + break; + case GL_COLOR_LOGIC_OP: + mGLES1State.setLogicOpEnabled(enabled); + break; + default: + UNREACHABLE(); + } +} + +void State::setEnableFeatureIndexed(GLenum feature, bool enabled, GLuint index) +{ + switch (feature) + { + case GL_BLEND: + setBlendIndexed(enabled, index); + break; + default: + UNREACHABLE(); + } +} + +bool State::getEnableFeature(GLenum feature) const +{ + switch (feature) + { + case GL_MULTISAMPLE_EXT: + return isMultisamplingEnabled(); + case GL_SAMPLE_ALPHA_TO_ONE_EXT: + return isSampleAlphaToOneEnabled(); + case GL_CULL_FACE: + return isCullFaceEnabled(); + case GL_POLYGON_OFFSET_FILL: + return isPolygonOffsetFillEnabled(); + case GL_SAMPLE_ALPHA_TO_COVERAGE: + return isSampleAlphaToCoverageEnabled(); + case GL_SAMPLE_COVERAGE: + return isSampleCoverageEnabled(); + case GL_SCISSOR_TEST: + return isScissorTestEnabled(); + case GL_STENCIL_TEST: + return isStencilTestEnabled(); + case GL_DEPTH_TEST: + return isDepthTestEnabled(); + case GL_BLEND: + return isBlendEnabled(); + case GL_DITHER: + return isDitherEnabled(); + case GL_COLOR_LOGIC_OP: + if (mClientVersion.major == 1) + { + // Handle logicOp in GLES1 through the GLES1 state management and emulation. + break; + } + return isLogicOpEnabled(); + case GL_PRIMITIVE_RESTART_FIXED_INDEX: + return isPrimitiveRestartEnabled(); + case GL_RASTERIZER_DISCARD: + return isRasterizerDiscardEnabled(); + case GL_SAMPLE_MASK: + return isSampleMaskEnabled(); + case GL_DEBUG_OUTPUT_SYNCHRONOUS: + return mDebug.isOutputSynchronous(); + case GL_DEBUG_OUTPUT: + return mDebug.isOutputEnabled(); + case GL_BIND_GENERATES_RESOURCE_CHROMIUM: + return isBindGeneratesResourceEnabled(); + case GL_CLIENT_ARRAYS_ANGLE: + return areClientArraysEnabled(); + case GL_FRAMEBUFFER_SRGB_EXT: + return getFramebufferSRGB(); + case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE: + return mRobustResourceInit; + case GL_PROGRAM_CACHE_ENABLED_ANGLE: + return mProgramBinaryCacheEnabled; + case GL_TEXTURE_RECTANGLE_ANGLE: + return mTextureRectangleEnabled; + case GL_SAMPLE_SHADING: + return isSampleShadingEnabled(); + // GL_APPLE_clip_distance/GL_EXT_clip_cull_distance + case GL_CLIP_DISTANCE0_EXT: + case GL_CLIP_DISTANCE1_EXT: + case GL_CLIP_DISTANCE2_EXT: + case GL_CLIP_DISTANCE3_EXT: + case GL_CLIP_DISTANCE4_EXT: + case GL_CLIP_DISTANCE5_EXT: + case GL_CLIP_DISTANCE6_EXT: + case GL_CLIP_DISTANCE7_EXT: + if (mClientVersion.major >= 2) + { + // If GLES version is 1, the GL_CLIP_DISTANCE0_EXT enum will be used as + // GL_CLIP_PLANE0 instead. + return mClipDistancesEnabled.test(feature - GL_CLIP_DISTANCE0_EXT); + } + break; + case GL_SHADING_RATE_PRESERVE_ASPECT_RATIO_QCOM: + return mShadingRatePreserveAspectRatio; + } + + ASSERT(mClientVersion.major == 1); + + switch (feature) + { + // GLES1 emulation + case GL_ALPHA_TEST: + return mGLES1State.mAlphaTestEnabled; + case GL_VERTEX_ARRAY: + return mGLES1State.mVertexArrayEnabled; + case GL_NORMAL_ARRAY: + return mGLES1State.mNormalArrayEnabled; + case GL_COLOR_ARRAY: + return mGLES1State.mColorArrayEnabled; + case GL_POINT_SIZE_ARRAY_OES: + return mGLES1State.mPointSizeArrayEnabled; + case GL_TEXTURE_COORD_ARRAY: + return mGLES1State.mTexCoordArrayEnabled[mGLES1State.mClientActiveTexture]; + case GL_TEXTURE_2D: + return mGLES1State.isTextureTargetEnabled(getActiveSampler(), TextureType::_2D); + case GL_TEXTURE_CUBE_MAP: + return mGLES1State.isTextureTargetEnabled(getActiveSampler(), TextureType::CubeMap); + case GL_LIGHTING: + return mGLES1State.mLightingEnabled; + case GL_LIGHT0: + case GL_LIGHT1: + case GL_LIGHT2: + case GL_LIGHT3: + case GL_LIGHT4: + case GL_LIGHT5: + case GL_LIGHT6: + case GL_LIGHT7: + return mGLES1State.mLights[feature - GL_LIGHT0].enabled; + case GL_NORMALIZE: + return mGLES1State.mNormalizeEnabled; + case GL_RESCALE_NORMAL: + return mGLES1State.mRescaleNormalEnabled; + case GL_COLOR_MATERIAL: + return mGLES1State.mColorMaterialEnabled; + case GL_CLIP_PLANE0: + case GL_CLIP_PLANE1: + case GL_CLIP_PLANE2: + case GL_CLIP_PLANE3: + case GL_CLIP_PLANE4: + case GL_CLIP_PLANE5: + return mGLES1State.mClipPlanes[feature - GL_CLIP_PLANE0].enabled; + case GL_FOG: + return mGLES1State.mFogEnabled; + case GL_POINT_SMOOTH: + return mGLES1State.mPointSmoothEnabled; + case GL_LINE_SMOOTH: + return mGLES1State.mLineSmoothEnabled; + case GL_POINT_SPRITE_OES: + return mGLES1State.mPointSpriteEnabled; + case GL_COLOR_LOGIC_OP: + return mGLES1State.mLogicOpEnabled; + default: + UNREACHABLE(); + return false; + } +} + +bool State::getEnableFeatureIndexed(GLenum feature, GLuint index) const +{ + switch (feature) + { + case GL_BLEND: + return isBlendEnabledIndexed(index); + default: + UNREACHABLE(); + return false; + } +} + +void State::setLineWidth(GLfloat width) +{ + mLineWidth = width; + mDirtyBits.set(DIRTY_BIT_LINE_WIDTH); +} + +void State::setGenerateMipmapHint(GLenum hint) +{ + mGenerateMipmapHint = hint; + mDirtyBits.set(DIRTY_BIT_EXTENDED); + mExtendedDirtyBits.set(EXTENDED_DIRTY_BIT_MIPMAP_GENERATION_HINT); +} + +GLenum State::getGenerateMipmapHint() const +{ + return mGenerateMipmapHint; +} + +void State::setTextureFilteringHint(GLenum hint) +{ + mTextureFilteringHint = hint; + // Note: we don't add a dirty bit for this flag as it's not expected to be toggled at + // runtime. +} + +GLenum State::getTextureFilteringHint() const +{ + return mTextureFilteringHint; +} + +void State::setFragmentShaderDerivativeHint(GLenum hint) +{ + mFragmentShaderDerivativeHint = hint; + mDirtyBits.set(DIRTY_BIT_EXTENDED); + mExtendedDirtyBits.set(EXTENDED_DIRTY_BIT_SHADER_DERIVATIVE_HINT); + // TODO: Propagate the hint to shader translator so we can write + // ddx, ddx_coarse, or ddx_fine depending on the hint. + // Ignore for now. It is valid for implementations to ignore hint. +} + +void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height) +{ + // [OpenGL ES 2.0.25] section 2.12.1 page 45: + // Viewport width and height are clamped to implementation-dependent maximums when specified. + width = std::min(width, mCaps.maxViewportWidth); + height = std::min(height, mCaps.maxViewportHeight); + + // Skip if same viewport info + if (mViewport.x != x || mViewport.y != y || mViewport.width != width || + mViewport.height != height) + { + mViewport.x = x; + mViewport.y = y; + mViewport.width = width; + mViewport.height = height; + mDirtyBits.set(DIRTY_BIT_VIEWPORT); + } +} + +void State::setActiveSampler(unsigned int active) +{ + mActiveSampler = active; +} + +void State::setSamplerTexture(const Context *context, TextureType type, Texture *texture) +{ + if (mExecutable && mExecutable->getActiveSamplersMask()[mActiveSampler] && + IsTextureCompatibleWithSampler(type, mExecutable->getActiveSamplerTypes()[mActiveSampler])) + { + updateTextureBinding(context, mActiveSampler, texture); + } + + mSamplerTextures[type][mActiveSampler].set(context, texture); + + mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS); +} + +Texture *State::getTargetTexture(TextureType type) const +{ + return getSamplerTexture(static_cast(mActiveSampler), type); +} + +TextureID State::getSamplerTextureId(unsigned int sampler, TextureType type) const +{ + ASSERT(sampler < mSamplerTextures[type].size()); + return mSamplerTextures[type][sampler].id(); +} + +void State::detachTexture(const Context *context, const TextureMap &zeroTextures, TextureID texture) +{ + // Textures have a detach method on State rather than a simple + // removeBinding, because the zero/null texture objects are managed + // separately, and don't have to go through the Context's maps or + // the ResourceManager. + + // [OpenGL ES 2.0.24] section 3.8 page 84: + // If a texture object is deleted, it is as if all texture units which are bound to that texture + // object are rebound to texture object zero + + for (TextureType type : angle::AllEnums()) + { + TextureBindingVector &textureVector = mSamplerTextures[type]; + + for (size_t bindingIndex = 0; bindingIndex < textureVector.size(); ++bindingIndex) + { + BindingPointer &binding = textureVector[bindingIndex]; + if (binding.id() == texture) + { + // Zero textures are the "default" textures instead of NULL + Texture *zeroTexture = zeroTextures[type].get(); + ASSERT(zeroTexture != nullptr); + if (mCompleteTextureBindings[bindingIndex].getSubject() == binding.get()) + { + updateTextureBinding(context, bindingIndex, zeroTexture); + } + binding.set(context, zeroTexture); + } + } + } + + for (auto &bindingImageUnit : mImageUnits) + { + if (bindingImageUnit.texture.id() == texture) + { + bindingImageUnit.texture.set(context, nullptr); + bindingImageUnit.level = 0; + bindingImageUnit.layered = false; + bindingImageUnit.layer = 0; + bindingImageUnit.access = GL_READ_ONLY; + bindingImageUnit.format = GL_R32UI; + } + } + + // [OpenGL ES 2.0.24] section 4.4 page 112: + // If a texture object is deleted while its image is attached to the currently bound + // framebuffer, then it is as if Texture2DAttachment had been called, with a texture of 0, for + // each attachment point to which this image was attached in the currently bound framebuffer. + + if (mReadFramebuffer && mReadFramebuffer->detachTexture(context, texture)) + { + mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER); + } + + if (mDrawFramebuffer && mDrawFramebuffer->detachTexture(context, texture)) + { + setDrawFramebufferDirty(); + } +} + +void State::initializeZeroTextures(const Context *context, const TextureMap &zeroTextures) +{ + for (TextureType type : angle::AllEnums()) + { + for (size_t textureUnit = 0; textureUnit < mSamplerTextures[type].size(); ++textureUnit) + { + mSamplerTextures[type][textureUnit].set(context, zeroTextures[type].get()); + } + } +} + +void State::invalidateTextureBindings(TextureType type) +{ + mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS); +} + +void State::setSamplerBinding(const Context *context, GLuint textureUnit, Sampler *sampler) +{ + if (mSamplers[textureUnit].get() == sampler) + { + return; + } + + mSamplers[textureUnit].set(context, sampler); + mDirtyBits.set(DIRTY_BIT_SAMPLER_BINDINGS); + // This is overly conservative as it assumes the sampler has never been bound. + setSamplerDirty(textureUnit); + onActiveTextureChange(context, textureUnit); +} + +void State::detachSampler(const Context *context, SamplerID sampler) +{ + // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124: + // If a sampler object that is currently bound to one or more texture units is + // deleted, it is as though BindSampler is called once for each texture unit to + // which the sampler is bound, with unit set to the texture unit and sampler set to zero. + for (size_t i = 0; i < mSamplers.size(); i++) + { + if (mSamplers[i].id() == sampler) + { + setSamplerBinding(context, static_cast(i), nullptr); + } + } +} + +void State::setRenderbufferBinding(const Context *context, Renderbuffer *renderbuffer) +{ + mRenderbuffer.set(context, renderbuffer); + mDirtyBits.set(DIRTY_BIT_RENDERBUFFER_BINDING); +} + +void State::detachRenderbuffer(const Context *context, RenderbufferID renderbuffer) +{ + // [OpenGL ES 2.0.24] section 4.4 page 109: + // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though + // BindRenderbuffer had been executed with the target RENDERBUFFER and name of zero. + + if (mRenderbuffer.id() == renderbuffer) + { + setRenderbufferBinding(context, nullptr); + } + + // [OpenGL ES 2.0.24] section 4.4 page 111: + // If a renderbuffer object is deleted while its image is attached to the currently bound + // framebuffer, then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of + // 0, for each attachment point to which this image was attached in the currently bound + // framebuffer. + + Framebuffer *readFramebuffer = mReadFramebuffer; + Framebuffer *drawFramebuffer = mDrawFramebuffer; + + if (readFramebuffer && readFramebuffer->detachRenderbuffer(context, renderbuffer)) + { + mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER); + } + + if (drawFramebuffer && drawFramebuffer != readFramebuffer) + { + if (drawFramebuffer->detachRenderbuffer(context, renderbuffer)) + { + setDrawFramebufferDirty(); + } + } +} + +void State::setReadFramebufferBinding(Framebuffer *framebuffer) +{ + if (mReadFramebuffer == framebuffer) + return; + + mReadFramebuffer = framebuffer; + mDirtyBits.set(DIRTY_BIT_READ_FRAMEBUFFER_BINDING); + + if (mReadFramebuffer && mReadFramebuffer->hasAnyDirtyBit()) + { + mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER); + } +} + +void State::setDrawFramebufferBinding(Framebuffer *framebuffer) +{ + if (mDrawFramebuffer == framebuffer) + return; + + mDrawFramebuffer = framebuffer; + mDirtyBits.set(DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING); + + if (mDrawFramebuffer) + { + mDrawFramebuffer->setWriteControlMode(getFramebufferSRGB() ? SrgbWriteControlMode::Default + : SrgbWriteControlMode::Linear); + + if (mDrawFramebuffer->hasAnyDirtyBit()) + { + mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER); + } + + if (mRobustResourceInit && mDrawFramebuffer->hasResourceThatNeedsInit()) + { + mDirtyObjects.set(DIRTY_OBJECT_DRAW_ATTACHMENTS); + } + } +} + +Framebuffer *State::getTargetFramebuffer(GLenum target) const +{ + switch (target) + { + case GL_READ_FRAMEBUFFER_ANGLE: + return mReadFramebuffer; + case GL_DRAW_FRAMEBUFFER_ANGLE: + case GL_FRAMEBUFFER: + return mDrawFramebuffer; + default: + UNREACHABLE(); + return nullptr; + } +} + +Framebuffer *State::getDefaultFramebuffer() const +{ + return mFramebufferManager->getDefaultFramebuffer(); +} + +bool State::removeReadFramebufferBinding(FramebufferID framebuffer) +{ + if (mReadFramebuffer != nullptr && mReadFramebuffer->id() == framebuffer) + { + setReadFramebufferBinding(nullptr); + return true; + } + + return false; +} + +bool State::removeDrawFramebufferBinding(FramebufferID framebuffer) +{ + if (mReadFramebuffer != nullptr && mDrawFramebuffer->id() == framebuffer) + { + setDrawFramebufferBinding(nullptr); + return true; + } + + return false; +} + +void State::setVertexArrayBinding(const Context *context, VertexArray *vertexArray) +{ + if (mVertexArray == vertexArray) + { + return; + } + + if (mVertexArray) + { + mVertexArray->onBindingChanged(context, -1); + } + if (vertexArray) + { + vertexArray->onBindingChanged(context, 1); + } + + mVertexArray = vertexArray; + mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING); + + if (mVertexArray && mVertexArray->hasAnyDirtyBit()) + { + mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY); + } +} + +bool State::removeVertexArrayBinding(const Context *context, VertexArrayID vertexArray) +{ + if (mVertexArray && mVertexArray->id().value == vertexArray.value) + { + mVertexArray->onBindingChanged(context, -1); + mVertexArray = nullptr; + mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING); + mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY); + return true; + } + + return false; +} + +VertexArrayID State::getVertexArrayId() const +{ + ASSERT(mVertexArray != nullptr); + return mVertexArray->id(); +} + +void State::bindVertexBuffer(const Context *context, + GLuint bindingIndex, + Buffer *boundBuffer, + GLintptr offset, + GLsizei stride) +{ + getVertexArray()->bindVertexBuffer(context, bindingIndex, boundBuffer, offset, stride); + mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY); +} + +void State::setVertexAttribFormat(GLuint attribIndex, + GLint size, + VertexAttribType type, + bool normalized, + bool pureInteger, + GLuint relativeOffset) +{ + getVertexArray()->setVertexAttribFormat(attribIndex, size, type, normalized, pureInteger, + relativeOffset); + mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY); +} + +void State::setVertexBindingDivisor(const Context *context, GLuint bindingIndex, GLuint divisor) +{ + getVertexArray()->setVertexBindingDivisor(context, bindingIndex, divisor); + mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY); +} + +angle::Result State::setProgram(const Context *context, Program *newProgram) +{ + if (newProgram && !newProgram->isLinked()) + { + // Protect against applications that disable validation and try to use a program that was + // not successfully linked. + WARN() << "Attempted to use a program that was not successfully linked"; + return angle::Result::Continue; + } + + if (mProgram != newProgram) + { + if (mProgram) + { + unsetActiveTextures(mExecutable->getActiveSamplersMask()); + mProgram->release(context); + } + + mProgram = newProgram; + mExecutable = nullptr; + + if (mProgram) + { + mExecutable = &mProgram->getExecutable(); + newProgram->addRef(); + ANGLE_TRY(onProgramExecutableChange(context, newProgram)); + } + else if (mProgramPipeline.get()) + { + mExecutable = &mProgramPipeline->getExecutable(); + ANGLE_TRY(onProgramPipelineExecutableChange(context)); + } + + // Note that rendering is undefined if glUseProgram(0) is called. But ANGLE will generate + // an error if the app tries to draw in this case. + + mDirtyBits.set(DIRTY_BIT_PROGRAM_BINDING); + } + + return angle::Result::Continue; +} + +void State::setTransformFeedbackBinding(const Context *context, + TransformFeedback *transformFeedback) +{ + if (transformFeedback == mTransformFeedback.get()) + return; + if (mTransformFeedback.get()) + mTransformFeedback->onBindingChanged(context, false); + mTransformFeedback.set(context, transformFeedback); + if (mTransformFeedback.get()) + mTransformFeedback->onBindingChanged(context, true); + mDirtyBits.set(DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING); +} + +bool State::removeTransformFeedbackBinding(const Context *context, + TransformFeedbackID transformFeedback) +{ + if (mTransformFeedback.id() == transformFeedback) + { + if (mTransformFeedback.get()) + mTransformFeedback->onBindingChanged(context, false); + mTransformFeedback.set(context, nullptr); + return true; + } + + return false; +} + +angle::Result State::setProgramPipelineBinding(const Context *context, ProgramPipeline *pipeline) +{ + if (mProgramPipeline.get() == pipeline) + { + return angle::Result::Continue; + } + + if (mProgramPipeline.get()) + { + unsetActiveTextures(mProgramPipeline->getExecutable().getActiveSamplersMask()); + } + + mProgramPipeline.set(context, pipeline); + mDirtyBits.set(DIRTY_BIT_PROGRAM_BINDING); + + // A bound Program always overrides the ProgramPipeline, so only update the + // current ProgramExecutable if there isn't currently a Program bound. + if (!mProgram) + { + if (mProgramPipeline.get()) + { + mExecutable = &mProgramPipeline->getExecutable(); + ANGLE_TRY(onProgramPipelineExecutableChange(context)); + } + else + { + mExecutable = nullptr; + } + } + + return angle::Result::Continue; +} + +void State::detachProgramPipeline(const Context *context, ProgramPipelineID pipeline) +{ + mProgramPipeline.set(context, nullptr); + + // A bound Program always overrides the ProgramPipeline, so only update the + // current ProgramExecutable if there isn't currently a Program bound. + if (!mProgram) + { + mExecutable = nullptr; + } +} + +bool State::isQueryActive(QueryType type) const +{ + const Query *query = mActiveQueries[type].get(); + if (query != nullptr) + { + return true; + } + + QueryType alternativeType; + if (GetAlternativeQueryType(type, &alternativeType)) + { + query = mActiveQueries[alternativeType].get(); + return query != nullptr; + } + + return false; +} + +bool State::isQueryActive(Query *query) const +{ + for (auto &queryPointer : mActiveQueries) + { + if (queryPointer.get() == query) + { + return true; + } + } + + return false; +} + +void State::setActiveQuery(const Context *context, QueryType type, Query *query) +{ + mActiveQueries[type].set(context, query); +} + +QueryID State::getActiveQueryId(QueryType type) const +{ + const Query *query = getActiveQuery(type); + if (query) + { + return query->id(); + } + return {0}; +} + +Query *State::getActiveQuery(QueryType type) const +{ + return mActiveQueries[type].get(); +} + +angle::Result State::setIndexedBufferBinding(const Context *context, + BufferBinding target, + GLuint index, + Buffer *buffer, + GLintptr offset, + GLsizeiptr size) +{ + setBufferBinding(context, target, buffer); + + switch (target) + { + case BufferBinding::TransformFeedback: + ANGLE_TRY(mTransformFeedback->bindIndexedBuffer(context, index, buffer, offset, size)); + setBufferBinding(context, target, buffer); + break; + case BufferBinding::Uniform: + mBoundUniformBuffersMask.set(index, buffer != nullptr); + UpdateIndexedBufferBinding(context, &mUniformBuffers[index], buffer, target, offset, + size); + break; + case BufferBinding::AtomicCounter: + mBoundAtomicCounterBuffersMask.set(index, buffer != nullptr); + UpdateIndexedBufferBinding(context, &mAtomicCounterBuffers[index], buffer, target, + offset, size); + break; + case BufferBinding::ShaderStorage: + mBoundShaderStorageBuffersMask.set(index, buffer != nullptr); + UpdateIndexedBufferBinding(context, &mShaderStorageBuffers[index], buffer, target, + offset, size); + break; + default: + UNREACHABLE(); + break; + } + + return angle::Result::Continue; +} + +const OffsetBindingPointer &State::getIndexedUniformBuffer(size_t index) const +{ + ASSERT(index < mUniformBuffers.size()); + return mUniformBuffers[index]; +} + +const OffsetBindingPointer &State::getIndexedAtomicCounterBuffer(size_t index) const +{ + ASSERT(index < mAtomicCounterBuffers.size()); + return mAtomicCounterBuffers[index]; +} + +const OffsetBindingPointer &State::getIndexedShaderStorageBuffer(size_t index) const +{ + ASSERT(index < mShaderStorageBuffers.size()); + return mShaderStorageBuffers[index]; +} + +angle::Result State::detachBuffer(Context *context, const Buffer *buffer) +{ + BufferID bufferID = buffer->id(); + for (gl::BufferBinding target : angle::AllEnums()) + { + if (mBoundBuffers[target].id() == bufferID) + { + UpdateBufferBinding(context, &mBoundBuffers[target], nullptr, target); + } + } + + TransformFeedback *curTransformFeedback = getCurrentTransformFeedback(); + if (curTransformFeedback) + { + ANGLE_TRY(curTransformFeedback->detachBuffer(context, bufferID)); + context->getStateCache().onActiveTransformFeedbackChange(context); + } + + if (getVertexArray()->detachBuffer(context, bufferID)) + { + mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY); + context->getStateCache().onVertexArrayStateChange(context); + } + + for (size_t uniformBufferIndex : mBoundUniformBuffersMask) + { + OffsetBindingPointer &binding = mUniformBuffers[uniformBufferIndex]; + + if (binding.id() == bufferID) + { + UpdateIndexedBufferBinding(context, &binding, nullptr, BufferBinding::Uniform, 0, 0); + mBoundUniformBuffersMask.reset(uniformBufferIndex); + } + } + + for (size_t atomicCounterBufferIndex : mBoundAtomicCounterBuffersMask) + { + OffsetBindingPointer &binding = mAtomicCounterBuffers[atomicCounterBufferIndex]; + + if (binding.id() == bufferID) + { + UpdateIndexedBufferBinding(context, &binding, nullptr, BufferBinding::AtomicCounter, 0, + 0); + mBoundAtomicCounterBuffersMask.reset(atomicCounterBufferIndex); + } + } + + for (size_t shaderStorageBufferIndex : mBoundShaderStorageBuffersMask) + { + OffsetBindingPointer &binding = mShaderStorageBuffers[shaderStorageBufferIndex]; + + if (binding.id() == bufferID) + { + UpdateIndexedBufferBinding(context, &binding, nullptr, BufferBinding::ShaderStorage, 0, + 0); + mBoundShaderStorageBuffersMask.reset(shaderStorageBufferIndex); + } + } + + return angle::Result::Continue; +} + +void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled) +{ + getVertexArray()->enableAttribute(attribNum, enabled); + mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY); +} + +void State::setVertexAttribf(GLuint index, const GLfloat values[4]) +{ + ASSERT(static_cast(index) < mVertexAttribCurrentValues.size()); + mVertexAttribCurrentValues[index].setFloatValues(values); + mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES); + mDirtyCurrentValues.set(index); + SetComponentTypeMask(ComponentType::Float, index, &mCurrentValuesTypeMask); +} + +void State::setVertexAttribu(GLuint index, const GLuint values[4]) +{ + ASSERT(static_cast(index) < mVertexAttribCurrentValues.size()); + mVertexAttribCurrentValues[index].setUnsignedIntValues(values); + mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES); + mDirtyCurrentValues.set(index); + SetComponentTypeMask(ComponentType::UnsignedInt, index, &mCurrentValuesTypeMask); +} + +void State::setVertexAttribi(GLuint index, const GLint values[4]) +{ + ASSERT(static_cast(index) < mVertexAttribCurrentValues.size()); + mVertexAttribCurrentValues[index].setIntValues(values); + mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES); + mDirtyCurrentValues.set(index); + SetComponentTypeMask(ComponentType::Int, index, &mCurrentValuesTypeMask); +} + +void State::setVertexAttribDivisor(const Context *context, GLuint index, GLuint divisor) +{ + getVertexArray()->setVertexAttribDivisor(context, index, divisor); + mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY); +} + +const void *State::getVertexAttribPointer(unsigned int attribNum) const +{ + return getVertexArray()->getVertexAttribute(attribNum).pointer; +} + +void State::setPackAlignment(GLint alignment) +{ + mPack.alignment = alignment; + mDirtyBits.set(DIRTY_BIT_PACK_STATE); +} + +void State::setPackReverseRowOrder(bool reverseRowOrder) +{ + mPack.reverseRowOrder = reverseRowOrder; + mDirtyBits.set(DIRTY_BIT_PACK_STATE); +} + +void State::setPackRowLength(GLint rowLength) +{ + mPack.rowLength = rowLength; + mDirtyBits.set(DIRTY_BIT_PACK_STATE); +} + +void State::setPackSkipRows(GLint skipRows) +{ + mPack.skipRows = skipRows; + mDirtyBits.set(DIRTY_BIT_PACK_STATE); +} + +void State::setPackSkipPixels(GLint skipPixels) +{ + mPack.skipPixels = skipPixels; + mDirtyBits.set(DIRTY_BIT_PACK_STATE); +} + +void State::setUnpackAlignment(GLint alignment) +{ + mUnpack.alignment = alignment; + mDirtyBits.set(DIRTY_BIT_UNPACK_STATE); +} + +void State::setUnpackRowLength(GLint rowLength) +{ + mUnpack.rowLength = rowLength; + mDirtyBits.set(DIRTY_BIT_UNPACK_STATE); +} + +void State::setUnpackImageHeight(GLint imageHeight) +{ + mUnpack.imageHeight = imageHeight; + mDirtyBits.set(DIRTY_BIT_UNPACK_STATE); +} + +void State::setUnpackSkipImages(GLint skipImages) +{ + mUnpack.skipImages = skipImages; + mDirtyBits.set(DIRTY_BIT_UNPACK_STATE); +} + +void State::setUnpackSkipRows(GLint skipRows) +{ + mUnpack.skipRows = skipRows; + mDirtyBits.set(DIRTY_BIT_UNPACK_STATE); +} + +void State::setUnpackSkipPixels(GLint skipPixels) +{ + mUnpack.skipPixels = skipPixels; + mDirtyBits.set(DIRTY_BIT_UNPACK_STATE); +} + +void State::setCoverageModulation(GLenum components) +{ + if (mCoverageModulation != components) + { + mCoverageModulation = components; + mDirtyBits.set(DIRTY_BIT_COVERAGE_MODULATION); + } +} + +void State::setFramebufferSRGB(bool sRGB) +{ + if (mFramebufferSRGB != sRGB) + { + mFramebufferSRGB = sRGB; + mDirtyBits.set(DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE); + setDrawFramebufferDirty(); + } +} + +void State::setMaxShaderCompilerThreads(GLuint count) +{ + mMaxShaderCompilerThreads = count; +} + +void State::setPatchVertices(GLuint value) +{ + if (mPatchVertices != value) + { + mPatchVertices = value; + mDirtyBits.set(DIRTY_BIT_PATCH_VERTICES); + } +} + +void State::setPixelLocalStorageActive(bool active) +{ + mPixelLocalStorageActive = active; +} + +void State::setShadingRate(GLenum rate) +{ + mShadingRate = FromGLenum(rate); + mDirtyBits.set(DIRTY_BIT_EXTENDED); + mExtendedDirtyBits.set(EXTENDED_DIRTY_BIT_SHADING_RATE); +} + +void State::getBooleanv(GLenum pname, GLboolean *params) const +{ + switch (pname) + { + case GL_SAMPLE_COVERAGE_INVERT: + *params = mSampleCoverageInvert; + break; + case GL_DEPTH_WRITEMASK: + *params = mDepthStencil.depthMask; + break; + case GL_COLOR_WRITEMASK: + { + // non-indexed get returns the state of draw buffer zero + bool r, g, b, a; + mBlendStateExt.getColorMaskIndexed(0, &r, &g, &b, &a); + params[0] = r; + params[1] = g; + params[2] = b; + params[3] = a; + break; + } + case GL_CULL_FACE: + *params = mRasterizer.cullFace; + break; + case GL_POLYGON_OFFSET_FILL: + *params = mRasterizer.polygonOffsetFill; + break; + case GL_SAMPLE_ALPHA_TO_COVERAGE: + *params = mSampleAlphaToCoverage; + break; + case GL_SAMPLE_COVERAGE: + *params = mSampleCoverage; + break; + case GL_SAMPLE_MASK: + *params = mSampleMask; + break; + case GL_SCISSOR_TEST: + *params = mScissorTest; + break; + case GL_STENCIL_TEST: + *params = mDepthStencil.stencilTest; + break; + case GL_DEPTH_TEST: + *params = mDepthStencil.depthTest; + break; + case GL_BLEND: + // non-indexed get returns the state of draw buffer zero + *params = mBlendStateExt.getEnabledMask().test(0); + break; + case GL_DITHER: + *params = mRasterizer.dither; + break; + case GL_COLOR_LOGIC_OP: + ASSERT(mClientVersion.major > 1); + *params = mLogicOpEnabled; + break; + case GL_TRANSFORM_FEEDBACK_ACTIVE: + *params = getCurrentTransformFeedback()->isActive() ? GL_TRUE : GL_FALSE; + break; + case GL_TRANSFORM_FEEDBACK_PAUSED: + *params = getCurrentTransformFeedback()->isPaused() ? GL_TRUE : GL_FALSE; + break; + case GL_PRIMITIVE_RESTART_FIXED_INDEX: + *params = mPrimitiveRestart; + break; + case GL_RASTERIZER_DISCARD: + *params = isRasterizerDiscardEnabled() ? GL_TRUE : GL_FALSE; + break; + case GL_DEBUG_OUTPUT_SYNCHRONOUS: + *params = mDebug.isOutputSynchronous() ? GL_TRUE : GL_FALSE; + break; + case GL_DEBUG_OUTPUT: + *params = mDebug.isOutputEnabled() ? GL_TRUE : GL_FALSE; + break; + case GL_MULTISAMPLE_EXT: + *params = mMultiSampling; + break; + case GL_SAMPLE_ALPHA_TO_ONE_EXT: + *params = mSampleAlphaToOne; + break; + case GL_BIND_GENERATES_RESOURCE_CHROMIUM: + *params = isBindGeneratesResourceEnabled() ? GL_TRUE : GL_FALSE; + break; + case GL_CLIENT_ARRAYS_ANGLE: + *params = areClientArraysEnabled() ? GL_TRUE : GL_FALSE; + break; + case GL_FRAMEBUFFER_SRGB_EXT: + *params = getFramebufferSRGB() ? GL_TRUE : GL_FALSE; + break; + case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE: + *params = mRobustResourceInit ? GL_TRUE : GL_FALSE; + break; + case GL_PROGRAM_CACHE_ENABLED_ANGLE: + *params = mProgramBinaryCacheEnabled ? GL_TRUE : GL_FALSE; + break; + case GL_TEXTURE_RECTANGLE_ANGLE: + *params = mTextureRectangleEnabled ? GL_TRUE : GL_FALSE; + break; + case GL_LIGHT_MODEL_TWO_SIDE: + *params = IsLightModelTwoSided(&mGLES1State); + break; + case GL_SAMPLE_SHADING: + *params = mIsSampleShadingEnabled; + break; + case GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED: + *params = isPrimitiveRestartEnabled() && getExtensions().tessellationShaderEXT; + break; + // 2.2.2 Data Conversions For State Query Commands, in GLES 3.2 spec. + // If a command returning boolean data is called, such as GetBooleanv, a floating-point or + // integer value converts to FALSE if and only if it is zero. Otherwise it converts to TRUE. + // GL_EXT_clip_control + case GL_CLIP_ORIGIN_EXT: + *params = GL_TRUE; + break; + case GL_CLIP_DEPTH_MODE_EXT: + *params = GL_TRUE; + break; + case GL_ROBUST_FRAGMENT_SHADER_OUTPUT_ANGLE: + *params = mExtensions.robustFragmentShaderOutputANGLE ? GL_TRUE : GL_FALSE; + break; + // GL_ANGLE_shader_pixel_local_storage + case GL_PIXEL_LOCAL_STORAGE_ACTIVE_ANGLE: + *params = mPixelLocalStorageActive ? GL_TRUE : GL_FALSE; + break; + default: + UNREACHABLE(); + break; + } +} + +void State::getFloatv(GLenum pname, GLfloat *params) const +{ + // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation + // because it is stored as a float, despite the fact that the GL ES 2.0 spec names + // GetIntegerv as its native query function. As it would require conversion in any + // case, this should make no difference to the calling application. + switch (pname) + { + case GL_LINE_WIDTH: + *params = mLineWidth; + break; + case GL_SAMPLE_COVERAGE_VALUE: + *params = mSampleCoverageValue; + break; + case GL_DEPTH_CLEAR_VALUE: + *params = mDepthClearValue; + break; + case GL_POLYGON_OFFSET_FACTOR: + *params = mRasterizer.polygonOffsetFactor; + break; + case GL_POLYGON_OFFSET_UNITS: + *params = mRasterizer.polygonOffsetUnits; + break; + case GL_DEPTH_RANGE: + params[0] = mNearZ; + params[1] = mFarZ; + break; + case GL_COLOR_CLEAR_VALUE: + params[0] = mColorClearValue.red; + params[1] = mColorClearValue.green; + params[2] = mColorClearValue.blue; + params[3] = mColorClearValue.alpha; + break; + case GL_BLEND_COLOR: + params[0] = mBlendColor.red; + params[1] = mBlendColor.green; + params[2] = mBlendColor.blue; + params[3] = mBlendColor.alpha; + break; + case GL_MULTISAMPLE_EXT: + *params = static_cast(mMultiSampling); + break; + case GL_SAMPLE_ALPHA_TO_ONE_EXT: + *params = static_cast(mSampleAlphaToOne); + break; + case GL_COVERAGE_MODULATION_CHROMIUM: + params[0] = static_cast(mCoverageModulation); + break; + case GL_ALPHA_TEST_REF: + *params = mGLES1State.mAlphaTestRef; + break; + case GL_CURRENT_COLOR: + { + const auto &color = mGLES1State.mCurrentColor; + params[0] = color.red; + params[1] = color.green; + params[2] = color.blue; + params[3] = color.alpha; + break; + } + case GL_CURRENT_NORMAL: + { + const auto &normal = mGLES1State.mCurrentNormal; + params[0] = normal[0]; + params[1] = normal[1]; + params[2] = normal[2]; + break; + } + case GL_CURRENT_TEXTURE_COORDS: + { + const auto &texcoord = mGLES1State.mCurrentTextureCoords[mActiveSampler]; + params[0] = texcoord.s; + params[1] = texcoord.t; + params[2] = texcoord.r; + params[3] = texcoord.q; + break; + } + case GL_MODELVIEW_MATRIX: + memcpy(params, mGLES1State.mModelviewMatrices.back().constData(), 16 * sizeof(GLfloat)); + break; + case GL_PROJECTION_MATRIX: + memcpy(params, mGLES1State.mProjectionMatrices.back().constData(), + 16 * sizeof(GLfloat)); + break; + case GL_TEXTURE_MATRIX: + memcpy(params, mGLES1State.mTextureMatrices[mActiveSampler].back().constData(), + 16 * sizeof(GLfloat)); + break; + case GL_LIGHT_MODEL_AMBIENT: + GetLightModelParameters(&mGLES1State, pname, params); + break; + case GL_FOG_MODE: + case GL_FOG_DENSITY: + case GL_FOG_START: + case GL_FOG_END: + case GL_FOG_COLOR: + GetFogParameters(&mGLES1State, pname, params); + break; + case GL_POINT_SIZE: + GetPointSize(&mGLES1State, params); + break; + case GL_POINT_SIZE_MIN: + case GL_POINT_SIZE_MAX: + case GL_POINT_FADE_THRESHOLD_SIZE: + case GL_POINT_DISTANCE_ATTENUATION: + GetPointParameter(&mGLES1State, FromGLenum(pname), params); + break; + case GL_MIN_SAMPLE_SHADING_VALUE: + *params = mMinSampleShading; + break; + // 2.2.2 Data Conversions For State Query Commands, in GLES 3.2 spec. + // If a command returning floating-point data is called, such as GetFloatv, ... An integer + // value is coerced to floating-point. + case GL_CLIP_ORIGIN_EXT: + *params = static_cast(mClipControlOrigin); + break; + case GL_CLIP_DEPTH_MODE_EXT: + *params = static_cast(mClipControlDepth); + break; + default: + UNREACHABLE(); + break; + } +} + +angle::Result State::getIntegerv(const Context *context, GLenum pname, GLint *params) const +{ + if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT) + { + size_t drawBuffer = (pname - GL_DRAW_BUFFER0_EXT); + ASSERT(drawBuffer < static_cast(mCaps.maxDrawBuffers)); + Framebuffer *framebuffer = mDrawFramebuffer; + // The default framebuffer may have fewer draw buffer states than a user-created one. The + // user is always allowed to query up to GL_MAX_DRAWBUFFERS so just return GL_NONE here if + // the draw buffer is out of range for this framebuffer. + *params = drawBuffer < framebuffer->getDrawbufferStateCount() + ? framebuffer->getDrawBufferState(drawBuffer) + : GL_NONE; + return angle::Result::Continue; + } + + // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation + // because it is stored as a float, despite the fact that the GL ES 2.0 spec names + // GetIntegerv as its native query function. As it would require conversion in any + // case, this should make no difference to the calling application. You may find it in + // State::getFloatv. + switch (pname) + { + case GL_ARRAY_BUFFER_BINDING: + *params = mBoundBuffers[BufferBinding::Array].id().value; + break; + case GL_DRAW_INDIRECT_BUFFER_BINDING: + *params = mBoundBuffers[BufferBinding::DrawIndirect].id().value; + break; + case GL_ELEMENT_ARRAY_BUFFER_BINDING: + { + Buffer *elementArrayBuffer = getVertexArray()->getElementArrayBuffer(); + *params = elementArrayBuffer ? elementArrayBuffer->id().value : 0; + break; + } + case GL_DRAW_FRAMEBUFFER_BINDING: + static_assert(GL_DRAW_FRAMEBUFFER_BINDING == GL_DRAW_FRAMEBUFFER_BINDING_ANGLE, + "Enum mismatch"); + *params = mDrawFramebuffer->id().value; + break; + case GL_READ_FRAMEBUFFER_BINDING: + static_assert(GL_READ_FRAMEBUFFER_BINDING == GL_READ_FRAMEBUFFER_BINDING_ANGLE, + "Enum mismatch"); + *params = mReadFramebuffer->id().value; + break; + case GL_RENDERBUFFER_BINDING: + *params = mRenderbuffer.id().value; + break; + case GL_VERTEX_ARRAY_BINDING: + *params = mVertexArray->id().value; + break; + case GL_CURRENT_PROGRAM: + *params = mProgram ? mProgram->id().value : 0; + break; + case GL_PACK_ALIGNMENT: + *params = mPack.alignment; + break; + case GL_PACK_REVERSE_ROW_ORDER_ANGLE: + *params = mPack.reverseRowOrder; + break; + case GL_PACK_ROW_LENGTH: + *params = mPack.rowLength; + break; + case GL_PACK_SKIP_ROWS: + *params = mPack.skipRows; + break; + case GL_PACK_SKIP_PIXELS: + *params = mPack.skipPixels; + break; + case GL_UNPACK_ALIGNMENT: + *params = mUnpack.alignment; + break; + case GL_UNPACK_ROW_LENGTH: + *params = mUnpack.rowLength; + break; + case GL_UNPACK_IMAGE_HEIGHT: + *params = mUnpack.imageHeight; + break; + case GL_UNPACK_SKIP_IMAGES: + *params = mUnpack.skipImages; + break; + case GL_UNPACK_SKIP_ROWS: + *params = mUnpack.skipRows; + break; + case GL_UNPACK_SKIP_PIXELS: + *params = mUnpack.skipPixels; + break; + case GL_GENERATE_MIPMAP_HINT: + *params = mGenerateMipmapHint; + break; + case GL_TEXTURE_FILTERING_HINT_CHROMIUM: + *params = mTextureFilteringHint; + break; + case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: + *params = mFragmentShaderDerivativeHint; + break; + case GL_ACTIVE_TEXTURE: + *params = (static_cast(mActiveSampler) + GL_TEXTURE0); + break; + case GL_STENCIL_FUNC: + *params = mDepthStencil.stencilFunc; + break; + case GL_STENCIL_REF: + *params = mStencilRef; + break; + case GL_STENCIL_VALUE_MASK: + *params = CastMaskValue(mDepthStencil.stencilMask); + break; + case GL_STENCIL_BACK_FUNC: + *params = mDepthStencil.stencilBackFunc; + break; + case GL_STENCIL_BACK_REF: + *params = mStencilBackRef; + break; + case GL_STENCIL_BACK_VALUE_MASK: + *params = CastMaskValue(mDepthStencil.stencilBackMask); + break; + case GL_STENCIL_FAIL: + *params = mDepthStencil.stencilFail; + break; + case GL_STENCIL_PASS_DEPTH_FAIL: + *params = mDepthStencil.stencilPassDepthFail; + break; + case GL_STENCIL_PASS_DEPTH_PASS: + *params = mDepthStencil.stencilPassDepthPass; + break; + case GL_STENCIL_BACK_FAIL: + *params = mDepthStencil.stencilBackFail; + break; + case GL_STENCIL_BACK_PASS_DEPTH_FAIL: + *params = mDepthStencil.stencilBackPassDepthFail; + break; + case GL_STENCIL_BACK_PASS_DEPTH_PASS: + *params = mDepthStencil.stencilBackPassDepthPass; + break; + case GL_DEPTH_FUNC: + *params = mDepthStencil.depthFunc; + break; + case GL_BLEND_SRC_RGB: + // non-indexed get returns the state of draw buffer zero + *params = mBlendStateExt.getSrcColorIndexed(0); + break; + case GL_BLEND_SRC_ALPHA: + *params = mBlendStateExt.getSrcAlphaIndexed(0); + break; + case GL_BLEND_DST_RGB: + *params = mBlendStateExt.getDstColorIndexed(0); + break; + case GL_BLEND_DST_ALPHA: + *params = mBlendStateExt.getDstAlphaIndexed(0); + break; + case GL_BLEND_EQUATION_RGB: + *params = mBlendStateExt.getEquationColorIndexed(0); + break; + case GL_BLEND_EQUATION_ALPHA: + *params = mBlendStateExt.getEquationAlphaIndexed(0); + break; + case GL_STENCIL_WRITEMASK: + *params = CastMaskValue(mDepthStencil.stencilWritemask); + break; + case GL_STENCIL_BACK_WRITEMASK: + *params = CastMaskValue(mDepthStencil.stencilBackWritemask); + break; + case GL_STENCIL_CLEAR_VALUE: + *params = mStencilClearValue; + break; + case GL_IMPLEMENTATION_COLOR_READ_TYPE: + *params = mReadFramebuffer->getImplementationColorReadType(context); + break; + case GL_IMPLEMENTATION_COLOR_READ_FORMAT: + *params = mReadFramebuffer->getImplementationColorReadFormat(context); + break; + case GL_SAMPLE_BUFFERS: + case GL_SAMPLES: + { + Framebuffer *framebuffer = mDrawFramebuffer; + if (framebuffer->isComplete(context)) + { + GLint samples = framebuffer->getSamples(context); + switch (pname) + { + case GL_SAMPLE_BUFFERS: + if (samples != 0) + { + *params = 1; + } + else + { + *params = 0; + } + break; + case GL_SAMPLES: + *params = samples; + break; + } + } + else + { + *params = 0; + } + } + break; + case GL_VIEWPORT: + params[0] = mViewport.x; + params[1] = mViewport.y; + params[2] = mViewport.width; + params[3] = mViewport.height; + break; + case GL_SCISSOR_BOX: + params[0] = mScissor.x; + params[1] = mScissor.y; + params[2] = mScissor.width; + params[3] = mScissor.height; + break; + case GL_CULL_FACE_MODE: + *params = ToGLenum(mRasterizer.cullMode); + break; + case GL_FRONT_FACE: + *params = mRasterizer.frontFace; + break; + case GL_RED_BITS: + case GL_GREEN_BITS: + case GL_BLUE_BITS: + case GL_ALPHA_BITS: + { + Framebuffer *framebuffer = getDrawFramebuffer(); + const FramebufferAttachment *colorbuffer = framebuffer->getFirstColorAttachment(); + + if (colorbuffer) + { + switch (pname) + { + case GL_RED_BITS: + *params = colorbuffer->getRedSize(); + break; + case GL_GREEN_BITS: + *params = colorbuffer->getGreenSize(); + break; + case GL_BLUE_BITS: + *params = colorbuffer->getBlueSize(); + break; + case GL_ALPHA_BITS: + *params = colorbuffer->getAlphaSize(); + break; + } + } + else + { + *params = 0; + } + } + break; + case GL_DEPTH_BITS: + { + const Framebuffer *framebuffer = getDrawFramebuffer(); + const FramebufferAttachment *depthbuffer = framebuffer->getDepthAttachment(); + + if (depthbuffer) + { + *params = depthbuffer->getDepthSize(); + } + else + { + *params = 0; + } + } + break; + case GL_STENCIL_BITS: + { + const Framebuffer *framebuffer = getDrawFramebuffer(); + const FramebufferAttachment *stencilbuffer = framebuffer->getStencilAttachment(); + + if (stencilbuffer) + { + *params = stencilbuffer->getStencilSize(); + } + else + { + *params = 0; + } + } + break; + case GL_TEXTURE_BINDING_2D: + ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits); + *params = + getSamplerTextureId(static_cast(mActiveSampler), TextureType::_2D) + .value; + break; + case GL_TEXTURE_BINDING_RECTANGLE_ANGLE: + ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits); + *params = getSamplerTextureId(static_cast(mActiveSampler), + TextureType::Rectangle) + .value; + break; + case GL_TEXTURE_BINDING_CUBE_MAP: + ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits); + *params = + getSamplerTextureId(static_cast(mActiveSampler), TextureType::CubeMap) + .value; + break; + case GL_TEXTURE_BINDING_3D: + ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits); + *params = + getSamplerTextureId(static_cast(mActiveSampler), TextureType::_3D) + .value; + break; + case GL_TEXTURE_BINDING_2D_ARRAY: + ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits); + *params = getSamplerTextureId(static_cast(mActiveSampler), + TextureType::_2DArray) + .value; + break; + case GL_TEXTURE_BINDING_2D_MULTISAMPLE: + ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits); + *params = getSamplerTextureId(static_cast(mActiveSampler), + TextureType::_2DMultisample) + .value; + break; + case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY: + ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits); + *params = getSamplerTextureId(static_cast(mActiveSampler), + TextureType::_2DMultisampleArray) + .value; + break; + case GL_TEXTURE_BINDING_CUBE_MAP_ARRAY: + ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits); + *params = getSamplerTextureId(static_cast(mActiveSampler), + TextureType::CubeMapArray) + .value; + break; + case GL_TEXTURE_BINDING_EXTERNAL_OES: + ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits); + *params = getSamplerTextureId(static_cast(mActiveSampler), + TextureType::External) + .value; + break; + + // GL_OES_texture_buffer + case GL_TEXTURE_BINDING_BUFFER: + ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits); + *params = + getSamplerTextureId(static_cast(mActiveSampler), TextureType::Buffer) + .value; + break; + case GL_TEXTURE_BUFFER_BINDING: + *params = mBoundBuffers[BufferBinding::Texture].id().value; + break; + + case GL_UNIFORM_BUFFER_BINDING: + *params = mBoundBuffers[BufferBinding::Uniform].id().value; + break; + case GL_TRANSFORM_FEEDBACK_BINDING: + *params = mTransformFeedback.id().value; + break; + case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: + *params = mBoundBuffers[BufferBinding::TransformFeedback].id().value; + break; + case GL_COPY_READ_BUFFER_BINDING: + *params = mBoundBuffers[BufferBinding::CopyRead].id().value; + break; + case GL_COPY_WRITE_BUFFER_BINDING: + *params = mBoundBuffers[BufferBinding::CopyWrite].id().value; + break; + case GL_PIXEL_PACK_BUFFER_BINDING: + *params = mBoundBuffers[BufferBinding::PixelPack].id().value; + break; + case GL_PIXEL_UNPACK_BUFFER_BINDING: + *params = mBoundBuffers[BufferBinding::PixelUnpack].id().value; + break; + + case GL_READ_BUFFER: + *params = mReadFramebuffer->getReadBufferState(); + break; + case GL_SAMPLER_BINDING: + ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits); + *params = getSamplerId(static_cast(mActiveSampler)).value; + break; + case GL_DEBUG_LOGGED_MESSAGES: + *params = static_cast(mDebug.getMessageCount()); + break; + case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH: + *params = static_cast(mDebug.getNextMessageLength()); + break; + case GL_DEBUG_GROUP_STACK_DEPTH: + *params = static_cast(mDebug.getGroupStackDepth()); + break; + case GL_MULTISAMPLE_EXT: + *params = static_cast(mMultiSampling); + break; + case GL_SAMPLE_ALPHA_TO_ONE_EXT: + *params = static_cast(mSampleAlphaToOne); + break; + case GL_COVERAGE_MODULATION_CHROMIUM: + *params = static_cast(mCoverageModulation); + break; + case GL_ATOMIC_COUNTER_BUFFER_BINDING: + *params = mBoundBuffers[BufferBinding::AtomicCounter].id().value; + break; + case GL_SHADER_STORAGE_BUFFER_BINDING: + *params = mBoundBuffers[BufferBinding::ShaderStorage].id().value; + break; + case GL_DISPATCH_INDIRECT_BUFFER_BINDING: + *params = mBoundBuffers[BufferBinding::DispatchIndirect].id().value; + break; + case GL_ALPHA_TEST_FUNC: + *params = ToGLenum(mGLES1State.mAlphaTestFunc); + break; + case GL_CLIENT_ACTIVE_TEXTURE: + *params = mGLES1State.mClientActiveTexture + GL_TEXTURE0; + break; + case GL_MATRIX_MODE: + *params = ToGLenum(mGLES1State.mMatrixMode); + break; + case GL_SHADE_MODEL: + *params = ToGLenum(mGLES1State.mShadeModel); + break; + case GL_MODELVIEW_STACK_DEPTH: + case GL_PROJECTION_STACK_DEPTH: + case GL_TEXTURE_STACK_DEPTH: + *params = mGLES1State.getCurrentMatrixStackDepth(pname); + break; + case GL_LOGIC_OP_MODE: + *params = ToGLenum(mGLES1State.mLogicOp); + break; + case GL_BLEND_SRC: + // non-indexed get returns the state of draw buffer zero + *params = mBlendStateExt.getSrcColorIndexed(0); + break; + case GL_BLEND_DST: + *params = mBlendStateExt.getDstColorIndexed(0); + break; + case GL_PERSPECTIVE_CORRECTION_HINT: + case GL_POINT_SMOOTH_HINT: + case GL_LINE_SMOOTH_HINT: + case GL_FOG_HINT: + *params = mGLES1State.getHint(pname); + break; + + // GL_ANGLE_provoking_vertex + case GL_PROVOKING_VERTEX: + *params = ToGLenum(mProvokingVertex); + break; + + case GL_PROGRAM_PIPELINE_BINDING: + { + ProgramPipeline *pipeline = getProgramPipeline(); + if (pipeline) + { + *params = pipeline->id().value; + } + else + { + *params = 0; + } + break; + } + case GL_PATCH_VERTICES: + *params = mPatchVertices; + break; + + // GL_EXT_clip_control + case GL_CLIP_ORIGIN_EXT: + *params = mClipControlOrigin; + break; + case GL_CLIP_DEPTH_MODE_EXT: + *params = mClipControlDepth; + break; + + // GL_QCOM_shading_rate + case GL_SHADING_RATE_QCOM: + *params = ToGLenum(mShadingRate); + break; + + default: + UNREACHABLE(); + break; + } + + return angle::Result::Continue; +} + +void State::getPointerv(const Context *context, GLenum pname, void **params) const +{ + switch (pname) + { + case GL_DEBUG_CALLBACK_FUNCTION: + *params = reinterpret_cast(mDebug.getCallback()); + break; + case GL_DEBUG_CALLBACK_USER_PARAM: + *params = const_cast(mDebug.getUserParam()); + break; + case GL_VERTEX_ARRAY_POINTER: + case GL_NORMAL_ARRAY_POINTER: + case GL_COLOR_ARRAY_POINTER: + case GL_TEXTURE_COORD_ARRAY_POINTER: + case GL_POINT_SIZE_ARRAY_POINTER_OES: + QueryVertexAttribPointerv(getVertexArray()->getVertexAttribute( + context->vertexArrayIndex(ParamToVertexArrayType(pname))), + GL_VERTEX_ATTRIB_ARRAY_POINTER, params); + return; + default: + UNREACHABLE(); + break; + } +} + +void State::getIntegeri_v(const Context *context, GLenum target, GLuint index, GLint *data) const +{ + switch (target) + { + case GL_BLEND_SRC_RGB: + ASSERT(static_cast(index) < mBlendStateExt.getDrawBufferCount()); + *data = mBlendStateExt.getSrcColorIndexed(index); + break; + case GL_BLEND_SRC_ALPHA: + ASSERT(static_cast(index) < mBlendStateExt.getDrawBufferCount()); + *data = mBlendStateExt.getSrcAlphaIndexed(index); + break; + case GL_BLEND_DST_RGB: + ASSERT(static_cast(index) < mBlendStateExt.getDrawBufferCount()); + *data = mBlendStateExt.getDstColorIndexed(index); + break; + case GL_BLEND_DST_ALPHA: + ASSERT(static_cast(index) < mBlendStateExt.getDrawBufferCount()); + *data = mBlendStateExt.getDstAlphaIndexed(index); + break; + case GL_BLEND_EQUATION_RGB: + ASSERT(static_cast(index) < mBlendStateExt.getDrawBufferCount()); + *data = mBlendStateExt.getEquationColorIndexed(index); + break; + case GL_BLEND_EQUATION_ALPHA: + ASSERT(static_cast(index) < mBlendStateExt.getDrawBufferCount()); + *data = mBlendStateExt.getEquationAlphaIndexed(index); + break; + case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: + ASSERT(static_cast(index) < mTransformFeedback->getIndexedBufferCount()); + *data = mTransformFeedback->getIndexedBuffer(index).id().value; + break; + case GL_UNIFORM_BUFFER_BINDING: + ASSERT(static_cast(index) < mUniformBuffers.size()); + *data = mUniformBuffers[index].id().value; + break; + case GL_ATOMIC_COUNTER_BUFFER_BINDING: + ASSERT(static_cast(index) < mAtomicCounterBuffers.size()); + *data = mAtomicCounterBuffers[index].id().value; + break; + case GL_SHADER_STORAGE_BUFFER_BINDING: + ASSERT(static_cast(index) < mShaderStorageBuffers.size()); + *data = mShaderStorageBuffers[index].id().value; + break; + case GL_VERTEX_BINDING_BUFFER: + ASSERT(static_cast(index) < mVertexArray->getMaxBindings()); + *data = mVertexArray->getVertexBinding(index).getBuffer().id().value; + break; + case GL_VERTEX_BINDING_DIVISOR: + ASSERT(static_cast(index) < mVertexArray->getMaxBindings()); + *data = mVertexArray->getVertexBinding(index).getDivisor(); + break; + case GL_VERTEX_BINDING_OFFSET: + ASSERT(static_cast(index) < mVertexArray->getMaxBindings()); + *data = static_cast(mVertexArray->getVertexBinding(index).getOffset()); + break; + case GL_VERTEX_BINDING_STRIDE: + ASSERT(static_cast(index) < mVertexArray->getMaxBindings()); + *data = mVertexArray->getVertexBinding(index).getStride(); + break; + case GL_SAMPLE_MASK_VALUE: + ASSERT(static_cast(index) < mSampleMaskValues.size()); + *data = mSampleMaskValues[index]; + break; + case GL_IMAGE_BINDING_NAME: + ASSERT(static_cast(index) < mImageUnits.size()); + *data = mImageUnits[index].texture.id().value; + break; + case GL_IMAGE_BINDING_LEVEL: + ASSERT(static_cast(index) < mImageUnits.size()); + *data = mImageUnits[index].level; + break; + case GL_IMAGE_BINDING_LAYER: + ASSERT(static_cast(index) < mImageUnits.size()); + *data = mImageUnits[index].layer; + break; + case GL_IMAGE_BINDING_ACCESS: + ASSERT(static_cast(index) < mImageUnits.size()); + *data = mImageUnits[index].access; + break; + case GL_IMAGE_BINDING_FORMAT: + ASSERT(static_cast(index) < mImageUnits.size()); + *data = mImageUnits[index].format; + break; + // GL_ANGLE_shader_pixel_local_storage. + case GL_PIXEL_LOCAL_FORMAT_ANGLE: + case GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE: + case GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE: + case GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE: + { + ASSERT(mDrawFramebuffer); + *data = mDrawFramebuffer->getPixelLocalStorage(context).getPlane(index).getIntegeri( + context, target, index); + break; + } + default: + UNREACHABLE(); + break; + } +} + +void State::getInteger64i_v(GLenum target, GLuint index, GLint64 *data) const +{ + switch (target) + { + case GL_TRANSFORM_FEEDBACK_BUFFER_START: + ASSERT(static_cast(index) < mTransformFeedback->getIndexedBufferCount()); + *data = mTransformFeedback->getIndexedBuffer(index).getOffset(); + break; + case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: + ASSERT(static_cast(index) < mTransformFeedback->getIndexedBufferCount()); + *data = mTransformFeedback->getIndexedBuffer(index).getSize(); + break; + case GL_UNIFORM_BUFFER_START: + ASSERT(static_cast(index) < mUniformBuffers.size()); + *data = mUniformBuffers[index].getOffset(); + break; + case GL_UNIFORM_BUFFER_SIZE: + ASSERT(static_cast(index) < mUniformBuffers.size()); + *data = mUniformBuffers[index].getSize(); + break; + case GL_ATOMIC_COUNTER_BUFFER_START: + ASSERT(static_cast(index) < mAtomicCounterBuffers.size()); + *data = mAtomicCounterBuffers[index].getOffset(); + break; + case GL_ATOMIC_COUNTER_BUFFER_SIZE: + ASSERT(static_cast(index) < mAtomicCounterBuffers.size()); + *data = mAtomicCounterBuffers[index].getSize(); + break; + case GL_SHADER_STORAGE_BUFFER_START: + ASSERT(static_cast(index) < mShaderStorageBuffers.size()); + *data = mShaderStorageBuffers[index].getOffset(); + break; + case GL_SHADER_STORAGE_BUFFER_SIZE: + ASSERT(static_cast(index) < mShaderStorageBuffers.size()); + *data = mShaderStorageBuffers[index].getSize(); + break; + default: + UNREACHABLE(); + break; + } +} + +void State::getBooleani_v(GLenum target, GLuint index, GLboolean *data) const +{ + switch (target) + { + case GL_COLOR_WRITEMASK: + { + ASSERT(static_cast(index) < mBlendStateExt.getDrawBufferCount()); + bool r, g, b, a; + mBlendStateExt.getColorMaskIndexed(index, &r, &g, &b, &a); + data[0] = r; + data[1] = g; + data[2] = b; + data[3] = a; + break; + } + case GL_IMAGE_BINDING_LAYERED: + ASSERT(static_cast(index) < mImageUnits.size()); + *data = mImageUnits[index].layered; + break; + default: + UNREACHABLE(); + break; + } +} + +// TODO(http://anglebug.com/3889): Remove this helper function after blink and chromium part +// refactor done. +Texture *State::getTextureForActiveSampler(TextureType type, size_t index) +{ + if (type != TextureType::VideoImage) + { + return mSamplerTextures[type][index].get(); + } + + ASSERT(type == TextureType::VideoImage); + + Texture *candidateTexture = mSamplerTextures[type][index].get(); + if (candidateTexture->getWidth(TextureTarget::VideoImage, 0) == 0 || + candidateTexture->getHeight(TextureTarget::VideoImage, 0) == 0 || + candidateTexture->getDepth(TextureTarget::VideoImage, 0) == 0) + { + return mSamplerTextures[TextureType::_2D][index].get(); + } + + return mSamplerTextures[type][index].get(); +} + +angle::Result State::syncActiveTextures(const Context *context, Command command) +{ + if (mDirtyActiveTextures.none()) + { + return angle::Result::Continue; + } + + for (size_t textureUnit : mDirtyActiveTextures) + { + if (mExecutable) + { + TextureType type = mExecutable->getActiveSamplerTypes()[textureUnit]; + Texture *activeTexture = (type != TextureType::InvalidEnum) + ? getTextureForActiveSampler(type, textureUnit) + : nullptr; + const Sampler *sampler = mSamplers[textureUnit].get(); + + updateActiveTextureStateOnSync(context, textureUnit, sampler, activeTexture); + } + } + + mDirtyActiveTextures.reset(); + return angle::Result::Continue; +} + +angle::Result State::syncTexturesInit(const Context *context, Command command) +{ + ASSERT(mRobustResourceInit); + + if (!mProgram) + return angle::Result::Continue; + + for (size_t textureUnitIndex : mExecutable->getActiveSamplersMask()) + { + Texture *texture = mActiveTexturesCache[textureUnitIndex]; + if (texture) + { + ANGLE_TRY(texture->ensureInitialized(context)); + } + } + return angle::Result::Continue; +} + +angle::Result State::syncImagesInit(const Context *context, Command command) +{ + ASSERT(mRobustResourceInit); + ASSERT(mExecutable); + for (size_t imageUnitIndex : mExecutable->getActiveImagesMask()) + { + Texture *texture = mImageUnits[imageUnitIndex].texture.get(); + if (texture) + { + ANGLE_TRY(texture->ensureInitialized(context)); + } + } + return angle::Result::Continue; +} + +angle::Result State::syncReadAttachments(const Context *context, Command command) +{ + ASSERT(mReadFramebuffer); + ASSERT(mRobustResourceInit); + return mReadFramebuffer->ensureReadAttachmentsInitialized(context); +} + +angle::Result State::syncDrawAttachments(const Context *context, Command command) +{ + ASSERT(mDrawFramebuffer); + ASSERT(mRobustResourceInit); + return mDrawFramebuffer->ensureDrawAttachmentsInitialized(context); +} + +angle::Result State::syncReadFramebuffer(const Context *context, Command command) +{ + ASSERT(mReadFramebuffer); + return mReadFramebuffer->syncState(context, GL_READ_FRAMEBUFFER, command); +} + +angle::Result State::syncDrawFramebuffer(const Context *context, Command command) +{ + ASSERT(mDrawFramebuffer); + mDrawFramebuffer->setWriteControlMode(context->getState().getFramebufferSRGB() + ? SrgbWriteControlMode::Default + : SrgbWriteControlMode::Linear); + return mDrawFramebuffer->syncState(context, GL_DRAW_FRAMEBUFFER, command); +} + +angle::Result State::syncTextures(const Context *context, Command command) +{ + if (mDirtyTextures.none()) + return angle::Result::Continue; + + for (size_t textureIndex : mDirtyTextures) + { + Texture *texture = mActiveTexturesCache[textureIndex]; + if (texture && texture->hasAnyDirtyBit()) + { + ANGLE_TRY(texture->syncState(context, Command::Other)); + } + } + + mDirtyTextures.reset(); + return angle::Result::Continue; +} + +angle::Result State::syncImages(const Context *context, Command command) +{ + if (mDirtyImages.none()) + return angle::Result::Continue; + + for (size_t imageUnitIndex : mDirtyImages) + { + Texture *texture = mImageUnits[imageUnitIndex].texture.get(); + if (texture && texture->hasAnyDirtyBit()) + { + ANGLE_TRY(texture->syncState(context, Command::Other)); + } + } + + mDirtyImages.reset(); + return angle::Result::Continue; +} + +angle::Result State::syncSamplers(const Context *context, Command command) +{ + if (mDirtySamplers.none()) + return angle::Result::Continue; + + for (size_t samplerIndex : mDirtySamplers) + { + BindingPointer &sampler = mSamplers[samplerIndex]; + if (sampler.get() && sampler->isDirty()) + { + ANGLE_TRY(sampler->syncState(context)); + } + } + + mDirtySamplers.reset(); + + return angle::Result::Continue; +} + +angle::Result State::syncVertexArray(const Context *context, Command command) +{ + ASSERT(mVertexArray); + return mVertexArray->syncState(context); +} + +angle::Result State::syncProgram(const Context *context, Command command) +{ + // There may not be a program if the calling application only uses program pipelines. + if (mProgram) + { + return mProgram->syncState(context); + } + return angle::Result::Continue; +} + +angle::Result State::syncProgramPipelineObject(const Context *context, Command command) +{ + // If a ProgramPipeline is bound, ensure it is linked. + if (mProgramPipeline.get()) + { + mProgramPipeline->resolveLink(context); + } + return angle::Result::Continue; +} + +angle::Result State::syncDirtyObject(const Context *context, GLenum target) +{ + DirtyObjects localSet; + + switch (target) + { + case GL_READ_FRAMEBUFFER: + localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER); + break; + case GL_DRAW_FRAMEBUFFER: + localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER); + break; + case GL_FRAMEBUFFER: + localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER); + localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER); + break; + case GL_VERTEX_ARRAY: + localSet.set(DIRTY_OBJECT_VERTEX_ARRAY); + break; + case GL_TEXTURE: + localSet.set(DIRTY_OBJECT_TEXTURES); + break; + case GL_SAMPLER: + localSet.set(DIRTY_OBJECT_SAMPLERS); + break; + case GL_PROGRAM: + localSet.set(DIRTY_OBJECT_PROGRAM); + break; + } + + return syncDirtyObjects(context, localSet, Command::Other); +} + +void State::setObjectDirty(GLenum target) +{ + switch (target) + { + case GL_READ_FRAMEBUFFER: + mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER); + break; + case GL_DRAW_FRAMEBUFFER: + setDrawFramebufferDirty(); + break; + case GL_FRAMEBUFFER: + mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER); + setDrawFramebufferDirty(); + break; + case GL_VERTEX_ARRAY: + mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY); + break; + case GL_PROGRAM: + mDirtyObjects.set(DIRTY_OBJECT_PROGRAM); + break; + default: + break; + } +} + +angle::Result State::onProgramExecutableChange(const Context *context, Program *program) +{ + // OpenGL Spec: + // "If LinkProgram or ProgramBinary successfully re-links a program object + // that was already in use as a result of a previous call to UseProgram, then the + // generated executable code will be installed as part of the current rendering state." + ASSERT(program->isLinked()); + + // If this Program is currently active, we need to update the State's pointer to the current + // ProgramExecutable if we just changed it. + if (mProgram == program) + { + mExecutable = &program->getExecutable(); + } + + mDirtyBits.set(DIRTY_BIT_PROGRAM_EXECUTABLE); + + if (program->hasAnyDirtyBit()) + { + mDirtyObjects.set(DIRTY_OBJECT_PROGRAM); + } + + // Set any bound textures. + const ProgramExecutable &executable = program->getExecutable(); + const ActiveTextureTypeArray &textureTypes = executable.getActiveSamplerTypes(); + for (size_t textureIndex : executable.getActiveSamplersMask()) + { + TextureType type = textureTypes[textureIndex]; + + // This can happen if there is a conflicting texture type. + if (type == TextureType::InvalidEnum) + continue; + + Texture *texture = getTextureForActiveSampler(type, textureIndex); + updateTextureBinding(context, textureIndex, texture); + } + + for (size_t imageUnitIndex : executable.getActiveImagesMask()) + { + Texture *image = mImageUnits[imageUnitIndex].texture.get(); + if (!image) + continue; + + if (image->hasAnyDirtyBit()) + { + ANGLE_TRY(image->syncState(context, Command::Other)); + } + + if (mRobustResourceInit && image->initState() == InitState::MayNeedInit) + { + mDirtyObjects.set(DIRTY_OBJECT_IMAGES_INIT); + } + } + + return angle::Result::Continue; +} + +angle::Result State::onProgramPipelineExecutableChange(const Context *context) +{ + mDirtyBits.set(DIRTY_BIT_PROGRAM_EXECUTABLE); + + if (!mProgramPipeline->isLinked()) + { + mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_PIPELINE_OBJECT); + } + + // Set any bound textures. + const ProgramExecutable &executable = mProgramPipeline->getExecutable(); + const ActiveTextureTypeArray &textureTypes = executable.getActiveSamplerTypes(); + + for (size_t textureIndex : executable.getActiveSamplersMask()) + { + TextureType type = textureTypes[textureIndex]; + + // This can happen if there is a conflicting texture type. + if (type == TextureType::InvalidEnum) + continue; + + Texture *texture = getTextureForActiveSampler(type, textureIndex); + updateTextureBinding(context, textureIndex, texture); + } + + for (size_t imageUnitIndex : executable.getActiveImagesMask()) + { + Texture *image = mImageUnits[imageUnitIndex].texture.get(); + if (!image) + continue; + + if (image->hasAnyDirtyBit()) + { + ANGLE_TRY(image->syncState(context, Command::Other)); + } + + if (mRobustResourceInit && image->initState() == InitState::MayNeedInit) + { + mDirtyObjects.set(DIRTY_OBJECT_IMAGES_INIT); + } + } + + return angle::Result::Continue; +} + +void State::setTextureDirty(size_t textureUnitIndex) +{ + mDirtyObjects.set(DIRTY_OBJECT_TEXTURES); + mDirtyTextures.set(textureUnitIndex); +} + +void State::setSamplerDirty(size_t samplerIndex) +{ + mDirtyObjects.set(DIRTY_OBJECT_SAMPLERS); + mDirtySamplers.set(samplerIndex); +} + +void State::setImageUnit(const Context *context, + size_t unit, + Texture *texture, + GLint level, + GLboolean layered, + GLint layer, + GLenum access, + GLenum format) +{ + ASSERT(!mImageUnits.empty()); + + ImageUnit &imageUnit = mImageUnits[unit]; + + if (texture) + { + texture->onBindAsImageTexture(); + + // Using individual layers of a 3d image as 2d may require that the image be respecified in + // a compatible layout + if (!layered && texture->getType() == TextureType::_3D) + { + texture->onBind3DTextureAs2DImage(); + } + } + imageUnit.texture.set(context, texture); + imageUnit.level = level; + imageUnit.layered = layered; + imageUnit.layer = layer; + imageUnit.access = access; + imageUnit.format = format; + mDirtyBits.set(DIRTY_BIT_IMAGE_BINDINGS); + + onImageStateChange(context, unit); +} + +// Handle a dirty texture event. +void State::onActiveTextureChange(const Context *context, size_t textureUnit) +{ + if (mExecutable) + { + TextureType type = mExecutable->getActiveSamplerTypes()[textureUnit]; + Texture *activeTexture = (type != TextureType::InvalidEnum) + ? getTextureForActiveSampler(type, textureUnit) + : nullptr; + updateTextureBinding(context, textureUnit, activeTexture); + + mExecutable->onStateChange(angle::SubjectMessage::ProgramTextureOrImageBindingChanged); + } +} + +void State::onActiveTextureStateChange(const Context *context, size_t textureUnit) +{ + if (mExecutable) + { + TextureType type = mExecutable->getActiveSamplerTypes()[textureUnit]; + Texture *activeTexture = (type != TextureType::InvalidEnum) + ? getTextureForActiveSampler(type, textureUnit) + : nullptr; + setActiveTextureDirty(textureUnit, activeTexture); + } +} + +void State::onImageStateChange(const Context *context, size_t unit) +{ + if (mExecutable) + { + const ImageUnit &image = mImageUnits[unit]; + + // Have nothing to do here if no texture bound + if (!image.texture.get()) + return; + + if (image.texture->hasAnyDirtyBit()) + { + mDirtyImages.set(unit); + mDirtyObjects.set(DIRTY_OBJECT_IMAGES); + } + + if (mRobustResourceInit && image.texture->initState() == InitState::MayNeedInit) + { + mDirtyObjects.set(DIRTY_OBJECT_IMAGES_INIT); + } + + mExecutable->onStateChange(angle::SubjectMessage::ProgramTextureOrImageBindingChanged); + } +} + +void State::onUniformBufferStateChange(size_t uniformBufferIndex) +{ + // This could be represented by a different dirty bit. Using the same one keeps it simple. + mDirtyBits.set(DIRTY_BIT_UNIFORM_BUFFER_BINDINGS); +} + +void State::onAtomicCounterBufferStateChange(size_t atomicCounterBufferIndex) +{ + mDirtyBits.set(DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING); +} + +void State::onShaderStorageBufferStateChange(size_t shaderStorageBufferIndex) +{ + mDirtyBits.set(DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING); +} + +AttributesMask State::getAndResetDirtyCurrentValues() const +{ + AttributesMask retVal = mDirtyCurrentValues; + mDirtyCurrentValues.reset(); + return retVal; +} + +State::ExtendedDirtyBits State::getAndResetExtendedDirtyBits() const +{ + ExtendedDirtyBits retVal = mExtendedDirtyBits; + mExtendedDirtyBits.reset(); + return retVal; +} + +void State::initializeForCapture(const Context *context) +{ + mCaps = context->getCaps(); + mExtensions = context->getExtensions(); + + // This little kludge gets around the frame capture "constness". It should be safe because + // nothing in the context is modified in a non-compatible way during capture. + Context *mutableContext = const_cast(context); + initialize(mutableContext); +} + +void State::setLogicOpEnabled(bool enabled) +{ + if (mLogicOpEnabled != enabled) + { + mLogicOpEnabled = enabled; + mDirtyBits.set(DIRTY_BIT_EXTENDED); + mExtendedDirtyBits.set(EXTENDED_DIRTY_BIT_LOGIC_OP_ENABLED); + } +} + +void State::setLogicOp(LogicalOperation opcode) +{ + if (mLogicOp != opcode) + { + mLogicOp = opcode; + mDirtyBits.set(DIRTY_BIT_EXTENDED); + mExtendedDirtyBits.set(EXTENDED_DIRTY_BIT_LOGIC_OP); + } +} + +constexpr State::DirtyObjectHandler State::kDirtyObjectHandlers[DIRTY_OBJECT_MAX]; + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/State.h b/gfx/angle/checkout/src/libANGLE/State.h new file mode 100644 index 0000000000..08098599e1 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/State.h @@ -0,0 +1,1258 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// State.h: Defines the State class, encapsulating raw GL state + +#ifndef LIBANGLE_STATE_H_ +#define LIBANGLE_STATE_H_ + +#include +#include + +#include "common/Color.h" +#include "common/angleutils.h" +#include "common/bitset_utils.h" +#include "libANGLE/Debug.h" +#include "libANGLE/GLES1State.h" +#include "libANGLE/Overlay.h" +#include "libANGLE/Program.h" +#include "libANGLE/ProgramExecutable.h" +#include "libANGLE/ProgramPipeline.h" +#include "libANGLE/RefCountObject.h" +#include "libANGLE/Renderbuffer.h" +#include "libANGLE/Sampler.h" +#include "libANGLE/Texture.h" +#include "libANGLE/TransformFeedback.h" +#include "libANGLE/Version.h" +#include "libANGLE/VertexArray.h" +#include "libANGLE/angletypes.h" + +namespace egl +{ +class ShareGroup; +} // namespace egl + +namespace gl +{ +class BufferManager; +struct Caps; +class Context; +class FramebufferManager; +class MemoryObjectManager; +class ProgramPipelineManager; +class Query; +class RenderbufferManager; +class SamplerManager; +class SemaphoreManager; +class ShaderProgramManager; +class SyncManager; +class TextureManager; +class VertexArray; + +static constexpr Version ES_1_0 = Version(1, 0); +static constexpr Version ES_1_1 = Version(1, 1); +static constexpr Version ES_2_0 = Version(2, 0); +static constexpr Version ES_3_0 = Version(3, 0); +static constexpr Version ES_3_1 = Version(3, 1); +static constexpr Version ES_3_2 = Version(3, 2); + +template +using BufferBindingMap = angle::PackedEnumMap; +using BoundBufferMap = BufferBindingMap>; +using TextureBindingVector = std::vector>; +using TextureBindingMap = angle::PackedEnumMap; +using ActiveQueryMap = angle::PackedEnumMap>; + +class ActiveTexturesCache final : angle::NonCopyable +{ + public: + ActiveTexturesCache(); + ~ActiveTexturesCache(); + + Texture *operator[](size_t textureIndex) const { return mTextures[textureIndex]; } + + void clear(); + void set(size_t textureIndex, Texture *texture); + void reset(size_t textureIndex); + bool empty() const; + size_t size() const { return mTextures.size(); } + + private: + ActiveTextureArray mTextures; +}; + +class State : angle::NonCopyable +{ + public: + State(const State *shareContextState, + egl::ShareGroup *shareGroup, + TextureManager *shareTextures, + SemaphoreManager *shareSemaphores, + const OverlayType *overlay, + const EGLenum clientType, + const Version &clientVersion, + EGLint profileMask, + bool debug, + bool bindGeneratesResourceCHROMIUM, + bool clientArraysEnabled, + bool robustResourceInit, + bool programBinaryCacheEnabled, + EGLenum contextPriority, + bool hasRobustAccess, + bool hasProtectedContent); + ~State(); + + void initialize(Context *context); + void reset(const Context *context); + + // Getters + ContextID getContextID() const { return mID; } + EGLenum getClientType() const { return mClientType; } + EGLint getProfileMask() const { return mProfileMask; } + EGLenum getContextPriority() const { return mContextPriority; } + bool hasRobustAccess() const { return mHasRobustAccess; } + bool hasProtectedContent() const { return mHasProtectedContent; } + bool isDebugContext() const { return mIsDebugContext; } + GLint getClientMajorVersion() const { return mClientVersion.major; } + GLint getClientMinorVersion() const { return mClientVersion.minor; } + const Version &getClientVersion() const { return mClientVersion; } + const Caps &getCaps() const { return mCaps; } + const TextureCapsMap &getTextureCaps() const { return mTextureCaps; } + const Extensions &getExtensions() const { return mExtensions; } + const Limitations &getLimitations() const { return mLimitations; } + egl::ShareGroup *getShareGroup() const { return mShareGroup; } + + bool isWebGL() const { return mExtensions.webglCompatibilityANGLE; } + + bool isWebGL1() const { return (isWebGL() && mClientVersion.major == 2); } + + bool isGLES1() const { return mClientVersion < ES_2_0; } + + const TextureCaps &getTextureCap(GLenum internalFormat) const + { + return mTextureCaps.get(internalFormat); + } + + // State chunk getters + bool allActiveDrawBufferChannelsMasked() const; + bool anyActiveDrawBufferChannelMasked() const; + const RasterizerState &getRasterizerState() const; + const BlendState &getBlendState() const { return mBlendState; } + const BlendStateExt &getBlendStateExt() const { return mBlendStateExt; } + const DepthStencilState &getDepthStencilState() const; + + // Clear behavior setters & state parameter block generation function + void setColorClearValue(float red, float green, float blue, float alpha); + void setDepthClearValue(float depth); + void setStencilClearValue(int stencil); + + const ColorF &getColorClearValue() const { return mColorClearValue; } + float getDepthClearValue() const { return mDepthClearValue; } + int getStencilClearValue() const { return mStencilClearValue; } + + // Write mask manipulation + void setColorMask(bool red, bool green, bool blue, bool alpha); + void setColorMaskIndexed(bool red, bool green, bool blue, bool alpha, GLuint index); + void setDepthMask(bool mask); + + // Discard toggle & query + bool isRasterizerDiscardEnabled() const { return mRasterizer.rasterizerDiscard; } + void setRasterizerDiscard(bool enabled); + + // Primitive restart + bool isPrimitiveRestartEnabled() const { return mPrimitiveRestart; } + void setPrimitiveRestart(bool enabled); + + // Face culling state manipulation + bool isCullFaceEnabled() const { return mRasterizer.cullFace; } + void setCullFace(bool enabled); + void setCullMode(CullFaceMode mode); + void setFrontFace(GLenum front); + + // Depth test state manipulation + bool isDepthTestEnabled() const { return mDepthStencil.depthTest; } + bool isDepthWriteEnabled() const { return mDepthStencil.depthTest && mDepthStencil.depthMask; } + void setDepthTest(bool enabled); + void setDepthFunc(GLenum depthFunc); + void setDepthRange(float zNear, float zFar); + float getNearPlane() const { return mNearZ; } + float getFarPlane() const { return mFarZ; } + + // Clip control extension + void setClipControl(GLenum origin, GLenum depth); + bool isClipControlDepthZeroToOne() const { return mClipControlDepth == GL_ZERO_TO_ONE_EXT; } + gl::ClipSpaceOrigin getClipSpaceOrigin() const + { + return mClipControlOrigin == GL_UPPER_LEFT_EXT ? ClipSpaceOrigin::UpperLeft + : ClipSpaceOrigin::LowerLeft; + } + + // Blend state manipulation + bool isBlendEnabled() const { return mBlendStateExt.getEnabledMask().test(0); } + bool isBlendEnabledIndexed(GLuint index) const + { + ASSERT(static_cast(index) < mBlendStateExt.getDrawBufferCount()); + return mBlendStateExt.getEnabledMask().test(index); + } + DrawBufferMask getBlendEnabledDrawBufferMask() const { return mBlendStateExt.getEnabledMask(); } + void setBlend(bool enabled); + void setBlendIndexed(bool enabled, GLuint index); + void setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha); + void setBlendFactorsIndexed(GLenum sourceRGB, + GLenum destRGB, + GLenum sourceAlpha, + GLenum destAlpha, + GLuint index); + void setBlendColor(float red, float green, float blue, float alpha); + void setBlendEquation(GLenum rgbEquation, GLenum alphaEquation); + void setBlendEquationIndexed(GLenum rgbEquation, GLenum alphaEquation, GLuint index); + const ColorF &getBlendColor() const { return mBlendColor; } + + // Stencil state maniupulation + bool isStencilTestEnabled() const { return mDepthStencil.stencilTest; } + void setStencilTest(bool enabled); + void setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask); + void setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask); + void setStencilWritemask(GLuint stencilWritemask); + void setStencilBackWritemask(GLuint stencilBackWritemask); + void setStencilOperations(GLenum stencilFail, + GLenum stencilPassDepthFail, + GLenum stencilPassDepthPass); + void setStencilBackOperations(GLenum stencilBackFail, + GLenum stencilBackPassDepthFail, + GLenum stencilBackPassDepthPass); + GLint getStencilRef() const { return mStencilRef; } + GLint getStencilBackRef() const { return mStencilBackRef; } + + // Depth bias/polygon offset state manipulation + bool isPolygonOffsetFillEnabled() const { return mRasterizer.polygonOffsetFill; } + void setPolygonOffsetFill(bool enabled); + void setPolygonOffsetParams(GLfloat factor, GLfloat units); + + // Multisample coverage state manipulation + bool isSampleAlphaToCoverageEnabled() const { return mSampleAlphaToCoverage; } + void setSampleAlphaToCoverage(bool enabled); + bool isSampleCoverageEnabled() const { return mSampleCoverage; } + void setSampleCoverage(bool enabled); + void setSampleCoverageParams(GLclampf value, bool invert); + GLclampf getSampleCoverageValue() const { return mSampleCoverageValue; } + bool getSampleCoverageInvert() const { return mSampleCoverageInvert; } + + // Multisample mask state manipulation. + bool isSampleMaskEnabled() const { return mSampleMask; } + void setSampleMaskEnabled(bool enabled); + void setSampleMaskParams(GLuint maskNumber, GLbitfield mask); + GLbitfield getSampleMaskWord(GLuint maskNumber) const + { + ASSERT(maskNumber < mMaxSampleMaskWords); + return mSampleMaskValues[maskNumber]; + } + SampleMaskArray getSampleMaskValues() const { return mSampleMaskValues; } + GLuint getMaxSampleMaskWords() const { return mMaxSampleMaskWords; } + + // Multisampling/alpha to one manipulation. + void setSampleAlphaToOne(bool enabled); + bool isSampleAlphaToOneEnabled() const { return mSampleAlphaToOne; } + void setMultisampling(bool enabled); + bool isMultisamplingEnabled() const { return mMultiSampling; } + + void setSampleShading(bool enabled); + bool isSampleShadingEnabled() const { return mIsSampleShadingEnabled; } + void setMinSampleShading(float value); + float getMinSampleShading() const { return mMinSampleShading; } + + // Scissor test state toggle & query + bool isScissorTestEnabled() const { return mScissorTest; } + void setScissorTest(bool enabled); + void setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height); + const Rectangle &getScissor() const { return mScissor; } + + // Dither state toggle & query + bool isDitherEnabled() const { return mRasterizer.dither; } + void setDither(bool enabled); + + // Generic state toggle & query + void setEnableFeature(GLenum feature, bool enabled); + void setEnableFeatureIndexed(GLenum feature, bool enabled, GLuint index); + bool getEnableFeature(GLenum feature) const; + bool getEnableFeatureIndexed(GLenum feature, GLuint index) const; + + // Line width state setter + void setLineWidth(GLfloat width); + float getLineWidth() const { return mLineWidth; } + + // Hint setters + void setGenerateMipmapHint(GLenum hint); + GLenum getGenerateMipmapHint() const; + void setTextureFilteringHint(GLenum hint); + GLenum getTextureFilteringHint() const; + GLenum getFragmentShaderDerivativeHint() const { return mFragmentShaderDerivativeHint; } + void setFragmentShaderDerivativeHint(GLenum hint); + + // GL_CHROMIUM_bind_generates_resource + bool isBindGeneratesResourceEnabled() const { return mBindGeneratesResource; } + + // GL_ANGLE_client_arrays + bool areClientArraysEnabled() const { return mClientArraysEnabled; } + + // Viewport state setter/getter + void setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height); + const Rectangle &getViewport() const { return mViewport; } + + // Texture binding & active texture unit manipulation + void setActiveSampler(unsigned int active); + unsigned int getActiveSampler() const { return static_cast(mActiveSampler); } + + void setSamplerTexture(const Context *context, TextureType type, Texture *texture); + Texture *getTargetTexture(TextureType type) const; + + Texture *getSamplerTexture(unsigned int sampler, TextureType type) const + { + ASSERT(sampler < mSamplerTextures[type].size()); + return mSamplerTextures[type][sampler].get(); + } + + TextureID getSamplerTextureId(unsigned int sampler, TextureType type) const; + void detachTexture(const Context *context, const TextureMap &zeroTextures, TextureID texture); + void initializeZeroTextures(const Context *context, const TextureMap &zeroTextures); + + void invalidateTextureBindings(TextureType type); + + // Sampler object binding manipulation + void setSamplerBinding(const Context *context, GLuint textureUnit, Sampler *sampler); + SamplerID getSamplerId(GLuint textureUnit) const + { + ASSERT(textureUnit < mSamplers.size()); + return mSamplers[textureUnit].id(); + } + + Sampler *getSampler(GLuint textureUnit) const { return mSamplers[textureUnit].get(); } + + const SamplerBindingVector &getSamplers() const { return mSamplers; } + + void detachSampler(const Context *context, SamplerID sampler); + + // Renderbuffer binding manipulation + void setRenderbufferBinding(const Context *context, Renderbuffer *renderbuffer); + RenderbufferID getRenderbufferId() const { return mRenderbuffer.id(); } + Renderbuffer *getCurrentRenderbuffer() const { return mRenderbuffer.get(); } + void detachRenderbuffer(const Context *context, RenderbufferID renderbuffer); + + // Framebuffer binding manipulation + void setReadFramebufferBinding(Framebuffer *framebuffer); + void setDrawFramebufferBinding(Framebuffer *framebuffer); + Framebuffer *getTargetFramebuffer(GLenum target) const; + Framebuffer *getReadFramebuffer() const { return mReadFramebuffer; } + Framebuffer *getDrawFramebuffer() const { return mDrawFramebuffer; } + Framebuffer *getDefaultFramebuffer() const; + + bool removeReadFramebufferBinding(FramebufferID framebuffer); + bool removeDrawFramebufferBinding(FramebufferID framebuffer); + + // Vertex array object binding manipulation + void setVertexArrayBinding(const Context *context, VertexArray *vertexArray); + bool removeVertexArrayBinding(const Context *context, VertexArrayID vertexArray); + VertexArrayID getVertexArrayId() const; + + VertexArray *getVertexArray() const + { + ASSERT(mVertexArray != nullptr); + return mVertexArray; + } + + // QCOM_shading_rate helpers + void setShadingRate(GLenum rate); + ShadingRate getShadingRate() const { return mShadingRate; } + + // If both a Program and a ProgramPipeline are bound, the Program will + // always override the ProgramPipeline. + ProgramExecutable *getProgramExecutable() const { return mExecutable; } + ProgramExecutable *getLinkedProgramExecutable(const Context *context) const + { + if (mProgram) + { + mProgram->resolveLink(context); + } + else if (mProgramPipeline.get()) + { + mProgramPipeline->resolveLink(context); + } + return mExecutable; + } + + // Program binding manipulation + angle::Result setProgram(const Context *context, Program *newProgram); + + Program *getProgram() const + { + ASSERT(!mProgram || !mProgram->isLinking()); + return mProgram; + } + + Program *getLinkedProgram(const Context *context) const + { + if (mProgram) + { + mProgram->resolveLink(context); + } + return mProgram; + } + + ProgramPipeline *getProgramPipeline() const { return mProgramPipeline.get(); } + + ProgramPipeline *getLinkedProgramPipeline(const Context *context) const + { + if (mProgramPipeline.get()) + { + mProgramPipeline->resolveLink(context); + } + return mProgramPipeline.get(); + } + + // Transform feedback object (not buffer) binding manipulation + void setTransformFeedbackBinding(const Context *context, TransformFeedback *transformFeedback); + TransformFeedback *getCurrentTransformFeedback() const { return mTransformFeedback.get(); } + + ANGLE_INLINE bool isTransformFeedbackActive() const + { + TransformFeedback *curTransformFeedback = mTransformFeedback.get(); + return curTransformFeedback && curTransformFeedback->isActive(); + } + ANGLE_INLINE bool isTransformFeedbackActiveUnpaused() const + { + TransformFeedback *curTransformFeedback = mTransformFeedback.get(); + return curTransformFeedback && curTransformFeedback->isActive() && + !curTransformFeedback->isPaused(); + } + + bool removeTransformFeedbackBinding(const Context *context, + TransformFeedbackID transformFeedback); + + // Query binding manipulation + bool isQueryActive(QueryType type) const; + bool isQueryActive(Query *query) const; + void setActiveQuery(const Context *context, QueryType type, Query *query); + QueryID getActiveQueryId(QueryType type) const; + Query *getActiveQuery(QueryType type) const; + + // Program Pipeline binding manipulation + angle::Result setProgramPipelineBinding(const Context *context, ProgramPipeline *pipeline); + void detachProgramPipeline(const Context *context, ProgramPipelineID pipeline); + + //// Typed buffer binding point manipulation //// + ANGLE_INLINE void setBufferBinding(const Context *context, BufferBinding target, Buffer *buffer) + { + (this->*(kBufferSetters[target]))(context, buffer); + } + + ANGLE_INLINE Buffer *getTargetBuffer(BufferBinding target) const + { + switch (target) + { + case BufferBinding::ElementArray: + return getVertexArray()->getElementArrayBuffer(); + default: + return mBoundBuffers[target].get(); + } + } + + ANGLE_INLINE Buffer *getArrayBuffer() const { return getTargetBuffer(BufferBinding::Array); } + + angle::Result setIndexedBufferBinding(const Context *context, + BufferBinding target, + GLuint index, + Buffer *buffer, + GLintptr offset, + GLsizeiptr size); + + size_t getAtomicCounterBufferCount() const { return mAtomicCounterBuffers.size(); } + + ANGLE_INLINE bool hasValidAtomicCounterBuffer() const + { + return mBoundAtomicCounterBuffersMask.any(); + } + + const OffsetBindingPointer &getIndexedUniformBuffer(size_t index) const; + const OffsetBindingPointer &getIndexedAtomicCounterBuffer(size_t index) const; + const OffsetBindingPointer &getIndexedShaderStorageBuffer(size_t index) const; + + const angle::BitSet &getUniformBuffersMask() + const + { + return mBoundUniformBuffersMask; + } + const angle::BitSet + &getAtomicCounterBuffersMask() const + { + return mBoundAtomicCounterBuffersMask; + } + const angle::BitSet + &getShaderStorageBuffersMask() const + { + return mBoundShaderStorageBuffersMask; + } + + // Detach a buffer from all bindings + angle::Result detachBuffer(Context *context, const Buffer *buffer); + + // Vertex attrib manipulation + void setEnableVertexAttribArray(unsigned int attribNum, bool enabled); + void setVertexAttribf(GLuint index, const GLfloat values[4]); + void setVertexAttribu(GLuint index, const GLuint values[4]); + void setVertexAttribi(GLuint index, const GLint values[4]); + + ANGLE_INLINE void setVertexAttribPointer(const Context *context, + unsigned int attribNum, + Buffer *boundBuffer, + GLint size, + VertexAttribType type, + bool normalized, + GLsizei stride, + const void *pointer) + { + mVertexArray->setVertexAttribPointer(context, attribNum, boundBuffer, size, type, + normalized, stride, pointer); + mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY); + } + + ANGLE_INLINE void setVertexAttribIPointer(const Context *context, + unsigned int attribNum, + Buffer *boundBuffer, + GLint size, + VertexAttribType type, + GLsizei stride, + const void *pointer) + { + mVertexArray->setVertexAttribIPointer(context, attribNum, boundBuffer, size, type, stride, + pointer); + mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY); + } + + void setVertexAttribDivisor(const Context *context, GLuint index, GLuint divisor); + const VertexAttribCurrentValueData &getVertexAttribCurrentValue(size_t attribNum) const + { + ASSERT(attribNum < mVertexAttribCurrentValues.size()); + return mVertexAttribCurrentValues[attribNum]; + } + + const std::vector &getVertexAttribCurrentValues() const + { + return mVertexAttribCurrentValues; + } + + const void *getVertexAttribPointer(unsigned int attribNum) const; + + void bindVertexBuffer(const Context *context, + GLuint bindingIndex, + Buffer *boundBuffer, + GLintptr offset, + GLsizei stride); + void setVertexAttribFormat(GLuint attribIndex, + GLint size, + VertexAttribType type, + bool normalized, + bool pureInteger, + GLuint relativeOffset); + + void setVertexAttribBinding(const Context *context, GLuint attribIndex, GLuint bindingIndex) + { + mVertexArray->setVertexAttribBinding(context, attribIndex, bindingIndex); + mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY); + } + + void setVertexBindingDivisor(const Context *context, GLuint bindingIndex, GLuint divisor); + + // Pixel pack state manipulation + void setPackAlignment(GLint alignment); + GLint getPackAlignment() const { return mPack.alignment; } + void setPackReverseRowOrder(bool reverseRowOrder); + bool getPackReverseRowOrder() const { return mPack.reverseRowOrder; } + void setPackRowLength(GLint rowLength); + GLint getPackRowLength() const { return mPack.rowLength; } + void setPackSkipRows(GLint skipRows); + GLint getPackSkipRows() const { return mPack.skipRows; } + void setPackSkipPixels(GLint skipPixels); + GLint getPackSkipPixels() const { return mPack.skipPixels; } + const PixelPackState &getPackState() const { return mPack; } + PixelPackState &getPackState() { return mPack; } + + // Pixel unpack state manipulation + void setUnpackAlignment(GLint alignment); + GLint getUnpackAlignment() const { return mUnpack.alignment; } + void setUnpackRowLength(GLint rowLength); + GLint getUnpackRowLength() const { return mUnpack.rowLength; } + void setUnpackImageHeight(GLint imageHeight); + GLint getUnpackImageHeight() const { return mUnpack.imageHeight; } + void setUnpackSkipImages(GLint skipImages); + GLint getUnpackSkipImages() const { return mUnpack.skipImages; } + void setUnpackSkipRows(GLint skipRows); + GLint getUnpackSkipRows() const { return mUnpack.skipRows; } + void setUnpackSkipPixels(GLint skipPixels); + GLint getUnpackSkipPixels() const { return mUnpack.skipPixels; } + const PixelUnpackState &getUnpackState() const { return mUnpack; } + PixelUnpackState &getUnpackState() { return mUnpack; } + + // Debug state + const Debug &getDebug() const { return mDebug; } + Debug &getDebug() { return mDebug; } + + // CHROMIUM_framebuffer_mixed_samples coverage modulation + void setCoverageModulation(GLenum components); + GLenum getCoverageModulation() const { return mCoverageModulation; } + + // GL_EXT_sRGB_write_control + void setFramebufferSRGB(bool sRGB); + bool getFramebufferSRGB() const { return mFramebufferSRGB; } + + // GL_KHR_parallel_shader_compile + void setMaxShaderCompilerThreads(GLuint count); + GLuint getMaxShaderCompilerThreads() const { return mMaxShaderCompilerThreads; } + + // GL_EXT_tessellation_shader + void setPatchVertices(GLuint value); + GLuint getPatchVertices() const { return mPatchVertices; } + + // GL_ANGLE_shader_pixel_local_storage + void setPixelLocalStorageActive(bool active); + bool getPixelLocalStorageActive() const { return mPixelLocalStorageActive; } + + // State query functions + void getBooleanv(GLenum pname, GLboolean *params) const; + void getFloatv(GLenum pname, GLfloat *params) const; + angle::Result getIntegerv(const Context *context, GLenum pname, GLint *params) const; + void getPointerv(const Context *context, GLenum pname, void **params) const; + void getIntegeri_v(const Context *context, GLenum target, GLuint index, GLint *data) const; + void getInteger64i_v(GLenum target, GLuint index, GLint64 *data) const; + void getBooleani_v(GLenum target, GLuint index, GLboolean *data) const; + + bool isRobustResourceInitEnabled() const { return mRobustResourceInit; } + + bool isDrawFramebufferBindingDirty() const + { + return mDirtyBits.test(DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING); + } + + // Sets the dirty bit for the program executable. + angle::Result onProgramExecutableChange(const Context *context, Program *program); + // Sets the dirty bit for the program pipeline executable. + angle::Result onProgramPipelineExecutableChange(const Context *context); + + enum DirtyBitType + { + // Note: process draw framebuffer binding first, so that other dirty bits whose effect + // depend on the current draw framebuffer are not processed while the old framebuffer is + // still bound. + DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING, + DIRTY_BIT_READ_FRAMEBUFFER_BINDING, + DIRTY_BIT_SCISSOR_TEST_ENABLED, + DIRTY_BIT_SCISSOR, + DIRTY_BIT_VIEWPORT, + DIRTY_BIT_DEPTH_RANGE, + DIRTY_BIT_BLEND_ENABLED, + DIRTY_BIT_BLEND_COLOR, + DIRTY_BIT_BLEND_FUNCS, + DIRTY_BIT_BLEND_EQUATIONS, + DIRTY_BIT_COLOR_MASK, + DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED, + DIRTY_BIT_SAMPLE_COVERAGE_ENABLED, + DIRTY_BIT_SAMPLE_COVERAGE, + DIRTY_BIT_SAMPLE_MASK_ENABLED, + DIRTY_BIT_SAMPLE_MASK, + DIRTY_BIT_DEPTH_TEST_ENABLED, + DIRTY_BIT_DEPTH_FUNC, + DIRTY_BIT_DEPTH_MASK, + DIRTY_BIT_STENCIL_TEST_ENABLED, + DIRTY_BIT_STENCIL_FUNCS_FRONT, + DIRTY_BIT_STENCIL_FUNCS_BACK, + DIRTY_BIT_STENCIL_OPS_FRONT, + DIRTY_BIT_STENCIL_OPS_BACK, + DIRTY_BIT_STENCIL_WRITEMASK_FRONT, + DIRTY_BIT_STENCIL_WRITEMASK_BACK, + DIRTY_BIT_CULL_FACE_ENABLED, + DIRTY_BIT_CULL_FACE, + DIRTY_BIT_FRONT_FACE, + DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED, + DIRTY_BIT_POLYGON_OFFSET, + DIRTY_BIT_RASTERIZER_DISCARD_ENABLED, + DIRTY_BIT_LINE_WIDTH, + DIRTY_BIT_PRIMITIVE_RESTART_ENABLED, + DIRTY_BIT_CLEAR_COLOR, + DIRTY_BIT_CLEAR_DEPTH, + DIRTY_BIT_CLEAR_STENCIL, + DIRTY_BIT_UNPACK_STATE, + DIRTY_BIT_UNPACK_BUFFER_BINDING, + DIRTY_BIT_PACK_STATE, + DIRTY_BIT_PACK_BUFFER_BINDING, + DIRTY_BIT_DITHER_ENABLED, + DIRTY_BIT_RENDERBUFFER_BINDING, + DIRTY_BIT_VERTEX_ARRAY_BINDING, + DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING, + DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING, + // TODO(jmadill): Fine-grained dirty bits for each index. + DIRTY_BIT_PROGRAM_BINDING, // Must be before DIRTY_BIT_PROGRAM_EXECUTABLE + DIRTY_BIT_PROGRAM_EXECUTABLE, + // TODO(jmadill): Fine-grained dirty bits for each texture/sampler. + DIRTY_BIT_SAMPLER_BINDINGS, + DIRTY_BIT_TEXTURE_BINDINGS, + DIRTY_BIT_IMAGE_BINDINGS, + DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING, + DIRTY_BIT_UNIFORM_BUFFER_BINDINGS, + DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING, + DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING, + DIRTY_BIT_MULTISAMPLING, + DIRTY_BIT_SAMPLE_ALPHA_TO_ONE, + DIRTY_BIT_COVERAGE_MODULATION, // CHROMIUM_framebuffer_mixed_samples + DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE, // GL_EXT_sRGB_write_control + DIRTY_BIT_CURRENT_VALUES, + DIRTY_BIT_PROVOKING_VERTEX, + DIRTY_BIT_SAMPLE_SHADING, + DIRTY_BIT_PATCH_VERTICES, + DIRTY_BIT_EXTENDED, // clip distances, mipmap generation hint, derivative hint, + // EXT_clip_control + DIRTY_BIT_INVALID, + DIRTY_BIT_MAX = DIRTY_BIT_INVALID, + }; + + static_assert(DIRTY_BIT_MAX <= 64, "State dirty bits must be capped at 64"); + + enum ExtendedDirtyBitType + { + EXTENDED_DIRTY_BIT_CLIP_CONTROL, // EXT_clip_control + EXTENDED_DIRTY_BIT_CLIP_DISTANCES, // clip distances + EXTENDED_DIRTY_BIT_MIPMAP_GENERATION_HINT, // mipmap generation hint + EXTENDED_DIRTY_BIT_SHADER_DERIVATIVE_HINT, // shader derivative hint + EXTENDED_DIRTY_BIT_SHADING_RATE, // QCOM_shading_rate + EXTENDED_DIRTY_BIT_LOGIC_OP_ENABLED, // ANGLE_logic_op + EXTENDED_DIRTY_BIT_LOGIC_OP, // ANGLE_logic_op + EXTENDED_DIRTY_BIT_INVALID, + EXTENDED_DIRTY_BIT_MAX = EXTENDED_DIRTY_BIT_INVALID, + }; + + static_assert(EXTENDED_DIRTY_BIT_MAX <= 32, "State extended dirty bits must be capped at 32"); + + // TODO(jmadill): Consider storing dirty objects in a list instead of by binding. + enum DirtyObjectType + { + DIRTY_OBJECT_ACTIVE_TEXTURES, // Top-level dirty bit. Also see mDirtyActiveTextures. + DIRTY_OBJECT_TEXTURES_INIT, + DIRTY_OBJECT_IMAGES_INIT, + DIRTY_OBJECT_READ_ATTACHMENTS, + DIRTY_OBJECT_DRAW_ATTACHMENTS, + DIRTY_OBJECT_READ_FRAMEBUFFER, + DIRTY_OBJECT_DRAW_FRAMEBUFFER, + DIRTY_OBJECT_VERTEX_ARRAY, + DIRTY_OBJECT_TEXTURES, // Top-level dirty bit. Also see mDirtyTextures. + DIRTY_OBJECT_IMAGES, // Top-level dirty bit. Also see mDirtyImages. + DIRTY_OBJECT_SAMPLERS, // Top-level dirty bit. Also see mDirtySamplers. + DIRTY_OBJECT_PROGRAM, + DIRTY_OBJECT_PROGRAM_PIPELINE_OBJECT, + DIRTY_OBJECT_UNKNOWN, + DIRTY_OBJECT_MAX = DIRTY_OBJECT_UNKNOWN, + }; + + using DirtyBits = angle::BitSet; + const DirtyBits &getDirtyBits() const { return mDirtyBits; } + void clearDirtyBits() { mDirtyBits.reset(); } + void clearDirtyBits(const DirtyBits &bitset) { mDirtyBits &= ~bitset; } + void setAllDirtyBits() + { + mDirtyBits.set(); + mExtendedDirtyBits.set(); + mDirtyCurrentValues.set(); + } + + using ExtendedDirtyBits = angle::BitSet32; + const ExtendedDirtyBits &getExtendedDirtyBits() const { return mExtendedDirtyBits; } + // TODO(https://anglebug.com/5631): Handle extended dirty bits on non-vulkan backends + ExtendedDirtyBits getAndResetExtendedDirtyBits() const; + void clearExtendedDirtyBits() { mExtendedDirtyBits.reset(); } + + using DirtyObjects = angle::BitSet; + void clearDirtyObjects() { mDirtyObjects.reset(); } + void setAllDirtyObjects() { mDirtyObjects.set(); } + angle::Result syncDirtyObjects(const Context *context, + const DirtyObjects &bitset, + Command command); + angle::Result syncDirtyObject(const Context *context, GLenum target); + void setObjectDirty(GLenum target); + void setTextureDirty(size_t textureUnitIndex); + void setSamplerDirty(size_t samplerIndex); + + ANGLE_INLINE void setReadFramebufferDirty() + { + mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER); + mDirtyObjects.set(DIRTY_OBJECT_READ_ATTACHMENTS); + } + + ANGLE_INLINE void setDrawFramebufferDirty() + { + mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER); + mDirtyObjects.set(DIRTY_OBJECT_DRAW_ATTACHMENTS); + } + + // This actually clears the current value dirty bits. + // TODO(jmadill): Pass mutable dirty bits into Impl. + AttributesMask getAndResetDirtyCurrentValues() const; + + void setImageUnit(const Context *context, + size_t unit, + Texture *texture, + GLint level, + GLboolean layered, + GLint layer, + GLenum access, + GLenum format); + + const ImageUnit &getImageUnit(size_t unit) const { return mImageUnits[unit]; } + const ActiveTexturesCache &getActiveTexturesCache() const { return mActiveTexturesCache; } + ComponentTypeMask getCurrentValuesTypeMask() const { return mCurrentValuesTypeMask; } + + // "onActiveTextureChange" is called when a texture binding changes. + void onActiveTextureChange(const Context *context, size_t textureUnit); + + // "onActiveTextureStateChange" is called when the Texture changed but the binding did not. + void onActiveTextureStateChange(const Context *context, size_t textureUnit); + + void onImageStateChange(const Context *context, size_t unit); + + void onUniformBufferStateChange(size_t uniformBufferIndex); + void onAtomicCounterBufferStateChange(size_t atomicCounterBufferIndex); + void onShaderStorageBufferStateChange(size_t shaderStorageBufferIndex); + + bool isCurrentTransformFeedback(const TransformFeedback *tf) const + { + return tf == mTransformFeedback.get(); + } + bool isCurrentVertexArray(const VertexArray *va) const { return va == mVertexArray; } + + GLES1State &gles1() { return mGLES1State; } + const GLES1State &gles1() const { return mGLES1State; } + + // Helpers for setting bound buffers. They should all have the same signature. + // Not meant to be called externally. Used for local helpers in State.cpp. + template + void setGenericBufferBindingWithBit(const Context *context, Buffer *buffer); + + template + void setGenericBufferBinding(const Context *context, Buffer *buffer); + + using BufferBindingSetter = void (State::*)(const Context *, Buffer *); + + ANGLE_INLINE bool validateSamplerFormats() const + { + return (!mExecutable || !(mTexturesIncompatibleWithSamplers.intersects( + mExecutable->getActiveSamplersMask()))); + } + + ProvokingVertexConvention getProvokingVertex() const { return mProvokingVertex; } + void setProvokingVertex(ProvokingVertexConvention val) + { + mDirtyBits.set(State::DIRTY_BIT_PROVOKING_VERTEX); + mProvokingVertex = val; + } + + ANGLE_INLINE void setReadFramebufferBindingDirty() + { + mDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING); + } + + ANGLE_INLINE void setDrawFramebufferBindingDirty() + { + mDirtyBits.set(State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING); + } + + using ClipDistanceEnableBits = angle::BitSet32; + const ClipDistanceEnableBits &getEnabledClipDistances() const { return mClipDistancesEnabled; } + void setClipDistanceEnable(int idx, bool enable); + + const OverlayType *getOverlay() const { return mOverlay; } + + // Not for general use. + const BufferManager &getBufferManagerForCapture() const { return *mBufferManager; } + const BoundBufferMap &getBoundBuffersForCapture() const { return mBoundBuffers; } + const TextureManager &getTextureManagerForCapture() const { return *mTextureManager; } + const TextureBindingMap &getBoundTexturesForCapture() const { return mSamplerTextures; } + const RenderbufferManager &getRenderbufferManagerForCapture() const + { + return *mRenderbufferManager; + } + const FramebufferManager &getFramebufferManagerForCapture() const + { + return *mFramebufferManager; + } + const ShaderProgramManager &getShaderProgramManagerForCapture() const + { + return *mShaderProgramManager; + } + const SyncManager &getSyncManagerForCapture() const { return *mSyncManager; } + const SamplerManager &getSamplerManagerForCapture() const { return *mSamplerManager; } + const ProgramPipelineManager *getProgramPipelineManagerForCapture() const + { + return mProgramPipelineManager; + } + const SamplerBindingVector &getSamplerBindingsForCapture() const { return mSamplers; } + const ActiveQueryMap &getActiveQueriesForCapture() const { return mActiveQueries; } + void initializeForCapture(const Context *context); + + bool hasConstantAlphaBlendFunc() const + { + return (mBlendFuncConstantAlphaDrawBuffers & mBlendStateExt.getEnabledMask()).any(); + } + + bool hasSimultaneousConstantColorAndAlphaBlendFunc() const + { + return (mBlendFuncConstantColorDrawBuffers & mBlendStateExt.getEnabledMask()).any() && + hasConstantAlphaBlendFunc(); + } + + bool noSimultaneousConstantColorAndAlphaBlendFunc() const + { + return mNoSimultaneousConstantColorAndAlphaBlendFunc; + } + + const BufferVector &getOffsetBindingPointerUniformBuffers() const { return mUniformBuffers; } + + const BufferVector &getOffsetBindingPointerAtomicCounterBuffers() const + { + return mAtomicCounterBuffers; + } + + const BufferVector &getOffsetBindingPointerShaderStorageBuffers() const + { + return mShaderStorageBuffers; + } + + ActiveTextureMask getTexturesIncompatibleWithSamplers() const + { + return mTexturesIncompatibleWithSamplers; + } + + bool isProgramBinaryCacheEnabled() const { return mProgramBinaryCacheEnabled; } + + bool isTextureRectangleEnabled() const { return mTextureRectangleEnabled; } + + DrawBufferMask getBlendFuncConstantAlphaDrawBuffers() const + { + return mBlendFuncConstantAlphaDrawBuffers; + } + + DrawBufferMask getBlendFuncConstantColorDrawBuffers() const + { + return mBlendFuncConstantColorDrawBuffers; + } + + const std::vector &getImageUnits() const { return mImageUnits; } + + bool hasDisplayTextureShareGroup() const { return mDisplayTextureShareGroup; } + + void setLogicOpEnabled(bool enabled); + bool isLogicOpEnabled() const { return mLogicOpEnabled; } + + void setLogicOp(LogicalOperation opcode); + LogicalOperation getLogicOp() const { return mLogicOp; } + + private: + friend class Context; + + void unsetActiveTextures(const ActiveTextureMask &textureMask); + void setActiveTextureDirty(size_t textureIndex, Texture *texture); + void updateTextureBinding(const Context *context, size_t textureIndex, Texture *texture); + void updateActiveTextureStateOnSync(const Context *context, + size_t textureIndex, + const Sampler *sampler, + Texture *texture); + Texture *getTextureForActiveSampler(TextureType type, size_t index); + + bool hasConstantColor(GLenum sourceRGB, GLenum destRGB) const; + bool hasConstantAlpha(GLenum sourceRGB, GLenum destRGB) const; + + // Functions to synchronize dirty states + angle::Result syncActiveTextures(const Context *context, Command command); + angle::Result syncTexturesInit(const Context *context, Command command); + angle::Result syncImagesInit(const Context *context, Command command); + angle::Result syncReadAttachments(const Context *context, Command command); + angle::Result syncDrawAttachments(const Context *context, Command command); + angle::Result syncReadFramebuffer(const Context *context, Command command); + angle::Result syncDrawFramebuffer(const Context *context, Command command); + angle::Result syncVertexArray(const Context *context, Command command); + angle::Result syncTextures(const Context *context, Command command); + angle::Result syncImages(const Context *context, Command command); + angle::Result syncSamplers(const Context *context, Command command); + angle::Result syncProgram(const Context *context, Command command); + angle::Result syncProgramPipelineObject(const Context *context, Command command); + + using DirtyObjectHandler = angle::Result (State::*)(const Context *context, Command command); + + static constexpr DirtyObjectHandler kDirtyObjectHandlers[DIRTY_OBJECT_MAX] = { + &State::syncActiveTextures, + &State::syncTexturesInit, + &State::syncImagesInit, + &State::syncReadAttachments, + &State::syncDrawAttachments, + &State::syncReadFramebuffer, + &State::syncDrawFramebuffer, + &State::syncVertexArray, + &State::syncTextures, + &State::syncImages, + &State::syncSamplers, + &State::syncProgram, + &State::syncProgramPipelineObject}; + + // Robust init must happen before Framebuffer init for the Vulkan back-end. + static_assert(DIRTY_OBJECT_ACTIVE_TEXTURES < DIRTY_OBJECT_TEXTURES_INIT, "init order"); + static_assert(DIRTY_OBJECT_TEXTURES_INIT < DIRTY_OBJECT_DRAW_FRAMEBUFFER, "init order"); + static_assert(DIRTY_OBJECT_IMAGES_INIT < DIRTY_OBJECT_DRAW_FRAMEBUFFER, "init order"); + static_assert(DIRTY_OBJECT_DRAW_ATTACHMENTS < DIRTY_OBJECT_DRAW_FRAMEBUFFER, "init order"); + static_assert(DIRTY_OBJECT_READ_ATTACHMENTS < DIRTY_OBJECT_READ_FRAMEBUFFER, "init order"); + + static_assert(DIRTY_OBJECT_ACTIVE_TEXTURES == 0, "check DIRTY_OBJECT_ACTIVE_TEXTURES index"); + static_assert(DIRTY_OBJECT_TEXTURES_INIT == 1, "check DIRTY_OBJECT_TEXTURES_INIT index"); + static_assert(DIRTY_OBJECT_IMAGES_INIT == 2, "check DIRTY_OBJECT_IMAGES_INIT index"); + static_assert(DIRTY_OBJECT_READ_ATTACHMENTS == 3, "check DIRTY_OBJECT_READ_ATTACHMENTS index"); + static_assert(DIRTY_OBJECT_DRAW_ATTACHMENTS == 4, "check DIRTY_OBJECT_DRAW_ATTACHMENTS index"); + static_assert(DIRTY_OBJECT_READ_FRAMEBUFFER == 5, "check DIRTY_OBJECT_READ_FRAMEBUFFER index"); + static_assert(DIRTY_OBJECT_DRAW_FRAMEBUFFER == 6, "check DIRTY_OBJECT_DRAW_FRAMEBUFFER index"); + static_assert(DIRTY_OBJECT_VERTEX_ARRAY == 7, "check DIRTY_OBJECT_VERTEX_ARRAY index"); + static_assert(DIRTY_OBJECT_TEXTURES == 8, "check DIRTY_OBJECT_TEXTURES index"); + static_assert(DIRTY_OBJECT_IMAGES == 9, "check DIRTY_OBJECT_IMAGES index"); + static_assert(DIRTY_OBJECT_SAMPLERS == 10, "check DIRTY_OBJECT_SAMPLERS index"); + static_assert(DIRTY_OBJECT_PROGRAM == 11, "check DIRTY_OBJECT_PROGRAM index"); + static_assert(DIRTY_OBJECT_PROGRAM_PIPELINE_OBJECT == 12, + "check DIRTY_OBJECT_PROGRAM_PIPELINE_OBJECT index"); + + // Dispatch table for buffer update functions. + static const angle::PackedEnumMap kBufferSetters; + + ContextID mID; + + EGLenum mClientType; + EGLint mProfileMask; + EGLenum mContextPriority; + bool mHasRobustAccess; + bool mHasProtectedContent; + bool mIsDebugContext; + Version mClientVersion; + + // Caps to use for validation + Caps mCaps; + TextureCapsMap mTextureCaps; + Extensions mExtensions; + Limitations mLimitations; + + egl::ShareGroup *mShareGroup; + + // Resource managers. + BufferManager *mBufferManager; + ShaderProgramManager *mShaderProgramManager; + TextureManager *mTextureManager; + RenderbufferManager *mRenderbufferManager; + SamplerManager *mSamplerManager; + SyncManager *mSyncManager; + FramebufferManager *mFramebufferManager; + ProgramPipelineManager *mProgramPipelineManager; + MemoryObjectManager *mMemoryObjectManager; + SemaphoreManager *mSemaphoreManager; + + ColorF mColorClearValue; + GLfloat mDepthClearValue; + int mStencilClearValue; + + RasterizerState mRasterizer; + bool mScissorTest; + Rectangle mScissor; + + bool mNoUnclampedBlendColor; + + BlendState mBlendState; // Buffer zero blend state legacy struct + BlendStateExt mBlendStateExt; + ColorF mBlendColor; + bool mSampleAlphaToCoverage; + bool mSampleCoverage; + GLfloat mSampleCoverageValue; + bool mSampleCoverageInvert; + bool mSampleMask; + GLuint mMaxSampleMaskWords; + SampleMaskArray mSampleMaskValues; + bool mIsSampleShadingEnabled; + float mMinSampleShading; + + DepthStencilState mDepthStencil; + GLint mStencilRef; + GLint mStencilBackRef; + + GLfloat mLineWidth; + + GLenum mGenerateMipmapHint; + GLenum mTextureFilteringHint; + GLenum mFragmentShaderDerivativeHint; + + const bool mBindGeneratesResource; + const bool mClientArraysEnabled; + + Rectangle mViewport; + float mNearZ; + float mFarZ; + + GLenum mClipControlOrigin; + GLenum mClipControlDepth; + + Framebuffer *mReadFramebuffer; + Framebuffer *mDrawFramebuffer; + BindingPointer mRenderbuffer; + Program *mProgram; + BindingPointer mProgramPipeline; + ProgramExecutable *mExecutable; + + // GL_ANGLE_provoking_vertex + ProvokingVertexConvention mProvokingVertex; + + using VertexAttribVector = std::vector; + VertexAttribVector mVertexAttribCurrentValues; // From glVertexAttrib + VertexArray *mVertexArray; + ComponentTypeMask mCurrentValuesTypeMask; + + // Texture and sampler bindings + GLint mActiveSampler; // Active texture unit selector - GL_TEXTURE0 + + TextureBindingMap mSamplerTextures; + + // Active Textures Cache + // --------------------- + // The active textures cache gives ANGLE components access to a complete array of textures + // on a draw call. gl::State implements angle::Observer and watches gl::Texture for state + // changes via the onSubjectStateChange method above. We update the cache before draws. + // See Observer.h and the design doc linked there for more info on Subject/Observer events. + // + // On state change events (re-binding textures, samplers, programs etc) we clear the cache + // and flag dirty bits. nullptr indicates unbound or incomplete. + ActiveTexturesCache mActiveTexturesCache; + std::vector mCompleteTextureBindings; + + ActiveTextureMask mTexturesIncompatibleWithSamplers; + + SamplerBindingVector mSamplers; + + // It would be nice to merge the image and observer binding. Same for textures. + std::vector mImageUnits; + + ActiveQueryMap mActiveQueries; + + // Stores the currently bound buffer for each binding point. It has an entry for the element + // array buffer but it should not be used. Instead this bind point is owned by the current + // vertex array object. + BoundBufferMap mBoundBuffers; + + BufferVector mUniformBuffers; + BufferVector mAtomicCounterBuffers; + BufferVector mShaderStorageBuffers; + + angle::BitSet mBoundUniformBuffersMask; + angle::BitSet + mBoundAtomicCounterBuffersMask; + angle::BitSet + mBoundShaderStorageBuffersMask; + + BindingPointer mTransformFeedback; + + PixelUnpackState mUnpack; + PixelPackState mPack; + + bool mPrimitiveRestart; + + Debug mDebug; + + bool mMultiSampling; + bool mSampleAlphaToOne; + + GLenum mCoverageModulation; + + // GL_EXT_sRGB_write_control + bool mFramebufferSRGB; + + // GL_ANGLE_robust_resource_initialization + const bool mRobustResourceInit; + + // GL_ANGLE_program_cache_control + const bool mProgramBinaryCacheEnabled; + + // GL_ANGLE_webgl_compatibility + bool mTextureRectangleEnabled; + + // GL_ANGLE_logic_op + bool mLogicOpEnabled; + LogicalOperation mLogicOp; + + // GL_KHR_parallel_shader_compile + GLuint mMaxShaderCompilerThreads; + + // GL_APPLE_clip_distance/GL_EXT_clip_cull_distance + ClipDistanceEnableBits mClipDistancesEnabled; + + // GL_EXT_tessellation_shader + GLuint mPatchVertices; + + // GL_ANGLE_shader_pixel_local_storage + bool mPixelLocalStorageActive; + + // GLES1 emulation: state specific to GLES1 + GLES1State mGLES1State; + + DirtyBits mDirtyBits; + mutable ExtendedDirtyBits mExtendedDirtyBits; + DirtyObjects mDirtyObjects; + mutable AttributesMask mDirtyCurrentValues; + ActiveTextureMask mDirtyActiveTextures; + ActiveTextureMask mDirtyTextures; + ActiveTextureMask mDirtySamplers; + ImageUnitMask mDirtyImages; + + // The Overlay object, used by the backend to render the overlay. + const OverlayType *mOverlay; + + // OES_draw_buffers_indexed + DrawBufferMask mBlendFuncConstantAlphaDrawBuffers; + DrawBufferMask mBlendFuncConstantColorDrawBuffers; + bool mNoSimultaneousConstantColorAndAlphaBlendFunc; + // Whether the indexed variants of setBlend* have been called. If so, the call to the + // non-indexed variants are not no-oped. + bool mSetBlendIndexedInvoked; + bool mSetBlendFactorsIndexedInvoked; + bool mSetBlendEquationsIndexedInvoked; + bool mDisplayTextureShareGroup; + + // GL_EXT_primitive_bounding_box + GLfloat mBoundingBoxMinX; + GLfloat mBoundingBoxMinY; + GLfloat mBoundingBoxMinZ; + GLfloat mBoundingBoxMinW; + GLfloat mBoundingBoxMaxX; + GLfloat mBoundingBoxMaxY; + GLfloat mBoundingBoxMaxZ; + GLfloat mBoundingBoxMaxW; + + // QCOM_shading_rate + bool mShadingRatePreserveAspectRatio; + ShadingRate mShadingRate; +}; + +ANGLE_INLINE angle::Result State::syncDirtyObjects(const Context *context, + const DirtyObjects &bitset, + Command command) +{ + const DirtyObjects &dirtyObjects = mDirtyObjects & bitset; + + for (size_t dirtyObject : dirtyObjects) + { + ANGLE_TRY((this->*kDirtyObjectHandlers[dirtyObject])(context, command)); + } + + mDirtyObjects &= ~dirtyObjects; + return angle::Result::Continue; +} + +} // namespace gl + +#endif // LIBANGLE_STATE_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Stream.cpp b/gfx/angle/checkout/src/libANGLE/Stream.cpp new file mode 100644 index 0000000000..8d2830287f --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Stream.cpp @@ -0,0 +1,282 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Stream.cpp: Implements the egl::Stream class, representing the stream +// where frames are streamed in. Implements EGLStreanKHR. + +#include "libANGLE/Stream.h" + +#include +#include + +#include "common/debug.h" +#include "common/mathutil.h" +#include "common/platform.h" +#include "common/utilities.h" +#include "libANGLE/Context.h" +#include "libANGLE/Display.h" +#include "libANGLE/renderer/DisplayImpl.h" +#include "libANGLE/renderer/StreamProducerImpl.h" + +namespace egl +{ + +Stream::Stream(Display *display, const AttributeMap &attribs) + : mLabel(nullptr), + mDisplay(display), + mProducerImplementation(nullptr), + mState(EGL_STREAM_STATE_CREATED_KHR), + mProducerFrame(0), + mConsumerFrame(0), + mConsumerLatency(attribs.getAsInt(EGL_CONSUMER_LATENCY_USEC_KHR, 0)), + mConsumerAcquireTimeout(attribs.getAsInt(EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR, 0)), + mPlaneCount(0), + mConsumerType(ConsumerType::NoConsumer), + mProducerType(ProducerType::NoProducer) +{ + for (auto &plane : mPlanes) + { + plane.textureUnit = -1; + plane.texture = nullptr; + } +} + +Stream::~Stream() +{ + SafeDelete(mProducerImplementation); + for (auto &plane : mPlanes) + { + if (plane.texture != nullptr) + { + plane.texture->releaseStream(); + } + } +} + +void Stream::setLabel(EGLLabelKHR label) +{ + mLabel = label; +} + +EGLLabelKHR Stream::getLabel() const +{ + return mLabel; +} + +void Stream::setConsumerLatency(EGLint latency) +{ + mConsumerLatency = latency; +} + +EGLint Stream::getConsumerLatency() const +{ + return mConsumerLatency; +} + +EGLuint64KHR Stream::getProducerFrame() const +{ + return mProducerFrame; +} + +EGLuint64KHR Stream::getConsumerFrame() const +{ + return mConsumerFrame; +} + +EGLenum Stream::getState() const +{ + return mState; +} + +void Stream::setConsumerAcquireTimeout(EGLint timeout) +{ + mConsumerAcquireTimeout = timeout; +} + +EGLint Stream::getConsumerAcquireTimeout() const +{ + return mConsumerAcquireTimeout; +} + +Stream::ProducerType Stream::getProducerType() const +{ + return mProducerType; +} + +Stream::ConsumerType Stream::getConsumerType() const +{ + return mConsumerType; +} + +EGLint Stream::getPlaneCount() const +{ + return mPlaneCount; +} + +rx::StreamProducerImpl *Stream::getImplementation() +{ + return mProducerImplementation; +} + +Error Stream::createConsumerGLTextureExternal(const AttributeMap &attributes, gl::Context *context) +{ + ASSERT(mState == EGL_STREAM_STATE_CREATED_KHR); + ASSERT(mConsumerType == ConsumerType::NoConsumer); + ASSERT(mProducerType == ProducerType::NoProducer); + ASSERT(context != nullptr); + + const auto &glState = context->getState(); + EGLenum bufferType = attributes.getAsInt(EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER); + if (bufferType == EGL_RGB_BUFFER) + { + mPlanes[0].texture = glState.getTargetTexture(gl::TextureType::External); + ASSERT(mPlanes[0].texture != nullptr); + mPlanes[0].texture->bindStream(this); + mConsumerType = ConsumerType::GLTextureRGB; + mPlaneCount = 1; + } + else + { + mPlaneCount = attributes.getAsInt(EGL_YUV_NUMBER_OF_PLANES_EXT, 2); + ASSERT(mPlaneCount <= 3); + for (EGLint i = 0; i < mPlaneCount; i++) + { + // Fetch all the textures + mPlanes[i].textureUnit = attributes.getAsInt(EGL_YUV_PLANE0_TEXTURE_UNIT_NV + i, -1); + if (mPlanes[i].textureUnit != EGL_NONE) + { + mPlanes[i].texture = + glState.getSamplerTexture(mPlanes[i].textureUnit, gl::TextureType::External); + ASSERT(mPlanes[i].texture != nullptr); + } + } + + // Bind them to the stream + for (EGLint i = 0; i < mPlaneCount; i++) + { + if (mPlanes[i].textureUnit != EGL_NONE) + { + mPlanes[i].texture->bindStream(this); + } + } + mConsumerType = ConsumerType::GLTextureYUV; + } + + mContext = context; + mState = EGL_STREAM_STATE_CONNECTING_KHR; + + return NoError(); +} + +Error Stream::createProducerD3D11Texture(const AttributeMap &attributes) +{ + ASSERT(mState == EGL_STREAM_STATE_CONNECTING_KHR); + ASSERT(mConsumerType == ConsumerType::GLTextureRGB || + mConsumerType == ConsumerType::GLTextureYUV); + ASSERT(mProducerType == ProducerType::NoProducer); + + mProducerImplementation = + mDisplay->getImplementation()->createStreamProducerD3DTexture(mConsumerType, attributes); + mProducerType = ProducerType::D3D11Texture; + mState = EGL_STREAM_STATE_EMPTY_KHR; + + return NoError(); +} + +// Called when the consumer of this stream starts using the stream +Error Stream::consumerAcquire(const gl::Context *context) +{ + ASSERT(mState == EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR || + mState == EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR); + ASSERT(mConsumerType == ConsumerType::GLTextureRGB || + mConsumerType == ConsumerType::GLTextureYUV); + ASSERT(mProducerType == ProducerType::D3D11Texture); + + mState = EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR; + mConsumerFrame++; + + // Bind the planes to the gl textures + for (int i = 0; i < mPlaneCount; i++) + { + if (mPlanes[i].texture != nullptr) + { + ANGLE_TRY(ResultToEGL(mPlanes[i].texture->acquireImageFromStream( + context, mProducerImplementation->getGLFrameDescription(i)))); + } + } + + return NoError(); +} + +Error Stream::consumerRelease(const gl::Context *context) +{ + ASSERT(mState == EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR || + mState == EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR); + ASSERT(mConsumerType == ConsumerType::GLTextureRGB || + mConsumerType == ConsumerType::GLTextureYUV); + ASSERT(mProducerType == ProducerType::D3D11Texture); + + // Release the images + for (int i = 0; i < mPlaneCount; i++) + { + if (mPlanes[i].texture != nullptr) + { + ANGLE_TRY(ResultToEGL(mPlanes[i].texture->releaseImageFromStream(context))); + } + } + + return NoError(); +} + +bool Stream::isConsumerBoundToContext(const gl::Context *context) const +{ + ASSERT(context != nullptr); + return (context == mContext); +} + +Error Stream::validateD3D11Texture(const void *texture, const AttributeMap &attributes) const +{ + ASSERT(mConsumerType == ConsumerType::GLTextureRGB || + mConsumerType == ConsumerType::GLTextureYUV); + ASSERT(mProducerType == ProducerType::D3D11Texture); + ASSERT(mProducerImplementation != nullptr); + + return mProducerImplementation->validateD3DTexture(texture, attributes); +} + +Error Stream::postD3D11Texture(void *texture, const AttributeMap &attributes) +{ + ASSERT(mConsumerType == ConsumerType::GLTextureRGB || + mConsumerType == ConsumerType::GLTextureYUV); + ASSERT(mProducerType == ProducerType::D3D11Texture); + + mProducerImplementation->postD3DTexture(texture, attributes); + mProducerFrame++; + + mState = EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR; + + return NoError(); +} + +// This is called when a texture object associated with this stream is destroyed. Even if multiple +// textures are bound, one being destroyed invalidates the stream, so all the remaining textures +// will be released and the stream will be invalidated. +void Stream::releaseTextures() +{ + for (auto &plane : mPlanes) + { + if (plane.texture != nullptr) + { + plane.texture->releaseStream(); + plane.texture = nullptr; + } + } + mConsumerType = ConsumerType::NoConsumer; + mProducerType = ProducerType::NoProducer; + mState = EGL_STREAM_STATE_DISCONNECTED_KHR; +} + +} // namespace egl diff --git a/gfx/angle/checkout/src/libANGLE/Stream.h b/gfx/angle/checkout/src/libANGLE/Stream.h new file mode 100644 index 0000000000..b53c90b764 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Stream.h @@ -0,0 +1,149 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Stream.h: Defines the egl::Stream class, representing the stream +// where frames are streamed in. Implements EGLStreanKHR. + +#ifndef LIBANGLE_STREAM_H_ +#define LIBANGLE_STREAM_H_ + +#include + +#include +#include + +#include "common/angleutils.h" +#include "libANGLE/AttributeMap.h" +#include "libANGLE/Debug.h" + +namespace rx +{ +class StreamProducerImpl; +} + +namespace gl +{ +class Context; +class Texture; +} // namespace gl + +namespace egl +{ +class Display; +class Error; +class Thread; + +class Stream final : public LabeledObject, angle::NonCopyable +{ + public: + Stream(Display *display, const AttributeMap &attribs); + ~Stream() override; + + void setLabel(EGLLabelKHR label) override; + EGLLabelKHR getLabel() const override; + + enum class ConsumerType + { + NoConsumer, + GLTextureRGB, + GLTextureYUV, + }; + + enum class ProducerType + { + NoProducer, + D3D11Texture, + }; + + // A GL texture interpretation of a part of a producer frame. For use with GL texture consumers + struct GLTextureDescription + { + unsigned int width; + unsigned int height; + unsigned int internalFormat; + unsigned int mipLevels; + }; + + EGLenum getState() const; + + void setConsumerLatency(EGLint latency); + EGLint getConsumerLatency() const; + + EGLuint64KHR getProducerFrame() const; + EGLuint64KHR getConsumerFrame() const; + + void setConsumerAcquireTimeout(EGLint timeout); + EGLint getConsumerAcquireTimeout() const; + + ConsumerType getConsumerType() const; + ProducerType getProducerType() const; + + EGLint getPlaneCount() const; + + rx::StreamProducerImpl *getImplementation(); + + // Consumer creation methods + Error createConsumerGLTextureExternal(const AttributeMap &attributes, gl::Context *context); + + // Producer creation methods + Error createProducerD3D11Texture(const AttributeMap &attributes); + + // Consumer methods + Error consumerAcquire(const gl::Context *context); + Error consumerRelease(const gl::Context *context); + + // Some consumers are bound to GL contexts. This validates that a given context is bound to the + // stream's consumer + bool isConsumerBoundToContext(const gl::Context *context) const; + + // Producer methods + Error validateD3D11Texture(const void *texture, const AttributeMap &attributes) const; + Error postD3D11Texture(void *texture, const AttributeMap &attributes); + + private: + EGLLabelKHR mLabel; + + // Associated display + Display *mDisplay; + + // Producer Implementation + rx::StreamProducerImpl *mProducerImplementation; + + // Associated GL context. Note that this is a weak pointer used for validation purposes only, + // and should never be arbitrarily dereferenced without knowing the context still exists as it + // can become dangling at any time. + gl::Context *mContext; + + // EGL defined attributes + EGLint mState; + EGLuint64KHR mProducerFrame; + EGLuint64KHR mConsumerFrame; + EGLint mConsumerLatency; + + // EGL gltexture consumer attributes + EGLint mConsumerAcquireTimeout; + + // EGL gltexture yuv consumer attributes + EGLint mPlaneCount; + struct PlaneTexture + { + EGLint textureUnit; + gl::Texture *texture; + }; + // Texture units and textures for all the planes + std::array mPlanes; + + // Consumer and producer types + ConsumerType mConsumerType; + ProducerType mProducerType; + + // ANGLE-only method, used internally + friend class gl::Texture; + void releaseTextures(); +}; +} // namespace egl + +#endif // LIBANGLE_STREAM_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Surface.cpp b/gfx/angle/checkout/src/libANGLE/Surface.cpp new file mode 100644 index 0000000000..acb382dd10 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Surface.cpp @@ -0,0 +1,941 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Surface.cpp: Implements the egl::Surface class, representing a drawing surface +// such as the client area of a window, including any back buffers. +// Implements EGLSurface and related functionality. [EGL 1.4] section 2.2 page 3. + +#include "libANGLE/Surface.h" + +#include + +#include "libANGLE/Config.h" +#include "libANGLE/Context.h" +#include "libANGLE/Display.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/Texture.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/EGLImplFactory.h" +#include "libANGLE/trace.h" + +namespace egl +{ +namespace +{ +angle::SubjectIndex kSurfaceImplSubjectIndex = 0; +} // namespace + +SurfaceState::SurfaceState(const egl::Config *configIn, const AttributeMap &attributesIn) + : label(nullptr), + config((configIn != nullptr) ? new egl::Config(*configIn) : nullptr), + attributes(attributesIn), + timestampsEnabled(false), + autoRefreshEnabled(false), + directComposition(false), + swapBehavior(EGL_NONE) +{ + directComposition = attributes.get(EGL_DIRECT_COMPOSITION_ANGLE, EGL_FALSE) == EGL_TRUE; +} + +SurfaceState::~SurfaceState() +{ + delete config; +} + +bool SurfaceState::isRobustResourceInitEnabled() const +{ + return attributes.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE; +} + +bool SurfaceState::hasProtectedContent() const +{ + return attributes.get(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE) == EGL_TRUE; +} + +EGLint SurfaceState::getPreferredSwapInterval() const +{ + return attributes.getAsInt(EGL_SWAP_INTERVAL_ANGLE, 1); +} + +Surface::Surface(EGLint surfaceType, + GLuint serialId, + const egl::Config *config, + const AttributeMap &attributes, + bool forceRobustResourceInit, + EGLenum buftype) + : FramebufferAttachmentObject(), + mState(config, attributes), + mImplementation(nullptr), + mRefCount(0), + mDestroyed(false), + mType(surfaceType), + mBuftype(buftype), + mPostSubBufferRequested(false), + mLargestPbuffer(false), + mGLColorspace(EGL_GL_COLORSPACE_LINEAR), + mVGAlphaFormat(EGL_VG_ALPHA_FORMAT_NONPRE), + mVGColorspace(EGL_VG_COLORSPACE_sRGB), + mMipmapTexture(false), + mMipmapLevel(0), + mHorizontalResolution(EGL_UNKNOWN), + mVerticalResolution(EGL_UNKNOWN), + mMultisampleResolve(EGL_MULTISAMPLE_RESOLVE_DEFAULT), + mFixedSize(false), + mFixedWidth(0), + mFixedHeight(0), + mTextureFormat(TextureFormat::NoTexture), + mTextureTarget(EGL_NO_TEXTURE), + // FIXME: Determine actual pixel aspect ratio + mPixelAspectRatio(static_cast(1.0 * EGL_DISPLAY_SCALING)), + mRenderBuffer(EGL_BACK_BUFFER), + mOrientation(0), + mTexture(nullptr), + mColorFormat(config->renderTargetFormat), + mDSFormat(config->depthStencilFormat), + mIsCurrentOnAnyContext(false), + mLockBufferPtr(nullptr), + mLockBufferPitch(0), + mBufferAgeQueriedSinceLastSwap(false), + mIsDamageRegionSet(false), + mColorInitState(gl::InitState::Initialized), + mDepthStencilInitState(gl::InitState::Initialized), + mImplObserverBinding(this, kSurfaceImplSubjectIndex), + mSerialId(serialId) +{ + mPostSubBufferRequested = + (attributes.get(EGL_POST_SUB_BUFFER_SUPPORTED_NV, EGL_FALSE) == EGL_TRUE); + + if (mType == EGL_PBUFFER_BIT) + { + mLargestPbuffer = (attributes.get(EGL_LARGEST_PBUFFER, EGL_FALSE) == EGL_TRUE); + } + + if (mType == EGL_PIXMAP_BIT) + { + mRenderBuffer = EGL_SINGLE_BUFFER; + } + + if (mType == EGL_WINDOW_BIT) + { + mRenderBuffer = mState.attributes.getAsInt(EGL_RENDER_BUFFER, EGL_BACK_BUFFER); + } + + mGLColorspace = + static_cast(attributes.get(EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_LINEAR)); + mVGAlphaFormat = + static_cast(attributes.get(EGL_VG_ALPHA_FORMAT, EGL_VG_ALPHA_FORMAT_NONPRE)); + mVGColorspace = static_cast(attributes.get(EGL_VG_COLORSPACE, EGL_VG_COLORSPACE_sRGB)); + mMipmapTexture = (attributes.get(EGL_MIPMAP_TEXTURE, EGL_FALSE) == EGL_TRUE); + + mRobustResourceInitialization = + forceRobustResourceInit || + (attributes.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE); + if (mRobustResourceInitialization) + { + mColorInitState = gl::InitState::MayNeedInit; + mDepthStencilInitState = gl::InitState::MayNeedInit; + } + + mFixedSize = (attributes.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE) == EGL_TRUE); + if (mFixedSize) + { + mFixedWidth = static_cast(attributes.get(EGL_WIDTH, 0)); + mFixedHeight = static_cast(attributes.get(EGL_HEIGHT, 0)); + } + + if (mType != EGL_WINDOW_BIT) + { + mTextureFormat = attributes.getAsPackedEnum(EGL_TEXTURE_FORMAT, TextureFormat::NoTexture); + mTextureTarget = static_cast(attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE)); + } + + mOrientation = static_cast(attributes.get(EGL_SURFACE_ORIENTATION_ANGLE, 0)); + + mTextureOffset.x = static_cast(mState.attributes.get(EGL_TEXTURE_OFFSET_X_ANGLE, 0)); + mTextureOffset.y = static_cast(mState.attributes.get(EGL_TEXTURE_OFFSET_Y_ANGLE, 0)); +} + +Surface::~Surface() {} + +rx::FramebufferAttachmentObjectImpl *Surface::getAttachmentImpl() const +{ + return mImplementation; +} + +Error Surface::destroyImpl(const Display *display) +{ + if (mImplementation) + { + mImplementation->destroy(display); + } + + ASSERT(!mTexture); + + SafeDelete(mImplementation); + + delete this; + return NoError(); +} + +void Surface::postSwap(const gl::Context *context) +{ + if (mRobustResourceInitialization && mState.swapBehavior != EGL_BUFFER_PRESERVED) + { + mColorInitState = gl::InitState::MayNeedInit; + mDepthStencilInitState = gl::InitState::MayNeedInit; + onStateChange(angle::SubjectMessage::SubjectChanged); + } + + mBufferAgeQueriedSinceLastSwap = false; + + mIsDamageRegionSet = false; +} + +Error Surface::initialize(const Display *display) +{ + GLenum overrideRenderTargetFormat = mState.config->renderTargetFormat; + + // To account for color space differences, override the renderTargetFormat with the + // non-linear format. If no suitable non-linear format was found, return + // EGL_BAD_MATCH error + if (!gl::ColorspaceFormatOverride(mGLColorspace, &overrideRenderTargetFormat)) + { + return egl::EglBadMatch(); + } + + // If an override is required update mState.config as well + if (mState.config->renderTargetFormat != overrideRenderTargetFormat) + { + egl::Config *overrideConfig = new egl::Config(*(mState.config)); + overrideConfig->renderTargetFormat = overrideRenderTargetFormat; + delete mState.config; + mState.config = overrideConfig; + + mColorFormat = gl::Format(mState.config->renderTargetFormat); + mDSFormat = gl::Format(mState.config->depthStencilFormat); + } + + ANGLE_TRY(mImplementation->initialize(display)); + + // Initialized here since impl is nullptr in the constructor. + // Must happen after implementation initialize for Android. + mState.swapBehavior = mImplementation->getSwapBehavior(); + + if (mBuftype == EGL_IOSURFACE_ANGLE) + { + GLenum internalFormat = + static_cast(mState.attributes.get(EGL_TEXTURE_INTERNAL_FORMAT_ANGLE)); + GLenum type = static_cast(mState.attributes.get(EGL_TEXTURE_TYPE_ANGLE)); + + // GL_RGBA + GL_HALF_FLOAT is not a valid format/type combination in GLES like it is in + // desktop GL. Adjust the frontend format to be sized RGBA16F. + if (internalFormat == GL_RGBA && type == GL_HALF_FLOAT) + { + internalFormat = GL_RGBA16F; + } + mColorFormat = gl::Format(internalFormat, type); + } + if (mBuftype == EGL_D3D_TEXTURE_ANGLE) + { + const angle::Format *colorFormat = mImplementation->getD3DTextureColorFormat(); + ASSERT(colorFormat != nullptr); + GLenum internalFormat = colorFormat->fboImplementationInternalFormat; + mColorFormat = gl::Format(internalFormat, colorFormat->componentType); + mGLColorspace = EGL_GL_COLORSPACE_LINEAR; + if (mColorFormat.info->colorEncoding == GL_SRGB) + { + mGLColorspace = EGL_GL_COLORSPACE_SRGB; + } + } + + if (mType == EGL_WINDOW_BIT && display->getExtensions().getFrameTimestamps) + { + mState.supportedCompositorTimings = mImplementation->getSupportedCompositorTimings(); + mState.supportedTimestamps = mImplementation->getSupportedTimestamps(); + } + + mImplObserverBinding.bind(mImplementation); + + return NoError(); +} + +Error Surface::makeCurrent(const gl::Context *context) +{ + if (isLocked()) + { + return EglBadAccess(); + } + ANGLE_TRY(mImplementation->makeCurrent(context)); + mIsCurrentOnAnyContext = true; + addRef(); + return NoError(); +} + +Error Surface::unMakeCurrent(const gl::Context *context) +{ + ANGLE_TRY(mImplementation->unMakeCurrent(context)); + mIsCurrentOnAnyContext = false; + return releaseRef(context->getDisplay()); +} + +Error Surface::releaseRef(const Display *display) +{ + ASSERT(mRefCount > 0); + mRefCount--; + if (mRefCount == 0 && mDestroyed) + { + ASSERT(display); + return destroyImpl(display); + } + + return NoError(); +} + +Error Surface::onDestroy(const Display *display) +{ + mDestroyed = true; + if (mRefCount == 0) + { + return destroyImpl(display); + } + return NoError(); +} + +void Surface::setLabel(EGLLabelKHR label) +{ + mState.label = label; +} + +EGLLabelKHR Surface::getLabel() const +{ + return mState.label; +} + +EGLint Surface::getType() const +{ + return mType; +} + +Error Surface::prepareSwap(const gl::Context *context) +{ + ANGLE_TRACE_EVENT0("gpu.angle", "egl::Surface::prepareSwap"); + return mImplementation->prepareSwap(context); +} + +Error Surface::swap(const gl::Context *context) +{ + ANGLE_TRACE_EVENT0("gpu.angle", "egl::Surface::swap"); + context->onPreSwap(); + + context->getState().getOverlay()->onSwap(); + + ANGLE_TRY(mImplementation->swap(context)); + postSwap(context); + return NoError(); +} + +Error Surface::swapWithDamage(const gl::Context *context, const EGLint *rects, EGLint n_rects) +{ + ANGLE_TRACE_EVENT0("gpu.angle", "egl::Surface::swapWithDamage"); + context->onPreSwap(); + + context->getState().getOverlay()->onSwap(); + + ANGLE_TRY(mImplementation->swapWithDamage(context, rects, n_rects)); + postSwap(context); + return NoError(); +} + +Error Surface::swapWithFrameToken(const gl::Context *context, EGLFrameTokenANGLE frameToken) +{ + ANGLE_TRACE_EVENT0("gpu.angle", "egl::Surface::swapWithFrameToken"); + context->onPreSwap(); + + context->getState().getOverlay()->onSwap(); + + ANGLE_TRY(mImplementation->swapWithFrameToken(context, frameToken)); + postSwap(context); + return NoError(); +} + +Error Surface::postSubBuffer(const gl::Context *context, + EGLint x, + EGLint y, + EGLint width, + EGLint height) +{ + if (width == 0 || height == 0) + { + return egl::NoError(); + } + + context->getState().getOverlay()->onSwap(); + + ANGLE_TRY(mImplementation->postSubBuffer(context, x, y, width, height)); + postSwap(context); + return NoError(); +} + +Error Surface::setPresentationTime(EGLnsecsANDROID time) +{ + return mImplementation->setPresentationTime(time); +} + +Error Surface::querySurfacePointerANGLE(EGLint attribute, void **value) +{ + return mImplementation->querySurfacePointerANGLE(attribute, value); +} + +EGLint Surface::isPostSubBufferSupported() const +{ + return mPostSubBufferRequested && mImplementation->isPostSubBufferSupported(); +} + +void Surface::setSwapInterval(EGLint interval) +{ + mImplementation->setSwapInterval(interval); +} + +void Surface::setMipmapLevel(EGLint level) +{ + // Level is set but ignored + UNIMPLEMENTED(); + mMipmapLevel = level; +} + +void Surface::setMultisampleResolve(EGLenum resolve) +{ + // Behaviour is set but ignored + UNIMPLEMENTED(); + mMultisampleResolve = resolve; +} + +void Surface::setSwapBehavior(EGLenum behavior) +{ + // Behaviour is set but ignored + UNIMPLEMENTED(); + mState.swapBehavior = behavior; +} + +void Surface::setFixedWidth(EGLint width) +{ + mFixedWidth = width; + mImplementation->setFixedWidth(width); +} + +void Surface::setFixedHeight(EGLint height) +{ + mFixedHeight = height; + mImplementation->setFixedHeight(height); +} + +const Config *Surface::getConfig() const +{ + return mState.config; +} + +EGLint Surface::getPixelAspectRatio() const +{ + return mPixelAspectRatio; +} + +EGLenum Surface::getRenderBuffer() const +{ + return mRenderBuffer; +} + +EGLenum Surface::getSwapBehavior() const +{ + return mState.swapBehavior; +} + +TextureFormat Surface::getTextureFormat() const +{ + return mTextureFormat; +} + +EGLenum Surface::getTextureTarget() const +{ + return mTextureTarget; +} + +bool Surface::getLargestPbuffer() const +{ + return mLargestPbuffer; +} + +EGLenum Surface::getGLColorspace() const +{ + return mGLColorspace; +} + +EGLenum Surface::getVGAlphaFormat() const +{ + return mVGAlphaFormat; +} + +EGLenum Surface::getVGColorspace() const +{ + return mVGColorspace; +} + +bool Surface::getMipmapTexture() const +{ + return mMipmapTexture; +} + +EGLint Surface::getMipmapLevel() const +{ + return mMipmapLevel; +} + +EGLint Surface::getHorizontalResolution() const +{ + return mHorizontalResolution; +} + +EGLint Surface::getVerticalResolution() const +{ + return mVerticalResolution; +} + +EGLenum Surface::getMultisampleResolve() const +{ + return mMultisampleResolve; +} + +EGLint Surface::isFixedSize() const +{ + return mFixedSize; +} + +EGLint Surface::getWidth() const +{ + return mFixedSize ? static_cast(mFixedWidth) : mImplementation->getWidth(); +} + +EGLint Surface::getHeight() const +{ + return mFixedSize ? static_cast(mFixedHeight) : mImplementation->getHeight(); +} + +egl::Error Surface::getUserWidth(const egl::Display *display, EGLint *value) const +{ + if (mFixedSize) + { + *value = static_cast(mFixedWidth); + return NoError(); + } + else + { + return mImplementation->getUserWidth(display, value); + } +} + +egl::Error Surface::getUserHeight(const egl::Display *display, EGLint *value) const +{ + if (mFixedSize) + { + *value = static_cast(mFixedHeight); + return NoError(); + } + else + { + return mImplementation->getUserHeight(display, value); + } +} + +Error Surface::bindTexImage(gl::Context *context, gl::Texture *texture, EGLint buffer) +{ + ASSERT(!mTexture); + ANGLE_TRY(mImplementation->bindTexImage(context, texture, buffer)); + + if (texture->bindTexImageFromSurface(context, this) == angle::Result::Stop) + { + return Error(EGL_BAD_SURFACE); + } + mTexture = texture; + addRef(); + + return NoError(); +} + +Error Surface::releaseTexImage(const gl::Context *context, EGLint buffer) +{ + ASSERT(context); + + ANGLE_TRY(mImplementation->releaseTexImage(context, buffer)); + + ASSERT(mTexture); + ANGLE_TRY(ResultToEGL(mTexture->releaseTexImageFromSurface(context))); + + return releaseTexImageFromTexture(context); +} + +Error Surface::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) +{ + return mImplementation->getSyncValues(ust, msc, sbc); +} + +Error Surface::getMscRate(EGLint *numerator, EGLint *denominator) +{ + return mImplementation->getMscRate(numerator, denominator); +} + +Error Surface::releaseTexImageFromTexture(const gl::Context *context) +{ + ASSERT(mTexture); + mTexture = nullptr; + return releaseRef(context->getDisplay()); +} + +gl::Extents Surface::getAttachmentSize(const gl::ImageIndex & /*target*/) const +{ + return gl::Extents(getWidth(), getHeight(), 1); +} + +gl::Format Surface::getAttachmentFormat(GLenum binding, const gl::ImageIndex &target) const +{ + return (binding == GL_BACK ? mColorFormat : mDSFormat); +} + +GLsizei Surface::getAttachmentSamples(const gl::ImageIndex &target) const +{ + return getConfig()->samples; +} + +bool Surface::isRenderable(const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex) const +{ + return true; +} + +bool Surface::isYUV() const +{ + // EGL_EXT_yuv_surface is not implemented. + return false; +} + +bool Surface::isCreatedWithAHB() const +{ + return false; +} + +GLuint Surface::getId() const +{ + return mSerialId; +} + +Error Surface::getBufferAgeImpl(const gl::Context *context, EGLint *age) const +{ + // When EGL_BUFFER_PRESERVED, the previous frame contents are copied to + // current frame, so the buffer age is always 1. + if (mState.swapBehavior == EGL_BUFFER_PRESERVED) + { + if (age != nullptr) + { + *age = 1; + } + return egl::NoError(); + } + return mImplementation->getBufferAge(context, age); +} + +Error Surface::getBufferAge(const gl::Context *context, EGLint *age) +{ + Error err = getBufferAgeImpl(context, age); + if (!err.isError()) + { + mBufferAgeQueriedSinceLastSwap = true; + } + return err; +} + +gl::InitState Surface::initState(GLenum binding, const gl::ImageIndex & /*imageIndex*/) const +{ + switch (binding) + { + case GL_BACK: + return mColorInitState; + case GL_DEPTH: + case GL_STENCIL: + return mDepthStencilInitState; + default: + UNREACHABLE(); + return gl::InitState::Initialized; + } +} + +void Surface::setInitState(GLenum binding, + const gl::ImageIndex & /*imageIndex*/, + gl::InitState initState) +{ + switch (binding) + { + case GL_BACK: + mColorInitState = initState; + break; + case GL_DEPTH: + case GL_STENCIL: + mDepthStencilInitState = initState; + break; + default: + UNREACHABLE(); + break; + } +} + +void Surface::setTimestampsEnabled(bool enabled) +{ + mImplementation->setTimestampsEnabled(enabled); + mState.timestampsEnabled = enabled; +} + +bool Surface::isTimestampsEnabled() const +{ + return mState.timestampsEnabled; +} + +Error Surface::setAutoRefreshEnabled(bool enabled) +{ + ANGLE_TRY(mImplementation->setAutoRefreshEnabled(enabled)); + mState.autoRefreshEnabled = enabled; + return NoError(); +} + +bool Surface::hasProtectedContent() const +{ + return mState.hasProtectedContent(); +} + +const SupportedCompositorTiming &Surface::getSupportedCompositorTimings() const +{ + return mState.supportedCompositorTimings; +} + +Error Surface::getCompositorTiming(EGLint numTimestamps, + const EGLint *names, + EGLnsecsANDROID *values) const +{ + return mImplementation->getCompositorTiming(numTimestamps, names, values); +} + +Error Surface::getNextFrameId(EGLuint64KHR *frameId) const +{ + return mImplementation->getNextFrameId(frameId); +} + +const SupportedTimestamps &Surface::getSupportedTimestamps() const +{ + return mState.supportedTimestamps; +} + +Error Surface::getFrameTimestamps(EGLuint64KHR frameId, + EGLint numTimestamps, + const EGLint *timestamps, + EGLnsecsANDROID *values) const +{ + return mImplementation->getFrameTimestamps(frameId, numTimestamps, timestamps, values); +} + +void Surface::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) +{ + ASSERT(index == kSurfaceImplSubjectIndex); + switch (message) + { + case angle::SubjectMessage::SubjectChanged: + onStateChange(angle::SubjectMessage::ContentsChanged); + break; + case angle::SubjectMessage::SurfaceChanged: + onStateChange(angle::SubjectMessage::SurfaceChanged); + break; + case angle::SubjectMessage::SwapchainImageChanged: + onStateChange(angle::SubjectMessage::SwapchainImageChanged); + break; + default: + UNREACHABLE(); + break; + } +} + +Error Surface::setRenderBuffer(EGLint renderBuffer) +{ + ANGLE_TRY(mImplementation->setRenderBuffer(renderBuffer)); + mRenderBuffer = renderBuffer; + return NoError(); +} + +bool Surface::isLocked() const +{ + return (mLockBufferPtr != nullptr); +} + +EGLint Surface::getBitmapPitch() const +{ + return mLockBufferPitch; +} + +EGLint Surface::getBitmapOrigin() const +{ + return mImplementation->origin(); +} + +EGLint Surface::getRedOffset() const +{ + const gl::InternalFormat &format = *mColorFormat.info; + if (gl::IsBGRAFormat(format.internalFormat)) + { + return format.blueBits + format.greenBits; + } + else + { + return 0; + } +} + +EGLint Surface::getGreenOffset() const +{ + const gl::InternalFormat &format = *mColorFormat.info; + if (gl::IsBGRAFormat(format.internalFormat)) + { + return format.blueBits; + } + else + { + return format.redBits; + } +} + +EGLint Surface::getBlueOffset() const +{ + const gl::InternalFormat &format = *mColorFormat.info; + if (gl::IsBGRAFormat(format.internalFormat)) + { + return 0; + } + else + { + return format.redBits + format.greenBits; + } +} + +EGLint Surface::getAlphaOffset() const +{ + const gl::InternalFormat &format = *mColorFormat.info; + if (format.isLUMA()) + { + return format.luminanceBits; // Luma always first, alpha optional + } + // For RGBA/BGRA alpha is last + return format.blueBits + format.greenBits + format.redBits; +} + +EGLint Surface::getLuminanceOffset() const +{ + return 0; +} + +EGLint Surface::getBitmapPixelSize() const +{ + constexpr EGLint kBitsPerByte = 8; + const gl::InternalFormat &format = *mColorFormat.info; + return (format.pixelBytes * kBitsPerByte); +} + +EGLAttribKHR Surface::getBitmapPointer() const +{ + return static_cast((intptr_t)mLockBufferPtr); +} + +egl::Error Surface::lockSurfaceKHR(const egl::Display *display, const AttributeMap &attributes) +{ + EGLint lockBufferUsageHint = attributes.getAsInt( + EGL_LOCK_USAGE_HINT_KHR, (EGL_READ_SURFACE_BIT_KHR | EGL_WRITE_SURFACE_BIT_KHR)); + + bool preservePixels = ((attributes.getAsInt(EGL_MAP_PRESERVE_PIXELS_KHR, false) == EGL_TRUE) || + (mState.swapBehavior == EGL_BUFFER_PRESERVED)); + + return mImplementation->lockSurface(display, lockBufferUsageHint, preservePixels, + &mLockBufferPtr, &mLockBufferPitch); +} + +egl::Error Surface::unlockSurfaceKHR(const egl::Display *display) +{ + mLockBufferPtr = nullptr; + mLockBufferPitch = 0; + return mImplementation->unlockSurface(display, true); +} + +WindowSurface::WindowSurface(rx::EGLImplFactory *implFactory, + const egl::Config *config, + EGLNativeWindowType window, + const AttributeMap &attribs, + bool robustResourceInit) + : Surface(EGL_WINDOW_BIT, implFactory->getNextSurfaceID(), config, attribs, robustResourceInit) +{ + mImplementation = implFactory->createWindowSurface(mState, window, attribs); +} + +void Surface::setDamageRegion(const EGLint *rects, EGLint n_rects) +{ + mIsDamageRegionSet = true; +} + +WindowSurface::~WindowSurface() {} + +PbufferSurface::PbufferSurface(rx::EGLImplFactory *implFactory, + const Config *config, + const AttributeMap &attribs, + bool robustResourceInit) + : Surface(EGL_PBUFFER_BIT, implFactory->getNextSurfaceID(), config, attribs, robustResourceInit) +{ + mImplementation = implFactory->createPbufferSurface(mState, attribs); +} + +PbufferSurface::PbufferSurface(rx::EGLImplFactory *implFactory, + const Config *config, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const AttributeMap &attribs, + bool robustResourceInit) + : Surface(EGL_PBUFFER_BIT, + implFactory->getNextSurfaceID(), + config, + attribs, + robustResourceInit, + buftype) +{ + mImplementation = + implFactory->createPbufferFromClientBuffer(mState, buftype, clientBuffer, attribs); +} + +PbufferSurface::~PbufferSurface() {} + +PixmapSurface::PixmapSurface(rx::EGLImplFactory *implFactory, + const Config *config, + NativePixmapType nativePixmap, + const AttributeMap &attribs, + bool robustResourceInit) + : Surface(EGL_PIXMAP_BIT, implFactory->getNextSurfaceID(), config, attribs, robustResourceInit) +{ + mImplementation = implFactory->createPixmapSurface(mState, nativePixmap, attribs); +} + +PixmapSurface::~PixmapSurface() {} + +// SurfaceDeleter implementation. + +SurfaceDeleter::SurfaceDeleter(const Display *display) : mDisplay(display) {} + +SurfaceDeleter::~SurfaceDeleter() {} + +void SurfaceDeleter::operator()(Surface *surface) +{ + ANGLE_SWALLOW_ERR(surface->onDestroy(mDisplay)); +} + +} // namespace egl diff --git a/gfx/angle/checkout/src/libANGLE/Surface.h b/gfx/angle/checkout/src/libANGLE/Surface.h new file mode 100644 index 0000000000..862d2f57b2 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Surface.h @@ -0,0 +1,388 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Surface.h: Defines the egl::Surface class, representing a drawing surface +// such as the client area of a window, including any back buffers. +// Implements EGLSurface and related functionality. [EGL 1.4] section 2.2 page 3. + +#ifndef LIBANGLE_SURFACE_H_ +#define LIBANGLE_SURFACE_H_ + +#include + +#include + +#include "common/PackedEnums.h" +#include "common/angleutils.h" +#include "libANGLE/AttributeMap.h" +#include "libANGLE/Debug.h" +#include "libANGLE/Error.h" +#include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/RefCountObject.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/SurfaceImpl.h" + +namespace gl +{ +class Context; +class Framebuffer; +class Texture; +} // namespace gl + +namespace rx +{ +class EGLImplFactory; +} + +namespace egl +{ +class Display; +struct Config; + +using SupportedCompositorTiming = angle::PackedEnumBitSet; +using SupportedTimestamps = angle::PackedEnumBitSet; + +struct SurfaceState final : private angle::NonCopyable +{ + SurfaceState(const egl::Config *configIn, const AttributeMap &attributesIn); + ~SurfaceState(); + + bool isRobustResourceInitEnabled() const; + bool hasProtectedContent() const; + EGLint getPreferredSwapInterval() const; + + EGLLabelKHR label; + const egl::Config *config; + AttributeMap attributes; + + bool timestampsEnabled; + bool autoRefreshEnabled; + SupportedCompositorTiming supportedCompositorTimings; + SupportedTimestamps supportedTimestamps; + bool directComposition; + EGLenum swapBehavior; +}; + +class Surface : public LabeledObject, public gl::FramebufferAttachmentObject +{ + public: + rx::SurfaceImpl *getImplementation() const { return mImplementation; } + + void setLabel(EGLLabelKHR label) override; + EGLLabelKHR getLabel() const override; + + EGLint getType() const; + + Error initialize(const Display *display); + Error makeCurrent(const gl::Context *context); + Error unMakeCurrent(const gl::Context *context); + Error prepareSwap(const gl::Context *context); + Error swap(const gl::Context *context); + Error swapWithDamage(const gl::Context *context, const EGLint *rects, EGLint n_rects); + Error swapWithFrameToken(const gl::Context *context, EGLFrameTokenANGLE frameToken); + Error postSubBuffer(const gl::Context *context, + EGLint x, + EGLint y, + EGLint width, + EGLint height); + Error setPresentationTime(EGLnsecsANDROID time); + Error querySurfacePointerANGLE(EGLint attribute, void **value); + Error bindTexImage(gl::Context *context, gl::Texture *texture, EGLint buffer); + Error releaseTexImage(const gl::Context *context, EGLint buffer); + + Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc); + Error getMscRate(EGLint *numerator, EGLint *denominator); + + EGLint isPostSubBufferSupported() const; + + void setSwapInterval(EGLint interval); + Error onDestroy(const Display *display); + + void setMipmapLevel(EGLint level); + void setMultisampleResolve(EGLenum resolve); + void setSwapBehavior(EGLenum behavior); + + void setFixedWidth(EGLint width); + void setFixedHeight(EGLint height); + + const Config *getConfig() const; + + // width and height can change with client window resizing + EGLint getWidth() const; + EGLint getHeight() const; + // Note: windows cannot be resized on Android. The approach requires + // calling vkGetPhysicalDeviceSurfaceCapabilitiesKHR. However, that is + // expensive; and there are troublesome timing issues for other parts of + // ANGLE (which cause test failures and crashes). Therefore, a + // special-Android-only path is created just for the querying of EGL_WIDTH + // and EGL_HEIGHT. + // https://issuetracker.google.com/issues/153329980 + egl::Error getUserWidth(const egl::Display *display, EGLint *value) const; + egl::Error getUserHeight(const egl::Display *display, EGLint *value) const; + EGLint getPixelAspectRatio() const; + EGLenum getRenderBuffer() const; + EGLenum getSwapBehavior() const; + TextureFormat getTextureFormat() const; + EGLenum getTextureTarget() const; + bool getLargestPbuffer() const; + EGLenum getGLColorspace() const; + EGLenum getVGAlphaFormat() const; + EGLenum getVGColorspace() const; + bool getMipmapTexture() const; + EGLint getMipmapLevel() const; + EGLint getHorizontalResolution() const; + EGLint getVerticalResolution() const; + EGLenum getMultisampleResolve() const; + bool hasProtectedContent() const override; + + // For lock surface buffer + EGLint getBitmapPitch() const; + EGLint getBitmapOrigin() const; + EGLint getRedOffset() const; + EGLint getGreenOffset() const; + EGLint getBlueOffset() const; + EGLint getAlphaOffset() const; + EGLint getLuminanceOffset() const; + EGLint getBitmapPixelSize() const; + EGLAttribKHR getBitmapPointer() const; + egl::Error lockSurfaceKHR(const egl::Display *display, const AttributeMap &attributes); + egl::Error unlockSurfaceKHR(const egl::Display *display); + + bool isLocked() const; + bool isCurrentOnAnyContext() const { return mIsCurrentOnAnyContext; } + + gl::Texture *getBoundTexture() const { return mTexture; } + + EGLint isFixedSize() const; + + // FramebufferAttachmentObject implementation + gl::Extents getAttachmentSize(const gl::ImageIndex &imageIndex) const override; + gl::Format getAttachmentFormat(GLenum binding, const gl::ImageIndex &imageIndex) const override; + GLsizei getAttachmentSamples(const gl::ImageIndex &imageIndex) const override; + bool isRenderable(const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex) const override; + bool isYUV() const override; + bool isCreatedWithAHB() const override; + + void onAttach(const gl::Context *context, rx::Serial framebufferSerial) override {} + void onDetach(const gl::Context *context, rx::Serial framebufferSerial) override {} + GLuint getId() const override; + + EGLint getOrientation() const { return mOrientation; } + + bool directComposition() const { return mState.directComposition; } + + gl::InitState initState(GLenum binding, const gl::ImageIndex &imageIndex) const override; + void setInitState(GLenum binding, + const gl::ImageIndex &imageIndex, + gl::InitState initState) override; + + bool isRobustResourceInitEnabled() const { return mRobustResourceInitialization; } + + const gl::Format &getBindTexImageFormat() const { return mColorFormat; } + + // EGL_ANDROID_get_frame_timestamps entry points + void setTimestampsEnabled(bool enabled); + bool isTimestampsEnabled() const; + + // EGL_ANDROID_front_buffer_auto_refresh entry points + Error setAutoRefreshEnabled(bool enabled); + + const SupportedCompositorTiming &getSupportedCompositorTimings() const; + Error getCompositorTiming(EGLint numTimestamps, + const EGLint *names, + EGLnsecsANDROID *values) const; + + Error getNextFrameId(EGLuint64KHR *frameId) const; + const SupportedTimestamps &getSupportedTimestamps() const; + Error getFrameTimestamps(EGLuint64KHR frameId, + EGLint numTimestamps, + const EGLint *timestamps, + EGLnsecsANDROID *values) const; + + // Returns the offset into the texture backing the surface if specified via texture offset + // attributes (see EGL_ANGLE_d3d_texture_client_buffer extension). Returns zero offset + // otherwise. + const gl::Offset &getTextureOffset() const { return mTextureOffset; } + + Error getBufferAge(const gl::Context *context, EGLint *age); + + Error setRenderBuffer(EGLint renderBuffer); + + bool bufferAgeQueriedSinceLastSwap() const { return mBufferAgeQueriedSinceLastSwap; } + void setDamageRegion(const EGLint *rects, EGLint n_rects); + bool isDamageRegionSet() const { return mIsDamageRegionSet; } + + void addRef() { mRefCount++; } + void release() + { + ASSERT(mRefCount > 0); + mRefCount--; + } + + protected: + Surface(EGLint surfaceType, + GLuint serialId, + const egl::Config *config, + const AttributeMap &attributes, + bool forceRobustResourceInit, + EGLenum buftype = EGL_NONE); + ~Surface() override; + rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override; + + // ANGLE-only method, used internally + friend class gl::Texture; + Error releaseTexImageFromTexture(const gl::Context *context); + + SurfaceState mState; + rx::SurfaceImpl *mImplementation; + int mRefCount; + bool mDestroyed; + + EGLint mType; + EGLenum mBuftype; + + bool mPostSubBufferRequested; + + bool mLargestPbuffer; + EGLenum mGLColorspace; + EGLenum mVGAlphaFormat; + EGLenum mVGColorspace; + bool mMipmapTexture; + EGLint mMipmapLevel; + EGLint mHorizontalResolution; + EGLint mVerticalResolution; + EGLenum mMultisampleResolve; + + bool mFixedSize; + size_t mFixedWidth; + size_t mFixedHeight; + + bool mRobustResourceInitialization; + + TextureFormat mTextureFormat; + EGLenum mTextureTarget; + + EGLint mPixelAspectRatio; // Display aspect ratio + EGLenum mRenderBuffer; // Render buffer + + EGLint mOrientation; + + // We don't use a binding pointer here. We don't ever want to own an orphaned texture. If a + // Texture is deleted the Surface is unbound in onDestroy. + gl::Texture *mTexture; + + gl::Format mColorFormat; + gl::Format mDSFormat; + + gl::Offset mTextureOffset; + + bool mIsCurrentOnAnyContext; // The surface is current to a context/client API + uint8_t *mLockBufferPtr; // Memory owned by backend. + EGLint mLockBufferPitch; + + bool mBufferAgeQueriedSinceLastSwap; + bool mIsDamageRegionSet; + + private: + Error getBufferAgeImpl(const gl::Context *context, EGLint *age) const; + + Error destroyImpl(const Display *display); + + void postSwap(const gl::Context *context); + Error releaseRef(const Display *display); + + // ObserverInterface implementation. + void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; + + gl::InitState mColorInitState; + gl::InitState mDepthStencilInitState; + angle::ObserverBinding mImplObserverBinding; + + GLuint mSerialId; +}; + +class WindowSurface final : public Surface +{ + public: + WindowSurface(rx::EGLImplFactory *implFactory, + const Config *config, + EGLNativeWindowType window, + const AttributeMap &attribs, + bool robustResourceInit); + ~WindowSurface() override; +}; + +class PbufferSurface final : public Surface +{ + public: + PbufferSurface(rx::EGLImplFactory *implFactory, + const Config *config, + const AttributeMap &attribs, + bool robustResourceInit); + PbufferSurface(rx::EGLImplFactory *implFactory, + const Config *config, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const AttributeMap &attribs, + bool robustResourceInit); + + protected: + ~PbufferSurface() override; +}; + +class PixmapSurface final : public Surface +{ + public: + PixmapSurface(rx::EGLImplFactory *implFactory, + const Config *config, + NativePixmapType nativePixmap, + const AttributeMap &attribs, + bool robustResourceInit); + + protected: + ~PixmapSurface() override; +}; + +class [[nodiscard]] ScopedSurfaceRef +{ + public: + ScopedSurfaceRef(Surface *surface) : mSurface(surface) + { + if (mSurface) + { + mSurface->addRef(); + } + } + ~ScopedSurfaceRef() + { + if (mSurface) + { + mSurface->release(); + } + } + + private: + Surface *const mSurface; +}; + +class SurfaceDeleter final +{ + public: + SurfaceDeleter(const Display *display); + ~SurfaceDeleter(); + void operator()(Surface *surface); + + private: + const Display *mDisplay; +}; + +using SurfacePointer = std::unique_ptr; + +} // namespace egl + +#endif // LIBANGLE_SURFACE_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Texture.cpp b/gfx/angle/checkout/src/libANGLE/Texture.cpp new file mode 100644 index 0000000000..89930d1c29 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Texture.cpp @@ -0,0 +1,2494 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Texture.cpp: Implements the gl::Texture class. [OpenGL ES 2.0.24] section 3.7 page 63. + +#include "libANGLE/Texture.h" + +#include "common/mathutil.h" +#include "common/utilities.h" +#include "libANGLE/Config.h" +#include "libANGLE/Context.h" +#include "libANGLE/Image.h" +#include "libANGLE/State.h" +#include "libANGLE/Surface.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/GLImplFactory.h" +#include "libANGLE/renderer/TextureImpl.h" + +namespace gl +{ + +namespace +{ +constexpr angle::SubjectIndex kBufferSubjectIndex = 2; +static_assert(kBufferSubjectIndex != rx::kTextureImageImplObserverMessageIndex, "Index collision"); +static_assert(kBufferSubjectIndex != rx::kTextureImageSiblingMessageIndex, "Index collision"); + +bool IsPointSampled(const SamplerState &samplerState) +{ + return (samplerState.getMagFilter() == GL_NEAREST && + (samplerState.getMinFilter() == GL_NEAREST || + samplerState.getMinFilter() == GL_NEAREST_MIPMAP_NEAREST)); +} + +size_t GetImageDescIndex(TextureTarget target, size_t level) +{ + return IsCubeMapFaceTarget(target) ? (level * 6 + CubeMapTextureTargetToFaceIndex(target)) + : level; +} + +InitState DetermineInitState(const Context *context, Buffer *unpackBuffer, const uint8_t *pixels) +{ + // Can happen in tests. + if (!context || !context->isRobustResourceInitEnabled()) + { + return InitState::Initialized; + } + + return (!pixels && !unpackBuffer) ? InitState::MayNeedInit : InitState::Initialized; +} +} // namespace + +GLenum ConvertToNearestFilterMode(GLenum filterMode) +{ + switch (filterMode) + { + case GL_LINEAR: + return GL_NEAREST; + case GL_LINEAR_MIPMAP_NEAREST: + return GL_NEAREST_MIPMAP_NEAREST; + case GL_LINEAR_MIPMAP_LINEAR: + return GL_NEAREST_MIPMAP_LINEAR; + default: + return filterMode; + } +} + +GLenum ConvertToNearestMipFilterMode(GLenum filterMode) +{ + switch (filterMode) + { + case GL_LINEAR_MIPMAP_LINEAR: + return GL_LINEAR_MIPMAP_NEAREST; + case GL_NEAREST_MIPMAP_LINEAR: + return GL_NEAREST_MIPMAP_NEAREST; + default: + return filterMode; + } +} + +bool IsMipmapSupported(const TextureType &type) +{ + if (type == TextureType::_2DMultisample || type == TextureType::Buffer) + { + return false; + } + return true; +} + +SwizzleState::SwizzleState() + : swizzleRed(GL_RED), swizzleGreen(GL_GREEN), swizzleBlue(GL_BLUE), swizzleAlpha(GL_ALPHA) +{} + +SwizzleState::SwizzleState(GLenum red, GLenum green, GLenum blue, GLenum alpha) + : swizzleRed(red), swizzleGreen(green), swizzleBlue(blue), swizzleAlpha(alpha) +{} + +bool SwizzleState::swizzleRequired() const +{ + return swizzleRed != GL_RED || swizzleGreen != GL_GREEN || swizzleBlue != GL_BLUE || + swizzleAlpha != GL_ALPHA; +} + +bool SwizzleState::operator==(const SwizzleState &other) const +{ + return swizzleRed == other.swizzleRed && swizzleGreen == other.swizzleGreen && + swizzleBlue == other.swizzleBlue && swizzleAlpha == other.swizzleAlpha; +} + +bool SwizzleState::operator!=(const SwizzleState &other) const +{ + return !(*this == other); +} + +TextureState::TextureState(TextureType type) + : mType(type), + mSamplerState(SamplerState::CreateDefaultForTarget(type)), + mSrgbOverride(SrgbOverride::Default), + mBaseLevel(0), + mMaxLevel(kInitialMaxLevel), + mDepthStencilTextureMode(GL_DEPTH_COMPONENT), + mHasBeenBoundAsImage(false), + mIs3DAndHasBeenBoundAs2DImage(false), + mHasBeenBoundAsAttachment(false), + mImmutableFormat(false), + mImmutableLevels(0), + mUsage(GL_NONE), + mHasProtectedContent(false), + mImageDescs((IMPLEMENTATION_MAX_TEXTURE_LEVELS + 1) * (type == TextureType::CubeMap ? 6 : 1)), + mCropRect(0, 0, 0, 0), + mGenerateMipmapHint(GL_FALSE), + mInitState(InitState::Initialized), + mCachedSamplerFormat(SamplerFormat::InvalidEnum), + mCachedSamplerCompareMode(GL_NONE), + mCachedSamplerFormatValid(false) +{} + +TextureState::~TextureState() {} + +bool TextureState::swizzleRequired() const +{ + return mSwizzleState.swizzleRequired(); +} + +GLuint TextureState::getEffectiveBaseLevel() const +{ + if (mImmutableFormat) + { + // GLES 3.0.4 section 3.8.10 + return std::min(mBaseLevel, mImmutableLevels - 1); + } + // Some classes use the effective base level to index arrays with level data. By clamping the + // effective base level to max levels these arrays need just one extra item to store properties + // that should be returned for all out-of-range base level values, instead of needing special + // handling for out-of-range base levels. + return std::min(mBaseLevel, static_cast(IMPLEMENTATION_MAX_TEXTURE_LEVELS)); +} + +GLuint TextureState::getEffectiveMaxLevel() const +{ + if (mImmutableFormat) + { + // GLES 3.0.4 section 3.8.10 + GLuint clampedMaxLevel = std::max(mMaxLevel, getEffectiveBaseLevel()); + clampedMaxLevel = std::min(clampedMaxLevel, mImmutableLevels - 1); + return clampedMaxLevel; + } + return mMaxLevel; +} + +GLuint TextureState::getMipmapMaxLevel() const +{ + const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), getEffectiveBaseLevel()); + GLuint expectedMipLevels = 0; + if (mType == TextureType::_3D) + { + const int maxDim = std::max(std::max(baseImageDesc.size.width, baseImageDesc.size.height), + baseImageDesc.size.depth); + expectedMipLevels = static_cast(log2(maxDim)); + } + else + { + expectedMipLevels = static_cast( + log2(std::max(baseImageDesc.size.width, baseImageDesc.size.height))); + } + + return std::min(getEffectiveBaseLevel() + expectedMipLevels, getEffectiveMaxLevel()); +} + +bool TextureState::setBaseLevel(GLuint baseLevel) +{ + if (mBaseLevel != baseLevel) + { + mBaseLevel = baseLevel; + return true; + } + return false; +} + +bool TextureState::setMaxLevel(GLuint maxLevel) +{ + if (mMaxLevel != maxLevel) + { + mMaxLevel = maxLevel; + return true; + } + + return false; +} + +// Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81. +// According to [OpenGL ES 3.0.5] section 3.8.13 Texture Completeness page 160 any +// per-level checks begin at the base-level. +// For OpenGL ES2 the base level is always zero. +bool TextureState::isCubeComplete() const +{ + ASSERT(mType == TextureType::CubeMap); + + angle::EnumIterator face = kCubeMapTextureTargetMin; + const ImageDesc &baseImageDesc = getImageDesc(*face, getEffectiveBaseLevel()); + if (baseImageDesc.size.width == 0 || baseImageDesc.size.width != baseImageDesc.size.height) + { + return false; + } + + ++face; + + for (; face != kAfterCubeMapTextureTargetMax; ++face) + { + const ImageDesc &faceImageDesc = getImageDesc(*face, getEffectiveBaseLevel()); + if (faceImageDesc.size.width != baseImageDesc.size.width || + faceImageDesc.size.height != baseImageDesc.size.height || + !Format::SameSized(faceImageDesc.format, baseImageDesc.format)) + { + return false; + } + } + + return true; +} + +const ImageDesc &TextureState::getBaseLevelDesc() const +{ + ASSERT(mType != TextureType::CubeMap || isCubeComplete()); + return getImageDesc(getBaseImageTarget(), getEffectiveBaseLevel()); +} + +const ImageDesc &TextureState::getLevelZeroDesc() const +{ + ASSERT(mType != TextureType::CubeMap || isCubeComplete()); + return getImageDesc(getBaseImageTarget(), 0); +} + +void TextureState::setCrop(const Rectangle &rect) +{ + mCropRect = rect; +} + +const Rectangle &TextureState::getCrop() const +{ + return mCropRect; +} + +void TextureState::setGenerateMipmapHint(GLenum hint) +{ + mGenerateMipmapHint = hint; +} + +GLenum TextureState::getGenerateMipmapHint() const +{ + return mGenerateMipmapHint; +} + +SamplerFormat TextureState::computeRequiredSamplerFormat(const SamplerState &samplerState) const +{ + const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), getEffectiveBaseLevel()); + if ((baseImageDesc.format.info->format == GL_DEPTH_COMPONENT || + baseImageDesc.format.info->format == GL_DEPTH_STENCIL) && + samplerState.getCompareMode() != GL_NONE) + { + return SamplerFormat::Shadow; + } + else + { + switch (baseImageDesc.format.info->componentType) + { + case GL_UNSIGNED_NORMALIZED: + case GL_SIGNED_NORMALIZED: + case GL_FLOAT: + return SamplerFormat::Float; + case GL_INT: + return SamplerFormat::Signed; + case GL_UNSIGNED_INT: + return SamplerFormat::Unsigned; + default: + return SamplerFormat::InvalidEnum; + } + } +} + +bool TextureState::computeSamplerCompleteness(const SamplerState &samplerState, + const State &state) const +{ + // Buffer textures cannot be incomplete. + if (mType == TextureType::Buffer) + { + return true; + } + + // Check for all non-format-based completeness rules + if (!computeSamplerCompletenessForCopyImage(samplerState, state)) + { + return false; + } + + const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), getEffectiveBaseLevel()); + + // According to es 3.1 spec, texture is justified as incomplete if sized internalformat is + // unfilterable(table 20.11) and filter is not GL_NEAREST(8.16). The default value of minFilter + // is NEAREST_MIPMAP_LINEAR and magFilter is LINEAR(table 20.11,). For multismaple texture, + // filter state of multisample texture is ignored(11.1.3.3). So it shouldn't be judged as + // incomplete texture. So, we ignore filtering for multisample texture completeness here. + if (!IsMultisampled(mType) && + !baseImageDesc.format.info->filterSupport(state.getClientVersion(), + state.getExtensions()) && + !IsPointSampled(samplerState)) + { + return false; + } + + // OpenGLES 3.0.2 spec section 3.8.13 states that a texture is not mipmap complete if: + // The internalformat specified for the texture arrays is a sized internal depth or + // depth and stencil format (see table 3.13), the value of TEXTURE_COMPARE_- + // MODE is NONE, and either the magnification filter is not NEAREST or the mini- + // fication filter is neither NEAREST nor NEAREST_MIPMAP_NEAREST. + if (!IsMultisampled(mType) && baseImageDesc.format.info->depthBits > 0 && + state.getClientMajorVersion() >= 3) + { + // Note: we restrict this validation to sized types. For the OES_depth_textures + // extension, due to some underspecification problems, we must allow linear filtering + // for legacy compatibility with WebGL 1. + // See http://crbug.com/649200 + if (samplerState.getCompareMode() == GL_NONE && baseImageDesc.format.info->sized) + { + if ((samplerState.getMinFilter() != GL_NEAREST && + samplerState.getMinFilter() != GL_NEAREST_MIPMAP_NEAREST) || + samplerState.getMagFilter() != GL_NEAREST) + { + return false; + } + } + } + + // OpenGLES 3.1 spec section 8.16 states that a texture is not mipmap complete if: + // The internalformat specified for the texture is DEPTH_STENCIL format, the value of + // DEPTH_STENCIL_TEXTURE_MODE is STENCIL_INDEX, and either the magnification filter is + // not NEAREST or the minification filter is neither NEAREST nor NEAREST_MIPMAP_NEAREST. + // However, the ES 3.1 spec differs from the statement above, because it is incorrect. + // See the issue at https://github.com/KhronosGroup/OpenGL-API/issues/33. + // For multismaple texture, filter state of multisample texture is ignored(11.1.3.3). + // So it shouldn't be judged as incomplete texture. So, we ignore filtering for multisample + // texture completeness here. + if (!IsMultisampled(mType) && baseImageDesc.format.info->depthBits > 0 && + mDepthStencilTextureMode == GL_STENCIL_INDEX) + { + if ((samplerState.getMinFilter() != GL_NEAREST && + samplerState.getMinFilter() != GL_NEAREST_MIPMAP_NEAREST) || + samplerState.getMagFilter() != GL_NEAREST) + { + return false; + } + } + + return true; +} + +// CopyImageSubData has more lax rules for texture completeness: format-based completeness rules are +// ignored, so a texture can still be considered complete even if it violates format-specific +// conditions +bool TextureState::computeSamplerCompletenessForCopyImage(const SamplerState &samplerState, + const State &state) const +{ + // Buffer textures cannot be incomplete. + if (mType == TextureType::Buffer) + { + return true; + } + + if (!mImmutableFormat && mBaseLevel > mMaxLevel) + { + return false; + } + const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), getEffectiveBaseLevel()); + if (baseImageDesc.size.width == 0 || baseImageDesc.size.height == 0 || + baseImageDesc.size.depth == 0) + { + return false; + } + // The cases where the texture is incomplete because base level is out of range should be + // handled by the above condition. + ASSERT(mBaseLevel < IMPLEMENTATION_MAX_TEXTURE_LEVELS || mImmutableFormat); + + if (mType == TextureType::CubeMap && baseImageDesc.size.width != baseImageDesc.size.height) + { + return false; + } + + bool npotSupport = state.getExtensions().textureNpotOES || state.getClientMajorVersion() >= 3; + if (!npotSupport) + { + if ((samplerState.getWrapS() != GL_CLAMP_TO_EDGE && + samplerState.getWrapS() != GL_CLAMP_TO_BORDER && !isPow2(baseImageDesc.size.width)) || + (samplerState.getWrapT() != GL_CLAMP_TO_EDGE && + samplerState.getWrapT() != GL_CLAMP_TO_BORDER && !isPow2(baseImageDesc.size.height))) + { + return false; + } + } + + if (IsMipmapSupported(mType) && IsMipmapFiltered(samplerState.getMinFilter())) + { + if (!npotSupport) + { + if (!isPow2(baseImageDesc.size.width) || !isPow2(baseImageDesc.size.height)) + { + return false; + } + } + + if (!computeMipmapCompleteness()) + { + return false; + } + } + else + { + if (mType == TextureType::CubeMap && !isCubeComplete()) + { + return false; + } + } + + // From GL_OES_EGL_image_external_essl3: If state is present in a sampler object bound to a + // texture unit that would have been rejected by a call to TexParameter* for the texture bound + // to that unit, the behavior of the implementation is as if the texture were incomplete. For + // example, if TEXTURE_WRAP_S or TEXTURE_WRAP_T is set to anything but CLAMP_TO_EDGE on the + // sampler object bound to a texture unit and the texture bound to that unit is an external + // texture and EXT_EGL_image_external_wrap_modes is not enabled, the texture will be considered + // incomplete. + // Sampler object state which does not affect sampling for the type of texture bound + // to a texture unit, such as TEXTURE_WRAP_R for an external texture, does not affect + // completeness. + if (mType == TextureType::External) + { + if (!state.getExtensions().EGLImageExternalWrapModesEXT) + { + if (samplerState.getWrapS() != GL_CLAMP_TO_EDGE || + samplerState.getWrapT() != GL_CLAMP_TO_EDGE) + { + return false; + } + } + + if (samplerState.getMinFilter() != GL_LINEAR && samplerState.getMinFilter() != GL_NEAREST) + { + return false; + } + } + + return true; +} + +bool TextureState::computeMipmapCompleteness() const +{ + const GLuint maxLevel = getMipmapMaxLevel(); + + for (GLuint level = getEffectiveBaseLevel(); level <= maxLevel; level++) + { + if (mType == TextureType::CubeMap) + { + for (TextureTarget face : AllCubeFaceTextureTargets()) + { + if (!computeLevelCompleteness(face, level)) + { + return false; + } + } + } + else + { + if (!computeLevelCompleteness(NonCubeTextureTypeToTarget(mType), level)) + { + return false; + } + } + } + + return true; +} + +bool TextureState::computeLevelCompleteness(TextureTarget target, size_t level) const +{ + ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS); + + if (mImmutableFormat) + { + return true; + } + + const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), getEffectiveBaseLevel()); + if (baseImageDesc.size.width == 0 || baseImageDesc.size.height == 0 || + baseImageDesc.size.depth == 0) + { + return false; + } + + const ImageDesc &levelImageDesc = getImageDesc(target, level); + if (levelImageDesc.size.width == 0 || levelImageDesc.size.height == 0 || + levelImageDesc.size.depth == 0) + { + return false; + } + + if (!Format::SameSized(levelImageDesc.format, baseImageDesc.format)) + { + return false; + } + + ASSERT(level >= getEffectiveBaseLevel()); + const size_t relativeLevel = level - getEffectiveBaseLevel(); + if (levelImageDesc.size.width != std::max(1, baseImageDesc.size.width >> relativeLevel)) + { + return false; + } + + if (levelImageDesc.size.height != std::max(1, baseImageDesc.size.height >> relativeLevel)) + { + return false; + } + + if (mType == TextureType::_3D) + { + if (levelImageDesc.size.depth != std::max(1, baseImageDesc.size.depth >> relativeLevel)) + { + return false; + } + } + else if (IsArrayTextureType(mType)) + { + if (levelImageDesc.size.depth != baseImageDesc.size.depth) + { + return false; + } + } + + return true; +} + +TextureTarget TextureState::getBaseImageTarget() const +{ + return mType == TextureType::CubeMap ? kCubeMapTextureTargetMin + : NonCubeTextureTypeToTarget(mType); +} + +GLuint TextureState::getEnabledLevelCount() const +{ + GLuint levelCount = 0; + const GLuint baseLevel = getEffectiveBaseLevel(); + const GLuint maxLevel = std::min(getEffectiveMaxLevel(), getMipmapMaxLevel()); + + // The mip chain will have either one or more sequential levels, or max levels, + // but not a sparse one. + Optional expectedSize; + for (size_t enabledLevel = baseLevel; enabledLevel <= maxLevel; ++enabledLevel, ++levelCount) + { + // Note: for cube textures, we only check the first face. + TextureTarget target = TextureTypeToTarget(mType, 0); + size_t descIndex = GetImageDescIndex(target, enabledLevel); + const Extents &levelSize = mImageDescs[descIndex].size; + + if (levelSize.empty()) + { + break; + } + if (expectedSize.valid()) + { + Extents newSize = expectedSize.value(); + newSize.width = std::max(1, newSize.width >> 1); + newSize.height = std::max(1, newSize.height >> 1); + + if (!IsArrayTextureType(mType)) + { + newSize.depth = std::max(1, newSize.depth >> 1); + } + + if (newSize != levelSize) + { + break; + } + } + expectedSize = levelSize; + } + + return levelCount; +} + +ImageDesc::ImageDesc() + : ImageDesc(Extents(0, 0, 0), Format::Invalid(), 0, GL_TRUE, InitState::Initialized) +{} + +ImageDesc::ImageDesc(const Extents &size, const Format &format, const InitState initState) + : size(size), format(format), samples(0), fixedSampleLocations(GL_TRUE), initState(initState) +{} + +ImageDesc::ImageDesc(const Extents &size, + const Format &format, + const GLsizei samples, + const bool fixedSampleLocations, + const InitState initState) + : size(size), + format(format), + samples(samples), + fixedSampleLocations(fixedSampleLocations), + initState(initState) +{} + +GLint ImageDesc::getMemorySize() const +{ + // Assume allocated size is around width * height * depth * samples * pixelBytes + angle::CheckedNumeric levelSize = 1; + levelSize *= format.info->pixelBytes; + levelSize *= size.width; + levelSize *= size.height; + levelSize *= size.depth; + levelSize *= std::max(samples, 1); + return levelSize.ValueOrDefault(std::numeric_limits::max()); +} + +const ImageDesc &TextureState::getImageDesc(TextureTarget target, size_t level) const +{ + size_t descIndex = GetImageDescIndex(target, level); + ASSERT(descIndex < mImageDescs.size()); + return mImageDescs[descIndex]; +} + +void TextureState::setImageDesc(TextureTarget target, size_t level, const ImageDesc &desc) +{ + size_t descIndex = GetImageDescIndex(target, level); + ASSERT(descIndex < mImageDescs.size()); + mImageDescs[descIndex] = desc; + if (desc.initState == InitState::MayNeedInit) + { + mInitState = InitState::MayNeedInit; + } + else + { + // Scan for any uninitialized images. If there are none, set the init state of the entire + // texture to initialized. The cost of the scan is only paid after doing image + // initialization which is already very expensive. + bool allImagesInitialized = true; + + for (const ImageDesc &initDesc : mImageDescs) + { + if (initDesc.initState == InitState::MayNeedInit) + { + allImagesInitialized = false; + break; + } + } + + if (allImagesInitialized) + { + mInitState = InitState::Initialized; + } + } +} + +// Note that an ImageIndex that represents an entire level of a cube map corresponds to 6 +// ImageDescs, so if the cube map is cube complete, we return the ImageDesc of the first cube +// face, and we don't allow using this function when the cube map is not cube complete. +const ImageDesc &TextureState::getImageDesc(const ImageIndex &imageIndex) const +{ + if (imageIndex.isEntireLevelCubeMap()) + { + ASSERT(isCubeComplete()); + const GLint levelIndex = imageIndex.getLevelIndex(); + return getImageDesc(kCubeMapTextureTargetMin, levelIndex); + } + + return getImageDesc(imageIndex.getTarget(), imageIndex.getLevelIndex()); +} + +void TextureState::setImageDescChain(GLuint baseLevel, + GLuint maxLevel, + Extents baseSize, + const Format &format, + InitState initState) +{ + for (GLuint level = baseLevel; level <= maxLevel; level++) + { + int relativeLevel = (level - baseLevel); + Extents levelSize(std::max(baseSize.width >> relativeLevel, 1), + std::max(baseSize.height >> relativeLevel, 1), + (IsArrayTextureType(mType)) + ? baseSize.depth + : std::max(baseSize.depth >> relativeLevel, 1)); + ImageDesc levelInfo(levelSize, format, initState); + + if (mType == TextureType::CubeMap) + { + for (TextureTarget face : AllCubeFaceTextureTargets()) + { + setImageDesc(face, level, levelInfo); + } + } + else + { + setImageDesc(NonCubeTextureTypeToTarget(mType), level, levelInfo); + } + } +} + +void TextureState::setImageDescChainMultisample(Extents baseSize, + const Format &format, + GLsizei samples, + bool fixedSampleLocations, + InitState initState) +{ + ASSERT(mType == TextureType::_2DMultisample || mType == TextureType::_2DMultisampleArray); + ImageDesc levelInfo(baseSize, format, samples, fixedSampleLocations, initState); + setImageDesc(NonCubeTextureTypeToTarget(mType), 0, levelInfo); +} + +void TextureState::clearImageDesc(TextureTarget target, size_t level) +{ + setImageDesc(target, level, ImageDesc()); +} + +void TextureState::clearImageDescs() +{ + for (size_t descIndex = 0; descIndex < mImageDescs.size(); descIndex++) + { + mImageDescs[descIndex] = ImageDesc(); + } +} + +Texture::Texture(rx::GLImplFactory *factory, TextureID id, TextureType type) + : RefCountObject(factory->generateSerial(), id), + mState(type), + mTexture(factory->createTexture(mState)), + mImplObserver(this, rx::kTextureImageImplObserverMessageIndex), + mBufferObserver(this, kBufferSubjectIndex), + mBoundSurface(nullptr), + mBoundStream(nullptr) +{ + mImplObserver.bind(mTexture); + + // Initially assume the implementation is dirty. + mDirtyBits.set(DIRTY_BIT_IMPLEMENTATION); +} + +void Texture::onDestroy(const Context *context) +{ + if (mBoundSurface) + { + ANGLE_SWALLOW_ERR(mBoundSurface->releaseTexImage(context, EGL_BACK_BUFFER)); + mBoundSurface = nullptr; + } + if (mBoundStream) + { + mBoundStream->releaseTextures(); + mBoundStream = nullptr; + } + + egl::RefCountObjectReleaser releaseImage; + (void)orphanImages(context, &releaseImage); + + mState.mBuffer.set(context, nullptr, 0, 0); + + if (mTexture) + { + mTexture->onDestroy(context); + } +} + +Texture::~Texture() +{ + SafeDelete(mTexture); +} + +angle::Result Texture::setLabel(const Context *context, const std::string &label) +{ + mState.mLabel = label; + return mTexture->onLabelUpdate(context); +} + +const std::string &Texture::getLabel() const +{ + return mState.mLabel; +} + +void Texture::setSwizzleRed(const Context *context, GLenum swizzleRed) +{ + if (mState.mSwizzleState.swizzleRed != swizzleRed) + { + mState.mSwizzleState.swizzleRed = swizzleRed; + signalDirtyState(DIRTY_BIT_SWIZZLE_RED); + } +} + +GLenum Texture::getSwizzleRed() const +{ + return mState.mSwizzleState.swizzleRed; +} + +void Texture::setSwizzleGreen(const Context *context, GLenum swizzleGreen) +{ + if (mState.mSwizzleState.swizzleGreen != swizzleGreen) + { + mState.mSwizzleState.swizzleGreen = swizzleGreen; + signalDirtyState(DIRTY_BIT_SWIZZLE_GREEN); + } +} + +GLenum Texture::getSwizzleGreen() const +{ + return mState.mSwizzleState.swizzleGreen; +} + +void Texture::setSwizzleBlue(const Context *context, GLenum swizzleBlue) +{ + if (mState.mSwizzleState.swizzleBlue != swizzleBlue) + { + mState.mSwizzleState.swizzleBlue = swizzleBlue; + signalDirtyState(DIRTY_BIT_SWIZZLE_BLUE); + } +} + +GLenum Texture::getSwizzleBlue() const +{ + return mState.mSwizzleState.swizzleBlue; +} + +void Texture::setSwizzleAlpha(const Context *context, GLenum swizzleAlpha) +{ + if (mState.mSwizzleState.swizzleAlpha != swizzleAlpha) + { + mState.mSwizzleState.swizzleAlpha = swizzleAlpha; + signalDirtyState(DIRTY_BIT_SWIZZLE_ALPHA); + } +} + +GLenum Texture::getSwizzleAlpha() const +{ + return mState.mSwizzleState.swizzleAlpha; +} + +void Texture::setMinFilter(const Context *context, GLenum minFilter) +{ + if (mState.mSamplerState.setMinFilter(minFilter)) + { + signalDirtyState(DIRTY_BIT_MIN_FILTER); + } +} + +GLenum Texture::getMinFilter() const +{ + return mState.mSamplerState.getMinFilter(); +} + +void Texture::setMagFilter(const Context *context, GLenum magFilter) +{ + if (mState.mSamplerState.setMagFilter(magFilter)) + { + signalDirtyState(DIRTY_BIT_MAG_FILTER); + } +} + +GLenum Texture::getMagFilter() const +{ + return mState.mSamplerState.getMagFilter(); +} + +void Texture::setWrapS(const Context *context, GLenum wrapS) +{ + if (mState.mSamplerState.setWrapS(wrapS)) + { + signalDirtyState(DIRTY_BIT_WRAP_S); + } +} + +GLenum Texture::getWrapS() const +{ + return mState.mSamplerState.getWrapS(); +} + +void Texture::setWrapT(const Context *context, GLenum wrapT) +{ + if (mState.mSamplerState.getWrapT() == wrapT) + return; + if (mState.mSamplerState.setWrapT(wrapT)) + { + signalDirtyState(DIRTY_BIT_WRAP_T); + } +} + +GLenum Texture::getWrapT() const +{ + return mState.mSamplerState.getWrapT(); +} + +void Texture::setWrapR(const Context *context, GLenum wrapR) +{ + if (mState.mSamplerState.setWrapR(wrapR)) + { + signalDirtyState(DIRTY_BIT_WRAP_R); + } +} + +GLenum Texture::getWrapR() const +{ + return mState.mSamplerState.getWrapR(); +} + +void Texture::setMaxAnisotropy(const Context *context, float maxAnisotropy) +{ + if (mState.mSamplerState.setMaxAnisotropy(maxAnisotropy)) + { + signalDirtyState(DIRTY_BIT_MAX_ANISOTROPY); + } +} + +float Texture::getMaxAnisotropy() const +{ + return mState.mSamplerState.getMaxAnisotropy(); +} + +void Texture::setMinLod(const Context *context, GLfloat minLod) +{ + if (mState.mSamplerState.setMinLod(minLod)) + { + signalDirtyState(DIRTY_BIT_MIN_LOD); + } +} + +GLfloat Texture::getMinLod() const +{ + return mState.mSamplerState.getMinLod(); +} + +void Texture::setMaxLod(const Context *context, GLfloat maxLod) +{ + if (mState.mSamplerState.setMaxLod(maxLod)) + { + signalDirtyState(DIRTY_BIT_MAX_LOD); + } +} + +GLfloat Texture::getMaxLod() const +{ + return mState.mSamplerState.getMaxLod(); +} + +void Texture::setCompareMode(const Context *context, GLenum compareMode) +{ + if (mState.mSamplerState.setCompareMode(compareMode)) + { + signalDirtyState(DIRTY_BIT_COMPARE_MODE); + } +} + +GLenum Texture::getCompareMode() const +{ + return mState.mSamplerState.getCompareMode(); +} + +void Texture::setCompareFunc(const Context *context, GLenum compareFunc) +{ + if (mState.mSamplerState.setCompareFunc(compareFunc)) + { + signalDirtyState(DIRTY_BIT_COMPARE_FUNC); + } +} + +GLenum Texture::getCompareFunc() const +{ + return mState.mSamplerState.getCompareFunc(); +} + +void Texture::setSRGBDecode(const Context *context, GLenum sRGBDecode) +{ + if (mState.mSamplerState.setSRGBDecode(sRGBDecode)) + { + signalDirtyState(DIRTY_BIT_SRGB_DECODE); + } +} + +GLenum Texture::getSRGBDecode() const +{ + return mState.mSamplerState.getSRGBDecode(); +} + +void Texture::setSRGBOverride(const Context *context, GLenum sRGBOverride) +{ + SrgbOverride oldOverride = mState.mSrgbOverride; + mState.mSrgbOverride = (sRGBOverride == GL_SRGB) ? SrgbOverride::SRGB : SrgbOverride::Default; + if (mState.mSrgbOverride != oldOverride) + { + signalDirtyState(DIRTY_BIT_SRGB_OVERRIDE); + } +} + +GLenum Texture::getSRGBOverride() const +{ + return (mState.mSrgbOverride == SrgbOverride::SRGB) ? GL_SRGB : GL_NONE; +} + +const SamplerState &Texture::getSamplerState() const +{ + return mState.mSamplerState; +} + +angle::Result Texture::setBaseLevel(const Context *context, GLuint baseLevel) +{ + if (mState.setBaseLevel(baseLevel)) + { + ANGLE_TRY(mTexture->setBaseLevel(context, mState.getEffectiveBaseLevel())); + signalDirtyState(DIRTY_BIT_BASE_LEVEL); + } + + return angle::Result::Continue; +} + +GLuint Texture::getBaseLevel() const +{ + return mState.mBaseLevel; +} + +void Texture::setMaxLevel(const Context *context, GLuint maxLevel) +{ + if (mState.setMaxLevel(maxLevel)) + { + signalDirtyState(DIRTY_BIT_MAX_LEVEL); + } +} + +GLuint Texture::getMaxLevel() const +{ + return mState.mMaxLevel; +} + +void Texture::setDepthStencilTextureMode(const Context *context, GLenum mode) +{ + if (mState.mDepthStencilTextureMode != mode) + { + mState.mDepthStencilTextureMode = mode; + signalDirtyState(DIRTY_BIT_DEPTH_STENCIL_TEXTURE_MODE); + } +} + +GLenum Texture::getDepthStencilTextureMode() const +{ + return mState.mDepthStencilTextureMode; +} + +bool Texture::getImmutableFormat() const +{ + return mState.mImmutableFormat; +} + +GLuint Texture::getImmutableLevels() const +{ + return mState.mImmutableLevels; +} + +void Texture::setUsage(const Context *context, GLenum usage) +{ + mState.mUsage = usage; + signalDirtyState(DIRTY_BIT_USAGE); +} + +GLenum Texture::getUsage() const +{ + return mState.mUsage; +} + +void Texture::setProtectedContent(Context *context, bool hasProtectedContent) +{ + mState.mHasProtectedContent = hasProtectedContent; +} + +bool Texture::hasProtectedContent() const +{ + return mState.mHasProtectedContent; +} + +const TextureState &Texture::getTextureState() const +{ + return mState; +} + +const Extents &Texture::getExtents(TextureTarget target, size_t level) const +{ + ASSERT(TextureTargetToType(target) == mState.mType); + return mState.getImageDesc(target, level).size; +} + +size_t Texture::getWidth(TextureTarget target, size_t level) const +{ + ASSERT(TextureTargetToType(target) == mState.mType); + return mState.getImageDesc(target, level).size.width; +} + +size_t Texture::getHeight(TextureTarget target, size_t level) const +{ + ASSERT(TextureTargetToType(target) == mState.mType); + return mState.getImageDesc(target, level).size.height; +} + +size_t Texture::getDepth(TextureTarget target, size_t level) const +{ + ASSERT(TextureTargetToType(target) == mState.mType); + return mState.getImageDesc(target, level).size.depth; +} + +const Format &Texture::getFormat(TextureTarget target, size_t level) const +{ + ASSERT(TextureTargetToType(target) == mState.mType); + return mState.getImageDesc(target, level).format; +} + +GLsizei Texture::getSamples(TextureTarget target, size_t level) const +{ + ASSERT(TextureTargetToType(target) == mState.mType); + return mState.getImageDesc(target, level).samples; +} + +bool Texture::getFixedSampleLocations(TextureTarget target, size_t level) const +{ + ASSERT(TextureTargetToType(target) == mState.mType); + return mState.getImageDesc(target, level).fixedSampleLocations; +} + +GLuint Texture::getMipmapMaxLevel() const +{ + return mState.getMipmapMaxLevel(); +} + +bool Texture::isMipmapComplete() const +{ + return mState.computeMipmapCompleteness(); +} + +egl::Surface *Texture::getBoundSurface() const +{ + return mBoundSurface; +} + +egl::Stream *Texture::getBoundStream() const +{ + return mBoundStream; +} + +GLint Texture::getMemorySize() const +{ + GLint implSize = mTexture->getMemorySize(); + if (implSize > 0) + { + return implSize; + } + + angle::CheckedNumeric size = 0; + for (const ImageDesc &imageDesc : mState.mImageDescs) + { + size += imageDesc.getMemorySize(); + } + return size.ValueOrDefault(std::numeric_limits::max()); +} + +GLint Texture::getLevelMemorySize(TextureTarget target, GLint level) const +{ + GLint implSize = mTexture->getLevelMemorySize(target, level); + if (implSize > 0) + { + return implSize; + } + + return mState.getImageDesc(target, level).getMemorySize(); +} + +void Texture::signalDirtyStorage(InitState initState) +{ + mState.mInitState = initState; + invalidateCompletenessCache(); + mState.mCachedSamplerFormatValid = false; + onStateChange(angle::SubjectMessage::SubjectChanged); +} + +void Texture::signalDirtyState(size_t dirtyBit) +{ + mDirtyBits.set(dirtyBit); + invalidateCompletenessCache(); + mState.mCachedSamplerFormatValid = false; + + if (dirtyBit == DIRTY_BIT_BASE_LEVEL || dirtyBit == DIRTY_BIT_MAX_LEVEL) + { + onStateChange(angle::SubjectMessage::SubjectChanged); + } + else + { + onStateChange(angle::SubjectMessage::DirtyBitsFlagged); + } +} + +angle::Result Texture::setImage(Context *context, + const PixelUnpackState &unpackState, + Buffer *unpackBuffer, + TextureTarget target, + GLint level, + GLenum internalFormat, + const Extents &size, + GLenum format, + GLenum type, + const uint8_t *pixels) +{ + ASSERT(TextureTargetToType(target) == mState.mType); + + // Release from previous calls to eglBindTexImage, to avoid calling the Impl after + ANGLE_TRY(releaseTexImageInternal(context)); + + egl::RefCountObjectReleaser releaseImage; + ANGLE_TRY(orphanImages(context, &releaseImage)); + + ImageIndex index = ImageIndex::MakeFromTarget(target, level, size.depth); + + ANGLE_TRY(mTexture->setImage(context, index, internalFormat, size, format, type, unpackState, + unpackBuffer, pixels)); + + InitState initState = DetermineInitState(context, unpackBuffer, pixels); + mState.setImageDesc(target, level, ImageDesc(size, Format(internalFormat, type), initState)); + + ANGLE_TRY(handleMipmapGenerationHint(context, level)); + + signalDirtyStorage(initState); + + return angle::Result::Continue; +} + +angle::Result Texture::setSubImage(Context *context, + const PixelUnpackState &unpackState, + Buffer *unpackBuffer, + TextureTarget target, + GLint level, + const Box &area, + GLenum format, + GLenum type, + const uint8_t *pixels) +{ + ASSERT(TextureTargetToType(target) == mState.mType); + + ImageIndex index = ImageIndex::MakeFromTarget(target, level, area.depth); + ANGLE_TRY(ensureSubImageInitialized(context, index, area)); + + ANGLE_TRY(mTexture->setSubImage(context, index, area, format, type, unpackState, unpackBuffer, + pixels)); + + ANGLE_TRY(handleMipmapGenerationHint(context, level)); + + onStateChange(angle::SubjectMessage::ContentsChanged); + + return angle::Result::Continue; +} + +angle::Result Texture::setCompressedImage(Context *context, + const PixelUnpackState &unpackState, + TextureTarget target, + GLint level, + GLenum internalFormat, + const Extents &size, + size_t imageSize, + const uint8_t *pixels) +{ + ASSERT(TextureTargetToType(target) == mState.mType); + + // Release from previous calls to eglBindTexImage, to avoid calling the Impl after + ANGLE_TRY(releaseTexImageInternal(context)); + + egl::RefCountObjectReleaser releaseImage; + ANGLE_TRY(orphanImages(context, &releaseImage)); + + ImageIndex index = ImageIndex::MakeFromTarget(target, level, size.depth); + + ANGLE_TRY(mTexture->setCompressedImage(context, index, internalFormat, size, unpackState, + imageSize, pixels)); + + Buffer *unpackBuffer = context->getState().getTargetBuffer(BufferBinding::PixelUnpack); + + InitState initState = DetermineInitState(context, unpackBuffer, pixels); + mState.setImageDesc(target, level, ImageDesc(size, Format(internalFormat), initState)); + signalDirtyStorage(initState); + + return angle::Result::Continue; +} + +angle::Result Texture::setCompressedSubImage(const Context *context, + const PixelUnpackState &unpackState, + TextureTarget target, + GLint level, + const Box &area, + GLenum format, + size_t imageSize, + const uint8_t *pixels) +{ + ASSERT(TextureTargetToType(target) == mState.mType); + + ImageIndex index = ImageIndex::MakeFromTarget(target, level, area.depth); + ANGLE_TRY(ensureSubImageInitialized(context, index, area)); + + ANGLE_TRY(mTexture->setCompressedSubImage(context, index, area, format, unpackState, imageSize, + pixels)); + + onStateChange(angle::SubjectMessage::ContentsChanged); + + return angle::Result::Continue; +} + +angle::Result Texture::copyImage(Context *context, + TextureTarget target, + GLint level, + const Rectangle &sourceArea, + GLenum internalFormat, + Framebuffer *source) +{ + ASSERT(TextureTargetToType(target) == mState.mType); + + // Release from previous calls to eglBindTexImage, to avoid calling the Impl after + ANGLE_TRY(releaseTexImageInternal(context)); + + egl::RefCountObjectReleaser releaseImage; + ANGLE_TRY(orphanImages(context, &releaseImage)); + + ImageIndex index = ImageIndex::MakeFromTarget(target, level, 1); + + const InternalFormat &internalFormatInfo = + GetInternalFormatInfo(internalFormat, GL_UNSIGNED_BYTE); + + // Most if not all renderers clip these copies to the size of the source framebuffer, leaving + // other pixels untouched. For safety in robust resource initialization, assume that that + // clipping is going to occur when computing the region for which to ensure initialization. If + // the copy lies entirely off the source framebuffer, initialize as though a zero-size box is + // going to be set during the copy operation. + Box destBox; + bool forceCopySubImage = false; + if (context->isRobustResourceInitEnabled()) + { + const FramebufferAttachment *sourceReadAttachment = source->getReadColorAttachment(); + Extents fbSize = sourceReadAttachment->getSize(); + // Force using copySubImage when the source area is out of bounds AND + // we're not copying to and from the same texture + forceCopySubImage = ((sourceArea.x < 0) || (sourceArea.y < 0) || + ((sourceArea.x + sourceArea.width) > fbSize.width) || + ((sourceArea.y + sourceArea.height) > fbSize.height)) && + (sourceReadAttachment->getResource() != this); + Rectangle clippedArea; + if (ClipRectangle(sourceArea, Rectangle(0, 0, fbSize.width, fbSize.height), &clippedArea)) + { + const Offset clippedOffset(clippedArea.x - sourceArea.x, clippedArea.y - sourceArea.y, + 0); + destBox = Box(clippedOffset.x, clippedOffset.y, clippedOffset.z, clippedArea.width, + clippedArea.height, 1); + } + } + + InitState initState = DetermineInitState(context, nullptr, nullptr); + + // If we need to initialize the destination texture we split the call into a create call, + // an initializeContents call, and then a copySubImage call. This ensures the destination + // texture exists before we try to clear it. + Extents size(sourceArea.width, sourceArea.height, 1); + if (forceCopySubImage || doesSubImageNeedInit(context, index, destBox)) + { + ANGLE_TRY(mTexture->setImage(context, index, internalFormat, size, + internalFormatInfo.format, internalFormatInfo.type, + PixelUnpackState(), nullptr, nullptr)); + mState.setImageDesc(target, level, ImageDesc(size, Format(internalFormatInfo), initState)); + ANGLE_TRY(ensureSubImageInitialized(context, index, destBox)); + ANGLE_TRY(mTexture->copySubImage(context, index, Offset(), sourceArea, source)); + } + else + { + ANGLE_TRY(mTexture->copyImage(context, index, sourceArea, internalFormat, source)); + } + + mState.setImageDesc(target, level, + ImageDesc(size, Format(internalFormatInfo), InitState::Initialized)); + + ANGLE_TRY(handleMipmapGenerationHint(context, level)); + + // Because this could affect the texture storage we might need to init other layers/levels. + signalDirtyStorage(initState); + + return angle::Result::Continue; +} + +angle::Result Texture::copySubImage(Context *context, + const ImageIndex &index, + const Offset &destOffset, + const Rectangle &sourceArea, + Framebuffer *source) +{ + ASSERT(TextureTargetToType(index.getTarget()) == mState.mType); + + // Most if not all renderers clip these copies to the size of the source framebuffer, leaving + // other pixels untouched. For safety in robust resource initialization, assume that that + // clipping is going to occur when computing the region for which to ensure initialization. If + // the copy lies entirely off the source framebuffer, initialize as though a zero-size box is + // going to be set during the copy operation. Note that this assumes that + // ensureSubImageInitialized ensures initialization of the entire destination texture, and not + // just a sub-region. + Box destBox; + if (context->isRobustResourceInitEnabled()) + { + Extents fbSize = source->getReadColorAttachment()->getSize(); + Rectangle clippedArea; + if (ClipRectangle(sourceArea, Rectangle(0, 0, fbSize.width, fbSize.height), &clippedArea)) + { + const Offset clippedOffset(destOffset.x + clippedArea.x - sourceArea.x, + destOffset.y + clippedArea.y - sourceArea.y, 0); + destBox = Box(clippedOffset.x, clippedOffset.y, clippedOffset.z, clippedArea.width, + clippedArea.height, 1); + } + } + + ANGLE_TRY(ensureSubImageInitialized(context, index, destBox)); + + ANGLE_TRY(mTexture->copySubImage(context, index, destOffset, sourceArea, source)); + ANGLE_TRY(handleMipmapGenerationHint(context, index.getLevelIndex())); + + onStateChange(angle::SubjectMessage::ContentsChanged); + + return angle::Result::Continue; +} + +angle::Result Texture::copyRenderbufferSubData(Context *context, + const gl::Renderbuffer *srcBuffer, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth) +{ + ANGLE_TRY(mTexture->copyRenderbufferSubData(context, srcBuffer, srcLevel, srcX, srcY, srcZ, + dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight, + srcDepth)); + + signalDirtyStorage(InitState::Initialized); + + return angle::Result::Continue; +} + +angle::Result Texture::copyTextureSubData(Context *context, + const gl::Texture *srcTexture, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth) +{ + ANGLE_TRY(mTexture->copyTextureSubData(context, srcTexture, srcLevel, srcX, srcY, srcZ, + dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight, + srcDepth)); + + signalDirtyStorage(InitState::Initialized); + + return angle::Result::Continue; +} + +angle::Result Texture::copyTexture(Context *context, + TextureTarget target, + GLint level, + GLenum internalFormat, + GLenum type, + GLint sourceLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + Texture *source) +{ + ASSERT(TextureTargetToType(target) == mState.mType); + ASSERT(source->getType() != TextureType::CubeMap); + + // Release from previous calls to eglBindTexImage, to avoid calling the Impl after + ANGLE_TRY(releaseTexImageInternal(context)); + + egl::RefCountObjectReleaser releaseImage; + ANGLE_TRY(orphanImages(context, &releaseImage)); + + // Initialize source texture. + // Note: we don't have a way to notify which portions of the image changed currently. + ANGLE_TRY(source->ensureInitialized(context)); + + ImageIndex index = ImageIndex::MakeFromTarget(target, level, ImageIndex::kEntireLevel); + + ANGLE_TRY(mTexture->copyTexture(context, index, internalFormat, type, sourceLevel, unpackFlipY, + unpackPremultiplyAlpha, unpackUnmultiplyAlpha, source)); + + const auto &sourceDesc = + source->mState.getImageDesc(NonCubeTextureTypeToTarget(source->getType()), sourceLevel); + const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type); + mState.setImageDesc( + target, level, + ImageDesc(sourceDesc.size, Format(internalFormatInfo), InitState::Initialized)); + + signalDirtyStorage(InitState::Initialized); + + return angle::Result::Continue; +} + +angle::Result Texture::copySubTexture(const Context *context, + TextureTarget target, + GLint level, + const Offset &destOffset, + GLint sourceLevel, + const Box &sourceBox, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + Texture *source) +{ + ASSERT(TextureTargetToType(target) == mState.mType); + + // Ensure source is initialized. + ANGLE_TRY(source->ensureInitialized(context)); + + Box destBox(destOffset.x, destOffset.y, destOffset.z, sourceBox.width, sourceBox.height, + sourceBox.depth); + ImageIndex index = ImageIndex::MakeFromTarget(target, level, sourceBox.depth); + ANGLE_TRY(ensureSubImageInitialized(context, index, destBox)); + + ANGLE_TRY(mTexture->copySubTexture(context, index, destOffset, sourceLevel, sourceBox, + unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha, + source)); + + onStateChange(angle::SubjectMessage::ContentsChanged); + + return angle::Result::Continue; +} + +angle::Result Texture::copyCompressedTexture(Context *context, const Texture *source) +{ + // Release from previous calls to eglBindTexImage, to avoid calling the Impl after + ANGLE_TRY(releaseTexImageInternal(context)); + + egl::RefCountObjectReleaser releaseImage; + ANGLE_TRY(orphanImages(context, &releaseImage)); + + ANGLE_TRY(mTexture->copyCompressedTexture(context, source)); + + ASSERT(source->getType() != TextureType::CubeMap && getType() != TextureType::CubeMap); + const auto &sourceDesc = + source->mState.getImageDesc(NonCubeTextureTypeToTarget(source->getType()), 0); + mState.setImageDesc(NonCubeTextureTypeToTarget(getType()), 0, sourceDesc); + + return angle::Result::Continue; +} + +angle::Result Texture::setStorage(Context *context, + TextureType type, + GLsizei levels, + GLenum internalFormat, + const Extents &size) +{ + ASSERT(type == mState.mType); + + // Release from previous calls to eglBindTexImage, to avoid calling the Impl after + ANGLE_TRY(releaseTexImageInternal(context)); + + egl::RefCountObjectReleaser releaseImage; + ANGLE_TRY(orphanImages(context, &releaseImage)); + + mState.mImmutableFormat = true; + mState.mImmutableLevels = static_cast(levels); + mState.clearImageDescs(); + InitState initState = DetermineInitState(context, nullptr, nullptr); + mState.setImageDescChain(0, static_cast(levels - 1), size, Format(internalFormat), + initState); + + ANGLE_TRY(mTexture->setStorage(context, type, levels, internalFormat, size)); + + // Changing the texture to immutable can trigger a change in the base and max levels: + // GLES 3.0.4 section 3.8.10 pg 158: + // "For immutable-format textures, levelbase is clamped to the range[0;levels],levelmax is then + // clamped to the range[levelbase;levels]. + mDirtyBits.set(DIRTY_BIT_BASE_LEVEL); + mDirtyBits.set(DIRTY_BIT_MAX_LEVEL); + + signalDirtyStorage(initState); + + return angle::Result::Continue; +} + +angle::Result Texture::setImageExternal(Context *context, + TextureTarget target, + GLint level, + GLenum internalFormat, + const Extents &size, + GLenum format, + GLenum type) +{ + ASSERT(TextureTargetToType(target) == mState.mType); + + // Release from previous calls to eglBindTexImage, to avoid calling the Impl after + ANGLE_TRY(releaseTexImageInternal(context)); + + egl::RefCountObjectReleaser releaseImage; + ANGLE_TRY(orphanImages(context, &releaseImage)); + + ImageIndex index = ImageIndex::MakeFromTarget(target, level, size.depth); + + ANGLE_TRY(mTexture->setImageExternal(context, index, internalFormat, size, format, type)); + + InitState initState = InitState::Initialized; + mState.setImageDesc(target, level, ImageDesc(size, Format(internalFormat, type), initState)); + + ANGLE_TRY(handleMipmapGenerationHint(context, level)); + + signalDirtyStorage(initState); + + return angle::Result::Continue; +} + +angle::Result Texture::setStorageMultisample(Context *context, + TextureType type, + GLsizei samplesIn, + GLint internalFormat, + const Extents &size, + bool fixedSampleLocations) +{ + ASSERT(type == mState.mType); + + // Release from previous calls to eglBindTexImage, to avoid calling the Impl after + ANGLE_TRY(releaseTexImageInternal(context)); + + egl::RefCountObjectReleaser releaseImage; + ANGLE_TRY(orphanImages(context, &releaseImage)); + + // Potentially adjust "samples" to a supported value + const TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat); + GLsizei samples = formatCaps.getNearestSamples(samplesIn); + + mState.mImmutableFormat = true; + mState.mImmutableLevels = static_cast(1); + mState.clearImageDescs(); + InitState initState = DetermineInitState(context, nullptr, nullptr); + mState.setImageDescChainMultisample(size, Format(internalFormat), samples, fixedSampleLocations, + initState); + + ANGLE_TRY(mTexture->setStorageMultisample(context, type, samples, internalFormat, size, + fixedSampleLocations)); + signalDirtyStorage(initState); + + return angle::Result::Continue; +} + +angle::Result Texture::setStorageExternalMemory(Context *context, + TextureType type, + GLsizei levels, + GLenum internalFormat, + const Extents &size, + MemoryObject *memoryObject, + GLuint64 offset, + GLbitfield createFlags, + GLbitfield usageFlags, + const void *imageCreateInfoPNext) +{ + ASSERT(type == mState.mType); + + // Release from previous calls to eglBindTexImage, to avoid calling the Impl after + ANGLE_TRY(releaseTexImageInternal(context)); + + egl::RefCountObjectReleaser releaseImage; + ANGLE_TRY(orphanImages(context, &releaseImage)); + + ANGLE_TRY(mTexture->setStorageExternalMemory(context, type, levels, internalFormat, size, + memoryObject, offset, createFlags, usageFlags, + imageCreateInfoPNext)); + + mState.mImmutableFormat = true; + mState.mImmutableLevels = static_cast(levels); + mState.clearImageDescs(); + mState.setImageDescChain(0, static_cast(levels - 1), size, Format(internalFormat), + InitState::Initialized); + + // Changing the texture to immutable can trigger a change in the base and max levels: + // GLES 3.0.4 section 3.8.10 pg 158: + // "For immutable-format textures, levelbase is clamped to the range[0;levels],levelmax is then + // clamped to the range[levelbase;levels]. + mDirtyBits.set(DIRTY_BIT_BASE_LEVEL); + mDirtyBits.set(DIRTY_BIT_MAX_LEVEL); + + signalDirtyStorage(InitState::Initialized); + + return angle::Result::Continue; +} + +angle::Result Texture::generateMipmap(Context *context) +{ + // Release from previous calls to eglBindTexImage, to avoid calling the Impl after + ANGLE_TRY(releaseTexImageInternal(context)); + + // EGL_KHR_gl_image states that images are only orphaned when generating mipmaps if the texture + // is not mip complete. + egl::RefCountObjectReleaser releaseImage; + if (!isMipmapComplete()) + { + ANGLE_TRY(orphanImages(context, &releaseImage)); + } + + const GLuint baseLevel = mState.getEffectiveBaseLevel(); + const GLuint maxLevel = mState.getMipmapMaxLevel(); + + if (maxLevel <= baseLevel) + { + return angle::Result::Continue; + } + + // If any dimension is zero, this is a no-op: + // + // > Otherwise, if level_base is not defined, or if any dimension is zero, all mipmap levels are + // > left unchanged. This is not an error. + const ImageDesc &baseImageInfo = mState.getImageDesc(mState.getBaseImageTarget(), baseLevel); + if (baseImageInfo.size.empty()) + { + return angle::Result::Continue; + } + + // Clear the base image(s) immediately if needed + if (context->isRobustResourceInitEnabled()) + { + ImageIndexIterator it = + ImageIndexIterator::MakeGeneric(mState.mType, baseLevel, baseLevel + 1, + ImageIndex::kEntireLevel, ImageIndex::kEntireLevel); + while (it.hasNext()) + { + const ImageIndex index = it.next(); + const ImageDesc &desc = mState.getImageDesc(index.getTarget(), index.getLevelIndex()); + + if (desc.initState == InitState::MayNeedInit) + { + ANGLE_TRY(initializeContents(context, GL_NONE, index)); + } + } + } + + ANGLE_TRY(syncState(context, Command::GenerateMipmap)); + ANGLE_TRY(mTexture->generateMipmap(context)); + + // Propagate the format and size of the base mip to the smaller ones. Cube maps are guaranteed + // to have faces of the same size and format so any faces can be picked. + mState.setImageDescChain(baseLevel, maxLevel, baseImageInfo.size, baseImageInfo.format, + InitState::Initialized); + + signalDirtyStorage(InitState::Initialized); + + return angle::Result::Continue; +} + +angle::Result Texture::bindTexImageFromSurface(Context *context, egl::Surface *surface) +{ + ASSERT(surface); + + if (mBoundSurface) + { + ANGLE_TRY(releaseTexImageFromSurface(context)); + } + + mBoundSurface = surface; + + // Set the image info to the size and format of the surface + ASSERT(mState.mType == TextureType::_2D || mState.mType == TextureType::Rectangle); + Extents size(surface->getWidth(), surface->getHeight(), 1); + ImageDesc desc(size, surface->getBindTexImageFormat(), InitState::Initialized); + mState.setImageDesc(NonCubeTextureTypeToTarget(mState.mType), 0, desc); + mState.mHasProtectedContent = surface->hasProtectedContent(); + + ANGLE_TRY(mTexture->bindTexImage(context, surface)); + + signalDirtyStorage(InitState::Initialized); + return angle::Result::Continue; +} + +angle::Result Texture::releaseTexImageFromSurface(const Context *context) +{ + ASSERT(mBoundSurface); + mBoundSurface = nullptr; + ANGLE_TRY(mTexture->releaseTexImage(context)); + + // Erase the image info for level 0 + ASSERT(mState.mType == TextureType::_2D || mState.mType == TextureType::Rectangle); + mState.clearImageDesc(NonCubeTextureTypeToTarget(mState.mType), 0); + mState.mHasProtectedContent = false; + signalDirtyStorage(InitState::Initialized); + return angle::Result::Continue; +} + +void Texture::bindStream(egl::Stream *stream) +{ + ASSERT(stream); + + // It should not be possible to bind a texture already bound to another stream + ASSERT(mBoundStream == nullptr); + + mBoundStream = stream; + + ASSERT(mState.mType == TextureType::External); +} + +void Texture::releaseStream() +{ + ASSERT(mBoundStream); + mBoundStream = nullptr; +} + +angle::Result Texture::acquireImageFromStream(const Context *context, + const egl::Stream::GLTextureDescription &desc) +{ + ASSERT(mBoundStream != nullptr); + ANGLE_TRY(mTexture->setImageExternal(context, mState.mType, mBoundStream, desc)); + + Extents size(desc.width, desc.height, 1); + mState.setImageDesc(NonCubeTextureTypeToTarget(mState.mType), 0, + ImageDesc(size, Format(desc.internalFormat), InitState::Initialized)); + signalDirtyStorage(InitState::Initialized); + return angle::Result::Continue; +} + +angle::Result Texture::releaseImageFromStream(const Context *context) +{ + ASSERT(mBoundStream != nullptr); + ANGLE_TRY(mTexture->setImageExternal(context, mState.mType, nullptr, + egl::Stream::GLTextureDescription())); + + // Set to incomplete + mState.clearImageDesc(NonCubeTextureTypeToTarget(mState.mType), 0); + signalDirtyStorage(InitState::Initialized); + return angle::Result::Continue; +} + +angle::Result Texture::releaseTexImageInternal(Context *context) +{ + if (mBoundSurface) + { + // Notify the surface + egl::Error eglErr = mBoundSurface->releaseTexImageFromTexture(context); + // TODO(jmadill): Remove this once refactor is complete. http://anglebug.com/3041 + if (eglErr.isError()) + { + context->handleError(GL_INVALID_OPERATION, "Error releasing tex image from texture", + __FILE__, ANGLE_FUNCTION, __LINE__); + } + + // Then, call the same method as from the surface + ANGLE_TRY(releaseTexImageFromSurface(context)); + } + return angle::Result::Continue; +} + +angle::Result Texture::setEGLImageTargetImpl(Context *context, + TextureType type, + GLuint levels, + egl::Image *imageTarget) +{ + ASSERT(type == mState.mType); + + // Release from previous calls to eglBindTexImage, to avoid calling the Impl after + ANGLE_TRY(releaseTexImageInternal(context)); + + egl::RefCountObjectReleaser releaseImage; + ANGLE_TRY(orphanImages(context, &releaseImage)); + + setTargetImage(context, imageTarget); + + auto initState = imageTarget->sourceInitState(); + + mState.clearImageDescs(); + mState.setImageDescChain(0, levels - 1, imageTarget->getExtents(), imageTarget->getFormat(), + initState); + mState.mHasProtectedContent = imageTarget->hasProtectedContent(); + + ANGLE_TRY(mTexture->setEGLImageTarget(context, type, imageTarget)); + + signalDirtyStorage(initState); + + return angle::Result::Continue; +} + +angle::Result Texture::setEGLImageTarget(Context *context, + TextureType type, + egl::Image *imageTarget) +{ + ASSERT(type == TextureType::_2D || type == TextureType::External || + type == TextureType::_2DArray); + + return setEGLImageTargetImpl(context, type, 1u, imageTarget); +} + +angle::Result Texture::setStorageEGLImageTarget(Context *context, + TextureType type, + egl::Image *imageTarget, + const GLint *attrib_list) +{ + ASSERT(type == TextureType::External || type == TextureType::_3D || type == TextureType::_2D || + type == TextureType::_2DArray || type == TextureType::CubeMap || + type == TextureType::CubeMapArray); + + ANGLE_TRY(setEGLImageTargetImpl(context, type, imageTarget->getLevelCount(), imageTarget)); + + mState.mImmutableLevels = imageTarget->getLevelCount(); + mState.mImmutableFormat = true; + + // Changing the texture to immutable can trigger a change in the base and max levels: + // GLES 3.0.4 section 3.8.10 pg 158: + // "For immutable-format textures, levelbase is clamped to the range[0;levels],levelmax is then + // clamped to the range[levelbase;levels]. + mDirtyBits.set(DIRTY_BIT_BASE_LEVEL); + mDirtyBits.set(DIRTY_BIT_MAX_LEVEL); + + return angle::Result::Continue; +} + +Extents Texture::getAttachmentSize(const ImageIndex &imageIndex) const +{ + // As an ImageIndex that represents an entire level of a cube map corresponds to 6 ImageDescs, + // we only allow querying ImageDesc on a complete cube map, and this ImageDesc is exactly the + // one that belongs to the first face of the cube map. + if (imageIndex.isEntireLevelCubeMap()) + { + // A cube map texture is cube complete if the following conditions all hold true: + // - The levelbase arrays of each of the six texture images making up the cube map have + // identical, positive, and square dimensions. + if (!mState.isCubeComplete()) + { + return Extents(); + } + } + + return mState.getImageDesc(imageIndex).size; +} + +Format Texture::getAttachmentFormat(GLenum /*binding*/, const ImageIndex &imageIndex) const +{ + // As an ImageIndex that represents an entire level of a cube map corresponds to 6 ImageDescs, + // we only allow querying ImageDesc on a complete cube map, and this ImageDesc is exactly the + // one that belongs to the first face of the cube map. + if (imageIndex.isEntireLevelCubeMap()) + { + // A cube map texture is cube complete if the following conditions all hold true: + // - The levelbase arrays were each specified with the same effective internal format. + if (!mState.isCubeComplete()) + { + return Format::Invalid(); + } + } + return mState.getImageDesc(imageIndex).format; +} + +GLsizei Texture::getAttachmentSamples(const ImageIndex &imageIndex) const +{ + // We do not allow querying TextureTarget by an ImageIndex that represents an entire level of a + // cube map (See comments in function TextureTypeToTarget() in ImageIndex.cpp). + if (imageIndex.isEntireLevelCubeMap()) + { + return 0; + } + + return getSamples(imageIndex.getTarget(), imageIndex.getLevelIndex()); +} + +bool Texture::isRenderable(const Context *context, + GLenum binding, + const ImageIndex &imageIndex) const +{ + if (isEGLImageTarget()) + { + return ImageSibling::isRenderable(context, binding, imageIndex); + } + + // Surfaces bound to textures are always renderable. This avoids issues with surfaces with ES3+ + // formats not being renderable when bound to textures in ES2 contexts. + if (mBoundSurface) + { + return true; + } + + return getAttachmentFormat(binding, imageIndex) + .info->textureAttachmentSupport(context->getClientVersion(), context->getExtensions()); +} + +bool Texture::getAttachmentFixedSampleLocations(const ImageIndex &imageIndex) const +{ + // We do not allow querying TextureTarget by an ImageIndex that represents an entire level of a + // cube map (See comments in function TextureTypeToTarget() in ImageIndex.cpp). + if (imageIndex.isEntireLevelCubeMap()) + { + return true; + } + + // ES3.1 (section 9.4) requires that the value of TEXTURE_FIXED_SAMPLE_LOCATIONS should be + // the same for all attached textures. + return getFixedSampleLocations(imageIndex.getTarget(), imageIndex.getLevelIndex()); +} + +void Texture::setBorderColor(const Context *context, const ColorGeneric &color) +{ + mState.mSamplerState.setBorderColor(color); + signalDirtyState(DIRTY_BIT_BORDER_COLOR); +} + +const ColorGeneric &Texture::getBorderColor() const +{ + return mState.mSamplerState.getBorderColor(); +} + +GLint Texture::getRequiredTextureImageUnits(const Context *context) const +{ + // Only external texture types can return non-1. + if (mState.mType != TextureType::External) + { + return 1; + } + + return mTexture->getRequiredExternalTextureImageUnits(context); +} + +void Texture::setCrop(const Rectangle &rect) +{ + mState.setCrop(rect); +} + +const Rectangle &Texture::getCrop() const +{ + return mState.getCrop(); +} + +void Texture::setGenerateMipmapHint(GLenum hint) +{ + mState.setGenerateMipmapHint(hint); +} + +GLenum Texture::getGenerateMipmapHint() const +{ + return mState.getGenerateMipmapHint(); +} + +angle::Result Texture::setBuffer(const gl::Context *context, + gl::Buffer *buffer, + GLenum internalFormat) +{ + // Use 0 to indicate that the size is taken from whatever size the buffer has when the texture + // buffer is used. + return setBufferRange(context, buffer, internalFormat, 0, 0); +} + +angle::Result Texture::setBufferRange(const gl::Context *context, + gl::Buffer *buffer, + GLenum internalFormat, + GLintptr offset, + GLsizeiptr size) +{ + mState.mImmutableFormat = true; + mState.mBuffer.set(context, buffer, offset, size); + ANGLE_TRY(mTexture->setBuffer(context, internalFormat)); + + mState.clearImageDescs(); + if (buffer == nullptr) + { + mBufferObserver.reset(); + InitState initState = DetermineInitState(context, nullptr, nullptr); + signalDirtyStorage(initState); + return angle::Result::Continue; + } + + size = GetBoundBufferAvailableSize(mState.mBuffer); + + mState.mImmutableLevels = static_cast(1); + InternalFormat internalFormatInfo = GetSizedInternalFormatInfo(internalFormat); + Format format(internalFormat); + Extents extents(static_cast(size / internalFormatInfo.pixelBytes), 1, 1); + InitState initState = buffer->initState(); + mState.setImageDesc(TextureTarget::Buffer, 0, ImageDesc(extents, format, initState)); + + signalDirtyStorage(initState); + + // Observe modifications to the buffer, so that extents can be updated. + mBufferObserver.bind(buffer); + + return angle::Result::Continue; +} + +const OffsetBindingPointer &Texture::getBuffer() const +{ + return mState.mBuffer; +} + +void Texture::onAttach(const Context *context, rx::Serial framebufferSerial) +{ + addRef(); + + // Duplicates allowed for multiple attachment points. See the comment in the header. + mBoundFramebufferSerials.push_back(framebufferSerial); + + if (!mState.mHasBeenBoundAsAttachment) + { + mDirtyBits.set(DIRTY_BIT_BOUND_AS_ATTACHMENT); + mState.mHasBeenBoundAsAttachment = true; + } +} + +void Texture::onDetach(const Context *context, rx::Serial framebufferSerial) +{ + // Erase first instance. If there are multiple bindings, leave the others. + ASSERT(isBoundToFramebuffer(framebufferSerial)); + mBoundFramebufferSerials.remove_and_permute(framebufferSerial); + + release(context); +} + +GLuint Texture::getId() const +{ + return id().value; +} + +GLuint Texture::getNativeID() const +{ + return mTexture->getNativeID(); +} + +angle::Result Texture::syncState(const Context *context, Command source) +{ + ASSERT(hasAnyDirtyBit() || source == Command::GenerateMipmap); + ANGLE_TRY(mTexture->syncState(context, mDirtyBits, source)); + mDirtyBits.reset(); + mState.mInitState = InitState::Initialized; + return angle::Result::Continue; +} + +rx::FramebufferAttachmentObjectImpl *Texture::getAttachmentImpl() const +{ + return mTexture; +} + +bool Texture::isSamplerComplete(const Context *context, const Sampler *optionalSampler) +{ + const auto &samplerState = + optionalSampler ? optionalSampler->getSamplerState() : mState.mSamplerState; + const auto &contextState = context->getState(); + + if (contextState.getContextID() != mCompletenessCache.context || + !mCompletenessCache.samplerState.sameCompleteness(samplerState)) + { + mCompletenessCache.context = context->getState().getContextID(); + mCompletenessCache.samplerState = samplerState; + mCompletenessCache.samplerComplete = + mState.computeSamplerCompleteness(samplerState, contextState); + } + + return mCompletenessCache.samplerComplete; +} + +// CopyImageSubData requires that we ignore format-based completeness rules +bool Texture::isSamplerCompleteForCopyImage(const Context *context, + const Sampler *optionalSampler) const +{ + const gl::SamplerState &samplerState = + optionalSampler ? optionalSampler->getSamplerState() : mState.mSamplerState; + const gl::State &contextState = context->getState(); + return mState.computeSamplerCompletenessForCopyImage(samplerState, contextState); +} + +Texture::SamplerCompletenessCache::SamplerCompletenessCache() + : context({0}), samplerState(), samplerComplete(false) +{} + +void Texture::invalidateCompletenessCache() const +{ + mCompletenessCache.context = {0}; +} + +angle::Result Texture::ensureInitialized(const Context *context) +{ + if (!context->isRobustResourceInitEnabled() || mState.mInitState == InitState::Initialized) + { + return angle::Result::Continue; + } + + bool anyDirty = false; + + ImageIndexIterator it = + ImageIndexIterator::MakeGeneric(mState.mType, 0, IMPLEMENTATION_MAX_TEXTURE_LEVELS + 1, + ImageIndex::kEntireLevel, ImageIndex::kEntireLevel); + while (it.hasNext()) + { + const ImageIndex index = it.next(); + ImageDesc &desc = + mState.mImageDescs[GetImageDescIndex(index.getTarget(), index.getLevelIndex())]; + if (desc.initState == InitState::MayNeedInit && !desc.size.empty()) + { + ASSERT(mState.mInitState == InitState::MayNeedInit); + ANGLE_TRY(initializeContents(context, GL_NONE, index)); + desc.initState = InitState::Initialized; + anyDirty = true; + } + } + if (anyDirty) + { + signalDirtyStorage(InitState::Initialized); + } + mState.mInitState = InitState::Initialized; + + return angle::Result::Continue; +} + +InitState Texture::initState(GLenum /*binding*/, const ImageIndex &imageIndex) const +{ + // As an ImageIndex that represents an entire level of a cube map corresponds to 6 ImageDescs, + // we need to check all the related ImageDescs. + if (imageIndex.isEntireLevelCubeMap()) + { + const GLint levelIndex = imageIndex.getLevelIndex(); + for (TextureTarget cubeFaceTarget : AllCubeFaceTextureTargets()) + { + if (mState.getImageDesc(cubeFaceTarget, levelIndex).initState == InitState::MayNeedInit) + { + return InitState::MayNeedInit; + } + } + return InitState::Initialized; + } + + return mState.getImageDesc(imageIndex).initState; +} + +void Texture::setInitState(GLenum binding, const ImageIndex &imageIndex, InitState initState) +{ + // As an ImageIndex that represents an entire level of a cube map corresponds to 6 ImageDescs, + // we need to update all the related ImageDescs. + if (imageIndex.isEntireLevelCubeMap()) + { + const GLint levelIndex = imageIndex.getLevelIndex(); + for (TextureTarget cubeFaceTarget : AllCubeFaceTextureTargets()) + { + setInitState(binding, ImageIndex::MakeCubeMapFace(cubeFaceTarget, levelIndex), + initState); + } + } + else + { + ImageDesc newDesc = mState.getImageDesc(imageIndex); + newDesc.initState = initState; + mState.setImageDesc(imageIndex.getTarget(), imageIndex.getLevelIndex(), newDesc); + } +} + +void Texture::setInitState(InitState initState) +{ + for (ImageDesc &imageDesc : mState.mImageDescs) + { + // Only modify defined images, undefined images will remain in the initialized state + if (!imageDesc.size.empty()) + { + imageDesc.initState = initState; + } + } + mState.mInitState = initState; +} + +bool Texture::doesSubImageNeedInit(const Context *context, + const ImageIndex &imageIndex, + const Box &area) const +{ + if (!context->isRobustResourceInitEnabled() || mState.mInitState == InitState::Initialized) + { + return false; + } + + // Pre-initialize the texture contents if necessary. + const ImageDesc &desc = mState.getImageDesc(imageIndex); + if (desc.initState != InitState::MayNeedInit) + { + return false; + } + + ASSERT(mState.mInitState == InitState::MayNeedInit); + return !area.coversSameExtent(desc.size); +} + +angle::Result Texture::ensureSubImageInitialized(const Context *context, + const ImageIndex &imageIndex, + const Box &area) +{ + if (doesSubImageNeedInit(context, imageIndex, area)) + { + // NOTE: do not optimize this to only initialize the passed area of the texture, or the + // initialization logic in copySubImage will be incorrect. + ANGLE_TRY(initializeContents(context, GL_NONE, imageIndex)); + } + // Note: binding is ignored for textures. + setInitState(GL_NONE, imageIndex, InitState::Initialized); + return angle::Result::Continue; +} + +angle::Result Texture::handleMipmapGenerationHint(Context *context, int level) +{ + if (getGenerateMipmapHint() == GL_TRUE && level == 0) + { + ANGLE_TRY(generateMipmap(context)); + } + + return angle::Result::Continue; +} + +void Texture::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) +{ + switch (message) + { + case angle::SubjectMessage::ContentsChanged: + if (index != kBufferSubjectIndex) + { + // ContentsChange originates from TextureStorage11::resolveAndReleaseTexture + // which resolves the underlying multisampled texture if it exists and so + // Texture will signal dirty storage to invalidate its own cache and the + // attached framebuffer's cache. + signalDirtyStorage(InitState::Initialized); + } + break; + case angle::SubjectMessage::DirtyBitsFlagged: + signalDirtyState(DIRTY_BIT_IMPLEMENTATION); + + // Notify siblings that we are dirty. + if (index == rx::kTextureImageImplObserverMessageIndex) + { + notifySiblings(message); + } + break; + case angle::SubjectMessage::SubjectChanged: + mState.mInitState = InitState::MayNeedInit; + signalDirtyState(DIRTY_BIT_IMPLEMENTATION); + onStateChange(angle::SubjectMessage::ContentsChanged); + + // Notify siblings that we are dirty. + if (index == rx::kTextureImageImplObserverMessageIndex) + { + notifySiblings(message); + } + else if (index == kBufferSubjectIndex) + { + const gl::Buffer *buffer = mState.mBuffer.get(); + ASSERT(buffer != nullptr); + + // Update cached image desc based on buffer size. + GLsizeiptr size = GetBoundBufferAvailableSize(mState.mBuffer); + + ImageDesc desc = mState.getImageDesc(TextureTarget::Buffer, 0); + const GLuint pixelBytes = desc.format.info->pixelBytes; + desc.size.width = static_cast(size / pixelBytes); + + mState.setImageDesc(TextureTarget::Buffer, 0, desc); + } + break; + case angle::SubjectMessage::StorageReleased: + // When the TextureStorage is released, it needs to update the + // RenderTargetCache of the Framebuffer attaching this Texture. + // This is currently only for D3D back-end. See http://crbug.com/1234829 + if (index == rx::kTextureImageImplObserverMessageIndex) + { + onStateChange(angle::SubjectMessage::StorageReleased); + } + break; + case angle::SubjectMessage::SubjectMapped: + case angle::SubjectMessage::SubjectUnmapped: + case angle::SubjectMessage::BindingChanged: + ASSERT(index == kBufferSubjectIndex); + break; + case angle::SubjectMessage::InitializationComplete: + ASSERT(index == rx::kTextureImageImplObserverMessageIndex); + setInitState(InitState::Initialized); + break; + case angle::SubjectMessage::InternalMemoryAllocationChanged: + // Need to mark the texture dirty to give the back end a chance to handle the new + // buffer. For example, the Vulkan back end needs to create a new buffer view that + // points to the newly allocated buffer and update the texture descriptor set. + signalDirtyState(DIRTY_BIT_IMPLEMENTATION); + break; + default: + UNREACHABLE(); + break; + } +} + +GLenum Texture::getImplementationColorReadFormat(const Context *context) const +{ + return mTexture->getColorReadFormat(context); +} + +GLenum Texture::getImplementationColorReadType(const Context *context) const +{ + return mTexture->getColorReadType(context); +} + +bool Texture::isCompressedFormatEmulated(const Context *context, + TextureTarget target, + GLint level) const +{ + if (!getFormat(target, level).info->compressed) + { + // If it isn't compressed, the remaining logic won't work + return false; + } + + GLenum implFormat = getImplementationColorReadFormat(context); + + // Check against the list of formats used to emulate compressed textures + return IsEmulatedCompressedFormat(implFormat); +} + +angle::Result Texture::getTexImage(const Context *context, + const PixelPackState &packState, + Buffer *packBuffer, + TextureTarget target, + GLint level, + GLenum format, + GLenum type, + void *pixels) +{ + // No-op if the image level is empty. + if (getExtents(target, level).empty()) + { + return angle::Result::Continue; + } + + return mTexture->getTexImage(context, packState, packBuffer, target, level, format, type, + pixels); +} + +angle::Result Texture::getCompressedTexImage(const Context *context, + const PixelPackState &packState, + Buffer *packBuffer, + TextureTarget target, + GLint level, + void *pixels) +{ + // No-op if the image level is empty. + if (getExtents(target, level).empty()) + { + return angle::Result::Continue; + } + + return mTexture->getCompressedTexImage(context, packState, packBuffer, target, level, pixels); +} + +void Texture::onBindAsImageTexture() +{ + if (!mState.mHasBeenBoundAsImage) + { + mDirtyBits.set(DIRTY_BIT_BOUND_AS_IMAGE); + mState.mHasBeenBoundAsImage = true; + } +} + +void Texture::onBind3DTextureAs2DImage() +{ + if (!mState.mIs3DAndHasBeenBoundAs2DImage) + { + mDirtyBits.set(DIRTY_BIT_BOUND_AS_IMAGE); + mState.mIs3DAndHasBeenBoundAs2DImage = true; + } +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/Texture.h b/gfx/angle/checkout/src/libANGLE/Texture.h new file mode 100644 index 0000000000..757f1a2e7e --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Texture.h @@ -0,0 +1,738 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Texture.h: Defines the gl::Texture class [OpenGL ES 2.0.24] section 3.7 page 63. + +#ifndef LIBANGLE_TEXTURE_H_ +#define LIBANGLE_TEXTURE_H_ + +#include +#include + +#include "angle_gl.h" +#include "common/Optional.h" +#include "common/debug.h" +#include "common/utilities.h" +#include "libANGLE/Caps.h" +#include "libANGLE/Constants.h" +#include "libANGLE/Debug.h" +#include "libANGLE/Error.h" +#include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/Image.h" +#include "libANGLE/Observer.h" +#include "libANGLE/Stream.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/formatutils.h" + +namespace egl +{ +class Surface; +class Stream; +} // namespace egl + +namespace rx +{ +class GLImplFactory; +class TextureImpl; +class TextureGL; +} // namespace rx + +namespace gl +{ +class Framebuffer; +class MemoryObject; +class Sampler; +class State; +class Texture; + +constexpr GLuint kInitialMaxLevel = 1000; + +bool IsMipmapFiltered(GLenum minFilterMode); + +// Convert a given filter mode to nearest filtering. +GLenum ConvertToNearestFilterMode(GLenum filterMode); + +// Convert a given filter mode to nearest mip filtering. +GLenum ConvertToNearestMipFilterMode(GLenum filterMode); + +struct ImageDesc final +{ + ImageDesc(); + ImageDesc(const Extents &size, const Format &format, const InitState initState); + ImageDesc(const Extents &size, + const Format &format, + const GLsizei samples, + const bool fixedSampleLocations, + const InitState initState); + + ImageDesc(const ImageDesc &other) = default; + ImageDesc &operator=(const ImageDesc &other) = default; + + GLint getMemorySize() const; + + Extents size; + Format format; + GLsizei samples; + bool fixedSampleLocations; + + // Needed for robust resource initialization. + InitState initState; +}; + +struct SwizzleState final +{ + SwizzleState(); + SwizzleState(GLenum red, GLenum green, GLenum blue, GLenum alpha); + SwizzleState(const SwizzleState &other) = default; + SwizzleState &operator=(const SwizzleState &other) = default; + + bool swizzleRequired() const; + + bool operator==(const SwizzleState &other) const; + bool operator!=(const SwizzleState &other) const; + + GLenum swizzleRed; + GLenum swizzleGreen; + GLenum swizzleBlue; + GLenum swizzleAlpha; +}; + +// State from Table 6.9 (state per texture object) in the OpenGL ES 3.0.2 spec. +class TextureState final : private angle::NonCopyable +{ + public: + TextureState(TextureType type); + ~TextureState(); + + bool swizzleRequired() const; + GLuint getEffectiveBaseLevel() const; + GLuint getEffectiveMaxLevel() const; + + // Returns the value called "q" in the GLES 3.0.4 spec section 3.8.10. + GLuint getMipmapMaxLevel() const; + + // Returns true if base level changed. + bool setBaseLevel(GLuint baseLevel); + GLuint getBaseLevel() const { return mBaseLevel; } + bool setMaxLevel(GLuint maxLevel); + GLuint getMaxLevel() const { return mMaxLevel; } + + bool isCubeComplete() const; + + ANGLE_INLINE bool compatibleWithSamplerFormatForWebGL(SamplerFormat format, + const SamplerState &samplerState) const + { + if (!mCachedSamplerFormatValid || + mCachedSamplerCompareMode != samplerState.getCompareMode()) + { + mCachedSamplerFormat = computeRequiredSamplerFormat(samplerState); + mCachedSamplerCompareMode = samplerState.getCompareMode(); + mCachedSamplerFormatValid = true; + } + // Incomplete textures are compatible with any sampler format. + return mCachedSamplerFormat == SamplerFormat::InvalidEnum || format == mCachedSamplerFormat; + } + + const ImageDesc &getImageDesc(TextureTarget target, size_t level) const; + const ImageDesc &getImageDesc(const ImageIndex &imageIndex) const; + + TextureType getType() const { return mType; } + const SwizzleState &getSwizzleState() const { return mSwizzleState; } + const SamplerState &getSamplerState() const { return mSamplerState; } + GLenum getUsage() const { return mUsage; } + bool hasProtectedContent() const { return mHasProtectedContent; } + GLenum getDepthStencilTextureMode() const { return mDepthStencilTextureMode; } + bool isStencilMode() const { return mDepthStencilTextureMode == GL_STENCIL_INDEX; } + + bool hasBeenBoundAsImage() const { return mHasBeenBoundAsImage; } + bool is3DTextureAndHasBeenBoundAs2DImage() const { return mIs3DAndHasBeenBoundAs2DImage; } + bool hasBeenBoundAsAttachment() const { return mHasBeenBoundAsAttachment; } + + gl::SrgbOverride getSRGBOverride() const { return mSrgbOverride; } + + // Returns the desc of the base level. Only valid for cube-complete/mip-complete textures. + const ImageDesc &getBaseLevelDesc() const; + const ImageDesc &getLevelZeroDesc() const; + + // GLES1 emulation: For GL_OES_draw_texture + void setCrop(const Rectangle &rect); + const Rectangle &getCrop() const; + + // GLES1 emulation: Auto-mipmap generation is a texparameter + void setGenerateMipmapHint(GLenum hint); + GLenum getGenerateMipmapHint() const; + + // Return the enabled mipmap level count. + GLuint getEnabledLevelCount() const; + + bool getImmutableFormat() const { return mImmutableFormat; } + GLuint getImmutableLevels() const { return mImmutableLevels; } + + const std::vector &getImageDescs() const { return mImageDescs; } + + InitState getInitState() const { return mInitState; } + + const OffsetBindingPointer &getBuffer() const { return mBuffer; } + + const std::string &getLabel() const { return mLabel; } + + private: + // Texture needs access to the ImageDesc functions. + friend class Texture; + friend bool operator==(const TextureState &a, const TextureState &b); + + bool computeSamplerCompleteness(const SamplerState &samplerState, const State &state) const; + bool computeSamplerCompletenessForCopyImage(const SamplerState &samplerState, + const State &state) const; + + bool computeMipmapCompleteness() const; + bool computeLevelCompleteness(TextureTarget target, size_t level) const; + SamplerFormat computeRequiredSamplerFormat(const SamplerState &samplerState) const; + + TextureTarget getBaseImageTarget() const; + + void setImageDesc(TextureTarget target, size_t level, const ImageDesc &desc); + void setImageDescChain(GLuint baselevel, + GLuint maxLevel, + Extents baseSize, + const Format &format, + InitState initState); + void setImageDescChainMultisample(Extents baseSize, + const Format &format, + GLsizei samples, + bool fixedSampleLocations, + InitState initState); + + void clearImageDesc(TextureTarget target, size_t level); + void clearImageDescs(); + + const TextureType mType; + + SwizzleState mSwizzleState; + + SamplerState mSamplerState; + + SrgbOverride mSrgbOverride; + + GLuint mBaseLevel; + GLuint mMaxLevel; + + GLenum mDepthStencilTextureMode; + + bool mHasBeenBoundAsImage; + bool mIs3DAndHasBeenBoundAs2DImage; + bool mHasBeenBoundAsAttachment; + + bool mImmutableFormat; + GLuint mImmutableLevels; + + // From GL_ANGLE_texture_usage + GLenum mUsage; + + // GL_EXT_protected_textures + bool mHasProtectedContent; + + std::vector mImageDescs; + + // GLES1 emulation: Texture crop rectangle + // For GL_OES_draw_texture + Rectangle mCropRect; + + // GLES1 emulation: Generate-mipmap hint per texture + GLenum mGenerateMipmapHint; + + // GL_OES_texture_buffer / GLES3.2 + OffsetBindingPointer mBuffer; + + InitState mInitState; + + mutable SamplerFormat mCachedSamplerFormat; + mutable GLenum mCachedSamplerCompareMode; + mutable bool mCachedSamplerFormatValid; + std::string mLabel; +}; + +bool operator==(const TextureState &a, const TextureState &b); +bool operator!=(const TextureState &a, const TextureState &b); + +class Texture final : public RefCountObject, + public egl::ImageSibling, + public LabeledObject +{ + public: + Texture(rx::GLImplFactory *factory, TextureID id, TextureType type); + ~Texture() override; + + void onDestroy(const Context *context) override; + + angle::Result setLabel(const Context *context, const std::string &label) override; + + const std::string &getLabel() const override; + + TextureType getType() const { return mState.mType; } + + void setSwizzleRed(const Context *context, GLenum swizzleRed); + GLenum getSwizzleRed() const; + + void setSwizzleGreen(const Context *context, GLenum swizzleGreen); + GLenum getSwizzleGreen() const; + + void setSwizzleBlue(const Context *context, GLenum swizzleBlue); + GLenum getSwizzleBlue() const; + + void setSwizzleAlpha(const Context *context, GLenum swizzleAlpha); + GLenum getSwizzleAlpha() const; + + void setMinFilter(const Context *context, GLenum minFilter); + GLenum getMinFilter() const; + + void setMagFilter(const Context *context, GLenum magFilter); + GLenum getMagFilter() const; + + void setWrapS(const Context *context, GLenum wrapS); + GLenum getWrapS() const; + + void setWrapT(const Context *context, GLenum wrapT); + GLenum getWrapT() const; + + void setWrapR(const Context *context, GLenum wrapR); + GLenum getWrapR() const; + + void setMaxAnisotropy(const Context *context, float maxAnisotropy); + float getMaxAnisotropy() const; + + void setMinLod(const Context *context, GLfloat minLod); + GLfloat getMinLod() const; + + void setMaxLod(const Context *context, GLfloat maxLod); + GLfloat getMaxLod() const; + + void setCompareMode(const Context *context, GLenum compareMode); + GLenum getCompareMode() const; + + void setCompareFunc(const Context *context, GLenum compareFunc); + GLenum getCompareFunc() const; + + void setSRGBDecode(const Context *context, GLenum sRGBDecode); + GLenum getSRGBDecode() const; + + void setSRGBOverride(const Context *context, GLenum sRGBOverride); + GLenum getSRGBOverride() const; + + const SamplerState &getSamplerState() const; + + angle::Result setBaseLevel(const Context *context, GLuint baseLevel); + GLuint getBaseLevel() const; + + void setMaxLevel(const Context *context, GLuint maxLevel); + GLuint getMaxLevel() const; + + void setDepthStencilTextureMode(const Context *context, GLenum mode); + GLenum getDepthStencilTextureMode() const; + + bool getImmutableFormat() const; + + GLuint getImmutableLevels() const; + + void setUsage(const Context *context, GLenum usage); + GLenum getUsage() const; + + void setProtectedContent(Context *context, bool hasProtectedContent); + bool hasProtectedContent() const override; + + const TextureState &getState() const { return mState; } + + void setBorderColor(const Context *context, const ColorGeneric &color); + const ColorGeneric &getBorderColor() const; + + angle::Result setBuffer(const Context *context, gl::Buffer *buffer, GLenum internalFormat); + angle::Result setBufferRange(const Context *context, + gl::Buffer *buffer, + GLenum internalFormat, + GLintptr offset, + GLsizeiptr size); + const OffsetBindingPointer &getBuffer() const; + + GLint getRequiredTextureImageUnits(const Context *context) const; + + const TextureState &getTextureState() const; + + const Extents &getExtents(TextureTarget target, size_t level) const; + size_t getWidth(TextureTarget target, size_t level) const; + size_t getHeight(TextureTarget target, size_t level) const; + size_t getDepth(TextureTarget target, size_t level) const; + GLsizei getSamples(TextureTarget target, size_t level) const; + bool getFixedSampleLocations(TextureTarget target, size_t level) const; + const Format &getFormat(TextureTarget target, size_t level) const; + + // Returns the value called "q" in the GLES 3.0.4 spec section 3.8.10. + GLuint getMipmapMaxLevel() const; + + bool isMipmapComplete() const; + + angle::Result setImage(Context *context, + const PixelUnpackState &unpackState, + Buffer *unpackBuffer, + TextureTarget target, + GLint level, + GLenum internalFormat, + const Extents &size, + GLenum format, + GLenum type, + const uint8_t *pixels); + angle::Result setSubImage(Context *context, + const PixelUnpackState &unpackState, + Buffer *unpackBuffer, + TextureTarget target, + GLint level, + const Box &area, + GLenum format, + GLenum type, + const uint8_t *pixels); + + angle::Result setCompressedImage(Context *context, + const PixelUnpackState &unpackState, + TextureTarget target, + GLint level, + GLenum internalFormat, + const Extents &size, + size_t imageSize, + const uint8_t *pixels); + angle::Result setCompressedSubImage(const Context *context, + const PixelUnpackState &unpackState, + TextureTarget target, + GLint level, + const Box &area, + GLenum format, + size_t imageSize, + const uint8_t *pixels); + + angle::Result copyImage(Context *context, + TextureTarget target, + GLint level, + const Rectangle &sourceArea, + GLenum internalFormat, + Framebuffer *source); + angle::Result copySubImage(Context *context, + const ImageIndex &index, + const Offset &destOffset, + const Rectangle &sourceArea, + Framebuffer *source); + + angle::Result copyRenderbufferSubData(Context *context, + const gl::Renderbuffer *srcBuffer, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth); + + angle::Result copyTextureSubData(Context *context, + const gl::Texture *srcTexture, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth); + + angle::Result copyTexture(Context *context, + TextureTarget target, + GLint level, + GLenum internalFormat, + GLenum type, + GLint sourceLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + Texture *source); + angle::Result copySubTexture(const Context *context, + TextureTarget target, + GLint level, + const Offset &destOffset, + GLint sourceLevel, + const Box &sourceBox, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + Texture *source); + angle::Result copyCompressedTexture(Context *context, const Texture *source); + + angle::Result setStorage(Context *context, + TextureType type, + GLsizei levels, + GLenum internalFormat, + const Extents &size); + + angle::Result setStorageMultisample(Context *context, + TextureType type, + GLsizei samplesIn, + GLint internalformat, + const Extents &size, + bool fixedSampleLocations); + + angle::Result setStorageExternalMemory(Context *context, + TextureType type, + GLsizei levels, + GLenum internalFormat, + const Extents &size, + MemoryObject *memoryObject, + GLuint64 offset, + GLbitfield createFlags, + GLbitfield usageFlags, + const void *imageCreateInfoPNext); + + angle::Result setImageExternal(Context *context, + TextureTarget target, + GLint level, + GLenum internalFormat, + const Extents &size, + GLenum format, + GLenum type); + + angle::Result setEGLImageTarget(Context *context, TextureType type, egl::Image *imageTarget); + + angle::Result setStorageEGLImageTarget(Context *context, + TextureType type, + egl::Image *image, + const GLint *attrib_list); + + angle::Result generateMipmap(Context *context); + + void onBindAsImageTexture(); + void onBind3DTextureAs2DImage(); + + egl::Surface *getBoundSurface() const; + egl::Stream *getBoundStream() const; + + GLint getMemorySize() const; + GLint getLevelMemorySize(TextureTarget target, GLint level) const; + + void signalDirtyStorage(InitState initState); + + bool isSamplerComplete(const Context *context, const Sampler *optionalSampler); + bool isSamplerCompleteForCopyImage(const Context *context, + const Sampler *optionalSampler) const; + + GLenum getImplementationColorReadFormat(const Context *context) const; + GLenum getImplementationColorReadType(const Context *context) const; + + bool isCompressedFormatEmulated(const Context *context, + TextureTarget target, + GLint level) const; + + // We pass the pack buffer and state explicitly so they can be overridden during capture. + angle::Result getTexImage(const Context *context, + const PixelPackState &packState, + Buffer *packBuffer, + TextureTarget target, + GLint level, + GLenum format, + GLenum type, + void *pixels); + + angle::Result getCompressedTexImage(const Context *context, + const PixelPackState &packState, + Buffer *packBuffer, + TextureTarget target, + GLint level, + void *pixels); + + rx::TextureImpl *getImplementation() const { return mTexture; } + + // FramebufferAttachmentObject implementation + Extents getAttachmentSize(const ImageIndex &imageIndex) const override; + Format getAttachmentFormat(GLenum binding, const ImageIndex &imageIndex) const override; + GLsizei getAttachmentSamples(const ImageIndex &imageIndex) const override; + bool isRenderable(const Context *context, + GLenum binding, + const ImageIndex &imageIndex) const override; + + bool getAttachmentFixedSampleLocations(const ImageIndex &imageIndex) const; + + // GLES1 emulation + void setCrop(const Rectangle &rect); + const Rectangle &getCrop() const; + void setGenerateMipmapHint(GLenum generate); + GLenum getGenerateMipmapHint() const; + + void onAttach(const Context *context, rx::Serial framebufferSerial) override; + void onDetach(const Context *context, rx::Serial framebufferSerial) override; + + // Used specifically for FramebufferAttachmentObject. + GLuint getId() const override; + + GLuint getNativeID() const; + + // Needed for robust resource init. + angle::Result ensureInitialized(const Context *context); + InitState initState(GLenum binding, const ImageIndex &imageIndex) const override; + InitState initState() const { return mState.mInitState; } + void setInitState(GLenum binding, const ImageIndex &imageIndex, InitState initState) override; + void setInitState(InitState initState); + + bool isBoundToFramebuffer(rx::Serial framebufferSerial) const + { + for (size_t index = 0; index < mBoundFramebufferSerials.size(); ++index) + { + if (mBoundFramebufferSerials[index] == framebufferSerial) + return true; + } + + return false; + } + + bool isDepthOrStencil() const + { + return mState.getBaseLevelDesc().format.info->isDepthOrStencil(); + } + + enum DirtyBitType + { + // Sampler state + DIRTY_BIT_MIN_FILTER, + DIRTY_BIT_MAG_FILTER, + DIRTY_BIT_WRAP_S, + DIRTY_BIT_WRAP_T, + DIRTY_BIT_WRAP_R, + DIRTY_BIT_MAX_ANISOTROPY, + DIRTY_BIT_MIN_LOD, + DIRTY_BIT_MAX_LOD, + DIRTY_BIT_COMPARE_MODE, + DIRTY_BIT_COMPARE_FUNC, + DIRTY_BIT_SRGB_DECODE, + DIRTY_BIT_SRGB_OVERRIDE, + DIRTY_BIT_BORDER_COLOR, + + // Texture state + DIRTY_BIT_SWIZZLE_RED, + DIRTY_BIT_SWIZZLE_GREEN, + DIRTY_BIT_SWIZZLE_BLUE, + DIRTY_BIT_SWIZZLE_ALPHA, + DIRTY_BIT_BASE_LEVEL, + DIRTY_BIT_MAX_LEVEL, + DIRTY_BIT_DEPTH_STENCIL_TEXTURE_MODE, + + // Image state + DIRTY_BIT_BOUND_AS_IMAGE, + DIRTY_BIT_BOUND_AS_ATTACHMENT, + + // Misc + DIRTY_BIT_USAGE, + DIRTY_BIT_IMPLEMENTATION, + + DIRTY_BIT_COUNT, + }; + using DirtyBits = angle::BitSet; + + angle::Result syncState(const Context *context, Command source); + bool hasAnyDirtyBit() const { return mDirtyBits.any(); } + bool hasAnyDirtyBitExcludingBoundAsAttachmentBit() const + { + static constexpr DirtyBits kBoundAsAttachment = DirtyBits({DIRTY_BIT_BOUND_AS_ATTACHMENT}); + return mDirtyBits.any() && mDirtyBits != kBoundAsAttachment; + } + + // ObserverInterface implementation. + void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; + + private: + rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override; + + // ANGLE-only method, used internally + friend class egl::Surface; + angle::Result bindTexImageFromSurface(Context *context, egl::Surface *surface); + angle::Result releaseTexImageFromSurface(const Context *context); + + // ANGLE-only methods, used internally + friend class egl::Stream; + void bindStream(egl::Stream *stream); + void releaseStream(); + angle::Result acquireImageFromStream(const Context *context, + const egl::Stream::GLTextureDescription &desc); + angle::Result releaseImageFromStream(const Context *context); + + void invalidateCompletenessCache() const; + angle::Result releaseTexImageInternal(Context *context); + + bool doesSubImageNeedInit(const Context *context, + const ImageIndex &imageIndex, + const Box &area) const; + angle::Result ensureSubImageInitialized(const Context *context, + const ImageIndex &imageIndex, + const Box &area); + + angle::Result handleMipmapGenerationHint(Context *context, int level); + + angle::Result setEGLImageTargetImpl(Context *context, + TextureType type, + GLuint levels, + egl::Image *imageTarget); + + void signalDirtyState(size_t dirtyBit); + + TextureState mState; + DirtyBits mDirtyBits; + rx::TextureImpl *mTexture; + angle::ObserverBinding mImplObserver; + // For EXT_texture_buffer, observes buffer changes. + angle::ObserverBinding mBufferObserver; + + egl::Surface *mBoundSurface; + egl::Stream *mBoundStream; + + // We track all the serials of the Framebuffers this texture is attached to. Note that this + // allows duplicates because different ranges of a Texture can be bound to the same Framebuffer. + // For the purposes of depth-stencil loops, a simple "isBound" check works fine. For color + // attachment Feedback Loop checks we then need to check further to see when a Texture is bound + // to mulitple bindings that the bindings don't overlap. + static constexpr uint32_t kFastFramebufferSerialCount = 8; + angle::FastVector mBoundFramebufferSerials; + + struct SamplerCompletenessCache + { + SamplerCompletenessCache(); + + // Context used to generate this cache entry + ContextID context; + + // All values that affect sampler completeness that are not stored within + // the texture itself + SamplerState samplerState; + + // Result of the sampler completeness with the above parameters + bool samplerComplete; + }; + + mutable SamplerCompletenessCache mCompletenessCache; +}; + +inline bool operator==(const TextureState &a, const TextureState &b) +{ + return a.mSwizzleState == b.mSwizzleState && a.mSamplerState == b.mSamplerState && + a.mBaseLevel == b.mBaseLevel && a.mMaxLevel == b.mMaxLevel && + a.mImmutableFormat == b.mImmutableFormat && a.mImmutableLevels == b.mImmutableLevels && + a.mUsage == b.mUsage; +} + +inline bool operator!=(const TextureState &a, const TextureState &b) +{ + return !(a == b); +} +} // namespace gl + +#endif // LIBANGLE_TEXTURE_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Thread.cpp b/gfx/angle/checkout/src/libANGLE/Thread.cpp new file mode 100644 index 0000000000..7f5f65fa3c --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Thread.cpp @@ -0,0 +1,168 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Thread.cpp : Defines the Thread class which represents a global EGL thread. + +#include "libANGLE/Thread.h" + +#include "libANGLE/Context.h" +#include "libANGLE/Debug.h" +#include "libANGLE/Display.h" +#include "libANGLE/Error.h" + +namespace angle +{ +#if defined(ANGLE_USE_ANDROID_TLS_SLOT) +bool gUseAndroidOpenGLTlsSlot; +#endif + +void PthreadKeyDestructorCallback(void *ptr) +{ + egl::Thread *thread = static_cast(ptr); + ASSERT(thread); + + egl::Display::EglDisplaySet displays = egl::Display::GetEglDisplaySet(); + for (egl::Display *display : displays) + { + ASSERT(display); + // Perform necessary cleanup. + display->threadCleanup(thread); + } +} +} // namespace angle + +namespace egl +{ +namespace +{ +Debug *sDebug = nullptr; +} // namespace + +Thread::Thread() + : mLabel(nullptr), + mError(EGL_SUCCESS), + mAPI(EGL_OPENGL_ES_API), + mContext(static_cast(EGL_NO_CONTEXT)) +{} + +void Thread::setLabel(EGLLabelKHR label) +{ + mLabel = label; +} + +EGLLabelKHR Thread::getLabel() const +{ + return mLabel; +} + +void Thread::setSuccess() +{ + mError = EGL_SUCCESS; +} + +void Thread::setError(EGLint error, + const char *command, + const LabeledObject *object, + const char *message) +{ + mError = error; + if (error != EGL_SUCCESS && message) + { + EnsureDebugAllocated(); + sDebug->insertMessage(error, command, ErrorCodeToMessageType(error), getLabel(), + object ? object->getLabel() : nullptr, message); + } +} + +void Thread::setError(const Error &error, const char *command, const LabeledObject *object) +{ + mError = error.getCode(); + if (error.isError() && !error.getMessage().empty()) + { + EnsureDebugAllocated(); + sDebug->insertMessage(error.getCode(), command, ErrorCodeToMessageType(error.getCode()), + getLabel(), object ? object->getLabel() : nullptr, + error.getMessage()); + } +} + +EGLint Thread::getError() const +{ + return mError; +} + +void Thread::setAPI(EGLenum api) +{ + mAPI = api; +} + +EGLenum Thread::getAPI() const +{ + return mAPI; +} + +void Thread::setCurrent(gl::Context *context) +{ + mContext = context; + if (mContext) + { + ASSERT(mContext->getDisplay()); + mContext->getDisplay()->addActiveThread(this); + } +} + +Surface *Thread::getCurrentDrawSurface() const +{ + if (mContext) + { + return mContext->getCurrentDrawSurface(); + } + return nullptr; +} + +Surface *Thread::getCurrentReadSurface() const +{ + if (mContext) + { + return mContext->getCurrentReadSurface(); + } + return nullptr; +} + +gl::Context *Thread::getContext() const +{ + return mContext; +} + +Display *Thread::getDisplay() const +{ + if (mContext) + { + return mContext->getDisplay(); + } + return nullptr; +} + +void EnsureDebugAllocated() +{ + // All EGL calls use a global lock, this is thread safe + if (sDebug == nullptr) + { + sDebug = new Debug(); + } +} + +void DeallocateDebug() +{ + SafeDelete(sDebug); +} + +Debug *GetDebug() +{ + EnsureDebugAllocated(); + return sDebug; +} +} // namespace egl diff --git a/gfx/angle/checkout/src/libANGLE/Thread.h b/gfx/angle/checkout/src/libANGLE/Thread.h new file mode 100644 index 0000000000..415c09bf37 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Thread.h @@ -0,0 +1,80 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Thread.h : Defines the Thread class which represents a global EGL thread. + +#ifndef LIBANGLE_THREAD_H_ +#define LIBANGLE_THREAD_H_ + +#include + +#include "libANGLE/Debug.h" + +#include + +namespace angle +{ +#if defined(ANGLE_USE_ANDROID_TLS_SLOT) +extern bool gUseAndroidOpenGLTlsSlot; +#endif + +void PthreadKeyDestructorCallback(void *ptr); +} // namespace angle + +namespace gl +{ +class Context; +} // namespace gl + +namespace egl +{ +class Error; +class Debug; +class Display; +class Surface; + +class Thread : public LabeledObject +{ + public: + Thread(); + + void setLabel(EGLLabelKHR label) override; + EGLLabelKHR getLabel() const override; + + void setSuccess(); + + void setError(EGLint error, + const char *command, + const LabeledObject *object, + const char *message); + + // TODO: Remove egl::Error. http://anglebug.com/3041 + void setError(const Error &error, const char *command, const LabeledObject *object); + EGLint getError() const; + + void setAPI(EGLenum api); + EGLenum getAPI() const; + + void setCurrent(gl::Context *context); + Surface *getCurrentDrawSurface() const; + Surface *getCurrentReadSurface() const; + gl::Context *getContext() const; + Display *getDisplay() const; + + private: + EGLLabelKHR mLabel; + EGLint mError; + EGLenum mAPI; + gl::Context *mContext; +}; + +void EnsureDebugAllocated(); +void DeallocateDebug(); +Debug *GetDebug(); + +} // namespace egl + +#endif // LIBANGLE_THREAD_H_ diff --git a/gfx/angle/checkout/src/libANGLE/TransformFeedback.cpp b/gfx/angle/checkout/src/libANGLE/TransformFeedback.cpp new file mode 100644 index 0000000000..af1875ac50 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/TransformFeedback.cpp @@ -0,0 +1,347 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "libANGLE/TransformFeedback.h" + +#include "common/mathutil.h" +#include "libANGLE/Buffer.h" +#include "libANGLE/Caps.h" +#include "libANGLE/Context.h" +#include "libANGLE/Program.h" +#include "libANGLE/State.h" +#include "libANGLE/renderer/GLImplFactory.h" +#include "libANGLE/renderer/TransformFeedbackImpl.h" + +#include + +namespace gl +{ + +angle::CheckedNumeric GetVerticesNeededForDraw(PrimitiveMode primitiveMode, + GLsizei count, + GLsizei primcount) +{ + if (count < 0 || primcount < 0) + { + return 0; + } + // Transform feedback only outputs complete primitives, so we need to round down to the nearest + // complete primitive before multiplying by the number of instances. + angle::CheckedNumeric checkedCount = count; + angle::CheckedNumeric checkedPrimcount = primcount; + switch (primitiveMode) + { + case PrimitiveMode::Triangles: + return checkedPrimcount * (checkedCount - checkedCount % 3); + case PrimitiveMode::Lines: + return checkedPrimcount * (checkedCount - checkedCount % 2); + case PrimitiveMode::Points: + return checkedPrimcount * checkedCount; + default: + UNREACHABLE(); + return checkedPrimcount * checkedCount; + } +} + +TransformFeedbackState::TransformFeedbackState(size_t maxIndexedBuffers) + : mLabel(), + mActive(false), + mPrimitiveMode(PrimitiveMode::InvalidEnum), + mPaused(false), + mVerticesDrawn(0), + mVertexCapacity(0), + mProgram(nullptr), + mIndexedBuffers(maxIndexedBuffers) +{} + +TransformFeedbackState::~TransformFeedbackState() {} + +const OffsetBindingPointer &TransformFeedbackState::getIndexedBuffer(size_t idx) const +{ + return mIndexedBuffers[idx]; +} + +const std::vector> &TransformFeedbackState::getIndexedBuffers() const +{ + return mIndexedBuffers; +} + +GLsizeiptr TransformFeedbackState::getPrimitivesDrawn() const +{ + switch (mPrimitiveMode) + { + case gl::PrimitiveMode::Points: + return mVerticesDrawn; + case gl::PrimitiveMode::Lines: + return mVerticesDrawn / 2; + case gl::PrimitiveMode::Triangles: + return mVerticesDrawn / 3; + default: + return 0; + } +} + +TransformFeedback::TransformFeedback(rx::GLImplFactory *implFactory, + TransformFeedbackID id, + const Caps &caps) + : RefCountObject(implFactory->generateSerial(), id), + mState(caps.maxTransformFeedbackSeparateAttributes), + mImplementation(implFactory->createTransformFeedback(mState)) +{ + ASSERT(mImplementation != nullptr); +} + +void TransformFeedback::onDestroy(const Context *context) +{ + ASSERT(!context || !context->isCurrentTransformFeedback(this)); + if (mState.mProgram) + { + mState.mProgram->release(context); + mState.mProgram = nullptr; + } + + ASSERT(!mState.mProgram); + for (size_t i = 0; i < mState.mIndexedBuffers.size(); i++) + { + mState.mIndexedBuffers[i].set(context, nullptr, 0, 0); + } + + if (mImplementation) + { + mImplementation->onDestroy(context); + } +} + +TransformFeedback::~TransformFeedback() +{ + SafeDelete(mImplementation); +} + +angle::Result TransformFeedback::setLabel(const Context *context, const std::string &label) +{ + mState.mLabel = label; + + if (mImplementation) + { + return mImplementation->onLabelUpdate(context); + } + return angle::Result::Continue; +} + +const std::string &TransformFeedback::getLabel() const +{ + return mState.mLabel; +} + +angle::Result TransformFeedback::begin(const Context *context, + PrimitiveMode primitiveMode, + Program *program) +{ + // TODO: http://anglebug.com/5486: This method should take in as parameter a + // ProgramExecutable instead of a Program. + + ANGLE_TRY(mImplementation->begin(context, primitiveMode)); + mState.mActive = true; + mState.mPrimitiveMode = primitiveMode; + mState.mPaused = false; + mState.mVerticesDrawn = 0; + bindProgram(context, program); + + // In one of the angle_unittests - "TransformFeedbackTest.SideEffectsOfStartAndStop" + // there is a code path where is a nullptr, account for that possiblity. + const ProgramExecutable *programExecutable = + context ? context->getState().getLinkedProgramExecutable(context) : nullptr; + if (programExecutable) + { + // Compute the number of vertices we can draw before overflowing the bound buffers. + auto strides = programExecutable->getTransformFeedbackStrides(); + ASSERT(strides.size() <= mState.mIndexedBuffers.size() && !strides.empty()); + GLsizeiptr minCapacity = std::numeric_limits::max(); + for (size_t index = 0; index < strides.size(); index++) + { + GLsizeiptr capacity = + GetBoundBufferAvailableSize(mState.mIndexedBuffers[index]) / strides[index]; + minCapacity = std::min(minCapacity, capacity); + } + mState.mVertexCapacity = minCapacity; + } + else + { + mState.mVertexCapacity = 0; + } + return angle::Result::Continue; +} + +angle::Result TransformFeedback::end(const Context *context) +{ + ANGLE_TRY(mImplementation->end(context)); + mState.mActive = false; + mState.mPrimitiveMode = PrimitiveMode::InvalidEnum; + mState.mPaused = false; + mState.mVerticesDrawn = 0; + mState.mVertexCapacity = 0; + if (mState.mProgram) + { + mState.mProgram->release(context); + mState.mProgram = nullptr; + } + return angle::Result::Continue; +} + +angle::Result TransformFeedback::pause(const Context *context) +{ + ANGLE_TRY(mImplementation->pause(context)); + mState.mPaused = true; + return angle::Result::Continue; +} + +angle::Result TransformFeedback::resume(const Context *context) +{ + ANGLE_TRY(mImplementation->resume(context)); + mState.mPaused = false; + return angle::Result::Continue; +} + +bool TransformFeedback::isPaused() const +{ + return mState.mPaused; +} + +PrimitiveMode TransformFeedback::getPrimitiveMode() const +{ + return mState.mPrimitiveMode; +} + +bool TransformFeedback::checkBufferSpaceForDraw(GLsizei count, GLsizei primcount) const +{ + auto vertices = + mState.mVerticesDrawn + GetVerticesNeededForDraw(mState.mPrimitiveMode, count, primcount); + return vertices.IsValid() && vertices.ValueOrDie() <= mState.mVertexCapacity; +} + +void TransformFeedback::onVerticesDrawn(const Context *context, GLsizei count, GLsizei primcount) +{ + ASSERT(mState.mActive && !mState.mPaused); + // All draws should be validated with checkBufferSpaceForDraw so ValueOrDie should never fail. + mState.mVerticesDrawn = + (mState.mVerticesDrawn + GetVerticesNeededForDraw(mState.mPrimitiveMode, count, primcount)) + .ValueOrDie(); + + for (auto &buffer : mState.mIndexedBuffers) + { + if (buffer.get() != nullptr) + { + buffer->onDataChanged(); + } + } +} + +void TransformFeedback::bindProgram(const Context *context, Program *program) +{ + if (mState.mProgram != program) + { + if (mState.mProgram != nullptr) + { + mState.mProgram->release(context); + } + mState.mProgram = program; + if (mState.mProgram != nullptr) + { + mState.mProgram->addRef(); + } + } +} + +bool TransformFeedback::hasBoundProgram(ShaderProgramID program) const +{ + return mState.mProgram != nullptr && mState.mProgram->id().value == program.value; +} + +angle::Result TransformFeedback::detachBuffer(const Context *context, BufferID bufferID) +{ + bool isBound = context->isCurrentTransformFeedback(this); + for (size_t index = 0; index < mState.mIndexedBuffers.size(); index++) + { + if (mState.mIndexedBuffers[index].id() == bufferID) + { + if (isBound) + { + mState.mIndexedBuffers[index]->onTFBindingChanged(context, false, true); + } + mState.mIndexedBuffers[index].set(context, nullptr, 0, 0); + ANGLE_TRY( + mImplementation->bindIndexedBuffer(context, index, mState.mIndexedBuffers[index])); + } + } + + return angle::Result::Continue; +} + +angle::Result TransformFeedback::bindIndexedBuffer(const Context *context, + size_t index, + Buffer *buffer, + size_t offset, + size_t size) +{ + ASSERT(index < mState.mIndexedBuffers.size()); + bool isBound = context && context->isCurrentTransformFeedback(this); + if (isBound && mState.mIndexedBuffers[index].get()) + { + mState.mIndexedBuffers[index]->onTFBindingChanged(context, false, true); + } + mState.mIndexedBuffers[index].set(context, buffer, offset, size); + if (isBound && buffer) + { + buffer->onTFBindingChanged(context, true, true); + } + + return mImplementation->bindIndexedBuffer(context, index, mState.mIndexedBuffers[index]); +} + +const OffsetBindingPointer &TransformFeedback::getIndexedBuffer(size_t index) const +{ + ASSERT(index < mState.mIndexedBuffers.size()); + return mState.mIndexedBuffers[index]; +} + +size_t TransformFeedback::getIndexedBufferCount() const +{ + return mState.mIndexedBuffers.size(); +} + +bool TransformFeedback::buffersBoundForOtherUseInWebGL() const +{ + for (auto &buffer : mState.mIndexedBuffers) + { + if (buffer.get() && buffer->hasWebGLXFBBindingConflict(true)) + { + return true; + } + } + return false; +} + +rx::TransformFeedbackImpl *TransformFeedback::getImplementation() const +{ + return mImplementation; +} + +void TransformFeedback::onBindingChanged(const Context *context, bool bound) +{ + for (auto &buffer : mState.mIndexedBuffers) + { + if (buffer.get()) + { + buffer->onTFBindingChanged(context, bound, true); + } + } +} + +const std::vector> &TransformFeedback::getIndexedBuffers() const +{ + return mState.mIndexedBuffers; +} +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/TransformFeedback.h b/gfx/angle/checkout/src/libANGLE/TransformFeedback.h new file mode 100644 index 0000000000..e55d0054c1 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/TransformFeedback.h @@ -0,0 +1,120 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef LIBANGLE_TRANSFORM_FEEDBACK_H_ +#define LIBANGLE_TRANSFORM_FEEDBACK_H_ + +#include "libANGLE/RefCountObject.h" + +#include "common/PackedEnums.h" +#include "common/angleutils.h" +#include "libANGLE/Debug.h" + +#include "angle_gl.h" + +namespace rx +{ +class GLImplFactory; +class TransformFeedbackImpl; +class TransformFeedbackGL; +} // namespace rx + +namespace gl +{ +class Buffer; +struct Caps; +class Context; +class Program; + +class TransformFeedbackState final : angle::NonCopyable +{ + public: + TransformFeedbackState(size_t maxIndexedBuffers); + ~TransformFeedbackState(); + + const OffsetBindingPointer &getIndexedBuffer(size_t idx) const; + const std::vector> &getIndexedBuffers() const; + const Program *getBoundProgram() const { return mProgram; } + GLsizeiptr getVerticesDrawn() const { return mVerticesDrawn; } + GLsizeiptr getPrimitivesDrawn() const; + + private: + friend class TransformFeedback; + + std::string mLabel; + + bool mActive; + PrimitiveMode mPrimitiveMode; + bool mPaused; + GLsizeiptr mVerticesDrawn; + GLsizeiptr mVertexCapacity; + + Program *mProgram; + + std::vector> mIndexedBuffers; +}; + +class TransformFeedback final : public RefCountObject, public LabeledObject +{ + public: + TransformFeedback(rx::GLImplFactory *implFactory, TransformFeedbackID id, const Caps &caps); + ~TransformFeedback() override; + void onDestroy(const Context *context) override; + + angle::Result setLabel(const Context *context, const std::string &label) override; + const std::string &getLabel() const override; + + angle::Result begin(const Context *context, PrimitiveMode primitiveMode, Program *program); + angle::Result end(const Context *context); + angle::Result pause(const Context *context); + angle::Result resume(const Context *context); + + bool isActive() const { return mState.mActive; } + + bool isPaused() const; + PrimitiveMode getPrimitiveMode() const; + // Validates that the vertices produced by a draw call will fit in the bound transform feedback + // buffers. + bool checkBufferSpaceForDraw(GLsizei count, GLsizei primcount) const; + // This must be called after each draw call when transform feedback is enabled to keep track of + // how many vertices have been written to the buffers. This information is needed by + // checkBufferSpaceForDraw because each draw call appends vertices to the buffers starting just + // after the last vertex of the previous draw call. + void onVerticesDrawn(const Context *context, GLsizei count, GLsizei primcount); + + bool hasBoundProgram(ShaderProgramID program) const; + + angle::Result bindIndexedBuffer(const Context *context, + size_t index, + Buffer *buffer, + size_t offset, + size_t size); + const OffsetBindingPointer &getIndexedBuffer(size_t index) const; + size_t getIndexedBufferCount() const; + const std::vector> &getIndexedBuffers() const; + + GLsizeiptr getVerticesDrawn() const { return mState.getVerticesDrawn(); } + GLsizeiptr getPrimitivesDrawn() const { return mState.getPrimitivesDrawn(); } + + // Returns true if any buffer bound to this object is also bound to another target. + bool buffersBoundForOtherUseInWebGL() const; + + angle::Result detachBuffer(const Context *context, BufferID bufferID); + + rx::TransformFeedbackImpl *getImplementation() const; + + void onBindingChanged(const Context *context, bool bound); + + private: + void bindProgram(const Context *context, Program *program); + + TransformFeedbackState mState; + rx::TransformFeedbackImpl *mImplementation; +}; + +} // namespace gl + +#endif // LIBANGLE_TRANSFORM_FEEDBACK_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Uniform.cpp b/gfx/angle/checkout/src/libANGLE/Uniform.cpp new file mode 100644 index 0000000000..d41ed5698a --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Uniform.cpp @@ -0,0 +1,179 @@ +// +// Copyright 2010 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "libANGLE/Uniform.h" + +#include + +namespace gl +{ + +ActiveVariable::ActiveVariable() {} + +ActiveVariable::~ActiveVariable() {} + +ActiveVariable::ActiveVariable(const ActiveVariable &rhs) = default; +ActiveVariable &ActiveVariable::operator=(const ActiveVariable &rhs) = default; + +void ActiveVariable::setActive(ShaderType shaderType, bool used) +{ + ASSERT(shaderType != ShaderType::InvalidEnum); + mActiveUseBits.set(shaderType, used); +} + +void ActiveVariable::unionReferencesWith(const ActiveVariable &other) +{ + mActiveUseBits |= other.mActiveUseBits; +} + +ShaderType ActiveVariable::getFirstShaderTypeWhereActive() const +{ + return static_cast(ScanForward(mActiveUseBits.bits())); +} + +GLuint ActiveVariable::activeShaderCount() const +{ + return static_cast(mActiveUseBits.count()); +} + +LinkedUniform::LinkedUniform() + : typeInfo(nullptr), + bufferIndex(-1), + blockInfo(sh::kDefaultBlockMemberInfo), + outerArrayOffset(0) +{} + +LinkedUniform::LinkedUniform(GLenum typeIn, + GLenum precisionIn, + const std::string &nameIn, + const std::vector &arraySizesIn, + const int bindingIn, + const int offsetIn, + const int locationIn, + const int bufferIndexIn, + const sh::BlockMemberInfo &blockInfoIn) + : typeInfo(&GetUniformTypeInfo(typeIn)), + bufferIndex(bufferIndexIn), + blockInfo(blockInfoIn), + outerArrayOffset(0) +{ + type = typeIn; + precision = precisionIn; + name = nameIn; + arraySizes = arraySizesIn; + binding = bindingIn; + offset = offsetIn; + location = locationIn; + ASSERT(!isArrayOfArrays()); + ASSERT(!isArray() || !isStruct()); +} + +LinkedUniform::LinkedUniform(const sh::ShaderVariable &uniform) + : sh::ShaderVariable(uniform), + typeInfo(&GetUniformTypeInfo(type)), + bufferIndex(-1), + blockInfo(sh::kDefaultBlockMemberInfo) +{ + ASSERT(!isArrayOfArrays()); + ASSERT(!isArray() || !isStruct()); +} + +LinkedUniform::LinkedUniform(const LinkedUniform &uniform) + : sh::ShaderVariable(uniform), + ActiveVariable(uniform), + typeInfo(uniform.typeInfo), + bufferIndex(uniform.bufferIndex), + blockInfo(uniform.blockInfo), + outerArraySizes(uniform.outerArraySizes), + outerArrayOffset(uniform.outerArrayOffset) +{} + +LinkedUniform &LinkedUniform::operator=(const LinkedUniform &uniform) +{ + sh::ShaderVariable::operator=(uniform); + ActiveVariable::operator =(uniform); + typeInfo = uniform.typeInfo; + bufferIndex = uniform.bufferIndex; + blockInfo = uniform.blockInfo; + outerArraySizes = uniform.outerArraySizes; + outerArrayOffset = uniform.outerArrayOffset; + return *this; +} + +LinkedUniform::~LinkedUniform() {} + +BufferVariable::BufferVariable() + : bufferIndex(-1), blockInfo(sh::kDefaultBlockMemberInfo), topLevelArraySize(-1) +{} + +BufferVariable::BufferVariable(GLenum typeIn, + GLenum precisionIn, + const std::string &nameIn, + const std::vector &arraySizesIn, + const int bufferIndexIn, + const sh::BlockMemberInfo &blockInfoIn) + : bufferIndex(bufferIndexIn), blockInfo(blockInfoIn), topLevelArraySize(-1) +{ + type = typeIn; + precision = precisionIn; + name = nameIn; + arraySizes = arraySizesIn; +} + +BufferVariable::~BufferVariable() {} + +ShaderVariableBuffer::ShaderVariableBuffer() : binding(0), dataSize(0) {} + +ShaderVariableBuffer::ShaderVariableBuffer(const ShaderVariableBuffer &other) = default; + +ShaderVariableBuffer::~ShaderVariableBuffer() {} + +int ShaderVariableBuffer::numActiveVariables() const +{ + return static_cast(memberIndexes.size()); +} + +InterfaceBlock::InterfaceBlock() : isArray(false), arrayElement(0) {} + +InterfaceBlock::InterfaceBlock(const std::string &nameIn, + const std::string &mappedNameIn, + bool isArrayIn, + unsigned int arrayElementIn, + unsigned int firstFieldArraySizeIn, + int bindingIn) + : name(nameIn), + mappedName(mappedNameIn), + isArray(isArrayIn), + arrayElement(arrayElementIn), + firstFieldArraySize(firstFieldArraySizeIn) +{ + binding = bindingIn; +} + +std::string InterfaceBlock::nameWithArrayIndex() const +{ + std::stringstream fullNameStr; + fullNameStr << name; + if (isArray) + { + fullNameStr << "[" << arrayElement << "]"; + } + + return fullNameStr.str(); +} + +std::string InterfaceBlock::mappedNameWithArrayIndex() const +{ + std::stringstream fullNameStr; + fullNameStr << mappedName; + if (isArray) + { + fullNameStr << "[" << arrayElement << "]"; + } + + return fullNameStr.str(); +} +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/Uniform.h b/gfx/angle/checkout/src/libANGLE/Uniform.h new file mode 100644 index 0000000000..5c15906779 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Uniform.h @@ -0,0 +1,138 @@ +// +// Copyright 2010 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef LIBANGLE_UNIFORM_H_ +#define LIBANGLE_UNIFORM_H_ + +#include +#include + +#include "angle_gl.h" +#include "common/MemoryBuffer.h" +#include "common/debug.h" +#include "common/utilities.h" +#include "compiler/translator/blocklayout.h" +#include "libANGLE/angletypes.h" + +namespace gl +{ +struct UniformTypeInfo; + +struct ActiveVariable +{ + ActiveVariable(); + ActiveVariable(const ActiveVariable &rhs); + virtual ~ActiveVariable(); + + ActiveVariable &operator=(const ActiveVariable &rhs); + + ShaderType getFirstShaderTypeWhereActive() const; + void setActive(ShaderType shaderType, bool used); + void unionReferencesWith(const ActiveVariable &other); + bool isActive(ShaderType shaderType) const + { + ASSERT(shaderType != ShaderType::InvalidEnum); + return mActiveUseBits[shaderType]; + } + ShaderBitSet activeShaders() const { return mActiveUseBits; } + GLuint activeShaderCount() const; + + private: + ShaderBitSet mActiveUseBits; +}; + +// Helper struct representing a single shader uniform +struct LinkedUniform : public sh::ShaderVariable, public ActiveVariable +{ + LinkedUniform(); + LinkedUniform(GLenum type, + GLenum precision, + const std::string &name, + const std::vector &arraySizes, + const int binding, + const int offset, + const int location, + const int bufferIndex, + const sh::BlockMemberInfo &blockInfo); + LinkedUniform(const sh::ShaderVariable &uniform); + LinkedUniform(const LinkedUniform &uniform); + LinkedUniform &operator=(const LinkedUniform &uniform); + ~LinkedUniform() override; + + bool isSampler() const { return typeInfo->isSampler; } + bool isImage() const { return typeInfo->isImageType; } + bool isAtomicCounter() const { return IsAtomicCounterType(type); } + bool isInDefaultBlock() const { return bufferIndex == -1; } + bool isField() const { return name.find('.') != std::string::npos; } + size_t getElementSize() const { return typeInfo->externalSize; } + size_t getElementComponents() const { return typeInfo->componentCount; } + + const UniformTypeInfo *typeInfo; + + // Identifies the containing buffer backed resource -- interface block or atomic counter buffer. + int bufferIndex; + sh::BlockMemberInfo blockInfo; + std::vector outerArraySizes; + unsigned int outerArrayOffset; +}; + +struct BufferVariable : public sh::ShaderVariable, public ActiveVariable +{ + BufferVariable(); + BufferVariable(GLenum type, + GLenum precision, + const std::string &name, + const std::vector &arraySizes, + const int bufferIndex, + const sh::BlockMemberInfo &blockInfo); + ~BufferVariable() override; + + int bufferIndex; + sh::BlockMemberInfo blockInfo; + + int topLevelArraySize; +}; + +// Parent struct for atomic counter, uniform block, and shader storage block buffer, which all +// contain a group of shader variables, and have a GL buffer backed. +struct ShaderVariableBuffer : public ActiveVariable +{ + ShaderVariableBuffer(); + ShaderVariableBuffer(const ShaderVariableBuffer &other); + ~ShaderVariableBuffer() override; + int numActiveVariables() const; + + int binding; + unsigned int dataSize; + std::vector memberIndexes; +}; + +using AtomicCounterBuffer = ShaderVariableBuffer; + +// Helper struct representing a single shader interface block +struct InterfaceBlock : public ShaderVariableBuffer +{ + InterfaceBlock(); + InterfaceBlock(const std::string &nameIn, + const std::string &mappedNameIn, + bool isArrayIn, + unsigned int arrayElementIn, + unsigned int firstFieldArraySizeIn, + int bindingIn); + + std::string nameWithArrayIndex() const; + std::string mappedNameWithArrayIndex() const; + + std::string name; + std::string mappedName; + bool isArray; + unsigned int arrayElement; + unsigned int firstFieldArraySize; +}; + +} // namespace gl + +#endif // LIBANGLE_UNIFORM_H_ diff --git a/gfx/angle/checkout/src/libANGLE/VaryingPacking.cpp b/gfx/angle/checkout/src/libANGLE/VaryingPacking.cpp new file mode 100644 index 0000000000..7dbb0cc2b8 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/VaryingPacking.cpp @@ -0,0 +1,1152 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// VaryingPacking: +// Class which describes a mapping from varyings to registers, according +// to the spec, or using custom packing algorithms. We also keep a register +// allocation list for the D3D renderer. +// + +#include "libANGLE/VaryingPacking.h" + +#include "common/utilities.h" +#include "libANGLE/Program.h" +#include "libANGLE/ProgramExecutable.h" +#include "libANGLE/Shader.h" + +namespace gl +{ + +namespace +{ + +// true if varying x has a higher priority in packing than y +bool ComparePackedVarying(const PackedVarying &x, const PackedVarying &y) +{ + // If the PackedVarying 'x' or 'y' to be compared is an array element for transform feedback, + // this clones an equivalent non-array shader variable 'vx' or 'vy' for actual comparison + // instead. For I/O block arrays, the array index is used in the comparison. + sh::ShaderVariable vx, vy; + const sh::ShaderVariable *px, *py; + + px = &x.varying(); + py = &y.varying(); + + if (x.isTransformFeedbackArrayElement()) + { + vx = *px; + vx.arraySizes.clear(); + px = &vx; + } + + if (y.isTransformFeedbackArrayElement()) + { + vy = *py; + vy.arraySizes.clear(); + py = &vy; + } + + // Make sure struct fields end up together. + if (x.isStructField() != y.isStructField()) + { + return x.isStructField(); + } + + if (x.isStructField()) + { + ASSERT(y.isStructField()); + + if (x.getParentStructName() != y.getParentStructName()) + { + return x.getParentStructName() < y.getParentStructName(); + } + } + + // For I/O block fields, order first by array index: + if (!x.isTransformFeedbackArrayElement() && !y.isTransformFeedbackArrayElement()) + { + if (x.arrayIndex != y.arrayIndex) + { + return x.arrayIndex < y.arrayIndex; + } + } + + // Then order by field index + if (x.fieldIndex != y.fieldIndex) + { + return x.fieldIndex < y.fieldIndex; + } + + // Then order by secondary field index + if (x.secondaryFieldIndex != y.secondaryFieldIndex) + { + return x.secondaryFieldIndex < y.secondaryFieldIndex; + } + + // Otherwise order by variable + return gl::CompareShaderVar(*px, *py); +} + +bool InterfaceVariablesMatch(const sh::ShaderVariable &front, const sh::ShaderVariable &back) +{ + // Matching ruels from 7.4.1 Shader Interface Matching from the GLES 3.2 spec: + // - the two variables match in name, type, and qualification; or + // - the two variables are declared with the same location qualifier and match in type and + // qualification. Note that we use a more permissive check here thanks to front-end validation. + if (back.location != -1 && back.location == front.location) + { + return true; + } + + if (front.isShaderIOBlock != back.isShaderIOBlock) + { + return false; + } + + // Compare names, or if shader I/O blocks, block names. + const std::string &backName = back.isShaderIOBlock ? back.structOrBlockName : back.name; + const std::string &frontName = front.isShaderIOBlock ? front.structOrBlockName : front.name; + return backName == frontName; +} + +GLint GetMaxShaderInputVectors(const Caps &caps, ShaderType shaderStage) +{ + switch (shaderStage) + { + case ShaderType::TessControl: + return caps.maxTessControlInputComponents / 4; + case ShaderType::TessEvaluation: + return caps.maxTessEvaluationInputComponents / 4; + case ShaderType::Geometry: + return caps.maxGeometryInputComponents / 4; + case ShaderType::Fragment: + return caps.maxFragmentInputComponents / 4; + default: + return std::numeric_limits::max(); + } +} + +GLint GetMaxShaderOutputVectors(const Caps &caps, ShaderType shaderStage) +{ + switch (shaderStage) + { + case ShaderType::Vertex: + return caps.maxVertexOutputComponents / 4; + case ShaderType::TessControl: + return caps.maxTessControlOutputComponents / 4; + case ShaderType::TessEvaluation: + return caps.maxTessEvaluationOutputComponents / 4; + case ShaderType::Geometry: + return caps.maxGeometryOutputComponents / 4; + default: + return std::numeric_limits::max(); + } +} + +bool ShouldSkipPackedVarying(const sh::ShaderVariable &varying, PackMode packMode) +{ + // Don't pack gl_Position. Also don't count gl_PointSize for D3D9. + return varying.name == "gl_Position" || + (varying.name == "gl_PointSize" && packMode == PackMode::ANGLE_NON_CONFORMANT_D3D9); +} + +std::vector StripVaryingArrayDimension(const sh::ShaderVariable *frontVarying, + ShaderType frontShaderStage, + const sh::ShaderVariable *backVarying, + ShaderType backShaderStage, + bool isStructField) +{ + // "Geometry shader inputs, tessellation control shader inputs and outputs, and tessellation + // evaluation inputs all have an additional level of arrayness relative to other shader inputs + // and outputs. This outer array level is removed from the type before considering how many + // locations the type consumes." + + if (backVarying && backVarying->isArray() && !backVarying->isPatch && !isStructField && + (backShaderStage == ShaderType::Geometry || backShaderStage == ShaderType::TessEvaluation || + backShaderStage == ShaderType::TessControl)) + { + std::vector arr = backVarying->arraySizes; + arr.pop_back(); + return arr; + } + + if (frontVarying && frontVarying->isArray() && !frontVarying->isPatch && !isStructField && + frontShaderStage == ShaderType::TessControl) + { + std::vector arr = frontVarying->arraySizes; + arr.pop_back(); + return arr; + } + + return frontVarying ? frontVarying->arraySizes : backVarying->arraySizes; +} +} // anonymous namespace + +// Implementation of VaryingInShaderRef +VaryingInShaderRef::VaryingInShaderRef(ShaderType stageIn, const sh::ShaderVariable *varyingIn) + : varying(varyingIn), stage(stageIn) +{} + +VaryingInShaderRef::~VaryingInShaderRef() = default; + +VaryingInShaderRef::VaryingInShaderRef(VaryingInShaderRef &&other) + : varying(other.varying), + stage(other.stage), + parentStructName(std::move(other.parentStructName)), + parentStructMappedName(std::move(other.parentStructMappedName)) +{} + +VaryingInShaderRef &VaryingInShaderRef::operator=(VaryingInShaderRef &&other) +{ + std::swap(varying, other.varying); + std::swap(stage, other.stage); + std::swap(parentStructName, other.parentStructName); + std::swap(parentStructMappedName, other.parentStructMappedName); + + return *this; +} + +// Implementation of PackedVarying +PackedVarying::PackedVarying(VaryingInShaderRef &&frontVaryingIn, + VaryingInShaderRef &&backVaryingIn, + sh::InterpolationType interpolationIn) + : PackedVarying(std::move(frontVaryingIn), + std::move(backVaryingIn), + interpolationIn, + GL_INVALID_INDEX, + 0, + 0) +{} + +PackedVarying::PackedVarying(VaryingInShaderRef &&frontVaryingIn, + VaryingInShaderRef &&backVaryingIn, + sh::InterpolationType interpolationIn, + GLuint arrayIndexIn, + GLuint fieldIndexIn, + GLuint secondaryFieldIndexIn) + : frontVarying(std::move(frontVaryingIn)), + backVarying(std::move(backVaryingIn)), + interpolation(interpolationIn), + arrayIndex(arrayIndexIn), + isTransformFeedback(false), + fieldIndex(fieldIndexIn), + secondaryFieldIndex(secondaryFieldIndexIn) +{} + +PackedVarying::~PackedVarying() = default; + +PackedVarying::PackedVarying(PackedVarying &&other) + : frontVarying(std::move(other.frontVarying)), + backVarying(std::move(other.backVarying)), + interpolation(other.interpolation), + arrayIndex(other.arrayIndex), + isTransformFeedback(other.isTransformFeedback), + fieldIndex(other.fieldIndex), + secondaryFieldIndex(other.secondaryFieldIndex) +{} + +PackedVarying &PackedVarying::operator=(PackedVarying &&other) +{ + std::swap(frontVarying, other.frontVarying); + std::swap(backVarying, other.backVarying); + std::swap(interpolation, other.interpolation); + std::swap(arrayIndex, other.arrayIndex); + std::swap(isTransformFeedback, other.isTransformFeedback); + std::swap(fieldIndex, other.fieldIndex); + std::swap(secondaryFieldIndex, other.secondaryFieldIndex); + + return *this; +} + +unsigned int PackedVarying::getBasicTypeElementCount() const +{ + // "Geometry shader inputs, tessellation control shader inputs and outputs, and tessellation + // evaluation inputs all have an additional level of arrayness relative to other shader inputs + // and outputs. This outer array level is removed from the type before considering how many + // locations the type consumes." + std::vector arr = + StripVaryingArrayDimension(frontVarying.varying, frontVarying.stage, backVarying.varying, + backVarying.stage, isStructField()); + return arr.empty() ? 1u : arr.back(); +} + +// Implementation of VaryingPacking +VaryingPacking::VaryingPacking() = default; + +VaryingPacking::~VaryingPacking() = default; + +void VaryingPacking::reset() +{ + clearRegisterMap(); + mRegisterList.clear(); + mPackedVaryings.clear(); + + for (std::vector &inactiveVaryingMappedNames : mInactiveVaryingMappedNames) + { + inactiveVaryingMappedNames.clear(); + } + + for (std::vector &activeBuiltIns : mActiveOutputBuiltIns) + { + activeBuiltIns.clear(); + } +} + +void VaryingPacking::clearRegisterMap() +{ + std::fill(mRegisterMap.begin(), mRegisterMap.end(), Register()); +} + +// Packs varyings into generic varying registers, using the algorithm from +// See [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111 +// Also [OpenGL ES Shading Language 3.00 rev. 4] Section 11 page 119 +// Returns false if unsuccessful. +bool VaryingPacking::packVaryingIntoRegisterMap(PackMode packMode, + const PackedVarying &packedVarying) +{ + const sh::ShaderVariable &varying = packedVarying.varying(); + + // "Non - square matrices of type matCxR consume the same space as a square matrix of type matN + // where N is the greater of C and R." + // Here we are a bit more conservative and allow packing non-square matrices more tightly. + // Make sure we use transposed matrix types to count registers correctly. + ASSERT(!varying.isStruct()); + GLenum transposedType = gl::TransposeMatrixType(varying.type); + unsigned int varyingRows = gl::VariableRowCount(transposedType); + unsigned int varyingColumns = gl::VariableColumnCount(transposedType); + + // Special pack mode for D3D9. Each varying takes a full register, no sharing. + // TODO(jmadill): Implement more sophisticated component packing in D3D9. + if (packMode == PackMode::ANGLE_NON_CONFORMANT_D3D9) + { + varyingColumns = 4; + } + + // "Variables of type mat2 occupies 2 complete rows." + // For non-WebGL contexts, we allow mat2 to occupy only two columns per row. + else if (packMode == PackMode::WEBGL_STRICT && varying.type == GL_FLOAT_MAT2) + { + varyingColumns = 4; + } + + // "Arrays of size N are assumed to take N times the size of the base type" + // GLSL ES 3.10 section 4.3.6: Output variables cannot be arrays of arrays or arrays of + // structures, so we may use getBasicTypeElementCount(). + const unsigned int elementCount = packedVarying.getBasicTypeElementCount(); + varyingRows *= (packedVarying.isTransformFeedbackArrayElement() ? 1 : elementCount); + + unsigned int maxVaryingVectors = static_cast(mRegisterMap.size()); + + // Fail if we are packing a single over-large varying. + if (varyingRows > maxVaryingVectors) + { + return false; + } + + // "For 2, 3 and 4 component variables packing is started using the 1st column of the 1st row. + // Variables are then allocated to successive rows, aligning them to the 1st column." + if (varyingColumns >= 2 && varyingColumns <= 4) + { + for (unsigned int row = 0; row <= maxVaryingVectors - varyingRows; ++row) + { + if (isRegisterRangeFree(row, 0, varyingRows, varyingColumns)) + { + insertVaryingIntoRegisterMap(row, 0, varyingColumns, packedVarying); + return true; + } + } + + // "For 2 component variables, when there are no spare rows, the strategy is switched to + // using the highest numbered row and the lowest numbered column where the variable will + // fit." + if (varyingColumns == 2) + { + for (unsigned int r = maxVaryingVectors - varyingRows + 1; r-- >= 1;) + { + if (isRegisterRangeFree(r, 2, varyingRows, 2)) + { + insertVaryingIntoRegisterMap(r, 2, varyingColumns, packedVarying); + return true; + } + } + } + + return false; + } + + // "1 component variables have their own packing rule. They are packed in order of size, largest + // first. Each variable is placed in the column that leaves the least amount of space in the + // column and aligned to the lowest available rows within that column." + ASSERT(varyingColumns == 1); + unsigned int contiguousSpace[4] = {0}; + unsigned int bestContiguousSpace[4] = {0}; + unsigned int totalSpace[4] = {0}; + + for (unsigned int row = 0; row < maxVaryingVectors; ++row) + { + for (unsigned int column = 0; column < 4; ++column) + { + if (mRegisterMap[row][column]) + { + contiguousSpace[column] = 0; + } + else + { + contiguousSpace[column]++; + totalSpace[column]++; + + if (contiguousSpace[column] > bestContiguousSpace[column]) + { + bestContiguousSpace[column] = contiguousSpace[column]; + } + } + } + } + + unsigned int bestColumn = 0; + for (unsigned int column = 1; column < 4; ++column) + { + if (bestContiguousSpace[column] >= varyingRows && + (bestContiguousSpace[bestColumn] < varyingRows || + totalSpace[column] < totalSpace[bestColumn])) + { + bestColumn = column; + } + } + + if (bestContiguousSpace[bestColumn] >= varyingRows) + { + for (unsigned int row = 0; row < maxVaryingVectors; row++) + { + if (isRegisterRangeFree(row, bestColumn, varyingRows, 1)) + { + for (unsigned int arrayIndex = 0; arrayIndex < varyingRows; ++arrayIndex) + { + // If varyingRows > 1, it must be an array. + PackedVaryingRegister registerInfo; + registerInfo.packedVarying = &packedVarying; + registerInfo.registerRow = row + arrayIndex; + registerInfo.registerColumn = bestColumn; + registerInfo.varyingArrayIndex = + (packedVarying.isTransformFeedbackArrayElement() ? packedVarying.arrayIndex + : arrayIndex); + registerInfo.varyingRowIndex = 0; + // Do not record register info for builtins. + // TODO(jmadill): Clean this up. + if (!varying.isBuiltIn()) + { + mRegisterList.push_back(registerInfo); + } + mRegisterMap[row + arrayIndex][bestColumn] = true; + } + break; + } + } + return true; + } + + return false; +} + +bool VaryingPacking::isRegisterRangeFree(unsigned int registerRow, + unsigned int registerColumn, + unsigned int varyingRows, + unsigned int varyingColumns) const +{ + for (unsigned int row = 0; row < varyingRows; ++row) + { + ASSERT(registerRow + row < mRegisterMap.size()); + for (unsigned int column = 0; column < varyingColumns; ++column) + { + ASSERT(registerColumn + column < 4); + if (mRegisterMap[registerRow + row][registerColumn + column]) + { + return false; + } + } + } + + return true; +} + +void VaryingPacking::insertVaryingIntoRegisterMap(unsigned int registerRow, + unsigned int registerColumn, + unsigned int varyingColumns, + const PackedVarying &packedVarying) +{ + unsigned int varyingRows = 0; + + const sh::ShaderVariable &varying = packedVarying.varying(); + ASSERT(!varying.isStruct()); + GLenum transposedType = gl::TransposeMatrixType(varying.type); + varyingRows = gl::VariableRowCount(transposedType); + + PackedVaryingRegister registerInfo; + registerInfo.packedVarying = &packedVarying; + registerInfo.registerColumn = registerColumn; + + // GLSL ES 3.10 section 4.3.6: Output variables cannot be arrays of arrays or arrays of + // structures, so we may use getBasicTypeElementCount(). + const unsigned int arrayElementCount = packedVarying.getBasicTypeElementCount(); + for (unsigned int arrayElement = 0; arrayElement < arrayElementCount; ++arrayElement) + { + if (packedVarying.isTransformFeedbackArrayElement() && + arrayElement != packedVarying.arrayIndex) + { + continue; + } + for (unsigned int varyingRow = 0; varyingRow < varyingRows; ++varyingRow) + { + registerInfo.registerRow = registerRow + (arrayElement * varyingRows) + varyingRow; + registerInfo.varyingRowIndex = varyingRow; + registerInfo.varyingArrayIndex = arrayElement; + // Do not record register info for builtins. + // TODO(jmadill): Clean this up. + if (!varying.isBuiltIn()) + { + mRegisterList.push_back(registerInfo); + } + + for (unsigned int columnIndex = 0; columnIndex < varyingColumns; ++columnIndex) + { + mRegisterMap[registerInfo.registerRow][registerColumn + columnIndex] = true; + } + } + } +} + +void VaryingPacking::collectUserVarying(const ProgramVaryingRef &ref, + VaryingUniqueFullNames *uniqueFullNames) +{ + const sh::ShaderVariable *input = ref.frontShader; + const sh::ShaderVariable *output = ref.backShader; + + // Will get the vertex shader interpolation by default. + sh::InterpolationType interpolation = input ? input->interpolation : output->interpolation; + + VaryingInShaderRef frontVarying(ref.frontShaderStage, input); + VaryingInShaderRef backVarying(ref.backShaderStage, output); + + mPackedVaryings.emplace_back(std::move(frontVarying), std::move(backVarying), interpolation); + if (input && !input->isBuiltIn()) + { + (*uniqueFullNames)[ref.frontShaderStage].insert( + mPackedVaryings.back().fullName(ref.frontShaderStage)); + } + if (output && !output->isBuiltIn()) + { + (*uniqueFullNames)[ref.backShaderStage].insert( + mPackedVaryings.back().fullName(ref.backShaderStage)); + } +} + +void VaryingPacking::collectUserVaryingField(const ProgramVaryingRef &ref, + GLuint arrayIndex, + GLuint fieldIndex, + GLuint secondaryFieldIndex, + VaryingUniqueFullNames *uniqueFullNames) +{ + const sh::ShaderVariable *input = ref.frontShader; + const sh::ShaderVariable *output = ref.backShader; + + // Will get the vertex shader interpolation by default. + sh::InterpolationType interpolation = input ? input->interpolation : output->interpolation; + + const sh::ShaderVariable *frontField = input ? &input->fields[fieldIndex] : nullptr; + const sh::ShaderVariable *backField = output ? &output->fields[fieldIndex] : nullptr; + + if (secondaryFieldIndex != GL_INVALID_INDEX) + { + frontField = frontField ? &frontField->fields[secondaryFieldIndex] : nullptr; + backField = backField ? &backField->fields[secondaryFieldIndex] : nullptr; + } + + VaryingInShaderRef frontVarying(ref.frontShaderStage, frontField); + VaryingInShaderRef backVarying(ref.backShaderStage, backField); + + if (input) + { + if (frontField->isShaderIOBlock) + { + frontVarying.parentStructName = input->structOrBlockName; + frontVarying.parentStructMappedName = input->mappedStructOrBlockName; + } + else + { + ASSERT(!frontField->isStruct() && !frontField->isArray()); + frontVarying.parentStructName = input->name; + frontVarying.parentStructMappedName = input->mappedName; + } + } + if (output) + { + if (backField->isShaderIOBlock) + { + backVarying.parentStructName = output->structOrBlockName; + backVarying.parentStructMappedName = output->mappedStructOrBlockName; + } + else + { + ASSERT(!backField->isStruct() && !backField->isArray()); + backVarying.parentStructName = output->name; + backVarying.parentStructMappedName = output->mappedName; + } + } + + mPackedVaryings.emplace_back(std::move(frontVarying), std::move(backVarying), interpolation, + arrayIndex, fieldIndex, + secondaryFieldIndex == GL_INVALID_INDEX ? 0 : secondaryFieldIndex); + + if (input) + { + (*uniqueFullNames)[ref.frontShaderStage].insert( + mPackedVaryings.back().fullName(ref.frontShaderStage)); + } + if (output) + { + (*uniqueFullNames)[ref.backShaderStage].insert( + mPackedVaryings.back().fullName(ref.backShaderStage)); + } +} + +void VaryingPacking::collectUserVaryingTF(const ProgramVaryingRef &ref, size_t subscript) +{ + const sh::ShaderVariable *input = ref.frontShader; + + VaryingInShaderRef frontVarying(ref.frontShaderStage, input); + VaryingInShaderRef backVarying(ref.backShaderStage, nullptr); + + mPackedVaryings.emplace_back(std::move(frontVarying), std::move(backVarying), + input->interpolation); + mPackedVaryings.back().arrayIndex = static_cast(subscript); + mPackedVaryings.back().isTransformFeedback = true; +} + +void VaryingPacking::collectUserVaryingFieldTF(const ProgramVaryingRef &ref, + const sh::ShaderVariable &field, + GLuint fieldIndex, + GLuint secondaryFieldIndex) +{ + const sh::ShaderVariable *input = ref.frontShader; + + const sh::ShaderVariable *frontField = &field; + if (secondaryFieldIndex != GL_INVALID_INDEX) + { + frontField = &frontField->fields[secondaryFieldIndex]; + } + + VaryingInShaderRef frontVarying(ref.frontShaderStage, frontField); + VaryingInShaderRef backVarying(ref.backShaderStage, nullptr); + + if (frontField->isShaderIOBlock) + { + frontVarying.parentStructName = input->structOrBlockName; + frontVarying.parentStructMappedName = input->mappedStructOrBlockName; + } + else + { + ASSERT(!frontField->isStruct() && !frontField->isArray()); + frontVarying.parentStructName = input->name; + frontVarying.parentStructMappedName = input->mappedName; + } + + mPackedVaryings.emplace_back(std::move(frontVarying), std::move(backVarying), + input->interpolation, GL_INVALID_INDEX, fieldIndex, + secondaryFieldIndex == GL_INVALID_INDEX ? 0 : secondaryFieldIndex); +} + +void VaryingPacking::collectVarying(const sh::ShaderVariable &varying, + const ProgramVaryingRef &ref, + PackMode packMode, + VaryingUniqueFullNames *uniqueFullNames) +{ + const sh::ShaderVariable *input = ref.frontShader; + const sh::ShaderVariable *output = ref.backShader; + + if (varying.isStruct()) + { + std::vector arraySizes = StripVaryingArrayDimension( + ref.frontShader, ref.frontShaderStage, ref.backShader, ref.backShaderStage, false); + const bool isArray = !arraySizes.empty(); + const GLuint arraySize = isArray ? arraySizes[0] : 1; + + for (GLuint arrayIndex = 0; arrayIndex < arraySize; ++arrayIndex) + { + const GLuint effectiveArrayIndex = isArray ? arrayIndex : GL_INVALID_INDEX; + for (GLuint fieldIndex = 0; fieldIndex < varying.fields.size(); ++fieldIndex) + { + const sh::ShaderVariable &fieldVarying = varying.fields[fieldIndex]; + if (ShouldSkipPackedVarying(fieldVarying, packMode)) + { + continue; + } + + if (fieldVarying.isStruct()) + { + if (fieldVarying.isArray()) + { + unsigned int structFieldArraySize = fieldVarying.arraySizes[0]; + for (unsigned int fieldArrayIndex = 0; + fieldArrayIndex < structFieldArraySize; ++fieldArrayIndex) + { + for (GLuint nestedIndex = 0; nestedIndex < fieldVarying.fields.size(); + nestedIndex++) + { + collectUserVaryingField(ref, effectiveArrayIndex, fieldIndex, + nestedIndex, uniqueFullNames); + } + } + } + else + { + for (GLuint nestedIndex = 0; nestedIndex < fieldVarying.fields.size(); + nestedIndex++) + { + collectUserVaryingField(ref, effectiveArrayIndex, fieldIndex, + nestedIndex, uniqueFullNames); + } + } + } + else + { + collectUserVaryingField(ref, effectiveArrayIndex, fieldIndex, GL_INVALID_INDEX, + uniqueFullNames); + } + } + } + if (input) + { + (*uniqueFullNames)[ref.frontShaderStage].insert(input->name); + if (input->isShaderIOBlock) + { + (*uniqueFullNames)[ref.frontShaderStage].insert(input->structOrBlockName); + } + } + if (output) + { + (*uniqueFullNames)[ref.backShaderStage].insert(output->name); + } + } + else + { + collectUserVarying(ref, uniqueFullNames); + } +} + +void VaryingPacking::collectTFVarying(const std::string &tfVarying, + const ProgramVaryingRef &ref, + VaryingUniqueFullNames *uniqueFullNames) +{ + const sh::ShaderVariable *input = ref.frontShader; + + std::vector subscripts; + std::string baseName = ParseResourceName(tfVarying, &subscripts); + + // Already packed as active varying. + if ((*uniqueFullNames)[ref.frontShaderStage].count(tfVarying) > 0 || + (*uniqueFullNames)[ref.frontShaderStage].count(baseName) > 0 || + (input->isShaderIOBlock && + (*uniqueFullNames)[ref.frontShaderStage].count(input->structOrBlockName) > 0)) + { + return; + } + + if (input->isStruct()) + { + GLuint fieldIndex = 0; + const sh::ShaderVariable *field = input->findField(tfVarying, &fieldIndex); + if (field != nullptr) + { + ASSERT(input->isShaderIOBlock || (!field->isStruct() && !field->isArray())); + + // If it's an I/O block whose member is being captured, pack every member of the + // block. Currently, we pack either all or none of an I/O block. + if (input->isShaderIOBlock) + { + for (fieldIndex = 0; fieldIndex < input->fields.size(); ++fieldIndex) + { + if (input->fields[fieldIndex].isStruct()) + { + + for (GLuint nestedIndex = 0; + nestedIndex < input->fields[fieldIndex].fields.size(); nestedIndex++) + { + collectUserVaryingFieldTF(ref, input->fields[fieldIndex], fieldIndex, + nestedIndex); + } + } + else + { + collectUserVaryingFieldTF(ref, input->fields[fieldIndex], fieldIndex, + GL_INVALID_INDEX); + } + } + + (*uniqueFullNames)[ref.frontShaderStage].insert(input->structOrBlockName); + } + else + { + collectUserVaryingFieldTF(ref, *field, fieldIndex, GL_INVALID_INDEX); + } + (*uniqueFullNames)[ref.frontShaderStage].insert(tfVarying); + (*uniqueFullNames)[ref.frontShaderStage].insert(input->name); + } + } + // Array as a whole and array element conflict has already been checked in + // linkValidateTransformFeedback. + else if (baseName == input->name) + { + size_t subscript = GL_INVALID_INDEX; + if (!subscripts.empty()) + { + subscript = subscripts.back(); + } + + // only pack varyings that are not builtins. + if (tfVarying.compare(0, 3, "gl_") != 0) + { + collectUserVaryingTF(ref, subscript); + (*uniqueFullNames)[ref.frontShaderStage].insert(tfVarying); + } + } +} + +bool VaryingPacking::collectAndPackUserVaryings(gl::InfoLog &infoLog, + GLint maxVaryingVectors, + PackMode packMode, + ShaderType frontShaderStage, + ShaderType backShaderStage, + const ProgramMergedVaryings &mergedVaryings, + const std::vector &tfVaryings, + const bool isSeparableProgram) +{ + VaryingUniqueFullNames uniqueFullNames; + + reset(); + + for (const ProgramVaryingRef &ref : mergedVaryings) + { + const sh::ShaderVariable *input = ref.frontShader; + const sh::ShaderVariable *output = ref.backShader; + + if ((input && ref.frontShaderStage != frontShaderStage) || + (output && ref.backShaderStage != backShaderStage)) + { + continue; + } + + const bool isActiveBuiltInInput = input && input->isBuiltIn() && input->active; + const bool isActiveBuiltInOutput = output && output->isBuiltIn() && output->active; + + // Keep track of output builtins that are used by the shader, such as gl_Position, + // gl_PointSize etc. + if (isActiveBuiltInInput) + { + mActiveOutputBuiltIns[ref.frontShaderStage].push_back(input->name); + // Keep track of members of builtins, such as gl_out[].gl_Position, too. + for (sh::ShaderVariable field : input->fields) + { + mActiveOutputBuiltIns[ref.frontShaderStage].push_back(field.name); + } + } + + // Only pack statically used varyings that have a matched input or output, plus special + // builtins. Note that we pack all statically used user-defined varyings even if they are + // not active. GLES specs are a bit vague on whether it's allowed to only pack active + // varyings, though GLES 3.1 spec section 11.1.2.1 says that "device-dependent + // optimizations" may be used to make vertex shader outputs fit. + // + // When separable programs are linked, varyings at the separable program's boundary are + // treated as active. See section 7.4.1 in + // https://www.khronos.org/registry/OpenGL/specs/es/3.2/es_spec_3.2.pdf + bool matchedInputOutputStaticUse = (input && output && output->staticUse); + bool activeBuiltIn = (isActiveBuiltInInput || isActiveBuiltInOutput); + + // Output variable in TCS can be read as input in another invocation by barrier. + // See section 11.2.1.2.4 Tessellation Control Shader Execution Order in OpenGL ES 3.2. + bool staticUseInTCS = + (input && input->staticUse && ref.frontShaderStage == ShaderType::TessControl); + + // Separable program requirements + bool separableActiveInput = (input && (input->active || !output)); + bool separableActiveOutput = (output && (output->active || !input)); + bool separableActiveVarying = + (isSeparableProgram && (separableActiveInput || separableActiveOutput)); + + if (matchedInputOutputStaticUse || activeBuiltIn || separableActiveVarying || + staticUseInTCS) + { + const sh::ShaderVariable *varying = output ? output : input; + + if (!ShouldSkipPackedVarying(*varying, packMode)) + { + collectVarying(*varying, ref, packMode, &uniqueFullNames); + continue; + } + } + + // If the varying is not used in the input, we know it is inactive, unless it's a separable + // program, in which case the input shader may not exist in this program. + if (!input && !isSeparableProgram) + { + if (!output->isBuiltIn()) + { + mInactiveVaryingMappedNames[ref.backShaderStage].push_back(output->mappedName); + if (output->isShaderIOBlock) + { + mInactiveVaryingMappedNames[ref.backShaderStage].push_back( + output->mappedStructOrBlockName); + } + } + continue; + } + + // Keep Transform FB varyings in the merged list always. + for (const std::string &tfVarying : tfVaryings) + { + collectTFVarying(tfVarying, ref, &uniqueFullNames); + } + + if (input && !input->isBuiltIn() && + uniqueFullNames[ref.frontShaderStage].count(input->name) == 0) + { + mInactiveVaryingMappedNames[ref.frontShaderStage].push_back(input->mappedName); + if (input->isShaderIOBlock) + { + mInactiveVaryingMappedNames[ref.frontShaderStage].push_back( + input->mappedStructOrBlockName); + } + } + if (output && !output->isBuiltIn() && + uniqueFullNames[ref.backShaderStage].count(output->name) == 0) + { + mInactiveVaryingMappedNames[ref.backShaderStage].push_back(output->mappedName); + if (output->isShaderIOBlock) + { + mInactiveVaryingMappedNames[ref.backShaderStage].push_back( + output->mappedStructOrBlockName); + } + } + } + + std::sort(mPackedVaryings.begin(), mPackedVaryings.end(), ComparePackedVarying); + + return packUserVaryings(infoLog, maxVaryingVectors, packMode, mPackedVaryings); +} + +// See comment on packVarying. +bool VaryingPacking::packUserVaryings(gl::InfoLog &infoLog, + GLint maxVaryingVectors, + PackMode packMode, + const std::vector &packedVaryings) +{ + clearRegisterMap(); + mRegisterMap.resize(maxVaryingVectors); + + // "Variables are packed into the registers one at a time so that they each occupy a contiguous + // subrectangle. No splitting of variables is permitted." + for (const PackedVarying &packedVarying : packedVaryings) + { + if (!packVaryingIntoRegisterMap(packMode, packedVarying)) + { + ShaderType eitherStage = packedVarying.frontVarying.varying + ? packedVarying.frontVarying.stage + : packedVarying.backVarying.stage; + infoLog << "Could not pack varying " << packedVarying.fullName(eitherStage); + + // TODO(jmadill): Implement more sophisticated component packing in D3D9. + if (packMode == PackMode::ANGLE_NON_CONFORMANT_D3D9) + { + infoLog << "Note: Additional non-conformant packing restrictions are enforced on " + "D3D9."; + } + + return false; + } + } + + // Sort the packed register list + std::sort(mRegisterList.begin(), mRegisterList.end()); + + return true; +} + +// ProgramVaryingPacking implementation. +ProgramVaryingPacking::ProgramVaryingPacking() = default; + +ProgramVaryingPacking::~ProgramVaryingPacking() = default; + +const VaryingPacking &ProgramVaryingPacking::getInputPacking(ShaderType backShaderStage) const +{ + ShaderType frontShaderStage = mBackToFrontStageMap[backShaderStage]; + + // If there's a missing shader stage, return the compute shader packing which is always empty. + if (frontShaderStage == ShaderType::InvalidEnum) + { + ASSERT(mVaryingPackings[ShaderType::Compute].getMaxSemanticIndex() == 0); + return mVaryingPackings[ShaderType::Compute]; + } + + return mVaryingPackings[frontShaderStage]; +} + +const VaryingPacking &ProgramVaryingPacking::getOutputPacking(ShaderType frontShaderStage) const +{ + return mVaryingPackings[frontShaderStage]; +} + +bool ProgramVaryingPacking::collectAndPackUserVaryings(InfoLog &infoLog, + const Caps &caps, + PackMode packMode, + const ShaderBitSet &activeShadersMask, + const ProgramMergedVaryings &mergedVaryings, + const std::vector &tfVaryings, + bool isSeparableProgram) +{ + mBackToFrontStageMap.fill(ShaderType::InvalidEnum); + + ShaderBitSet activeShaders = activeShadersMask; + + ASSERT(activeShaders.any()); + ShaderType frontShaderStage = activeShaders.first(); + activeShaders[frontShaderStage] = false; + + // Special case for start-after-vertex. + if (frontShaderStage != ShaderType::Vertex) + { + ShaderType emulatedFrontShaderStage = ShaderType::Vertex; + ShaderType backShaderStage = frontShaderStage; + + if (!mVaryingPackings[emulatedFrontShaderStage].collectAndPackUserVaryings( + infoLog, GetMaxShaderInputVectors(caps, backShaderStage), packMode, + ShaderType::InvalidEnum, backShaderStage, mergedVaryings, tfVaryings, + isSeparableProgram)) + { + return false; + } + mBackToFrontStageMap[backShaderStage] = emulatedFrontShaderStage; + } + + // Process input/output shader pairs. + for (ShaderType backShaderStage : activeShaders) + { + GLint maxVaryingVectors; + if (frontShaderStage == ShaderType::Vertex && backShaderStage == ShaderType::Fragment) + { + maxVaryingVectors = caps.maxVaryingVectors; + } + else + { + GLint outputVaryingsMax = GetMaxShaderOutputVectors(caps, frontShaderStage); + GLint inputVaryingsMax = GetMaxShaderInputVectors(caps, backShaderStage); + maxVaryingVectors = std::min(inputVaryingsMax, outputVaryingsMax); + } + + ASSERT(maxVaryingVectors > 0 && maxVaryingVectors < std::numeric_limits::max()); + + if (!mVaryingPackings[frontShaderStage].collectAndPackUserVaryings( + infoLog, maxVaryingVectors, packMode, frontShaderStage, backShaderStage, + mergedVaryings, tfVaryings, isSeparableProgram)) + { + return false; + } + + mBackToFrontStageMap[backShaderStage] = frontShaderStage; + frontShaderStage = backShaderStage; + } + + // Special case for stop-before-fragment. + if (frontShaderStage != ShaderType::Fragment) + { + if (!mVaryingPackings[frontShaderStage].collectAndPackUserVaryings( + infoLog, GetMaxShaderOutputVectors(caps, frontShaderStage), packMode, + frontShaderStage, ShaderType::InvalidEnum, mergedVaryings, tfVaryings, + isSeparableProgram)) + { + return false; + } + + ShaderType emulatedBackShaderStage = ShaderType::Fragment; + mBackToFrontStageMap[emulatedBackShaderStage] = frontShaderStage; + } + + return true; +} + +ProgramMergedVaryings GetMergedVaryingsFromLinkingVariables( + const LinkingVariables &linkingVariables) +{ + ShaderType frontShaderType = ShaderType::InvalidEnum; + ProgramMergedVaryings merged; + + for (ShaderType backShaderType : kAllGraphicsShaderTypes) + { + if (!linkingVariables.isShaderStageUsedBitset[backShaderType]) + { + continue; + } + const std::vector &backShaderOutputVaryings = + linkingVariables.outputVaryings[backShaderType]; + const std::vector &backShaderInputVaryings = + linkingVariables.inputVaryings[backShaderType]; + + // Add outputs. These are always unmatched since we walk shader stages sequentially. + for (const sh::ShaderVariable &frontVarying : backShaderOutputVaryings) + { + ProgramVaryingRef ref; + ref.frontShader = &frontVarying; + ref.frontShaderStage = backShaderType; + merged.push_back(ref); + } + + if (frontShaderType == ShaderType::InvalidEnum) + { + // If this is our first shader stage, and not a VS, we might have unmatched inputs. + for (const sh::ShaderVariable &backVarying : backShaderInputVaryings) + { + ProgramVaryingRef ref; + ref.backShader = &backVarying; + ref.backShaderStage = backShaderType; + merged.push_back(ref); + } + } + else + { + // Match inputs with the prior shader stage outputs. + for (const sh::ShaderVariable &backVarying : backShaderInputVaryings) + { + bool found = false; + for (ProgramVaryingRef &ref : merged) + { + if (ref.frontShader && ref.frontShaderStage == frontShaderType && + InterfaceVariablesMatch(*ref.frontShader, backVarying)) + { + ASSERT(ref.backShader == nullptr); + + ref.backShader = &backVarying; + ref.backShaderStage = backShaderType; + found = true; + break; + } + } + + // Some outputs are never matched, e.g. some builtin variables. + if (!found) + { + ProgramVaryingRef ref; + ref.backShader = &backVarying; + ref.backShaderStage = backShaderType; + merged.push_back(ref); + } + } + } + + // Save the current back shader to use as the next front shader. + frontShaderType = backShaderType; + } + + return merged; +} +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/VaryingPacking.h b/gfx/angle/checkout/src/libANGLE/VaryingPacking.h new file mode 100644 index 0000000000..3edb9326be --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/VaryingPacking.h @@ -0,0 +1,329 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// VaryingPacking: +// Class which describes a mapping from varyings to registers, according +// to the spec, or using custom packing algorithms. We also keep a register +// allocation list for the D3D renderer. +// + +#ifndef LIBANGLE_VARYINGPACKING_H_ +#define LIBANGLE_VARYINGPACKING_H_ + +#include + +#include "angle_gl.h" +#include "common/angleutils.h" +#include "libANGLE/angletypes.h" + +#include + +namespace gl +{ +class InfoLog; +class ProgramExecutable; +struct Caps; +struct LinkingVariables; +struct ProgramVaryingRef; + +using ProgramMergedVaryings = std::vector; + +// A varying can have different names between stages if matched by the location layout qualifier. +// Additionally, same name varyings could still be of two identical struct types with different +// names. This struct contains information on the varying in one of the two stages. PackedVarying +// will thus contain two copies of this along with common information, such as interpolation or +// field index. +struct VaryingInShaderRef : angle::NonCopyable +{ + VaryingInShaderRef(ShaderType stageIn, const sh::ShaderVariable *varyingIn); + VaryingInShaderRef(VaryingInShaderRef &&other); + ~VaryingInShaderRef(); + + VaryingInShaderRef &operator=(VaryingInShaderRef &&other); + + const sh::ShaderVariable *varying; + + ShaderType stage; + + // Struct name + std::string parentStructName; + std::string parentStructMappedName; +}; + +struct PackedVarying : angle::NonCopyable +{ + // Throughout this file, the "front" stage refers to the stage that outputs the varying, and the + // "back" stage refers to the stage that takes the varying as input. Note that this struct + // contains linked varyings, which means both front and back stage varyings are valid, except + // for the following which may have only one valid stage. + // + // - transform-feedback-captured varyings + // - builtins + // - separable program stages, + // + PackedVarying(VaryingInShaderRef &&frontVaryingIn, + VaryingInShaderRef &&backVaryingIn, + sh::InterpolationType interpolationIn); + PackedVarying(VaryingInShaderRef &&frontVaryingIn, + VaryingInShaderRef &&backVaryingIn, + sh::InterpolationType interpolationIn, + GLuint arrayIndexIn, + GLuint fieldIndexIn, + GLuint secondaryFieldIndexIn); + PackedVarying(PackedVarying &&other); + ~PackedVarying(); + + PackedVarying &operator=(PackedVarying &&other); + + bool isStructField() const + { + return frontVarying.varying ? !frontVarying.parentStructName.empty() + : !backVarying.parentStructName.empty(); + } + + bool isTransformFeedbackArrayElement() const + { + return isTransformFeedback && arrayIndex != GL_INVALID_INDEX; + } + + // Return either front or back varying, whichever is available. Only used when the name of the + // varying is not important, but only the type is interesting. + const sh::ShaderVariable &varying() const + { + return frontVarying.varying ? *frontVarying.varying : *backVarying.varying; + } + + const std::string &getParentStructName() const + { + ASSERT(isStructField()); + return frontVarying.varying ? frontVarying.parentStructName : backVarying.parentStructName; + } + + std::string fullName(ShaderType stage) const + { + ASSERT(stage == frontVarying.stage || stage == backVarying.stage); + const VaryingInShaderRef &varying = + stage == frontVarying.stage ? frontVarying : backVarying; + + std::stringstream fullNameStr; + if (isStructField()) + { + fullNameStr << varying.parentStructName << "."; + } + + fullNameStr << varying.varying->name; + if (arrayIndex != GL_INVALID_INDEX) + { + fullNameStr << "[" << arrayIndex << "]"; + } + return fullNameStr.str(); + } + + // Transform feedback varyings can be only referenced in the VS. + bool vertexOnly() const + { + return frontVarying.stage == ShaderType::Vertex && backVarying.varying == nullptr; + } + + // Special handling for GS/TS array inputs. + unsigned int getBasicTypeElementCount() const; + + VaryingInShaderRef frontVarying; + VaryingInShaderRef backVarying; + + // Cached so we can store sh::ShaderVariable to point to varying fields. + sh::InterpolationType interpolation; + + // Used by varyings that are captured with transform feedback, xor arrays of shader I/O blocks, + // distinguished by isTransformFeedback; + GLuint arrayIndex; + bool isTransformFeedback; + + // Field index in the struct. In Vulkan, this is used to assign a + // struct-typed varying location to the location of its first field. + GLuint fieldIndex; + GLuint secondaryFieldIndex; +}; + +struct PackedVaryingRegister final +{ + PackedVaryingRegister() + : packedVarying(nullptr), + varyingArrayIndex(0), + varyingRowIndex(0), + registerRow(0), + registerColumn(0) + {} + + PackedVaryingRegister(const PackedVaryingRegister &) = default; + PackedVaryingRegister &operator=(const PackedVaryingRegister &) = default; + + bool operator<(const PackedVaryingRegister &other) const + { + return sortOrder() < other.sortOrder(); + } + + unsigned int sortOrder() const + { + // TODO(jmadill): Handle interpolation types + return registerRow * 4 + registerColumn; + } + + std::string tfVaryingName() const + { + return packedVarying->fullName(packedVarying->frontVarying.stage); + } + + // Index to the array of varyings. + const PackedVarying *packedVarying; + + // The array element of the packed varying. + unsigned int varyingArrayIndex; + + // The row of the array element of the packed varying. + unsigned int varyingRowIndex; + + // The register row to which we've assigned this packed varying. + unsigned int registerRow; + + // The column of the register row into which we've packed this varying. + unsigned int registerColumn; +}; + +// Supported packing modes: +enum class PackMode +{ + // We treat mat2 arrays as taking two full rows. + WEBGL_STRICT, + + // We allow mat2 to take a 2x2 chunk. + ANGLE_RELAXED, + + // Each varying takes a separate register. No register sharing. + ANGLE_NON_CONFORMANT_D3D9, +}; + +class VaryingPacking final : angle::NonCopyable +{ + public: + VaryingPacking(); + ~VaryingPacking(); + + [[nodiscard]] bool collectAndPackUserVaryings(InfoLog &infoLog, + GLint maxVaryingVectors, + PackMode packMode, + ShaderType frontShaderStage, + ShaderType backShaderStage, + const ProgramMergedVaryings &mergedVaryings, + const std::vector &tfVaryings, + const bool isSeparableProgram); + + struct Register + { + Register() { data[0] = data[1] = data[2] = data[3] = false; } + + bool &operator[](unsigned int index) { return data[index]; } + bool operator[](unsigned int index) const { return data[index]; } + + bool data[4]; + }; + + Register &operator[](unsigned int index) { return mRegisterMap[index]; } + const Register &operator[](unsigned int index) const { return mRegisterMap[index]; } + + const std::vector &getRegisterList() const { return mRegisterList; } + unsigned int getMaxSemanticIndex() const + { + return static_cast(mRegisterList.size()); + } + + const ShaderMap> &getInactiveVaryingMappedNames() const + { + return mInactiveVaryingMappedNames; + } + + const ShaderMap> &getActiveOutputBuiltInNames() const + { + return mActiveOutputBuiltIns; + } + + void reset(); + + private: + using VaryingUniqueFullNames = ShaderMap>; + + // Register map functions. + bool packUserVaryings(InfoLog &infoLog, + GLint maxVaryingVectors, + PackMode packMode, + const std::vector &packedVaryings); + bool packVaryingIntoRegisterMap(PackMode packMode, const PackedVarying &packedVarying); + bool isRegisterRangeFree(unsigned int registerRow, + unsigned int registerColumn, + unsigned int varyingRows, + unsigned int varyingColumns) const; + void insertVaryingIntoRegisterMap(unsigned int registerRow, + unsigned int registerColumn, + unsigned int varyingColumns, + const PackedVarying &packedVarying); + void clearRegisterMap(); + + // Collection functions. + void collectUserVarying(const ProgramVaryingRef &ref, VaryingUniqueFullNames *uniqueFullNames); + void collectUserVaryingField(const ProgramVaryingRef &ref, + GLuint arrayIndex, + GLuint fieldIndex, + GLuint secondaryFieldIndex, + VaryingUniqueFullNames *uniqueFullNames); + void collectUserVaryingTF(const ProgramVaryingRef &ref, size_t subscript); + void collectUserVaryingFieldTF(const ProgramVaryingRef &ref, + const sh::ShaderVariable &field, + GLuint fieldIndex, + GLuint secondaryFieldIndex); + void collectVarying(const sh::ShaderVariable &varying, + const ProgramVaryingRef &ref, + PackMode packMode, + VaryingUniqueFullNames *uniqueFullNames); + void collectTFVarying(const std::string &tfVarying, + const ProgramVaryingRef &ref, + VaryingUniqueFullNames *uniqueFullNames); + + std::vector mRegisterMap; + std::vector mRegisterList; + std::vector mPackedVaryings; + ShaderMap> mInactiveVaryingMappedNames; + ShaderMap> mActiveOutputBuiltIns; +}; + +class ProgramVaryingPacking final : angle::NonCopyable +{ + public: + ProgramVaryingPacking(); + ~ProgramVaryingPacking(); + + const VaryingPacking &getInputPacking(ShaderType backShaderStage) const; + const VaryingPacking &getOutputPacking(ShaderType frontShaderStage) const; + + [[nodiscard]] bool collectAndPackUserVaryings(InfoLog &infoLog, + const Caps &caps, + PackMode packMode, + const ShaderBitSet &activeShadersMask, + const ProgramMergedVaryings &mergedVaryings, + const std::vector &tfVaryings, + bool isSeparableProgram); + + private: + // Indexed by the front shader. + ShaderMap mVaryingPackings; + + // Looks up the front stage from the back stage. + ShaderMap mBackToFrontStageMap; +}; + +ProgramMergedVaryings GetMergedVaryingsFromLinkingVariables( + const LinkingVariables &linkingVariables); +} // namespace gl + +#endif // LIBANGLE_VARYINGPACKING_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Version.h b/gfx/angle/checkout/src/libANGLE/Version.h new file mode 100644 index 0000000000..0d3b502d21 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Version.h @@ -0,0 +1,34 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Version.h: Encapsulation of a GL version. + +#ifndef LIBANGLE_VERSION_H_ +#define LIBANGLE_VERSION_H_ + +namespace gl +{ + +struct Version +{ + constexpr Version(); + constexpr Version(unsigned int major, unsigned int minor); + + unsigned int major; + unsigned int minor; +}; + +bool operator==(const Version &a, const Version &b); +bool operator!=(const Version &a, const Version &b); +bool operator>=(const Version &a, const Version &b); +bool operator<=(const Version &a, const Version &b); +bool operator<(const Version &a, const Version &b); +bool operator>(const Version &a, const Version &b); +} // namespace gl + +#include "Version.inc" + +#endif // LIBANGLE_VERSION_H_ diff --git a/gfx/angle/checkout/src/libANGLE/Version.inc b/gfx/angle/checkout/src/libANGLE/Version.inc new file mode 100644 index 0000000000..a2bab8dc1f --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Version.inc @@ -0,0 +1,59 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Version.inc: Encapsulation of a GL version. + +#include + +namespace gl +{ + +constexpr Version::Version() + : Version(0, 0) +{ +} + +// Avoid conflicts with linux system defines +#undef major +#undef minor + +constexpr Version::Version(unsigned int major_, unsigned int minor_) + : major(major_), + minor(minor_) +{ +} + +inline bool operator==(const Version &a, const Version &b) +{ + return std::tie(a.major, a.minor) == std::tie(b.major, b.minor); +} + +inline bool operator!=(const Version &a, const Version &b) +{ + return std::tie(a.major, a.minor) != std::tie(b.major, b.minor); +} + +inline bool operator>=(const Version &a, const Version &b) +{ + return std::tie(a.major, a.minor) >= std::tie(b.major, b.minor); +} + +inline bool operator<=(const Version &a, const Version &b) +{ + return std::tie(a.major, a.minor) <= std::tie(b.major, b.minor); +} + +inline bool operator<(const Version &a, const Version &b) +{ + return std::tie(a.major, a.minor) < std::tie(b.major, b.minor); +} + +inline bool operator>(const Version &a, const Version &b) +{ + return std::tie(a.major, a.minor) > std::tie(b.major, b.minor); +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/VertexArray.cpp b/gfx/angle/checkout/src/libANGLE/VertexArray.cpp new file mode 100644 index 0000000000..2a9bcd7cc0 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/VertexArray.cpp @@ -0,0 +1,906 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Implementation of the state class for mananging GLES 3 Vertex Array Objects. +// + +#include "libANGLE/VertexArray.h" + +#include "common/utilities.h" +#include "libANGLE/Buffer.h" +#include "libANGLE/Context.h" +#include "libANGLE/renderer/BufferImpl.h" +#include "libANGLE/renderer/GLImplFactory.h" +#include "libANGLE/renderer/VertexArrayImpl.h" + +namespace gl +{ +namespace +{ +constexpr size_t kMaxObserverCountToTriggerUnobserve = 20; + +bool IsElementArrayBufferSubjectIndex(angle::SubjectIndex subjectIndex) +{ + return (subjectIndex == kElementArrayBufferIndex); +} +} // namespace + +// VertexArrayState implementation. +VertexArrayState::VertexArrayState(VertexArray *vertexArray, + size_t maxAttribs, + size_t maxAttribBindings) + : mElementArrayBuffer(vertexArray, kElementArrayBufferIndex) +{ + ASSERT(maxAttribs <= maxAttribBindings); + + for (size_t i = 0; i < maxAttribs; i++) + { + mVertexAttributes.emplace_back(static_cast(i)); + mVertexBindings.emplace_back(static_cast(i)); + } + + // Initially all attributes start as "client" with no buffer bound. + mClientMemoryAttribsMask.set(); +} + +VertexArrayState::~VertexArrayState() {} + +bool VertexArrayState::hasEnabledNullPointerClientArray() const +{ + return (mNullPointerClientMemoryAttribsMask & mEnabledAttributesMask).any(); +} + +AttributesMask VertexArrayState::getBindingToAttributesMask(GLuint bindingIndex) const +{ + ASSERT(bindingIndex < mVertexBindings.size()); + return mVertexBindings[bindingIndex].getBoundAttributesMask(); +} + +// Set an attribute using a new binding. +void VertexArrayState::setAttribBinding(const Context *context, + size_t attribIndex, + GLuint newBindingIndex) +{ + ASSERT(attribIndex < mVertexAttributes.size() && newBindingIndex < mVertexBindings.size()); + + VertexAttribute &attrib = mVertexAttributes[attribIndex]; + + // Update the binding-attribute map. + const GLuint oldBindingIndex = attrib.bindingIndex; + ASSERT(oldBindingIndex != newBindingIndex); + + VertexBinding &oldBinding = mVertexBindings[oldBindingIndex]; + VertexBinding &newBinding = mVertexBindings[newBindingIndex]; + + ASSERT(oldBinding.getBoundAttributesMask().test(attribIndex) && + !newBinding.getBoundAttributesMask().test(attribIndex)); + + oldBinding.resetBoundAttribute(attribIndex); + newBinding.setBoundAttribute(attribIndex); + + // Set the attribute using the new binding. + attrib.bindingIndex = newBindingIndex; + + if (context->isBufferAccessValidationEnabled()) + { + attrib.updateCachedElementLimit(newBinding); + } + + bool isMapped = newBinding.getBuffer().get() && newBinding.getBuffer()->isMapped(); + mCachedMappedArrayBuffers.set(attribIndex, isMapped); + mEnabledAttributesMask.set(attribIndex, attrib.enabled); + updateCachedMutableOrNonPersistentArrayBuffers(attribIndex); + mCachedInvalidMappedArrayBuffer = mCachedMappedArrayBuffers & mEnabledAttributesMask & + mCachedMutableOrImpersistentArrayBuffers; +} + +void VertexArrayState::updateCachedMutableOrNonPersistentArrayBuffers(size_t index) +{ + const VertexBinding &vertexBinding = mVertexBindings[index]; + const BindingPointer &buffer = vertexBinding.getBuffer(); + bool isMutableOrImpersistentArrayBuffer = + buffer.get() && + (!buffer->isImmutable() || (buffer->getAccessFlags() & GL_MAP_PERSISTENT_BIT_EXT) == 0); + mCachedMutableOrImpersistentArrayBuffers.set(index, isMutableOrImpersistentArrayBuffer); +} + +// VertexArray implementation. +VertexArray::VertexArray(rx::GLImplFactory *factory, + VertexArrayID id, + size_t maxAttribs, + size_t maxAttribBindings) + : mId(id), + mState(this, maxAttribs, maxAttribBindings), + mVertexArray(factory->createVertexArray(mState)), + mBufferAccessValidationEnabled(false), + mContentsObservers(this) +{ + for (size_t attribIndex = 0; attribIndex < maxAttribBindings; ++attribIndex) + { + mArrayBufferObserverBindings.emplace_back(this, attribIndex); + } + + mVertexArray->setContentsObservers(&mContentsObservers); +} + +void VertexArray::onDestroy(const Context *context) +{ + bool isBound = context->isCurrentVertexArray(this); + for (uint32_t bindingIndex = 0; bindingIndex < mState.mVertexBindings.size(); ++bindingIndex) + { + VertexBinding &binding = mState.mVertexBindings[bindingIndex]; + Buffer *buffer = binding.getBuffer().get(); + if (isBound) + { + if (buffer) + { + buffer->onNonTFBindingChanged(-1); + } + } + if (buffer) + { + // Note: the non-contents observer is unbound in the ObserverBinding destructor. + buffer->removeContentsObserver(this, bindingIndex); + } + binding.setBuffer(context, nullptr); + } + if (mState.mElementArrayBuffer.get()) + { + if (isBound) + { + mState.mElementArrayBuffer->onNonTFBindingChanged(-1); + } + mState.mElementArrayBuffer->removeContentsObserver(this, kElementArrayBufferIndex); + } + mState.mElementArrayBuffer.bind(context, nullptr); + + // If mDirtyObserverBindingBits is set, it means we have removed it from the buffer's observer + // list. We should unassign subject to avoid assertion. + for (size_t bindingIndex : mDirtyObserverBindingBits) + { + angle::ObserverBinding *observer = &mArrayBufferObserverBindings[bindingIndex]; + observer->assignSubject(nullptr); + } + + mVertexArray->destroy(context); + SafeDelete(mVertexArray); + delete this; +} + +VertexArray::~VertexArray() +{ + ASSERT(!mVertexArray); +} + +angle::Result VertexArray::setLabel(const Context *context, const std::string &label) +{ + mState.mLabel = label; + + if (mVertexArray) + { + return mVertexArray->onLabelUpdate(context); + } + return angle::Result::Continue; +} + +const std::string &VertexArray::getLabel() const +{ + return mState.mLabel; +} + +bool VertexArray::detachBuffer(const Context *context, BufferID bufferID) +{ + bool isBound = context->isCurrentVertexArray(this); + bool anyBufferDetached = false; + for (uint32_t bindingIndex = 0; bindingIndex < mState.mVertexBindings.size(); ++bindingIndex) + { + VertexBinding &binding = mState.mVertexBindings[bindingIndex]; + const BindingPointer &bufferBinding = binding.getBuffer(); + if (bufferBinding.id() == bufferID) + { + if (isBound) + { + if (bufferBinding.get()) + bufferBinding->onNonTFBindingChanged(-1); + } + bufferBinding->removeContentsObserver(this, bindingIndex); + binding.setBuffer(context, nullptr); + mArrayBufferObserverBindings[bindingIndex].reset(); + + if (context->getClientVersion() >= ES_3_1) + { + setDirtyBindingBit(bindingIndex, DIRTY_BINDING_BUFFER); + } + else + { + static_assert(gl::MAX_VERTEX_ATTRIB_BINDINGS < 8 * sizeof(uint32_t), + "Not enough bits in bindingIndex"); + // The redundant uint32_t cast here is required to avoid a warning on MSVC. + ASSERT(binding.getBoundAttributesMask() == + AttributesMask(static_cast(1 << bindingIndex))); + setDirtyAttribBit(bindingIndex, DIRTY_ATTRIB_POINTER); + } + + anyBufferDetached = true; + mState.mClientMemoryAttribsMask |= binding.getBoundAttributesMask(); + } + } + + if (mState.mElementArrayBuffer.get() && mState.mElementArrayBuffer->id() == bufferID) + { + if (isBound && mState.mElementArrayBuffer.get()) + mState.mElementArrayBuffer->onNonTFBindingChanged(-1); + mState.mElementArrayBuffer->removeContentsObserver(this, kElementArrayBufferIndex); + mState.mElementArrayBuffer.bind(context, nullptr); + mDirtyBits.set(DIRTY_BIT_ELEMENT_ARRAY_BUFFER); + anyBufferDetached = true; + } + + return anyBufferDetached; +} + +const VertexAttribute &VertexArray::getVertexAttribute(size_t attribIndex) const +{ + ASSERT(attribIndex < getMaxAttribs()); + return mState.mVertexAttributes[attribIndex]; +} + +const VertexBinding &VertexArray::getVertexBinding(size_t bindingIndex) const +{ + ASSERT(bindingIndex < getMaxBindings()); + return mState.mVertexBindings[bindingIndex]; +} + +size_t VertexArray::GetVertexIndexFromDirtyBit(size_t dirtyBit) +{ + static_assert(gl::MAX_VERTEX_ATTRIBS == gl::MAX_VERTEX_ATTRIB_BINDINGS, + "The stride of vertex attributes should equal to that of vertex bindings."); + ASSERT(dirtyBit > DIRTY_BIT_ELEMENT_ARRAY_BUFFER); + return (dirtyBit - DIRTY_BIT_ATTRIB_0) % gl::MAX_VERTEX_ATTRIBS; +} + +ANGLE_INLINE void VertexArray::setDirtyAttribBit(size_t attribIndex, + DirtyAttribBitType dirtyAttribBit) +{ + mDirtyBits.set(DIRTY_BIT_ATTRIB_0 + attribIndex); + mDirtyAttribBits[attribIndex].set(dirtyAttribBit); +} + +ANGLE_INLINE void VertexArray::clearDirtyAttribBit(size_t attribIndex, + DirtyAttribBitType dirtyAttribBit) +{ + mDirtyAttribBits[attribIndex].set(dirtyAttribBit, false); + if (mDirtyAttribBits[attribIndex].any()) + { + return; + } + mDirtyBits.set(DIRTY_BIT_ATTRIB_0 + attribIndex, false); +} + +ANGLE_INLINE void VertexArray::setDirtyBindingBit(size_t bindingIndex, + DirtyBindingBitType dirtyBindingBit) +{ + mDirtyBits.set(DIRTY_BIT_BINDING_0 + bindingIndex); + mDirtyBindingBits[bindingIndex].set(dirtyBindingBit); +} + +ANGLE_INLINE void VertexArray::updateCachedBufferBindingSize(VertexBinding *binding) +{ + if (!mBufferAccessValidationEnabled) + return; + + for (size_t boundAttribute : binding->getBoundAttributesMask()) + { + mState.mVertexAttributes[boundAttribute].updateCachedElementLimit(*binding); + } +} + +ANGLE_INLINE void VertexArray::updateCachedArrayBuffersMasks( + bool isMapped, + bool isImmutable, + bool isPersistent, + const AttributesMask &boundAttributesMask) +{ + if (isMapped) + { + mState.mCachedMappedArrayBuffers |= boundAttributesMask; + } + else + { + mState.mCachedMappedArrayBuffers &= ~boundAttributesMask; + } + + if (!isImmutable || !isPersistent) + { + mState.mCachedMutableOrImpersistentArrayBuffers |= boundAttributesMask; + } + else + { + mState.mCachedMutableOrImpersistentArrayBuffers &= ~boundAttributesMask; + } + + mState.mCachedInvalidMappedArrayBuffer = mState.mCachedMappedArrayBuffers & + mState.mEnabledAttributesMask & + mState.mCachedMutableOrImpersistentArrayBuffers; +} + +ANGLE_INLINE void VertexArray::updateCachedMappedArrayBuffersBinding(const VertexBinding &binding) +{ + const Buffer *buffer = binding.getBuffer().get(); + bool isMapped = buffer && buffer->isMapped(); + bool isImmutable = buffer && buffer->isImmutable(); + bool isPersistent = buffer && (buffer->getAccessFlags() & GL_MAP_PERSISTENT_BIT_EXT) != 0; + return updateCachedArrayBuffersMasks(isMapped, isImmutable, isPersistent, + binding.getBoundAttributesMask()); +} + +ANGLE_INLINE void VertexArray::updateCachedTransformFeedbackBindingValidation(size_t bindingIndex, + const Buffer *buffer) +{ + const bool hasConflict = buffer && buffer->hasWebGLXFBBindingConflict(true); + mCachedTransformFeedbackConflictedBindingsMask.set(bindingIndex, hasConflict); +} + +bool VertexArray::bindVertexBufferImpl(const Context *context, + size_t bindingIndex, + Buffer *boundBuffer, + GLintptr offset, + GLsizei stride) +{ + ASSERT(bindingIndex < getMaxBindings()); + ASSERT(context->isCurrentVertexArray(this)); + + VertexBinding *binding = &mState.mVertexBindings[bindingIndex]; + + Buffer *oldBuffer = binding->getBuffer().get(); + + const bool sameBuffer = oldBuffer == boundBuffer; + const bool sameStride = static_cast(stride) == binding->getStride(); + const bool sameOffset = offset == binding->getOffset(); + + if (sameBuffer && sameStride && sameOffset) + { + return false; + } + + angle::ObserverBinding *observer = &mArrayBufferObserverBindings[bindingIndex]; + observer->assignSubject(boundBuffer); + + // Several nullptr checks are combined here for optimization purposes. + if (oldBuffer) + { + oldBuffer->onNonTFBindingChanged(-1); + oldBuffer->removeObserver(observer); + oldBuffer->removeContentsObserver(this, static_cast(bindingIndex)); + oldBuffer->release(context); + } + + binding->assignBuffer(boundBuffer); + binding->setOffset(offset); + binding->setStride(stride); + updateCachedBufferBindingSize(binding); + + // Update client memory attribute pointers. Affects all bound attributes. + if (boundBuffer) + { + boundBuffer->addRef(); + boundBuffer->onNonTFBindingChanged(1); + boundBuffer->addObserver(observer); + if (context->isWebGL()) + { + mCachedTransformFeedbackConflictedBindingsMask.set( + bindingIndex, boundBuffer->hasWebGLXFBBindingConflict(true)); + } + mState.mClientMemoryAttribsMask &= ~binding->getBoundAttributesMask(); + + bool isMapped = boundBuffer->isMapped() == GL_TRUE; + bool isImmutable = boundBuffer->isImmutable() == GL_TRUE; + bool isPersistent = (boundBuffer->getAccessFlags() & GL_MAP_PERSISTENT_BIT_EXT) != 0; + updateCachedArrayBuffersMasks(isMapped, isImmutable, isPersistent, + binding->getBoundAttributesMask()); + } + else + { + if (context->isWebGL()) + { + mCachedTransformFeedbackConflictedBindingsMask.set(bindingIndex, false); + } + mState.mClientMemoryAttribsMask |= binding->getBoundAttributesMask(); + updateCachedArrayBuffersMasks(false, false, false, binding->getBoundAttributesMask()); + } + + return true; +} + +void VertexArray::bindVertexBuffer(const Context *context, + size_t bindingIndex, + Buffer *boundBuffer, + GLintptr offset, + GLsizei stride) +{ + if (bindVertexBufferImpl(context, bindingIndex, boundBuffer, offset, stride)) + { + setDirtyBindingBit(bindingIndex, DIRTY_BINDING_BUFFER); + } +} + +void VertexArray::setVertexAttribBinding(const Context *context, + size_t attribIndex, + GLuint bindingIndex) +{ + ASSERT(attribIndex < getMaxAttribs() && bindingIndex < getMaxBindings()); + + if (mState.mVertexAttributes[attribIndex].bindingIndex == bindingIndex) + { + return; + } + + // In ES 3.0 contexts, the binding cannot change, hence the code below is unreachable. + ASSERT(context->getClientVersion() >= ES_3_1); + + mState.setAttribBinding(context, attribIndex, bindingIndex); + + setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_BINDING); + + // Update client attribs mask. + bool hasBuffer = mState.mVertexBindings[bindingIndex].getBuffer().get() != nullptr; + mState.mClientMemoryAttribsMask.set(attribIndex, !hasBuffer); +} + +void VertexArray::setVertexBindingDivisor(const Context *context, + size_t bindingIndex, + GLuint divisor) +{ + ASSERT(bindingIndex < getMaxBindings()); + + VertexBinding &binding = mState.mVertexBindings[bindingIndex]; + + if (binding.getDivisor() == divisor) + { + return; + } + + binding.setDivisor(divisor); + setDirtyBindingBit(bindingIndex, DIRTY_BINDING_DIVISOR); + + // Trigger updates in all bound attributes. + if (context->isBufferAccessValidationEnabled()) + { + for (size_t attribIndex : binding.getBoundAttributesMask()) + { + mState.mVertexAttributes[attribIndex].updateCachedElementLimit(binding); + } + } +} + +ANGLE_INLINE bool VertexArray::setVertexAttribFormatImpl(VertexAttribute *attrib, + GLint size, + VertexAttribType type, + bool normalized, + bool pureInteger, + GLuint relativeOffset) +{ + angle::FormatID formatID = gl::GetVertexFormatID(type, normalized, size, pureInteger); + + if (formatID != attrib->format->id || attrib->relativeOffset != relativeOffset) + { + attrib->relativeOffset = relativeOffset; + attrib->format = &angle::Format::Get(formatID); + return true; + } + + return false; +} + +void VertexArray::setVertexAttribFormat(size_t attribIndex, + GLint size, + VertexAttribType type, + bool normalized, + bool pureInteger, + GLuint relativeOffset) +{ + VertexAttribute &attrib = mState.mVertexAttributes[attribIndex]; + + ComponentType componentType = GetVertexAttributeComponentType(pureInteger, type); + SetComponentTypeMask(componentType, attribIndex, &mState.mVertexAttributesTypeMask); + + if (setVertexAttribFormatImpl(&attrib, size, type, normalized, pureInteger, relativeOffset)) + { + setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_FORMAT); + } + + attrib.updateCachedElementLimit(mState.mVertexBindings[attrib.bindingIndex]); +} + +void VertexArray::setVertexAttribDivisor(const Context *context, size_t attribIndex, GLuint divisor) +{ + ASSERT(attribIndex < getMaxAttribs()); + + setVertexAttribBinding(context, attribIndex, static_cast(attribIndex)); + setVertexBindingDivisor(context, attribIndex, divisor); +} + +void VertexArray::enableAttribute(size_t attribIndex, bool enabledState) +{ + ASSERT(attribIndex < getMaxAttribs()); + + VertexAttribute &attrib = mState.mVertexAttributes[attribIndex]; + + if (mState.mEnabledAttributesMask.test(attribIndex) == enabledState) + { + return; + } + + attrib.enabled = enabledState; + + // Update state cache + mState.mEnabledAttributesMask.set(attribIndex, enabledState); + bool enableChanged = (mState.mEnabledAttributesMask.test(attribIndex) != + mState.mLastSyncedEnabledAttributesMask.test(attribIndex)); + + if (enableChanged) + { + setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_ENABLED); + } + else + { + clearDirtyAttribBit(attribIndex, DIRTY_ATTRIB_ENABLED); + } + + mState.updateCachedMutableOrNonPersistentArrayBuffers(attribIndex); + mState.mCachedInvalidMappedArrayBuffer = mState.mCachedMappedArrayBuffers & + mState.mEnabledAttributesMask & + mState.mCachedMutableOrImpersistentArrayBuffers; +} + +ANGLE_INLINE void VertexArray::setVertexAttribPointerImpl(const Context *context, + ComponentType componentType, + bool pureInteger, + size_t attribIndex, + Buffer *boundBuffer, + GLint size, + VertexAttribType type, + bool normalized, + GLsizei stride, + const void *pointer) +{ + ASSERT(attribIndex < getMaxAttribs()); + + VertexAttribute &attrib = mState.mVertexAttributes[attribIndex]; + + SetComponentTypeMask(componentType, attribIndex, &mState.mVertexAttributesTypeMask); + + bool attribDirty = setVertexAttribFormatImpl(&attrib, size, type, normalized, pureInteger, 0); + + if (attrib.bindingIndex != attribIndex) + { + setVertexAttribBinding(context, attribIndex, static_cast(attribIndex)); + } + + GLsizei effectiveStride = + stride == 0 ? static_cast(ComputeVertexAttributeTypeSize(attrib)) : stride; + + if (attrib.vertexAttribArrayStride != static_cast(stride)) + { + attribDirty = true; + } + attrib.vertexAttribArrayStride = stride; + + // If we switch from an array buffer to a client pointer(or vice-versa), we set the whole + // attribute dirty. This notifies the Vulkan back-end to update all its caches. + const VertexBinding &binding = mState.mVertexBindings[attribIndex]; + if ((boundBuffer == nullptr) != (binding.getBuffer().get() == nullptr)) + { + attribDirty = true; + } + + // Change of attrib.pointer is not part of attribDirty. Pointer is actually the buffer offset + // which is handled within bindVertexBufferImpl and reflected in bufferDirty. + attrib.pointer = pointer; + GLintptr offset = boundBuffer ? reinterpret_cast(pointer) : 0; + const bool bufferDirty = + bindVertexBufferImpl(context, attribIndex, boundBuffer, offset, effectiveStride); + + if (attribDirty) + { + setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_POINTER); + } + else if (bufferDirty) + { + setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_POINTER_BUFFER); + } + + mState.mNullPointerClientMemoryAttribsMask.set(attribIndex, + boundBuffer == nullptr && pointer == nullptr); +} + +void VertexArray::setVertexAttribPointer(const Context *context, + size_t attribIndex, + gl::Buffer *boundBuffer, + GLint size, + VertexAttribType type, + bool normalized, + GLsizei stride, + const void *pointer) +{ + setVertexAttribPointerImpl(context, ComponentType::Float, false, attribIndex, boundBuffer, size, + type, normalized, stride, pointer); +} + +void VertexArray::setVertexAttribIPointer(const Context *context, + size_t attribIndex, + gl::Buffer *boundBuffer, + GLint size, + VertexAttribType type, + GLsizei stride, + const void *pointer) +{ + ComponentType componentType = GetVertexAttributeComponentType(true, type); + setVertexAttribPointerImpl(context, componentType, true, attribIndex, boundBuffer, size, type, + false, stride, pointer); +} + +angle::Result VertexArray::syncState(const Context *context) +{ + if (mDirtyBits.any()) + { + mDirtyBitsGuard = mDirtyBits; + ANGLE_TRY( + mVertexArray->syncState(context, mDirtyBits, &mDirtyAttribBits, &mDirtyBindingBits)); + mDirtyBits.reset(); + mDirtyBitsGuard.reset(); + + // The dirty bits should be reset in the back-end. To simplify ASSERTs only check attrib 0. + ASSERT(mDirtyAttribBits[0].none()); + ASSERT(mDirtyBindingBits[0].none()); + mState.mLastSyncedEnabledAttributesMask = mState.mEnabledAttributesMask; + } + return angle::Result::Continue; +} + +// This becomes current vertex array on the context +void VertexArray::onBind(const Context *context) +{ + if (mDirtyObserverBindingBits.none()) + { + return; + } + + // This vertex array becoming current. Some of the bindings we may have removed from buffer's + // observer list. We need to add it back to the buffer's observer list and update dirty bits + // that we may have missed while we were not observing. + for (size_t bindingIndex : mDirtyObserverBindingBits) + { + const gl::VertexBinding &binding = mState.getVertexBindings()[bindingIndex]; + gl::Buffer *bufferGL = binding.getBuffer().get(); + ASSERT(bufferGL != nullptr); + + bufferGL->addObserver(&mArrayBufferObserverBindings[bindingIndex]); + updateCachedMappedArrayBuffersBinding(mState.mVertexBindings[bindingIndex]); + + // Assume both data and internal storage has been dirtied. + mDirtyBits.set(DIRTY_BIT_BINDING_0 + bindingIndex); + + if (mBufferAccessValidationEnabled) + { + for (size_t boundAttribute : + mState.mVertexBindings[bindingIndex].getBoundAttributesMask()) + { + mState.mVertexAttributes[boundAttribute].updateCachedElementLimit( + mState.mVertexBindings[bindingIndex]); + } + } + + if (context->isWebGL()) + { + updateCachedTransformFeedbackBindingValidation(bindingIndex, bufferGL); + } + } + mDirtyObserverBindingBits.reset(); + + onStateChange(angle::SubjectMessage::ContentsChanged); +} + +// This becomes non-current vertex array on the context +void VertexArray::onUnbind(const Context *context) +{ + // This vertex array becoming non-current. For performance reason, if there are too many + // observers in the buffer, we remove it from the buffers' observer list so that the cost of + // buffer sending signal to observers will be too expensive. + for (uint32_t bindingIndex = 0; bindingIndex < mArrayBufferObserverBindings.size(); + ++bindingIndex) + { + const gl::VertexBinding &binding = mState.getVertexBindings()[bindingIndex]; + gl::Buffer *bufferGL = binding.getBuffer().get(); + if (bufferGL && bufferGL->getObserversCount() > kMaxObserverCountToTriggerUnobserve) + { + bufferGL->removeObserver(&mArrayBufferObserverBindings[bindingIndex]); + mDirtyObserverBindingBits.set(bindingIndex); + } + } +} + +void VertexArray::onBindingChanged(const Context *context, int incr) +{ + // When vertex array gets unbound, we remove it from bound buffers' observer list so that when + // buffer changes, it wont has to loop over all these non-current vertex arrays and set dirty + // bit on them. To compensate for that, when we bind a vertex array, we have to check against + // each bound buffers and see if they have changed and needs to update vertex array's dirty bits + // accordingly + ASSERT(incr == 1 || incr == -1); + if (incr < 0) + { + onUnbind(context); + } + else + { + onBind(context); + } + + if (context->isWebGL()) + { + if (mState.mElementArrayBuffer.get()) + mState.mElementArrayBuffer->onNonTFBindingChanged(incr); + for (auto &binding : mState.mVertexBindings) + { + binding.onContainerBindingChanged(context, incr); + } + } +} + +VertexArray::DirtyBitType VertexArray::getDirtyBitFromIndex(bool contentsChanged, + angle::SubjectIndex index) const +{ + if (IsElementArrayBufferSubjectIndex(index)) + { + mIndexRangeCache.invalidate(); + return contentsChanged ? DIRTY_BIT_ELEMENT_ARRAY_BUFFER_DATA + : DIRTY_BIT_ELEMENT_ARRAY_BUFFER; + } + else + { + // Note: this currently just gets the top-level dirty bit. + ASSERT(index < mArrayBufferObserverBindings.size()); + return static_cast( + (contentsChanged ? DIRTY_BIT_BUFFER_DATA_0 : DIRTY_BIT_BINDING_0) + index); + } +} + +void VertexArray::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) +{ + switch (message) + { + case angle::SubjectMessage::SubjectChanged: + if (!IsElementArrayBufferSubjectIndex(index)) + { + updateCachedBufferBindingSize(&mState.mVertexBindings[index]); + } + setDependentDirtyBit(false, index); + break; + + case angle::SubjectMessage::BindingChanged: + if (!IsElementArrayBufferSubjectIndex(index)) + { + const Buffer *buffer = mState.mVertexBindings[index].getBuffer().get(); + updateCachedTransformFeedbackBindingValidation(index, buffer); + } + break; + + case angle::SubjectMessage::SubjectMapped: + if (!IsElementArrayBufferSubjectIndex(index)) + { + updateCachedMappedArrayBuffersBinding(mState.mVertexBindings[index]); + } + onStateChange(angle::SubjectMessage::SubjectMapped); + break; + + case angle::SubjectMessage::SubjectUnmapped: + setDependentDirtyBit(true, index); + + if (!IsElementArrayBufferSubjectIndex(index)) + { + updateCachedMappedArrayBuffersBinding(mState.mVertexBindings[index]); + } + onStateChange(angle::SubjectMessage::SubjectUnmapped); + break; + + case angle::SubjectMessage::InternalMemoryAllocationChanged: + setDependentDirtyBit(false, index); + break; + + default: + UNREACHABLE(); + break; + } +} + +void VertexArray::setDependentDirtyBit(bool contentsChanged, angle::SubjectIndex index) +{ + DirtyBitType dirtyBit = getDirtyBitFromIndex(contentsChanged, index); + ASSERT(!mDirtyBitsGuard.valid() || mDirtyBitsGuard.value().test(dirtyBit)); + mDirtyBits.set(dirtyBit); + onStateChange(angle::SubjectMessage::ContentsChanged); +} + +bool VertexArray::hasTransformFeedbackBindingConflict(const gl::Context *context) const +{ + // Fast check first. + if (!mCachedTransformFeedbackConflictedBindingsMask.any()) + { + return false; + } + + const AttributesMask &activeAttribues = context->getStateCache().getActiveBufferedAttribsMask(); + + // Slow check. We must ensure that the conflicting attributes are enabled/active. + for (size_t attribIndex : activeAttribues) + { + const VertexAttribute &attrib = mState.mVertexAttributes[attribIndex]; + if (mCachedTransformFeedbackConflictedBindingsMask[attrib.bindingIndex]) + { + return true; + } + } + + return false; +} + +angle::Result VertexArray::getIndexRangeImpl(const Context *context, + DrawElementsType type, + GLsizei indexCount, + const void *indices, + IndexRange *indexRangeOut) const +{ + Buffer *elementArrayBuffer = mState.mElementArrayBuffer.get(); + if (!elementArrayBuffer) + { + *indexRangeOut = ComputeIndexRange(type, indices, indexCount, + context->getState().isPrimitiveRestartEnabled()); + return angle::Result::Continue; + } + + size_t offset = reinterpret_cast(indices); + ANGLE_TRY(elementArrayBuffer->getIndexRange(context, type, offset, indexCount, + context->getState().isPrimitiveRestartEnabled(), + indexRangeOut)); + + mIndexRangeCache.put(type, indexCount, offset, *indexRangeOut); + return angle::Result::Continue; +} + +VertexArray::IndexRangeCache::IndexRangeCache() = default; + +void VertexArray::IndexRangeCache::put(DrawElementsType type, + GLsizei indexCount, + size_t offset, + const IndexRange &indexRange) +{ + ASSERT(type != DrawElementsType::InvalidEnum); + + mTypeKey = type; + mIndexCountKey = indexCount; + mOffsetKey = offset; + mPayload = indexRange; +} + +void VertexArray::onBufferContentsChange(uint32_t bufferIndex) +{ + setDependentDirtyBit(true, bufferIndex); +} + +VertexArrayBufferContentsObservers::VertexArrayBufferContentsObservers(VertexArray *vertexArray) + : mVertexArray(vertexArray) +{} + +void VertexArrayBufferContentsObservers::enableForBuffer(Buffer *buffer, uint32_t bufferIndex) +{ + buffer->addContentsObserver(mVertexArray, bufferIndex); +} + +void VertexArrayBufferContentsObservers::disableForBuffer(Buffer *buffer, uint32_t bufferIndex) +{ + buffer->removeContentsObserver(mVertexArray, bufferIndex); +} +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/VertexArray.h b/gfx/angle/checkout/src/libANGLE/VertexArray.h new file mode 100644 index 0000000000..16f036c86b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/VertexArray.h @@ -0,0 +1,436 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// This class contains prototypes for representing GLES 3 Vertex Array Objects: +// +// The buffer objects that are to be used by the vertex stage of the GL are collected +// together to form a vertex array object. All state related to the definition of data used +// by the vertex processor is encapsulated in a vertex array object. +// + +#ifndef LIBANGLE_VERTEXARRAY_H_ +#define LIBANGLE_VERTEXARRAY_H_ + +#include "common/Optional.h" +#include "libANGLE/Constants.h" +#include "libANGLE/Debug.h" +#include "libANGLE/Observer.h" +#include "libANGLE/RefCountObject.h" +#include "libANGLE/VertexAttribute.h" + +#include + +namespace rx +{ +class GLImplFactory; +class VertexArrayImpl; +} // namespace rx + +namespace gl +{ +class Buffer; + +constexpr uint32_t kElementArrayBufferIndex = MAX_VERTEX_ATTRIBS; + +class VertexArrayState final : angle::NonCopyable +{ + public: + VertexArrayState(VertexArray *vertexArray, size_t maxAttribs, size_t maxBindings); + ~VertexArrayState(); + + const std::string &getLabel() const { return mLabel; } + + Buffer *getElementArrayBuffer() const { return mElementArrayBuffer.get(); } + size_t getMaxAttribs() const { return mVertexAttributes.size(); } + size_t getMaxBindings() const { return mVertexBindings.size(); } + const AttributesMask &getEnabledAttributesMask() const { return mEnabledAttributesMask; } + const std::vector &getVertexAttributes() const { return mVertexAttributes; } + const VertexAttribute &getVertexAttribute(size_t attribIndex) const + { + return mVertexAttributes[attribIndex]; + } + const std::vector &getVertexBindings() const { return mVertexBindings; } + const VertexBinding &getVertexBinding(size_t bindingIndex) const + { + return mVertexBindings[bindingIndex]; + } + const VertexBinding &getBindingFromAttribIndex(size_t attribIndex) const + { + return mVertexBindings[mVertexAttributes[attribIndex].bindingIndex]; + } + size_t getBindingIndexFromAttribIndex(size_t attribIndex) const + { + return mVertexAttributes[attribIndex].bindingIndex; + } + + void setAttribBinding(const Context *context, size_t attribIndex, GLuint newBindingIndex); + + // Extra validation performed on the Vertex Array. + bool hasEnabledNullPointerClientArray() const; + + // Get all the attributes in an AttributesMask that are using the given binding. + AttributesMask getBindingToAttributesMask(GLuint bindingIndex) const; + + ComponentTypeMask getVertexAttributesTypeMask() const { return mVertexAttributesTypeMask; } + + AttributesMask getClientMemoryAttribsMask() const { return mClientMemoryAttribsMask; } + + gl::AttributesMask getNullPointerClientMemoryAttribsMask() const + { + return mNullPointerClientMemoryAttribsMask; + } + + private: + void updateCachedMutableOrNonPersistentArrayBuffers(size_t index); + + friend class VertexArray; + std::string mLabel; + std::vector mVertexAttributes; + SubjectBindingPointer mElementArrayBuffer; + std::vector mVertexBindings; + AttributesMask mEnabledAttributesMask; + ComponentTypeMask mVertexAttributesTypeMask; + AttributesMask mLastSyncedEnabledAttributesMask; + + // This is a performance optimization for buffer binding. Allows element array buffer updates. + friend class State; + + // From the GLES 3.1 spec: + // When a generic attribute array is sourced from client memory, the vertex attribute binding + // state is ignored. Thus we don't have to worry about binding state when using client memory + // attribs. + gl::AttributesMask mClientMemoryAttribsMask; + gl::AttributesMask mNullPointerClientMemoryAttribsMask; + + // Used for validation cache. Indexed by attribute. + AttributesMask mCachedMappedArrayBuffers; + AttributesMask mCachedMutableOrImpersistentArrayBuffers; + AttributesMask mCachedInvalidMappedArrayBuffer; +}; + +class VertexArrayBufferContentsObservers final : angle::NonCopyable +{ + public: + VertexArrayBufferContentsObservers(VertexArray *vertexArray); + void enableForBuffer(Buffer *buffer, uint32_t bufferIndex); + void disableForBuffer(Buffer *buffer, uint32_t bufferIndex); + + private: + VertexArray *mVertexArray; +}; + +class VertexArray final : public angle::ObserverInterface, + public LabeledObject, + public angle::Subject +{ + public: + // Dirty bits for VertexArrays use a hierarchical design. At the top level, each attribute + // has a single dirty bit. Then an array of MAX_ATTRIBS dirty bits each has a dirty bit for + // enabled/pointer/format/binding. Bindings are handled similarly. Note that because the + // total number of dirty bits is 33, it will not be as fast on a 32-bit machine, which + // can't support the advanced 64-bit scanning intrinsics. We could consider packing the + // binding and attribute bits together if this becomes a problem. + // + // Special note on "DIRTY_ATTRIB_POINTER_BUFFER": this is a special case when the app + // calls glVertexAttribPointer but only changes a VBO and/or offset binding. This allows + // the Vulkan back-end to skip performing a pipeline change for performance. + enum DirtyBitType + { + DIRTY_BIT_ELEMENT_ARRAY_BUFFER, + DIRTY_BIT_ELEMENT_ARRAY_BUFFER_DATA, + + // Dirty bits for bindings. + DIRTY_BIT_BINDING_0, + DIRTY_BIT_BINDING_MAX = DIRTY_BIT_BINDING_0 + gl::MAX_VERTEX_ATTRIB_BINDINGS, + + // We keep separate dirty bits for bound buffers whose data changed since last update. + DIRTY_BIT_BUFFER_DATA_0 = DIRTY_BIT_BINDING_MAX, + DIRTY_BIT_BUFFER_DATA_MAX = DIRTY_BIT_BUFFER_DATA_0 + gl::MAX_VERTEX_ATTRIB_BINDINGS, + + // Dirty bits for attributes. + DIRTY_BIT_ATTRIB_0 = DIRTY_BIT_BUFFER_DATA_MAX, + DIRTY_BIT_ATTRIB_MAX = DIRTY_BIT_ATTRIB_0 + gl::MAX_VERTEX_ATTRIBS, + + DIRTY_BIT_UNKNOWN = DIRTY_BIT_ATTRIB_MAX, + DIRTY_BIT_MAX = DIRTY_BIT_UNKNOWN, + }; + + // We want to keep the number of dirty bits within 64 to keep iteration times fast. + static_assert(DIRTY_BIT_MAX <= 64, "Too many vertex array dirty bits."); + // The dirty bit processing has the logic to avoid redundant processing by removing other dirty + // bits when it processes dirtyBits. This assertion ensures these dirty bit order matches what + // VertexArrayVk::syncState expects. + static_assert(DIRTY_BIT_BINDING_0 < DIRTY_BIT_BUFFER_DATA_0, + "BINDING dity bits should come before DATA."); + static_assert(DIRTY_BIT_BUFFER_DATA_0 < DIRTY_BIT_ATTRIB_0, + "DATA dity bits should come before ATTRIB."); + + enum DirtyAttribBitType + { + DIRTY_ATTRIB_ENABLED, + DIRTY_ATTRIB_POINTER, + DIRTY_ATTRIB_FORMAT, + DIRTY_ATTRIB_BINDING, + DIRTY_ATTRIB_POINTER_BUFFER, + DIRTY_ATTRIB_UNKNOWN, + DIRTY_ATTRIB_MAX = DIRTY_ATTRIB_UNKNOWN, + }; + + enum DirtyBindingBitType + { + DIRTY_BINDING_BUFFER, + DIRTY_BINDING_DIVISOR, + DIRTY_BINDING_UNKNOWN, + DIRTY_BINDING_MAX = DIRTY_BINDING_UNKNOWN, + }; + + using DirtyBits = angle::BitSet; + using DirtyAttribBits = angle::BitSet; + using DirtyBindingBits = angle::BitSet; + using DirtyAttribBitsArray = std::array; + using DirtyBindingBitsArray = std::array; + using DirtyObserverBindingBits = angle::BitSet; + + VertexArray(rx::GLImplFactory *factory, + VertexArrayID id, + size_t maxAttribs, + size_t maxAttribBindings); + + void onDestroy(const Context *context); + + VertexArrayID id() const { return mId; } + + angle::Result setLabel(const Context *context, const std::string &label) override; + const std::string &getLabel() const override; + + const VertexBinding &getVertexBinding(size_t bindingIndex) const; + const VertexAttribute &getVertexAttribute(size_t attribIndex) const; + const VertexBinding &getBindingFromAttribIndex(size_t attribIndex) const + { + return mState.getBindingFromAttribIndex(attribIndex); + } + + // Returns true if the function finds and detaches a bound buffer. + bool detachBuffer(const Context *context, BufferID bufferID); + + void setVertexAttribDivisor(const Context *context, size_t index, GLuint divisor); + void enableAttribute(size_t attribIndex, bool enabledState); + + void setVertexAttribPointer(const Context *context, + size_t attribIndex, + Buffer *boundBuffer, + GLint size, + VertexAttribType type, + bool normalized, + GLsizei stride, + const void *pointer); + + void setVertexAttribIPointer(const Context *context, + size_t attribIndex, + Buffer *boundBuffer, + GLint size, + VertexAttribType type, + GLsizei stride, + const void *pointer); + + void setVertexAttribFormat(size_t attribIndex, + GLint size, + VertexAttribType type, + bool normalized, + bool pureInteger, + GLuint relativeOffset); + void bindVertexBuffer(const Context *context, + size_t bindingIndex, + Buffer *boundBuffer, + GLintptr offset, + GLsizei stride); + void setVertexAttribBinding(const Context *context, size_t attribIndex, GLuint bindingIndex); + void setVertexBindingDivisor(const Context *context, size_t bindingIndex, GLuint divisor); + + Buffer *getElementArrayBuffer() const { return mState.getElementArrayBuffer(); } + size_t getMaxAttribs() const { return mState.getMaxAttribs(); } + size_t getMaxBindings() const { return mState.getMaxBindings(); } + + const std::vector &getVertexAttributes() const + { + return mState.getVertexAttributes(); + } + const std::vector &getVertexBindings() const + { + return mState.getVertexBindings(); + } + + rx::VertexArrayImpl *getImplementation() const { return mVertexArray; } + + const AttributesMask &getEnabledAttributesMask() const + { + return mState.getEnabledAttributesMask(); + } + + gl::AttributesMask getClientAttribsMask() const { return mState.mClientMemoryAttribsMask; } + + bool hasEnabledNullPointerClientArray() const + { + return mState.hasEnabledNullPointerClientArray(); + } + + bool hasInvalidMappedArrayBuffer() const + { + return mState.mCachedInvalidMappedArrayBuffer.any(); + } + + const VertexArrayState &getState() const { return mState; } + + bool isBufferAccessValidationEnabled() const { return mBufferAccessValidationEnabled; } + + // Observer implementation + void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; + void onBufferContentsChange(uint32_t bufferIndex); + + static size_t GetVertexIndexFromDirtyBit(size_t dirtyBit); + + angle::Result syncState(const Context *context); + bool hasAnyDirtyBit() const { return mDirtyBits.any(); } + + ComponentTypeMask getAttributesTypeMask() const { return mState.mVertexAttributesTypeMask; } + AttributesMask getAttributesMask() const { return mState.mEnabledAttributesMask; } + + void onBindingChanged(const Context *context, int incr); + bool hasTransformFeedbackBindingConflict(const gl::Context *context) const; + + ANGLE_INLINE angle::Result getIndexRange(const Context *context, + DrawElementsType type, + GLsizei indexCount, + const void *indices, + IndexRange *indexRangeOut) const + { + Buffer *elementArrayBuffer = mState.mElementArrayBuffer.get(); + if (elementArrayBuffer && mIndexRangeCache.get(type, indexCount, indices, indexRangeOut)) + { + return angle::Result::Continue; + } + + return getIndexRangeImpl(context, type, indexCount, indices, indexRangeOut); + } + + void setBufferAccessValidationEnabled(bool enabled) + { + mBufferAccessValidationEnabled = enabled; + } + + private: + ~VertexArray() override; + + // This is a performance optimization for buffer binding. Allows element array buffer updates. + friend class State; + + void setDirtyAttribBit(size_t attribIndex, DirtyAttribBitType dirtyAttribBit); + void setDirtyBindingBit(size_t bindingIndex, DirtyBindingBitType dirtyBindingBit); + void clearDirtyAttribBit(size_t attribIndex, DirtyAttribBitType dirtyAttribBit); + + DirtyBitType getDirtyBitFromIndex(bool contentsChanged, angle::SubjectIndex index) const; + void setDependentDirtyBit(bool contentsChanged, angle::SubjectIndex index); + + // These are used to optimize draw call validation. + void updateCachedBufferBindingSize(VertexBinding *binding); + void updateCachedTransformFeedbackBindingValidation(size_t bindingIndex, const Buffer *buffer); + void updateCachedArrayBuffersMasks(bool isMapped, + bool isImmutable, + bool isPersistent, + const AttributesMask &boundAttributesMask); + void updateCachedMappedArrayBuffersBinding(const VertexBinding &binding); + + angle::Result getIndexRangeImpl(const Context *context, + DrawElementsType type, + GLsizei indexCount, + const void *indices, + IndexRange *indexRangeOut) const; + + void setVertexAttribPointerImpl(const Context *context, + ComponentType componentType, + bool pureInteger, + size_t attribIndex, + Buffer *boundBuffer, + GLint size, + VertexAttribType type, + bool normalized, + GLsizei stride, + const void *pointer); + + // These two functions return true if the state was dirty. + bool setVertexAttribFormatImpl(VertexAttribute *attrib, + GLint size, + VertexAttribType type, + bool normalized, + bool pureInteger, + GLuint relativeOffset); + bool bindVertexBufferImpl(const Context *context, + size_t bindingIndex, + Buffer *boundBuffer, + GLintptr offset, + GLsizei stride); + + void onBind(const Context *context); + void onUnbind(const Context *context); + + VertexArrayID mId; + + VertexArrayState mState; + DirtyBits mDirtyBits; + DirtyAttribBitsArray mDirtyAttribBits; + DirtyBindingBitsArray mDirtyBindingBits; + Optional mDirtyBitsGuard; + + rx::VertexArrayImpl *mVertexArray; + + std::vector mArrayBufferObserverBindings; + // Track which observer in mArrayBufferObserverBindings is not currently been removed from + // subject's observer list. + DirtyObserverBindingBits mDirtyObserverBindingBits; + + AttributesMask mCachedTransformFeedbackConflictedBindingsMask; + + class IndexRangeCache final : angle::NonCopyable + { + public: + IndexRangeCache(); + + void invalidate() { mTypeKey = DrawElementsType::InvalidEnum; } + + bool get(DrawElementsType type, + GLsizei indexCount, + const void *indices, + IndexRange *indexRangeOut) + { + size_t offset = reinterpret_cast(indices); + if (mTypeKey == type && mIndexCountKey == indexCount && mOffsetKey == offset) + { + *indexRangeOut = mPayload; + return true; + } + + return false; + } + + void put(DrawElementsType type, + GLsizei indexCount, + size_t offset, + const IndexRange &indexRange); + + private: + DrawElementsType mTypeKey; + GLsizei mIndexCountKey; + size_t mOffsetKey; + IndexRange mPayload; + }; + + mutable IndexRangeCache mIndexRangeCache; + bool mBufferAccessValidationEnabled; + VertexArrayBufferContentsObservers mContentsObservers; +}; + +} // namespace gl + +#endif // LIBANGLE_VERTEXARRAY_H_ diff --git a/gfx/angle/checkout/src/libANGLE/VertexAttribute.cpp b/gfx/angle/checkout/src/libANGLE/VertexAttribute.cpp new file mode 100644 index 0000000000..f525addbba --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/VertexAttribute.cpp @@ -0,0 +1,170 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Implementation of the state classes for mananging GLES 3.1 Vertex Array Objects. +// + +#include "libANGLE/VertexAttribute.h" + +namespace gl +{ + +// [OpenGL ES 3.1] (November 3, 2016) Section 20 Page 361 +// Table 20.2: Vertex Array Object State +VertexBinding::VertexBinding() : VertexBinding(0) {} + +VertexBinding::VertexBinding(GLuint boundAttribute) : mStride(16u), mDivisor(0), mOffset(0) +{ + mBoundAttributesMask.set(boundAttribute); +} + +VertexBinding::VertexBinding(VertexBinding &&binding) +{ + *this = std::move(binding); +} + +VertexBinding::~VertexBinding() {} + +VertexBinding &VertexBinding::operator=(VertexBinding &&binding) +{ + if (this != &binding) + { + mStride = binding.mStride; + mDivisor = binding.mDivisor; + mOffset = binding.mOffset; + mBoundAttributesMask = binding.mBoundAttributesMask; + std::swap(binding.mBuffer, mBuffer); + } + return *this; +} + +void VertexBinding::onContainerBindingChanged(const Context *context, int incr) const +{ + if (mBuffer.get()) + mBuffer->onNonTFBindingChanged(incr); +} + +VertexAttribute::VertexAttribute(GLuint bindingIndex) + : enabled(false), + format(&angle::Format::Get(angle::FormatID::R32G32B32A32_FLOAT)), + pointer(nullptr), + relativeOffset(0), + vertexAttribArrayStride(0), + bindingIndex(bindingIndex), + mCachedElementLimit(0) +{} + +VertexAttribute::VertexAttribute(VertexAttribute &&attrib) + : enabled(attrib.enabled), + format(attrib.format), + pointer(attrib.pointer), + relativeOffset(attrib.relativeOffset), + vertexAttribArrayStride(attrib.vertexAttribArrayStride), + bindingIndex(attrib.bindingIndex), + mCachedElementLimit(attrib.mCachedElementLimit) +{} + +VertexAttribute &VertexAttribute::operator=(VertexAttribute &&attrib) +{ + if (this != &attrib) + { + enabled = attrib.enabled; + format = attrib.format; + pointer = attrib.pointer; + relativeOffset = attrib.relativeOffset; + vertexAttribArrayStride = attrib.vertexAttribArrayStride; + bindingIndex = attrib.bindingIndex; + mCachedElementLimit = attrib.mCachedElementLimit; + } + return *this; +} + +void VertexAttribute::updateCachedElementLimit(const VertexBinding &binding) +{ + Buffer *buffer = binding.getBuffer().get(); + if (!buffer) + { + mCachedElementLimit = 0; + return; + } + + angle::CheckedNumeric bufferSize(buffer->getSize()); + angle::CheckedNumeric bufferOffset(binding.getOffset()); + angle::CheckedNumeric attribOffset(relativeOffset); + angle::CheckedNumeric attribSize(ComputeVertexAttributeTypeSize(*this)); + + // (buffer.size - buffer.offset - attrib.relativeOffset - attrib.size) / binding.stride + angle::CheckedNumeric elementLimit = + (bufferSize - bufferOffset - attribOffset - attribSize); + + // Use the special integer overflow value if there was a math error. + if (!elementLimit.IsValid()) + { + static_assert(kIntegerOverflow < 0, "Unexpected value"); + mCachedElementLimit = kIntegerOverflow; + return; + } + + mCachedElementLimit = elementLimit.ValueOrDie(); + if (mCachedElementLimit < 0) + { + return; + } + + if (binding.getStride() == 0) + { + // Special case for a zero stride. If we can fit one vertex we can fit infinite vertices. + mCachedElementLimit = std::numeric_limits::max(); + return; + } + + angle::CheckedNumeric bindingStride(binding.getStride()); + elementLimit /= bindingStride; + + if (binding.getDivisor() > 0) + { + // For instanced draws, the element count is floor(instanceCount - 1) / binding.divisor. + angle::CheckedNumeric bindingDivisor(binding.getDivisor()); + elementLimit *= bindingDivisor; + + // We account for the floor() part rounding by adding a rounding constant. + elementLimit += bindingDivisor - 1; + } + + mCachedElementLimit = elementLimit.ValueOrDefault(kIntegerOverflow); +} + +size_t ComputeVertexAttributeStride(const VertexAttribute &attrib, const VertexBinding &binding) +{ + // In ES 3.1, VertexAttribPointer will store the type size in the binding stride. + // Hence, rendering always uses the binding's stride. + return attrib.enabled ? binding.getStride() : 16u; +} + +// Warning: you should ensure binding really matches attrib.bindingIndex before using this function. +GLintptr ComputeVertexAttributeOffset(const VertexAttribute &attrib, const VertexBinding &binding) +{ + return attrib.relativeOffset + binding.getOffset(); +} + +size_t ComputeVertexBindingElementCount(GLuint divisor, size_t drawCount, size_t instanceCount) +{ + // For instanced rendering, we draw "instanceDrawCount" sets of "vertexDrawCount" vertices. + // + // A vertex attribute with a positive divisor loads one instanced vertex for every set of + // non-instanced vertices, and the instanced vertex index advances once every "mDivisor" + // instances. + if (instanceCount > 0 && divisor > 0) + { + // When instanceDrawCount is not a multiple attrib.divisor, the division must round up. + // For instance, with 5 non-instanced vertices and a divisor equal to 3, we need 2 instanced + // vertices. + return (instanceCount + divisor - 1u) / divisor; + } + + return drawCount; +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/VertexAttribute.h b/gfx/angle/checkout/src/libANGLE/VertexAttribute.h new file mode 100644 index 0000000000..dd89228d2a --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/VertexAttribute.h @@ -0,0 +1,139 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Helper structures about Generic Vertex Attribute. +// + +#ifndef LIBANGLE_VERTEXATTRIBUTE_H_ +#define LIBANGLE_VERTEXATTRIBUTE_H_ + +#include "libANGLE/Buffer.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/renderer/Format.h" + +namespace gl +{ +class VertexArray; + +// +// Implementation of Generic Vertex Attribute Bindings for ES3.1. The members are intentionally made +// private in order to hide implementation details. +// +class VertexBinding final : angle::NonCopyable +{ + public: + VertexBinding(); + explicit VertexBinding(GLuint boundAttribute); + VertexBinding(VertexBinding &&binding); + ~VertexBinding(); + VertexBinding &operator=(VertexBinding &&binding); + + GLuint getStride() const { return mStride; } + void setStride(GLuint strideIn) { mStride = strideIn; } + + GLuint getDivisor() const { return mDivisor; } + void setDivisor(GLuint divisorIn) { mDivisor = divisorIn; } + + GLintptr getOffset() const { return mOffset; } + void setOffset(GLintptr offsetIn) { mOffset = offsetIn; } + + const BindingPointer &getBuffer() const { return mBuffer; } + + ANGLE_INLINE void setBuffer(const gl::Context *context, Buffer *bufferIn) + { + mBuffer.set(context, bufferIn); + } + + // Skips ref counting for better inlined performance. + ANGLE_INLINE void assignBuffer(Buffer *bufferIn) { mBuffer.assign(bufferIn); } + + void onContainerBindingChanged(const Context *context, int incr) const; + + const AttributesMask &getBoundAttributesMask() const { return mBoundAttributesMask; } + + void setBoundAttribute(size_t index) { mBoundAttributesMask.set(index); } + + void resetBoundAttribute(size_t index) { mBoundAttributesMask.reset(index); } + + private: + GLuint mStride; + GLuint mDivisor; + GLintptr mOffset; + + BindingPointer mBuffer; + + // Mapping from this binding to all of the attributes that are using this binding. + AttributesMask mBoundAttributesMask; +}; + +// +// Implementation of Generic Vertex Attributes for ES3.1 +// +struct VertexAttribute final : private angle::NonCopyable +{ + explicit VertexAttribute(GLuint bindingIndex); + VertexAttribute(VertexAttribute &&attrib); + VertexAttribute &operator=(VertexAttribute &&attrib); + + // Called from VertexArray. + void updateCachedElementLimit(const VertexBinding &binding); + GLint64 getCachedElementLimit() const { return mCachedElementLimit; } + + bool enabled; // For glEnable/DisableVertexAttribArray + const angle::Format *format; + + const void *pointer; + GLuint relativeOffset; + + GLuint vertexAttribArrayStride; // ONLY for queries of VERTEX_ATTRIB_ARRAY_STRIDE + GLuint bindingIndex; + + // Special value for the cached element limit on the integer overflow case. + static constexpr GLint64 kIntegerOverflow = std::numeric_limits::min(); + + private: + // This is kept in sync by the VertexArray. It is used to optimize draw call validation. + GLint64 mCachedElementLimit; +}; + +ANGLE_INLINE size_t ComputeVertexAttributeTypeSize(const VertexAttribute &attrib) +{ + ASSERT(attrib.format); + return attrib.format->pixelBytes; +} + +// Warning: you should ensure binding really matches attrib.bindingIndex before using this function. +size_t ComputeVertexAttributeStride(const VertexAttribute &attrib, const VertexBinding &binding); + +// Warning: you should ensure binding really matches attrib.bindingIndex before using this function. +GLintptr ComputeVertexAttributeOffset(const VertexAttribute &attrib, const VertexBinding &binding); + +size_t ComputeVertexBindingElementCount(GLuint divisor, size_t drawCount, size_t instanceCount); + +struct VertexAttribCurrentValueData +{ + union + { + GLfloat FloatValues[4]; + GLint IntValues[4]; + GLuint UnsignedIntValues[4]; + } Values; + VertexAttribType Type; + + VertexAttribCurrentValueData(); + + void setFloatValues(const GLfloat floatValues[4]); + void setIntValues(const GLint intValues[4]); + void setUnsignedIntValues(const GLuint unsignedIntValues[4]); +}; + +bool operator==(const VertexAttribCurrentValueData &a, const VertexAttribCurrentValueData &b); +bool operator!=(const VertexAttribCurrentValueData &a, const VertexAttribCurrentValueData &b); + +} // namespace gl + +#include "VertexAttribute.inc" + +#endif // LIBANGLE_VERTEXATTRIBUTE_H_ diff --git a/gfx/angle/checkout/src/libANGLE/VertexAttribute.inc b/gfx/angle/checkout/src/libANGLE/VertexAttribute.inc new file mode 100644 index 0000000000..0c98f091b9 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/VertexAttribute.inc @@ -0,0 +1,58 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// VertexAttribute.inc: Inline vertex attribute methods +// + +namespace gl +{ + +inline VertexAttribCurrentValueData::VertexAttribCurrentValueData() + : Type(gl::VertexAttribType::Float) +{ + Values.FloatValues[0] = 0.0f; + Values.FloatValues[1] = 0.0f; + Values.FloatValues[2] = 0.0f; + Values.FloatValues[3] = 1.0f; +} + +inline void VertexAttribCurrentValueData::setFloatValues(const GLfloat floatValues[4]) +{ + for (unsigned int valueIndex = 0; valueIndex < 4; valueIndex++) + { + Values.FloatValues[valueIndex] = floatValues[valueIndex]; + } + Type = gl::VertexAttribType::Float; +} + +inline void VertexAttribCurrentValueData::setIntValues(const GLint intValues[4]) +{ + for (unsigned int valueIndex = 0; valueIndex < 4; valueIndex++) + { + Values.IntValues[valueIndex] = intValues[valueIndex]; + } + Type = gl::VertexAttribType::Int; +} + +inline void VertexAttribCurrentValueData::setUnsignedIntValues(const GLuint unsignedIntValues[4]) +{ + for (unsigned int valueIndex = 0; valueIndex < 4; valueIndex++) + { + Values.UnsignedIntValues[valueIndex] = unsignedIntValues[valueIndex]; + } + Type = gl::VertexAttribType::UnsignedInt; +} + +inline bool operator==(const VertexAttribCurrentValueData &a, const VertexAttribCurrentValueData &b) +{ + return (a.Type == b.Type && memcmp(&a.Values, &b.Values, sizeof(VertexAttribCurrentValueData::Values)) == 0); +} + +inline bool operator!=(const VertexAttribCurrentValueData &a, const VertexAttribCurrentValueData &b) +{ + return !(a == b); +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/WorkerThread.cpp b/gfx/angle/checkout/src/libANGLE/WorkerThread.cpp new file mode 100644 index 0000000000..30c454dd26 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/WorkerThread.cpp @@ -0,0 +1,356 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// WorkerThread: +// Task running thread for ANGLE, similar to a TaskRunner in Chromium. +// Might be implemented differently depending on platform. +// + +#include "libANGLE/WorkerThread.h" + +#include "libANGLE/trace.h" + +#if (ANGLE_DELEGATE_WORKERS == ANGLE_ENABLED) || (ANGLE_STD_ASYNC_WORKERS == ANGLE_ENABLED) +# include +# include +# include +# include +# include +#endif // (ANGLE_DELEGATE_WORKERS == ANGLE_ENABLED) || (ANGLE_STD_ASYNC_WORKERS == ANGLE_ENABLED) + +namespace angle +{ + +WaitableEvent::WaitableEvent() = default; +WaitableEvent::~WaitableEvent() = default; + +void WaitableEventDone::wait() {} + +bool WaitableEventDone::isReady() +{ + return true; +} + +WorkerThreadPool::WorkerThreadPool() = default; +WorkerThreadPool::~WorkerThreadPool() = default; + +class SingleThreadedWaitableEvent final : public WaitableEvent +{ + public: + SingleThreadedWaitableEvent() = default; + ~SingleThreadedWaitableEvent() override = default; + + void wait() override; + bool isReady() override; +}; + +void SingleThreadedWaitableEvent::wait() {} + +bool SingleThreadedWaitableEvent::isReady() +{ + return true; +} + +class SingleThreadedWorkerPool final : public WorkerThreadPool +{ + public: + std::shared_ptr postWorkerTask(std::shared_ptr task) override; + void setMaxThreads(size_t maxThreads) override; + bool isAsync() override; +}; + +// SingleThreadedWorkerPool implementation. +std::shared_ptr SingleThreadedWorkerPool::postWorkerTask( + std::shared_ptr task) +{ + (*task)(); + return std::make_shared(); +} + +void SingleThreadedWorkerPool::setMaxThreads(size_t maxThreads) {} + +bool SingleThreadedWorkerPool::isAsync() +{ + return false; +} + +#if (ANGLE_STD_ASYNC_WORKERS == ANGLE_ENABLED) +class AsyncWaitableEvent final : public WaitableEvent +{ + public: + AsyncWaitableEvent() : mIsPending(true) {} + ~AsyncWaitableEvent() override = default; + + void wait() override; + bool isReady() override; + + private: + friend class AsyncWorkerPool; + void setFuture(std::future &&future); + + // To block wait() when the task is still in queue to be run. + // Also to protect the concurrent accesses from both main thread and + // background threads to the member fields. + std::mutex mMutex; + + bool mIsPending; + std::condition_variable mCondition; + std::future mFuture; +}; + +void AsyncWaitableEvent::setFuture(std::future &&future) +{ + mFuture = std::move(future); +} + +void AsyncWaitableEvent::wait() +{ + ANGLE_TRACE_EVENT0("gpu.angle", "AsyncWaitableEvent::wait"); + { + std::unique_lock lock(mMutex); + mCondition.wait(lock, [this] { return !mIsPending; }); + } + + ASSERT(mFuture.valid()); + mFuture.wait(); +} + +bool AsyncWaitableEvent::isReady() +{ + std::lock_guard lock(mMutex); + if (mIsPending) + { + return false; + } + ASSERT(mFuture.valid()); + return mFuture.wait_for(std::chrono::seconds(0)) == std::future_status::ready; +} + +class AsyncWorkerPool final : public WorkerThreadPool +{ + public: + AsyncWorkerPool(size_t maxThreads) : mMaxThreads(maxThreads), mRunningThreads(0) {} + ~AsyncWorkerPool() override = default; + + std::shared_ptr postWorkerTask(std::shared_ptr task) override; + void setMaxThreads(size_t maxThreads) override; + bool isAsync() override; + + private: + void checkToRunPendingTasks(); + + // To protect the concurrent accesses from both main thread and background + // threads to the member fields. + std::mutex mMutex; + + size_t mMaxThreads; + size_t mRunningThreads; + std::queue, std::shared_ptr>> mTaskQueue; +}; + +// AsyncWorkerPool implementation. +std::shared_ptr AsyncWorkerPool::postWorkerTask(std::shared_ptr task) +{ + ASSERT(mMaxThreads > 0); + + auto waitable = std::make_shared(); + { + std::lock_guard lock(mMutex); + mTaskQueue.push(std::make_pair(waitable, task)); + } + checkToRunPendingTasks(); + return std::move(waitable); +} + +void AsyncWorkerPool::setMaxThreads(size_t maxThreads) +{ + { + std::lock_guard lock(mMutex); + mMaxThreads = (maxThreads == 0xFFFFFFFF ? std::thread::hardware_concurrency() : maxThreads); + } + checkToRunPendingTasks(); +} + +bool AsyncWorkerPool::isAsync() +{ + return true; +} + +void AsyncWorkerPool::checkToRunPendingTasks() +{ + std::lock_guard lock(mMutex); + while (mRunningThreads < mMaxThreads && !mTaskQueue.empty()) + { + auto task = mTaskQueue.front(); + mTaskQueue.pop(); + auto waitable = task.first; + auto closure = task.second; + + auto future = std::async(std::launch::async, [closure, this] { + { + ANGLE_TRACE_EVENT0("gpu.angle", "AsyncWorkerPool::RunTask"); + (*closure)(); + } + { + std::lock_guard lock(mMutex); + ASSERT(mRunningThreads != 0); + --mRunningThreads; + } + checkToRunPendingTasks(); + }); + + ++mRunningThreads; + + { + std::lock_guard waitableLock(waitable->mMutex); + waitable->mIsPending = false; + waitable->setFuture(std::move(future)); + } + waitable->mCondition.notify_all(); + } +} +#endif // (ANGLE_STD_ASYNC_WORKERS == ANGLE_ENABLED) + +#if (ANGLE_DELEGATE_WORKERS == ANGLE_ENABLED) +class DelegateWaitableEvent final : public WaitableEvent +{ + public: + DelegateWaitableEvent() = default; + ~DelegateWaitableEvent() override = default; + + void wait() override; + bool isReady() override; + + void markAsReady(); + + private: + // To protect the concurrent accesses from both main thread and background + // threads to the member fields. + std::mutex mMutex; + + bool mIsReady = false; + std::condition_variable mCondition; +}; + +void DelegateWaitableEvent::markAsReady() +{ + std::lock_guard lock(mMutex); + mIsReady = true; + mCondition.notify_all(); +} + +void DelegateWaitableEvent::wait() +{ + std::unique_lock lock(mMutex); + mCondition.wait(lock, [this] { return mIsReady; }); +} + +bool DelegateWaitableEvent::isReady() +{ + std::lock_guard lock(mMutex); + return mIsReady; +} + +class DelegateWorkerPool final : public WorkerThreadPool +{ + public: + DelegateWorkerPool() = default; + ~DelegateWorkerPool() override = default; + + std::shared_ptr postWorkerTask(std::shared_ptr task) override; + + void setMaxThreads(size_t maxThreads) override; + bool isAsync() override; +}; + +// A function wrapper to execute the closure and to notify the waitable +// event after the execution. +class DelegateWorkerTask +{ + public: + DelegateWorkerTask(std::shared_ptr task, + std::shared_ptr waitable) + : mTask(task), mWaitable(waitable) + {} + DelegateWorkerTask() = delete; + DelegateWorkerTask(DelegateWorkerTask &) = delete; + + static void RunTask(void *userData) + { + DelegateWorkerTask *workerTask = static_cast(userData); + (*workerTask->mTask)(); + workerTask->mWaitable->markAsReady(); + + // Delete the task after its execution. + delete workerTask; + } + + private: + ~DelegateWorkerTask() = default; + + std::shared_ptr mTask; + std::shared_ptr mWaitable; +}; + +std::shared_ptr DelegateWorkerPool::postWorkerTask(std::shared_ptr task) +{ + auto waitable = std::make_shared(); + + // The task will be deleted by DelegateWorkerTask::RunTask(...) after its execution. + DelegateWorkerTask *workerTask = new DelegateWorkerTask(task, waitable); + auto *platform = ANGLEPlatformCurrent(); + platform->postWorkerTask(platform, DelegateWorkerTask::RunTask, workerTask); + + return std::move(waitable); +} + +void DelegateWorkerPool::setMaxThreads(size_t maxThreads) {} + +bool DelegateWorkerPool::isAsync() +{ + return true; +} +#endif + +// static +std::shared_ptr WorkerThreadPool::Create(bool multithreaded) +{ + std::shared_ptr pool(nullptr); + +#if (ANGLE_DELEGATE_WORKERS == ANGLE_ENABLED) + const bool hasPostWorkerTaskImpl = ANGLEPlatformCurrent()->postWorkerTask; + if (hasPostWorkerTaskImpl && multithreaded) + { + pool = std::shared_ptr(new DelegateWorkerPool()); + } +#endif +#if (ANGLE_STD_ASYNC_WORKERS == ANGLE_ENABLED) + if (!pool && multithreaded) + { + pool = std::shared_ptr( + new AsyncWorkerPool(std::thread::hardware_concurrency())); + } +#endif + if (!pool) + { + return std::shared_ptr(new SingleThreadedWorkerPool()); + } + return pool; +} + +// static +std::shared_ptr WorkerThreadPool::PostWorkerTask( + std::shared_ptr pool, + std::shared_ptr task) +{ + std::shared_ptr event = pool->postWorkerTask(task); + if (event.get()) + { + event->setWorkerThreadPool(pool); + } + return event; +} + +} // namespace angle diff --git a/gfx/angle/checkout/src/libANGLE/WorkerThread.h b/gfx/angle/checkout/src/libANGLE/WorkerThread.h new file mode 100644 index 0000000000..6ef94fcc5b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/WorkerThread.h @@ -0,0 +1,94 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// WorkerThread: +// Asychronous tasks/threads for ANGLE, similar to a TaskRunner in Chromium. +// Can be implemented as different targets, depending on platform. +// + +#ifndef LIBANGLE_WORKER_THREAD_H_ +#define LIBANGLE_WORKER_THREAD_H_ + +#include +#include +#include + +#include "common/debug.h" +#include "libANGLE/features.h" + +namespace angle +{ + +class WorkerThreadPool; + +// A callback function with no return value and no arguments. +class Closure +{ + public: + virtual ~Closure() = default; + virtual void operator()() = 0; +}; + +// An event that we can wait on, useful for joining worker threads. +class WaitableEvent : angle::NonCopyable +{ + public: + WaitableEvent(); + virtual ~WaitableEvent(); + + // Waits indefinitely for the event to be signaled. + virtual void wait() = 0; + + // Peeks whether the event is ready. If ready, wait() will not block. + virtual bool isReady() = 0; + void setWorkerThreadPool(std::shared_ptr pool) { mPool = pool; } + + template + static void WaitMany(std::array, Count> *waitables) + { + ASSERT(Count > 0); + for (size_t index = 0; index < Count; ++index) + { + (*waitables)[index]->wait(); + } + } + + private: + std::shared_ptr mPool; +}; + +// A mock waitable event. +class WaitableEventDone final : public WaitableEvent +{ + public: + void wait() override; + bool isReady() override; +}; + +// Request WorkerThreads from the WorkerThreadPool. Each pool can keep worker threads around so +// we avoid the costly spin up and spin down time. +class WorkerThreadPool : angle::NonCopyable +{ + public: + WorkerThreadPool(); + virtual ~WorkerThreadPool(); + + static std::shared_ptr Create(bool multithreaded); + static std::shared_ptr PostWorkerTask(std::shared_ptr pool, + std::shared_ptr task); + + virtual void setMaxThreads(size_t maxThreads) = 0; + + virtual bool isAsync() = 0; + + private: + // Returns an event to wait on for the task to finish. + // If the pool fails to create the task, returns null. + virtual std::shared_ptr postWorkerTask(std::shared_ptr task) = 0; +}; + +} // namespace angle + +#endif // LIBANGLE_WORKER_THREAD_H_ diff --git a/gfx/angle/checkout/src/libANGLE/angletypes.cpp b/gfx/angle/checkout/src/libANGLE/angletypes.cpp new file mode 100644 index 0000000000..19f9a25441 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/angletypes.cpp @@ -0,0 +1,1039 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// angletypes.h : Defines a variety of structures and enum types that are used throughout libGLESv2 + +#include "libANGLE/angletypes.h" +#include "libANGLE/Program.h" +#include "libANGLE/State.h" +#include "libANGLE/VertexArray.h" +#include "libANGLE/VertexAttribute.h" + +#include + +namespace gl +{ +namespace +{ +bool IsStencilNoOp(GLenum stencilFunc, + GLenum stencilFail, + GLenum stencilPassDepthFail, + GLenum stencilPassDepthPass) +{ + const bool isNeverAndKeep = stencilFunc == GL_NEVER && stencilFail == GL_KEEP; + const bool isAlwaysAndKeepOrAllKeep = (stencilFunc == GL_ALWAYS || stencilFail == GL_KEEP) && + stencilPassDepthFail == GL_KEEP && + stencilPassDepthPass == GL_KEEP; + + return isNeverAndKeep || isAlwaysAndKeepOrAllKeep; +} + +// Calculate whether the range [outsideLow, outsideHigh] encloses the range [insideLow, insideHigh] +bool EnclosesRange(int outsideLow, int outsideHigh, int insideLow, int insideHigh) +{ + return outsideLow <= insideLow && outsideHigh >= insideHigh; +} + +bool IsAdvancedBlendEquation(gl::BlendEquationType blendEquation) +{ + return blendEquation >= gl::BlendEquationType::Multiply && + blendEquation <= gl::BlendEquationType::HslLuminosity; +} +} // anonymous namespace + +RasterizerState::RasterizerState() +{ + memset(this, 0, sizeof(RasterizerState)); + + rasterizerDiscard = false; + cullFace = false; + cullMode = CullFaceMode::Back; + frontFace = GL_CCW; + polygonOffsetFill = false; + polygonOffsetFactor = 0.0f; + polygonOffsetUnits = 0.0f; + pointDrawMode = false; + multiSample = false; + dither = true; +} + +RasterizerState::RasterizerState(const RasterizerState &other) +{ + memcpy(this, &other, sizeof(RasterizerState)); +} + +RasterizerState &RasterizerState::operator=(const RasterizerState &other) +{ + memcpy(this, &other, sizeof(RasterizerState)); + return *this; +} + +bool operator==(const RasterizerState &a, const RasterizerState &b) +{ + return memcmp(&a, &b, sizeof(RasterizerState)) == 0; +} + +bool operator!=(const RasterizerState &a, const RasterizerState &b) +{ + return !(a == b); +} + +BlendState::BlendState() +{ + memset(this, 0, sizeof(BlendState)); + + blend = false; + sourceBlendRGB = GL_ONE; + sourceBlendAlpha = GL_ONE; + destBlendRGB = GL_ZERO; + destBlendAlpha = GL_ZERO; + blendEquationRGB = GL_FUNC_ADD; + blendEquationAlpha = GL_FUNC_ADD; + colorMaskRed = true; + colorMaskGreen = true; + colorMaskBlue = true; + colorMaskAlpha = true; +} + +BlendState::BlendState(const BlendState &other) +{ + memcpy(this, &other, sizeof(BlendState)); +} + +bool operator==(const BlendState &a, const BlendState &b) +{ + return memcmp(&a, &b, sizeof(BlendState)) == 0; +} + +bool operator!=(const BlendState &a, const BlendState &b) +{ + return !(a == b); +} + +DepthStencilState::DepthStencilState() +{ + memset(this, 0, sizeof(DepthStencilState)); + + depthTest = false; + depthFunc = GL_LESS; + depthMask = true; + stencilTest = false; + stencilFunc = GL_ALWAYS; + stencilMask = static_cast(-1); + stencilWritemask = static_cast(-1); + stencilBackFunc = GL_ALWAYS; + stencilBackMask = static_cast(-1); + stencilBackWritemask = static_cast(-1); + stencilFail = GL_KEEP; + stencilPassDepthFail = GL_KEEP; + stencilPassDepthPass = GL_KEEP; + stencilBackFail = GL_KEEP; + stencilBackPassDepthFail = GL_KEEP; + stencilBackPassDepthPass = GL_KEEP; +} + +DepthStencilState::DepthStencilState(const DepthStencilState &other) +{ + memcpy(this, &other, sizeof(DepthStencilState)); +} + +DepthStencilState &DepthStencilState::operator=(const DepthStencilState &other) +{ + memcpy(this, &other, sizeof(DepthStencilState)); + return *this; +} + +bool DepthStencilState::isDepthMaskedOut() const +{ + return !depthMask; +} + +bool DepthStencilState::isStencilMaskedOut() const +{ + return (stencilMask & stencilWritemask) == 0; +} + +bool DepthStencilState::isStencilNoOp() const +{ + return isStencilMaskedOut() || + IsStencilNoOp(stencilFunc, stencilFail, stencilPassDepthFail, stencilPassDepthPass); +} + +bool DepthStencilState::isStencilBackNoOp() const +{ + const bool isStencilBackMaskedOut = (stencilBackMask & stencilBackWritemask) == 0; + return isStencilBackMaskedOut || + IsStencilNoOp(stencilBackFunc, stencilBackFail, stencilBackPassDepthFail, + stencilBackPassDepthPass); +} + +bool operator==(const DepthStencilState &a, const DepthStencilState &b) +{ + return memcmp(&a, &b, sizeof(DepthStencilState)) == 0; +} + +bool operator!=(const DepthStencilState &a, const DepthStencilState &b) +{ + return !(a == b); +} + +SamplerState::SamplerState() +{ + memset(this, 0, sizeof(SamplerState)); + + setMinFilter(GL_NEAREST_MIPMAP_LINEAR); + setMagFilter(GL_LINEAR); + setWrapS(GL_REPEAT); + setWrapT(GL_REPEAT); + setWrapR(GL_REPEAT); + setMaxAnisotropy(1.0f); + setMinLod(-1000.0f); + setMaxLod(1000.0f); + setCompareMode(GL_NONE); + setCompareFunc(GL_LEQUAL); + setSRGBDecode(GL_DECODE_EXT); +} + +SamplerState::SamplerState(const SamplerState &other) = default; + +SamplerState &SamplerState::operator=(const SamplerState &other) = default; + +// static +SamplerState SamplerState::CreateDefaultForTarget(TextureType type) +{ + SamplerState state; + + // According to OES_EGL_image_external and ARB_texture_rectangle: For external textures, the + // default min filter is GL_LINEAR and the default s and t wrap modes are GL_CLAMP_TO_EDGE. + if (type == TextureType::External || type == TextureType::Rectangle) + { + state.mMinFilter = GL_LINEAR; + state.mWrapS = GL_CLAMP_TO_EDGE; + state.mWrapT = GL_CLAMP_TO_EDGE; + } + + return state; +} + +bool SamplerState::setMinFilter(GLenum minFilter) +{ + if (mMinFilter != minFilter) + { + mMinFilter = minFilter; + mCompleteness.typed.minFilter = static_cast(FromGLenum(minFilter)); + return true; + } + return false; +} + +bool SamplerState::setMagFilter(GLenum magFilter) +{ + if (mMagFilter != magFilter) + { + mMagFilter = magFilter; + mCompleteness.typed.magFilter = static_cast(FromGLenum(magFilter)); + return true; + } + return false; +} + +bool SamplerState::setWrapS(GLenum wrapS) +{ + if (mWrapS != wrapS) + { + mWrapS = wrapS; + mCompleteness.typed.wrapS = static_cast(FromGLenum(wrapS)); + return true; + } + return false; +} + +bool SamplerState::setWrapT(GLenum wrapT) +{ + if (mWrapT != wrapT) + { + mWrapT = wrapT; + updateWrapTCompareMode(); + return true; + } + return false; +} + +bool SamplerState::setWrapR(GLenum wrapR) +{ + if (mWrapR != wrapR) + { + mWrapR = wrapR; + return true; + } + return false; +} + +bool SamplerState::setMaxAnisotropy(float maxAnisotropy) +{ + if (mMaxAnisotropy != maxAnisotropy) + { + mMaxAnisotropy = maxAnisotropy; + return true; + } + return false; +} + +bool SamplerState::setMinLod(GLfloat minLod) +{ + if (mMinLod != minLod) + { + mMinLod = minLod; + return true; + } + return false; +} + +bool SamplerState::setMaxLod(GLfloat maxLod) +{ + if (mMaxLod != maxLod) + { + mMaxLod = maxLod; + return true; + } + return false; +} + +bool SamplerState::setCompareMode(GLenum compareMode) +{ + if (mCompareMode != compareMode) + { + mCompareMode = compareMode; + updateWrapTCompareMode(); + return true; + } + return false; +} + +bool SamplerState::setCompareFunc(GLenum compareFunc) +{ + if (mCompareFunc != compareFunc) + { + mCompareFunc = compareFunc; + return true; + } + return false; +} + +bool SamplerState::setSRGBDecode(GLenum sRGBDecode) +{ + if (mSRGBDecode != sRGBDecode) + { + mSRGBDecode = sRGBDecode; + return true; + } + return false; +} + +bool SamplerState::setBorderColor(const ColorGeneric &color) +{ + if (mBorderColor != color) + { + mBorderColor = color; + return true; + } + return false; +} + +void SamplerState::updateWrapTCompareMode() +{ + uint8_t wrap = static_cast(FromGLenum(mWrapT)); + uint8_t compare = static_cast(mCompareMode == GL_NONE ? 0x10 : 0x00); + mCompleteness.typed.wrapTCompareMode = wrap | compare; +} + +ImageUnit::ImageUnit() + : texture(), level(0), layered(false), layer(0), access(GL_READ_ONLY), format(GL_R32UI) +{} + +ImageUnit::ImageUnit(const ImageUnit &other) = default; + +ImageUnit::~ImageUnit() = default; + +BlendStateExt::BlendStateExt(const size_t drawBufferCount) + : mParameterMask(FactorStorage::GetMask(drawBufferCount)), + mSrcColor(FactorStorage::GetReplicatedValue(BlendFactorType::One, mParameterMask)), + mDstColor(FactorStorage::GetReplicatedValue(BlendFactorType::Zero, mParameterMask)), + mSrcAlpha(FactorStorage::GetReplicatedValue(BlendFactorType::One, mParameterMask)), + mDstAlpha(FactorStorage::GetReplicatedValue(BlendFactorType::Zero, mParameterMask)), + mEquationColor(EquationStorage::GetReplicatedValue(BlendEquationType::Add, mParameterMask)), + mEquationAlpha(EquationStorage::GetReplicatedValue(BlendEquationType::Add, mParameterMask)), + mAllColorMask( + ColorMaskStorage::GetReplicatedValue(PackColorMask(true, true, true, true), + ColorMaskStorage::GetMask(drawBufferCount))), + mColorMask(mAllColorMask), + mAllEnabledMask(0xFF >> (8 - drawBufferCount)), + mDrawBufferCount(drawBufferCount) +{} + +BlendStateExt::BlendStateExt(const BlendStateExt &other) = default; + +BlendStateExt &BlendStateExt::operator=(const BlendStateExt &other) = default; + +void BlendStateExt::setEnabled(const bool enabled) +{ + mEnabledMask = enabled ? mAllEnabledMask : DrawBufferMask::Zero(); +} + +void BlendStateExt::setEnabledIndexed(const size_t index, const bool enabled) +{ + ASSERT(index < mDrawBufferCount); + mEnabledMask.set(index, enabled); +} + +BlendStateExt::ColorMaskStorage::Type BlendStateExt::expandColorMaskValue(const bool red, + const bool green, + const bool blue, + const bool alpha) const +{ + return BlendStateExt::ColorMaskStorage::GetReplicatedValue( + PackColorMask(red, green, blue, alpha), mAllColorMask); +} + +BlendStateExt::ColorMaskStorage::Type BlendStateExt::expandColorMaskIndexed( + const size_t index) const +{ + return ColorMaskStorage::GetReplicatedValue( + ColorMaskStorage::GetValueIndexed(index, mColorMask), mAllColorMask); +} + +void BlendStateExt::setColorMask(const bool red, + const bool green, + const bool blue, + const bool alpha) +{ + mColorMask = expandColorMaskValue(red, green, blue, alpha); +} + +void BlendStateExt::setColorMaskIndexed(const size_t index, const uint8_t value) +{ + ASSERT(index < mDrawBufferCount); + ASSERT(value <= 0xF); + ColorMaskStorage::SetValueIndexed(index, value, &mColorMask); +} + +void BlendStateExt::setColorMaskIndexed(const size_t index, + const bool red, + const bool green, + const bool blue, + const bool alpha) +{ + ASSERT(index < mDrawBufferCount); + ColorMaskStorage::SetValueIndexed(index, PackColorMask(red, green, blue, alpha), &mColorMask); +} + +uint8_t BlendStateExt::getColorMaskIndexed(const size_t index) const +{ + ASSERT(index < mDrawBufferCount); + return ColorMaskStorage::GetValueIndexed(index, mColorMask); +} + +void BlendStateExt::getColorMaskIndexed(const size_t index, + bool *red, + bool *green, + bool *blue, + bool *alpha) const +{ + ASSERT(index < mDrawBufferCount); + UnpackColorMask(ColorMaskStorage::GetValueIndexed(index, mColorMask), red, green, blue, alpha); +} + +DrawBufferMask BlendStateExt::compareColorMask(ColorMaskStorage::Type other) const +{ + return ColorMaskStorage::GetDiffMask(mColorMask, other); +} + +BlendStateExt::EquationStorage::Type BlendStateExt::expandEquationValue(const GLenum mode) const +{ + return EquationStorage::GetReplicatedValue(FromGLenum(mode), mParameterMask); +} + +BlendStateExt::EquationStorage::Type BlendStateExt::expandEquationValue( + const gl::BlendEquationType equation) const +{ + return EquationStorage::GetReplicatedValue(equation, mParameterMask); +} + +BlendStateExt::EquationStorage::Type BlendStateExt::expandEquationColorIndexed( + const size_t index) const +{ + return EquationStorage::GetReplicatedValue( + EquationStorage::GetValueIndexed(index, mEquationColor), mParameterMask); +} + +BlendStateExt::EquationStorage::Type BlendStateExt::expandEquationAlphaIndexed( + const size_t index) const +{ + return EquationStorage::GetReplicatedValue( + EquationStorage::GetValueIndexed(index, mEquationAlpha), mParameterMask); +} + +void BlendStateExt::setEquations(const GLenum modeColor, const GLenum modeAlpha) +{ + const gl::BlendEquationType colorEquation = FromGLenum(modeColor); + const gl::BlendEquationType alphaEquation = FromGLenum(modeAlpha); + + mEquationColor = expandEquationValue(colorEquation); + mEquationAlpha = expandEquationValue(alphaEquation); + + // Note that advanced blend equations cannot be independently set for color and alpha, so only + // the color equation can be checked. + if (IsAdvancedBlendEquation(colorEquation)) + { + mUsesAdvancedBlendEquationMask = mAllEnabledMask; + } + else + { + mUsesAdvancedBlendEquationMask.reset(); + } +} + +void BlendStateExt::setEquationsIndexed(const size_t index, + const GLenum modeColor, + const GLenum modeAlpha) +{ + ASSERT(index < mDrawBufferCount); + + const gl::BlendEquationType colorEquation = FromGLenum(modeColor); + const gl::BlendEquationType alphaEquation = FromGLenum(modeAlpha); + + EquationStorage::SetValueIndexed(index, colorEquation, &mEquationColor); + EquationStorage::SetValueIndexed(index, alphaEquation, &mEquationAlpha); + + mUsesAdvancedBlendEquationMask.set(index, IsAdvancedBlendEquation(colorEquation)); +} + +void BlendStateExt::setEquationsIndexed(const size_t index, + const size_t sourceIndex, + const BlendStateExt &source) +{ + ASSERT(index < mDrawBufferCount); + ASSERT(sourceIndex < source.mDrawBufferCount); + + const gl::BlendEquationType colorEquation = + EquationStorage::GetValueIndexed(sourceIndex, source.mEquationColor); + const gl::BlendEquationType alphaEquation = + EquationStorage::GetValueIndexed(sourceIndex, source.mEquationAlpha); + + EquationStorage::SetValueIndexed(index, colorEquation, &mEquationColor); + EquationStorage::SetValueIndexed(index, alphaEquation, &mEquationAlpha); + + mUsesAdvancedBlendEquationMask.set(index, IsAdvancedBlendEquation(colorEquation)); +} + +GLenum BlendStateExt::getEquationColorIndexed(size_t index) const +{ + ASSERT(index < mDrawBufferCount); + return ToGLenum(EquationStorage::GetValueIndexed(index, mEquationColor)); +} + +GLenum BlendStateExt::getEquationAlphaIndexed(size_t index) const +{ + ASSERT(index < mDrawBufferCount); + return ToGLenum(EquationStorage::GetValueIndexed(index, mEquationAlpha)); +} + +DrawBufferMask BlendStateExt::compareEquations(const EquationStorage::Type color, + const EquationStorage::Type alpha) const +{ + return EquationStorage::GetDiffMask(mEquationColor, color) | + EquationStorage::GetDiffMask(mEquationAlpha, alpha); +} + +BlendStateExt::FactorStorage::Type BlendStateExt::expandFactorValue(const GLenum func) const +{ + return FactorStorage::GetReplicatedValue(FromGLenum(func), mParameterMask); +} + +BlendStateExt::FactorStorage::Type BlendStateExt::expandSrcColorIndexed(const size_t index) const +{ + ASSERT(index < mDrawBufferCount); + return FactorStorage::GetReplicatedValue(FactorStorage::GetValueIndexed(index, mSrcColor), + mParameterMask); +} + +BlendStateExt::FactorStorage::Type BlendStateExt::expandDstColorIndexed(const size_t index) const +{ + ASSERT(index < mDrawBufferCount); + return FactorStorage::GetReplicatedValue(FactorStorage::GetValueIndexed(index, mDstColor), + mParameterMask); +} + +BlendStateExt::FactorStorage::Type BlendStateExt::expandSrcAlphaIndexed(const size_t index) const +{ + ASSERT(index < mDrawBufferCount); + return FactorStorage::GetReplicatedValue(FactorStorage::GetValueIndexed(index, mSrcAlpha), + mParameterMask); +} + +BlendStateExt::FactorStorage::Type BlendStateExt::expandDstAlphaIndexed(const size_t index) const +{ + ASSERT(index < mDrawBufferCount); + return FactorStorage::GetReplicatedValue(FactorStorage::GetValueIndexed(index, mDstAlpha), + mParameterMask); +} + +void BlendStateExt::setFactors(const GLenum srcColor, + const GLenum dstColor, + const GLenum srcAlpha, + const GLenum dstAlpha) +{ + mSrcColor = expandFactorValue(srcColor); + mDstColor = expandFactorValue(dstColor); + mSrcAlpha = expandFactorValue(srcAlpha); + mDstAlpha = expandFactorValue(dstAlpha); +} + +void BlendStateExt::setFactorsIndexed(const size_t index, + const GLenum srcColor, + const GLenum dstColor, + const GLenum srcAlpha, + const GLenum dstAlpha) +{ + ASSERT(index < mDrawBufferCount); + FactorStorage::SetValueIndexed(index, FromGLenum(srcColor), &mSrcColor); + FactorStorage::SetValueIndexed(index, FromGLenum(dstColor), &mDstColor); + FactorStorage::SetValueIndexed(index, FromGLenum(srcAlpha), &mSrcAlpha); + FactorStorage::SetValueIndexed(index, FromGLenum(dstAlpha), &mDstAlpha); +} + +void BlendStateExt::setFactorsIndexed(const size_t index, + const size_t sourceIndex, + const BlendStateExt &source) +{ + ASSERT(index < mDrawBufferCount); + ASSERT(sourceIndex < source.mDrawBufferCount); + FactorStorage::SetValueIndexed( + index, FactorStorage::GetValueIndexed(sourceIndex, source.mSrcColor), &mSrcColor); + FactorStorage::SetValueIndexed( + index, FactorStorage::GetValueIndexed(sourceIndex, source.mDstColor), &mDstColor); + FactorStorage::SetValueIndexed( + index, FactorStorage::GetValueIndexed(sourceIndex, source.mSrcAlpha), &mSrcAlpha); + FactorStorage::SetValueIndexed( + index, FactorStorage::GetValueIndexed(sourceIndex, source.mDstAlpha), &mDstAlpha); +} + +GLenum BlendStateExt::getSrcColorIndexed(size_t index) const +{ + ASSERT(index < mDrawBufferCount); + return ToGLenum(FactorStorage::GetValueIndexed(index, mSrcColor)); +} + +GLenum BlendStateExt::getDstColorIndexed(size_t index) const +{ + ASSERT(index < mDrawBufferCount); + return ToGLenum(FactorStorage::GetValueIndexed(index, mDstColor)); +} + +GLenum BlendStateExt::getSrcAlphaIndexed(size_t index) const +{ + ASSERT(index < mDrawBufferCount); + return ToGLenum(FactorStorage::GetValueIndexed(index, mSrcAlpha)); +} + +GLenum BlendStateExt::getDstAlphaIndexed(size_t index) const +{ + ASSERT(index < mDrawBufferCount); + return ToGLenum(FactorStorage::GetValueIndexed(index, mDstAlpha)); +} + +DrawBufferMask BlendStateExt::compareFactors(const FactorStorage::Type srcColor, + const FactorStorage::Type dstColor, + const FactorStorage::Type srcAlpha, + const FactorStorage::Type dstAlpha) const +{ + return FactorStorage::GetDiffMask(mSrcColor, srcColor) | + FactorStorage::GetDiffMask(mDstColor, dstColor) | + FactorStorage::GetDiffMask(mSrcAlpha, srcAlpha) | + FactorStorage::GetDiffMask(mDstAlpha, dstAlpha); +} + +static void MinMax(int a, int b, int *minimum, int *maximum) +{ + if (a < b) + { + *minimum = a; + *maximum = b; + } + else + { + *minimum = b; + *maximum = a; + } +} + +template <> +bool RectangleImpl::empty() const +{ + return width == 0 && height == 0; +} + +template <> +bool RectangleImpl::empty() const +{ + return std::abs(width) < std::numeric_limits::epsilon() && + std::abs(height) < std::numeric_limits::epsilon(); +} + +bool ClipRectangle(const Rectangle &source, const Rectangle &clip, Rectangle *intersection) +{ + angle::CheckedNumeric sourceX2(source.x); + sourceX2 += source.width; + if (!sourceX2.IsValid()) + { + return false; + } + angle::CheckedNumeric sourceY2(source.y); + sourceY2 += source.height; + if (!sourceY2.IsValid()) + { + return false; + } + + int minSourceX, maxSourceX, minSourceY, maxSourceY; + MinMax(source.x, sourceX2.ValueOrDie(), &minSourceX, &maxSourceX); + MinMax(source.y, sourceY2.ValueOrDie(), &minSourceY, &maxSourceY); + + angle::CheckedNumeric clipX2(clip.x); + clipX2 += clip.width; + if (!clipX2.IsValid()) + { + return false; + } + angle::CheckedNumeric clipY2(clip.y); + clipY2 += clip.height; + if (!clipY2.IsValid()) + { + return false; + } + + int minClipX, maxClipX, minClipY, maxClipY; + MinMax(clip.x, clipX2.ValueOrDie(), &minClipX, &maxClipX); + MinMax(clip.y, clipY2.ValueOrDie(), &minClipY, &maxClipY); + + if (minSourceX >= maxClipX || maxSourceX <= minClipX || minSourceY >= maxClipY || + maxSourceY <= minClipY) + { + return false; + } + + int x = std::max(minSourceX, minClipX); + int y = std::max(minSourceY, minClipY); + int width = std::min(maxSourceX, maxClipX) - x; + int height = std::min(maxSourceY, maxClipY) - y; + + if (intersection) + { + intersection->x = x; + intersection->y = y; + intersection->width = width; + intersection->height = height; + } + return width != 0 && height != 0; +} + +void GetEnclosingRectangle(const Rectangle &rect1, const Rectangle &rect2, Rectangle *rectUnion) +{ + // All callers use non-flipped framebuffer-size-clipped rectangles, so both flip and overflow + // are impossible. + ASSERT(!rect1.isReversedX() && !rect1.isReversedY()); + ASSERT(!rect2.isReversedX() && !rect2.isReversedY()); + ASSERT((angle::CheckedNumeric(rect1.x) + rect1.width).IsValid()); + ASSERT((angle::CheckedNumeric(rect1.y) + rect1.height).IsValid()); + ASSERT((angle::CheckedNumeric(rect2.x) + rect2.width).IsValid()); + ASSERT((angle::CheckedNumeric(rect2.y) + rect2.height).IsValid()); + + // This function calculates a rectangle that covers both input rectangles: + // + // +---------+ + // rect1 --> | | + // | +---+-----+ + // | | | | <-- rect2 + // +-----+---+ | + // | | + // +---------+ + // + // xy0 = min(rect1.xy0, rect2.xy0) + // \ + // +---------+-----+ + // union --> | . | + // | + . + . . + + // | . . | + // + . . + . + | + // | . | + // +-----+---------+ + // / + // xy1 = max(rect1.xy1, rect2.xy1) + + int x0 = std::min(rect1.x0(), rect2.x0()); + int y0 = std::min(rect1.y0(), rect2.y0()); + + int x1 = std::max(rect1.x1(), rect2.x1()); + int y1 = std::max(rect1.y1(), rect2.y1()); + + rectUnion->x = x0; + rectUnion->y = y0; + rectUnion->width = x1 - x0; + rectUnion->height = y1 - y0; +} + +void ExtendRectangle(const Rectangle &source, const Rectangle &extend, Rectangle *extended) +{ + // All callers use non-flipped framebuffer-size-clipped rectangles, so both flip and overflow + // are impossible. + ASSERT(!source.isReversedX() && !source.isReversedY()); + ASSERT(!extend.isReversedX() && !extend.isReversedY()); + ASSERT((angle::CheckedNumeric(source.x) + source.width).IsValid()); + ASSERT((angle::CheckedNumeric(source.y) + source.height).IsValid()); + ASSERT((angle::CheckedNumeric(extend.x) + extend.width).IsValid()); + ASSERT((angle::CheckedNumeric(extend.y) + extend.height).IsValid()); + + int x0 = source.x0(); + int x1 = source.x1(); + int y0 = source.y0(); + int y1 = source.y1(); + + const int extendX0 = extend.x0(); + const int extendX1 = extend.x1(); + const int extendY0 = extend.y0(); + const int extendY1 = extend.y1(); + + // For each side of the rectangle, calculate whether it can be extended by the second rectangle. + // If so, extend it and continue for the next side with the new dimensions. + + // Left: Reduce x0 if the second rectangle's vertical edge covers the source's: + // + // +--- - - - +--- - - - + // | | + // | +--------------+ +-----------------+ + // | | source | --> | source | + // | +--------------+ +-----------------+ + // | | + // +--- - - - +--- - - - + // + const bool enclosesHeight = EnclosesRange(extendY0, extendY1, y0, y1); + if (extendX0 < x0 && extendX1 >= x0 && enclosesHeight) + { + x0 = extendX0; + } + + // Right: Increase x1 simiarly. + if (extendX0 <= x1 && extendX1 > x1 && enclosesHeight) + { + x1 = extendX1; + } + + // Top: Reduce y0 if the second rectangle's horizontal edge covers the source's potentially + // extended edge. + const bool enclosesWidth = EnclosesRange(extendX0, extendX1, x0, x1); + if (extendY0 < y0 && extendY1 >= y0 && enclosesWidth) + { + y0 = extendY0; + } + + // Right: Increase y1 simiarly. + if (extendY0 <= y1 && extendY1 > y1 && enclosesWidth) + { + y1 = extendY1; + } + + extended->x = x0; + extended->y = y0; + extended->width = x1 - x0; + extended->height = y1 - y0; +} + +bool Box::valid() const +{ + return width != 0 && height != 0 && depth != 0; +} + +bool Box::operator==(const Box &other) const +{ + return (x == other.x && y == other.y && z == other.z && width == other.width && + height == other.height && depth == other.depth); +} + +bool Box::operator!=(const Box &other) const +{ + return !(*this == other); +} + +Rectangle Box::toRect() const +{ + ASSERT(z == 0 && depth == 1); + return Rectangle(x, y, width, height); +} + +bool Box::coversSameExtent(const Extents &size) const +{ + return x == 0 && y == 0 && z == 0 && width == size.width && height == size.height && + depth == size.depth; +} + +bool Box::contains(const Box &other) const +{ + return x <= other.x && y <= other.y && z <= other.z && x + width >= other.x + other.width && + y + height >= other.y + other.height && z + depth >= other.z + other.depth; +} + +size_t Box::volume() const +{ + return width * height * depth; +} + +void Box::extend(const Box &other) +{ + // This extends the logic of "ExtendRectangle" to 3 dimensions + + int x0 = x; + int x1 = x + width; + int y0 = y; + int y1 = y + height; + int z0 = z; + int z1 = z + depth; + + const int otherx0 = other.x; + const int otherx1 = other.x + other.width; + const int othery0 = other.y; + const int othery1 = other.y + other.height; + const int otherz0 = other.z; + const int otherz1 = other.z + other.depth; + + // For each side of the box, calculate whether it can be extended by the other box. + // If so, extend it and continue to the next side with the new dimensions. + + const bool enclosesWidth = EnclosesRange(otherx0, otherx1, x0, x1); + const bool enclosesHeight = EnclosesRange(othery0, othery1, y0, y1); + const bool enclosesDepth = EnclosesRange(otherz0, otherz1, z0, z1); + + // Left: Reduce x0 if the other box's Y and Z plane encloses the source + if (otherx0 < x0 && otherx1 >= x0 && enclosesHeight && enclosesDepth) + { + x0 = otherx0; + } + + // Right: Increase x1 simiarly. + if (otherx0 <= x1 && otherx1 > x1 && enclosesHeight && enclosesDepth) + { + x1 = otherx1; + } + + // Bottom: Reduce y0 if the other box's X and Z plane encloses the source + if (othery0 < y0 && othery1 >= y0 && enclosesWidth && enclosesDepth) + { + y0 = othery0; + } + + // Top: Increase y1 simiarly. + if (othery0 <= y1 && othery1 > y1 && enclosesWidth && enclosesDepth) + { + y1 = othery1; + } + + // Front: Reduce z0 if the other box's X and Y plane encloses the source + if (otherz0 < z0 && otherz1 >= z0 && enclosesWidth && enclosesHeight) + { + z0 = otherz0; + } + + // Back: Increase z1 simiarly. + if (otherz0 <= z1 && otherz1 > z1 && enclosesWidth && enclosesHeight) + { + z1 = otherz1; + } + + // Update member var with new dimensions + x = x0; + width = x1 - x0; + y = y0; + height = y1 - y0; + z = z0; + depth = z1 - z0; +} + +bool operator==(const Offset &a, const Offset &b) +{ + return a.x == b.x && a.y == b.y && a.z == b.z; +} + +bool operator!=(const Offset &a, const Offset &b) +{ + return !(a == b); +} + +bool operator==(const Extents &lhs, const Extents &rhs) +{ + return lhs.width == rhs.width && lhs.height == rhs.height && lhs.depth == rhs.depth; +} + +bool operator!=(const Extents &lhs, const Extents &rhs) +{ + return !(lhs == rhs); +} + +bool ValidateComponentTypeMasks(unsigned long outputTypes, + unsigned long inputTypes, + unsigned long outputMask, + unsigned long inputMask) +{ + static_assert(IMPLEMENTATION_MAX_DRAW_BUFFERS <= kMaxComponentTypeMaskIndex, + "Output/input masks should fit into 16 bits - 1 bit per draw buffer. The " + "corresponding type masks should fit into 32 bits - 2 bits per draw buffer."); + static_assert(MAX_VERTEX_ATTRIBS <= kMaxComponentTypeMaskIndex, + "Output/input masks should fit into 16 bits - 1 bit per attrib. The " + "corresponding type masks should fit into 32 bits - 2 bits per attrib."); + + // For performance reasons, draw buffer and attribute type validation is done using bit masks. + // We store two bits representing the type split, with the low bit in the lower 16 bits of the + // variable, and the high bit in the upper 16 bits of the variable. This is done so we can AND + // with the elswewhere used DrawBufferMask or AttributeMask. + + // OR the masks with themselves, shifted 16 bits. This is to match our split type bits. + outputMask |= (outputMask << kMaxComponentTypeMaskIndex); + inputMask |= (inputMask << kMaxComponentTypeMaskIndex); + + // To validate: + // 1. Remove any indexes that are not enabled in the input (& inputMask) + // 2. Remove any indexes that exist in output, but not in input (& outputMask) + // 3. Use == to verify equality + return (outputTypes & inputMask) == ((inputTypes & outputMask) & inputMask); +} + +GLsizeiptr GetBoundBufferAvailableSize(const OffsetBindingPointer &binding) +{ + Buffer *buffer = binding.get(); + if (buffer == nullptr) + { + return 0; + } + + const GLsizeiptr bufferSize = static_cast(buffer->getSize()); + + if (binding.getSize() == 0) + { + return bufferSize; + } + + const GLintptr offset = binding.getOffset(); + const GLsizeiptr size = binding.getSize(); + + ASSERT(offset >= 0 && bufferSize >= 0); + + if (bufferSize <= offset) + { + return 0; + } + + return std::min(size, bufferSize - offset); +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/angletypes.h b/gfx/angle/checkout/src/libANGLE/angletypes.h new file mode 100644 index 0000000000..6ac65a5cf3 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/angletypes.h @@ -0,0 +1,1203 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// angletypes.h : Defines a variety of structures and enum types that are used throughout libGLESv2 + +#ifndef LIBANGLE_ANGLETYPES_H_ +#define LIBANGLE_ANGLETYPES_H_ + +#include "common/Color.h" +#include "common/FixedVector.h" +#include "common/PackedEnums.h" +#include "common/bitset_utils.h" +#include "common/vector_utils.h" +#include "libANGLE/Constants.h" +#include "libANGLE/Error.h" +#include "libANGLE/RefCountObject.h" + +#include +#include + +#include +#include +#include +#include + +namespace gl +{ +class Buffer; +class Texture; + +enum class Command +{ + // The Blit command carries the bitmask of which buffers are being blit. The command passed to + // the backends is: + // + // Blit + (Color?0x1) + (Depth?0x2) + (Stencil?0x4) + Blit, + BlitAll = Blit + 0x7, + Clear, + CopyImage, + Dispatch, + Draw, + GenerateMipmap, + Invalidate, + ReadPixels, + TexImage, + Other, +}; + +enum CommandBlitBuffer +{ + CommandBlitBufferColor = 0x1, + CommandBlitBufferDepth = 0x2, + CommandBlitBufferStencil = 0x4, +}; + +enum class InitState +{ + MayNeedInit, + Initialized, +}; + +template +struct RectangleImpl +{ + RectangleImpl() : x(T(0)), y(T(0)), width(T(0)), height(T(0)) {} + constexpr RectangleImpl(T x_in, T y_in, T width_in, T height_in) + : x(x_in), y(y_in), width(width_in), height(height_in) + {} + explicit constexpr RectangleImpl(const T corners[4]) + : x(corners[0]), + y(corners[1]), + width(corners[2] - corners[0]), + height(corners[3] - corners[1]) + {} + template + explicit constexpr RectangleImpl(const RectangleImpl rect) + : x(rect.x), y(rect.y), width(rect.width), height(rect.height) + {} + + T x0() const { return x; } + T y0() const { return y; } + T x1() const { return x + width; } + T y1() const { return y + height; } + + bool isReversedX() const { return width < T(0); } + bool isReversedY() const { return height < T(0); } + + // Returns a rectangle with the same area but flipped in X, Y, neither or both. + RectangleImpl flip(bool flipX, bool flipY) const + { + RectangleImpl flipped = *this; + if (flipX) + { + flipped.x = flipped.x + flipped.width; + flipped.width = -flipped.width; + } + if (flipY) + { + flipped.y = flipped.y + flipped.height; + flipped.height = -flipped.height; + } + return flipped; + } + + // Returns a rectangle with the same area but with height and width guaranteed to be positive. + RectangleImpl removeReversal() const { return flip(isReversedX(), isReversedY()); } + + bool encloses(const RectangleImpl &inside) const + { + return x0() <= inside.x0() && y0() <= inside.y0() && x1() >= inside.x1() && + y1() >= inside.y1(); + } + + bool empty() const; + + T x; + T y; + T width; + T height; +}; + +template +bool operator==(const RectangleImpl &a, const RectangleImpl &b); +template +bool operator!=(const RectangleImpl &a, const RectangleImpl &b); + +using Rectangle = RectangleImpl; + +enum class ClipSpaceOrigin +{ + LowerLeft = 0, + UpperLeft = 1 +}; + +// Calculate the intersection of two rectangles. Returns false if the intersection is empty. +[[nodiscard]] bool ClipRectangle(const Rectangle &source, + const Rectangle &clip, + Rectangle *intersection); +// Calculate the smallest rectangle that covers both rectangles. This rectangle may cover areas +// not covered by the two rectangles, for example in this situation: +// +// +--+ +----+ +// | ++-+ -> | | +// +-++ | | | +// +--+ +----+ +// +void GetEnclosingRectangle(const Rectangle &rect1, const Rectangle &rect2, Rectangle *rectUnion); +// Extend the source rectangle to cover parts (or all of) the second rectangle, in such a way that +// no area is covered that isn't covered by both rectangles. For example: +// +// +--+ +--+ +// source --> | | | | +// ++--+-+ -> | | +// |+--+ | | | +// +-----+ +--+ +// +void ExtendRectangle(const Rectangle &source, const Rectangle &extend, Rectangle *extended); + +struct Offset +{ + constexpr Offset() : x(0), y(0), z(0) {} + constexpr Offset(int x_in, int y_in, int z_in) : x(x_in), y(y_in), z(z_in) {} + + int x; + int y; + int z; +}; + +constexpr Offset kOffsetZero(0, 0, 0); + +bool operator==(const Offset &a, const Offset &b); +bool operator!=(const Offset &a, const Offset &b); + +struct Extents +{ + Extents() : width(0), height(0), depth(0) {} + Extents(int width_, int height_, int depth_) : width(width_), height(height_), depth(depth_) {} + + Extents(const Extents &other) = default; + Extents &operator=(const Extents &other) = default; + + bool empty() const { return (width * height * depth) == 0; } + + int width; + int height; + int depth; +}; + +bool operator==(const Extents &lhs, const Extents &rhs); +bool operator!=(const Extents &lhs, const Extents &rhs); + +struct Box +{ + Box() : x(0), y(0), z(0), width(0), height(0), depth(0) {} + Box(int x_in, int y_in, int z_in, int width_in, int height_in, int depth_in) + : x(x_in), y(y_in), z(z_in), width(width_in), height(height_in), depth(depth_in) + {} + template + Box(const O &offset, const E &size) + : x(offset.x), + y(offset.y), + z(offset.z), + width(size.width), + height(size.height), + depth(size.depth) + {} + bool valid() const; + bool operator==(const Box &other) const; + bool operator!=(const Box &other) const; + Rectangle toRect() const; + + // Whether the Box has offset 0 and the same extents as argument. + bool coversSameExtent(const Extents &size) const; + + bool contains(const Box &other) const; + size_t volume() const; + void extend(const Box &other); + + int x; + int y; + int z; + int width; + int height; + int depth; +}; + +struct RasterizerState final +{ + // This will zero-initialize the struct, including padding. + RasterizerState(); + RasterizerState(const RasterizerState &other); + RasterizerState &operator=(const RasterizerState &other); + + bool cullFace; + CullFaceMode cullMode; + GLenum frontFace; + + bool polygonOffsetFill; + GLfloat polygonOffsetFactor; + GLfloat polygonOffsetUnits; + + // pointDrawMode/multiSample are only used in the D3D back-end right now. + bool pointDrawMode; + bool multiSample; + + bool rasterizerDiscard; + + bool dither; +}; + +bool operator==(const RasterizerState &a, const RasterizerState &b); +bool operator!=(const RasterizerState &a, const RasterizerState &b); + +struct BlendState final +{ + // This will zero-initialize the struct, including padding. + BlendState(); + BlendState(const BlendState &other); + + bool blend; + GLenum sourceBlendRGB; + GLenum destBlendRGB; + GLenum sourceBlendAlpha; + GLenum destBlendAlpha; + GLenum blendEquationRGB; + GLenum blendEquationAlpha; + + bool colorMaskRed; + bool colorMaskGreen; + bool colorMaskBlue; + bool colorMaskAlpha; +}; + +bool operator==(const BlendState &a, const BlendState &b); +bool operator!=(const BlendState &a, const BlendState &b); + +struct DepthStencilState final +{ + // This will zero-initialize the struct, including padding. + DepthStencilState(); + DepthStencilState(const DepthStencilState &other); + DepthStencilState &operator=(const DepthStencilState &other); + + bool isDepthMaskedOut() const; + bool isStencilMaskedOut() const; + bool isStencilNoOp() const; + bool isStencilBackNoOp() const; + + bool depthTest; + GLenum depthFunc; + bool depthMask; + + bool stencilTest; + GLenum stencilFunc; + GLuint stencilMask; + GLenum stencilFail; + GLenum stencilPassDepthFail; + GLenum stencilPassDepthPass; + GLuint stencilWritemask; + GLenum stencilBackFunc; + GLuint stencilBackMask; + GLenum stencilBackFail; + GLenum stencilBackPassDepthFail; + GLenum stencilBackPassDepthPass; + GLuint stencilBackWritemask; +}; + +bool operator==(const DepthStencilState &a, const DepthStencilState &b); +bool operator!=(const DepthStencilState &a, const DepthStencilState &b); + +// Packs a sampler state for completeness checks: +// * minFilter: 5 values (3 bits) +// * magFilter: 2 values (1 bit) +// * wrapS: 3 values (2 bits) +// * wrapT: 3 values (2 bits) +// * compareMode: 1 bit (for == GL_NONE). +// This makes a total of 9 bits. We can pack this easily into 32 bits: +// * minFilter: 8 bits +// * magFilter: 8 bits +// * wrapS: 8 bits +// * wrapT: 4 bits +// * compareMode: 4 bits + +struct PackedSamplerCompleteness +{ + uint8_t minFilter; + uint8_t magFilter; + uint8_t wrapS; + uint8_t wrapTCompareMode; +}; + +static_assert(sizeof(PackedSamplerCompleteness) == sizeof(uint32_t), "Unexpected size"); + +// State from Table 6.10 (state per sampler object) +class SamplerState final +{ + public: + // This will zero-initialize the struct, including padding. + SamplerState(); + SamplerState(const SamplerState &other); + + SamplerState &operator=(const SamplerState &other); + + static SamplerState CreateDefaultForTarget(TextureType type); + + GLenum getMinFilter() const { return mMinFilter; } + + bool setMinFilter(GLenum minFilter); + + GLenum getMagFilter() const { return mMagFilter; } + + bool setMagFilter(GLenum magFilter); + + GLenum getWrapS() const { return mWrapS; } + + bool setWrapS(GLenum wrapS); + + GLenum getWrapT() const { return mWrapT; } + + bool setWrapT(GLenum wrapT); + + GLenum getWrapR() const { return mWrapR; } + + bool setWrapR(GLenum wrapR); + + float getMaxAnisotropy() const { return mMaxAnisotropy; } + + bool setMaxAnisotropy(float maxAnisotropy); + + GLfloat getMinLod() const { return mMinLod; } + + bool setMinLod(GLfloat minLod); + + GLfloat getMaxLod() const { return mMaxLod; } + + bool setMaxLod(GLfloat maxLod); + + GLenum getCompareMode() const { return mCompareMode; } + + bool setCompareMode(GLenum compareMode); + + GLenum getCompareFunc() const { return mCompareFunc; } + + bool setCompareFunc(GLenum compareFunc); + + GLenum getSRGBDecode() const { return mSRGBDecode; } + + bool setSRGBDecode(GLenum sRGBDecode); + + bool setBorderColor(const ColorGeneric &color); + + const ColorGeneric &getBorderColor() const { return mBorderColor; } + + bool sameCompleteness(const SamplerState &samplerState) const + { + return mCompleteness.packed == samplerState.mCompleteness.packed; + } + + private: + void updateWrapTCompareMode(); + + GLenum mMinFilter; + GLenum mMagFilter; + + GLenum mWrapS; + GLenum mWrapT; + GLenum mWrapR; + + // From EXT_texture_filter_anisotropic + float mMaxAnisotropy; + + GLfloat mMinLod; + GLfloat mMaxLod; + + GLenum mCompareMode; + GLenum mCompareFunc; + + GLenum mSRGBDecode; + + ColorGeneric mBorderColor; + + union Completeness + { + uint32_t packed; + PackedSamplerCompleteness typed; + }; + + Completeness mCompleteness; +}; + +bool operator==(const SamplerState &a, const SamplerState &b); +bool operator!=(const SamplerState &a, const SamplerState &b); + +struct DrawArraysIndirectCommand +{ + GLuint count; + GLuint instanceCount; + GLuint first; + GLuint baseInstance; +}; +static_assert(sizeof(DrawArraysIndirectCommand) == 16, + "Unexpected size of DrawArraysIndirectCommand"); + +struct DrawElementsIndirectCommand +{ + GLuint count; + GLuint primCount; + GLuint firstIndex; + GLint baseVertex; + GLuint baseInstance; +}; +static_assert(sizeof(DrawElementsIndirectCommand) == 20, + "Unexpected size of DrawElementsIndirectCommand"); + +struct ImageUnit +{ + ImageUnit(); + ImageUnit(const ImageUnit &other); + ~ImageUnit(); + + BindingPointer texture; + GLint level; + GLboolean layered; + GLint layer; + GLenum access; + GLenum format; +}; + +using ImageUnitTextureTypeMap = std::map; + +struct PixelStoreStateBase +{ + GLint alignment = 4; + GLint rowLength = 0; + GLint skipRows = 0; + GLint skipPixels = 0; + GLint imageHeight = 0; + GLint skipImages = 0; +}; + +struct PixelUnpackState : PixelStoreStateBase +{}; + +struct PixelPackState : PixelStoreStateBase +{ + bool reverseRowOrder = false; +}; + +// Used in Program and VertexArray. +using AttributesMask = angle::BitSet; + +// Used in Program +using UniformBlockBindingMask = angle::BitSet; + +// Used in Framebuffer / Program +using DrawBufferMask = angle::BitSet8; + +class BlendStateExt final +{ + static_assert(IMPLEMENTATION_MAX_DRAW_BUFFERS == 8, "Only up to 8 draw buffers supported."); + + public: + template + struct StorageType final + { + static_assert(ElementCount <= 256, "ElementCount cannot exceed 256."); + +#if defined(ANGLE_IS_64_BIT_CPU) + // Always use uint64_t on 64-bit systems + static constexpr size_t kBits = 8; +#else + static constexpr size_t kBits = ElementCount > 16 ? 8 : 4; +#endif + + using Type = typename std::conditional::type; + + static constexpr Type kMaxValueMask = (kBits == 8) ? 0xFF : 0xF; + + static constexpr Type GetMask(const size_t drawBuffers) + { + ASSERT(drawBuffers > 0); + ASSERT(drawBuffers <= IMPLEMENTATION_MAX_DRAW_BUFFERS); + return static_cast(0xFFFFFFFFFFFFFFFFull >> (64 - drawBuffers * kBits)); + } + + // A multiplier that is used to replicate 4- or 8-bit value 8 times. + static constexpr Type kReplicator = (kBits == 8) ? 0x0101010101010101ull : 0x11111111; + + // Extract packed `Bits`-bit value of index `index`. `values` variable contains up to 8 + // packed values. + static constexpr ElementType GetValueIndexed(const size_t index, const Type values) + { + ASSERT(index < IMPLEMENTATION_MAX_DRAW_BUFFERS); + + return static_cast((values >> (index * kBits)) & kMaxValueMask); + } + + // Replicate `Bits`-bit value 8 times and mask the result. + static constexpr Type GetReplicatedValue(const ElementType value, const Type mask) + { + ASSERT(static_cast(value) <= kMaxValueMask); + return (static_cast(value) * kReplicator) & mask; + } + + // Replace `Bits`-bit value of index `index` in `target` with `value`. + static constexpr void SetValueIndexed(const size_t index, + const ElementType value, + Type *target) + { + ASSERT(static_cast(value) <= kMaxValueMask); + ASSERT(index < IMPLEMENTATION_MAX_DRAW_BUFFERS); + + // Bitmask with set bits that contain the value of index `index`. + const Type selector = kMaxValueMask << (index * kBits); + + // Shift the new `value` to its position in the packed value. + const Type builtValue = static_cast(value) << (index * kBits); + + // Mark differing bits of `target` and `builtValue`, then flip the bits on those + // positions in `target`. + // Taken from https://graphics.stanford.edu/~seander/bithacks.html#MaskedMerge + *target = *target ^ ((*target ^ builtValue) & selector); + } + + // Compare two packed sets of eight 4-bit values and return an 8-bit diff mask. + static constexpr DrawBufferMask GetDiffMask(const uint32_t packedValue1, + const uint32_t packedValue2) + { + uint32_t diff = packedValue1 ^ packedValue2; + + // For each 4-bit value that is different between inputs, set the msb to 1 and other + // bits to 0. + diff = (diff | ((diff & 0x77777777) + 0x77777777)) & 0x88888888; + + // By this point, `diff` looks like a...b...c...d...e...f...g...h... (dots mean zeros). + // To get DrawBufferMask, we need to compress this 32-bit value to 8 bits, i.e. abcdefgh + + // Multiplying the lower half of `diff` by 0x249 (0x200 + 0x40 + 0x8 + 0x1) produces: + // ................e...f...g...h... + + // .............e...f...g...h...... + + // ..........e...f...g...h......... + + // .......e...f...g...h............ + // ________________________________ = + // .......e..ef.efgefghfgh.gh..h... + // ^^^^ + // Similar operation is applied to the upper word. + // This calculation could be replaced with a single PEXT instruction from BMI2 set. + diff = ((((diff & 0xFFFF0000) * 0x249) >> 24) & 0xF0) | (((diff * 0x249) >> 12) & 0xF); + + return DrawBufferMask(static_cast(diff)); + } + + // Compare two packed sets of eight 8-bit values and return an 8-bit diff mask. + static constexpr DrawBufferMask GetDiffMask(const uint64_t packedValue1, + const uint64_t packedValue2) + { + uint64_t diff = packedValue1 ^ packedValue2; + + // For each 8-bit value that is different between inputs, set the msb to 1 and other + // bits to 0. + diff = (diff | ((diff & 0x7F7F7F7F7F7F7F7F) + 0x7F7F7F7F7F7F7F7F)) & 0x8080808080808080; + + // By this point, `diff` looks like (dots mean zeros): + // a.......b.......c.......d.......e.......f.......g.......h....... + // To get DrawBufferMask, we need to compress this 64-bit value to 8 bits, i.e. abcdefgh + + // Multiplying `diff` by 0x0002040810204081 produces: + // a.......b.......c.......d.......e.......f.......g.......h....... + + // .b.......c.......d.......e.......f.......g.......h.............. + + // ..c.......d.......e.......f.......g.......h..................... + + // ...d.......e.......f.......g.......h............................ + + // ....e.......f.......g.......h................................... + + // .....f.......g.......h.......................................... + + // ......g.......h................................................. + + // .......h........................................................ + // ________________________________________________________________ = + // abcdefghbcdefgh.cdefgh..defgh...efgh....fgh.....gh......h....... + // ^^^^^^^^ + // This operation could be replaced with a single PEXT instruction from BMI2 set. + diff = 0x0002040810204081 * diff >> 56; + + return DrawBufferMask(static_cast(diff)); + } + }; + + using FactorStorage = StorageType()>; + using EquationStorage = StorageType()>; + using ColorMaskStorage = StorageType; + static_assert(std::is_same::value && + std::is_same::value, + "Factor and Equation storage must be 64-bit."); + + BlendStateExt(const size_t drawBuffers = 1); + + BlendStateExt(const BlendStateExt &other); + BlendStateExt &operator=(const BlendStateExt &other); + + ///////// Blending Toggle ///////// + + void setEnabled(const bool enabled); + void setEnabledIndexed(const size_t index, const bool enabled); + + ///////// Color Write Mask ///////// + + static constexpr size_t PackColorMask(const bool red, + const bool green, + const bool blue, + const bool alpha) + { + return (red ? 1 : 0) | (green ? 2 : 0) | (blue ? 4 : 0) | (alpha ? 8 : 0); + } + + static constexpr void UnpackColorMask(const size_t value, + bool *red, + bool *green, + bool *blue, + bool *alpha) + { + *red = static_cast(value & 1); + *green = static_cast(value & 2); + *blue = static_cast(value & 4); + *alpha = static_cast(value & 8); + } + + ColorMaskStorage::Type expandColorMaskValue(const bool red, + const bool green, + const bool blue, + const bool alpha) const; + ColorMaskStorage::Type expandColorMaskIndexed(const size_t index) const; + void setColorMask(const bool red, const bool green, const bool blue, const bool alpha); + void setColorMaskIndexed(const size_t index, const uint8_t value); + void setColorMaskIndexed(const size_t index, + const bool red, + const bool green, + const bool blue, + const bool alpha); + uint8_t getColorMaskIndexed(const size_t index) const; + void getColorMaskIndexed(const size_t index, + bool *red, + bool *green, + bool *blue, + bool *alpha) const; + DrawBufferMask compareColorMask(ColorMaskStorage::Type other) const; + + ///////// Blend Equation ///////// + + EquationStorage::Type expandEquationValue(const GLenum mode) const; + EquationStorage::Type expandEquationValue(const gl::BlendEquationType equation) const; + EquationStorage::Type expandEquationColorIndexed(const size_t index) const; + EquationStorage::Type expandEquationAlphaIndexed(const size_t index) const; + void setEquations(const GLenum modeColor, const GLenum modeAlpha); + void setEquationsIndexed(const size_t index, const GLenum modeColor, const GLenum modeAlpha); + void setEquationsIndexed(const size_t index, + const size_t otherIndex, + const BlendStateExt &other); + GLenum getEquationColorIndexed(size_t index) const; + GLenum getEquationAlphaIndexed(size_t index) const; + DrawBufferMask compareEquations(const EquationStorage::Type color, + const EquationStorage::Type alpha) const; + DrawBufferMask compareEquations(const BlendStateExt &other) const + { + return compareEquations(other.mEquationColor, other.mEquationAlpha); + } + + ///////// Blend Factors ///////// + + FactorStorage::Type expandFactorValue(const GLenum func) const; + FactorStorage::Type expandSrcColorIndexed(const size_t index) const; + FactorStorage::Type expandDstColorIndexed(const size_t index) const; + FactorStorage::Type expandSrcAlphaIndexed(const size_t index) const; + FactorStorage::Type expandDstAlphaIndexed(const size_t index) const; + void setFactors(const GLenum srcColor, + const GLenum dstColor, + const GLenum srcAlpha, + const GLenum dstAlpha); + void setFactorsIndexed(const size_t index, + const GLenum srcColor, + const GLenum dstColor, + const GLenum srcAlpha, + const GLenum dstAlpha); + void setFactorsIndexed(const size_t index, const size_t otherIndex, const BlendStateExt &other); + GLenum getSrcColorIndexed(size_t index) const; + GLenum getDstColorIndexed(size_t index) const; + GLenum getSrcAlphaIndexed(size_t index) const; + GLenum getDstAlphaIndexed(size_t index) const; + DrawBufferMask compareFactors(const FactorStorage::Type srcColor, + const FactorStorage::Type dstColor, + const FactorStorage::Type srcAlpha, + const FactorStorage::Type dstAlpha) const; + DrawBufferMask compareFactors(const BlendStateExt &other) const + { + return compareFactors(other.mSrcColor, other.mDstColor, other.mSrcAlpha, other.mDstAlpha); + } + + constexpr FactorStorage::Type getSrcColorBits() const { return mSrcColor; } + constexpr FactorStorage::Type getSrcAlphaBits() const { return mSrcAlpha; } + constexpr FactorStorage::Type getDstColorBits() const { return mDstColor; } + constexpr FactorStorage::Type getDstAlphaBits() const { return mDstAlpha; } + + constexpr EquationStorage::Type getEquationColorBits() const { return mEquationColor; } + constexpr EquationStorage::Type getEquationAlphaBits() const { return mEquationAlpha; } + + constexpr ColorMaskStorage::Type getAllColorMaskBits() const { return mAllColorMask; } + constexpr ColorMaskStorage::Type getColorMaskBits() const { return mColorMask; } + + constexpr DrawBufferMask getAllEnabledMask() const { return mAllEnabledMask; } + constexpr DrawBufferMask getEnabledMask() const { return mEnabledMask; } + + constexpr DrawBufferMask getUsesAdvancedBlendEquationMask() const + { + return mUsesAdvancedBlendEquationMask; + } + + constexpr uint8_t getDrawBufferCount() const { return mDrawBufferCount; } + + constexpr void setSrcColorBits(const FactorStorage::Type srcColor) { mSrcColor = srcColor; } + constexpr void setSrcAlphaBits(const FactorStorage::Type srcAlpha) { mSrcAlpha = srcAlpha; } + constexpr void setDstColorBits(const FactorStorage::Type dstColor) { mDstColor = dstColor; } + constexpr void setDstAlphaBits(const FactorStorage::Type dstAlpha) { mDstAlpha = dstAlpha; } + + constexpr void setEquationColorBits(const EquationStorage::Type equationColor) + { + mEquationColor = equationColor; + } + constexpr void setEquationAlphaBits(const EquationStorage::Type equationAlpha) + { + mEquationAlpha = equationAlpha; + } + + constexpr void setColorMaskBits(const ColorMaskStorage::Type colorMask) + { + mColorMask = colorMask; + } + + constexpr void setEnabledMask(const DrawBufferMask enabledMask) { mEnabledMask = enabledMask; } + + ///////// Data Members ///////// + private: + uint64_t mParameterMask; + + FactorStorage::Type mSrcColor; + FactorStorage::Type mDstColor; + FactorStorage::Type mSrcAlpha; + FactorStorage::Type mDstAlpha; + + EquationStorage::Type mEquationColor; + EquationStorage::Type mEquationAlpha; + + ColorMaskStorage::Type mAllColorMask; + ColorMaskStorage::Type mColorMask; + + DrawBufferMask mAllEnabledMask; + DrawBufferMask mEnabledMask; + + // Cache of whether the blend equation for each index is from KHR_blend_equation_advanced. + DrawBufferMask mUsesAdvancedBlendEquationMask; + + uint8_t mDrawBufferCount; + + [[maybe_unused]] uint32_t kUnused = 0; +}; + +static_assert(sizeof(BlendStateExt) == sizeof(uint64_t) + + (sizeof(BlendStateExt::FactorStorage::Type) * 4 + + sizeof(BlendStateExt::EquationStorage::Type) * 2 + + sizeof(BlendStateExt::ColorMaskStorage::Type) * 2 + + sizeof(DrawBufferMask) * 3 + sizeof(uint8_t)) + + sizeof(uint32_t), + "The BlendStateExt class must not contain gaps."); + +// Used in StateCache +using StorageBuffersMask = angle::BitSet; + +template +using SampleMaskArray = std::array; + +template +using TexLevelArray = std::array; + +using TexLevelMask = angle::BitSet; + +enum class ComponentType +{ + Float = 0, + Int = 1, + UnsignedInt = 2, + NoType = 3, + EnumCount = 4, + InvalidEnum = 4, +}; + +constexpr ComponentType GLenumToComponentType(GLenum componentType) +{ + switch (componentType) + { + case GL_FLOAT: + return ComponentType::Float; + case GL_INT: + return ComponentType::Int; + case GL_UNSIGNED_INT: + return ComponentType::UnsignedInt; + case GL_NONE: + return ComponentType::NoType; + default: + return ComponentType::InvalidEnum; + } +} + +constexpr angle::PackedEnumMap kComponentMasks = {{ + {ComponentType::Float, 0x10001}, + {ComponentType::Int, 0x00001}, + {ComponentType::UnsignedInt, 0x10000}, +}}; + +constexpr size_t kMaxComponentTypeMaskIndex = 16; +using ComponentTypeMask = angle::BitSet; + +ANGLE_INLINE void SetComponentTypeMask(ComponentType type, size_t index, ComponentTypeMask *mask) +{ + ASSERT(index <= kMaxComponentTypeMaskIndex); + *mask &= ~(0x10001 << index); + *mask |= kComponentMasks[type] << index; +} + +ANGLE_INLINE ComponentType GetComponentTypeMask(const ComponentTypeMask &mask, size_t index) +{ + ASSERT(index <= kMaxComponentTypeMaskIndex); + uint32_t mask_bits = static_cast((mask.to_ulong() >> index) & 0x10001); + switch (mask_bits) + { + case 0x10001: + return ComponentType::Float; + case 0x00001: + return ComponentType::Int; + case 0x10000: + return ComponentType::UnsignedInt; + default: + return ComponentType::InvalidEnum; + } +} + +bool ValidateComponentTypeMasks(unsigned long outputTypes, + unsigned long inputTypes, + unsigned long outputMask, + unsigned long inputMask); + +enum class RenderToTextureImageIndex +{ + // The default image of the texture, where data is expected to be. + Default = 0, + + // Intermediate multisampled images for EXT_multisampled_render_to_texture. + // These values must match log2(SampleCount). + IntermediateImage2xMultisampled = 1, + IntermediateImage4xMultisampled = 2, + IntermediateImage8xMultisampled = 3, + IntermediateImage16xMultisampled = 4, + + // We currently only support up to 16xMSAA in backends that use this enum. + InvalidEnum = 5, + EnumCount = 5, +}; + +template +using RenderToTextureImageMap = angle::PackedEnumMap; + +struct ContextID +{ + uint32_t value; +}; + +inline bool operator==(ContextID lhs, ContextID rhs) +{ + return lhs.value == rhs.value; +} + +inline bool operator!=(ContextID lhs, ContextID rhs) +{ + return lhs.value != rhs.value; +} + +inline bool operator<(ContextID lhs, ContextID rhs) +{ + return lhs.value < rhs.value; +} + +constexpr size_t kCubeFaceCount = 6; + +template +using TextureTypeMap = angle::PackedEnumMap; +using TextureMap = TextureTypeMap>; + +// ShaderVector can contain one item per shader. It differs from ShaderMap in that the values are +// not indexed by ShaderType. +template +using ShaderVector = angle::FixedVector(ShaderType::EnumCount)>; + +template +using AttachmentArray = std::array; + +template +using AttachmentVector = angle::FixedVector; + +using AttachmentsMask = angle::BitSet; + +template +using DrawBuffersArray = std::array; + +template +using DrawBuffersVector = angle::FixedVector; + +template +using AttribArray = std::array; + +using ActiveTextureMask = angle::BitSet; + +template +using ActiveTextureArray = std::array; + +using ActiveTextureTypeArray = ActiveTextureArray; + +template +using UniformBuffersArray = std::array; +template +using StorageBuffersArray = std::array; +template +using AtomicCounterBuffersArray = std::array; +using AtomicCounterBufferMask = angle::BitSet; +template +using ImagesArray = std::array; + +using ImageUnitMask = angle::BitSet; + +using SupportedSampleSet = std::set; + +template +using TransformFeedbackBuffersArray = + std::array; + +template +using QueryTypeMap = angle::PackedEnumMap; + +constexpr size_t kBarrierVectorDefaultSize = 16; + +template +using BarrierVector = angle::FastVector; + +using BufferBarrierVector = BarrierVector; + +using SamplerBindingVector = std::vector>; +using BufferVector = std::vector>; + +struct TextureAndLayout +{ + Texture *texture; + GLenum layout; +}; +using TextureBarrierVector = BarrierVector; + +// OffsetBindingPointer.getSize() returns the size specified by the user, which may be larger than +// the size of the bound buffer. This function reduces the returned size to fit the bound buffer if +// necessary. Returns 0 if no buffer is bound or if integer overflow occurs. +GLsizeiptr GetBoundBufferAvailableSize(const OffsetBindingPointer &binding); + +// A texture level index. +template +class LevelIndexWrapper +{ + public: + LevelIndexWrapper() = default; + explicit constexpr LevelIndexWrapper(T levelIndex) : mLevelIndex(levelIndex) {} + constexpr LevelIndexWrapper(const LevelIndexWrapper &other) = default; + constexpr LevelIndexWrapper &operator=(const LevelIndexWrapper &other) = default; + + constexpr T get() const { return mLevelIndex; } + + LevelIndexWrapper &operator++() + { + ++mLevelIndex; + return *this; + } + constexpr bool operator<(const LevelIndexWrapper &other) const + { + return mLevelIndex < other.mLevelIndex; + } + constexpr bool operator<=(const LevelIndexWrapper &other) const + { + return mLevelIndex <= other.mLevelIndex; + } + constexpr bool operator>(const LevelIndexWrapper &other) const + { + return mLevelIndex > other.mLevelIndex; + } + constexpr bool operator>=(const LevelIndexWrapper &other) const + { + return mLevelIndex >= other.mLevelIndex; + } + constexpr bool operator==(const LevelIndexWrapper &other) const + { + return mLevelIndex == other.mLevelIndex; + } + constexpr bool operator!=(const LevelIndexWrapper &other) const + { + return mLevelIndex != other.mLevelIndex; + } + constexpr LevelIndexWrapper operator+(T other) const + { + return LevelIndexWrapper(mLevelIndex + other); + } + constexpr LevelIndexWrapper operator-(T other) const + { + return LevelIndexWrapper(mLevelIndex - other); + } + constexpr T operator-(LevelIndexWrapper other) const { return mLevelIndex - other.mLevelIndex; } + + private: + T mLevelIndex; +}; + +// A GL texture level index. +using LevelIndex = LevelIndexWrapper; + +enum class MultisamplingMode +{ + // Regular multisampling + Regular = 0, + // GL_EXT_multisampled_render_to_texture renderbuffer/texture attachments which perform implicit + // resolve of multisampled data. + MultisampledRenderToTexture, +}; +} // namespace gl + +namespace rx +{ +// A macro that determines whether an object has a given runtime type. +#if defined(__clang__) +# if __has_feature(cxx_rtti) +# define ANGLE_HAS_DYNAMIC_CAST 1 +# endif +#elif !defined(NDEBUG) && (!defined(_MSC_VER) || defined(_CPPRTTI)) && \ + (!defined(__GNUC__) || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3) || \ + defined(__GXX_RTTI)) +# define ANGLE_HAS_DYNAMIC_CAST 1 +#endif + +#ifdef ANGLE_HAS_DYNAMIC_CAST +# define ANGLE_HAS_DYNAMIC_TYPE(type, obj) (dynamic_cast(obj) != nullptr) +# undef ANGLE_HAS_DYNAMIC_CAST +#else +# define ANGLE_HAS_DYNAMIC_TYPE(type, obj) (obj != nullptr) +#endif + +// Downcast a base implementation object (EG TextureImpl to TextureD3D) +template +inline DestT *GetAs(SrcT *src) +{ + ASSERT(ANGLE_HAS_DYNAMIC_TYPE(DestT *, src)); + return static_cast(src); +} + +template +inline const DestT *GetAs(const SrcT *src) +{ + ASSERT(ANGLE_HAS_DYNAMIC_TYPE(const DestT *, src)); + return static_cast(src); +} + +#undef ANGLE_HAS_DYNAMIC_TYPE + +// Downcast a GL object to an Impl (EG gl::Texture to rx::TextureD3D) +template +inline DestT *GetImplAs(SrcT *src) +{ + return GetAs(src->getImplementation()); +} + +template +inline DestT *SafeGetImplAs(SrcT *src) +{ + return src != nullptr ? GetAs(src->getImplementation()) : nullptr; +} + +} // namespace rx + +#include "angletypes.inc" + +namespace angle +{ +// Zero-based for better array indexing +enum FramebufferBinding +{ + FramebufferBindingRead = 0, + FramebufferBindingDraw, + FramebufferBindingSingletonMax, + FramebufferBindingBoth = FramebufferBindingSingletonMax, + FramebufferBindingMax, + FramebufferBindingUnknown = FramebufferBindingMax, +}; + +inline FramebufferBinding EnumToFramebufferBinding(GLenum enumValue) +{ + switch (enumValue) + { + case GL_READ_FRAMEBUFFER: + return FramebufferBindingRead; + case GL_DRAW_FRAMEBUFFER: + return FramebufferBindingDraw; + case GL_FRAMEBUFFER: + return FramebufferBindingBoth; + default: + UNREACHABLE(); + return FramebufferBindingUnknown; + } +} + +inline GLenum FramebufferBindingToEnum(FramebufferBinding binding) +{ + switch (binding) + { + case FramebufferBindingRead: + return GL_READ_FRAMEBUFFER; + case FramebufferBindingDraw: + return GL_DRAW_FRAMEBUFFER; + case FramebufferBindingBoth: + return GL_FRAMEBUFFER; + default: + UNREACHABLE(); + return GL_NONE; + } +} + +template +class DestroyThenDelete +{ + public: + DestroyThenDelete() = default; + DestroyThenDelete(const ContextT *context) : mContext(context) {} + + void operator()(ObjT *obj) + { + (void)(obj->onDestroy(mContext)); + delete obj; + } + + private: + const ContextT *mContext = nullptr; +}; + +template +using UniqueObjectPointer = std::unique_ptr>; + +} // namespace angle + +namespace gl +{ +class State; +} // namespace gl + +#endif // LIBANGLE_ANGLETYPES_H_ diff --git a/gfx/angle/checkout/src/libANGLE/angletypes.inc b/gfx/angle/checkout/src/libANGLE/angletypes.inc new file mode 100644 index 0000000000..862a3214a1 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/angletypes.inc @@ -0,0 +1,35 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// angletypes.inc : Inline definitions of some functions from angletypes.h + +namespace gl +{ + +inline bool operator==(const Rectangle &a, const Rectangle &b) +{ + return a.x == b.x && + a.y == b.y && + a.width == b.width && + a.height == b.height; +} + +inline bool operator!=(const Rectangle &a, const Rectangle &b) +{ + return !(a == b); +} + +inline bool operator==(const SamplerState &a, const SamplerState &b) +{ + return memcmp(&a, &b, sizeof(SamplerState)) == 0; +} + +inline bool operator!=(const SamplerState &a, const SamplerState &b) +{ + return !(a == b); +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/capture/FrameCapture.h b/gfx/angle/checkout/src/libANGLE/capture/FrameCapture.h new file mode 100644 index 0000000000..a9b0348b6a --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/capture/FrameCapture.h @@ -0,0 +1,1208 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// FrameCapture.h: +// ANGLE Frame capture interface. +// + +#ifndef LIBANGLE_FRAME_CAPTURE_H_ +#define LIBANGLE_FRAME_CAPTURE_H_ + +#include "common/PackedEnums.h" +#include "common/system_utils.h" +#include "libANGLE/Context.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/capture/frame_capture_utils_autogen.h" +#include "libANGLE/entry_points_utils.h" + +namespace gl +{ +enum class BigGLEnum; +enum class GLESEnum; +} // namespace gl + +namespace angle +{ + +using ParamData = std::vector>; +struct ParamCapture : angle::NonCopyable +{ + ParamCapture(); + ParamCapture(const char *nameIn, ParamType typeIn); + ~ParamCapture(); + + ParamCapture(ParamCapture &&other); + ParamCapture &operator=(ParamCapture &&other); + + std::string name; + ParamType type; + ParamValue value; + gl::GLESEnum enumGroup; // only used for param type GLenum, GLboolean and GLbitfield + gl::BigGLEnum bigGLEnum; // only used for param type GLenum, GLboolean and GLbitfield + ParamData data; + int dataNElements = 0; + int arrayClientPointerIndex = -1; + size_t readBufferSizeBytes = 0; +}; + +class ParamBuffer final : angle::NonCopyable +{ + public: + ParamBuffer(); + ~ParamBuffer(); + + ParamBuffer(ParamBuffer &&other); + ParamBuffer &operator=(ParamBuffer &&other); + + template + void addValueParam(const char *paramName, ParamType paramType, T paramValue); + template + void setValueParamAtIndex(const char *paramName, ParamType paramType, T paramValue, int index); + template + void addEnumParam(const char *paramName, + gl::GLESEnum enumGroup, + ParamType paramType, + T paramValue); + template + void addEnumParam(const char *paramName, + gl::BigGLEnum enumGroup, + ParamType paramType, + T paramValue); + + ParamCapture &getParam(const char *paramName, ParamType paramType, int index); + const ParamCapture &getParam(const char *paramName, ParamType paramType, int index) const; + ParamCapture &getParamFlexName(const char *paramName1, + const char *paramName2, + ParamType paramType, + int index); + const ParamCapture &getParamFlexName(const char *paramName1, + const char *paramName2, + ParamType paramType, + int index) const; + const ParamCapture &getReturnValue() const { return mReturnValueCapture; } + + void addParam(ParamCapture &¶m); + void addReturnValue(ParamCapture &&returnValue); + bool hasClientArrayData() const { return mClientArrayDataParam != -1; } + ParamCapture &getClientArrayPointerParameter(); + size_t getReadBufferSize() const { return mReadBufferSize; } + + const std::vector &getParamCaptures() const { return mParamCaptures; } + + // These helpers allow us to track the ID of the buffer that was active when + // MapBufferRange was called. We'll use it during replay to track the + // buffer's contents, as they can be modified by the host. + void setMappedBufferID(gl::BufferID bufferID) { mMappedBufferID = bufferID; } + gl::BufferID getMappedBufferID() const { return mMappedBufferID; } + + private: + std::vector mParamCaptures; + ParamCapture mReturnValueCapture; + int mClientArrayDataParam = -1; + size_t mReadBufferSize = 0; + gl::BufferID mMappedBufferID; +}; + +struct CallCapture +{ + CallCapture(EntryPoint entryPointIn, ParamBuffer &¶msIn); + CallCapture(const std::string &customFunctionNameIn, ParamBuffer &¶msIn); + ~CallCapture(); + + CallCapture(CallCapture &&other); + CallCapture &operator=(CallCapture &&other); + + const char *name() const; + + EntryPoint entryPoint; + std::string customFunctionName; + ParamBuffer params; + bool isActive = true; +}; + +class ReplayContext +{ + public: + ReplayContext(size_t readBufferSizebytes, const gl::AttribArray &clientArraysSizebytes); + ~ReplayContext(); + + template + T getReadBufferPointer(const ParamCapture ¶m) + { + ASSERT(param.readBufferSizeBytes > 0); + ASSERT(mReadBuffer.size() >= param.readBufferSizeBytes); + return reinterpret_cast(mReadBuffer.data()); + } + template + T getAsConstPointer(const ParamCapture ¶m) + { + if (param.arrayClientPointerIndex != -1) + { + return reinterpret_cast(mClientArraysBuffer[param.arrayClientPointerIndex].data()); + } + + if (!param.data.empty()) + { + ASSERT(param.data.size() == 1); + return reinterpret_cast(param.data[0].data()); + } + + return nullptr; + } + + template + T getAsPointerConstPointer(const ParamCapture ¶m) + { + static_assert(sizeof(typename std::remove_pointer::type) == sizeof(uint8_t *), + "pointer size not match!"); + + ASSERT(!param.data.empty()); + mPointersBuffer.clear(); + mPointersBuffer.reserve(param.data.size()); + for (const std::vector &data : param.data) + { + mPointersBuffer.emplace_back(data.data()); + } + return reinterpret_cast(mPointersBuffer.data()); + } + + gl::AttribArray> &getClientArraysBuffer() { return mClientArraysBuffer; } + + private: + std::vector mReadBuffer; + std::vector mPointersBuffer; + gl::AttribArray> mClientArraysBuffer; +}; + +// Helper to use unique IDs for each local data variable. +class DataCounters final : angle::NonCopyable +{ + public: + DataCounters(); + ~DataCounters(); + + int getAndIncrement(EntryPoint entryPoint, const std::string ¶mName); + + private: + // + using Counter = std::pair; + std::map mData; +}; + +constexpr int kStringsNotFound = -1; +class StringCounters final : angle::NonCopyable +{ + public: + StringCounters(); + ~StringCounters(); + + int getStringCounter(const std::vector &str); + void setStringCounter(const std::vector &str, int &counter); + + private: + std::map, int> mStringCounterMap; +}; + +class DataTracker final : angle::NonCopyable +{ + public: + DataTracker(); + ~DataTracker(); + + DataCounters &getCounters() { return mCounters; } + StringCounters &getStringCounters() { return mStringCounters; } + + private: + DataCounters mCounters; + StringCounters mStringCounters; +}; + +class ReplayWriter final : angle::NonCopyable +{ + public: + ReplayWriter(); + ~ReplayWriter(); + + void setSourceFileSizeThreshold(size_t sourceFileSizeThreshold); + void setFilenamePattern(const std::string &pattern); + void setCaptureLabel(const std::string &label); + void setSourcePrologue(const std::string &prologue); + void setHeaderPrologue(const std::string &prologue); + + void addPublicFunction(const std::string &functionProto, + const std::stringstream &headerStream, + const std::stringstream &bodyStream); + void addPrivateFunction(const std::string &functionProto, + const std::stringstream &headerStream, + const std::stringstream &bodyStream); + std::string getInlineVariableName(EntryPoint entryPoint, const std::string ¶mName); + + std::string getInlineStringSetVariableName(EntryPoint entryPoint, + const std::string ¶mName, + const std::vector &strings, + bool *isNewEntryOut); + + void saveFrame(); + void saveFrameIfFull(); + void saveIndexFilesAndHeader(); + void saveSetupFile(); + + std::vector getAndResetWrittenFiles(); + + private: + static std::string GetVarName(EntryPoint entryPoint, const std::string ¶mName, int counter); + + void saveHeader(); + void writeReplaySource(const std::string &filename); + void addWrittenFile(const std::string &filename); + size_t getStoredReplaySourceSize() const; + + size_t mSourceFileSizeThreshold; + size_t mFrameIndex; + + DataTracker mDataTracker; + std::string mFilenamePattern; + std::string mCaptureLabel; + std::string mSourcePrologue; + std::string mHeaderPrologue; + + std::vector mReplayHeaders; + std::vector mGlobalVariableDeclarations; + + std::vector mPublicFunctionPrototypes; + std::vector mPublicFunctions; + + std::vector mPrivateFunctionPrototypes; + std::vector mPrivateFunctions; + + std::vector mWrittenFiles; +}; + +using BufferCalls = std::map>; + +// true means mapped, false means unmapped +using BufferMapStatusMap = std::map; + +using FenceSyncSet = std::set; +using FenceSyncCalls = std::map>; + +// For default uniforms, we need to track which ones are dirty, and the series of calls to reset. +// Each program has unique default uniforms, and each uniform has one or more locations in the +// default buffer. For reset efficiency, we track only the uniforms dirty by location, per program. + +// A set of all default uniforms (per program) that were modified during the run +using DefaultUniformLocationsSet = std::set; +using DefaultUniformLocationsPerProgramMap = + std::map; + +// A map of programs which maps to locations and their reset calls +using DefaultUniformCallsPerLocationMap = std::map>; +using DefaultUniformCallsPerProgramMap = + std::map; + +using DefaultUniformBaseLocationMap = + std::map, gl::UniformLocation>; + +using ResourceSet = std::set; +using ResourceCalls = std::map>; + +class TrackedResource final : angle::NonCopyable +{ + public: + TrackedResource(); + ~TrackedResource(); + + const ResourceSet &getStartingResources() const { return mStartingResources; } + ResourceSet &getStartingResources() { return mStartingResources; } + const ResourceSet &getNewResources() const { return mNewResources; } + ResourceSet &getNewResources() { return mNewResources; } + const ResourceSet &getResourcesToRegen() const { return mResourcesToRegen; } + ResourceSet &getResourcesToRegen() { return mResourcesToRegen; } + const ResourceSet &getResourcesToRestore() const { return mResourcesToRestore; } + ResourceSet &getResourcesToRestore() { return mResourcesToRestore; } + + void setGennedResource(GLuint id); + void setDeletedResource(GLuint id); + void setModifiedResource(GLuint id); + bool resourceIsGenerated(GLuint id); + + ResourceCalls &getResourceRegenCalls() { return mResourceRegenCalls; } + ResourceCalls &getResourceRestoreCalls() { return mResourceRestoreCalls; } + + private: + // Resource regen calls will gen a resource + ResourceCalls mResourceRegenCalls; + // Resource restore calls will restore the contents of a resource + ResourceCalls mResourceRestoreCalls; + + // Resources created during startup + ResourceSet mStartingResources; + + // Resources created during the run that need to be deleted + ResourceSet mNewResources; + // Resources deleted during the run that need to be recreated + ResourceSet mResourcesToRegen; + // Resources modified during the run that need to be restored + ResourceSet mResourcesToRestore; +}; + +using TrackedResourceArray = + std::array(ResourceIDType::EnumCount)>; + +// Helper to track resource changes during the capture +class ResourceTracker final : angle::NonCopyable +{ + public: + ResourceTracker(); + ~ResourceTracker(); + + BufferCalls &getBufferMapCalls() { return mBufferMapCalls; } + BufferCalls &getBufferUnmapCalls() { return mBufferUnmapCalls; } + + std::vector &getBufferBindingCalls() { return mBufferBindingCalls; } + + void setBufferMapped(gl::ContextID contextID, GLuint id); + void setBufferUnmapped(gl::ContextID contextID, GLuint id); + + bool getStartingBuffersMappedCurrent(GLuint id) const; + bool getStartingBuffersMappedInitial(GLuint id) const; + + void setStartingBufferMapped(GLuint id, bool mapped) + { + // Track the current state (which will change throughout the trace) + mStartingBuffersMappedCurrent[id] = mapped; + + // And the initial state, to compare during frame loop reset + mStartingBuffersMappedInitial[id] = mapped; + } + + void onShaderProgramAccess(gl::ShaderProgramID shaderProgramID); + uint32_t getMaxShaderPrograms() const { return mMaxShaderPrograms; } + + FenceSyncSet &getStartingFenceSyncs() { return mStartingFenceSyncs; } + FenceSyncCalls &getFenceSyncRegenCalls() { return mFenceSyncRegenCalls; } + FenceSyncSet &getFenceSyncsToRegen() { return mFenceSyncsToRegen; } + void setDeletedFenceSync(GLsync sync); + + DefaultUniformLocationsPerProgramMap &getDefaultUniformsToReset() + { + return mDefaultUniformsToReset; + } + DefaultUniformCallsPerLocationMap &getDefaultUniformResetCalls(gl::ShaderProgramID id) + { + return mDefaultUniformResetCalls[id]; + } + void setModifiedDefaultUniform(gl::ShaderProgramID programID, gl::UniformLocation location); + void setDefaultUniformBaseLocation(gl::ShaderProgramID programID, + gl::UniformLocation location, + gl::UniformLocation baseLocation); + gl::UniformLocation getDefaultUniformBaseLocation(gl::ShaderProgramID programID, + gl::UniformLocation location) + { + ASSERT(mDefaultUniformBaseLocations.find({programID, location}) != + mDefaultUniformBaseLocations.end()); + return mDefaultUniformBaseLocations[{programID, location}]; + } + + TrackedResource &getTrackedResource(gl::ContextID contextID, ResourceIDType type); + + void getContextIDs(std::set &idsOut); + + std::map &getImageToAttribTable() { return mMatchImageToAttribs; } + + std::map &getTextureIDToImageTable() { return mMatchTextureIDToImage; } + + private: + // Buffer map calls will map a buffer with correct offset, length, and access flags + BufferCalls mBufferMapCalls; + // Buffer unmap calls will bind and unmap a given buffer + BufferCalls mBufferUnmapCalls; + + // Buffer binding calls to restore bindings recorded during MEC + std::vector mBufferBindingCalls; + + // Whether a given buffer was mapped at the start of the trace + BufferMapStatusMap mStartingBuffersMappedInitial; + // The status of buffer mapping throughout the trace, modified with each Map/Unmap call + BufferMapStatusMap mStartingBuffersMappedCurrent; + + // Maximum accessed shader program ID. + uint32_t mMaxShaderPrograms = 0; + + // Fence sync objects created during MEC setup + FenceSyncSet mStartingFenceSyncs; + // Fence sync regen calls will create a fence sync objects + FenceSyncCalls mFenceSyncRegenCalls; + // Fence syncs to regen are a list of starting fence sync objects that were deleted and need to + // be regen'ed. + FenceSyncSet mFenceSyncsToRegen; + + // Default uniforms that were modified during the run + DefaultUniformLocationsPerProgramMap mDefaultUniformsToReset; + // Calls per default uniform to return to original state + DefaultUniformCallsPerProgramMap mDefaultUniformResetCalls; + + // Base location of arrayed uniforms + DefaultUniformBaseLocationMap mDefaultUniformBaseLocations; + + // Tracked resources per context + TrackedResourceArray mTrackedResourcesShared; + std::map mTrackedResourcesPerContext; + + std::map mMatchImageToAttribs; + std::map mMatchTextureIDToImage; +}; + +// Used by the CPP replay to filter out unnecessary code. +using HasResourceTypeMap = angle::PackedEnumBitSet; + +// Map of ResourceType to IDs and range of setup calls +using ResourceIDToSetupCallsMap = + PackedEnumMap>>; + +// Map of buffer ID to offset and size used when mapped +using BufferDataMap = std::map>; + +// A dictionary of sources indexed by shader type. +using ProgramSources = gl::ShaderMap; + +// Maps from IDs to sources. +using ShaderSourceMap = std::map; +using ProgramSourceMap = std::map; + +// Map from textureID to level and data +using TextureLevels = std::map>; +using TextureLevelDataMap = std::map; + +struct SurfaceParams +{ + gl::Extents extents; + egl::ColorSpace colorSpace; +}; + +// Map from ContextID to SurfaceParams +using SurfaceParamsMap = std::map; + +using CallVector = std::vector *>; + +// A map from API entry point to calls +using CallResetMap = std::map>; + +// StateResetHelper provides a simple way to track whether an entry point has been called during the +// trace, along with the reset calls to get it back to starting state. This is useful for things +// that are one dimensional, like context bindings or context state. +class StateResetHelper final : angle::NonCopyable +{ + public: + StateResetHelper(); + ~StateResetHelper(); + + const std::set &getDirtyEntryPoints() const { return mDirtyEntryPoints; } + void setEntryPointDirty(EntryPoint entryPoint) { mDirtyEntryPoints.insert(entryPoint); } + + CallResetMap &getResetCalls() { return mResetCalls; } + const CallResetMap &getResetCalls() const { return mResetCalls; } + + void setDefaultResetCalls(const gl::Context *context, angle::EntryPoint); + + private: + // Dirty state per entry point + std::set mDirtyEntryPoints; + + // Reset calls per API entry point + CallResetMap mResetCalls; +}; + +class FrameCapture final : angle::NonCopyable +{ + public: + FrameCapture(); + ~FrameCapture(); + + std::vector &getSetupCalls() { return mSetupCalls; } + void clearSetupCalls() { mSetupCalls.clear(); } + + StateResetHelper &getStateResetHelper() { return mStateResetHelper; } + + void reset(); + + private: + std::vector mSetupCalls; + + StateResetHelper mStateResetHelper; +}; + +// Page range inside a coherent buffer +struct PageRange +{ + PageRange(size_t start, size_t end); + ~PageRange(); + + // Relative start page + size_t start; + + // First page after the relative end + size_t end; +}; + +// Memory address range defined by start and size +struct AddressRange +{ + AddressRange(); + AddressRange(uintptr_t start, size_t size); + ~AddressRange(); + + uintptr_t end(); + + uintptr_t start; + size_t size; +}; + +// Used to handle protection of buffers that overlap in pages. +enum class PageSharingType +{ + NoneShared, + FirstShared, + LastShared, + FirstAndLastShared +}; + +class CoherentBuffer +{ + public: + CoherentBuffer(uintptr_t start, size_t size, size_t pageSize); + ~CoherentBuffer(); + + // Sets the a range in the buffer clean and protects a selected range + void protectPageRange(const PageRange &pageRange); + + // Sets a page dirty state and sets it's protection + void setDirty(size_t relativePage, bool dirty); + + // Removes protection + void removeProtection(PageSharingType sharingType); + + bool contains(size_t page, size_t *relativePage); + bool isDirty(); + + // Returns dirty page ranges + std::vector getDirtyPageRanges(); + + // Calculates address range from page range + AddressRange getDirtyAddressRange(const PageRange &dirtyPageRange); + AddressRange getRange(); + + private: + // Actual buffer start and size + AddressRange mRange; + + // Start and size of page aligned protected area + AddressRange mProtectionRange; + + // Start and end of protection in relative pages, calculated from mProtectionRange. + size_t mProtectionStartPage; + size_t mProtectionEndPage; + + size_t mPageCount; + size_t mPageSize; + + // Clean pages are protected + std::vector mDirtyPages; +}; + +class CoherentBufferTracker final : angle::NonCopyable +{ + public: + CoherentBufferTracker(); + ~CoherentBufferTracker(); + + bool isDirty(gl::BufferID id); + void addBuffer(gl::BufferID id, uintptr_t start, size_t size); + void removeBuffer(gl::BufferID id); + void disable(); + void enable(); + void onEndFrame(); + + private: + // Detect overlapping pages when removing protection + PageSharingType doesBufferSharePage(gl::BufferID id); + + // Returns a map to found buffers and the corresponding pages for a given address. + // For addresses that are in a page shared by 2 buffers, 2 results are returned. + HashMap, size_t> getBufferPagesForAddress(uintptr_t address); + PageFaultHandlerRangeType handleWrite(uintptr_t address); + bool haveBuffer(gl::BufferID id); + + public: + std::mutex mMutex; + HashMap> mBuffers; + + private: + bool mEnabled = false; + std::unique_ptr mPageFaultHandler; + size_t mPageSize; +}; + +// Shared class for any items that need to be tracked by FrameCapture across shared contexts +class FrameCaptureShared final : angle::NonCopyable +{ + public: + FrameCaptureShared(); + ~FrameCaptureShared(); + + void captureCall(const gl::Context *context, CallCapture &&call, bool isCallValid); + void checkForCaptureTrigger(); + void onEndFrame(const gl::Context *context); + void onDestroyContext(const gl::Context *context); + void onMakeCurrent(const gl::Context *context, const egl::Surface *drawSurface); + bool enabled() const { return mEnabled; } + + bool isCapturing() const; + void replay(gl::Context *context); + uint32_t getFrameCount() const; + + // Returns a frame index starting from "1" as the first frame. + uint32_t getReplayFrameIndex() const; + + void trackBufferMapping(const gl::Context *context, + CallCapture *call, + gl::BufferID id, + gl::Buffer *buffer, + GLintptr offset, + GLsizeiptr length, + bool writable, + bool coherent); + + void trackTextureUpdate(const gl::Context *context, const CallCapture &call); + void trackDefaultUniformUpdate(const gl::Context *context, const CallCapture &call); + void trackVertexArrayUpdate(const gl::Context *context, const CallCapture &call); + + const std::string &getShaderSource(gl::ShaderProgramID id) const; + void setShaderSource(gl::ShaderProgramID id, std::string sources); + + const ProgramSources &getProgramSources(gl::ShaderProgramID id) const; + void setProgramSources(gl::ShaderProgramID id, ProgramSources sources); + + // Load data from a previously stored texture level + const std::vector &retrieveCachedTextureLevel(gl::TextureID id, + gl::TextureTarget target, + GLint level); + + // Create new texture level data and copy the source into it + void copyCachedTextureLevel(const gl::Context *context, + gl::TextureID srcID, + GLint srcLevel, + gl::TextureID dstID, + GLint dstLevel, + const CallCapture &call); + + // Create the location that should be used to cache texture level data + std::vector &getCachedTextureLevelData(gl::Texture *texture, + gl::TextureTarget target, + GLint level, + EntryPoint entryPoint); + + // Capture coherent buffer storages + void captureCoherentBufferSnapshot(const gl::Context *context, gl::BufferID bufferID); + + // Remove any cached texture levels on deletion + void deleteCachedTextureLevelData(gl::TextureID id); + + void eraseBufferDataMapEntry(const gl::BufferID bufferId) + { + const auto &bufferDataInfo = mBufferDataMap.find(bufferId); + if (bufferDataInfo != mBufferDataMap.end()) + { + mBufferDataMap.erase(bufferDataInfo); + } + } + + bool hasBufferData(gl::BufferID bufferID) + { + const auto &bufferDataInfo = mBufferDataMap.find(bufferID); + if (bufferDataInfo != mBufferDataMap.end()) + { + return true; + } + return false; + } + + std::pair getBufferDataOffsetAndLength(gl::BufferID bufferID) + { + const auto &bufferDataInfo = mBufferDataMap.find(bufferID); + ASSERT(bufferDataInfo != mBufferDataMap.end()); + return bufferDataInfo->second; + } + + void setCaptureActive() { mCaptureActive = true; } + void setCaptureInactive() { mCaptureActive = false; } + bool isCaptureActive() { return mCaptureActive; } + bool usesMidExecutionCapture() { return mCaptureStartFrame > 1; } + + gl::ContextID getWindowSurfaceContextID() const { return mWindowSurfaceContextID; } + + void markResourceSetupCallsInactive(std::vector *setupCalls, + ResourceIDType type, + GLuint id, + gl::Range range); + + void updateReadBufferSize(size_t readBufferSize) + { + mReadBufferSize = std::max(mReadBufferSize, readBufferSize); + } + + template + void handleGennedResource(const gl::Context *context, ResourceType resourceID) + { + if (isCaptureActive()) + { + ResourceIDType idType = GetResourceIDTypeFromType::IDType; + TrackedResource &tracker = mResourceTracker.getTrackedResource(context->id(), idType); + tracker.setGennedResource(resourceID.value); + } + } + + template + bool resourceIsGenerated(const gl::Context *context, ResourceType resourceID) + { + ResourceIDType idType = GetResourceIDTypeFromType::IDType; + TrackedResource &tracker = mResourceTracker.getTrackedResource(context->id(), idType); + return tracker.resourceIsGenerated(resourceID.value); + } + + template + void handleDeletedResource(const gl::Context *context, ResourceType resourceID) + { + if (isCaptureActive()) + { + ResourceIDType idType = GetResourceIDTypeFromType::IDType; + TrackedResource &tracker = mResourceTracker.getTrackedResource(context->id(), idType); + tracker.setDeletedResource(resourceID.value); + } + } + + private: + void writeJSON(const gl::Context *context); + void writeCppReplayIndexFiles(const gl::Context *context, bool writeResetContextCall); + void writeMainContextCppReplay(const gl::Context *context, + const std::vector &setupCalls, + StateResetHelper &StateResetHelper); + + void captureClientArraySnapshot(const gl::Context *context, + size_t vertexCount, + size_t instanceCount); + void captureMappedBufferSnapshot(const gl::Context *context, const CallCapture &call); + + void copyCompressedTextureData(const gl::Context *context, const CallCapture &call); + void captureCompressedTextureData(const gl::Context *context, const CallCapture &call); + + void reset(); + void maybeOverrideEntryPoint(const gl::Context *context, + CallCapture &call, + std::vector &newCalls); + void maybeCapturePreCallUpdates(const gl::Context *context, + CallCapture &call, + std::vector *shareGroupSetupCalls, + ResourceIDToSetupCallsMap *resourceIDToSetupCalls); + template + void maybeGenResourceOnBind(const gl::Context *context, CallCapture &call); + void maybeCapturePostCallUpdates(const gl::Context *context); + void maybeCaptureDrawArraysClientData(const gl::Context *context, + CallCapture &call, + size_t instanceCount); + void maybeCaptureDrawElementsClientData(const gl::Context *context, + CallCapture &call, + size_t instanceCount); + void maybeCaptureCoherentBuffers(const gl::Context *context); + void updateCopyImageSubData(CallCapture &call); + void overrideProgramBinary(const gl::Context *context, + CallCapture &call, + std::vector &outCalls); + void updateResourceCountsFromParamCapture(const ParamCapture ¶m, ResourceIDType idType); + void updateResourceCountsFromCallCapture(const CallCapture &call); + + void runMidExecutionCapture(const gl::Context *context); + + void scanSetupCalls(const gl::Context *context, std::vector &setupCalls); + + static void ReplayCall(gl::Context *context, + ReplayContext *replayContext, + const CallCapture &call); + + std::vector mFrameCalls; + gl::ContextID mLastContextId; + + // We save one large buffer of binary data for the whole CPP replay. + // This simplifies a lot of file management. + std::vector mBinaryData; + + bool mEnabled; + bool mSerializeStateEnabled; + std::string mOutDirectory; + std::string mCaptureLabel; + bool mCompression; + gl::AttribArray mClientVertexArrayMap; + uint32_t mFrameIndex; + uint32_t mCaptureStartFrame; + uint32_t mCaptureEndFrame; + bool mIsFirstFrame = true; + bool mWroteIndexFile = false; + SurfaceParamsMap mDrawSurfaceParams; + gl::AttribArray mClientArraySizes; + size_t mReadBufferSize; + HasResourceTypeMap mHasResourceType; + ResourceIDToSetupCallsMap mResourceIDToSetupCalls; + BufferDataMap mBufferDataMap; + bool mValidateSerializedState = false; + std::string mValidationExpression; + bool mTrimEnabled = true; + PackedEnumMap mMaxAccessedResourceIDs; + CoherentBufferTracker mCoherentBufferTracker; + + ResourceTracker mResourceTracker; + ReplayWriter mReplayWriter; + + // If you don't know which frame you want to start capturing at, use the capture trigger. + // Initialize it to the number of frames you want to capture, and then clear the value to 0 when + // you reach the content you want to capture. Currently only available on Android. + uint32_t mCaptureTrigger; + + bool mCaptureActive; + std::vector mActiveFrameIndices; + + // Cache most recently compiled and linked sources. + ShaderSourceMap mCachedShaderSource; + ProgramSourceMap mCachedProgramSources; + + gl::ContextID mWindowSurfaceContextID; + + std::vector mShareGroupSetupCalls; +}; + +template +void CaptureCallToFrameCapture(CaptureFuncT captureFunc, + bool isCallValid, + gl::Context *context, + ArgsT... captureParams) +{ + FrameCaptureShared *frameCaptureShared = context->getShareGroup()->getFrameCaptureShared(); + if (!frameCaptureShared->isCapturing()) + { + return; + } + + CallCapture call = captureFunc(context->getState(), isCallValid, captureParams...); + + frameCaptureShared->captureCall(context, std::move(call), isCallValid); +} + +template +void ParamBuffer::addValueParam(const char *paramName, ParamType paramType, T paramValue) +{ + ParamCapture capture(paramName, paramType); + InitParamValue(paramType, paramValue, &capture.value); + mParamCaptures.emplace_back(std::move(capture)); +} + +template +void ParamBuffer::setValueParamAtIndex(const char *paramName, + ParamType paramType, + T paramValue, + int index) +{ + ASSERT(mParamCaptures.size() > static_cast(index)); + + ParamCapture capture(paramName, paramType); + InitParamValue(paramType, paramValue, &capture.value); + mParamCaptures[index] = std::move(capture); +} + +template +void ParamBuffer::addEnumParam(const char *paramName, + gl::GLESEnum enumGroup, + ParamType paramType, + T paramValue) +{ + ParamCapture capture(paramName, paramType); + InitParamValue(paramType, paramValue, &capture.value); + capture.enumGroup = enumGroup; + mParamCaptures.emplace_back(std::move(capture)); +} + +template +void ParamBuffer::addEnumParam(const char *paramName, + gl::BigGLEnum enumGroup, + ParamType paramType, + T paramValue) +{ + ParamCapture capture(paramName, paramType); + InitParamValue(paramType, paramValue, &capture.value); + capture.bigGLEnum = enumGroup; + mParamCaptures.emplace_back(std::move(capture)); +} + +// Pointer capture helpers. +void CaptureMemory(const void *source, size_t size, ParamCapture *paramCapture); +void CaptureString(const GLchar *str, ParamCapture *paramCapture); +void CaptureStringLimit(const GLchar *str, uint32_t limit, ParamCapture *paramCapture); +void CaptureVertexPointerGLES1(const gl::State &glState, + gl::ClientVertexArrayType type, + const void *pointer, + ParamCapture *paramCapture); + +gl::Program *GetProgramForCapture(const gl::State &glState, gl::ShaderProgramID handle); + +// For GetIntegerv, GetFloatv, etc. +void CaptureGetParameter(const gl::State &glState, + GLenum pname, + size_t typeSize, + ParamCapture *paramCapture); + +void CaptureGetActiveUniformBlockivParameters(const gl::State &glState, + gl::ShaderProgramID handle, + gl::UniformBlockIndex uniformBlockIndex, + GLenum pname, + ParamCapture *paramCapture); + +template +void CaptureClearBufferValue(GLenum buffer, const T *value, ParamCapture *paramCapture) +{ + // Per the spec, color buffers have a vec4, the rest a single value + uint32_t valueSize = (buffer == GL_COLOR) ? 4 : 1; + CaptureMemory(value, valueSize * sizeof(T), paramCapture); +} + +void CaptureGenHandlesImpl(GLsizei n, GLuint *handles, ParamCapture *paramCapture); + +template +void CaptureGenHandles(GLsizei n, T *handles, ParamCapture *paramCapture) +{ + paramCapture->dataNElements = n; + CaptureGenHandlesImpl(n, reinterpret_cast(handles), paramCapture); +} + +template +void CaptureArray(T *elements, GLsizei n, ParamCapture *paramCapture) +{ + paramCapture->dataNElements = n; + CaptureMemory(elements, n * sizeof(T), paramCapture); +} + +void CaptureShaderStrings(GLsizei count, + const GLchar *const *strings, + const GLint *length, + ParamCapture *paramCapture); + +template +void WriteParamValueReplay(std::ostream &os, const CallCapture &call, T value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + GLboolean value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + GLboolean *value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + const void *value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + void *value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + const GLfloat *value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + const GLint *value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + GLsizei *value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + const GLuint *value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + GLDEBUGPROCKHR value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + GLDEBUGPROC value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + gl::BufferID value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + gl::FenceNVID value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + gl::FramebufferID value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + gl::MemoryObjectID value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + gl::ProgramPipelineID value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + gl::QueryID value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + gl::RenderbufferID value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + gl::SamplerID value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + gl::SemaphoreID value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + gl::ShaderProgramID value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + gl::TextureID value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + gl::TransformFeedbackID value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + gl::VertexArrayID value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + gl::UniformLocation value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + gl::UniformBlockIndex value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + GLsync value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + GLeglImageOES value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + GLubyte value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + EGLContext value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + EGLContext value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + EGLContext value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + EGLDEBUGPROCKHR value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + EGLGetBlobFuncANDROID value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + EGLSetBlobFuncANDROID value); +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + EGLClientBuffer value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + EGLConfig value); + +template <> +void WriteParamValueReplay(std::ostream &os, + const CallCapture &call, + EGLSurface value); + +// General fallback for any unspecific type. +template +void WriteParamValueReplay(std::ostream &os, const CallCapture &call, T value) +{ + os << value; +} +} // namespace angle + +template +void CaptureTextureAndSamplerParameter_params(GLenum pname, + const T *param, + angle::ParamCapture *paramCapture) +{ + if (pname == GL_TEXTURE_BORDER_COLOR || pname == GL_TEXTURE_CROP_RECT_OES) + { + CaptureMemory(param, sizeof(T) * 4, paramCapture); + } + else + { + CaptureMemory(param, sizeof(T), paramCapture); + } +} + +#endif // LIBANGLE_FRAME_CAPTURE_H_ diff --git a/gfx/angle/checkout/src/libANGLE/capture/FrameCapture_mock.cpp b/gfx/angle/checkout/src/libANGLE/capture/FrameCapture_mock.cpp new file mode 100644 index 0000000000..dc9e44c5bb --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/capture/FrameCapture_mock.cpp @@ -0,0 +1,55 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// FrameCapture_mock.cpp: +// ANGLE mock Frame capture implementation. +// + +#include "libANGLE/capture/FrameCapture.h" + +#if ANGLE_CAPTURE_ENABLED +# error Frame capture must be disabled to include this file. +#endif // ANGLE_CAPTURE_ENABLED + +namespace angle +{ +CallCapture::~CallCapture() {} +ParamBuffer::~ParamBuffer() {} +ParamCapture::~ParamCapture() {} +ResourceTracker::ResourceTracker() {} +ResourceTracker::~ResourceTracker() {} +TrackedResource::TrackedResource() {} +TrackedResource::~TrackedResource() {} +StateResetHelper::StateResetHelper() {} +StateResetHelper::~StateResetHelper() {} +DataTracker::DataTracker() {} +DataTracker::~DataTracker() {} +DataCounters::DataCounters() {} +DataCounters::~DataCounters() {} +StringCounters::StringCounters() {} +StringCounters::~StringCounters() {} +ReplayWriter::ReplayWriter() {} +ReplayWriter::~ReplayWriter() {} + +FrameCapture::FrameCapture() {} +FrameCapture::~FrameCapture() {} + +FrameCaptureShared::FrameCaptureShared() : mEnabled(false) {} +FrameCaptureShared::~FrameCaptureShared() {} +void FrameCaptureShared::onEndFrame(const gl::Context *context) {} +void FrameCaptureShared::onMakeCurrent(const gl::Context *context, const egl::Surface *drawSurface) +{} +void FrameCaptureShared::onDestroyContext(const gl::Context *context) {} +void FrameCaptureShared::replay(gl::Context *context) {} +const ProgramSources &FrameCaptureShared::getProgramSources(gl::ShaderProgramID id) const +{ + const auto &foundSources = mCachedProgramSources.find(id); + return foundSources->second; +} +void FrameCaptureShared::setProgramSources(gl::ShaderProgramID id, ProgramSources sources) {} + +CoherentBufferTracker::CoherentBufferTracker() {} +CoherentBufferTracker::~CoherentBufferTracker() {} +} // namespace angle diff --git a/gfx/angle/checkout/src/libANGLE/capture/capture_egl.h b/gfx/angle/checkout/src/libANGLE/capture/capture_egl.h new file mode 100644 index 0000000000..f23bc1a2ce --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/capture/capture_egl.h @@ -0,0 +1,69 @@ +// +// Copyright 2022 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// capture_egl.h: +// EGL capture functions +// + +#ifndef LIBANGLE_CAPTURE_EGL_H_ +#define LIBANGLE_CAPTURE_EGL_H_ + +#include "libANGLE/Context.h" +#include "libANGLE/Thread.h" +#include "libANGLE/capture/FrameCapture.h" + +namespace gl +{ +enum class GLenumGroup; +} + +namespace egl +{ + +template +void CaptureCallToCaptureEGL(CaptureFuncT captureFunc, egl::Thread *thread, ArgsT... captureParams) +{ + gl::Context *context = thread->getContext(); + if (!context) + { + return; + } + + angle::FrameCaptureShared *frameCaptureShared = + context->getShareGroup()->getFrameCaptureShared(); + if (!frameCaptureShared->isCapturing()) + { + return; + } + + angle::CallCapture call = captureFunc(captureParams...); + + frameCaptureShared->captureCall(context, std::move(call), true); +} + +angle::CallCapture CaptureCreateNativeClientBufferANDROID(const egl::AttributeMap &attribMap, + EGLClientBuffer eglClientBuffer); +angle::CallCapture CaptureEGLCreateImage(const gl::Context *context, + EGLenum target, + EGLClientBuffer buffer, + const egl::AttributeMap &attributes, + egl::Image *image); +angle::CallCapture CaptureEGLDestroyImage(egl::Display *display, egl::Image *image); + +angle::CallCapture CaptureEGLCreatePbufferSurface(const AttributeMap &attrib_list, + egl::Surface *surface); + +angle::CallCapture CaptureEGLDestroySurface(Display *display, Surface *surface); + +angle::CallCapture CaptureEGLBindTexImage(egl::Surface *surface, EGLint buffer); + +angle::CallCapture CaptureEGLReleaseTexImage(egl::Surface *surface, EGLint buffer); + +angle::CallCapture CaptureEGLMakeCurrent(Surface *drawSurface, + Surface *readSurface, + gl::Context *context); +} // namespace egl + +#endif // LIBANGLE_FRAME_CAPTURE_H_ diff --git a/gfx/angle/checkout/src/libANGLE/capture/capture_gl_1_autogen.h b/gfx/angle/checkout/src/libANGLE/capture/capture_gl_1_autogen.h new file mode 100644 index 0000000000..7e4eea7af1 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/capture/capture_gl_1_autogen.h @@ -0,0 +1,2072 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// capture_gl_1_autogen.h: +// Capture functions for the OpenGL ES Desktop GL 1.x entry points. + +#ifndef LIBANGLE_CAPTURE_GL_1_AUTOGEN_H_ +#define LIBANGLE_CAPTURE_GL_1_AUTOGEN_H_ + +#include "common/PackedEnums.h" +#include "libANGLE/capture/FrameCapture.h" + +namespace gl +{ + +// Method Captures + +// GL 1.0 +angle::CallCapture CaptureAccum(const State &glState, bool isCallValid, GLenum op, GLfloat value); +angle::CallCapture CaptureBegin(const State &glState, bool isCallValid, GLenum mode); +angle::CallCapture CaptureBitmap(const State &glState, + bool isCallValid, + GLsizei width, + GLsizei height, + GLfloat xorig, + GLfloat yorig, + GLfloat xmove, + GLfloat ymove, + const GLubyte *bitmap); +angle::CallCapture CaptureCallList(const State &glState, bool isCallValid, GLuint list); +angle::CallCapture CaptureCallLists(const State &glState, + bool isCallValid, + GLsizei n, + GLenum type, + const void *lists); +angle::CallCapture CaptureClearAccum(const State &glState, + bool isCallValid, + GLfloat red, + GLfloat green, + GLfloat blue, + GLfloat alpha); +angle::CallCapture CaptureClearDepth(const State &glState, bool isCallValid, GLdouble depth); +angle::CallCapture CaptureClearIndex(const State &glState, bool isCallValid, GLfloat c); +angle::CallCapture CaptureClipPlane(const State &glState, + bool isCallValid, + GLenum plane, + const GLdouble *equation); +angle::CallCapture CaptureColor3b(const State &glState, + bool isCallValid, + GLbyte red, + GLbyte green, + GLbyte blue); +angle::CallCapture CaptureColor3bv(const State &glState, bool isCallValid, const GLbyte *v); +angle::CallCapture CaptureColor3d(const State &glState, + bool isCallValid, + GLdouble red, + GLdouble green, + GLdouble blue); +angle::CallCapture CaptureColor3dv(const State &glState, bool isCallValid, const GLdouble *v); +angle::CallCapture CaptureColor3f(const State &glState, + bool isCallValid, + GLfloat red, + GLfloat green, + GLfloat blue); +angle::CallCapture CaptureColor3fv(const State &glState, bool isCallValid, const GLfloat *v); +angle::CallCapture CaptureColor3i(const State &glState, + bool isCallValid, + GLint red, + GLint green, + GLint blue); +angle::CallCapture CaptureColor3iv(const State &glState, bool isCallValid, const GLint *v); +angle::CallCapture CaptureColor3s(const State &glState, + bool isCallValid, + GLshort red, + GLshort green, + GLshort blue); +angle::CallCapture CaptureColor3sv(const State &glState, bool isCallValid, const GLshort *v); +angle::CallCapture CaptureColor3ub(const State &glState, + bool isCallValid, + GLubyte red, + GLubyte green, + GLubyte blue); +angle::CallCapture CaptureColor3ubv(const State &glState, bool isCallValid, const GLubyte *v); +angle::CallCapture CaptureColor3ui(const State &glState, + bool isCallValid, + GLuint red, + GLuint green, + GLuint blue); +angle::CallCapture CaptureColor3uiv(const State &glState, bool isCallValid, const GLuint *v); +angle::CallCapture CaptureColor3us(const State &glState, + bool isCallValid, + GLushort red, + GLushort green, + GLushort blue); +angle::CallCapture CaptureColor3usv(const State &glState, bool isCallValid, const GLushort *v); +angle::CallCapture CaptureColor4b(const State &glState, + bool isCallValid, + GLbyte red, + GLbyte green, + GLbyte blue, + GLbyte alpha); +angle::CallCapture CaptureColor4bv(const State &glState, bool isCallValid, const GLbyte *v); +angle::CallCapture CaptureColor4d(const State &glState, + bool isCallValid, + GLdouble red, + GLdouble green, + GLdouble blue, + GLdouble alpha); +angle::CallCapture CaptureColor4dv(const State &glState, bool isCallValid, const GLdouble *v); +angle::CallCapture CaptureColor4fv(const State &glState, bool isCallValid, const GLfloat *v); +angle::CallCapture CaptureColor4i(const State &glState, + bool isCallValid, + GLint red, + GLint green, + GLint blue, + GLint alpha); +angle::CallCapture CaptureColor4iv(const State &glState, bool isCallValid, const GLint *v); +angle::CallCapture CaptureColor4s(const State &glState, + bool isCallValid, + GLshort red, + GLshort green, + GLshort blue, + GLshort alpha); +angle::CallCapture CaptureColor4sv(const State &glState, bool isCallValid, const GLshort *v); +angle::CallCapture CaptureColor4ubv(const State &glState, bool isCallValid, const GLubyte *v); +angle::CallCapture CaptureColor4ui(const State &glState, + bool isCallValid, + GLuint red, + GLuint green, + GLuint blue, + GLuint alpha); +angle::CallCapture CaptureColor4uiv(const State &glState, bool isCallValid, const GLuint *v); +angle::CallCapture CaptureColor4us(const State &glState, + bool isCallValid, + GLushort red, + GLushort green, + GLushort blue, + GLushort alpha); +angle::CallCapture CaptureColor4usv(const State &glState, bool isCallValid, const GLushort *v); +angle::CallCapture CaptureColorMaterial(const State &glState, + bool isCallValid, + GLenum face, + GLenum mode); +angle::CallCapture CaptureCopyPixels(const State &glState, + bool isCallValid, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum type); +angle::CallCapture CaptureDeleteLists(const State &glState, + bool isCallValid, + GLuint list, + GLsizei range); +angle::CallCapture CaptureDepthRange(const State &glState, + bool isCallValid, + GLdouble n, + GLdouble f); +angle::CallCapture CaptureDrawBuffer(const State &glState, bool isCallValid, GLenum buf); +angle::CallCapture CaptureDrawPixels(const State &glState, + bool isCallValid, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void *pixels); +angle::CallCapture CaptureEdgeFlag(const State &glState, bool isCallValid, GLboolean flag); +angle::CallCapture CaptureEdgeFlagv(const State &glState, bool isCallValid, const GLboolean *flag); +angle::CallCapture CaptureEnd(const State &glState, bool isCallValid); +angle::CallCapture CaptureEndList(const State &glState, bool isCallValid); +angle::CallCapture CaptureEvalCoord1d(const State &glState, bool isCallValid, GLdouble u); +angle::CallCapture CaptureEvalCoord1dv(const State &glState, bool isCallValid, const GLdouble *u); +angle::CallCapture CaptureEvalCoord1f(const State &glState, bool isCallValid, GLfloat u); +angle::CallCapture CaptureEvalCoord1fv(const State &glState, bool isCallValid, const GLfloat *u); +angle::CallCapture CaptureEvalCoord2d(const State &glState, + bool isCallValid, + GLdouble u, + GLdouble v); +angle::CallCapture CaptureEvalCoord2dv(const State &glState, bool isCallValid, const GLdouble *u); +angle::CallCapture CaptureEvalCoord2f(const State &glState, bool isCallValid, GLfloat u, GLfloat v); +angle::CallCapture CaptureEvalCoord2fv(const State &glState, bool isCallValid, const GLfloat *u); +angle::CallCapture CaptureEvalMesh1(const State &glState, + bool isCallValid, + GLenum mode, + GLint i1, + GLint i2); +angle::CallCapture CaptureEvalMesh2(const State &glState, + bool isCallValid, + GLenum mode, + GLint i1, + GLint i2, + GLint j1, + GLint j2); +angle::CallCapture CaptureEvalPoint1(const State &glState, bool isCallValid, GLint i); +angle::CallCapture CaptureEvalPoint2(const State &glState, bool isCallValid, GLint i, GLint j); +angle::CallCapture CaptureFeedbackBuffer(const State &glState, + bool isCallValid, + GLsizei size, + GLenum type, + GLfloat *buffer); +angle::CallCapture CaptureFogi(const State &glState, bool isCallValid, GLenum pname, GLint param); +angle::CallCapture CaptureFogiv(const State &glState, + bool isCallValid, + GLenum pname, + const GLint *params); +angle::CallCapture CaptureFrustum(const State &glState, + bool isCallValid, + GLdouble left, + GLdouble right, + GLdouble bottom, + GLdouble top, + GLdouble zNear, + GLdouble zFar); +angle::CallCapture CaptureGenLists(const State &glState, + bool isCallValid, + GLsizei range, + GLuint returnValue); +angle::CallCapture CaptureGetClipPlane(const State &glState, + bool isCallValid, + GLenum plane, + GLdouble *equation); +angle::CallCapture CaptureGetDoublev(const State &glState, + bool isCallValid, + GLenum pname, + GLdouble *data); +angle::CallCapture CaptureGetLightiv(const State &glState, + bool isCallValid, + GLenum light, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetMapdv(const State &glState, + bool isCallValid, + GLenum target, + GLenum query, + GLdouble *v); +angle::CallCapture CaptureGetMapfv(const State &glState, + bool isCallValid, + GLenum target, + GLenum query, + GLfloat *v); +angle::CallCapture CaptureGetMapiv(const State &glState, + bool isCallValid, + GLenum target, + GLenum query, + GLint *v); +angle::CallCapture CaptureGetMaterialiv(const State &glState, + bool isCallValid, + GLenum face, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetPixelMapfv(const State &glState, + bool isCallValid, + GLenum map, + GLfloat *values); +angle::CallCapture CaptureGetPixelMapuiv(const State &glState, + bool isCallValid, + GLenum map, + GLuint *values); +angle::CallCapture CaptureGetPixelMapusv(const State &glState, + bool isCallValid, + GLenum map, + GLushort *values); +angle::CallCapture CaptureGetPolygonStipple(const State &glState, bool isCallValid, GLubyte *mask); +angle::CallCapture CaptureGetTexGendv(const State &glState, + bool isCallValid, + GLenum coord, + GLenum pname, + GLdouble *params); +angle::CallCapture CaptureGetTexGenfv(const State &glState, + bool isCallValid, + GLenum coord, + GLenum pname, + GLfloat *params); +angle::CallCapture CaptureGetTexGeniv(const State &glState, + bool isCallValid, + GLenum coord, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetTexImage(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLenum format, + GLenum type, + void *pixels); +angle::CallCapture CaptureIndexMask(const State &glState, bool isCallValid, GLuint mask); +angle::CallCapture CaptureIndexd(const State &glState, bool isCallValid, GLdouble c); +angle::CallCapture CaptureIndexdv(const State &glState, bool isCallValid, const GLdouble *c); +angle::CallCapture CaptureIndexf(const State &glState, bool isCallValid, GLfloat c); +angle::CallCapture CaptureIndexfv(const State &glState, bool isCallValid, const GLfloat *c); +angle::CallCapture CaptureIndexi(const State &glState, bool isCallValid, GLint c); +angle::CallCapture CaptureIndexiv(const State &glState, bool isCallValid, const GLint *c); +angle::CallCapture CaptureIndexs(const State &glState, bool isCallValid, GLshort c); +angle::CallCapture CaptureIndexsv(const State &glState, bool isCallValid, const GLshort *c); +angle::CallCapture CaptureInitNames(const State &glState, bool isCallValid); +angle::CallCapture CaptureIsList(const State &glState, + bool isCallValid, + GLuint list, + GLboolean returnValue); +angle::CallCapture CaptureLightModeli(const State &glState, + bool isCallValid, + GLenum pname, + GLint param); +angle::CallCapture CaptureLightModeliv(const State &glState, + bool isCallValid, + GLenum pname, + const GLint *params); +angle::CallCapture CaptureLighti(const State &glState, + bool isCallValid, + GLenum light, + GLenum pname, + GLint param); +angle::CallCapture CaptureLightiv(const State &glState, + bool isCallValid, + GLenum light, + GLenum pname, + const GLint *params); +angle::CallCapture CaptureLineStipple(const State &glState, + bool isCallValid, + GLint factor, + GLushort pattern); +angle::CallCapture CaptureListBase(const State &glState, bool isCallValid, GLuint base); +angle::CallCapture CaptureLoadMatrixd(const State &glState, bool isCallValid, const GLdouble *m); +angle::CallCapture CaptureLoadName(const State &glState, bool isCallValid, GLuint name); +angle::CallCapture CaptureMap1d(const State &glState, + bool isCallValid, + GLenum target, + GLdouble u1, + GLdouble u2, + GLint stride, + GLint order, + const GLdouble *points); +angle::CallCapture CaptureMap1f(const State &glState, + bool isCallValid, + GLenum target, + GLfloat u1, + GLfloat u2, + GLint stride, + GLint order, + const GLfloat *points); +angle::CallCapture CaptureMap2d(const State &glState, + bool isCallValid, + GLenum target, + GLdouble u1, + GLdouble u2, + GLint ustride, + GLint uorder, + GLdouble v1, + GLdouble v2, + GLint vstride, + GLint vorder, + const GLdouble *points); +angle::CallCapture CaptureMap2f(const State &glState, + bool isCallValid, + GLenum target, + GLfloat u1, + GLfloat u2, + GLint ustride, + GLint uorder, + GLfloat v1, + GLfloat v2, + GLint vstride, + GLint vorder, + const GLfloat *points); +angle::CallCapture CaptureMapGrid1d(const State &glState, + bool isCallValid, + GLint un, + GLdouble u1, + GLdouble u2); +angle::CallCapture CaptureMapGrid1f(const State &glState, + bool isCallValid, + GLint un, + GLfloat u1, + GLfloat u2); +angle::CallCapture CaptureMapGrid2d(const State &glState, + bool isCallValid, + GLint un, + GLdouble u1, + GLdouble u2, + GLint vn, + GLdouble v1, + GLdouble v2); +angle::CallCapture CaptureMapGrid2f(const State &glState, + bool isCallValid, + GLint un, + GLfloat u1, + GLfloat u2, + GLint vn, + GLfloat v1, + GLfloat v2); +angle::CallCapture CaptureMateriali(const State &glState, + bool isCallValid, + GLenum face, + GLenum pname, + GLint param); +angle::CallCapture CaptureMaterialiv(const State &glState, + bool isCallValid, + GLenum face, + GLenum pname, + const GLint *params); +angle::CallCapture CaptureMultMatrixd(const State &glState, bool isCallValid, const GLdouble *m); +angle::CallCapture CaptureNewList(const State &glState, bool isCallValid, GLuint list, GLenum mode); +angle::CallCapture CaptureNormal3b(const State &glState, + bool isCallValid, + GLbyte nx, + GLbyte ny, + GLbyte nz); +angle::CallCapture CaptureNormal3bv(const State &glState, bool isCallValid, const GLbyte *v); +angle::CallCapture CaptureNormal3d(const State &glState, + bool isCallValid, + GLdouble nx, + GLdouble ny, + GLdouble nz); +angle::CallCapture CaptureNormal3dv(const State &glState, bool isCallValid, const GLdouble *v); +angle::CallCapture CaptureNormal3fv(const State &glState, bool isCallValid, const GLfloat *v); +angle::CallCapture CaptureNormal3i(const State &glState, + bool isCallValid, + GLint nx, + GLint ny, + GLint nz); +angle::CallCapture CaptureNormal3iv(const State &glState, bool isCallValid, const GLint *v); +angle::CallCapture CaptureNormal3s(const State &glState, + bool isCallValid, + GLshort nx, + GLshort ny, + GLshort nz); +angle::CallCapture CaptureNormal3sv(const State &glState, bool isCallValid, const GLshort *v); +angle::CallCapture CaptureOrtho(const State &glState, + bool isCallValid, + GLdouble left, + GLdouble right, + GLdouble bottom, + GLdouble top, + GLdouble zNear, + GLdouble zFar); +angle::CallCapture CapturePassThrough(const State &glState, bool isCallValid, GLfloat token); +angle::CallCapture CapturePixelMapfv(const State &glState, + bool isCallValid, + GLenum map, + GLsizei mapsize, + const GLfloat *values); +angle::CallCapture CapturePixelMapuiv(const State &glState, + bool isCallValid, + GLenum map, + GLsizei mapsize, + const GLuint *values); +angle::CallCapture CapturePixelMapusv(const State &glState, + bool isCallValid, + GLenum map, + GLsizei mapsize, + const GLushort *values); +angle::CallCapture CapturePixelStoref(const State &glState, + bool isCallValid, + GLenum pname, + GLfloat param); +angle::CallCapture CapturePixelTransferf(const State &glState, + bool isCallValid, + GLenum pname, + GLfloat param); +angle::CallCapture CapturePixelTransferi(const State &glState, + bool isCallValid, + GLenum pname, + GLint param); +angle::CallCapture CapturePixelZoom(const State &glState, + bool isCallValid, + GLfloat xfactor, + GLfloat yfactor); +angle::CallCapture CapturePolygonMode(const State &glState, + bool isCallValid, + GLenum face, + GLenum mode); +angle::CallCapture CapturePolygonStipple(const State &glState, + bool isCallValid, + const GLubyte *mask); +angle::CallCapture CapturePopAttrib(const State &glState, bool isCallValid); +angle::CallCapture CapturePopName(const State &glState, bool isCallValid); +angle::CallCapture CapturePushAttrib(const State &glState, bool isCallValid, GLbitfield mask); +angle::CallCapture CapturePushName(const State &glState, bool isCallValid, GLuint name); +angle::CallCapture CaptureRasterPos2d(const State &glState, + bool isCallValid, + GLdouble x, + GLdouble y); +angle::CallCapture CaptureRasterPos2dv(const State &glState, bool isCallValid, const GLdouble *v); +angle::CallCapture CaptureRasterPos2f(const State &glState, bool isCallValid, GLfloat x, GLfloat y); +angle::CallCapture CaptureRasterPos2fv(const State &glState, bool isCallValid, const GLfloat *v); +angle::CallCapture CaptureRasterPos2i(const State &glState, bool isCallValid, GLint x, GLint y); +angle::CallCapture CaptureRasterPos2iv(const State &glState, bool isCallValid, const GLint *v); +angle::CallCapture CaptureRasterPos2s(const State &glState, bool isCallValid, GLshort x, GLshort y); +angle::CallCapture CaptureRasterPos2sv(const State &glState, bool isCallValid, const GLshort *v); +angle::CallCapture CaptureRasterPos3d(const State &glState, + bool isCallValid, + GLdouble x, + GLdouble y, + GLdouble z); +angle::CallCapture CaptureRasterPos3dv(const State &glState, bool isCallValid, const GLdouble *v); +angle::CallCapture CaptureRasterPos3f(const State &glState, + bool isCallValid, + GLfloat x, + GLfloat y, + GLfloat z); +angle::CallCapture CaptureRasterPos3fv(const State &glState, bool isCallValid, const GLfloat *v); +angle::CallCapture CaptureRasterPos3i(const State &glState, + bool isCallValid, + GLint x, + GLint y, + GLint z); +angle::CallCapture CaptureRasterPos3iv(const State &glState, bool isCallValid, const GLint *v); +angle::CallCapture CaptureRasterPos3s(const State &glState, + bool isCallValid, + GLshort x, + GLshort y, + GLshort z); +angle::CallCapture CaptureRasterPos3sv(const State &glState, bool isCallValid, const GLshort *v); +angle::CallCapture CaptureRasterPos4d(const State &glState, + bool isCallValid, + GLdouble x, + GLdouble y, + GLdouble z, + GLdouble w); +angle::CallCapture CaptureRasterPos4dv(const State &glState, bool isCallValid, const GLdouble *v); +angle::CallCapture CaptureRasterPos4f(const State &glState, + bool isCallValid, + GLfloat x, + GLfloat y, + GLfloat z, + GLfloat w); +angle::CallCapture CaptureRasterPos4fv(const State &glState, bool isCallValid, const GLfloat *v); +angle::CallCapture CaptureRasterPos4i(const State &glState, + bool isCallValid, + GLint x, + GLint y, + GLint z, + GLint w); +angle::CallCapture CaptureRasterPos4iv(const State &glState, bool isCallValid, const GLint *v); +angle::CallCapture CaptureRasterPos4s(const State &glState, + bool isCallValid, + GLshort x, + GLshort y, + GLshort z, + GLshort w); +angle::CallCapture CaptureRasterPos4sv(const State &glState, bool isCallValid, const GLshort *v); +angle::CallCapture CaptureRectd(const State &glState, + bool isCallValid, + GLdouble x1, + GLdouble y1, + GLdouble x2, + GLdouble y2); +angle::CallCapture CaptureRectdv(const State &glState, + bool isCallValid, + const GLdouble *v1, + const GLdouble *v2); +angle::CallCapture CaptureRectf(const State &glState, + bool isCallValid, + GLfloat x1, + GLfloat y1, + GLfloat x2, + GLfloat y2); +angle::CallCapture CaptureRectfv(const State &glState, + bool isCallValid, + const GLfloat *v1, + const GLfloat *v2); +angle::CallCapture CaptureRecti(const State &glState, + bool isCallValid, + GLint x1, + GLint y1, + GLint x2, + GLint y2); +angle::CallCapture CaptureRectiv(const State &glState, + bool isCallValid, + const GLint *v1, + const GLint *v2); +angle::CallCapture CaptureRects(const State &glState, + bool isCallValid, + GLshort x1, + GLshort y1, + GLshort x2, + GLshort y2); +angle::CallCapture CaptureRectsv(const State &glState, + bool isCallValid, + const GLshort *v1, + const GLshort *v2); +angle::CallCapture CaptureRenderMode(const State &glState, + bool isCallValid, + GLenum mode, + GLint returnValue); +angle::CallCapture CaptureRotated(const State &glState, + bool isCallValid, + GLdouble angle, + GLdouble x, + GLdouble y, + GLdouble z); +angle::CallCapture CaptureScaled(const State &glState, + bool isCallValid, + GLdouble x, + GLdouble y, + GLdouble z); +angle::CallCapture CaptureSelectBuffer(const State &glState, + bool isCallValid, + GLsizei size, + GLuint *buffer); +angle::CallCapture CaptureTexCoord1d(const State &glState, bool isCallValid, GLdouble s); +angle::CallCapture CaptureTexCoord1dv(const State &glState, bool isCallValid, const GLdouble *v); +angle::CallCapture CaptureTexCoord1f(const State &glState, bool isCallValid, GLfloat s); +angle::CallCapture CaptureTexCoord1fv(const State &glState, bool isCallValid, const GLfloat *v); +angle::CallCapture CaptureTexCoord1i(const State &glState, bool isCallValid, GLint s); +angle::CallCapture CaptureTexCoord1iv(const State &glState, bool isCallValid, const GLint *v); +angle::CallCapture CaptureTexCoord1s(const State &glState, bool isCallValid, GLshort s); +angle::CallCapture CaptureTexCoord1sv(const State &glState, bool isCallValid, const GLshort *v); +angle::CallCapture CaptureTexCoord2d(const State &glState, + bool isCallValid, + GLdouble s, + GLdouble t); +angle::CallCapture CaptureTexCoord2dv(const State &glState, bool isCallValid, const GLdouble *v); +angle::CallCapture CaptureTexCoord2f(const State &glState, bool isCallValid, GLfloat s, GLfloat t); +angle::CallCapture CaptureTexCoord2fv(const State &glState, bool isCallValid, const GLfloat *v); +angle::CallCapture CaptureTexCoord2i(const State &glState, bool isCallValid, GLint s, GLint t); +angle::CallCapture CaptureTexCoord2iv(const State &glState, bool isCallValid, const GLint *v); +angle::CallCapture CaptureTexCoord2s(const State &glState, bool isCallValid, GLshort s, GLshort t); +angle::CallCapture CaptureTexCoord2sv(const State &glState, bool isCallValid, const GLshort *v); +angle::CallCapture CaptureTexCoord3d(const State &glState, + bool isCallValid, + GLdouble s, + GLdouble t, + GLdouble r); +angle::CallCapture CaptureTexCoord3dv(const State &glState, bool isCallValid, const GLdouble *v); +angle::CallCapture CaptureTexCoord3f(const State &glState, + bool isCallValid, + GLfloat s, + GLfloat t, + GLfloat r); +angle::CallCapture CaptureTexCoord3fv(const State &glState, bool isCallValid, const GLfloat *v); +angle::CallCapture CaptureTexCoord3i(const State &glState, + bool isCallValid, + GLint s, + GLint t, + GLint r); +angle::CallCapture CaptureTexCoord3iv(const State &glState, bool isCallValid, const GLint *v); +angle::CallCapture CaptureTexCoord3s(const State &glState, + bool isCallValid, + GLshort s, + GLshort t, + GLshort r); +angle::CallCapture CaptureTexCoord3sv(const State &glState, bool isCallValid, const GLshort *v); +angle::CallCapture CaptureTexCoord4d(const State &glState, + bool isCallValid, + GLdouble s, + GLdouble t, + GLdouble r, + GLdouble q); +angle::CallCapture CaptureTexCoord4dv(const State &glState, bool isCallValid, const GLdouble *v); +angle::CallCapture CaptureTexCoord4f(const State &glState, + bool isCallValid, + GLfloat s, + GLfloat t, + GLfloat r, + GLfloat q); +angle::CallCapture CaptureTexCoord4fv(const State &glState, bool isCallValid, const GLfloat *v); +angle::CallCapture CaptureTexCoord4i(const State &glState, + bool isCallValid, + GLint s, + GLint t, + GLint r, + GLint q); +angle::CallCapture CaptureTexCoord4iv(const State &glState, bool isCallValid, const GLint *v); +angle::CallCapture CaptureTexCoord4s(const State &glState, + bool isCallValid, + GLshort s, + GLshort t, + GLshort r, + GLshort q); +angle::CallCapture CaptureTexCoord4sv(const State &glState, bool isCallValid, const GLshort *v); +angle::CallCapture CaptureTexGend(const State &glState, + bool isCallValid, + GLenum coord, + GLenum pname, + GLdouble param); +angle::CallCapture CaptureTexGendv(const State &glState, + bool isCallValid, + GLenum coord, + GLenum pname, + const GLdouble *params); +angle::CallCapture CaptureTexGenf(const State &glState, + bool isCallValid, + GLenum coord, + GLenum pname, + GLfloat param); +angle::CallCapture CaptureTexGenfv(const State &glState, + bool isCallValid, + GLenum coord, + GLenum pname, + const GLfloat *params); +angle::CallCapture CaptureTexGeni(const State &glState, + bool isCallValid, + GLenum coord, + GLenum pname, + GLint param); +angle::CallCapture CaptureTexGeniv(const State &glState, + bool isCallValid, + GLenum coord, + GLenum pname, + const GLint *params); +angle::CallCapture CaptureTexImage1D(const State &glState, + bool isCallValid, + GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLint border, + GLenum format, + GLenum type, + const void *pixels); +angle::CallCapture CaptureTranslated(const State &glState, + bool isCallValid, + GLdouble x, + GLdouble y, + GLdouble z); +angle::CallCapture CaptureVertex2d(const State &glState, bool isCallValid, GLdouble x, GLdouble y); +angle::CallCapture CaptureVertex2dv(const State &glState, bool isCallValid, const GLdouble *v); +angle::CallCapture CaptureVertex2f(const State &glState, bool isCallValid, GLfloat x, GLfloat y); +angle::CallCapture CaptureVertex2fv(const State &glState, bool isCallValid, const GLfloat *v); +angle::CallCapture CaptureVertex2i(const State &glState, bool isCallValid, GLint x, GLint y); +angle::CallCapture CaptureVertex2iv(const State &glState, bool isCallValid, const GLint *v); +angle::CallCapture CaptureVertex2s(const State &glState, bool isCallValid, GLshort x, GLshort y); +angle::CallCapture CaptureVertex2sv(const State &glState, bool isCallValid, const GLshort *v); +angle::CallCapture CaptureVertex3d(const State &glState, + bool isCallValid, + GLdouble x, + GLdouble y, + GLdouble z); +angle::CallCapture CaptureVertex3dv(const State &glState, bool isCallValid, const GLdouble *v); +angle::CallCapture CaptureVertex3f(const State &glState, + bool isCallValid, + GLfloat x, + GLfloat y, + GLfloat z); +angle::CallCapture CaptureVertex3fv(const State &glState, bool isCallValid, const GLfloat *v); +angle::CallCapture CaptureVertex3i(const State &glState, + bool isCallValid, + GLint x, + GLint y, + GLint z); +angle::CallCapture CaptureVertex3iv(const State &glState, bool isCallValid, const GLint *v); +angle::CallCapture CaptureVertex3s(const State &glState, + bool isCallValid, + GLshort x, + GLshort y, + GLshort z); +angle::CallCapture CaptureVertex3sv(const State &glState, bool isCallValid, const GLshort *v); +angle::CallCapture CaptureVertex4d(const State &glState, + bool isCallValid, + GLdouble x, + GLdouble y, + GLdouble z, + GLdouble w); +angle::CallCapture CaptureVertex4dv(const State &glState, bool isCallValid, const GLdouble *v); +angle::CallCapture CaptureVertex4f(const State &glState, + bool isCallValid, + GLfloat x, + GLfloat y, + GLfloat z, + GLfloat w); +angle::CallCapture CaptureVertex4fv(const State &glState, bool isCallValid, const GLfloat *v); +angle::CallCapture CaptureVertex4i(const State &glState, + bool isCallValid, + GLint x, + GLint y, + GLint z, + GLint w); +angle::CallCapture CaptureVertex4iv(const State &glState, bool isCallValid, const GLint *v); +angle::CallCapture CaptureVertex4s(const State &glState, + bool isCallValid, + GLshort x, + GLshort y, + GLshort z, + GLshort w); +angle::CallCapture CaptureVertex4sv(const State &glState, bool isCallValid, const GLshort *v); + +// GL 1.1 +angle::CallCapture CaptureAreTexturesResident(const State &glState, + bool isCallValid, + GLsizei n, + const GLuint *textures, + GLboolean *residences, + GLboolean returnValue); +angle::CallCapture CaptureArrayElement(const State &glState, bool isCallValid, GLint i); +angle::CallCapture CaptureCopyTexImage1D(const State &glState, + bool isCallValid, + GLenum target, + GLint level, + GLenum internalformat, + GLint x, + GLint y, + GLsizei width, + GLint border); +angle::CallCapture CaptureCopyTexSubImage1D(const State &glState, + bool isCallValid, + GLenum target, + GLint level, + GLint xoffset, + GLint x, + GLint y, + GLsizei width); +angle::CallCapture CaptureEdgeFlagPointer(const State &glState, + bool isCallValid, + GLsizei stride, + const void *pointer); +angle::CallCapture CaptureIndexPointer(const State &glState, + bool isCallValid, + GLenum type, + GLsizei stride, + const void *pointer); +angle::CallCapture CaptureIndexub(const State &glState, bool isCallValid, GLubyte c); +angle::CallCapture CaptureIndexubv(const State &glState, bool isCallValid, const GLubyte *c); +angle::CallCapture CaptureInterleavedArrays(const State &glState, + bool isCallValid, + GLenum format, + GLsizei stride, + const void *pointer); +angle::CallCapture CapturePopClientAttrib(const State &glState, bool isCallValid); +angle::CallCapture CapturePrioritizeTextures(const State &glState, + bool isCallValid, + GLsizei n, + const GLuint *textures, + const GLfloat *priorities); +angle::CallCapture CapturePushClientAttrib(const State &glState, bool isCallValid, GLbitfield mask); +angle::CallCapture CaptureTexSubImage1D(const State &glState, + bool isCallValid, + GLenum target, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, + GLenum type, + const void *pixels); + +// GL 1.2 + +// GL 1.3 +angle::CallCapture CaptureCompressedTexImage1D(const State &glState, + bool isCallValid, + GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLint border, + GLsizei imageSize, + const void *data); +angle::CallCapture CaptureCompressedTexSubImage1D(const State &glState, + bool isCallValid, + GLenum target, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, + GLsizei imageSize, + const void *data); +angle::CallCapture CaptureGetCompressedTexImage(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + void *img); +angle::CallCapture CaptureLoadTransposeMatrixd(const State &glState, + bool isCallValid, + const GLdouble *m); +angle::CallCapture CaptureLoadTransposeMatrixf(const State &glState, + bool isCallValid, + const GLfloat *m); +angle::CallCapture CaptureMultTransposeMatrixd(const State &glState, + bool isCallValid, + const GLdouble *m); +angle::CallCapture CaptureMultTransposeMatrixf(const State &glState, + bool isCallValid, + const GLfloat *m); +angle::CallCapture CaptureMultiTexCoord1d(const State &glState, + bool isCallValid, + GLenum target, + GLdouble s); +angle::CallCapture CaptureMultiTexCoord1dv(const State &glState, + bool isCallValid, + GLenum target, + const GLdouble *v); +angle::CallCapture CaptureMultiTexCoord1f(const State &glState, + bool isCallValid, + GLenum target, + GLfloat s); +angle::CallCapture CaptureMultiTexCoord1fv(const State &glState, + bool isCallValid, + GLenum target, + const GLfloat *v); +angle::CallCapture CaptureMultiTexCoord1i(const State &glState, + bool isCallValid, + GLenum target, + GLint s); +angle::CallCapture CaptureMultiTexCoord1iv(const State &glState, + bool isCallValid, + GLenum target, + const GLint *v); +angle::CallCapture CaptureMultiTexCoord1s(const State &glState, + bool isCallValid, + GLenum target, + GLshort s); +angle::CallCapture CaptureMultiTexCoord1sv(const State &glState, + bool isCallValid, + GLenum target, + const GLshort *v); +angle::CallCapture CaptureMultiTexCoord2d(const State &glState, + bool isCallValid, + GLenum target, + GLdouble s, + GLdouble t); +angle::CallCapture CaptureMultiTexCoord2dv(const State &glState, + bool isCallValid, + GLenum target, + const GLdouble *v); +angle::CallCapture CaptureMultiTexCoord2f(const State &glState, + bool isCallValid, + GLenum target, + GLfloat s, + GLfloat t); +angle::CallCapture CaptureMultiTexCoord2fv(const State &glState, + bool isCallValid, + GLenum target, + const GLfloat *v); +angle::CallCapture CaptureMultiTexCoord2i(const State &glState, + bool isCallValid, + GLenum target, + GLint s, + GLint t); +angle::CallCapture CaptureMultiTexCoord2iv(const State &glState, + bool isCallValid, + GLenum target, + const GLint *v); +angle::CallCapture CaptureMultiTexCoord2s(const State &glState, + bool isCallValid, + GLenum target, + GLshort s, + GLshort t); +angle::CallCapture CaptureMultiTexCoord2sv(const State &glState, + bool isCallValid, + GLenum target, + const GLshort *v); +angle::CallCapture CaptureMultiTexCoord3d(const State &glState, + bool isCallValid, + GLenum target, + GLdouble s, + GLdouble t, + GLdouble r); +angle::CallCapture CaptureMultiTexCoord3dv(const State &glState, + bool isCallValid, + GLenum target, + const GLdouble *v); +angle::CallCapture CaptureMultiTexCoord3f(const State &glState, + bool isCallValid, + GLenum target, + GLfloat s, + GLfloat t, + GLfloat r); +angle::CallCapture CaptureMultiTexCoord3fv(const State &glState, + bool isCallValid, + GLenum target, + const GLfloat *v); +angle::CallCapture CaptureMultiTexCoord3i(const State &glState, + bool isCallValid, + GLenum target, + GLint s, + GLint t, + GLint r); +angle::CallCapture CaptureMultiTexCoord3iv(const State &glState, + bool isCallValid, + GLenum target, + const GLint *v); +angle::CallCapture CaptureMultiTexCoord3s(const State &glState, + bool isCallValid, + GLenum target, + GLshort s, + GLshort t, + GLshort r); +angle::CallCapture CaptureMultiTexCoord3sv(const State &glState, + bool isCallValid, + GLenum target, + const GLshort *v); +angle::CallCapture CaptureMultiTexCoord4d(const State &glState, + bool isCallValid, + GLenum target, + GLdouble s, + GLdouble t, + GLdouble r, + GLdouble q); +angle::CallCapture CaptureMultiTexCoord4dv(const State &glState, + bool isCallValid, + GLenum target, + const GLdouble *v); +angle::CallCapture CaptureMultiTexCoord4fv(const State &glState, + bool isCallValid, + GLenum target, + const GLfloat *v); +angle::CallCapture CaptureMultiTexCoord4i(const State &glState, + bool isCallValid, + GLenum target, + GLint s, + GLint t, + GLint r, + GLint q); +angle::CallCapture CaptureMultiTexCoord4iv(const State &glState, + bool isCallValid, + GLenum target, + const GLint *v); +angle::CallCapture CaptureMultiTexCoord4s(const State &glState, + bool isCallValid, + GLenum target, + GLshort s, + GLshort t, + GLshort r, + GLshort q); +angle::CallCapture CaptureMultiTexCoord4sv(const State &glState, + bool isCallValid, + GLenum target, + const GLshort *v); + +// GL 1.4 +angle::CallCapture CaptureFogCoordPointer(const State &glState, + bool isCallValid, + GLenum type, + GLsizei stride, + const void *pointer); +angle::CallCapture CaptureFogCoordd(const State &glState, bool isCallValid, GLdouble coord); +angle::CallCapture CaptureFogCoorddv(const State &glState, bool isCallValid, const GLdouble *coord); +angle::CallCapture CaptureFogCoordf(const State &glState, bool isCallValid, GLfloat coord); +angle::CallCapture CaptureFogCoordfv(const State &glState, bool isCallValid, const GLfloat *coord); +angle::CallCapture CaptureMultiDrawArrays(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLint *first, + const GLsizei *count, + GLsizei drawcount); +angle::CallCapture CaptureMultiDrawElements(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLsizei *count, + DrawElementsType typePacked, + const void *const *indices, + GLsizei drawcount); +angle::CallCapture CapturePointParameteri(const State &glState, + bool isCallValid, + GLenum pname, + GLint param); +angle::CallCapture CapturePointParameteriv(const State &glState, + bool isCallValid, + GLenum pname, + const GLint *params); +angle::CallCapture CaptureSecondaryColor3b(const State &glState, + bool isCallValid, + GLbyte red, + GLbyte green, + GLbyte blue); +angle::CallCapture CaptureSecondaryColor3bv(const State &glState, + bool isCallValid, + const GLbyte *v); +angle::CallCapture CaptureSecondaryColor3d(const State &glState, + bool isCallValid, + GLdouble red, + GLdouble green, + GLdouble blue); +angle::CallCapture CaptureSecondaryColor3dv(const State &glState, + bool isCallValid, + const GLdouble *v); +angle::CallCapture CaptureSecondaryColor3f(const State &glState, + bool isCallValid, + GLfloat red, + GLfloat green, + GLfloat blue); +angle::CallCapture CaptureSecondaryColor3fv(const State &glState, + bool isCallValid, + const GLfloat *v); +angle::CallCapture CaptureSecondaryColor3i(const State &glState, + bool isCallValid, + GLint red, + GLint green, + GLint blue); +angle::CallCapture CaptureSecondaryColor3iv(const State &glState, bool isCallValid, const GLint *v); +angle::CallCapture CaptureSecondaryColor3s(const State &glState, + bool isCallValid, + GLshort red, + GLshort green, + GLshort blue); +angle::CallCapture CaptureSecondaryColor3sv(const State &glState, + bool isCallValid, + const GLshort *v); +angle::CallCapture CaptureSecondaryColor3ub(const State &glState, + bool isCallValid, + GLubyte red, + GLubyte green, + GLubyte blue); +angle::CallCapture CaptureSecondaryColor3ubv(const State &glState, + bool isCallValid, + const GLubyte *v); +angle::CallCapture CaptureSecondaryColor3ui(const State &glState, + bool isCallValid, + GLuint red, + GLuint green, + GLuint blue); +angle::CallCapture CaptureSecondaryColor3uiv(const State &glState, + bool isCallValid, + const GLuint *v); +angle::CallCapture CaptureSecondaryColor3us(const State &glState, + bool isCallValid, + GLushort red, + GLushort green, + GLushort blue); +angle::CallCapture CaptureSecondaryColor3usv(const State &glState, + bool isCallValid, + const GLushort *v); +angle::CallCapture CaptureSecondaryColorPointer(const State &glState, + bool isCallValid, + GLint size, + GLenum type, + GLsizei stride, + const void *pointer); +angle::CallCapture CaptureWindowPos2d(const State &glState, + bool isCallValid, + GLdouble x, + GLdouble y); +angle::CallCapture CaptureWindowPos2dv(const State &glState, bool isCallValid, const GLdouble *v); +angle::CallCapture CaptureWindowPos2f(const State &glState, bool isCallValid, GLfloat x, GLfloat y); +angle::CallCapture CaptureWindowPos2fv(const State &glState, bool isCallValid, const GLfloat *v); +angle::CallCapture CaptureWindowPos2i(const State &glState, bool isCallValid, GLint x, GLint y); +angle::CallCapture CaptureWindowPos2iv(const State &glState, bool isCallValid, const GLint *v); +angle::CallCapture CaptureWindowPos2s(const State &glState, bool isCallValid, GLshort x, GLshort y); +angle::CallCapture CaptureWindowPos2sv(const State &glState, bool isCallValid, const GLshort *v); +angle::CallCapture CaptureWindowPos3d(const State &glState, + bool isCallValid, + GLdouble x, + GLdouble y, + GLdouble z); +angle::CallCapture CaptureWindowPos3dv(const State &glState, bool isCallValid, const GLdouble *v); +angle::CallCapture CaptureWindowPos3f(const State &glState, + bool isCallValid, + GLfloat x, + GLfloat y, + GLfloat z); +angle::CallCapture CaptureWindowPos3fv(const State &glState, bool isCallValid, const GLfloat *v); +angle::CallCapture CaptureWindowPos3i(const State &glState, + bool isCallValid, + GLint x, + GLint y, + GLint z); +angle::CallCapture CaptureWindowPos3iv(const State &glState, bool isCallValid, const GLint *v); +angle::CallCapture CaptureWindowPos3s(const State &glState, + bool isCallValid, + GLshort x, + GLshort y, + GLshort z); +angle::CallCapture CaptureWindowPos3sv(const State &glState, bool isCallValid, const GLshort *v); + +// GL 1.5 +angle::CallCapture CaptureGetBufferSubData(const State &glState, + bool isCallValid, + GLenum target, + GLintptr offset, + GLsizeiptr size, + void *data); +angle::CallCapture CaptureGetQueryObjectiv(const State &glState, + bool isCallValid, + QueryID idPacked, + GLenum pname, + GLint *params); +angle::CallCapture CaptureMapBuffer(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLenum access, + void *returnValue); + +// Parameter Captures + +// GL 1.0 +void CaptureBitmap_bitmap(const State &glState, + bool isCallValid, + GLsizei width, + GLsizei height, + GLfloat xorig, + GLfloat yorig, + GLfloat xmove, + GLfloat ymove, + const GLubyte *bitmap, + angle::ParamCapture *paramCapture); +void CaptureCallLists_lists(const State &glState, + bool isCallValid, + GLsizei n, + GLenum type, + const void *lists, + angle::ParamCapture *paramCapture); +void CaptureClipPlane_equation(const State &glState, + bool isCallValid, + GLenum plane, + const GLdouble *equation, + angle::ParamCapture *paramCapture); +void CaptureColor3bv_v(const State &glState, + bool isCallValid, + const GLbyte *v, + angle::ParamCapture *paramCapture); +void CaptureColor3dv_v(const State &glState, + bool isCallValid, + const GLdouble *v, + angle::ParamCapture *paramCapture); +void CaptureColor3fv_v(const State &glState, + bool isCallValid, + const GLfloat *v, + angle::ParamCapture *paramCapture); +void CaptureColor3iv_v(const State &glState, + bool isCallValid, + const GLint *v, + angle::ParamCapture *paramCapture); +void CaptureColor3sv_v(const State &glState, + bool isCallValid, + const GLshort *v, + angle::ParamCapture *paramCapture); +void CaptureColor3ubv_v(const State &glState, + bool isCallValid, + const GLubyte *v, + angle::ParamCapture *paramCapture); +void CaptureColor3uiv_v(const State &glState, + bool isCallValid, + const GLuint *v, + angle::ParamCapture *paramCapture); +void CaptureColor3usv_v(const State &glState, + bool isCallValid, + const GLushort *v, + angle::ParamCapture *paramCapture); +void CaptureColor4bv_v(const State &glState, + bool isCallValid, + const GLbyte *v, + angle::ParamCapture *paramCapture); +void CaptureColor4dv_v(const State &glState, + bool isCallValid, + const GLdouble *v, + angle::ParamCapture *paramCapture); +void CaptureColor4fv_v(const State &glState, + bool isCallValid, + const GLfloat *v, + angle::ParamCapture *paramCapture); +void CaptureColor4iv_v(const State &glState, + bool isCallValid, + const GLint *v, + angle::ParamCapture *paramCapture); +void CaptureColor4sv_v(const State &glState, + bool isCallValid, + const GLshort *v, + angle::ParamCapture *paramCapture); +void CaptureColor4ubv_v(const State &glState, + bool isCallValid, + const GLubyte *v, + angle::ParamCapture *paramCapture); +void CaptureColor4uiv_v(const State &glState, + bool isCallValid, + const GLuint *v, + angle::ParamCapture *paramCapture); +void CaptureColor4usv_v(const State &glState, + bool isCallValid, + const GLushort *v, + angle::ParamCapture *paramCapture); +void CaptureDrawPixels_pixels(const State &glState, + bool isCallValid, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void *pixels, + angle::ParamCapture *paramCapture); +void CaptureEdgeFlagv_flag(const State &glState, + bool isCallValid, + const GLboolean *flag, + angle::ParamCapture *paramCapture); +void CaptureEvalCoord1dv_u(const State &glState, + bool isCallValid, + const GLdouble *u, + angle::ParamCapture *paramCapture); +void CaptureEvalCoord1fv_u(const State &glState, + bool isCallValid, + const GLfloat *u, + angle::ParamCapture *paramCapture); +void CaptureEvalCoord2dv_u(const State &glState, + bool isCallValid, + const GLdouble *u, + angle::ParamCapture *paramCapture); +void CaptureEvalCoord2fv_u(const State &glState, + bool isCallValid, + const GLfloat *u, + angle::ParamCapture *paramCapture); +void CaptureFeedbackBuffer_buffer(const State &glState, + bool isCallValid, + GLsizei size, + GLenum type, + GLfloat *buffer, + angle::ParamCapture *paramCapture); +void CaptureFogiv_params(const State &glState, + bool isCallValid, + GLenum pname, + const GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetClipPlane_equation(const State &glState, + bool isCallValid, + GLenum plane, + GLdouble *equation, + angle::ParamCapture *paramCapture); +void CaptureGetDoublev_data(const State &glState, + bool isCallValid, + GLenum pname, + GLdouble *data, + angle::ParamCapture *paramCapture); +void CaptureGetLightiv_params(const State &glState, + bool isCallValid, + GLenum light, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetMapdv_v(const State &glState, + bool isCallValid, + GLenum target, + GLenum query, + GLdouble *v, + angle::ParamCapture *paramCapture); +void CaptureGetMapfv_v(const State &glState, + bool isCallValid, + GLenum target, + GLenum query, + GLfloat *v, + angle::ParamCapture *paramCapture); +void CaptureGetMapiv_v(const State &glState, + bool isCallValid, + GLenum target, + GLenum query, + GLint *v, + angle::ParamCapture *paramCapture); +void CaptureGetMaterialiv_params(const State &glState, + bool isCallValid, + GLenum face, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetPixelMapfv_values(const State &glState, + bool isCallValid, + GLenum map, + GLfloat *values, + angle::ParamCapture *paramCapture); +void CaptureGetPixelMapuiv_values(const State &glState, + bool isCallValid, + GLenum map, + GLuint *values, + angle::ParamCapture *paramCapture); +void CaptureGetPixelMapusv_values(const State &glState, + bool isCallValid, + GLenum map, + GLushort *values, + angle::ParamCapture *paramCapture); +void CaptureGetPolygonStipple_mask(const State &glState, + bool isCallValid, + GLubyte *mask, + angle::ParamCapture *paramCapture); +void CaptureGetTexGendv_params(const State &glState, + bool isCallValid, + GLenum coord, + GLenum pname, + GLdouble *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexGenfv_params(const State &glState, + bool isCallValid, + GLenum coord, + GLenum pname, + GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexGeniv_params(const State &glState, + bool isCallValid, + GLenum coord, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexImage_pixels(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLenum format, + GLenum type, + void *pixels, + angle::ParamCapture *paramCapture); +void CaptureIndexdv_c(const State &glState, + bool isCallValid, + const GLdouble *c, + angle::ParamCapture *paramCapture); +void CaptureIndexfv_c(const State &glState, + bool isCallValid, + const GLfloat *c, + angle::ParamCapture *paramCapture); +void CaptureIndexiv_c(const State &glState, + bool isCallValid, + const GLint *c, + angle::ParamCapture *paramCapture); +void CaptureIndexsv_c(const State &glState, + bool isCallValid, + const GLshort *c, + angle::ParamCapture *paramCapture); +void CaptureLightModeliv_params(const State &glState, + bool isCallValid, + GLenum pname, + const GLint *params, + angle::ParamCapture *paramCapture); +void CaptureLightiv_params(const State &glState, + bool isCallValid, + GLenum light, + GLenum pname, + const GLint *params, + angle::ParamCapture *paramCapture); +void CaptureLoadMatrixd_m(const State &glState, + bool isCallValid, + const GLdouble *m, + angle::ParamCapture *paramCapture); +void CaptureMap1d_points(const State &glState, + bool isCallValid, + GLenum target, + GLdouble u1, + GLdouble u2, + GLint stride, + GLint order, + const GLdouble *points, + angle::ParamCapture *paramCapture); +void CaptureMap1f_points(const State &glState, + bool isCallValid, + GLenum target, + GLfloat u1, + GLfloat u2, + GLint stride, + GLint order, + const GLfloat *points, + angle::ParamCapture *paramCapture); +void CaptureMap2d_points(const State &glState, + bool isCallValid, + GLenum target, + GLdouble u1, + GLdouble u2, + GLint ustride, + GLint uorder, + GLdouble v1, + GLdouble v2, + GLint vstride, + GLint vorder, + const GLdouble *points, + angle::ParamCapture *paramCapture); +void CaptureMap2f_points(const State &glState, + bool isCallValid, + GLenum target, + GLfloat u1, + GLfloat u2, + GLint ustride, + GLint uorder, + GLfloat v1, + GLfloat v2, + GLint vstride, + GLint vorder, + const GLfloat *points, + angle::ParamCapture *paramCapture); +void CaptureMaterialiv_params(const State &glState, + bool isCallValid, + GLenum face, + GLenum pname, + const GLint *params, + angle::ParamCapture *paramCapture); +void CaptureMultMatrixd_m(const State &glState, + bool isCallValid, + const GLdouble *m, + angle::ParamCapture *paramCapture); +void CaptureNormal3bv_v(const State &glState, + bool isCallValid, + const GLbyte *v, + angle::ParamCapture *paramCapture); +void CaptureNormal3dv_v(const State &glState, + bool isCallValid, + const GLdouble *v, + angle::ParamCapture *paramCapture); +void CaptureNormal3fv_v(const State &glState, + bool isCallValid, + const GLfloat *v, + angle::ParamCapture *paramCapture); +void CaptureNormal3iv_v(const State &glState, + bool isCallValid, + const GLint *v, + angle::ParamCapture *paramCapture); +void CaptureNormal3sv_v(const State &glState, + bool isCallValid, + const GLshort *v, + angle::ParamCapture *paramCapture); +void CapturePixelMapfv_values(const State &glState, + bool isCallValid, + GLenum map, + GLsizei mapsize, + const GLfloat *values, + angle::ParamCapture *paramCapture); +void CapturePixelMapuiv_values(const State &glState, + bool isCallValid, + GLenum map, + GLsizei mapsize, + const GLuint *values, + angle::ParamCapture *paramCapture); +void CapturePixelMapusv_values(const State &glState, + bool isCallValid, + GLenum map, + GLsizei mapsize, + const GLushort *values, + angle::ParamCapture *paramCapture); +void CapturePolygonStipple_mask(const State &glState, + bool isCallValid, + const GLubyte *mask, + angle::ParamCapture *paramCapture); +void CaptureRasterPos2dv_v(const State &glState, + bool isCallValid, + const GLdouble *v, + angle::ParamCapture *paramCapture); +void CaptureRasterPos2fv_v(const State &glState, + bool isCallValid, + const GLfloat *v, + angle::ParamCapture *paramCapture); +void CaptureRasterPos2iv_v(const State &glState, + bool isCallValid, + const GLint *v, + angle::ParamCapture *paramCapture); +void CaptureRasterPos2sv_v(const State &glState, + bool isCallValid, + const GLshort *v, + angle::ParamCapture *paramCapture); +void CaptureRasterPos3dv_v(const State &glState, + bool isCallValid, + const GLdouble *v, + angle::ParamCapture *paramCapture); +void CaptureRasterPos3fv_v(const State &glState, + bool isCallValid, + const GLfloat *v, + angle::ParamCapture *paramCapture); +void CaptureRasterPos3iv_v(const State &glState, + bool isCallValid, + const GLint *v, + angle::ParamCapture *paramCapture); +void CaptureRasterPos3sv_v(const State &glState, + bool isCallValid, + const GLshort *v, + angle::ParamCapture *paramCapture); +void CaptureRasterPos4dv_v(const State &glState, + bool isCallValid, + const GLdouble *v, + angle::ParamCapture *paramCapture); +void CaptureRasterPos4fv_v(const State &glState, + bool isCallValid, + const GLfloat *v, + angle::ParamCapture *paramCapture); +void CaptureRasterPos4iv_v(const State &glState, + bool isCallValid, + const GLint *v, + angle::ParamCapture *paramCapture); +void CaptureRasterPos4sv_v(const State &glState, + bool isCallValid, + const GLshort *v, + angle::ParamCapture *paramCapture); +void CaptureRectdv_v1(const State &glState, + bool isCallValid, + const GLdouble *v1, + const GLdouble *v2, + angle::ParamCapture *paramCapture); +void CaptureRectdv_v2(const State &glState, + bool isCallValid, + const GLdouble *v1, + const GLdouble *v2, + angle::ParamCapture *paramCapture); +void CaptureRectfv_v1(const State &glState, + bool isCallValid, + const GLfloat *v1, + const GLfloat *v2, + angle::ParamCapture *paramCapture); +void CaptureRectfv_v2(const State &glState, + bool isCallValid, + const GLfloat *v1, + const GLfloat *v2, + angle::ParamCapture *paramCapture); +void CaptureRectiv_v1(const State &glState, + bool isCallValid, + const GLint *v1, + const GLint *v2, + angle::ParamCapture *paramCapture); +void CaptureRectiv_v2(const State &glState, + bool isCallValid, + const GLint *v1, + const GLint *v2, + angle::ParamCapture *paramCapture); +void CaptureRectsv_v1(const State &glState, + bool isCallValid, + const GLshort *v1, + const GLshort *v2, + angle::ParamCapture *paramCapture); +void CaptureRectsv_v2(const State &glState, + bool isCallValid, + const GLshort *v1, + const GLshort *v2, + angle::ParamCapture *paramCapture); +void CaptureSelectBuffer_buffer(const State &glState, + bool isCallValid, + GLsizei size, + GLuint *buffer, + angle::ParamCapture *paramCapture); +void CaptureTexCoord1dv_v(const State &glState, + bool isCallValid, + const GLdouble *v, + angle::ParamCapture *paramCapture); +void CaptureTexCoord1fv_v(const State &glState, + bool isCallValid, + const GLfloat *v, + angle::ParamCapture *paramCapture); +void CaptureTexCoord1iv_v(const State &glState, + bool isCallValid, + const GLint *v, + angle::ParamCapture *paramCapture); +void CaptureTexCoord1sv_v(const State &glState, + bool isCallValid, + const GLshort *v, + angle::ParamCapture *paramCapture); +void CaptureTexCoord2dv_v(const State &glState, + bool isCallValid, + const GLdouble *v, + angle::ParamCapture *paramCapture); +void CaptureTexCoord2fv_v(const State &glState, + bool isCallValid, + const GLfloat *v, + angle::ParamCapture *paramCapture); +void CaptureTexCoord2iv_v(const State &glState, + bool isCallValid, + const GLint *v, + angle::ParamCapture *paramCapture); +void CaptureTexCoord2sv_v(const State &glState, + bool isCallValid, + const GLshort *v, + angle::ParamCapture *paramCapture); +void CaptureTexCoord3dv_v(const State &glState, + bool isCallValid, + const GLdouble *v, + angle::ParamCapture *paramCapture); +void CaptureTexCoord3fv_v(const State &glState, + bool isCallValid, + const GLfloat *v, + angle::ParamCapture *paramCapture); +void CaptureTexCoord3iv_v(const State &glState, + bool isCallValid, + const GLint *v, + angle::ParamCapture *paramCapture); +void CaptureTexCoord3sv_v(const State &glState, + bool isCallValid, + const GLshort *v, + angle::ParamCapture *paramCapture); +void CaptureTexCoord4dv_v(const State &glState, + bool isCallValid, + const GLdouble *v, + angle::ParamCapture *paramCapture); +void CaptureTexCoord4fv_v(const State &glState, + bool isCallValid, + const GLfloat *v, + angle::ParamCapture *paramCapture); +void CaptureTexCoord4iv_v(const State &glState, + bool isCallValid, + const GLint *v, + angle::ParamCapture *paramCapture); +void CaptureTexCoord4sv_v(const State &glState, + bool isCallValid, + const GLshort *v, + angle::ParamCapture *paramCapture); +void CaptureTexGendv_params(const State &glState, + bool isCallValid, + GLenum coord, + GLenum pname, + const GLdouble *params, + angle::ParamCapture *paramCapture); +void CaptureTexGenfv_params(const State &glState, + bool isCallValid, + GLenum coord, + GLenum pname, + const GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureTexGeniv_params(const State &glState, + bool isCallValid, + GLenum coord, + GLenum pname, + const GLint *params, + angle::ParamCapture *paramCapture); +void CaptureTexImage1D_pixels(const State &glState, + bool isCallValid, + GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLint border, + GLenum format, + GLenum type, + const void *pixels, + angle::ParamCapture *paramCapture); +void CaptureVertex2dv_v(const State &glState, + bool isCallValid, + const GLdouble *v, + angle::ParamCapture *paramCapture); +void CaptureVertex2fv_v(const State &glState, + bool isCallValid, + const GLfloat *v, + angle::ParamCapture *paramCapture); +void CaptureVertex2iv_v(const State &glState, + bool isCallValid, + const GLint *v, + angle::ParamCapture *paramCapture); +void CaptureVertex2sv_v(const State &glState, + bool isCallValid, + const GLshort *v, + angle::ParamCapture *paramCapture); +void CaptureVertex3dv_v(const State &glState, + bool isCallValid, + const GLdouble *v, + angle::ParamCapture *paramCapture); +void CaptureVertex3fv_v(const State &glState, + bool isCallValid, + const GLfloat *v, + angle::ParamCapture *paramCapture); +void CaptureVertex3iv_v(const State &glState, + bool isCallValid, + const GLint *v, + angle::ParamCapture *paramCapture); +void CaptureVertex3sv_v(const State &glState, + bool isCallValid, + const GLshort *v, + angle::ParamCapture *paramCapture); +void CaptureVertex4dv_v(const State &glState, + bool isCallValid, + const GLdouble *v, + angle::ParamCapture *paramCapture); +void CaptureVertex4fv_v(const State &glState, + bool isCallValid, + const GLfloat *v, + angle::ParamCapture *paramCapture); +void CaptureVertex4iv_v(const State &glState, + bool isCallValid, + const GLint *v, + angle::ParamCapture *paramCapture); +void CaptureVertex4sv_v(const State &glState, + bool isCallValid, + const GLshort *v, + angle::ParamCapture *paramCapture); + +// GL 1.1 +void CaptureAreTexturesResident_textures(const State &glState, + bool isCallValid, + GLsizei n, + const GLuint *textures, + GLboolean *residences, + angle::ParamCapture *paramCapture); +void CaptureAreTexturesResident_residences(const State &glState, + bool isCallValid, + GLsizei n, + const GLuint *textures, + GLboolean *residences, + angle::ParamCapture *paramCapture); +void CaptureEdgeFlagPointer_pointer(const State &glState, + bool isCallValid, + GLsizei stride, + const void *pointer, + angle::ParamCapture *paramCapture); +void CaptureIndexPointer_pointer(const State &glState, + bool isCallValid, + GLenum type, + GLsizei stride, + const void *pointer, + angle::ParamCapture *paramCapture); +void CaptureIndexubv_c(const State &glState, + bool isCallValid, + const GLubyte *c, + angle::ParamCapture *paramCapture); +void CaptureInterleavedArrays_pointer(const State &glState, + bool isCallValid, + GLenum format, + GLsizei stride, + const void *pointer, + angle::ParamCapture *paramCapture); +void CapturePrioritizeTextures_textures(const State &glState, + bool isCallValid, + GLsizei n, + const GLuint *textures, + const GLfloat *priorities, + angle::ParamCapture *paramCapture); +void CapturePrioritizeTextures_priorities(const State &glState, + bool isCallValid, + GLsizei n, + const GLuint *textures, + const GLfloat *priorities, + angle::ParamCapture *paramCapture); +void CaptureTexSubImage1D_pixels(const State &glState, + bool isCallValid, + GLenum target, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, + GLenum type, + const void *pixels, + angle::ParamCapture *paramCapture); + +// GL 1.2 + +// GL 1.3 +void CaptureCompressedTexImage1D_data(const State &glState, + bool isCallValid, + GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLint border, + GLsizei imageSize, + const void *data, + angle::ParamCapture *paramCapture); +void CaptureCompressedTexSubImage1D_data(const State &glState, + bool isCallValid, + GLenum target, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, + GLsizei imageSize, + const void *data, + angle::ParamCapture *paramCapture); +void CaptureGetCompressedTexImage_img(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + void *img, + angle::ParamCapture *paramCapture); +void CaptureLoadTransposeMatrixd_m(const State &glState, + bool isCallValid, + const GLdouble *m, + angle::ParamCapture *paramCapture); +void CaptureLoadTransposeMatrixf_m(const State &glState, + bool isCallValid, + const GLfloat *m, + angle::ParamCapture *paramCapture); +void CaptureMultTransposeMatrixd_m(const State &glState, + bool isCallValid, + const GLdouble *m, + angle::ParamCapture *paramCapture); +void CaptureMultTransposeMatrixf_m(const State &glState, + bool isCallValid, + const GLfloat *m, + angle::ParamCapture *paramCapture); +void CaptureMultiTexCoord1dv_v(const State &glState, + bool isCallValid, + GLenum target, + const GLdouble *v, + angle::ParamCapture *paramCapture); +void CaptureMultiTexCoord1fv_v(const State &glState, + bool isCallValid, + GLenum target, + const GLfloat *v, + angle::ParamCapture *paramCapture); +void CaptureMultiTexCoord1iv_v(const State &glState, + bool isCallValid, + GLenum target, + const GLint *v, + angle::ParamCapture *paramCapture); +void CaptureMultiTexCoord1sv_v(const State &glState, + bool isCallValid, + GLenum target, + const GLshort *v, + angle::ParamCapture *paramCapture); +void CaptureMultiTexCoord2dv_v(const State &glState, + bool isCallValid, + GLenum target, + const GLdouble *v, + angle::ParamCapture *paramCapture); +void CaptureMultiTexCoord2fv_v(const State &glState, + bool isCallValid, + GLenum target, + const GLfloat *v, + angle::ParamCapture *paramCapture); +void CaptureMultiTexCoord2iv_v(const State &glState, + bool isCallValid, + GLenum target, + const GLint *v, + angle::ParamCapture *paramCapture); +void CaptureMultiTexCoord2sv_v(const State &glState, + bool isCallValid, + GLenum target, + const GLshort *v, + angle::ParamCapture *paramCapture); +void CaptureMultiTexCoord3dv_v(const State &glState, + bool isCallValid, + GLenum target, + const GLdouble *v, + angle::ParamCapture *paramCapture); +void CaptureMultiTexCoord3fv_v(const State &glState, + bool isCallValid, + GLenum target, + const GLfloat *v, + angle::ParamCapture *paramCapture); +void CaptureMultiTexCoord3iv_v(const State &glState, + bool isCallValid, + GLenum target, + const GLint *v, + angle::ParamCapture *paramCapture); +void CaptureMultiTexCoord3sv_v(const State &glState, + bool isCallValid, + GLenum target, + const GLshort *v, + angle::ParamCapture *paramCapture); +void CaptureMultiTexCoord4dv_v(const State &glState, + bool isCallValid, + GLenum target, + const GLdouble *v, + angle::ParamCapture *paramCapture); +void CaptureMultiTexCoord4fv_v(const State &glState, + bool isCallValid, + GLenum target, + const GLfloat *v, + angle::ParamCapture *paramCapture); +void CaptureMultiTexCoord4iv_v(const State &glState, + bool isCallValid, + GLenum target, + const GLint *v, + angle::ParamCapture *paramCapture); +void CaptureMultiTexCoord4sv_v(const State &glState, + bool isCallValid, + GLenum target, + const GLshort *v, + angle::ParamCapture *paramCapture); + +// GL 1.4 +void CaptureFogCoordPointer_pointer(const State &glState, + bool isCallValid, + GLenum type, + GLsizei stride, + const void *pointer, + angle::ParamCapture *paramCapture); +void CaptureFogCoorddv_coord(const State &glState, + bool isCallValid, + const GLdouble *coord, + angle::ParamCapture *paramCapture); +void CaptureFogCoordfv_coord(const State &glState, + bool isCallValid, + const GLfloat *coord, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawArrays_first(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLint *first, + const GLsizei *count, + GLsizei drawcount, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawArrays_count(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLint *first, + const GLsizei *count, + GLsizei drawcount, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawElements_count(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLsizei *count, + DrawElementsType typePacked, + const void *const *indices, + GLsizei drawcount, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawElements_indices(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLsizei *count, + DrawElementsType typePacked, + const void *const *indices, + GLsizei drawcount, + angle::ParamCapture *paramCapture); +void CapturePointParameteriv_params(const State &glState, + bool isCallValid, + GLenum pname, + const GLint *params, + angle::ParamCapture *paramCapture); +void CaptureSecondaryColor3bv_v(const State &glState, + bool isCallValid, + const GLbyte *v, + angle::ParamCapture *paramCapture); +void CaptureSecondaryColor3dv_v(const State &glState, + bool isCallValid, + const GLdouble *v, + angle::ParamCapture *paramCapture); +void CaptureSecondaryColor3fv_v(const State &glState, + bool isCallValid, + const GLfloat *v, + angle::ParamCapture *paramCapture); +void CaptureSecondaryColor3iv_v(const State &glState, + bool isCallValid, + const GLint *v, + angle::ParamCapture *paramCapture); +void CaptureSecondaryColor3sv_v(const State &glState, + bool isCallValid, + const GLshort *v, + angle::ParamCapture *paramCapture); +void CaptureSecondaryColor3ubv_v(const State &glState, + bool isCallValid, + const GLubyte *v, + angle::ParamCapture *paramCapture); +void CaptureSecondaryColor3uiv_v(const State &glState, + bool isCallValid, + const GLuint *v, + angle::ParamCapture *paramCapture); +void CaptureSecondaryColor3usv_v(const State &glState, + bool isCallValid, + const GLushort *v, + angle::ParamCapture *paramCapture); +void CaptureSecondaryColorPointer_pointer(const State &glState, + bool isCallValid, + GLint size, + GLenum type, + GLsizei stride, + const void *pointer, + angle::ParamCapture *paramCapture); +void CaptureWindowPos2dv_v(const State &glState, + bool isCallValid, + const GLdouble *v, + angle::ParamCapture *paramCapture); +void CaptureWindowPos2fv_v(const State &glState, + bool isCallValid, + const GLfloat *v, + angle::ParamCapture *paramCapture); +void CaptureWindowPos2iv_v(const State &glState, + bool isCallValid, + const GLint *v, + angle::ParamCapture *paramCapture); +void CaptureWindowPos2sv_v(const State &glState, + bool isCallValid, + const GLshort *v, + angle::ParamCapture *paramCapture); +void CaptureWindowPos3dv_v(const State &glState, + bool isCallValid, + const GLdouble *v, + angle::ParamCapture *paramCapture); +void CaptureWindowPos3fv_v(const State &glState, + bool isCallValid, + const GLfloat *v, + angle::ParamCapture *paramCapture); +void CaptureWindowPos3iv_v(const State &glState, + bool isCallValid, + const GLint *v, + angle::ParamCapture *paramCapture); +void CaptureWindowPos3sv_v(const State &glState, + bool isCallValid, + const GLshort *v, + angle::ParamCapture *paramCapture); + +// GL 1.5 +void CaptureGetBufferSubData_data(const State &glState, + bool isCallValid, + GLenum target, + GLintptr offset, + GLsizeiptr size, + void *data, + angle::ParamCapture *paramCapture); +void CaptureGetQueryObjectiv_params(const State &glState, + bool isCallValid, + QueryID idPacked, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +} // namespace gl + +#endif // LIBANGLE_CAPTURE_GL_1_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/capture/capture_gl_2_autogen.h b/gfx/angle/checkout/src/libANGLE/capture/capture_gl_2_autogen.h new file mode 100644 index 0000000000..5ab30a6b9a --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/capture/capture_gl_2_autogen.h @@ -0,0 +1,266 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// capture_gl_2_autogen.h: +// Capture functions for the OpenGL ES Desktop GL 2.x entry points. + +#ifndef LIBANGLE_CAPTURE_GL_2_AUTOGEN_H_ +#define LIBANGLE_CAPTURE_GL_2_AUTOGEN_H_ + +#include "common/PackedEnums.h" +#include "libANGLE/capture/FrameCapture.h" + +namespace gl +{ + +// Method Captures + +// GL 2.0 +angle::CallCapture CaptureGetVertexAttribdv(const State &glState, + bool isCallValid, + GLuint index, + GLenum pname, + GLdouble *params); +angle::CallCapture CaptureVertexAttrib1d(const State &glState, + bool isCallValid, + GLuint index, + GLdouble x); +angle::CallCapture CaptureVertexAttrib1dv(const State &glState, + bool isCallValid, + GLuint index, + const GLdouble *v); +angle::CallCapture CaptureVertexAttrib1s(const State &glState, + bool isCallValid, + GLuint index, + GLshort x); +angle::CallCapture CaptureVertexAttrib1sv(const State &glState, + bool isCallValid, + GLuint index, + const GLshort *v); +angle::CallCapture CaptureVertexAttrib2d(const State &glState, + bool isCallValid, + GLuint index, + GLdouble x, + GLdouble y); +angle::CallCapture CaptureVertexAttrib2dv(const State &glState, + bool isCallValid, + GLuint index, + const GLdouble *v); +angle::CallCapture CaptureVertexAttrib2s(const State &glState, + bool isCallValid, + GLuint index, + GLshort x, + GLshort y); +angle::CallCapture CaptureVertexAttrib2sv(const State &glState, + bool isCallValid, + GLuint index, + const GLshort *v); +angle::CallCapture CaptureVertexAttrib3d(const State &glState, + bool isCallValid, + GLuint index, + GLdouble x, + GLdouble y, + GLdouble z); +angle::CallCapture CaptureVertexAttrib3dv(const State &glState, + bool isCallValid, + GLuint index, + const GLdouble *v); +angle::CallCapture CaptureVertexAttrib3s(const State &glState, + bool isCallValid, + GLuint index, + GLshort x, + GLshort y, + GLshort z); +angle::CallCapture CaptureVertexAttrib3sv(const State &glState, + bool isCallValid, + GLuint index, + const GLshort *v); +angle::CallCapture CaptureVertexAttrib4Nbv(const State &glState, + bool isCallValid, + GLuint index, + const GLbyte *v); +angle::CallCapture CaptureVertexAttrib4Niv(const State &glState, + bool isCallValid, + GLuint index, + const GLint *v); +angle::CallCapture CaptureVertexAttrib4Nsv(const State &glState, + bool isCallValid, + GLuint index, + const GLshort *v); +angle::CallCapture CaptureVertexAttrib4Nub(const State &glState, + bool isCallValid, + GLuint index, + GLubyte x, + GLubyte y, + GLubyte z, + GLubyte w); +angle::CallCapture CaptureVertexAttrib4Nubv(const State &glState, + bool isCallValid, + GLuint index, + const GLubyte *v); +angle::CallCapture CaptureVertexAttrib4Nuiv(const State &glState, + bool isCallValid, + GLuint index, + const GLuint *v); +angle::CallCapture CaptureVertexAttrib4Nusv(const State &glState, + bool isCallValid, + GLuint index, + const GLushort *v); +angle::CallCapture CaptureVertexAttrib4bv(const State &glState, + bool isCallValid, + GLuint index, + const GLbyte *v); +angle::CallCapture CaptureVertexAttrib4d(const State &glState, + bool isCallValid, + GLuint index, + GLdouble x, + GLdouble y, + GLdouble z, + GLdouble w); +angle::CallCapture CaptureVertexAttrib4dv(const State &glState, + bool isCallValid, + GLuint index, + const GLdouble *v); +angle::CallCapture CaptureVertexAttrib4iv(const State &glState, + bool isCallValid, + GLuint index, + const GLint *v); +angle::CallCapture CaptureVertexAttrib4s(const State &glState, + bool isCallValid, + GLuint index, + GLshort x, + GLshort y, + GLshort z, + GLshort w); +angle::CallCapture CaptureVertexAttrib4sv(const State &glState, + bool isCallValid, + GLuint index, + const GLshort *v); +angle::CallCapture CaptureVertexAttrib4ubv(const State &glState, + bool isCallValid, + GLuint index, + const GLubyte *v); +angle::CallCapture CaptureVertexAttrib4uiv(const State &glState, + bool isCallValid, + GLuint index, + const GLuint *v); +angle::CallCapture CaptureVertexAttrib4usv(const State &glState, + bool isCallValid, + GLuint index, + const GLushort *v); + +// GL 2.1 + +// Parameter Captures + +// GL 2.0 +void CaptureGetVertexAttribdv_params(const State &glState, + bool isCallValid, + GLuint index, + GLenum pname, + GLdouble *params, + angle::ParamCapture *paramCapture); +void CaptureVertexAttrib1dv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLdouble *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttrib1sv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLshort *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttrib2dv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLdouble *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttrib2sv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLshort *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttrib3dv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLdouble *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttrib3sv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLshort *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttrib4Nbv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLbyte *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttrib4Niv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLint *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttrib4Nsv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLshort *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttrib4Nubv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLubyte *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttrib4Nuiv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLuint *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttrib4Nusv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLushort *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttrib4bv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLbyte *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttrib4dv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLdouble *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttrib4iv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLint *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttrib4sv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLshort *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttrib4ubv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLubyte *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttrib4uiv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLuint *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttrib4usv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLushort *v, + angle::ParamCapture *paramCapture); + +// GL 2.1 +} // namespace gl + +#endif // LIBANGLE_CAPTURE_GL_2_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/capture/capture_gl_3_autogen.h b/gfx/angle/checkout/src/libANGLE/capture/capture_gl_3_autogen.h new file mode 100644 index 0000000000..b365fbec7c --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/capture/capture_gl_3_autogen.h @@ -0,0 +1,609 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// capture_gl_3_autogen.h: +// Capture functions for the OpenGL ES Desktop GL 3.x entry points. + +#ifndef LIBANGLE_CAPTURE_GL_3_AUTOGEN_H_ +#define LIBANGLE_CAPTURE_GL_3_AUTOGEN_H_ + +#include "common/PackedEnums.h" +#include "libANGLE/capture/FrameCapture.h" + +namespace gl +{ + +// Method Captures + +// GL 3.0 +angle::CallCapture CaptureBeginConditionalRender(const State &glState, + bool isCallValid, + GLuint id, + GLenum mode); +angle::CallCapture CaptureBindFragDataLocation(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLuint color, + const GLchar *name); +angle::CallCapture CaptureClampColor(const State &glState, + bool isCallValid, + GLenum target, + GLenum clamp); +angle::CallCapture CaptureEndConditionalRender(const State &glState, bool isCallValid); +angle::CallCapture CaptureFramebufferTexture1D(const State &glState, + bool isCallValid, + GLenum target, + GLenum attachment, + TextureTarget textargetPacked, + TextureID texturePacked, + GLint level); +angle::CallCapture CaptureFramebufferTexture3D(const State &glState, + bool isCallValid, + GLenum target, + GLenum attachment, + TextureTarget textargetPacked, + TextureID texturePacked, + GLint level, + GLint zoffset); +angle::CallCapture CaptureVertexAttribI1i(const State &glState, + bool isCallValid, + GLuint index, + GLint x); +angle::CallCapture CaptureVertexAttribI1iv(const State &glState, + bool isCallValid, + GLuint index, + const GLint *v); +angle::CallCapture CaptureVertexAttribI1ui(const State &glState, + bool isCallValid, + GLuint index, + GLuint x); +angle::CallCapture CaptureVertexAttribI1uiv(const State &glState, + bool isCallValid, + GLuint index, + const GLuint *v); +angle::CallCapture CaptureVertexAttribI2i(const State &glState, + bool isCallValid, + GLuint index, + GLint x, + GLint y); +angle::CallCapture CaptureVertexAttribI2iv(const State &glState, + bool isCallValid, + GLuint index, + const GLint *v); +angle::CallCapture CaptureVertexAttribI2ui(const State &glState, + bool isCallValid, + GLuint index, + GLuint x, + GLuint y); +angle::CallCapture CaptureVertexAttribI2uiv(const State &glState, + bool isCallValid, + GLuint index, + const GLuint *v); +angle::CallCapture CaptureVertexAttribI3i(const State &glState, + bool isCallValid, + GLuint index, + GLint x, + GLint y, + GLint z); +angle::CallCapture CaptureVertexAttribI3iv(const State &glState, + bool isCallValid, + GLuint index, + const GLint *v); +angle::CallCapture CaptureVertexAttribI3ui(const State &glState, + bool isCallValid, + GLuint index, + GLuint x, + GLuint y, + GLuint z); +angle::CallCapture CaptureVertexAttribI3uiv(const State &glState, + bool isCallValid, + GLuint index, + const GLuint *v); +angle::CallCapture CaptureVertexAttribI4bv(const State &glState, + bool isCallValid, + GLuint index, + const GLbyte *v); +angle::CallCapture CaptureVertexAttribI4sv(const State &glState, + bool isCallValid, + GLuint index, + const GLshort *v); +angle::CallCapture CaptureVertexAttribI4ubv(const State &glState, + bool isCallValid, + GLuint index, + const GLubyte *v); +angle::CallCapture CaptureVertexAttribI4usv(const State &glState, + bool isCallValid, + GLuint index, + const GLushort *v); + +// GL 3.1 +angle::CallCapture CaptureGetActiveUniformName(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLuint uniformIndex, + GLsizei bufSize, + GLsizei *length, + GLchar *uniformName); +angle::CallCapture CapturePrimitiveRestartIndex(const State &glState, + bool isCallValid, + GLuint index); + +// GL 3.2 +angle::CallCapture CaptureMultiDrawElementsBaseVertex(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLsizei *count, + DrawElementsType typePacked, + const void *const *indices, + GLsizei drawcount, + const GLint *basevertex); +angle::CallCapture CaptureProvokingVertex(const State &glState, + bool isCallValid, + ProvokingVertexConvention modePacked); +angle::CallCapture CaptureTexImage2DMultisample(const State &glState, + bool isCallValid, + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations); +angle::CallCapture CaptureTexImage3DMultisample(const State &glState, + bool isCallValid, + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedsamplelocations); + +// GL 3.3 +angle::CallCapture CaptureBindFragDataLocationIndexed(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLuint colorNumber, + GLuint index, + const GLchar *name); +angle::CallCapture CaptureColorP3ui(const State &glState, + bool isCallValid, + GLenum type, + GLuint color); +angle::CallCapture CaptureColorP3uiv(const State &glState, + bool isCallValid, + GLenum type, + const GLuint *color); +angle::CallCapture CaptureColorP4ui(const State &glState, + bool isCallValid, + GLenum type, + GLuint color); +angle::CallCapture CaptureColorP4uiv(const State &glState, + bool isCallValid, + GLenum type, + const GLuint *color); +angle::CallCapture CaptureGetFragDataIndex(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + const GLchar *name, + GLint returnValue); +angle::CallCapture CaptureGetQueryObjecti64v(const State &glState, + bool isCallValid, + QueryID idPacked, + GLenum pname, + GLint64 *params); +angle::CallCapture CaptureGetQueryObjectui64v(const State &glState, + bool isCallValid, + QueryID idPacked, + GLenum pname, + GLuint64 *params); +angle::CallCapture CaptureMultiTexCoordP1ui(const State &glState, + bool isCallValid, + GLenum texture, + GLenum type, + GLuint coords); +angle::CallCapture CaptureMultiTexCoordP1uiv(const State &glState, + bool isCallValid, + GLenum texture, + GLenum type, + const GLuint *coords); +angle::CallCapture CaptureMultiTexCoordP2ui(const State &glState, + bool isCallValid, + GLenum texture, + GLenum type, + GLuint coords); +angle::CallCapture CaptureMultiTexCoordP2uiv(const State &glState, + bool isCallValid, + GLenum texture, + GLenum type, + const GLuint *coords); +angle::CallCapture CaptureMultiTexCoordP3ui(const State &glState, + bool isCallValid, + GLenum texture, + GLenum type, + GLuint coords); +angle::CallCapture CaptureMultiTexCoordP3uiv(const State &glState, + bool isCallValid, + GLenum texture, + GLenum type, + const GLuint *coords); +angle::CallCapture CaptureMultiTexCoordP4ui(const State &glState, + bool isCallValid, + GLenum texture, + GLenum type, + GLuint coords); +angle::CallCapture CaptureMultiTexCoordP4uiv(const State &glState, + bool isCallValid, + GLenum texture, + GLenum type, + const GLuint *coords); +angle::CallCapture CaptureNormalP3ui(const State &glState, + bool isCallValid, + GLenum type, + GLuint coords); +angle::CallCapture CaptureNormalP3uiv(const State &glState, + bool isCallValid, + GLenum type, + const GLuint *coords); +angle::CallCapture CaptureQueryCounter(const State &glState, + bool isCallValid, + QueryID idPacked, + QueryType targetPacked); +angle::CallCapture CaptureSecondaryColorP3ui(const State &glState, + bool isCallValid, + GLenum type, + GLuint color); +angle::CallCapture CaptureSecondaryColorP3uiv(const State &glState, + bool isCallValid, + GLenum type, + const GLuint *color); +angle::CallCapture CaptureTexCoordP1ui(const State &glState, + bool isCallValid, + GLenum type, + GLuint coords); +angle::CallCapture CaptureTexCoordP1uiv(const State &glState, + bool isCallValid, + GLenum type, + const GLuint *coords); +angle::CallCapture CaptureTexCoordP2ui(const State &glState, + bool isCallValid, + GLenum type, + GLuint coords); +angle::CallCapture CaptureTexCoordP2uiv(const State &glState, + bool isCallValid, + GLenum type, + const GLuint *coords); +angle::CallCapture CaptureTexCoordP3ui(const State &glState, + bool isCallValid, + GLenum type, + GLuint coords); +angle::CallCapture CaptureTexCoordP3uiv(const State &glState, + bool isCallValid, + GLenum type, + const GLuint *coords); +angle::CallCapture CaptureTexCoordP4ui(const State &glState, + bool isCallValid, + GLenum type, + GLuint coords); +angle::CallCapture CaptureTexCoordP4uiv(const State &glState, + bool isCallValid, + GLenum type, + const GLuint *coords); +angle::CallCapture CaptureVertexAttribP1ui(const State &glState, + bool isCallValid, + GLuint index, + GLenum type, + GLboolean normalized, + GLuint value); +angle::CallCapture CaptureVertexAttribP1uiv(const State &glState, + bool isCallValid, + GLuint index, + GLenum type, + GLboolean normalized, + const GLuint *value); +angle::CallCapture CaptureVertexAttribP2ui(const State &glState, + bool isCallValid, + GLuint index, + GLenum type, + GLboolean normalized, + GLuint value); +angle::CallCapture CaptureVertexAttribP2uiv(const State &glState, + bool isCallValid, + GLuint index, + GLenum type, + GLboolean normalized, + const GLuint *value); +angle::CallCapture CaptureVertexAttribP3ui(const State &glState, + bool isCallValid, + GLuint index, + GLenum type, + GLboolean normalized, + GLuint value); +angle::CallCapture CaptureVertexAttribP3uiv(const State &glState, + bool isCallValid, + GLuint index, + GLenum type, + GLboolean normalized, + const GLuint *value); +angle::CallCapture CaptureVertexAttribP4ui(const State &glState, + bool isCallValid, + GLuint index, + GLenum type, + GLboolean normalized, + GLuint value); +angle::CallCapture CaptureVertexAttribP4uiv(const State &glState, + bool isCallValid, + GLuint index, + GLenum type, + GLboolean normalized, + const GLuint *value); +angle::CallCapture CaptureVertexP2ui(const State &glState, + bool isCallValid, + GLenum type, + GLuint value); +angle::CallCapture CaptureVertexP2uiv(const State &glState, + bool isCallValid, + GLenum type, + const GLuint *value); +angle::CallCapture CaptureVertexP3ui(const State &glState, + bool isCallValid, + GLenum type, + GLuint value); +angle::CallCapture CaptureVertexP3uiv(const State &glState, + bool isCallValid, + GLenum type, + const GLuint *value); +angle::CallCapture CaptureVertexP4ui(const State &glState, + bool isCallValid, + GLenum type, + GLuint value); +angle::CallCapture CaptureVertexP4uiv(const State &glState, + bool isCallValid, + GLenum type, + const GLuint *value); + +// Parameter Captures + +// GL 3.0 +void CaptureBindFragDataLocation_name(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLuint color, + const GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureVertexAttribI1iv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLint *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttribI1uiv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLuint *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttribI2iv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLint *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttribI2uiv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLuint *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttribI3iv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLint *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttribI3uiv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLuint *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttribI4bv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLbyte *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttribI4sv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLshort *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttribI4ubv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLubyte *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttribI4usv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLushort *v, + angle::ParamCapture *paramCapture); + +// GL 3.1 +void CaptureGetActiveUniformName_length(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLuint uniformIndex, + GLsizei bufSize, + GLsizei *length, + GLchar *uniformName, + angle::ParamCapture *paramCapture); +void CaptureGetActiveUniformName_uniformName(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLuint uniformIndex, + GLsizei bufSize, + GLsizei *length, + GLchar *uniformName, + angle::ParamCapture *paramCapture); + +// GL 3.2 +void CaptureMultiDrawElementsBaseVertex_count(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLsizei *count, + DrawElementsType typePacked, + const void *const *indices, + GLsizei drawcount, + const GLint *basevertex, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawElementsBaseVertex_indices(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLsizei *count, + DrawElementsType typePacked, + const void *const *indices, + GLsizei drawcount, + const GLint *basevertex, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawElementsBaseVertex_basevertex(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLsizei *count, + DrawElementsType typePacked, + const void *const *indices, + GLsizei drawcount, + const GLint *basevertex, + angle::ParamCapture *paramCapture); + +// GL 3.3 +void CaptureBindFragDataLocationIndexed_name(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLuint colorNumber, + GLuint index, + const GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureColorP3uiv_color(const State &glState, + bool isCallValid, + GLenum type, + const GLuint *color, + angle::ParamCapture *paramCapture); +void CaptureColorP4uiv_color(const State &glState, + bool isCallValid, + GLenum type, + const GLuint *color, + angle::ParamCapture *paramCapture); +void CaptureGetFragDataIndex_name(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + const GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureGetQueryObjecti64v_params(const State &glState, + bool isCallValid, + QueryID idPacked, + GLenum pname, + GLint64 *params, + angle::ParamCapture *paramCapture); +void CaptureGetQueryObjectui64v_params(const State &glState, + bool isCallValid, + QueryID idPacked, + GLenum pname, + GLuint64 *params, + angle::ParamCapture *paramCapture); +void CaptureMultiTexCoordP1uiv_coords(const State &glState, + bool isCallValid, + GLenum texture, + GLenum type, + const GLuint *coords, + angle::ParamCapture *paramCapture); +void CaptureMultiTexCoordP2uiv_coords(const State &glState, + bool isCallValid, + GLenum texture, + GLenum type, + const GLuint *coords, + angle::ParamCapture *paramCapture); +void CaptureMultiTexCoordP3uiv_coords(const State &glState, + bool isCallValid, + GLenum texture, + GLenum type, + const GLuint *coords, + angle::ParamCapture *paramCapture); +void CaptureMultiTexCoordP4uiv_coords(const State &glState, + bool isCallValid, + GLenum texture, + GLenum type, + const GLuint *coords, + angle::ParamCapture *paramCapture); +void CaptureNormalP3uiv_coords(const State &glState, + bool isCallValid, + GLenum type, + const GLuint *coords, + angle::ParamCapture *paramCapture); +void CaptureSecondaryColorP3uiv_color(const State &glState, + bool isCallValid, + GLenum type, + const GLuint *color, + angle::ParamCapture *paramCapture); +void CaptureTexCoordP1uiv_coords(const State &glState, + bool isCallValid, + GLenum type, + const GLuint *coords, + angle::ParamCapture *paramCapture); +void CaptureTexCoordP2uiv_coords(const State &glState, + bool isCallValid, + GLenum type, + const GLuint *coords, + angle::ParamCapture *paramCapture); +void CaptureTexCoordP3uiv_coords(const State &glState, + bool isCallValid, + GLenum type, + const GLuint *coords, + angle::ParamCapture *paramCapture); +void CaptureTexCoordP4uiv_coords(const State &glState, + bool isCallValid, + GLenum type, + const GLuint *coords, + angle::ParamCapture *paramCapture); +void CaptureVertexAttribP1uiv_value(const State &glState, + bool isCallValid, + GLuint index, + GLenum type, + GLboolean normalized, + const GLuint *value, + angle::ParamCapture *paramCapture); +void CaptureVertexAttribP2uiv_value(const State &glState, + bool isCallValid, + GLuint index, + GLenum type, + GLboolean normalized, + const GLuint *value, + angle::ParamCapture *paramCapture); +void CaptureVertexAttribP3uiv_value(const State &glState, + bool isCallValid, + GLuint index, + GLenum type, + GLboolean normalized, + const GLuint *value, + angle::ParamCapture *paramCapture); +void CaptureVertexAttribP4uiv_value(const State &glState, + bool isCallValid, + GLuint index, + GLenum type, + GLboolean normalized, + const GLuint *value, + angle::ParamCapture *paramCapture); +void CaptureVertexP2uiv_value(const State &glState, + bool isCallValid, + GLenum type, + const GLuint *value, + angle::ParamCapture *paramCapture); +void CaptureVertexP3uiv_value(const State &glState, + bool isCallValid, + GLenum type, + const GLuint *value, + angle::ParamCapture *paramCapture); +void CaptureVertexP4uiv_value(const State &glState, + bool isCallValid, + GLenum type, + const GLuint *value, + angle::ParamCapture *paramCapture); +} // namespace gl + +#endif // LIBANGLE_CAPTURE_GL_3_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/capture/capture_gl_4_autogen.h b/gfx/angle/checkout/src/libANGLE/capture/capture_gl_4_autogen.h new file mode 100644 index 0000000000..495bf4cb7f --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/capture/capture_gl_4_autogen.h @@ -0,0 +1,2524 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// capture_gl_4_autogen.h: +// Capture functions for the OpenGL ES Desktop GL 4.x entry points. + +#ifndef LIBANGLE_CAPTURE_GL_4_AUTOGEN_H_ +#define LIBANGLE_CAPTURE_GL_4_AUTOGEN_H_ + +#include "common/PackedEnums.h" +#include "libANGLE/capture/FrameCapture.h" + +namespace gl +{ + +// Method Captures + +// GL 4.0 +angle::CallCapture CaptureBeginQueryIndexed(const State &glState, + bool isCallValid, + GLenum target, + GLuint index, + QueryID idPacked); +angle::CallCapture CaptureDrawTransformFeedback(const State &glState, + bool isCallValid, + GLenum mode, + TransformFeedbackID idPacked); +angle::CallCapture CaptureDrawTransformFeedbackStream(const State &glState, + bool isCallValid, + GLenum mode, + TransformFeedbackID idPacked, + GLuint stream); +angle::CallCapture CaptureEndQueryIndexed(const State &glState, + bool isCallValid, + GLenum target, + GLuint index); +angle::CallCapture CaptureGetActiveSubroutineName(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum shadertype, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name); +angle::CallCapture CaptureGetActiveSubroutineUniformName(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum shadertype, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name); +angle::CallCapture CaptureGetActiveSubroutineUniformiv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum shadertype, + GLuint index, + GLenum pname, + GLint *values); +angle::CallCapture CaptureGetProgramStageiv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum shadertype, + GLenum pname, + GLint *values); +angle::CallCapture CaptureGetQueryIndexediv(const State &glState, + bool isCallValid, + GLenum target, + GLuint index, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetSubroutineIndex(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum shadertype, + const GLchar *name, + GLuint returnValue); +angle::CallCapture CaptureGetSubroutineUniformLocation(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum shadertype, + const GLchar *name, + GLint returnValue); +angle::CallCapture CaptureGetUniformSubroutineuiv(const State &glState, + bool isCallValid, + GLenum shadertype, + GLint location, + GLuint *params); +angle::CallCapture CaptureGetUniformdv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLdouble *params); +angle::CallCapture CapturePatchParameterfv(const State &glState, + bool isCallValid, + GLenum pname, + const GLfloat *values); +angle::CallCapture CaptureUniform1d(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLdouble x); +angle::CallCapture CaptureUniform1dv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLdouble *value); +angle::CallCapture CaptureUniform2d(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLdouble x, + GLdouble y); +angle::CallCapture CaptureUniform2dv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLdouble *value); +angle::CallCapture CaptureUniform3d(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLdouble x, + GLdouble y, + GLdouble z); +angle::CallCapture CaptureUniform3dv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLdouble *value); +angle::CallCapture CaptureUniform4d(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLdouble x, + GLdouble y, + GLdouble z, + GLdouble w); +angle::CallCapture CaptureUniform4dv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLdouble *value); +angle::CallCapture CaptureUniformMatrix2dv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +angle::CallCapture CaptureUniformMatrix2x3dv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +angle::CallCapture CaptureUniformMatrix2x4dv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +angle::CallCapture CaptureUniformMatrix3dv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +angle::CallCapture CaptureUniformMatrix3x2dv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +angle::CallCapture CaptureUniformMatrix3x4dv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +angle::CallCapture CaptureUniformMatrix4dv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +angle::CallCapture CaptureUniformMatrix4x2dv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +angle::CallCapture CaptureUniformMatrix4x3dv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +angle::CallCapture CaptureUniformSubroutinesuiv(const State &glState, + bool isCallValid, + GLenum shadertype, + GLsizei count, + const GLuint *indices); + +// GL 4.1 +angle::CallCapture CaptureDepthRangeArrayv(const State &glState, + bool isCallValid, + GLuint first, + GLsizei count, + const GLdouble *v); +angle::CallCapture CaptureDepthRangeIndexed(const State &glState, + bool isCallValid, + GLuint index, + GLdouble n, + GLdouble f); +angle::CallCapture CaptureGetDoublei_v(const State &glState, + bool isCallValid, + GLenum target, + GLuint index, + GLdouble *data); +angle::CallCapture CaptureGetFloati_v(const State &glState, + bool isCallValid, + GLenum target, + GLuint index, + GLfloat *data); +angle::CallCapture CaptureGetVertexAttribLdv(const State &glState, + bool isCallValid, + GLuint index, + GLenum pname, + GLdouble *params); +angle::CallCapture CaptureProgramUniform1d(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLdouble v0); +angle::CallCapture CaptureProgramUniform1dv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLdouble *value); +angle::CallCapture CaptureProgramUniform2d(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLdouble v0, + GLdouble v1); +angle::CallCapture CaptureProgramUniform2dv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLdouble *value); +angle::CallCapture CaptureProgramUniform3d(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLdouble v0, + GLdouble v1, + GLdouble v2); +angle::CallCapture CaptureProgramUniform3dv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLdouble *value); +angle::CallCapture CaptureProgramUniform4d(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLdouble v0, + GLdouble v1, + GLdouble v2, + GLdouble v3); +angle::CallCapture CaptureProgramUniform4dv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLdouble *value); +angle::CallCapture CaptureProgramUniformMatrix2dv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +angle::CallCapture CaptureProgramUniformMatrix2x3dv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +angle::CallCapture CaptureProgramUniformMatrix2x4dv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +angle::CallCapture CaptureProgramUniformMatrix3dv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +angle::CallCapture CaptureProgramUniformMatrix3x2dv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +angle::CallCapture CaptureProgramUniformMatrix3x4dv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +angle::CallCapture CaptureProgramUniformMatrix4dv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +angle::CallCapture CaptureProgramUniformMatrix4x2dv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +angle::CallCapture CaptureProgramUniformMatrix4x3dv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +angle::CallCapture CaptureScissorArrayv(const State &glState, + bool isCallValid, + GLuint first, + GLsizei count, + const GLint *v); +angle::CallCapture CaptureScissorIndexed(const State &glState, + bool isCallValid, + GLuint index, + GLint left, + GLint bottom, + GLsizei width, + GLsizei height); +angle::CallCapture CaptureScissorIndexedv(const State &glState, + bool isCallValid, + GLuint index, + const GLint *v); +angle::CallCapture CaptureVertexAttribL1d(const State &glState, + bool isCallValid, + GLuint index, + GLdouble x); +angle::CallCapture CaptureVertexAttribL1dv(const State &glState, + bool isCallValid, + GLuint index, + const GLdouble *v); +angle::CallCapture CaptureVertexAttribL2d(const State &glState, + bool isCallValid, + GLuint index, + GLdouble x, + GLdouble y); +angle::CallCapture CaptureVertexAttribL2dv(const State &glState, + bool isCallValid, + GLuint index, + const GLdouble *v); +angle::CallCapture CaptureVertexAttribL3d(const State &glState, + bool isCallValid, + GLuint index, + GLdouble x, + GLdouble y, + GLdouble z); +angle::CallCapture CaptureVertexAttribL3dv(const State &glState, + bool isCallValid, + GLuint index, + const GLdouble *v); +angle::CallCapture CaptureVertexAttribL4d(const State &glState, + bool isCallValid, + GLuint index, + GLdouble x, + GLdouble y, + GLdouble z, + GLdouble w); +angle::CallCapture CaptureVertexAttribL4dv(const State &glState, + bool isCallValid, + GLuint index, + const GLdouble *v); +angle::CallCapture CaptureVertexAttribLPointer(const State &glState, + bool isCallValid, + GLuint index, + GLint size, + GLenum type, + GLsizei stride, + const void *pointer); +angle::CallCapture CaptureViewportArrayv(const State &glState, + bool isCallValid, + GLuint first, + GLsizei count, + const GLfloat *v); +angle::CallCapture CaptureViewportIndexedf(const State &glState, + bool isCallValid, + GLuint index, + GLfloat x, + GLfloat y, + GLfloat w, + GLfloat h); +angle::CallCapture CaptureViewportIndexedfv(const State &glState, + bool isCallValid, + GLuint index, + const GLfloat *v); + +// GL 4.2 +angle::CallCapture CaptureDrawArraysInstancedBaseInstance(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLint first, + GLsizei count, + GLsizei instancecount, + GLuint baseinstance); +angle::CallCapture CaptureDrawElementsInstancedBaseInstance(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLsizei instancecount, + GLuint baseinstance); +angle::CallCapture CaptureDrawElementsInstancedBaseVertexBaseInstance(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLsizei instancecount, + GLint basevertex, + GLuint baseinstance); +angle::CallCapture CaptureDrawTransformFeedbackInstanced(const State &glState, + bool isCallValid, + GLenum mode, + TransformFeedbackID idPacked, + GLsizei instancecount); +angle::CallCapture CaptureDrawTransformFeedbackStreamInstanced(const State &glState, + bool isCallValid, + GLenum mode, + TransformFeedbackID idPacked, + GLuint stream, + GLsizei instancecount); +angle::CallCapture CaptureGetActiveAtomicCounterBufferiv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLuint bufferIndex, + GLenum pname, + GLint *params); +angle::CallCapture CaptureTexStorage1D(const State &glState, + bool isCallValid, + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width); + +// GL 4.3 +angle::CallCapture CaptureClearBufferData(const State &glState, + bool isCallValid, + GLenum target, + GLenum internalformat, + GLenum format, + GLenum type, + const void *data); +angle::CallCapture CaptureClearBufferSubData(const State &glState, + bool isCallValid, + GLenum target, + GLenum internalformat, + GLintptr offset, + GLsizeiptr size, + GLenum format, + GLenum type, + const void *data); +angle::CallCapture CaptureGetInternalformati64v(const State &glState, + bool isCallValid, + GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei count, + GLint64 *params); +angle::CallCapture CaptureGetProgramResourceLocationIndex(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum programInterface, + const GLchar *name, + GLint returnValue); +angle::CallCapture CaptureInvalidateBufferData(const State &glState, + bool isCallValid, + BufferID bufferPacked); +angle::CallCapture CaptureInvalidateBufferSubData(const State &glState, + bool isCallValid, + BufferID bufferPacked, + GLintptr offset, + GLsizeiptr length); +angle::CallCapture CaptureInvalidateTexImage(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level); +angle::CallCapture CaptureInvalidateTexSubImage(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth); +angle::CallCapture CaptureMultiDrawArraysIndirect(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const void *indirect, + GLsizei drawcount, + GLsizei stride); +angle::CallCapture CaptureMultiDrawElementsIndirect(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + DrawElementsType typePacked, + const void *indirect, + GLsizei drawcount, + GLsizei stride); +angle::CallCapture CaptureShaderStorageBlockBinding(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLuint storageBlockIndex, + GLuint storageBlockBinding); +angle::CallCapture CaptureTextureView(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLenum target, + GLuint origtexture, + GLenum internalformat, + GLuint minlevel, + GLuint numlevels, + GLuint minlayer, + GLuint numlayers); +angle::CallCapture CaptureVertexAttribLFormat(const State &glState, + bool isCallValid, + GLuint attribindex, + GLint size, + GLenum type, + GLuint relativeoffset); + +// GL 4.4 +angle::CallCapture CaptureBindBuffersBase(const State &glState, + bool isCallValid, + GLenum target, + GLuint first, + GLsizei count, + const BufferID *buffersPacked); +angle::CallCapture CaptureBindBuffersRange(const State &glState, + bool isCallValid, + GLenum target, + GLuint first, + GLsizei count, + const BufferID *buffersPacked, + const GLintptr *offsets, + const GLsizeiptr *sizes); +angle::CallCapture CaptureBindImageTextures(const State &glState, + bool isCallValid, + GLuint first, + GLsizei count, + const GLuint *textures); +angle::CallCapture CaptureBindSamplers(const State &glState, + bool isCallValid, + GLuint first, + GLsizei count, + const GLuint *samplers); +angle::CallCapture CaptureBindTextures(const State &glState, + bool isCallValid, + GLuint first, + GLsizei count, + const GLuint *textures); +angle::CallCapture CaptureBindVertexBuffers(const State &glState, + bool isCallValid, + GLuint first, + GLsizei count, + const BufferID *buffersPacked, + const GLintptr *offsets, + const GLsizei *strides); +angle::CallCapture CaptureBufferStorage(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLsizeiptr size, + const void *data, + GLbitfield flags); +angle::CallCapture CaptureClearTexImage(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLenum format, + GLenum type, + const void *data); +angle::CallCapture CaptureClearTexSubImage(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *data); + +// GL 4.5 +angle::CallCapture CaptureBindTextureUnit(const State &glState, + bool isCallValid, + GLuint unit, + TextureID texturePacked); +angle::CallCapture CaptureBlitNamedFramebuffer(const State &glState, + bool isCallValid, + GLuint readFramebuffer, + GLuint drawFramebuffer, + GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter); +angle::CallCapture CaptureCheckNamedFramebufferStatus(const State &glState, + bool isCallValid, + FramebufferID framebufferPacked, + GLenum target, + GLenum returnValue); +angle::CallCapture CaptureClearNamedBufferData(const State &glState, + bool isCallValid, + BufferID bufferPacked, + GLenum internalformat, + GLenum format, + GLenum type, + const void *data); +angle::CallCapture CaptureClearNamedBufferSubData(const State &glState, + bool isCallValid, + BufferID bufferPacked, + GLenum internalformat, + GLintptr offset, + GLsizeiptr size, + GLenum format, + GLenum type, + const void *data); +angle::CallCapture CaptureClearNamedFramebufferfi(const State &glState, + bool isCallValid, + FramebufferID framebufferPacked, + GLenum buffer, + GLint drawbuffer, + GLfloat depth, + GLint stencil); +angle::CallCapture CaptureClearNamedFramebufferfv(const State &glState, + bool isCallValid, + FramebufferID framebufferPacked, + GLenum buffer, + GLint drawbuffer, + const GLfloat *value); +angle::CallCapture CaptureClearNamedFramebufferiv(const State &glState, + bool isCallValid, + FramebufferID framebufferPacked, + GLenum buffer, + GLint drawbuffer, + const GLint *value); +angle::CallCapture CaptureClearNamedFramebufferuiv(const State &glState, + bool isCallValid, + FramebufferID framebufferPacked, + GLenum buffer, + GLint drawbuffer, + const GLuint *value); +angle::CallCapture CaptureClipControl(const State &glState, + bool isCallValid, + GLenum origin, + GLenum depth); +angle::CallCapture CaptureCompressedTextureSubImage1D(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, + GLsizei imageSize, + const void *data); +angle::CallCapture CaptureCompressedTextureSubImage2D(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + const void *data); +angle::CallCapture CaptureCompressedTextureSubImage3D(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const void *data); +angle::CallCapture CaptureCopyNamedBufferSubData(const State &glState, + bool isCallValid, + GLuint readBuffer, + GLuint writeBuffer, + GLintptr readOffset, + GLintptr writeOffset, + GLsizeiptr size); +angle::CallCapture CaptureCopyTextureSubImage1D(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLint x, + GLint y, + GLsizei width); +angle::CallCapture CaptureCopyTextureSubImage2D(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height); +angle::CallCapture CaptureCopyTextureSubImage3D(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height); +angle::CallCapture CaptureCreateBuffers(const State &glState, + bool isCallValid, + GLsizei n, + BufferID *buffersPacked); +angle::CallCapture CaptureCreateFramebuffers(const State &glState, + bool isCallValid, + GLsizei n, + GLuint *framebuffers); +angle::CallCapture CaptureCreateProgramPipelines(const State &glState, + bool isCallValid, + GLsizei n, + GLuint *pipelines); +angle::CallCapture CaptureCreateQueries(const State &glState, + bool isCallValid, + GLenum target, + GLsizei n, + GLuint *ids); +angle::CallCapture CaptureCreateRenderbuffers(const State &glState, + bool isCallValid, + GLsizei n, + RenderbufferID *renderbuffersPacked); +angle::CallCapture CaptureCreateSamplers(const State &glState, + bool isCallValid, + GLsizei n, + GLuint *samplers); +angle::CallCapture CaptureCreateTextures(const State &glState, + bool isCallValid, + GLenum target, + GLsizei n, + GLuint *textures); +angle::CallCapture CaptureCreateTransformFeedbacks(const State &glState, + bool isCallValid, + GLsizei n, + GLuint *ids); +angle::CallCapture CaptureCreateVertexArrays(const State &glState, + bool isCallValid, + GLsizei n, + VertexArrayID *arraysPacked); +angle::CallCapture CaptureDisableVertexArrayAttrib(const State &glState, + bool isCallValid, + VertexArrayID vaobjPacked, + GLuint index); +angle::CallCapture CaptureEnableVertexArrayAttrib(const State &glState, + bool isCallValid, + VertexArrayID vaobjPacked, + GLuint index); +angle::CallCapture CaptureFlushMappedNamedBufferRange(const State &glState, + bool isCallValid, + BufferID bufferPacked, + GLintptr offset, + GLsizeiptr length); +angle::CallCapture CaptureGenerateTextureMipmap(const State &glState, + bool isCallValid, + TextureID texturePacked); +angle::CallCapture CaptureGetCompressedTextureImage(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLsizei bufSize, + void *pixels); +angle::CallCapture CaptureGetCompressedTextureSubImage(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLsizei bufSize, + void *pixels); +angle::CallCapture CaptureGetNamedBufferParameteri64v(const State &glState, + bool isCallValid, + BufferID bufferPacked, + GLenum pname, + GLint64 *params); +angle::CallCapture CaptureGetNamedBufferParameteriv(const State &glState, + bool isCallValid, + BufferID bufferPacked, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetNamedBufferPointerv(const State &glState, + bool isCallValid, + BufferID bufferPacked, + GLenum pname, + void **params); +angle::CallCapture CaptureGetNamedBufferSubData(const State &glState, + bool isCallValid, + BufferID bufferPacked, + GLintptr offset, + GLsizeiptr size, + void *data); +angle::CallCapture CaptureGetNamedFramebufferAttachmentParameteriv(const State &glState, + bool isCallValid, + FramebufferID framebufferPacked, + GLenum attachment, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetNamedFramebufferParameteriv(const State &glState, + bool isCallValid, + FramebufferID framebufferPacked, + GLenum pname, + GLint *param); +angle::CallCapture CaptureGetNamedRenderbufferParameteriv(const State &glState, + bool isCallValid, + RenderbufferID renderbufferPacked, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetQueryBufferObjecti64v(const State &glState, + bool isCallValid, + GLuint id, + BufferID bufferPacked, + GLenum pname, + GLintptr offset); +angle::CallCapture CaptureGetQueryBufferObjectiv(const State &glState, + bool isCallValid, + GLuint id, + BufferID bufferPacked, + GLenum pname, + GLintptr offset); +angle::CallCapture CaptureGetQueryBufferObjectui64v(const State &glState, + bool isCallValid, + GLuint id, + BufferID bufferPacked, + GLenum pname, + GLintptr offset); +angle::CallCapture CaptureGetQueryBufferObjectuiv(const State &glState, + bool isCallValid, + GLuint id, + BufferID bufferPacked, + GLenum pname, + GLintptr offset); +angle::CallCapture CaptureGetTextureImage(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLenum format, + GLenum type, + GLsizei bufSize, + void *pixels); +angle::CallCapture CaptureGetTextureLevelParameterfv(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLenum pname, + GLfloat *params); +angle::CallCapture CaptureGetTextureLevelParameteriv(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetTextureParameterIiv(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetTextureParameterIuiv(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLenum pname, + GLuint *params); +angle::CallCapture CaptureGetTextureParameterfv(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLenum pname, + GLfloat *params); +angle::CallCapture CaptureGetTextureParameteriv(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetTextureSubImage(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + GLsizei bufSize, + void *pixels); +angle::CallCapture CaptureGetTransformFeedbacki64_v(const State &glState, + bool isCallValid, + GLuint xfb, + GLenum pname, + GLuint index, + GLint64 *param); +angle::CallCapture CaptureGetTransformFeedbacki_v(const State &glState, + bool isCallValid, + GLuint xfb, + GLenum pname, + GLuint index, + GLint *param); +angle::CallCapture CaptureGetTransformFeedbackiv(const State &glState, + bool isCallValid, + GLuint xfb, + GLenum pname, + GLint *param); +angle::CallCapture CaptureGetVertexArrayIndexed64iv(const State &glState, + bool isCallValid, + VertexArrayID vaobjPacked, + GLuint index, + GLenum pname, + GLint64 *param); +angle::CallCapture CaptureGetVertexArrayIndexediv(const State &glState, + bool isCallValid, + VertexArrayID vaobjPacked, + GLuint index, + GLenum pname, + GLint *param); +angle::CallCapture CaptureGetVertexArrayiv(const State &glState, + bool isCallValid, + VertexArrayID vaobjPacked, + GLenum pname, + GLint *param); +angle::CallCapture CaptureGetnColorTable(const State &glState, + bool isCallValid, + GLenum target, + GLenum format, + GLenum type, + GLsizei bufSize, + void *table); +angle::CallCapture CaptureGetnCompressedTexImage(const State &glState, + bool isCallValid, + GLenum target, + GLint lod, + GLsizei bufSize, + void *pixels); +angle::CallCapture CaptureGetnConvolutionFilter(const State &glState, + bool isCallValid, + GLenum target, + GLenum format, + GLenum type, + GLsizei bufSize, + void *image); +angle::CallCapture CaptureGetnHistogram(const State &glState, + bool isCallValid, + GLenum target, + GLboolean reset, + GLenum format, + GLenum type, + GLsizei bufSize, + void *values); +angle::CallCapture CaptureGetnMapdv(const State &glState, + bool isCallValid, + GLenum target, + GLenum query, + GLsizei bufSize, + GLdouble *v); +angle::CallCapture CaptureGetnMapfv(const State &glState, + bool isCallValid, + GLenum target, + GLenum query, + GLsizei bufSize, + GLfloat *v); +angle::CallCapture CaptureGetnMapiv(const State &glState, + bool isCallValid, + GLenum target, + GLenum query, + GLsizei bufSize, + GLint *v); +angle::CallCapture CaptureGetnMinmax(const State &glState, + bool isCallValid, + GLenum target, + GLboolean reset, + GLenum format, + GLenum type, + GLsizei bufSize, + void *values); +angle::CallCapture CaptureGetnPixelMapfv(const State &glState, + bool isCallValid, + GLenum map, + GLsizei bufSize, + GLfloat *values); +angle::CallCapture CaptureGetnPixelMapuiv(const State &glState, + bool isCallValid, + GLenum map, + GLsizei bufSize, + GLuint *values); +angle::CallCapture CaptureGetnPixelMapusv(const State &glState, + bool isCallValid, + GLenum map, + GLsizei bufSize, + GLushort *values); +angle::CallCapture CaptureGetnPolygonStipple(const State &glState, + bool isCallValid, + GLsizei bufSize, + GLubyte *pattern); +angle::CallCapture CaptureGetnSeparableFilter(const State &glState, + bool isCallValid, + GLenum target, + GLenum format, + GLenum type, + GLsizei rowBufSize, + void *row, + GLsizei columnBufSize, + void *column, + void *span); +angle::CallCapture CaptureGetnTexImage(const State &glState, + bool isCallValid, + GLenum target, + GLint level, + GLenum format, + GLenum type, + GLsizei bufSize, + void *pixels); +angle::CallCapture CaptureGetnUniformdv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + GLdouble *params); +angle::CallCapture CaptureInvalidateNamedFramebufferData(const State &glState, + bool isCallValid, + FramebufferID framebufferPacked, + GLsizei numAttachments, + const GLenum *attachments); +angle::CallCapture CaptureInvalidateNamedFramebufferSubData(const State &glState, + bool isCallValid, + FramebufferID framebufferPacked, + GLsizei numAttachments, + const GLenum *attachments, + GLint x, + GLint y, + GLsizei width, + GLsizei height); +angle::CallCapture CaptureMapNamedBuffer(const State &glState, + bool isCallValid, + BufferID bufferPacked, + GLenum access, + void *returnValue); +angle::CallCapture CaptureMapNamedBufferRange(const State &glState, + bool isCallValid, + BufferID bufferPacked, + GLintptr offset, + GLsizeiptr length, + GLbitfield access, + void *returnValue); +angle::CallCapture CaptureNamedBufferData(const State &glState, + bool isCallValid, + BufferID bufferPacked, + GLsizeiptr size, + const void *data, + GLenum usage); +angle::CallCapture CaptureNamedBufferStorage(const State &glState, + bool isCallValid, + BufferID bufferPacked, + GLsizeiptr size, + const void *data, + GLbitfield flags); +angle::CallCapture CaptureNamedBufferSubData(const State &glState, + bool isCallValid, + BufferID bufferPacked, + GLintptr offset, + GLsizeiptr size, + const void *data); +angle::CallCapture CaptureNamedFramebufferDrawBuffer(const State &glState, + bool isCallValid, + FramebufferID framebufferPacked, + GLenum buf); +angle::CallCapture CaptureNamedFramebufferDrawBuffers(const State &glState, + bool isCallValid, + FramebufferID framebufferPacked, + GLsizei n, + const GLenum *bufs); +angle::CallCapture CaptureNamedFramebufferParameteri(const State &glState, + bool isCallValid, + FramebufferID framebufferPacked, + GLenum pname, + GLint param); +angle::CallCapture CaptureNamedFramebufferReadBuffer(const State &glState, + bool isCallValid, + FramebufferID framebufferPacked, + GLenum src); +angle::CallCapture CaptureNamedFramebufferRenderbuffer(const State &glState, + bool isCallValid, + FramebufferID framebufferPacked, + GLenum attachment, + GLenum renderbuffertarget, + RenderbufferID renderbufferPacked); +angle::CallCapture CaptureNamedFramebufferTexture(const State &glState, + bool isCallValid, + FramebufferID framebufferPacked, + GLenum attachment, + TextureID texturePacked, + GLint level); +angle::CallCapture CaptureNamedFramebufferTextureLayer(const State &glState, + bool isCallValid, + FramebufferID framebufferPacked, + GLenum attachment, + TextureID texturePacked, + GLint level, + GLint layer); +angle::CallCapture CaptureNamedRenderbufferStorage(const State &glState, + bool isCallValid, + RenderbufferID renderbufferPacked, + GLenum internalformat, + GLsizei width, + GLsizei height); +angle::CallCapture CaptureNamedRenderbufferStorageMultisample(const State &glState, + bool isCallValid, + RenderbufferID renderbufferPacked, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height); +angle::CallCapture CaptureTextureBarrier(const State &glState, bool isCallValid); +angle::CallCapture CaptureTextureBuffer(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLenum internalformat, + BufferID bufferPacked); +angle::CallCapture CaptureTextureBufferRange(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLenum internalformat, + BufferID bufferPacked, + GLintptr offset, + GLsizeiptr size); +angle::CallCapture CaptureTextureParameterIiv(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLenum pname, + const GLint *params); +angle::CallCapture CaptureTextureParameterIuiv(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLenum pname, + const GLuint *params); +angle::CallCapture CaptureTextureParameterf(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLenum pname, + GLfloat param); +angle::CallCapture CaptureTextureParameterfv(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLenum pname, + const GLfloat *param); +angle::CallCapture CaptureTextureParameteri(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLenum pname, + GLint param); +angle::CallCapture CaptureTextureParameteriv(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLenum pname, + const GLint *param); +angle::CallCapture CaptureTextureStorage1D(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLsizei levels, + GLenum internalformat, + GLsizei width); +angle::CallCapture CaptureTextureStorage2D(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height); +angle::CallCapture CaptureTextureStorage2DMultisample(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations); +angle::CallCapture CaptureTextureStorage3D(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth); +angle::CallCapture CaptureTextureStorage3DMultisample(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedsamplelocations); +angle::CallCapture CaptureTextureSubImage1D(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, + GLenum type, + const void *pixels); +angle::CallCapture CaptureTextureSubImage2D(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void *pixels); +angle::CallCapture CaptureTextureSubImage3D(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *pixels); +angle::CallCapture CaptureTransformFeedbackBufferBase(const State &glState, + bool isCallValid, + GLuint xfb, + GLuint index, + BufferID bufferPacked); +angle::CallCapture CaptureTransformFeedbackBufferRange(const State &glState, + bool isCallValid, + GLuint xfb, + GLuint index, + BufferID bufferPacked, + GLintptr offset, + GLsizeiptr size); +angle::CallCapture CaptureUnmapNamedBuffer(const State &glState, + bool isCallValid, + BufferID bufferPacked, + GLboolean returnValue); +angle::CallCapture CaptureVertexArrayAttribBinding(const State &glState, + bool isCallValid, + VertexArrayID vaobjPacked, + GLuint attribindex, + GLuint bindingindex); +angle::CallCapture CaptureVertexArrayAttribFormat(const State &glState, + bool isCallValid, + VertexArrayID vaobjPacked, + GLuint attribindex, + GLint size, + GLenum type, + GLboolean normalized, + GLuint relativeoffset); +angle::CallCapture CaptureVertexArrayAttribIFormat(const State &glState, + bool isCallValid, + VertexArrayID vaobjPacked, + GLuint attribindex, + GLint size, + GLenum type, + GLuint relativeoffset); +angle::CallCapture CaptureVertexArrayAttribLFormat(const State &glState, + bool isCallValid, + VertexArrayID vaobjPacked, + GLuint attribindex, + GLint size, + GLenum type, + GLuint relativeoffset); +angle::CallCapture CaptureVertexArrayBindingDivisor(const State &glState, + bool isCallValid, + VertexArrayID vaobjPacked, + GLuint bindingindex, + GLuint divisor); +angle::CallCapture CaptureVertexArrayElementBuffer(const State &glState, + bool isCallValid, + VertexArrayID vaobjPacked, + BufferID bufferPacked); +angle::CallCapture CaptureVertexArrayVertexBuffer(const State &glState, + bool isCallValid, + VertexArrayID vaobjPacked, + GLuint bindingindex, + BufferID bufferPacked, + GLintptr offset, + GLsizei stride); +angle::CallCapture CaptureVertexArrayVertexBuffers(const State &glState, + bool isCallValid, + VertexArrayID vaobjPacked, + GLuint first, + GLsizei count, + const BufferID *buffersPacked, + const GLintptr *offsets, + const GLsizei *strides); + +// GL 4.6 +angle::CallCapture CaptureMultiDrawArraysIndirectCount(const State &glState, + bool isCallValid, + GLenum mode, + const void *indirect, + GLintptr drawcount, + GLsizei maxdrawcount, + GLsizei stride); +angle::CallCapture CaptureMultiDrawElementsIndirectCount(const State &glState, + bool isCallValid, + GLenum mode, + GLenum type, + const void *indirect, + GLintptr drawcount, + GLsizei maxdrawcount, + GLsizei stride); +angle::CallCapture CapturePolygonOffsetClamp(const State &glState, + bool isCallValid, + GLfloat factor, + GLfloat units, + GLfloat clamp); +angle::CallCapture CaptureSpecializeShader(const State &glState, + bool isCallValid, + GLuint shader, + const GLchar *pEntryPoint, + GLuint numSpecializationConstants, + const GLuint *pConstantIndex, + const GLuint *pConstantValue); + +// Parameter Captures + +// GL 4.0 +void CaptureGetActiveSubroutineName_length(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum shadertype, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureGetActiveSubroutineName_name(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum shadertype, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureGetActiveSubroutineUniformName_length(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum shadertype, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureGetActiveSubroutineUniformName_name(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum shadertype, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureGetActiveSubroutineUniformiv_values(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum shadertype, + GLuint index, + GLenum pname, + GLint *values, + angle::ParamCapture *paramCapture); +void CaptureGetProgramStageiv_values(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum shadertype, + GLenum pname, + GLint *values, + angle::ParamCapture *paramCapture); +void CaptureGetQueryIndexediv_params(const State &glState, + bool isCallValid, + GLenum target, + GLuint index, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetSubroutineIndex_name(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum shadertype, + const GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureGetSubroutineUniformLocation_name(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum shadertype, + const GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureGetUniformSubroutineuiv_params(const State &glState, + bool isCallValid, + GLenum shadertype, + GLint location, + GLuint *params, + angle::ParamCapture *paramCapture); +void CaptureGetUniformdv_params(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLdouble *params, + angle::ParamCapture *paramCapture); +void CapturePatchParameterfv_values(const State &glState, + bool isCallValid, + GLenum pname, + const GLfloat *values, + angle::ParamCapture *paramCapture); +void CaptureUniform1dv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLdouble *value, + angle::ParamCapture *paramCapture); +void CaptureUniform2dv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLdouble *value, + angle::ParamCapture *paramCapture); +void CaptureUniform3dv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLdouble *value, + angle::ParamCapture *paramCapture); +void CaptureUniform4dv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLdouble *value, + angle::ParamCapture *paramCapture); +void CaptureUniformMatrix2dv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value, + angle::ParamCapture *paramCapture); +void CaptureUniformMatrix2x3dv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value, + angle::ParamCapture *paramCapture); +void CaptureUniformMatrix2x4dv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value, + angle::ParamCapture *paramCapture); +void CaptureUniformMatrix3dv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value, + angle::ParamCapture *paramCapture); +void CaptureUniformMatrix3x2dv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value, + angle::ParamCapture *paramCapture); +void CaptureUniformMatrix3x4dv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value, + angle::ParamCapture *paramCapture); +void CaptureUniformMatrix4dv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value, + angle::ParamCapture *paramCapture); +void CaptureUniformMatrix4x2dv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value, + angle::ParamCapture *paramCapture); +void CaptureUniformMatrix4x3dv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value, + angle::ParamCapture *paramCapture); +void CaptureUniformSubroutinesuiv_indices(const State &glState, + bool isCallValid, + GLenum shadertype, + GLsizei count, + const GLuint *indices, + angle::ParamCapture *paramCapture); + +// GL 4.1 +void CaptureDepthRangeArrayv_v(const State &glState, + bool isCallValid, + GLuint first, + GLsizei count, + const GLdouble *v, + angle::ParamCapture *paramCapture); +void CaptureGetDoublei_v_data(const State &glState, + bool isCallValid, + GLenum target, + GLuint index, + GLdouble *data, + angle::ParamCapture *paramCapture); +void CaptureGetFloati_v_data(const State &glState, + bool isCallValid, + GLenum target, + GLuint index, + GLfloat *data, + angle::ParamCapture *paramCapture); +void CaptureGetVertexAttribLdv_params(const State &glState, + bool isCallValid, + GLuint index, + GLenum pname, + GLdouble *params, + angle::ParamCapture *paramCapture); +void CaptureProgramUniform1dv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLdouble *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniform2dv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLdouble *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniform3dv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLdouble *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniform4dv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLdouble *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniformMatrix2dv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniformMatrix2x3dv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniformMatrix2x4dv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniformMatrix3dv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniformMatrix3x2dv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniformMatrix3x4dv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniformMatrix4dv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniformMatrix4x2dv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniformMatrix4x3dv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value, + angle::ParamCapture *paramCapture); +void CaptureScissorArrayv_v(const State &glState, + bool isCallValid, + GLuint first, + GLsizei count, + const GLint *v, + angle::ParamCapture *paramCapture); +void CaptureScissorIndexedv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLint *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttribL1dv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLdouble *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttribL2dv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLdouble *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttribL3dv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLdouble *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttribL4dv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLdouble *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttribLPointer_pointer(const State &glState, + bool isCallValid, + GLuint index, + GLint size, + GLenum type, + GLsizei stride, + const void *pointer, + angle::ParamCapture *paramCapture); +void CaptureViewportArrayv_v(const State &glState, + bool isCallValid, + GLuint first, + GLsizei count, + const GLfloat *v, + angle::ParamCapture *paramCapture); +void CaptureViewportIndexedfv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLfloat *v, + angle::ParamCapture *paramCapture); + +// GL 4.2 +void CaptureDrawElementsInstancedBaseInstance_indices(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLsizei instancecount, + GLuint baseinstance, + angle::ParamCapture *paramCapture); +void CaptureDrawElementsInstancedBaseVertexBaseInstance_indices(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLsizei instancecount, + GLint basevertex, + GLuint baseinstance, + angle::ParamCapture *paramCapture); +void CaptureGetActiveAtomicCounterBufferiv_params(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLuint bufferIndex, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); + +// GL 4.3 +void CaptureClearBufferData_data(const State &glState, + bool isCallValid, + GLenum target, + GLenum internalformat, + GLenum format, + GLenum type, + const void *data, + angle::ParamCapture *paramCapture); +void CaptureClearBufferSubData_data(const State &glState, + bool isCallValid, + GLenum target, + GLenum internalformat, + GLintptr offset, + GLsizeiptr size, + GLenum format, + GLenum type, + const void *data, + angle::ParamCapture *paramCapture); +void CaptureGetInternalformati64v_params(const State &glState, + bool isCallValid, + GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei count, + GLint64 *params, + angle::ParamCapture *paramCapture); +void CaptureGetProgramResourceLocationIndex_name(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum programInterface, + const GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawArraysIndirect_indirect(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const void *indirect, + GLsizei drawcount, + GLsizei stride, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawElementsIndirect_indirect(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + DrawElementsType typePacked, + const void *indirect, + GLsizei drawcount, + GLsizei stride, + angle::ParamCapture *paramCapture); + +// GL 4.4 +void CaptureBindBuffersBase_buffersPacked(const State &glState, + bool isCallValid, + GLenum target, + GLuint first, + GLsizei count, + const BufferID *buffersPacked, + angle::ParamCapture *paramCapture); +void CaptureBindBuffersRange_buffersPacked(const State &glState, + bool isCallValid, + GLenum target, + GLuint first, + GLsizei count, + const BufferID *buffersPacked, + const GLintptr *offsets, + const GLsizeiptr *sizes, + angle::ParamCapture *paramCapture); +void CaptureBindBuffersRange_offsets(const State &glState, + bool isCallValid, + GLenum target, + GLuint first, + GLsizei count, + const BufferID *buffersPacked, + const GLintptr *offsets, + const GLsizeiptr *sizes, + angle::ParamCapture *paramCapture); +void CaptureBindBuffersRange_sizes(const State &glState, + bool isCallValid, + GLenum target, + GLuint first, + GLsizei count, + const BufferID *buffersPacked, + const GLintptr *offsets, + const GLsizeiptr *sizes, + angle::ParamCapture *paramCapture); +void CaptureBindImageTextures_textures(const State &glState, + bool isCallValid, + GLuint first, + GLsizei count, + const GLuint *textures, + angle::ParamCapture *paramCapture); +void CaptureBindSamplers_samplers(const State &glState, + bool isCallValid, + GLuint first, + GLsizei count, + const GLuint *samplers, + angle::ParamCapture *paramCapture); +void CaptureBindTextures_textures(const State &glState, + bool isCallValid, + GLuint first, + GLsizei count, + const GLuint *textures, + angle::ParamCapture *paramCapture); +void CaptureBindVertexBuffers_buffersPacked(const State &glState, + bool isCallValid, + GLuint first, + GLsizei count, + const BufferID *buffersPacked, + const GLintptr *offsets, + const GLsizei *strides, + angle::ParamCapture *paramCapture); +void CaptureBindVertexBuffers_offsets(const State &glState, + bool isCallValid, + GLuint first, + GLsizei count, + const BufferID *buffersPacked, + const GLintptr *offsets, + const GLsizei *strides, + angle::ParamCapture *paramCapture); +void CaptureBindVertexBuffers_strides(const State &glState, + bool isCallValid, + GLuint first, + GLsizei count, + const BufferID *buffersPacked, + const GLintptr *offsets, + const GLsizei *strides, + angle::ParamCapture *paramCapture); +void CaptureBufferStorage_data(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLsizeiptr size, + const void *data, + GLbitfield flags, + angle::ParamCapture *paramCapture); +void CaptureClearTexImage_data(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLenum format, + GLenum type, + const void *data, + angle::ParamCapture *paramCapture); +void CaptureClearTexSubImage_data(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *data, + angle::ParamCapture *paramCapture); + +// GL 4.5 +void CaptureClearNamedBufferData_data(const State &glState, + bool isCallValid, + BufferID bufferPacked, + GLenum internalformat, + GLenum format, + GLenum type, + const void *data, + angle::ParamCapture *paramCapture); +void CaptureClearNamedBufferSubData_data(const State &glState, + bool isCallValid, + BufferID bufferPacked, + GLenum internalformat, + GLintptr offset, + GLsizeiptr size, + GLenum format, + GLenum type, + const void *data, + angle::ParamCapture *paramCapture); +void CaptureClearNamedFramebufferfv_value(const State &glState, + bool isCallValid, + FramebufferID framebufferPacked, + GLenum buffer, + GLint drawbuffer, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureClearNamedFramebufferiv_value(const State &glState, + bool isCallValid, + FramebufferID framebufferPacked, + GLenum buffer, + GLint drawbuffer, + const GLint *value, + angle::ParamCapture *paramCapture); +void CaptureClearNamedFramebufferuiv_value(const State &glState, + bool isCallValid, + FramebufferID framebufferPacked, + GLenum buffer, + GLint drawbuffer, + const GLuint *value, + angle::ParamCapture *paramCapture); +void CaptureCompressedTextureSubImage1D_data(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, + GLsizei imageSize, + const void *data, + angle::ParamCapture *paramCapture); +void CaptureCompressedTextureSubImage2D_data(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + const void *data, + angle::ParamCapture *paramCapture); +void CaptureCompressedTextureSubImage3D_data(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const void *data, + angle::ParamCapture *paramCapture); +void CaptureCreateBuffers_buffersPacked(const State &glState, + bool isCallValid, + GLsizei n, + BufferID *buffersPacked, + angle::ParamCapture *paramCapture); +void CaptureCreateFramebuffers_framebuffers(const State &glState, + bool isCallValid, + GLsizei n, + GLuint *framebuffers, + angle::ParamCapture *paramCapture); +void CaptureCreateProgramPipelines_pipelines(const State &glState, + bool isCallValid, + GLsizei n, + GLuint *pipelines, + angle::ParamCapture *paramCapture); +void CaptureCreateQueries_ids(const State &glState, + bool isCallValid, + GLenum target, + GLsizei n, + GLuint *ids, + angle::ParamCapture *paramCapture); +void CaptureCreateRenderbuffers_renderbuffersPacked(const State &glState, + bool isCallValid, + GLsizei n, + RenderbufferID *renderbuffersPacked, + angle::ParamCapture *paramCapture); +void CaptureCreateSamplers_samplers(const State &glState, + bool isCallValid, + GLsizei n, + GLuint *samplers, + angle::ParamCapture *paramCapture); +void CaptureCreateTextures_textures(const State &glState, + bool isCallValid, + GLenum target, + GLsizei n, + GLuint *textures, + angle::ParamCapture *paramCapture); +void CaptureCreateTransformFeedbacks_ids(const State &glState, + bool isCallValid, + GLsizei n, + GLuint *ids, + angle::ParamCapture *paramCapture); +void CaptureCreateVertexArrays_arraysPacked(const State &glState, + bool isCallValid, + GLsizei n, + VertexArrayID *arraysPacked, + angle::ParamCapture *paramCapture); +void CaptureGetCompressedTextureImage_pixels(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLsizei bufSize, + void *pixels, + angle::ParamCapture *paramCapture); +void CaptureGetCompressedTextureSubImage_pixels(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLsizei bufSize, + void *pixels, + angle::ParamCapture *paramCapture); +void CaptureGetNamedBufferParameteri64v_params(const State &glState, + bool isCallValid, + BufferID bufferPacked, + GLenum pname, + GLint64 *params, + angle::ParamCapture *paramCapture); +void CaptureGetNamedBufferParameteriv_params(const State &glState, + bool isCallValid, + BufferID bufferPacked, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetNamedBufferPointerv_params(const State &glState, + bool isCallValid, + BufferID bufferPacked, + GLenum pname, + void **params, + angle::ParamCapture *paramCapture); +void CaptureGetNamedBufferSubData_data(const State &glState, + bool isCallValid, + BufferID bufferPacked, + GLintptr offset, + GLsizeiptr size, + void *data, + angle::ParamCapture *paramCapture); +void CaptureGetNamedFramebufferAttachmentParameteriv_params(const State &glState, + bool isCallValid, + FramebufferID framebufferPacked, + GLenum attachment, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetNamedFramebufferParameteriv_param(const State &glState, + bool isCallValid, + FramebufferID framebufferPacked, + GLenum pname, + GLint *param, + angle::ParamCapture *paramCapture); +void CaptureGetNamedRenderbufferParameteriv_params(const State &glState, + bool isCallValid, + RenderbufferID renderbufferPacked, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetTextureImage_pixels(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLenum format, + GLenum type, + GLsizei bufSize, + void *pixels, + angle::ParamCapture *paramCapture); +void CaptureGetTextureLevelParameterfv_params(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLenum pname, + GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureGetTextureLevelParameteriv_params(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetTextureParameterIiv_params(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetTextureParameterIuiv_params(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLenum pname, + GLuint *params, + angle::ParamCapture *paramCapture); +void CaptureGetTextureParameterfv_params(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLenum pname, + GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureGetTextureParameteriv_params(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetTextureSubImage_pixels(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + GLsizei bufSize, + void *pixels, + angle::ParamCapture *paramCapture); +void CaptureGetTransformFeedbacki64_v_param(const State &glState, + bool isCallValid, + GLuint xfb, + GLenum pname, + GLuint index, + GLint64 *param, + angle::ParamCapture *paramCapture); +void CaptureGetTransformFeedbacki_v_param(const State &glState, + bool isCallValid, + GLuint xfb, + GLenum pname, + GLuint index, + GLint *param, + angle::ParamCapture *paramCapture); +void CaptureGetTransformFeedbackiv_param(const State &glState, + bool isCallValid, + GLuint xfb, + GLenum pname, + GLint *param, + angle::ParamCapture *paramCapture); +void CaptureGetVertexArrayIndexed64iv_param(const State &glState, + bool isCallValid, + VertexArrayID vaobjPacked, + GLuint index, + GLenum pname, + GLint64 *param, + angle::ParamCapture *paramCapture); +void CaptureGetVertexArrayIndexediv_param(const State &glState, + bool isCallValid, + VertexArrayID vaobjPacked, + GLuint index, + GLenum pname, + GLint *param, + angle::ParamCapture *paramCapture); +void CaptureGetVertexArrayiv_param(const State &glState, + bool isCallValid, + VertexArrayID vaobjPacked, + GLenum pname, + GLint *param, + angle::ParamCapture *paramCapture); +void CaptureGetnColorTable_table(const State &glState, + bool isCallValid, + GLenum target, + GLenum format, + GLenum type, + GLsizei bufSize, + void *table, + angle::ParamCapture *paramCapture); +void CaptureGetnCompressedTexImage_pixels(const State &glState, + bool isCallValid, + GLenum target, + GLint lod, + GLsizei bufSize, + void *pixels, + angle::ParamCapture *paramCapture); +void CaptureGetnConvolutionFilter_image(const State &glState, + bool isCallValid, + GLenum target, + GLenum format, + GLenum type, + GLsizei bufSize, + void *image, + angle::ParamCapture *paramCapture); +void CaptureGetnHistogram_values(const State &glState, + bool isCallValid, + GLenum target, + GLboolean reset, + GLenum format, + GLenum type, + GLsizei bufSize, + void *values, + angle::ParamCapture *paramCapture); +void CaptureGetnMapdv_v(const State &glState, + bool isCallValid, + GLenum target, + GLenum query, + GLsizei bufSize, + GLdouble *v, + angle::ParamCapture *paramCapture); +void CaptureGetnMapfv_v(const State &glState, + bool isCallValid, + GLenum target, + GLenum query, + GLsizei bufSize, + GLfloat *v, + angle::ParamCapture *paramCapture); +void CaptureGetnMapiv_v(const State &glState, + bool isCallValid, + GLenum target, + GLenum query, + GLsizei bufSize, + GLint *v, + angle::ParamCapture *paramCapture); +void CaptureGetnMinmax_values(const State &glState, + bool isCallValid, + GLenum target, + GLboolean reset, + GLenum format, + GLenum type, + GLsizei bufSize, + void *values, + angle::ParamCapture *paramCapture); +void CaptureGetnPixelMapfv_values(const State &glState, + bool isCallValid, + GLenum map, + GLsizei bufSize, + GLfloat *values, + angle::ParamCapture *paramCapture); +void CaptureGetnPixelMapuiv_values(const State &glState, + bool isCallValid, + GLenum map, + GLsizei bufSize, + GLuint *values, + angle::ParamCapture *paramCapture); +void CaptureGetnPixelMapusv_values(const State &glState, + bool isCallValid, + GLenum map, + GLsizei bufSize, + GLushort *values, + angle::ParamCapture *paramCapture); +void CaptureGetnPolygonStipple_pattern(const State &glState, + bool isCallValid, + GLsizei bufSize, + GLubyte *pattern, + angle::ParamCapture *paramCapture); +void CaptureGetnSeparableFilter_row(const State &glState, + bool isCallValid, + GLenum target, + GLenum format, + GLenum type, + GLsizei rowBufSize, + void *row, + GLsizei columnBufSize, + void *column, + void *span, + angle::ParamCapture *paramCapture); +void CaptureGetnSeparableFilter_column(const State &glState, + bool isCallValid, + GLenum target, + GLenum format, + GLenum type, + GLsizei rowBufSize, + void *row, + GLsizei columnBufSize, + void *column, + void *span, + angle::ParamCapture *paramCapture); +void CaptureGetnSeparableFilter_span(const State &glState, + bool isCallValid, + GLenum target, + GLenum format, + GLenum type, + GLsizei rowBufSize, + void *row, + GLsizei columnBufSize, + void *column, + void *span, + angle::ParamCapture *paramCapture); +void CaptureGetnTexImage_pixels(const State &glState, + bool isCallValid, + GLenum target, + GLint level, + GLenum format, + GLenum type, + GLsizei bufSize, + void *pixels, + angle::ParamCapture *paramCapture); +void CaptureGetnUniformdv_params(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + GLdouble *params, + angle::ParamCapture *paramCapture); +void CaptureInvalidateNamedFramebufferData_attachments(const State &glState, + bool isCallValid, + FramebufferID framebufferPacked, + GLsizei numAttachments, + const GLenum *attachments, + angle::ParamCapture *paramCapture); +void CaptureInvalidateNamedFramebufferSubData_attachments(const State &glState, + bool isCallValid, + FramebufferID framebufferPacked, + GLsizei numAttachments, + const GLenum *attachments, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + angle::ParamCapture *paramCapture); +void CaptureNamedBufferData_data(const State &glState, + bool isCallValid, + BufferID bufferPacked, + GLsizeiptr size, + const void *data, + GLenum usage, + angle::ParamCapture *paramCapture); +void CaptureNamedBufferStorage_data(const State &glState, + bool isCallValid, + BufferID bufferPacked, + GLsizeiptr size, + const void *data, + GLbitfield flags, + angle::ParamCapture *paramCapture); +void CaptureNamedBufferSubData_data(const State &glState, + bool isCallValid, + BufferID bufferPacked, + GLintptr offset, + GLsizeiptr size, + const void *data, + angle::ParamCapture *paramCapture); +void CaptureNamedFramebufferDrawBuffers_bufs(const State &glState, + bool isCallValid, + FramebufferID framebufferPacked, + GLsizei n, + const GLenum *bufs, + angle::ParamCapture *paramCapture); +void CaptureTextureParameterIiv_params(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLenum pname, + const GLint *params, + angle::ParamCapture *paramCapture); +void CaptureTextureParameterIuiv_params(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLenum pname, + const GLuint *params, + angle::ParamCapture *paramCapture); +void CaptureTextureParameterfv_param(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLenum pname, + const GLfloat *param, + angle::ParamCapture *paramCapture); +void CaptureTextureParameteriv_param(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLenum pname, + const GLint *param, + angle::ParamCapture *paramCapture); +void CaptureTextureSubImage1D_pixels(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, + GLenum type, + const void *pixels, + angle::ParamCapture *paramCapture); +void CaptureTextureSubImage2D_pixels(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void *pixels, + angle::ParamCapture *paramCapture); +void CaptureTextureSubImage3D_pixels(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *pixels, + angle::ParamCapture *paramCapture); +void CaptureVertexArrayVertexBuffers_buffersPacked(const State &glState, + bool isCallValid, + VertexArrayID vaobjPacked, + GLuint first, + GLsizei count, + const BufferID *buffersPacked, + const GLintptr *offsets, + const GLsizei *strides, + angle::ParamCapture *paramCapture); +void CaptureVertexArrayVertexBuffers_offsets(const State &glState, + bool isCallValid, + VertexArrayID vaobjPacked, + GLuint first, + GLsizei count, + const BufferID *buffersPacked, + const GLintptr *offsets, + const GLsizei *strides, + angle::ParamCapture *paramCapture); +void CaptureVertexArrayVertexBuffers_strides(const State &glState, + bool isCallValid, + VertexArrayID vaobjPacked, + GLuint first, + GLsizei count, + const BufferID *buffersPacked, + const GLintptr *offsets, + const GLsizei *strides, + angle::ParamCapture *paramCapture); + +// GL 4.6 +void CaptureMultiDrawArraysIndirectCount_indirect(const State &glState, + bool isCallValid, + GLenum mode, + const void *indirect, + GLintptr drawcount, + GLsizei maxdrawcount, + GLsizei stride, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawElementsIndirectCount_indirect(const State &glState, + bool isCallValid, + GLenum mode, + GLenum type, + const void *indirect, + GLintptr drawcount, + GLsizei maxdrawcount, + GLsizei stride, + angle::ParamCapture *paramCapture); +void CaptureSpecializeShader_pEntryPoint(const State &glState, + bool isCallValid, + GLuint shader, + const GLchar *pEntryPoint, + GLuint numSpecializationConstants, + const GLuint *pConstantIndex, + const GLuint *pConstantValue, + angle::ParamCapture *paramCapture); +void CaptureSpecializeShader_pConstantIndex(const State &glState, + bool isCallValid, + GLuint shader, + const GLchar *pEntryPoint, + GLuint numSpecializationConstants, + const GLuint *pConstantIndex, + const GLuint *pConstantValue, + angle::ParamCapture *paramCapture); +void CaptureSpecializeShader_pConstantValue(const State &glState, + bool isCallValid, + GLuint shader, + const GLchar *pEntryPoint, + GLuint numSpecializationConstants, + const GLuint *pConstantIndex, + const GLuint *pConstantValue, + angle::ParamCapture *paramCapture); +} // namespace gl + +#endif // LIBANGLE_CAPTURE_GL_4_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/capture/capture_gles_1_0_autogen.h b/gfx/angle/checkout/src/libANGLE/capture/capture_gles_1_0_autogen.h new file mode 100644 index 0000000000..009ddb9977 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/capture/capture_gles_1_0_autogen.h @@ -0,0 +1,582 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// capture_gles_1_0_autogen.h: +// Capture functions for the OpenGL ES 1.0 entry points. + +#ifndef LIBANGLE_CAPTURE_GLES_1_0_AUTOGEN_H_ +#define LIBANGLE_CAPTURE_GLES_1_0_AUTOGEN_H_ + +#include "common/PackedEnums.h" +#include "libANGLE/capture/FrameCapture.h" + +namespace gl +{ + +// Method Captures + +angle::CallCapture CaptureAlphaFunc(const State &glState, + bool isCallValid, + AlphaTestFunc funcPacked, + GLfloat ref); +angle::CallCapture CaptureAlphaFuncx(const State &glState, + bool isCallValid, + AlphaTestFunc funcPacked, + GLfixed ref); +angle::CallCapture CaptureClearColorx(const State &glState, + bool isCallValid, + GLfixed red, + GLfixed green, + GLfixed blue, + GLfixed alpha); +angle::CallCapture CaptureClearDepthx(const State &glState, bool isCallValid, GLfixed depth); +angle::CallCapture CaptureClientActiveTexture(const State &glState, + bool isCallValid, + GLenum texture); +angle::CallCapture CaptureClipPlanef(const State &glState, + bool isCallValid, + GLenum p, + const GLfloat *eqn); +angle::CallCapture CaptureClipPlanex(const State &glState, + bool isCallValid, + GLenum plane, + const GLfixed *equation); +angle::CallCapture CaptureColor4f(const State &glState, + bool isCallValid, + GLfloat red, + GLfloat green, + GLfloat blue, + GLfloat alpha); +angle::CallCapture CaptureColor4ub(const State &glState, + bool isCallValid, + GLubyte red, + GLubyte green, + GLubyte blue, + GLubyte alpha); +angle::CallCapture CaptureColor4x(const State &glState, + bool isCallValid, + GLfixed red, + GLfixed green, + GLfixed blue, + GLfixed alpha); +angle::CallCapture CaptureColorPointer(const State &glState, + bool isCallValid, + GLint size, + VertexAttribType typePacked, + GLsizei stride, + const void *pointer); +angle::CallCapture CaptureDepthRangex(const State &glState, bool isCallValid, GLfixed n, GLfixed f); +angle::CallCapture CaptureDisableClientState(const State &glState, + bool isCallValid, + ClientVertexArrayType arrayPacked); +angle::CallCapture CaptureEnableClientState(const State &glState, + bool isCallValid, + ClientVertexArrayType arrayPacked); +angle::CallCapture CaptureFogf(const State &glState, bool isCallValid, GLenum pname, GLfloat param); +angle::CallCapture CaptureFogfv(const State &glState, + bool isCallValid, + GLenum pname, + const GLfloat *params); +angle::CallCapture CaptureFogx(const State &glState, bool isCallValid, GLenum pname, GLfixed param); +angle::CallCapture CaptureFogxv(const State &glState, + bool isCallValid, + GLenum pname, + const GLfixed *param); +angle::CallCapture CaptureFrustumf(const State &glState, + bool isCallValid, + GLfloat l, + GLfloat r, + GLfloat b, + GLfloat t, + GLfloat n, + GLfloat f); +angle::CallCapture CaptureFrustumx(const State &glState, + bool isCallValid, + GLfixed l, + GLfixed r, + GLfixed b, + GLfixed t, + GLfixed n, + GLfixed f); +angle::CallCapture CaptureGetClipPlanef(const State &glState, + bool isCallValid, + GLenum plane, + GLfloat *equation); +angle::CallCapture CaptureGetClipPlanex(const State &glState, + bool isCallValid, + GLenum plane, + GLfixed *equation); +angle::CallCapture CaptureGetFixedv(const State &glState, + bool isCallValid, + GLenum pname, + GLfixed *params); +angle::CallCapture CaptureGetLightfv(const State &glState, + bool isCallValid, + GLenum light, + LightParameter pnamePacked, + GLfloat *params); +angle::CallCapture CaptureGetLightxv(const State &glState, + bool isCallValid, + GLenum light, + LightParameter pnamePacked, + GLfixed *params); +angle::CallCapture CaptureGetMaterialfv(const State &glState, + bool isCallValid, + GLenum face, + MaterialParameter pnamePacked, + GLfloat *params); +angle::CallCapture CaptureGetMaterialxv(const State &glState, + bool isCallValid, + GLenum face, + MaterialParameter pnamePacked, + GLfixed *params); +angle::CallCapture CaptureGetTexEnvfv(const State &glState, + bool isCallValid, + TextureEnvTarget targetPacked, + TextureEnvParameter pnamePacked, + GLfloat *params); +angle::CallCapture CaptureGetTexEnviv(const State &glState, + bool isCallValid, + TextureEnvTarget targetPacked, + TextureEnvParameter pnamePacked, + GLint *params); +angle::CallCapture CaptureGetTexEnvxv(const State &glState, + bool isCallValid, + TextureEnvTarget targetPacked, + TextureEnvParameter pnamePacked, + GLfixed *params); +angle::CallCapture CaptureGetTexParameterxv(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLfixed *params); +angle::CallCapture CaptureLightModelf(const State &glState, + bool isCallValid, + GLenum pname, + GLfloat param); +angle::CallCapture CaptureLightModelfv(const State &glState, + bool isCallValid, + GLenum pname, + const GLfloat *params); +angle::CallCapture CaptureLightModelx(const State &glState, + bool isCallValid, + GLenum pname, + GLfixed param); +angle::CallCapture CaptureLightModelxv(const State &glState, + bool isCallValid, + GLenum pname, + const GLfixed *param); +angle::CallCapture CaptureLightf(const State &glState, + bool isCallValid, + GLenum light, + LightParameter pnamePacked, + GLfloat param); +angle::CallCapture CaptureLightfv(const State &glState, + bool isCallValid, + GLenum light, + LightParameter pnamePacked, + const GLfloat *params); +angle::CallCapture CaptureLightx(const State &glState, + bool isCallValid, + GLenum light, + LightParameter pnamePacked, + GLfixed param); +angle::CallCapture CaptureLightxv(const State &glState, + bool isCallValid, + GLenum light, + LightParameter pnamePacked, + const GLfixed *params); +angle::CallCapture CaptureLineWidthx(const State &glState, bool isCallValid, GLfixed width); +angle::CallCapture CaptureLoadIdentity(const State &glState, bool isCallValid); +angle::CallCapture CaptureLoadMatrixf(const State &glState, bool isCallValid, const GLfloat *m); +angle::CallCapture CaptureLoadMatrixx(const State &glState, bool isCallValid, const GLfixed *m); +angle::CallCapture CaptureLogicOp(const State &glState, + bool isCallValid, + LogicalOperation opcodePacked); +angle::CallCapture CaptureMaterialf(const State &glState, + bool isCallValid, + GLenum face, + MaterialParameter pnamePacked, + GLfloat param); +angle::CallCapture CaptureMaterialfv(const State &glState, + bool isCallValid, + GLenum face, + MaterialParameter pnamePacked, + const GLfloat *params); +angle::CallCapture CaptureMaterialx(const State &glState, + bool isCallValid, + GLenum face, + MaterialParameter pnamePacked, + GLfixed param); +angle::CallCapture CaptureMaterialxv(const State &glState, + bool isCallValid, + GLenum face, + MaterialParameter pnamePacked, + const GLfixed *param); +angle::CallCapture CaptureMatrixMode(const State &glState, bool isCallValid, MatrixType modePacked); +angle::CallCapture CaptureMultMatrixf(const State &glState, bool isCallValid, const GLfloat *m); +angle::CallCapture CaptureMultMatrixx(const State &glState, bool isCallValid, const GLfixed *m); +angle::CallCapture CaptureMultiTexCoord4f(const State &glState, + bool isCallValid, + GLenum target, + GLfloat s, + GLfloat t, + GLfloat r, + GLfloat q); +angle::CallCapture CaptureMultiTexCoord4x(const State &glState, + bool isCallValid, + GLenum texture, + GLfixed s, + GLfixed t, + GLfixed r, + GLfixed q); +angle::CallCapture CaptureNormal3f(const State &glState, + bool isCallValid, + GLfloat nx, + GLfloat ny, + GLfloat nz); +angle::CallCapture CaptureNormal3x(const State &glState, + bool isCallValid, + GLfixed nx, + GLfixed ny, + GLfixed nz); +angle::CallCapture CaptureNormalPointer(const State &glState, + bool isCallValid, + VertexAttribType typePacked, + GLsizei stride, + const void *pointer); +angle::CallCapture CaptureOrthof(const State &glState, + bool isCallValid, + GLfloat l, + GLfloat r, + GLfloat b, + GLfloat t, + GLfloat n, + GLfloat f); +angle::CallCapture CaptureOrthox(const State &glState, + bool isCallValid, + GLfixed l, + GLfixed r, + GLfixed b, + GLfixed t, + GLfixed n, + GLfixed f); +angle::CallCapture CapturePointParameterf(const State &glState, + bool isCallValid, + PointParameter pnamePacked, + GLfloat param); +angle::CallCapture CapturePointParameterfv(const State &glState, + bool isCallValid, + PointParameter pnamePacked, + const GLfloat *params); +angle::CallCapture CapturePointParameterx(const State &glState, + bool isCallValid, + PointParameter pnamePacked, + GLfixed param); +angle::CallCapture CapturePointParameterxv(const State &glState, + bool isCallValid, + PointParameter pnamePacked, + const GLfixed *params); +angle::CallCapture CapturePointSize(const State &glState, bool isCallValid, GLfloat size); +angle::CallCapture CapturePointSizex(const State &glState, bool isCallValid, GLfixed size); +angle::CallCapture CapturePolygonOffsetx(const State &glState, + bool isCallValid, + GLfixed factor, + GLfixed units); +angle::CallCapture CapturePopMatrix(const State &glState, bool isCallValid); +angle::CallCapture CapturePushMatrix(const State &glState, bool isCallValid); +angle::CallCapture CaptureRotatef(const State &glState, + bool isCallValid, + GLfloat angle, + GLfloat x, + GLfloat y, + GLfloat z); +angle::CallCapture CaptureRotatex(const State &glState, + bool isCallValid, + GLfixed angle, + GLfixed x, + GLfixed y, + GLfixed z); +angle::CallCapture CaptureSampleCoveragex(const State &glState, + bool isCallValid, + GLclampx value, + GLboolean invert); +angle::CallCapture CaptureScalef(const State &glState, + bool isCallValid, + GLfloat x, + GLfloat y, + GLfloat z); +angle::CallCapture CaptureScalex(const State &glState, + bool isCallValid, + GLfixed x, + GLfixed y, + GLfixed z); +angle::CallCapture CaptureShadeModel(const State &glState, + bool isCallValid, + ShadingModel modePacked); +angle::CallCapture CaptureTexCoordPointer(const State &glState, + bool isCallValid, + GLint size, + VertexAttribType typePacked, + GLsizei stride, + const void *pointer); +angle::CallCapture CaptureTexEnvf(const State &glState, + bool isCallValid, + TextureEnvTarget targetPacked, + TextureEnvParameter pnamePacked, + GLfloat param); +angle::CallCapture CaptureTexEnvfv(const State &glState, + bool isCallValid, + TextureEnvTarget targetPacked, + TextureEnvParameter pnamePacked, + const GLfloat *params); +angle::CallCapture CaptureTexEnvi(const State &glState, + bool isCallValid, + TextureEnvTarget targetPacked, + TextureEnvParameter pnamePacked, + GLint param); +angle::CallCapture CaptureTexEnviv(const State &glState, + bool isCallValid, + TextureEnvTarget targetPacked, + TextureEnvParameter pnamePacked, + const GLint *params); +angle::CallCapture CaptureTexEnvx(const State &glState, + bool isCallValid, + TextureEnvTarget targetPacked, + TextureEnvParameter pnamePacked, + GLfixed param); +angle::CallCapture CaptureTexEnvxv(const State &glState, + bool isCallValid, + TextureEnvTarget targetPacked, + TextureEnvParameter pnamePacked, + const GLfixed *params); +angle::CallCapture CaptureTexParameterx(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLfixed param); +angle::CallCapture CaptureTexParameterxv(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + const GLfixed *params); +angle::CallCapture CaptureTranslatef(const State &glState, + bool isCallValid, + GLfloat x, + GLfloat y, + GLfloat z); +angle::CallCapture CaptureTranslatex(const State &glState, + bool isCallValid, + GLfixed x, + GLfixed y, + GLfixed z); +angle::CallCapture CaptureVertexPointer(const State &glState, + bool isCallValid, + GLint size, + VertexAttribType typePacked, + GLsizei stride, + const void *pointer); + +// Parameter Captures + +void CaptureClipPlanef_eqn(const State &glState, + bool isCallValid, + GLenum p, + const GLfloat *eqn, + angle::ParamCapture *paramCapture); +void CaptureClipPlanex_equation(const State &glState, + bool isCallValid, + GLenum plane, + const GLfixed *equation, + angle::ParamCapture *paramCapture); +void CaptureColorPointer_pointer(const State &glState, + bool isCallValid, + GLint size, + VertexAttribType typePacked, + GLsizei stride, + const void *pointer, + angle::ParamCapture *paramCapture); +void CaptureFogfv_params(const State &glState, + bool isCallValid, + GLenum pname, + const GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureFogxv_param(const State &glState, + bool isCallValid, + GLenum pname, + const GLfixed *param, + angle::ParamCapture *paramCapture); +void CaptureGetClipPlanef_equation(const State &glState, + bool isCallValid, + GLenum plane, + GLfloat *equation, + angle::ParamCapture *paramCapture); +void CaptureGetClipPlanex_equation(const State &glState, + bool isCallValid, + GLenum plane, + GLfixed *equation, + angle::ParamCapture *paramCapture); +void CaptureGetFixedv_params(const State &glState, + bool isCallValid, + GLenum pname, + GLfixed *params, + angle::ParamCapture *paramCapture); +void CaptureGetLightfv_params(const State &glState, + bool isCallValid, + GLenum light, + LightParameter pnamePacked, + GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureGetLightxv_params(const State &glState, + bool isCallValid, + GLenum light, + LightParameter pnamePacked, + GLfixed *params, + angle::ParamCapture *paramCapture); +void CaptureGetMaterialfv_params(const State &glState, + bool isCallValid, + GLenum face, + MaterialParameter pnamePacked, + GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureGetMaterialxv_params(const State &glState, + bool isCallValid, + GLenum face, + MaterialParameter pnamePacked, + GLfixed *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexEnvfv_params(const State &glState, + bool isCallValid, + TextureEnvTarget targetPacked, + TextureEnvParameter pnamePacked, + GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexEnviv_params(const State &glState, + bool isCallValid, + TextureEnvTarget targetPacked, + TextureEnvParameter pnamePacked, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexEnvxv_params(const State &glState, + bool isCallValid, + TextureEnvTarget targetPacked, + TextureEnvParameter pnamePacked, + GLfixed *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexParameterxv_params(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLfixed *params, + angle::ParamCapture *paramCapture); +void CaptureLightModelfv_params(const State &glState, + bool isCallValid, + GLenum pname, + const GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureLightModelxv_param(const State &glState, + bool isCallValid, + GLenum pname, + const GLfixed *param, + angle::ParamCapture *paramCapture); +void CaptureLightfv_params(const State &glState, + bool isCallValid, + GLenum light, + LightParameter pnamePacked, + const GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureLightxv_params(const State &glState, + bool isCallValid, + GLenum light, + LightParameter pnamePacked, + const GLfixed *params, + angle::ParamCapture *paramCapture); +void CaptureLoadMatrixf_m(const State &glState, + bool isCallValid, + const GLfloat *m, + angle::ParamCapture *paramCapture); +void CaptureLoadMatrixx_m(const State &glState, + bool isCallValid, + const GLfixed *m, + angle::ParamCapture *paramCapture); +void CaptureMaterialfv_params(const State &glState, + bool isCallValid, + GLenum face, + MaterialParameter pnamePacked, + const GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureMaterialxv_param(const State &glState, + bool isCallValid, + GLenum face, + MaterialParameter pnamePacked, + const GLfixed *param, + angle::ParamCapture *paramCapture); +void CaptureMultMatrixf_m(const State &glState, + bool isCallValid, + const GLfloat *m, + angle::ParamCapture *paramCapture); +void CaptureMultMatrixx_m(const State &glState, + bool isCallValid, + const GLfixed *m, + angle::ParamCapture *paramCapture); +void CaptureNormalPointer_pointer(const State &glState, + bool isCallValid, + VertexAttribType typePacked, + GLsizei stride, + const void *pointer, + angle::ParamCapture *paramCapture); +void CapturePointParameterfv_params(const State &glState, + bool isCallValid, + PointParameter pnamePacked, + const GLfloat *params, + angle::ParamCapture *paramCapture); +void CapturePointParameterxv_params(const State &glState, + bool isCallValid, + PointParameter pnamePacked, + const GLfixed *params, + angle::ParamCapture *paramCapture); +void CaptureTexCoordPointer_pointer(const State &glState, + bool isCallValid, + GLint size, + VertexAttribType typePacked, + GLsizei stride, + const void *pointer, + angle::ParamCapture *paramCapture); +void CaptureTexEnvfv_params(const State &glState, + bool isCallValid, + TextureEnvTarget targetPacked, + TextureEnvParameter pnamePacked, + const GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureTexEnviv_params(const State &glState, + bool isCallValid, + TextureEnvTarget targetPacked, + TextureEnvParameter pnamePacked, + const GLint *params, + angle::ParamCapture *paramCapture); +void CaptureTexEnvxv_params(const State &glState, + bool isCallValid, + TextureEnvTarget targetPacked, + TextureEnvParameter pnamePacked, + const GLfixed *params, + angle::ParamCapture *paramCapture); +void CaptureTexParameterxv_params(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + const GLfixed *params, + angle::ParamCapture *paramCapture); +void CaptureVertexPointer_pointer(const State &glState, + bool isCallValid, + GLint size, + VertexAttribType typePacked, + GLsizei stride, + const void *pointer, + angle::ParamCapture *paramCapture); +} // namespace gl + +#endif // LIBANGLE_CAPTURE_GLES_1_0_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/capture/capture_gles_2_0_autogen.h b/gfx/angle/checkout/src/libANGLE/capture/capture_gles_2_0_autogen.h new file mode 100644 index 0000000000..d4d1d978a2 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/capture/capture_gles_2_0_autogen.h @@ -0,0 +1,1195 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// capture_gles_2_0_autogen.h: +// Capture functions for the OpenGL ES 2.0 entry points. + +#ifndef LIBANGLE_CAPTURE_GLES_2_0_AUTOGEN_H_ +#define LIBANGLE_CAPTURE_GLES_2_0_AUTOGEN_H_ + +#include "common/PackedEnums.h" +#include "libANGLE/capture/FrameCapture.h" + +namespace gl +{ + +// Method Captures + +angle::CallCapture CaptureActiveTexture(const State &glState, bool isCallValid, GLenum texture); +angle::CallCapture CaptureAttachShader(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + ShaderProgramID shaderPacked); +angle::CallCapture CaptureBindAttribLocation(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLuint index, + const GLchar *name); +angle::CallCapture CaptureBindBuffer(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + BufferID bufferPacked); +angle::CallCapture CaptureBindFramebuffer(const State &glState, + bool isCallValid, + GLenum target, + FramebufferID framebufferPacked); +angle::CallCapture CaptureBindRenderbuffer(const State &glState, + bool isCallValid, + GLenum target, + RenderbufferID renderbufferPacked); +angle::CallCapture CaptureBindTexture(const State &glState, + bool isCallValid, + TextureType targetPacked, + TextureID texturePacked); +angle::CallCapture CaptureBlendColor(const State &glState, + bool isCallValid, + GLfloat red, + GLfloat green, + GLfloat blue, + GLfloat alpha); +angle::CallCapture CaptureBlendEquation(const State &glState, bool isCallValid, GLenum mode); +angle::CallCapture CaptureBlendEquationSeparate(const State &glState, + bool isCallValid, + GLenum modeRGB, + GLenum modeAlpha); +angle::CallCapture CaptureBlendFunc(const State &glState, + bool isCallValid, + GLenum sfactor, + GLenum dfactor); +angle::CallCapture CaptureBlendFuncSeparate(const State &glState, + bool isCallValid, + GLenum sfactorRGB, + GLenum dfactorRGB, + GLenum sfactorAlpha, + GLenum dfactorAlpha); +angle::CallCapture CaptureBufferData(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLsizeiptr size, + const void *data, + BufferUsage usagePacked); +angle::CallCapture CaptureBufferSubData(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLintptr offset, + GLsizeiptr size, + const void *data); +angle::CallCapture CaptureCheckFramebufferStatus(const State &glState, + bool isCallValid, + GLenum target, + GLenum returnValue); +angle::CallCapture CaptureClear(const State &glState, bool isCallValid, GLbitfield mask); +angle::CallCapture CaptureClearColor(const State &glState, + bool isCallValid, + GLfloat red, + GLfloat green, + GLfloat blue, + GLfloat alpha); +angle::CallCapture CaptureClearDepthf(const State &glState, bool isCallValid, GLfloat d); +angle::CallCapture CaptureClearStencil(const State &glState, bool isCallValid, GLint s); +angle::CallCapture CaptureColorMask(const State &glState, + bool isCallValid, + GLboolean red, + GLboolean green, + GLboolean blue, + GLboolean alpha); +angle::CallCapture CaptureCompileShader(const State &glState, + bool isCallValid, + ShaderProgramID shaderPacked); +angle::CallCapture CaptureCompressedTexImage2D(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + const void *data); +angle::CallCapture CaptureCompressedTexSubImage2D(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + const void *data); +angle::CallCapture CaptureCopyTexImage2D(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLenum internalformat, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border); +angle::CallCapture CaptureCopyTexSubImage2D(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height); +angle::CallCapture CaptureCreateProgram(const State &glState, bool isCallValid, GLuint returnValue); +angle::CallCapture CaptureCreateShader(const State &glState, + bool isCallValid, + ShaderType typePacked, + GLuint returnValue); +angle::CallCapture CaptureCullFace(const State &glState, bool isCallValid, CullFaceMode modePacked); +angle::CallCapture CaptureDeleteBuffers(const State &glState, + bool isCallValid, + GLsizei n, + const BufferID *buffersPacked); +angle::CallCapture CaptureDeleteFramebuffers(const State &glState, + bool isCallValid, + GLsizei n, + const FramebufferID *framebuffersPacked); +angle::CallCapture CaptureDeleteProgram(const State &glState, + bool isCallValid, + ShaderProgramID programPacked); +angle::CallCapture CaptureDeleteRenderbuffers(const State &glState, + bool isCallValid, + GLsizei n, + const RenderbufferID *renderbuffersPacked); +angle::CallCapture CaptureDeleteShader(const State &glState, + bool isCallValid, + ShaderProgramID shaderPacked); +angle::CallCapture CaptureDeleteTextures(const State &glState, + bool isCallValid, + GLsizei n, + const TextureID *texturesPacked); +angle::CallCapture CaptureDepthFunc(const State &glState, bool isCallValid, GLenum func); +angle::CallCapture CaptureDepthMask(const State &glState, bool isCallValid, GLboolean flag); +angle::CallCapture CaptureDepthRangef(const State &glState, bool isCallValid, GLfloat n, GLfloat f); +angle::CallCapture CaptureDetachShader(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + ShaderProgramID shaderPacked); +angle::CallCapture CaptureDisable(const State &glState, bool isCallValid, GLenum cap); +angle::CallCapture CaptureDisableVertexAttribArray(const State &glState, + bool isCallValid, + GLuint index); +angle::CallCapture CaptureDrawArrays(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLint first, + GLsizei count); +angle::CallCapture CaptureDrawElements(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices); +angle::CallCapture CaptureEnable(const State &glState, bool isCallValid, GLenum cap); +angle::CallCapture CaptureEnableVertexAttribArray(const State &glState, + bool isCallValid, + GLuint index); +angle::CallCapture CaptureFinish(const State &glState, bool isCallValid); +angle::CallCapture CaptureFlush(const State &glState, bool isCallValid); +angle::CallCapture CaptureFramebufferRenderbuffer(const State &glState, + bool isCallValid, + GLenum target, + GLenum attachment, + GLenum renderbuffertarget, + RenderbufferID renderbufferPacked); +angle::CallCapture CaptureFramebufferTexture2D(const State &glState, + bool isCallValid, + GLenum target, + GLenum attachment, + TextureTarget textargetPacked, + TextureID texturePacked, + GLint level); +angle::CallCapture CaptureFrontFace(const State &glState, bool isCallValid, GLenum mode); +angle::CallCapture CaptureGenBuffers(const State &glState, + bool isCallValid, + GLsizei n, + BufferID *buffersPacked); +angle::CallCapture CaptureGenFramebuffers(const State &glState, + bool isCallValid, + GLsizei n, + FramebufferID *framebuffersPacked); +angle::CallCapture CaptureGenRenderbuffers(const State &glState, + bool isCallValid, + GLsizei n, + RenderbufferID *renderbuffersPacked); +angle::CallCapture CaptureGenTextures(const State &glState, + bool isCallValid, + GLsizei n, + TextureID *texturesPacked); +angle::CallCapture CaptureGenerateMipmap(const State &glState, + bool isCallValid, + TextureType targetPacked); +angle::CallCapture CaptureGetActiveAttrib(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name); +angle::CallCapture CaptureGetActiveUniform(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name); +angle::CallCapture CaptureGetAttachedShaders(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLsizei maxCount, + GLsizei *count, + ShaderProgramID *shadersPacked); +angle::CallCapture CaptureGetAttribLocation(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + const GLchar *name, + GLint returnValue); +angle::CallCapture CaptureGetBooleanv(const State &glState, + bool isCallValid, + GLenum pname, + GLboolean *data); +angle::CallCapture CaptureGetBufferParameteriv(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetError(const State &glState, bool isCallValid, GLenum returnValue); +angle::CallCapture CaptureGetFloatv(const State &glState, + bool isCallValid, + GLenum pname, + GLfloat *data); +angle::CallCapture CaptureGetFramebufferAttachmentParameteriv(const State &glState, + bool isCallValid, + GLenum target, + GLenum attachment, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetIntegerv(const State &glState, + bool isCallValid, + GLenum pname, + GLint *data); +angle::CallCapture CaptureGetProgramInfoLog(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLsizei bufSize, + GLsizei *length, + GLchar *infoLog); +angle::CallCapture CaptureGetProgramiv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetRenderbufferParameteriv(const State &glState, + bool isCallValid, + GLenum target, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetShaderInfoLog(const State &glState, + bool isCallValid, + ShaderProgramID shaderPacked, + GLsizei bufSize, + GLsizei *length, + GLchar *infoLog); +angle::CallCapture CaptureGetShaderPrecisionFormat(const State &glState, + bool isCallValid, + GLenum shadertype, + GLenum precisiontype, + GLint *range, + GLint *precision); +angle::CallCapture CaptureGetShaderSource(const State &glState, + bool isCallValid, + ShaderProgramID shaderPacked, + GLsizei bufSize, + GLsizei *length, + GLchar *source); +angle::CallCapture CaptureGetShaderiv(const State &glState, + bool isCallValid, + ShaderProgramID shaderPacked, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetString(const State &glState, + bool isCallValid, + GLenum name, + const GLubyte *returnValue); +angle::CallCapture CaptureGetTexParameterfv(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLfloat *params); +angle::CallCapture CaptureGetTexParameteriv(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetUniformLocation(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + const GLchar *name, + GLint returnValue); +angle::CallCapture CaptureGetUniformfv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLfloat *params); +angle::CallCapture CaptureGetUniformiv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLint *params); +angle::CallCapture CaptureGetVertexAttribPointerv(const State &glState, + bool isCallValid, + GLuint index, + GLenum pname, + void **pointer); +angle::CallCapture CaptureGetVertexAttribfv(const State &glState, + bool isCallValid, + GLuint index, + GLenum pname, + GLfloat *params); +angle::CallCapture CaptureGetVertexAttribiv(const State &glState, + bool isCallValid, + GLuint index, + GLenum pname, + GLint *params); +angle::CallCapture CaptureHint(const State &glState, bool isCallValid, GLenum target, GLenum mode); +angle::CallCapture CaptureIsBuffer(const State &glState, + bool isCallValid, + BufferID bufferPacked, + GLboolean returnValue); +angle::CallCapture CaptureIsEnabled(const State &glState, + bool isCallValid, + GLenum cap, + GLboolean returnValue); +angle::CallCapture CaptureIsFramebuffer(const State &glState, + bool isCallValid, + FramebufferID framebufferPacked, + GLboolean returnValue); +angle::CallCapture CaptureIsProgram(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLboolean returnValue); +angle::CallCapture CaptureIsRenderbuffer(const State &glState, + bool isCallValid, + RenderbufferID renderbufferPacked, + GLboolean returnValue); +angle::CallCapture CaptureIsShader(const State &glState, + bool isCallValid, + ShaderProgramID shaderPacked, + GLboolean returnValue); +angle::CallCapture CaptureIsTexture(const State &glState, + bool isCallValid, + TextureID texturePacked, + GLboolean returnValue); +angle::CallCapture CaptureLineWidth(const State &glState, bool isCallValid, GLfloat width); +angle::CallCapture CaptureLinkProgram(const State &glState, + bool isCallValid, + ShaderProgramID programPacked); +angle::CallCapture CapturePixelStorei(const State &glState, + bool isCallValid, + GLenum pname, + GLint param); +angle::CallCapture CapturePolygonOffset(const State &glState, + bool isCallValid, + GLfloat factor, + GLfloat units); +angle::CallCapture CaptureReadPixels(const State &glState, + bool isCallValid, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + void *pixels); +angle::CallCapture CaptureReleaseShaderCompiler(const State &glState, bool isCallValid); +angle::CallCapture CaptureRenderbufferStorage(const State &glState, + bool isCallValid, + GLenum target, + GLenum internalformat, + GLsizei width, + GLsizei height); +angle::CallCapture CaptureSampleCoverage(const State &glState, + bool isCallValid, + GLfloat value, + GLboolean invert); +angle::CallCapture CaptureScissor(const State &glState, + bool isCallValid, + GLint x, + GLint y, + GLsizei width, + GLsizei height); +angle::CallCapture CaptureShaderBinary(const State &glState, + bool isCallValid, + GLsizei count, + const ShaderProgramID *shadersPacked, + GLenum binaryFormat, + const void *binary, + GLsizei length); +angle::CallCapture CaptureShaderSource(const State &glState, + bool isCallValid, + ShaderProgramID shaderPacked, + GLsizei count, + const GLchar *const *string, + const GLint *length); +angle::CallCapture CaptureStencilFunc(const State &glState, + bool isCallValid, + GLenum func, + GLint ref, + GLuint mask); +angle::CallCapture CaptureStencilFuncSeparate(const State &glState, + bool isCallValid, + GLenum face, + GLenum func, + GLint ref, + GLuint mask); +angle::CallCapture CaptureStencilMask(const State &glState, bool isCallValid, GLuint mask); +angle::CallCapture CaptureStencilMaskSeparate(const State &glState, + bool isCallValid, + GLenum face, + GLuint mask); +angle::CallCapture CaptureStencilOp(const State &glState, + bool isCallValid, + GLenum fail, + GLenum zfail, + GLenum zpass); +angle::CallCapture CaptureStencilOpSeparate(const State &glState, + bool isCallValid, + GLenum face, + GLenum sfail, + GLenum dpfail, + GLenum dppass); +angle::CallCapture CaptureTexImage2D(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + const void *pixels); +angle::CallCapture CaptureTexParameterf(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLfloat param); +angle::CallCapture CaptureTexParameterfv(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + const GLfloat *params); +angle::CallCapture CaptureTexParameteri(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLint param); +angle::CallCapture CaptureTexParameteriv(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + const GLint *params); +angle::CallCapture CaptureTexSubImage2D(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void *pixels); +angle::CallCapture CaptureUniform1f(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLfloat v0); +angle::CallCapture CaptureUniform1fv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value); +angle::CallCapture CaptureUniform1i(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLint v0); +angle::CallCapture CaptureUniform1iv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLint *value); +angle::CallCapture CaptureUniform2f(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLfloat v0, + GLfloat v1); +angle::CallCapture CaptureUniform2fv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value); +angle::CallCapture CaptureUniform2i(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLint v0, + GLint v1); +angle::CallCapture CaptureUniform2iv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLint *value); +angle::CallCapture CaptureUniform3f(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLfloat v0, + GLfloat v1, + GLfloat v2); +angle::CallCapture CaptureUniform3fv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value); +angle::CallCapture CaptureUniform3i(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLint v0, + GLint v1, + GLint v2); +angle::CallCapture CaptureUniform3iv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLint *value); +angle::CallCapture CaptureUniform4f(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLfloat v0, + GLfloat v1, + GLfloat v2, + GLfloat v3); +angle::CallCapture CaptureUniform4fv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value); +angle::CallCapture CaptureUniform4i(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLint v0, + GLint v1, + GLint v2, + GLint v3); +angle::CallCapture CaptureUniform4iv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLint *value); +angle::CallCapture CaptureUniformMatrix2fv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +angle::CallCapture CaptureUniformMatrix3fv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +angle::CallCapture CaptureUniformMatrix4fv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +angle::CallCapture CaptureUseProgram(const State &glState, + bool isCallValid, + ShaderProgramID programPacked); +angle::CallCapture CaptureValidateProgram(const State &glState, + bool isCallValid, + ShaderProgramID programPacked); +angle::CallCapture CaptureVertexAttrib1f(const State &glState, + bool isCallValid, + GLuint index, + GLfloat x); +angle::CallCapture CaptureVertexAttrib1fv(const State &glState, + bool isCallValid, + GLuint index, + const GLfloat *v); +angle::CallCapture CaptureVertexAttrib2f(const State &glState, + bool isCallValid, + GLuint index, + GLfloat x, + GLfloat y); +angle::CallCapture CaptureVertexAttrib2fv(const State &glState, + bool isCallValid, + GLuint index, + const GLfloat *v); +angle::CallCapture CaptureVertexAttrib3f(const State &glState, + bool isCallValid, + GLuint index, + GLfloat x, + GLfloat y, + GLfloat z); +angle::CallCapture CaptureVertexAttrib3fv(const State &glState, + bool isCallValid, + GLuint index, + const GLfloat *v); +angle::CallCapture CaptureVertexAttrib4f(const State &glState, + bool isCallValid, + GLuint index, + GLfloat x, + GLfloat y, + GLfloat z, + GLfloat w); +angle::CallCapture CaptureVertexAttrib4fv(const State &glState, + bool isCallValid, + GLuint index, + const GLfloat *v); +angle::CallCapture CaptureVertexAttribPointer(const State &glState, + bool isCallValid, + GLuint index, + GLint size, + VertexAttribType typePacked, + GLboolean normalized, + GLsizei stride, + const void *pointer); +angle::CallCapture CaptureViewport(const State &glState, + bool isCallValid, + GLint x, + GLint y, + GLsizei width, + GLsizei height); + +// Parameter Captures + +void CaptureBindAttribLocation_name(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLuint index, + const GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureBufferData_data(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLsizeiptr size, + const void *data, + BufferUsage usagePacked, + angle::ParamCapture *paramCapture); +void CaptureBufferSubData_data(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLintptr offset, + GLsizeiptr size, + const void *data, + angle::ParamCapture *paramCapture); +void CaptureCompressedTexImage2D_data(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + const void *data, + angle::ParamCapture *paramCapture); +void CaptureCompressedTexSubImage2D_data(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + const void *data, + angle::ParamCapture *paramCapture); +void CaptureDeleteBuffers_buffersPacked(const State &glState, + bool isCallValid, + GLsizei n, + const BufferID *buffersPacked, + angle::ParamCapture *paramCapture); +void CaptureDeleteFramebuffers_framebuffersPacked(const State &glState, + bool isCallValid, + GLsizei n, + const FramebufferID *framebuffersPacked, + angle::ParamCapture *paramCapture); +void CaptureDeleteRenderbuffers_renderbuffersPacked(const State &glState, + bool isCallValid, + GLsizei n, + const RenderbufferID *renderbuffersPacked, + angle::ParamCapture *paramCapture); +void CaptureDeleteTextures_texturesPacked(const State &glState, + bool isCallValid, + GLsizei n, + const TextureID *texturesPacked, + angle::ParamCapture *paramCapture); +void CaptureDrawElements_indices(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + angle::ParamCapture *paramCapture); +void CaptureGenBuffers_buffersPacked(const State &glState, + bool isCallValid, + GLsizei n, + BufferID *buffersPacked, + angle::ParamCapture *paramCapture); +void CaptureGenFramebuffers_framebuffersPacked(const State &glState, + bool isCallValid, + GLsizei n, + FramebufferID *framebuffersPacked, + angle::ParamCapture *paramCapture); +void CaptureGenRenderbuffers_renderbuffersPacked(const State &glState, + bool isCallValid, + GLsizei n, + RenderbufferID *renderbuffersPacked, + angle::ParamCapture *paramCapture); +void CaptureGenTextures_texturesPacked(const State &glState, + bool isCallValid, + GLsizei n, + TextureID *texturesPacked, + angle::ParamCapture *paramCapture); +void CaptureGetActiveAttrib_length(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureGetActiveAttrib_size(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureGetActiveAttrib_type(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureGetActiveAttrib_name(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureGetActiveUniform_length(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureGetActiveUniform_size(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureGetActiveUniform_type(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureGetActiveUniform_name(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureGetAttachedShaders_count(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLsizei maxCount, + GLsizei *count, + ShaderProgramID *shadersPacked, + angle::ParamCapture *paramCapture); +void CaptureGetAttachedShaders_shadersPacked(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLsizei maxCount, + GLsizei *count, + ShaderProgramID *shadersPacked, + angle::ParamCapture *paramCapture); +void CaptureGetAttribLocation_name(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + const GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureGetBooleanv_data(const State &glState, + bool isCallValid, + GLenum pname, + GLboolean *data, + angle::ParamCapture *paramCapture); +void CaptureGetBufferParameteriv_params(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetFloatv_data(const State &glState, + bool isCallValid, + GLenum pname, + GLfloat *data, + angle::ParamCapture *paramCapture); +void CaptureGetFramebufferAttachmentParameteriv_params(const State &glState, + bool isCallValid, + GLenum target, + GLenum attachment, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetIntegerv_data(const State &glState, + bool isCallValid, + GLenum pname, + GLint *data, + angle::ParamCapture *paramCapture); +void CaptureGetProgramInfoLog_length(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLsizei bufSize, + GLsizei *length, + GLchar *infoLog, + angle::ParamCapture *paramCapture); +void CaptureGetProgramInfoLog_infoLog(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLsizei bufSize, + GLsizei *length, + GLchar *infoLog, + angle::ParamCapture *paramCapture); +void CaptureGetProgramiv_params(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetRenderbufferParameteriv_params(const State &glState, + bool isCallValid, + GLenum target, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetShaderInfoLog_length(const State &glState, + bool isCallValid, + ShaderProgramID shaderPacked, + GLsizei bufSize, + GLsizei *length, + GLchar *infoLog, + angle::ParamCapture *paramCapture); +void CaptureGetShaderInfoLog_infoLog(const State &glState, + bool isCallValid, + ShaderProgramID shaderPacked, + GLsizei bufSize, + GLsizei *length, + GLchar *infoLog, + angle::ParamCapture *paramCapture); +void CaptureGetShaderPrecisionFormat_range(const State &glState, + bool isCallValid, + GLenum shadertype, + GLenum precisiontype, + GLint *range, + GLint *precision, + angle::ParamCapture *paramCapture); +void CaptureGetShaderPrecisionFormat_precision(const State &glState, + bool isCallValid, + GLenum shadertype, + GLenum precisiontype, + GLint *range, + GLint *precision, + angle::ParamCapture *paramCapture); +void CaptureGetShaderSource_length(const State &glState, + bool isCallValid, + ShaderProgramID shaderPacked, + GLsizei bufSize, + GLsizei *length, + GLchar *source, + angle::ParamCapture *paramCapture); +void CaptureGetShaderSource_source(const State &glState, + bool isCallValid, + ShaderProgramID shaderPacked, + GLsizei bufSize, + GLsizei *length, + GLchar *source, + angle::ParamCapture *paramCapture); +void CaptureGetShaderiv_params(const State &glState, + bool isCallValid, + ShaderProgramID shaderPacked, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexParameterfv_params(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexParameteriv_params(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetUniformLocation_name(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + const GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureGetUniformfv_params(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureGetUniformiv_params(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetVertexAttribPointerv_pointer(const State &glState, + bool isCallValid, + GLuint index, + GLenum pname, + void **pointer, + angle::ParamCapture *paramCapture); +void CaptureGetVertexAttribfv_params(const State &glState, + bool isCallValid, + GLuint index, + GLenum pname, + GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureGetVertexAttribiv_params(const State &glState, + bool isCallValid, + GLuint index, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureReadPixels_pixels(const State &glState, + bool isCallValid, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + void *pixels, + angle::ParamCapture *paramCapture); +void CaptureShaderBinary_shadersPacked(const State &glState, + bool isCallValid, + GLsizei count, + const ShaderProgramID *shadersPacked, + GLenum binaryFormat, + const void *binary, + GLsizei length, + angle::ParamCapture *paramCapture); +void CaptureShaderBinary_binary(const State &glState, + bool isCallValid, + GLsizei count, + const ShaderProgramID *shadersPacked, + GLenum binaryFormat, + const void *binary, + GLsizei length, + angle::ParamCapture *paramCapture); +void CaptureShaderSource_string(const State &glState, + bool isCallValid, + ShaderProgramID shaderPacked, + GLsizei count, + const GLchar *const *string, + const GLint *length, + angle::ParamCapture *paramCapture); +void CaptureShaderSource_length(const State &glState, + bool isCallValid, + ShaderProgramID shaderPacked, + GLsizei count, + const GLchar *const *string, + const GLint *length, + angle::ParamCapture *paramCapture); +void CaptureTexImage2D_pixels(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + const void *pixels, + angle::ParamCapture *paramCapture); +void CaptureTexParameterfv_params(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + const GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureTexParameteriv_params(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + const GLint *params, + angle::ParamCapture *paramCapture); +void CaptureTexSubImage2D_pixels(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void *pixels, + angle::ParamCapture *paramCapture); +void CaptureUniform1fv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureUniform1iv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLint *value, + angle::ParamCapture *paramCapture); +void CaptureUniform2fv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureUniform2iv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLint *value, + angle::ParamCapture *paramCapture); +void CaptureUniform3fv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureUniform3iv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLint *value, + angle::ParamCapture *paramCapture); +void CaptureUniform4fv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureUniform4iv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLint *value, + angle::ParamCapture *paramCapture); +void CaptureUniformMatrix2fv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureUniformMatrix3fv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureUniformMatrix4fv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureVertexAttrib1fv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLfloat *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttrib2fv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLfloat *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttrib3fv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLfloat *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttrib4fv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLfloat *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttribPointer_pointer(const State &glState, + bool isCallValid, + GLuint index, + GLint size, + VertexAttribType typePacked, + GLboolean normalized, + GLsizei stride, + const void *pointer, + angle::ParamCapture *paramCapture); +} // namespace gl + +#endif // LIBANGLE_CAPTURE_GLES_2_0_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/capture/capture_gles_3_0_autogen.h b/gfx/angle/checkout/src/libANGLE/capture/capture_gles_3_0_autogen.h new file mode 100644 index 0000000000..83e2f441b4 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/capture/capture_gles_3_0_autogen.h @@ -0,0 +1,1079 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// capture_gles_3_0_autogen.h: +// Capture functions for the OpenGL ES 3.0 entry points. + +#ifndef LIBANGLE_CAPTURE_GLES_3_0_AUTOGEN_H_ +#define LIBANGLE_CAPTURE_GLES_3_0_AUTOGEN_H_ + +#include "common/PackedEnums.h" +#include "libANGLE/capture/FrameCapture.h" + +namespace gl +{ + +// Method Captures + +angle::CallCapture CaptureBeginQuery(const State &glState, + bool isCallValid, + QueryType targetPacked, + QueryID idPacked); +angle::CallCapture CaptureBeginTransformFeedback(const State &glState, + bool isCallValid, + PrimitiveMode primitiveModePacked); +angle::CallCapture CaptureBindBufferBase(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLuint index, + BufferID bufferPacked); +angle::CallCapture CaptureBindBufferRange(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLuint index, + BufferID bufferPacked, + GLintptr offset, + GLsizeiptr size); +angle::CallCapture CaptureBindSampler(const State &glState, + bool isCallValid, + GLuint unit, + SamplerID samplerPacked); +angle::CallCapture CaptureBindTransformFeedback(const State &glState, + bool isCallValid, + GLenum target, + TransformFeedbackID idPacked); +angle::CallCapture CaptureBindVertexArray(const State &glState, + bool isCallValid, + VertexArrayID arrayPacked); +angle::CallCapture CaptureBlitFramebuffer(const State &glState, + bool isCallValid, + GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter); +angle::CallCapture CaptureClearBufferfi(const State &glState, + bool isCallValid, + GLenum buffer, + GLint drawbuffer, + GLfloat depth, + GLint stencil); +angle::CallCapture CaptureClearBufferfv(const State &glState, + bool isCallValid, + GLenum buffer, + GLint drawbuffer, + const GLfloat *value); +angle::CallCapture CaptureClearBufferiv(const State &glState, + bool isCallValid, + GLenum buffer, + GLint drawbuffer, + const GLint *value); +angle::CallCapture CaptureClearBufferuiv(const State &glState, + bool isCallValid, + GLenum buffer, + GLint drawbuffer, + const GLuint *value); +angle::CallCapture CaptureClientWaitSync(const State &glState, + bool isCallValid, + GLsync sync, + GLbitfield flags, + GLuint64 timeout, + GLenum returnValue); +angle::CallCapture CaptureCompressedTexImage3D(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + const void *data); +angle::CallCapture CaptureCompressedTexSubImage3D(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const void *data); +angle::CallCapture CaptureCopyBufferSubData(const State &glState, + bool isCallValid, + BufferBinding readTargetPacked, + BufferBinding writeTargetPacked, + GLintptr readOffset, + GLintptr writeOffset, + GLsizeiptr size); +angle::CallCapture CaptureCopyTexSubImage3D(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height); +angle::CallCapture CaptureDeleteQueries(const State &glState, + bool isCallValid, + GLsizei n, + const QueryID *idsPacked); +angle::CallCapture CaptureDeleteSamplers(const State &glState, + bool isCallValid, + GLsizei count, + const SamplerID *samplersPacked); +angle::CallCapture CaptureDeleteSync(const State &glState, bool isCallValid, GLsync sync); +angle::CallCapture CaptureDeleteTransformFeedbacks(const State &glState, + bool isCallValid, + GLsizei n, + const TransformFeedbackID *idsPacked); +angle::CallCapture CaptureDeleteVertexArrays(const State &glState, + bool isCallValid, + GLsizei n, + const VertexArrayID *arraysPacked); +angle::CallCapture CaptureDrawArraysInstanced(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLint first, + GLsizei count, + GLsizei instancecount); +angle::CallCapture CaptureDrawBuffers(const State &glState, + bool isCallValid, + GLsizei n, + const GLenum *bufs); +angle::CallCapture CaptureDrawElementsInstanced(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLsizei instancecount); +angle::CallCapture CaptureDrawRangeElements(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLuint start, + GLuint end, + GLsizei count, + DrawElementsType typePacked, + const void *indices); +angle::CallCapture CaptureEndQuery(const State &glState, bool isCallValid, QueryType targetPacked); +angle::CallCapture CaptureEndTransformFeedback(const State &glState, bool isCallValid); +angle::CallCapture CaptureFenceSync(const State &glState, + bool isCallValid, + GLenum condition, + GLbitfield flags, + GLsync returnValue); +angle::CallCapture CaptureFlushMappedBufferRange(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLintptr offset, + GLsizeiptr length); +angle::CallCapture CaptureFramebufferTextureLayer(const State &glState, + bool isCallValid, + GLenum target, + GLenum attachment, + TextureID texturePacked, + GLint level, + GLint layer); +angle::CallCapture CaptureGenQueries(const State &glState, + bool isCallValid, + GLsizei n, + QueryID *idsPacked); +angle::CallCapture CaptureGenSamplers(const State &glState, + bool isCallValid, + GLsizei count, + SamplerID *samplersPacked); +angle::CallCapture CaptureGenTransformFeedbacks(const State &glState, + bool isCallValid, + GLsizei n, + TransformFeedbackID *idsPacked); +angle::CallCapture CaptureGenVertexArrays(const State &glState, + bool isCallValid, + GLsizei n, + VertexArrayID *arraysPacked); +angle::CallCapture CaptureGetActiveUniformBlockName(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformBlockIndex uniformBlockIndexPacked, + GLsizei bufSize, + GLsizei *length, + GLchar *uniformBlockName); +angle::CallCapture CaptureGetActiveUniformBlockiv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformBlockIndex uniformBlockIndexPacked, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetActiveUniformsiv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLsizei uniformCount, + const GLuint *uniformIndices, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetBufferParameteri64v(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLenum pname, + GLint64 *params); +angle::CallCapture CaptureGetBufferPointerv(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLenum pname, + void **params); +angle::CallCapture CaptureGetFragDataLocation(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + const GLchar *name, + GLint returnValue); +angle::CallCapture CaptureGetInteger64i_v(const State &glState, + bool isCallValid, + GLenum target, + GLuint index, + GLint64 *data); +angle::CallCapture CaptureGetInteger64v(const State &glState, + bool isCallValid, + GLenum pname, + GLint64 *data); +angle::CallCapture CaptureGetIntegeri_v(const State &glState, + bool isCallValid, + GLenum target, + GLuint index, + GLint *data); +angle::CallCapture CaptureGetInternalformativ(const State &glState, + bool isCallValid, + GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei count, + GLint *params); +angle::CallCapture CaptureGetProgramBinary(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLsizei bufSize, + GLsizei *length, + GLenum *binaryFormat, + void *binary); +angle::CallCapture CaptureGetQueryObjectuiv(const State &glState, + bool isCallValid, + QueryID idPacked, + GLenum pname, + GLuint *params); +angle::CallCapture CaptureGetQueryiv(const State &glState, + bool isCallValid, + QueryType targetPacked, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetSamplerParameterfv(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLfloat *params); +angle::CallCapture CaptureGetSamplerParameteriv(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetStringi(const State &glState, + bool isCallValid, + GLenum name, + GLuint index, + const GLubyte *returnValue); +angle::CallCapture CaptureGetSynciv(const State &glState, + bool isCallValid, + GLsync sync, + GLenum pname, + GLsizei count, + GLsizei *length, + GLint *values); +angle::CallCapture CaptureGetTransformFeedbackVarying(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLsizei *size, + GLenum *type, + GLchar *name); +angle::CallCapture CaptureGetUniformBlockIndex(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + const GLchar *uniformBlockName, + GLuint returnValue); +angle::CallCapture CaptureGetUniformIndices(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLsizei uniformCount, + const GLchar *const *uniformNames, + GLuint *uniformIndices); +angle::CallCapture CaptureGetUniformuiv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLuint *params); +angle::CallCapture CaptureGetVertexAttribIiv(const State &glState, + bool isCallValid, + GLuint index, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetVertexAttribIuiv(const State &glState, + bool isCallValid, + GLuint index, + GLenum pname, + GLuint *params); +angle::CallCapture CaptureInvalidateFramebuffer(const State &glState, + bool isCallValid, + GLenum target, + GLsizei numAttachments, + const GLenum *attachments); +angle::CallCapture CaptureInvalidateSubFramebuffer(const State &glState, + bool isCallValid, + GLenum target, + GLsizei numAttachments, + const GLenum *attachments, + GLint x, + GLint y, + GLsizei width, + GLsizei height); +angle::CallCapture CaptureIsQuery(const State &glState, + bool isCallValid, + QueryID idPacked, + GLboolean returnValue); +angle::CallCapture CaptureIsSampler(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLboolean returnValue); +angle::CallCapture CaptureIsSync(const State &glState, + bool isCallValid, + GLsync sync, + GLboolean returnValue); +angle::CallCapture CaptureIsTransformFeedback(const State &glState, + bool isCallValid, + TransformFeedbackID idPacked, + GLboolean returnValue); +angle::CallCapture CaptureIsVertexArray(const State &glState, + bool isCallValid, + VertexArrayID arrayPacked, + GLboolean returnValue); +angle::CallCapture CaptureMapBufferRange(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLintptr offset, + GLsizeiptr length, + GLbitfield access, + void *returnValue); +angle::CallCapture CapturePauseTransformFeedback(const State &glState, bool isCallValid); +angle::CallCapture CaptureProgramBinary(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum binaryFormat, + const void *binary, + GLsizei length); +angle::CallCapture CaptureProgramParameteri(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum pname, + GLint value); +angle::CallCapture CaptureReadBuffer(const State &glState, bool isCallValid, GLenum src); +angle::CallCapture CaptureRenderbufferStorageMultisample(const State &glState, + bool isCallValid, + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height); +angle::CallCapture CaptureResumeTransformFeedback(const State &glState, bool isCallValid); +angle::CallCapture CaptureSamplerParameterf(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLfloat param); +angle::CallCapture CaptureSamplerParameterfv(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + const GLfloat *param); +angle::CallCapture CaptureSamplerParameteri(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLint param); +angle::CallCapture CaptureSamplerParameteriv(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + const GLint *param); +angle::CallCapture CaptureTexImage3D(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const void *pixels); +angle::CallCapture CaptureTexStorage2D(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height); +angle::CallCapture CaptureTexStorage3D(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth); +angle::CallCapture CaptureTexSubImage3D(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *pixels); +angle::CallCapture CaptureTransformFeedbackVaryings(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLsizei count, + const GLchar *const *varyings, + GLenum bufferMode); +angle::CallCapture CaptureUniform1ui(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLuint v0); +angle::CallCapture CaptureUniform1uiv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value); +angle::CallCapture CaptureUniform2ui(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLuint v0, + GLuint v1); +angle::CallCapture CaptureUniform2uiv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value); +angle::CallCapture CaptureUniform3ui(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLuint v0, + GLuint v1, + GLuint v2); +angle::CallCapture CaptureUniform3uiv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value); +angle::CallCapture CaptureUniform4ui(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3); +angle::CallCapture CaptureUniform4uiv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value); +angle::CallCapture CaptureUniformBlockBinding(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformBlockIndex uniformBlockIndexPacked, + GLuint uniformBlockBinding); +angle::CallCapture CaptureUniformMatrix2x3fv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +angle::CallCapture CaptureUniformMatrix2x4fv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +angle::CallCapture CaptureUniformMatrix3x2fv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +angle::CallCapture CaptureUniformMatrix3x4fv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +angle::CallCapture CaptureUniformMatrix4x2fv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +angle::CallCapture CaptureUniformMatrix4x3fv(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +angle::CallCapture CaptureUnmapBuffer(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLboolean returnValue); +angle::CallCapture CaptureVertexAttribDivisor(const State &glState, + bool isCallValid, + GLuint index, + GLuint divisor); +angle::CallCapture CaptureVertexAttribI4i(const State &glState, + bool isCallValid, + GLuint index, + GLint x, + GLint y, + GLint z, + GLint w); +angle::CallCapture CaptureVertexAttribI4iv(const State &glState, + bool isCallValid, + GLuint index, + const GLint *v); +angle::CallCapture CaptureVertexAttribI4ui(const State &glState, + bool isCallValid, + GLuint index, + GLuint x, + GLuint y, + GLuint z, + GLuint w); +angle::CallCapture CaptureVertexAttribI4uiv(const State &glState, + bool isCallValid, + GLuint index, + const GLuint *v); +angle::CallCapture CaptureVertexAttribIPointer(const State &glState, + bool isCallValid, + GLuint index, + GLint size, + VertexAttribType typePacked, + GLsizei stride, + const void *pointer); +angle::CallCapture CaptureWaitSync(const State &glState, + bool isCallValid, + GLsync sync, + GLbitfield flags, + GLuint64 timeout); + +// Parameter Captures + +void CaptureClearBufferfv_value(const State &glState, + bool isCallValid, + GLenum buffer, + GLint drawbuffer, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureClearBufferiv_value(const State &glState, + bool isCallValid, + GLenum buffer, + GLint drawbuffer, + const GLint *value, + angle::ParamCapture *paramCapture); +void CaptureClearBufferuiv_value(const State &glState, + bool isCallValid, + GLenum buffer, + GLint drawbuffer, + const GLuint *value, + angle::ParamCapture *paramCapture); +void CaptureCompressedTexImage3D_data(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + const void *data, + angle::ParamCapture *paramCapture); +void CaptureCompressedTexSubImage3D_data(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const void *data, + angle::ParamCapture *paramCapture); +void CaptureDeleteQueries_idsPacked(const State &glState, + bool isCallValid, + GLsizei n, + const QueryID *idsPacked, + angle::ParamCapture *paramCapture); +void CaptureDeleteSamplers_samplersPacked(const State &glState, + bool isCallValid, + GLsizei count, + const SamplerID *samplersPacked, + angle::ParamCapture *paramCapture); +void CaptureDeleteTransformFeedbacks_idsPacked(const State &glState, + bool isCallValid, + GLsizei n, + const TransformFeedbackID *idsPacked, + angle::ParamCapture *paramCapture); +void CaptureDeleteVertexArrays_arraysPacked(const State &glState, + bool isCallValid, + GLsizei n, + const VertexArrayID *arraysPacked, + angle::ParamCapture *paramCapture); +void CaptureDrawBuffers_bufs(const State &glState, + bool isCallValid, + GLsizei n, + const GLenum *bufs, + angle::ParamCapture *paramCapture); +void CaptureDrawElementsInstanced_indices(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLsizei instancecount, + angle::ParamCapture *paramCapture); +void CaptureDrawRangeElements_indices(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLuint start, + GLuint end, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + angle::ParamCapture *paramCapture); +void CaptureGenQueries_idsPacked(const State &glState, + bool isCallValid, + GLsizei n, + QueryID *idsPacked, + angle::ParamCapture *paramCapture); +void CaptureGenSamplers_samplersPacked(const State &glState, + bool isCallValid, + GLsizei count, + SamplerID *samplersPacked, + angle::ParamCapture *paramCapture); +void CaptureGenTransformFeedbacks_idsPacked(const State &glState, + bool isCallValid, + GLsizei n, + TransformFeedbackID *idsPacked, + angle::ParamCapture *paramCapture); +void CaptureGenVertexArrays_arraysPacked(const State &glState, + bool isCallValid, + GLsizei n, + VertexArrayID *arraysPacked, + angle::ParamCapture *paramCapture); +void CaptureGetActiveUniformBlockName_length(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformBlockIndex uniformBlockIndexPacked, + GLsizei bufSize, + GLsizei *length, + GLchar *uniformBlockName, + angle::ParamCapture *paramCapture); +void CaptureGetActiveUniformBlockName_uniformBlockName(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformBlockIndex uniformBlockIndexPacked, + GLsizei bufSize, + GLsizei *length, + GLchar *uniformBlockName, + angle::ParamCapture *paramCapture); +void CaptureGetActiveUniformBlockiv_params(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformBlockIndex uniformBlockIndexPacked, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetActiveUniformsiv_uniformIndices(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLsizei uniformCount, + const GLuint *uniformIndices, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetActiveUniformsiv_params(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLsizei uniformCount, + const GLuint *uniformIndices, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetBufferParameteri64v_params(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLenum pname, + GLint64 *params, + angle::ParamCapture *paramCapture); +void CaptureGetBufferPointerv_params(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLenum pname, + void **params, + angle::ParamCapture *paramCapture); +void CaptureGetFragDataLocation_name(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + const GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureGetInteger64i_v_data(const State &glState, + bool isCallValid, + GLenum target, + GLuint index, + GLint64 *data, + angle::ParamCapture *paramCapture); +void CaptureGetInteger64v_data(const State &glState, + bool isCallValid, + GLenum pname, + GLint64 *data, + angle::ParamCapture *paramCapture); +void CaptureGetIntegeri_v_data(const State &glState, + bool isCallValid, + GLenum target, + GLuint index, + GLint *data, + angle::ParamCapture *paramCapture); +void CaptureGetInternalformativ_params(const State &glState, + bool isCallValid, + GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei count, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetProgramBinary_length(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLsizei bufSize, + GLsizei *length, + GLenum *binaryFormat, + void *binary, + angle::ParamCapture *paramCapture); +void CaptureGetProgramBinary_binaryFormat(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLsizei bufSize, + GLsizei *length, + GLenum *binaryFormat, + void *binary, + angle::ParamCapture *paramCapture); +void CaptureGetProgramBinary_binary(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLsizei bufSize, + GLsizei *length, + GLenum *binaryFormat, + void *binary, + angle::ParamCapture *paramCapture); +void CaptureGetQueryObjectuiv_params(const State &glState, + bool isCallValid, + QueryID idPacked, + GLenum pname, + GLuint *params, + angle::ParamCapture *paramCapture); +void CaptureGetQueryiv_params(const State &glState, + bool isCallValid, + QueryType targetPacked, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetSamplerParameterfv_params(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureGetSamplerParameteriv_params(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetSynciv_length(const State &glState, + bool isCallValid, + GLsync sync, + GLenum pname, + GLsizei count, + GLsizei *length, + GLint *values, + angle::ParamCapture *paramCapture); +void CaptureGetSynciv_values(const State &glState, + bool isCallValid, + GLsync sync, + GLenum pname, + GLsizei count, + GLsizei *length, + GLint *values, + angle::ParamCapture *paramCapture); +void CaptureGetTransformFeedbackVarying_length(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLsizei *size, + GLenum *type, + GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureGetTransformFeedbackVarying_size(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLsizei *size, + GLenum *type, + GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureGetTransformFeedbackVarying_type(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLsizei *size, + GLenum *type, + GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureGetTransformFeedbackVarying_name(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLsizei *size, + GLenum *type, + GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureGetUniformBlockIndex_uniformBlockName(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + const GLchar *uniformBlockName, + angle::ParamCapture *paramCapture); +void CaptureGetUniformIndices_uniformNames(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLsizei uniformCount, + const GLchar *const *uniformNames, + GLuint *uniformIndices, + angle::ParamCapture *paramCapture); +void CaptureGetUniformIndices_uniformIndices(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLsizei uniformCount, + const GLchar *const *uniformNames, + GLuint *uniformIndices, + angle::ParamCapture *paramCapture); +void CaptureGetUniformuiv_params(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLuint *params, + angle::ParamCapture *paramCapture); +void CaptureGetVertexAttribIiv_params(const State &glState, + bool isCallValid, + GLuint index, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetVertexAttribIuiv_params(const State &glState, + bool isCallValid, + GLuint index, + GLenum pname, + GLuint *params, + angle::ParamCapture *paramCapture); +void CaptureInvalidateFramebuffer_attachments(const State &glState, + bool isCallValid, + GLenum target, + GLsizei numAttachments, + const GLenum *attachments, + angle::ParamCapture *paramCapture); +void CaptureInvalidateSubFramebuffer_attachments(const State &glState, + bool isCallValid, + GLenum target, + GLsizei numAttachments, + const GLenum *attachments, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + angle::ParamCapture *paramCapture); +void CaptureProgramBinary_binary(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum binaryFormat, + const void *binary, + GLsizei length, + angle::ParamCapture *paramCapture); +void CaptureSamplerParameterfv_param(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + const GLfloat *param, + angle::ParamCapture *paramCapture); +void CaptureSamplerParameteriv_param(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + const GLint *param, + angle::ParamCapture *paramCapture); +void CaptureTexImage3D_pixels(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const void *pixels, + angle::ParamCapture *paramCapture); +void CaptureTexSubImage3D_pixels(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *pixels, + angle::ParamCapture *paramCapture); +void CaptureTransformFeedbackVaryings_varyings(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLsizei count, + const GLchar *const *varyings, + GLenum bufferMode, + angle::ParamCapture *paramCapture); +void CaptureUniform1uiv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value, + angle::ParamCapture *paramCapture); +void CaptureUniform2uiv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value, + angle::ParamCapture *paramCapture); +void CaptureUniform3uiv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value, + angle::ParamCapture *paramCapture); +void CaptureUniform4uiv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value, + angle::ParamCapture *paramCapture); +void CaptureUniformMatrix2x3fv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureUniformMatrix2x4fv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureUniformMatrix3x2fv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureUniformMatrix3x4fv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureUniformMatrix4x2fv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureUniformMatrix4x3fv_value(const State &glState, + bool isCallValid, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureVertexAttribI4iv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLint *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttribI4uiv_v(const State &glState, + bool isCallValid, + GLuint index, + const GLuint *v, + angle::ParamCapture *paramCapture); +void CaptureVertexAttribIPointer_pointer(const State &glState, + bool isCallValid, + GLuint index, + GLint size, + VertexAttribType typePacked, + GLsizei stride, + const void *pointer, + angle::ParamCapture *paramCapture); +} // namespace gl + +#endif // LIBANGLE_CAPTURE_GLES_3_0_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/capture/capture_gles_3_1_autogen.h b/gfx/angle/checkout/src/libANGLE/capture/capture_gles_3_1_autogen.h new file mode 100644 index 0000000000..ee594a1c79 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/capture/capture_gles_3_1_autogen.h @@ -0,0 +1,728 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// capture_gles_3_1_autogen.h: +// Capture functions for the OpenGL ES 3.1 entry points. + +#ifndef LIBANGLE_CAPTURE_GLES_3_1_AUTOGEN_H_ +#define LIBANGLE_CAPTURE_GLES_3_1_AUTOGEN_H_ + +#include "common/PackedEnums.h" +#include "libANGLE/capture/FrameCapture.h" + +namespace gl +{ + +// Method Captures + +angle::CallCapture CaptureActiveShaderProgram(const State &glState, + bool isCallValid, + ProgramPipelineID pipelinePacked, + ShaderProgramID programPacked); +angle::CallCapture CaptureBindImageTexture(const State &glState, + bool isCallValid, + GLuint unit, + TextureID texturePacked, + GLint level, + GLboolean layered, + GLint layer, + GLenum access, + GLenum format); +angle::CallCapture CaptureBindProgramPipeline(const State &glState, + bool isCallValid, + ProgramPipelineID pipelinePacked); +angle::CallCapture CaptureBindVertexBuffer(const State &glState, + bool isCallValid, + GLuint bindingindex, + BufferID bufferPacked, + GLintptr offset, + GLsizei stride); +angle::CallCapture CaptureCreateShaderProgramv(const State &glState, + bool isCallValid, + ShaderType typePacked, + GLsizei count, + const GLchar *const *strings, + GLuint returnValue); +angle::CallCapture CaptureDeleteProgramPipelines(const State &glState, + bool isCallValid, + GLsizei n, + const ProgramPipelineID *pipelinesPacked); +angle::CallCapture CaptureDispatchCompute(const State &glState, + bool isCallValid, + GLuint num_groups_x, + GLuint num_groups_y, + GLuint num_groups_z); +angle::CallCapture CaptureDispatchComputeIndirect(const State &glState, + bool isCallValid, + GLintptr indirect); +angle::CallCapture CaptureDrawArraysIndirect(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const void *indirect); +angle::CallCapture CaptureDrawElementsIndirect(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + DrawElementsType typePacked, + const void *indirect); +angle::CallCapture CaptureFramebufferParameteri(const State &glState, + bool isCallValid, + GLenum target, + GLenum pname, + GLint param); +angle::CallCapture CaptureGenProgramPipelines(const State &glState, + bool isCallValid, + GLsizei n, + ProgramPipelineID *pipelinesPacked); +angle::CallCapture CaptureGetBooleani_v(const State &glState, + bool isCallValid, + GLenum target, + GLuint index, + GLboolean *data); +angle::CallCapture CaptureGetFramebufferParameteriv(const State &glState, + bool isCallValid, + GLenum target, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetMultisamplefv(const State &glState, + bool isCallValid, + GLenum pname, + GLuint index, + GLfloat *val); +angle::CallCapture CaptureGetProgramInterfaceiv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum programInterface, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetProgramPipelineInfoLog(const State &glState, + bool isCallValid, + ProgramPipelineID pipelinePacked, + GLsizei bufSize, + GLsizei *length, + GLchar *infoLog); +angle::CallCapture CaptureGetProgramPipelineiv(const State &glState, + bool isCallValid, + ProgramPipelineID pipelinePacked, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetProgramResourceIndex(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum programInterface, + const GLchar *name, + GLuint returnValue); +angle::CallCapture CaptureGetProgramResourceLocation(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum programInterface, + const GLchar *name, + GLint returnValue); +angle::CallCapture CaptureGetProgramResourceName(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum programInterface, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name); +angle::CallCapture CaptureGetProgramResourceiv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum programInterface, + GLuint index, + GLsizei propCount, + const GLenum *props, + GLsizei count, + GLsizei *length, + GLint *params); +angle::CallCapture CaptureGetTexLevelParameterfv(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLenum pname, + GLfloat *params); +angle::CallCapture CaptureGetTexLevelParameteriv(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLenum pname, + GLint *params); +angle::CallCapture CaptureIsProgramPipeline(const State &glState, + bool isCallValid, + ProgramPipelineID pipelinePacked, + GLboolean returnValue); +angle::CallCapture CaptureMemoryBarrier(const State &glState, + bool isCallValid, + GLbitfield barriers); +angle::CallCapture CaptureMemoryBarrierByRegion(const State &glState, + bool isCallValid, + GLbitfield barriers); +angle::CallCapture CaptureProgramUniform1f(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLfloat v0); +angle::CallCapture CaptureProgramUniform1fv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value); +angle::CallCapture CaptureProgramUniform1i(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLint v0); +angle::CallCapture CaptureProgramUniform1iv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value); +angle::CallCapture CaptureProgramUniform1ui(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLuint v0); +angle::CallCapture CaptureProgramUniform1uiv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value); +angle::CallCapture CaptureProgramUniform2f(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLfloat v0, + GLfloat v1); +angle::CallCapture CaptureProgramUniform2fv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value); +angle::CallCapture CaptureProgramUniform2i(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLint v0, + GLint v1); +angle::CallCapture CaptureProgramUniform2iv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value); +angle::CallCapture CaptureProgramUniform2ui(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLuint v0, + GLuint v1); +angle::CallCapture CaptureProgramUniform2uiv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value); +angle::CallCapture CaptureProgramUniform3f(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLfloat v0, + GLfloat v1, + GLfloat v2); +angle::CallCapture CaptureProgramUniform3fv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value); +angle::CallCapture CaptureProgramUniform3i(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLint v0, + GLint v1, + GLint v2); +angle::CallCapture CaptureProgramUniform3iv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value); +angle::CallCapture CaptureProgramUniform3ui(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLuint v0, + GLuint v1, + GLuint v2); +angle::CallCapture CaptureProgramUniform3uiv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value); +angle::CallCapture CaptureProgramUniform4f(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLfloat v0, + GLfloat v1, + GLfloat v2, + GLfloat v3); +angle::CallCapture CaptureProgramUniform4fv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value); +angle::CallCapture CaptureProgramUniform4i(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLint v0, + GLint v1, + GLint v2, + GLint v3); +angle::CallCapture CaptureProgramUniform4iv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value); +angle::CallCapture CaptureProgramUniform4ui(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3); +angle::CallCapture CaptureProgramUniform4uiv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value); +angle::CallCapture CaptureProgramUniformMatrix2fv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +angle::CallCapture CaptureProgramUniformMatrix2x3fv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +angle::CallCapture CaptureProgramUniformMatrix2x4fv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +angle::CallCapture CaptureProgramUniformMatrix3fv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +angle::CallCapture CaptureProgramUniformMatrix3x2fv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +angle::CallCapture CaptureProgramUniformMatrix3x4fv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +angle::CallCapture CaptureProgramUniformMatrix4fv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +angle::CallCapture CaptureProgramUniformMatrix4x2fv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +angle::CallCapture CaptureProgramUniformMatrix4x3fv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +angle::CallCapture CaptureSampleMaski(const State &glState, + bool isCallValid, + GLuint maskNumber, + GLbitfield mask); +angle::CallCapture CaptureTexStorage2DMultisample(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations); +angle::CallCapture CaptureUseProgramStages(const State &glState, + bool isCallValid, + ProgramPipelineID pipelinePacked, + GLbitfield stages, + ShaderProgramID programPacked); +angle::CallCapture CaptureValidateProgramPipeline(const State &glState, + bool isCallValid, + ProgramPipelineID pipelinePacked); +angle::CallCapture CaptureVertexAttribBinding(const State &glState, + bool isCallValid, + GLuint attribindex, + GLuint bindingindex); +angle::CallCapture CaptureVertexAttribFormat(const State &glState, + bool isCallValid, + GLuint attribindex, + GLint size, + VertexAttribType typePacked, + GLboolean normalized, + GLuint relativeoffset); +angle::CallCapture CaptureVertexAttribIFormat(const State &glState, + bool isCallValid, + GLuint attribindex, + GLint size, + VertexAttribType typePacked, + GLuint relativeoffset); +angle::CallCapture CaptureVertexBindingDivisor(const State &glState, + bool isCallValid, + GLuint bindingindex, + GLuint divisor); + +// Parameter Captures + +void CaptureCreateShaderProgramv_strings(const State &glState, + bool isCallValid, + ShaderType typePacked, + GLsizei count, + const GLchar *const *strings, + angle::ParamCapture *paramCapture); +void CaptureDeleteProgramPipelines_pipelinesPacked(const State &glState, + bool isCallValid, + GLsizei n, + const ProgramPipelineID *pipelinesPacked, + angle::ParamCapture *paramCapture); +void CaptureDrawArraysIndirect_indirect(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const void *indirect, + angle::ParamCapture *paramCapture); +void CaptureDrawElementsIndirect_indirect(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + DrawElementsType typePacked, + const void *indirect, + angle::ParamCapture *paramCapture); +void CaptureGenProgramPipelines_pipelinesPacked(const State &glState, + bool isCallValid, + GLsizei n, + ProgramPipelineID *pipelinesPacked, + angle::ParamCapture *paramCapture); +void CaptureGetBooleani_v_data(const State &glState, + bool isCallValid, + GLenum target, + GLuint index, + GLboolean *data, + angle::ParamCapture *paramCapture); +void CaptureGetFramebufferParameteriv_params(const State &glState, + bool isCallValid, + GLenum target, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetMultisamplefv_val(const State &glState, + bool isCallValid, + GLenum pname, + GLuint index, + GLfloat *val, + angle::ParamCapture *paramCapture); +void CaptureGetProgramInterfaceiv_params(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum programInterface, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetProgramPipelineInfoLog_length(const State &glState, + bool isCallValid, + ProgramPipelineID pipelinePacked, + GLsizei bufSize, + GLsizei *length, + GLchar *infoLog, + angle::ParamCapture *paramCapture); +void CaptureGetProgramPipelineInfoLog_infoLog(const State &glState, + bool isCallValid, + ProgramPipelineID pipelinePacked, + GLsizei bufSize, + GLsizei *length, + GLchar *infoLog, + angle::ParamCapture *paramCapture); +void CaptureGetProgramPipelineiv_params(const State &glState, + bool isCallValid, + ProgramPipelineID pipelinePacked, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetProgramResourceIndex_name(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum programInterface, + const GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureGetProgramResourceLocation_name(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum programInterface, + const GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureGetProgramResourceName_length(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum programInterface, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureGetProgramResourceName_name(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum programInterface, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureGetProgramResourceiv_props(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum programInterface, + GLuint index, + GLsizei propCount, + const GLenum *props, + GLsizei count, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetProgramResourceiv_length(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum programInterface, + GLuint index, + GLsizei propCount, + const GLenum *props, + GLsizei count, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetProgramResourceiv_params(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum programInterface, + GLuint index, + GLsizei propCount, + const GLenum *props, + GLsizei count, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexLevelParameterfv_params(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLenum pname, + GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexLevelParameteriv_params(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureProgramUniform1fv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniform1iv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniform1uiv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniform2fv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniform2iv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniform2uiv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniform3fv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniform3iv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniform3uiv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniform4fv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniform4iv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniform4uiv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniformMatrix2fv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniformMatrix2x3fv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniformMatrix2x4fv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniformMatrix3fv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniformMatrix3x2fv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniformMatrix3x4fv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniformMatrix4fv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniformMatrix4x2fv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniformMatrix4x3fv_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value, + angle::ParamCapture *paramCapture); +} // namespace gl + +#endif // LIBANGLE_CAPTURE_GLES_3_1_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/capture/capture_gles_3_2_autogen.h b/gfx/angle/checkout/src/libANGLE/capture/capture_gles_3_2_autogen.h new file mode 100644 index 0000000000..80001a0348 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/capture/capture_gles_3_2_autogen.h @@ -0,0 +1,553 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// capture_gles_3_2_autogen.h: +// Capture functions for the OpenGL ES 3.2 entry points. + +#ifndef LIBANGLE_CAPTURE_GLES_3_2_AUTOGEN_H_ +#define LIBANGLE_CAPTURE_GLES_3_2_AUTOGEN_H_ + +#include "common/PackedEnums.h" +#include "libANGLE/capture/FrameCapture.h" + +namespace gl +{ + +// Method Captures + +angle::CallCapture CaptureBlendBarrier(const State &glState, bool isCallValid); +angle::CallCapture CaptureBlendEquationSeparatei(const State &glState, + bool isCallValid, + GLuint buf, + GLenum modeRGB, + GLenum modeAlpha); +angle::CallCapture CaptureBlendEquationi(const State &glState, + bool isCallValid, + GLuint buf, + GLenum mode); +angle::CallCapture CaptureBlendFuncSeparatei(const State &glState, + bool isCallValid, + GLuint buf, + GLenum srcRGB, + GLenum dstRGB, + GLenum srcAlpha, + GLenum dstAlpha); +angle::CallCapture CaptureBlendFunci(const State &glState, + bool isCallValid, + GLuint buf, + GLenum src, + GLenum dst); +angle::CallCapture CaptureColorMaski(const State &glState, + bool isCallValid, + GLuint index, + GLboolean r, + GLboolean g, + GLboolean b, + GLboolean a); +angle::CallCapture CaptureCopyImageSubData(const State &glState, + bool isCallValid, + GLuint srcName, + GLenum srcTarget, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLuint dstName, + GLenum dstTarget, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth); +angle::CallCapture CaptureDebugMessageCallback(const State &glState, + bool isCallValid, + GLDEBUGPROC callback, + const void *userParam); +angle::CallCapture CaptureDebugMessageControl(const State &glState, + bool isCallValid, + GLenum source, + GLenum type, + GLenum severity, + GLsizei count, + const GLuint *ids, + GLboolean enabled); +angle::CallCapture CaptureDebugMessageInsert(const State &glState, + bool isCallValid, + GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar *buf); +angle::CallCapture CaptureDisablei(const State &glState, + bool isCallValid, + GLenum target, + GLuint index); +angle::CallCapture CaptureDrawElementsBaseVertex(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLint basevertex); +angle::CallCapture CaptureDrawElementsInstancedBaseVertex(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLsizei instancecount, + GLint basevertex); +angle::CallCapture CaptureDrawRangeElementsBaseVertex(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLuint start, + GLuint end, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLint basevertex); +angle::CallCapture CaptureEnablei(const State &glState, + bool isCallValid, + GLenum target, + GLuint index); +angle::CallCapture CaptureFramebufferTexture(const State &glState, + bool isCallValid, + GLenum target, + GLenum attachment, + TextureID texturePacked, + GLint level); +angle::CallCapture CaptureGetDebugMessageLog(const State &glState, + bool isCallValid, + GLuint count, + GLsizei bufSize, + GLenum *sources, + GLenum *types, + GLuint *ids, + GLenum *severities, + GLsizei *lengths, + GLchar *messageLog, + GLuint returnValue); +angle::CallCapture CaptureGetGraphicsResetStatus(const State &glState, + bool isCallValid, + GLenum returnValue); +angle::CallCapture CaptureGetObjectLabel(const State &glState, + bool isCallValid, + GLenum identifier, + GLuint name, + GLsizei bufSize, + GLsizei *length, + GLchar *label); +angle::CallCapture CaptureGetObjectPtrLabel(const State &glState, + bool isCallValid, + const void *ptr, + GLsizei bufSize, + GLsizei *length, + GLchar *label); +angle::CallCapture CaptureGetPointerv(const State &glState, + bool isCallValid, + GLenum pname, + void **params); +angle::CallCapture CaptureGetSamplerParameterIiv(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetSamplerParameterIuiv(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLuint *params); +angle::CallCapture CaptureGetTexParameterIiv(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetTexParameterIuiv(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLuint *params); +angle::CallCapture CaptureGetnUniformfv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + GLfloat *params); +angle::CallCapture CaptureGetnUniformiv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + GLint *params); +angle::CallCapture CaptureGetnUniformuiv(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + GLuint *params); +angle::CallCapture CaptureIsEnabledi(const State &glState, + bool isCallValid, + GLenum target, + GLuint index, + GLboolean returnValue); +angle::CallCapture CaptureMinSampleShading(const State &glState, bool isCallValid, GLfloat value); +angle::CallCapture CaptureObjectLabel(const State &glState, + bool isCallValid, + GLenum identifier, + GLuint name, + GLsizei length, + const GLchar *label); +angle::CallCapture CaptureObjectPtrLabel(const State &glState, + bool isCallValid, + const void *ptr, + GLsizei length, + const GLchar *label); +angle::CallCapture CapturePatchParameteri(const State &glState, + bool isCallValid, + GLenum pname, + GLint value); +angle::CallCapture CapturePopDebugGroup(const State &glState, bool isCallValid); +angle::CallCapture CapturePrimitiveBoundingBox(const State &glState, + bool isCallValid, + GLfloat minX, + GLfloat minY, + GLfloat minZ, + GLfloat minW, + GLfloat maxX, + GLfloat maxY, + GLfloat maxZ, + GLfloat maxW); +angle::CallCapture CapturePushDebugGroup(const State &glState, + bool isCallValid, + GLenum source, + GLuint id, + GLsizei length, + const GLchar *message); +angle::CallCapture CaptureReadnPixels(const State &glState, + bool isCallValid, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + void *data); +angle::CallCapture CaptureSamplerParameterIiv(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + const GLint *param); +angle::CallCapture CaptureSamplerParameterIuiv(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + const GLuint *param); +angle::CallCapture CaptureTexBuffer(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum internalformat, + BufferID bufferPacked); +angle::CallCapture CaptureTexBufferRange(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum internalformat, + BufferID bufferPacked, + GLintptr offset, + GLsizeiptr size); +angle::CallCapture CaptureTexParameterIiv(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + const GLint *params); +angle::CallCapture CaptureTexParameterIuiv(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + const GLuint *params); +angle::CallCapture CaptureTexStorage3DMultisample(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedsamplelocations); + +// Parameter Captures + +void CaptureDebugMessageCallback_userParam(const State &glState, + bool isCallValid, + GLDEBUGPROC callback, + const void *userParam, + angle::ParamCapture *paramCapture); +void CaptureDebugMessageControl_ids(const State &glState, + bool isCallValid, + GLenum source, + GLenum type, + GLenum severity, + GLsizei count, + const GLuint *ids, + GLboolean enabled, + angle::ParamCapture *paramCapture); +void CaptureDebugMessageInsert_buf(const State &glState, + bool isCallValid, + GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar *buf, + angle::ParamCapture *paramCapture); +void CaptureDrawElementsBaseVertex_indices(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLint basevertex, + angle::ParamCapture *paramCapture); +void CaptureDrawElementsInstancedBaseVertex_indices(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLsizei instancecount, + GLint basevertex, + angle::ParamCapture *paramCapture); +void CaptureDrawRangeElementsBaseVertex_indices(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLuint start, + GLuint end, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLint basevertex, + angle::ParamCapture *paramCapture); +void CaptureGetDebugMessageLog_sources(const State &glState, + bool isCallValid, + GLuint count, + GLsizei bufSize, + GLenum *sources, + GLenum *types, + GLuint *ids, + GLenum *severities, + GLsizei *lengths, + GLchar *messageLog, + angle::ParamCapture *paramCapture); +void CaptureGetDebugMessageLog_types(const State &glState, + bool isCallValid, + GLuint count, + GLsizei bufSize, + GLenum *sources, + GLenum *types, + GLuint *ids, + GLenum *severities, + GLsizei *lengths, + GLchar *messageLog, + angle::ParamCapture *paramCapture); +void CaptureGetDebugMessageLog_ids(const State &glState, + bool isCallValid, + GLuint count, + GLsizei bufSize, + GLenum *sources, + GLenum *types, + GLuint *ids, + GLenum *severities, + GLsizei *lengths, + GLchar *messageLog, + angle::ParamCapture *paramCapture); +void CaptureGetDebugMessageLog_severities(const State &glState, + bool isCallValid, + GLuint count, + GLsizei bufSize, + GLenum *sources, + GLenum *types, + GLuint *ids, + GLenum *severities, + GLsizei *lengths, + GLchar *messageLog, + angle::ParamCapture *paramCapture); +void CaptureGetDebugMessageLog_lengths(const State &glState, + bool isCallValid, + GLuint count, + GLsizei bufSize, + GLenum *sources, + GLenum *types, + GLuint *ids, + GLenum *severities, + GLsizei *lengths, + GLchar *messageLog, + angle::ParamCapture *paramCapture); +void CaptureGetDebugMessageLog_messageLog(const State &glState, + bool isCallValid, + GLuint count, + GLsizei bufSize, + GLenum *sources, + GLenum *types, + GLuint *ids, + GLenum *severities, + GLsizei *lengths, + GLchar *messageLog, + angle::ParamCapture *paramCapture); +void CaptureGetObjectLabel_length(const State &glState, + bool isCallValid, + GLenum identifier, + GLuint name, + GLsizei bufSize, + GLsizei *length, + GLchar *label, + angle::ParamCapture *paramCapture); +void CaptureGetObjectLabel_label(const State &glState, + bool isCallValid, + GLenum identifier, + GLuint name, + GLsizei bufSize, + GLsizei *length, + GLchar *label, + angle::ParamCapture *paramCapture); +void CaptureGetObjectPtrLabel_ptr(const State &glState, + bool isCallValid, + const void *ptr, + GLsizei bufSize, + GLsizei *length, + GLchar *label, + angle::ParamCapture *paramCapture); +void CaptureGetObjectPtrLabel_length(const State &glState, + bool isCallValid, + const void *ptr, + GLsizei bufSize, + GLsizei *length, + GLchar *label, + angle::ParamCapture *paramCapture); +void CaptureGetObjectPtrLabel_label(const State &glState, + bool isCallValid, + const void *ptr, + GLsizei bufSize, + GLsizei *length, + GLchar *label, + angle::ParamCapture *paramCapture); +void CaptureGetPointerv_params(const State &glState, + bool isCallValid, + GLenum pname, + void **params, + angle::ParamCapture *paramCapture); +void CaptureGetSamplerParameterIiv_params(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetSamplerParameterIuiv_params(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLuint *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexParameterIiv_params(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexParameterIuiv_params(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLuint *params, + angle::ParamCapture *paramCapture); +void CaptureGetnUniformfv_params(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureGetnUniformiv_params(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetnUniformuiv_params(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + GLuint *params, + angle::ParamCapture *paramCapture); +void CaptureObjectLabel_label(const State &glState, + bool isCallValid, + GLenum identifier, + GLuint name, + GLsizei length, + const GLchar *label, + angle::ParamCapture *paramCapture); +void CaptureObjectPtrLabel_ptr(const State &glState, + bool isCallValid, + const void *ptr, + GLsizei length, + const GLchar *label, + angle::ParamCapture *paramCapture); +void CaptureObjectPtrLabel_label(const State &glState, + bool isCallValid, + const void *ptr, + GLsizei length, + const GLchar *label, + angle::ParamCapture *paramCapture); +void CapturePushDebugGroup_message(const State &glState, + bool isCallValid, + GLenum source, + GLuint id, + GLsizei length, + const GLchar *message, + angle::ParamCapture *paramCapture); +void CaptureReadnPixels_data(const State &glState, + bool isCallValid, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + void *data, + angle::ParamCapture *paramCapture); +void CaptureSamplerParameterIiv_param(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + const GLint *param, + angle::ParamCapture *paramCapture); +void CaptureSamplerParameterIuiv_param(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + const GLuint *param, + angle::ParamCapture *paramCapture); +void CaptureTexParameterIiv_params(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + const GLint *params, + angle::ParamCapture *paramCapture); +void CaptureTexParameterIuiv_params(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + const GLuint *params, + angle::ParamCapture *paramCapture); +} // namespace gl + +#endif // LIBANGLE_CAPTURE_GLES_3_2_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/capture/capture_gles_ext_autogen.h b/gfx/angle/checkout/src/libANGLE/capture/capture_gles_ext_autogen.h new file mode 100644 index 0000000000..03211ffeb9 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/capture/capture_gles_ext_autogen.h @@ -0,0 +1,5231 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// capture_gles_ext_autogen.h: +// Capture functions for the OpenGL ES extension entry points. + +#ifndef LIBANGLE_CAPTURE_GLES_EXT_AUTOGEN_H_ +#define LIBANGLE_CAPTURE_GLES_EXT_AUTOGEN_H_ + +#include "common/PackedEnums.h" +#include "libANGLE/capture/FrameCapture.h" + +namespace gl +{ + +// Method Captures + +// GL_AMD_performance_monitor +angle::CallCapture CaptureBeginPerfMonitorAMD(const State &glState, + bool isCallValid, + GLuint monitor); +angle::CallCapture CaptureDeletePerfMonitorsAMD(const State &glState, + bool isCallValid, + GLsizei n, + GLuint *monitors); +angle::CallCapture CaptureEndPerfMonitorAMD(const State &glState, bool isCallValid, GLuint monitor); +angle::CallCapture CaptureGenPerfMonitorsAMD(const State &glState, + bool isCallValid, + GLsizei n, + GLuint *monitors); +angle::CallCapture CaptureGetPerfMonitorCounterDataAMD(const State &glState, + bool isCallValid, + GLuint monitor, + GLenum pname, + GLsizei dataSize, + GLuint *data, + GLint *bytesWritten); +angle::CallCapture CaptureGetPerfMonitorCounterInfoAMD(const State &glState, + bool isCallValid, + GLuint group, + GLuint counter, + GLenum pname, + void *data); +angle::CallCapture CaptureGetPerfMonitorCounterStringAMD(const State &glState, + bool isCallValid, + GLuint group, + GLuint counter, + GLsizei bufSize, + GLsizei *length, + GLchar *counterString); +angle::CallCapture CaptureGetPerfMonitorCountersAMD(const State &glState, + bool isCallValid, + GLuint group, + GLint *numCounters, + GLint *maxActiveCounters, + GLsizei counterSize, + GLuint *counters); +angle::CallCapture CaptureGetPerfMonitorGroupStringAMD(const State &glState, + bool isCallValid, + GLuint group, + GLsizei bufSize, + GLsizei *length, + GLchar *groupString); +angle::CallCapture CaptureGetPerfMonitorGroupsAMD(const State &glState, + bool isCallValid, + GLint *numGroups, + GLsizei groupsSize, + GLuint *groups); +angle::CallCapture CaptureSelectPerfMonitorCountersAMD(const State &glState, + bool isCallValid, + GLuint monitor, + GLboolean enable, + GLuint group, + GLint numCounters, + GLuint *counterList); + +// GL_ANDROID_extension_pack_es31a + +// GL_ANGLE_base_vertex_base_instance +angle::CallCapture CaptureDrawArraysInstancedBaseInstanceANGLE(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLint first, + GLsizei count, + GLsizei instanceCount, + GLuint baseInstance); +angle::CallCapture CaptureDrawElementsInstancedBaseVertexBaseInstanceANGLE( + const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const GLvoid *indices, + GLsizei instanceCount, + GLint baseVertex, + GLuint baseInstance); +angle::CallCapture CaptureMultiDrawArraysInstancedBaseInstanceANGLE(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLint *firsts, + const GLsizei *counts, + const GLsizei *instanceCounts, + const GLuint *baseInstances, + GLsizei drawcount); +angle::CallCapture CaptureMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE( + const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLsizei *counts, + DrawElementsType typePacked, + const GLvoid *const *indices, + const GLsizei *instanceCounts, + const GLint *baseVertices, + const GLuint *baseInstances, + GLsizei drawcount); + +// GL_ANGLE_copy_texture_3d +angle::CallCapture CaptureCopyTexture3DANGLE(const State &glState, + bool isCallValid, + TextureID sourceIdPacked, + GLint sourceLevel, + TextureTarget destTargetPacked, + TextureID destIdPacked, + GLint destLevel, + GLint internalFormat, + GLenum destType, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha); +angle::CallCapture CaptureCopySubTexture3DANGLE(const State &glState, + bool isCallValid, + TextureID sourceIdPacked, + GLint sourceLevel, + TextureTarget destTargetPacked, + TextureID destIdPacked, + GLint destLevel, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLint z, + GLint width, + GLint height, + GLint depth, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha); + +// GL_ANGLE_depth_texture + +// GL_ANGLE_framebuffer_blit +angle::CallCapture CaptureBlitFramebufferANGLE(const State &glState, + bool isCallValid, + GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter); + +// GL_ANGLE_framebuffer_multisample +angle::CallCapture CaptureRenderbufferStorageMultisampleANGLE(const State &glState, + bool isCallValid, + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height); + +// GL_ANGLE_get_image +angle::CallCapture CaptureGetTexImageANGLE(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLenum format, + GLenum type, + void *pixels); +angle::CallCapture CaptureGetCompressedTexImageANGLE(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + void *pixels); +angle::CallCapture CaptureGetRenderbufferImageANGLE(const State &glState, + bool isCallValid, + GLenum target, + GLenum format, + GLenum type, + void *pixels); + +// GL_ANGLE_get_tex_level_parameter +angle::CallCapture CaptureGetTexLevelParameterivANGLE(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetTexLevelParameterfvANGLE(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLenum pname, + GLfloat *params); + +// GL_ANGLE_instanced_arrays +angle::CallCapture CaptureDrawArraysInstancedANGLE(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLint first, + GLsizei count, + GLsizei primcount); +angle::CallCapture CaptureDrawElementsInstancedANGLE(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLsizei primcount); +angle::CallCapture CaptureVertexAttribDivisorANGLE(const State &glState, + bool isCallValid, + GLuint index, + GLuint divisor); + +// GL_ANGLE_logic_op +angle::CallCapture CaptureLogicOpANGLE(const State &glState, + bool isCallValid, + LogicalOperation opcodePacked); + +// GL_ANGLE_memory_object_flags +angle::CallCapture CaptureTexStorageMemFlags2DANGLE(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height, + MemoryObjectID memoryPacked, + GLuint64 offset, + GLbitfield createFlags, + GLbitfield usageFlags, + const void *imageCreateInfoPNext); +angle::CallCapture CaptureTexStorageMemFlags2DMultisampleANGLE(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLsizei samples, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLboolean fixedSampleLocations, + MemoryObjectID memoryPacked, + GLuint64 offset, + GLbitfield createFlags, + GLbitfield usageFlags, + const void *imageCreateInfoPNext); +angle::CallCapture CaptureTexStorageMemFlags3DANGLE(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth, + MemoryObjectID memoryPacked, + GLuint64 offset, + GLbitfield createFlags, + GLbitfield usageFlags, + const void *imageCreateInfoPNext); +angle::CallCapture CaptureTexStorageMemFlags3DMultisampleANGLE(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLsizei samples, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedSampleLocations, + MemoryObjectID memoryPacked, + GLuint64 offset, + GLbitfield createFlags, + GLbitfield usageFlags, + const void *imageCreateInfoPNext); + +// GL_ANGLE_memory_object_fuchsia +angle::CallCapture CaptureImportMemoryZirconHandleANGLE(const State &glState, + bool isCallValid, + MemoryObjectID memoryPacked, + GLuint64 size, + HandleType handleTypePacked, + GLuint handle); + +// GL_ANGLE_multi_draw +angle::CallCapture CaptureMultiDrawArraysANGLE(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLint *firsts, + const GLsizei *counts, + GLsizei drawcount); +angle::CallCapture CaptureMultiDrawArraysInstancedANGLE(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLint *firsts, + const GLsizei *counts, + const GLsizei *instanceCounts, + GLsizei drawcount); +angle::CallCapture CaptureMultiDrawElementsANGLE(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLsizei *counts, + DrawElementsType typePacked, + const GLvoid *const *indices, + GLsizei drawcount); +angle::CallCapture CaptureMultiDrawElementsInstancedANGLE(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLsizei *counts, + DrawElementsType typePacked, + const GLvoid *const *indices, + const GLsizei *instanceCounts, + GLsizei drawcount); + +// GL_ANGLE_pack_reverse_row_order + +// GL_ANGLE_program_binary + +// GL_ANGLE_provoking_vertex +angle::CallCapture CaptureProvokingVertexANGLE(const State &glState, + bool isCallValid, + ProvokingVertexConvention modePacked); + +// GL_ANGLE_request_extension +angle::CallCapture CaptureRequestExtensionANGLE(const State &glState, + bool isCallValid, + const GLchar *name); +angle::CallCapture CaptureDisableExtensionANGLE(const State &glState, + bool isCallValid, + const GLchar *name); + +// GL_ANGLE_robust_client_memory +angle::CallCapture CaptureGetBooleanvRobustANGLE(const State &glState, + bool isCallValid, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLboolean *params); +angle::CallCapture CaptureGetBufferParameterivRobustANGLE(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +angle::CallCapture CaptureGetFloatvRobustANGLE(const State &glState, + bool isCallValid, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params); +angle::CallCapture CaptureGetFramebufferAttachmentParameterivRobustANGLE(const State &glState, + bool isCallValid, + GLenum target, + GLenum attachment, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +angle::CallCapture CaptureGetIntegervRobustANGLE(const State &glState, + bool isCallValid, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *data); +angle::CallCapture CaptureGetProgramivRobustANGLE(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +angle::CallCapture CaptureGetRenderbufferParameterivRobustANGLE(const State &glState, + bool isCallValid, + GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +angle::CallCapture CaptureGetShaderivRobustANGLE(const State &glState, + bool isCallValid, + ShaderProgramID shaderPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +angle::CallCapture CaptureGetTexParameterfvRobustANGLE(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params); +angle::CallCapture CaptureGetTexParameterivRobustANGLE(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +angle::CallCapture CaptureGetUniformfvRobustANGLE(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + GLsizei *length, + GLfloat *params); +angle::CallCapture CaptureGetUniformivRobustANGLE(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + GLsizei *length, + GLint *params); +angle::CallCapture CaptureGetVertexAttribfvRobustANGLE(const State &glState, + bool isCallValid, + GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params); +angle::CallCapture CaptureGetVertexAttribivRobustANGLE(const State &glState, + bool isCallValid, + GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +angle::CallCapture CaptureGetVertexAttribPointervRobustANGLE(const State &glState, + bool isCallValid, + GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + void **pointer); +angle::CallCapture CaptureReadPixelsRobustANGLE(const State &glState, + bool isCallValid, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + GLsizei *length, + GLsizei *columns, + GLsizei *rows, + void *pixels); +angle::CallCapture CaptureTexImage2DRobustANGLE(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels); +angle::CallCapture CaptureTexParameterfvRobustANGLE(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLsizei bufSize, + const GLfloat *params); +angle::CallCapture CaptureTexParameterivRobustANGLE(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLsizei bufSize, + const GLint *params); +angle::CallCapture CaptureTexSubImage2DRobustANGLE(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels); +angle::CallCapture CaptureTexImage3DRobustANGLE(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels); +angle::CallCapture CaptureTexSubImage3DRobustANGLE(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels); +angle::CallCapture CaptureCompressedTexImage2DRobustANGLE(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + GLsizei dataSize, + const GLvoid *data); +angle::CallCapture CaptureCompressedTexSubImage2DRobustANGLE(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLsizei xoffset, + GLsizei yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + GLsizei dataSize, + const GLvoid *data); +angle::CallCapture CaptureCompressedTexImage3DRobustANGLE(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + GLsizei dataSize, + const GLvoid *data); +angle::CallCapture CaptureCompressedTexSubImage3DRobustANGLE(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + GLsizei dataSize, + const GLvoid *data); +angle::CallCapture CaptureGetQueryivRobustANGLE(const State &glState, + bool isCallValid, + QueryType targetPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +angle::CallCapture CaptureGetQueryObjectuivRobustANGLE(const State &glState, + bool isCallValid, + QueryID idPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params); +angle::CallCapture CaptureGetBufferPointervRobustANGLE(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + void **params); +angle::CallCapture CaptureGetIntegeri_vRobustANGLE(const State &glState, + bool isCallValid, + GLenum target, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint *data); +angle::CallCapture CaptureGetInternalformativRobustANGLE(const State &glState, + bool isCallValid, + GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +angle::CallCapture CaptureGetVertexAttribIivRobustANGLE(const State &glState, + bool isCallValid, + GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +angle::CallCapture CaptureGetVertexAttribIuivRobustANGLE(const State &glState, + bool isCallValid, + GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params); +angle::CallCapture CaptureGetUniformuivRobustANGLE(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + GLsizei *length, + GLuint *params); +angle::CallCapture CaptureGetActiveUniformBlockivRobustANGLE( + const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformBlockIndex uniformBlockIndexPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +angle::CallCapture CaptureGetInteger64vRobustANGLE(const State &glState, + bool isCallValid, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint64 *data); +angle::CallCapture CaptureGetInteger64i_vRobustANGLE(const State &glState, + bool isCallValid, + GLenum target, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint64 *data); +angle::CallCapture CaptureGetBufferParameteri64vRobustANGLE(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint64 *params); +angle::CallCapture CaptureSamplerParameterivRobustANGLE(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLuint pname, + GLsizei bufSize, + const GLint *param); +angle::CallCapture CaptureSamplerParameterfvRobustANGLE(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLsizei bufSize, + const GLfloat *param); +angle::CallCapture CaptureGetSamplerParameterivRobustANGLE(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +angle::CallCapture CaptureGetSamplerParameterfvRobustANGLE(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params); +angle::CallCapture CaptureGetFramebufferParameterivRobustANGLE(const State &glState, + bool isCallValid, + GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +angle::CallCapture CaptureGetProgramInterfaceivRobustANGLE(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum programInterface, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +angle::CallCapture CaptureGetBooleani_vRobustANGLE(const State &glState, + bool isCallValid, + GLenum target, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLboolean *data); +angle::CallCapture CaptureGetMultisamplefvRobustANGLE(const State &glState, + bool isCallValid, + GLenum pname, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLfloat *val); +angle::CallCapture CaptureGetTexLevelParameterivRobustANGLE(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +angle::CallCapture CaptureGetTexLevelParameterfvRobustANGLE(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params); +angle::CallCapture CaptureGetPointervRobustANGLERobustANGLE(const State &glState, + bool isCallValid, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + void **params); +angle::CallCapture CaptureReadnPixelsRobustANGLE(const State &glState, + bool isCallValid, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + GLsizei *length, + GLsizei *columns, + GLsizei *rows, + void *data); +angle::CallCapture CaptureGetnUniformfvRobustANGLE(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + GLsizei *length, + GLfloat *params); +angle::CallCapture CaptureGetnUniformivRobustANGLE(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + GLsizei *length, + GLint *params); +angle::CallCapture CaptureGetnUniformuivRobustANGLE(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + GLsizei *length, + GLuint *params); +angle::CallCapture CaptureTexParameterIivRobustANGLE(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLsizei bufSize, + const GLint *params); +angle::CallCapture CaptureTexParameterIuivRobustANGLE(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLsizei bufSize, + const GLuint *params); +angle::CallCapture CaptureGetTexParameterIivRobustANGLE(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +angle::CallCapture CaptureGetTexParameterIuivRobustANGLE(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params); +angle::CallCapture CaptureSamplerParameterIivRobustANGLE(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLsizei bufSize, + const GLint *param); +angle::CallCapture CaptureSamplerParameterIuivRobustANGLE(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLsizei bufSize, + const GLuint *param); +angle::CallCapture CaptureGetSamplerParameterIivRobustANGLE(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +angle::CallCapture CaptureGetSamplerParameterIuivRobustANGLE(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params); +angle::CallCapture CaptureGetQueryObjectivRobustANGLE(const State &glState, + bool isCallValid, + QueryID idPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +angle::CallCapture CaptureGetQueryObjecti64vRobustANGLE(const State &glState, + bool isCallValid, + QueryID idPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint64 *params); +angle::CallCapture CaptureGetQueryObjectui64vRobustANGLE(const State &glState, + bool isCallValid, + QueryID idPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint64 *params); + +// GL_ANGLE_robust_resource_initialization + +// GL_ANGLE_semaphore_fuchsia +angle::CallCapture CaptureImportSemaphoreZirconHandleANGLE(const State &glState, + bool isCallValid, + SemaphoreID semaphorePacked, + HandleType handleTypePacked, + GLuint handle); + +// GL_ANGLE_shader_pixel_local_storage +angle::CallCapture CaptureFramebufferMemorylessPixelLocalStorageANGLE(const State &glState, + bool isCallValid, + GLint plane, + GLenum internalformat); +angle::CallCapture CaptureFramebufferTexturePixelLocalStorageANGLE(const State &glState, + bool isCallValid, + GLint plane, + TextureID backingtexturePacked, + GLint level, + GLint layer); +angle::CallCapture CaptureBeginPixelLocalStorageANGLE(const State &glState, + bool isCallValid, + GLsizei planes, + const GLenum *loadops, + const void *cleardata); +angle::CallCapture CaptureEndPixelLocalStorageANGLE(const State &glState, bool isCallValid); +angle::CallCapture CapturePixelLocalStorageBarrierANGLE(const State &glState, bool isCallValid); + +// GL_ANGLE_texture_compression_dxt3 + +// GL_ANGLE_texture_compression_dxt5 + +// GL_ANGLE_texture_external_update +angle::CallCapture CaptureTexImage2DExternalANGLE(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type); +angle::CallCapture CaptureInvalidateTextureANGLE(const State &glState, + bool isCallValid, + TextureType targetPacked); + +// GL_ANGLE_texture_multisample +angle::CallCapture CaptureTexStorage2DMultisampleANGLE(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations); +angle::CallCapture CaptureGetMultisamplefvANGLE(const State &glState, + bool isCallValid, + GLenum pname, + GLuint index, + GLfloat *val); +angle::CallCapture CaptureSampleMaskiANGLE(const State &glState, + bool isCallValid, + GLuint maskNumber, + GLbitfield mask); + +// GL_ANGLE_texture_usage + +// GL_ANGLE_translated_shader_source +angle::CallCapture CaptureGetTranslatedShaderSourceANGLE(const State &glState, + bool isCallValid, + ShaderProgramID shaderPacked, + GLsizei bufSize, + GLsizei *length, + GLchar *source); + +// GL_ANGLE_vulkan_image +angle::CallCapture CaptureAcquireTexturesANGLE(const State &glState, + bool isCallValid, + GLuint numTextures, + const TextureID *texturesPacked, + const GLenum *layouts); +angle::CallCapture CaptureReleaseTexturesANGLE(const State &glState, + bool isCallValid, + GLuint numTextures, + const TextureID *texturesPacked, + GLenum *layouts); + +// GL_APPLE_clip_distance + +// GL_ARB_sync + +// GL_CHROMIUM_bind_uniform_location +angle::CallCapture CaptureBindUniformLocationCHROMIUM(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + const GLchar *name); + +// GL_CHROMIUM_copy_compressed_texture +angle::CallCapture CaptureCompressedCopyTextureCHROMIUM(const State &glState, + bool isCallValid, + TextureID sourceIdPacked, + TextureID destIdPacked); + +// GL_CHROMIUM_copy_texture +angle::CallCapture CaptureCopyTextureCHROMIUM(const State &glState, + bool isCallValid, + TextureID sourceIdPacked, + GLint sourceLevel, + TextureTarget destTargetPacked, + TextureID destIdPacked, + GLint destLevel, + GLint internalFormat, + GLenum destType, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha); +angle::CallCapture CaptureCopySubTextureCHROMIUM(const State &glState, + bool isCallValid, + TextureID sourceIdPacked, + GLint sourceLevel, + TextureTarget destTargetPacked, + TextureID destIdPacked, + GLint destLevel, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLint width, + GLint height, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha); + +// GL_CHROMIUM_framebuffer_mixed_samples +angle::CallCapture CaptureCoverageModulationCHROMIUM(const State &glState, + bool isCallValid, + GLenum components); + +// GL_CHROMIUM_lose_context +angle::CallCapture CaptureLoseContextCHROMIUM(const State &glState, + bool isCallValid, + GraphicsResetStatus currentPacked, + GraphicsResetStatus otherPacked); + +// GL_EXT_EGL_image_array + +// GL_EXT_EGL_image_storage +angle::CallCapture CaptureEGLImageTargetTexStorageEXT(const State &glState, + bool isCallValid, + GLenum target, + GLeglImageOES image, + const GLint *attrib_list); +angle::CallCapture CaptureEGLImageTargetTextureStorageEXT(const State &glState, + bool isCallValid, + GLuint texture, + GLeglImageOES image, + const GLint *attrib_list); + +// GL_EXT_YUV_target + +// GL_EXT_base_instance +angle::CallCapture CaptureDrawArraysInstancedBaseInstanceEXT(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLint first, + GLsizei count, + GLsizei instancecount, + GLuint baseinstance); +angle::CallCapture CaptureDrawElementsInstancedBaseInstanceEXT(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLsizei instancecount, + GLuint baseinstance); +angle::CallCapture CaptureDrawElementsInstancedBaseVertexBaseInstanceEXT( + const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLsizei instancecount, + GLint basevertex, + GLuint baseinstance); + +// GL_EXT_blend_func_extended +angle::CallCapture CaptureBindFragDataLocationEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLuint color, + const GLchar *name); +angle::CallCapture CaptureBindFragDataLocationIndexedEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLuint colorNumber, + GLuint index, + const GLchar *name); +angle::CallCapture CaptureGetFragDataIndexEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + const GLchar *name, + GLint returnValue); +angle::CallCapture CaptureGetProgramResourceLocationIndexEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum programInterface, + const GLchar *name, + GLint returnValue); + +// GL_EXT_blend_minmax + +// GL_EXT_buffer_storage +angle::CallCapture CaptureBufferStorageEXT(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLsizeiptr size, + const void *data, + GLbitfield flags); + +// GL_EXT_clip_control +angle::CallCapture CaptureClipControlEXT(const State &glState, + bool isCallValid, + GLenum origin, + GLenum depth); + +// GL_EXT_clip_cull_distance + +// GL_EXT_color_buffer_float + +// GL_EXT_color_buffer_half_float + +// GL_EXT_copy_image +angle::CallCapture CaptureCopyImageSubDataEXT(const State &glState, + bool isCallValid, + GLuint srcName, + GLenum srcTarget, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLuint dstName, + GLenum dstTarget, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth); + +// GL_EXT_debug_label +angle::CallCapture CaptureGetObjectLabelEXT(const State &glState, + bool isCallValid, + GLenum type, + GLuint object, + GLsizei bufSize, + GLsizei *length, + GLchar *label); +angle::CallCapture CaptureLabelObjectEXT(const State &glState, + bool isCallValid, + GLenum type, + GLuint object, + GLsizei length, + const GLchar *label); + +// GL_EXT_debug_marker +angle::CallCapture CaptureInsertEventMarkerEXT(const State &glState, + bool isCallValid, + GLsizei length, + const GLchar *marker); +angle::CallCapture CapturePopGroupMarkerEXT(const State &glState, bool isCallValid); +angle::CallCapture CapturePushGroupMarkerEXT(const State &glState, + bool isCallValid, + GLsizei length, + const GLchar *marker); + +// GL_EXT_discard_framebuffer +angle::CallCapture CaptureDiscardFramebufferEXT(const State &glState, + bool isCallValid, + GLenum target, + GLsizei numAttachments, + const GLenum *attachments); + +// GL_EXT_disjoint_timer_query +angle::CallCapture CaptureBeginQueryEXT(const State &glState, + bool isCallValid, + QueryType targetPacked, + QueryID idPacked); +angle::CallCapture CaptureDeleteQueriesEXT(const State &glState, + bool isCallValid, + GLsizei n, + const QueryID *idsPacked); +angle::CallCapture CaptureEndQueryEXT(const State &glState, + bool isCallValid, + QueryType targetPacked); +angle::CallCapture CaptureGenQueriesEXT(const State &glState, + bool isCallValid, + GLsizei n, + QueryID *idsPacked); +angle::CallCapture CaptureGetInteger64vEXT(const State &glState, + bool isCallValid, + GLenum pname, + GLint64 *data); +angle::CallCapture CaptureGetQueryObjecti64vEXT(const State &glState, + bool isCallValid, + QueryID idPacked, + GLenum pname, + GLint64 *params); +angle::CallCapture CaptureGetQueryObjectivEXT(const State &glState, + bool isCallValid, + QueryID idPacked, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetQueryObjectui64vEXT(const State &glState, + bool isCallValid, + QueryID idPacked, + GLenum pname, + GLuint64 *params); +angle::CallCapture CaptureGetQueryObjectuivEXT(const State &glState, + bool isCallValid, + QueryID idPacked, + GLenum pname, + GLuint *params); +angle::CallCapture CaptureGetQueryivEXT(const State &glState, + bool isCallValid, + QueryType targetPacked, + GLenum pname, + GLint *params); +angle::CallCapture CaptureIsQueryEXT(const State &glState, + bool isCallValid, + QueryID idPacked, + GLboolean returnValue); +angle::CallCapture CaptureQueryCounterEXT(const State &glState, + bool isCallValid, + QueryID idPacked, + QueryType targetPacked); + +// GL_EXT_draw_buffers +angle::CallCapture CaptureDrawBuffersEXT(const State &glState, + bool isCallValid, + GLsizei n, + const GLenum *bufs); + +// GL_EXT_draw_buffers_indexed +angle::CallCapture CaptureBlendEquationSeparateiEXT(const State &glState, + bool isCallValid, + GLuint buf, + GLenum modeRGB, + GLenum modeAlpha); +angle::CallCapture CaptureBlendEquationiEXT(const State &glState, + bool isCallValid, + GLuint buf, + GLenum mode); +angle::CallCapture CaptureBlendFuncSeparateiEXT(const State &glState, + bool isCallValid, + GLuint buf, + GLenum srcRGB, + GLenum dstRGB, + GLenum srcAlpha, + GLenum dstAlpha); +angle::CallCapture CaptureBlendFunciEXT(const State &glState, + bool isCallValid, + GLuint buf, + GLenum src, + GLenum dst); +angle::CallCapture CaptureColorMaskiEXT(const State &glState, + bool isCallValid, + GLuint index, + GLboolean r, + GLboolean g, + GLboolean b, + GLboolean a); +angle::CallCapture CaptureDisableiEXT(const State &glState, + bool isCallValid, + GLenum target, + GLuint index); +angle::CallCapture CaptureEnableiEXT(const State &glState, + bool isCallValid, + GLenum target, + GLuint index); +angle::CallCapture CaptureIsEnablediEXT(const State &glState, + bool isCallValid, + GLenum target, + GLuint index, + GLboolean returnValue); + +// GL_EXT_draw_elements_base_vertex +angle::CallCapture CaptureDrawElementsBaseVertexEXT(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLint basevertex); +angle::CallCapture CaptureDrawElementsInstancedBaseVertexEXT(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLsizei instancecount, + GLint basevertex); +angle::CallCapture CaptureDrawRangeElementsBaseVertexEXT(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLuint start, + GLuint end, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLint basevertex); +angle::CallCapture CaptureMultiDrawElementsBaseVertexEXT(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLsizei *count, + DrawElementsType typePacked, + const void *const *indices, + GLsizei drawcount, + const GLint *basevertex); + +// GL_EXT_external_buffer +angle::CallCapture CaptureBufferStorageExternalEXT(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLintptr offset, + GLsizeiptr size, + GLeglClientBufferEXT clientBuffer, + GLbitfield flags); +angle::CallCapture CaptureNamedBufferStorageExternalEXT(const State &glState, + bool isCallValid, + GLuint buffer, + GLintptr offset, + GLsizeiptr size, + GLeglClientBufferEXT clientBuffer, + GLbitfield flags); + +// GL_EXT_float_blend + +// GL_EXT_geometry_shader +angle::CallCapture CaptureFramebufferTextureEXT(const State &glState, + bool isCallValid, + GLenum target, + GLenum attachment, + TextureID texturePacked, + GLint level); + +// GL_EXT_gpu_shader5 + +// GL_EXT_instanced_arrays +angle::CallCapture CaptureDrawArraysInstancedEXT(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLint start, + GLsizei count, + GLsizei primcount); +angle::CallCapture CaptureDrawElementsInstancedEXT(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLsizei primcount); +angle::CallCapture CaptureVertexAttribDivisorEXT(const State &glState, + bool isCallValid, + GLuint index, + GLuint divisor); + +// GL_EXT_map_buffer_range +angle::CallCapture CaptureFlushMappedBufferRangeEXT(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLintptr offset, + GLsizeiptr length); +angle::CallCapture CaptureMapBufferRangeEXT(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLintptr offset, + GLsizeiptr length, + GLbitfield access, + void *returnValue); + +// GL_EXT_memory_object +angle::CallCapture CaptureBufferStorageMemEXT(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLsizeiptr size, + MemoryObjectID memoryPacked, + GLuint64 offset); +angle::CallCapture CaptureCreateMemoryObjectsEXT(const State &glState, + bool isCallValid, + GLsizei n, + MemoryObjectID *memoryObjectsPacked); +angle::CallCapture CaptureDeleteMemoryObjectsEXT(const State &glState, + bool isCallValid, + GLsizei n, + const MemoryObjectID *memoryObjectsPacked); +angle::CallCapture CaptureGetMemoryObjectParameterivEXT(const State &glState, + bool isCallValid, + MemoryObjectID memoryObjectPacked, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetUnsignedBytevEXT(const State &glState, + bool isCallValid, + GLenum pname, + GLubyte *data); +angle::CallCapture CaptureGetUnsignedBytei_vEXT(const State &glState, + bool isCallValid, + GLenum target, + GLuint index, + GLubyte *data); +angle::CallCapture CaptureIsMemoryObjectEXT(const State &glState, + bool isCallValid, + MemoryObjectID memoryObjectPacked, + GLboolean returnValue); +angle::CallCapture CaptureMemoryObjectParameterivEXT(const State &glState, + bool isCallValid, + MemoryObjectID memoryObjectPacked, + GLenum pname, + const GLint *params); +angle::CallCapture CaptureTexStorageMem2DEXT(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height, + MemoryObjectID memoryPacked, + GLuint64 offset); +angle::CallCapture CaptureTexStorageMem2DMultisampleEXT(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLsizei samples, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLboolean fixedSampleLocations, + MemoryObjectID memoryPacked, + GLuint64 offset); +angle::CallCapture CaptureTexStorageMem3DEXT(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth, + MemoryObjectID memoryPacked, + GLuint64 offset); +angle::CallCapture CaptureTexStorageMem3DMultisampleEXT(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLsizei samples, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedSampleLocations, + MemoryObjectID memoryPacked, + GLuint64 offset); + +// GL_EXT_memory_object_fd +angle::CallCapture CaptureImportMemoryFdEXT(const State &glState, + bool isCallValid, + MemoryObjectID memoryPacked, + GLuint64 size, + HandleType handleTypePacked, + GLint fd); + +// GL_EXT_multi_draw_indirect +angle::CallCapture CaptureMultiDrawArraysIndirectEXT(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const void *indirect, + GLsizei drawcount, + GLsizei stride); +angle::CallCapture CaptureMultiDrawElementsIndirectEXT(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + DrawElementsType typePacked, + const void *indirect, + GLsizei drawcount, + GLsizei stride); + +// GL_EXT_multisampled_render_to_texture +angle::CallCapture CaptureFramebufferTexture2DMultisampleEXT(const State &glState, + bool isCallValid, + GLenum target, + GLenum attachment, + TextureTarget textargetPacked, + TextureID texturePacked, + GLint level, + GLsizei samples); +angle::CallCapture CaptureRenderbufferStorageMultisampleEXT(const State &glState, + bool isCallValid, + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height); + +// GL_EXT_multisampled_render_to_texture2 + +// GL_EXT_occlusion_query_boolean + +// GL_EXT_primitive_bounding_box +angle::CallCapture CapturePrimitiveBoundingBoxEXT(const State &glState, + bool isCallValid, + GLfloat minX, + GLfloat minY, + GLfloat minZ, + GLfloat minW, + GLfloat maxX, + GLfloat maxY, + GLfloat maxZ, + GLfloat maxW); + +// GL_EXT_protected_textures + +// GL_EXT_pvrtc_sRGB + +// GL_EXT_read_format_bgra + +// GL_EXT_robustness +angle::CallCapture CaptureGetGraphicsResetStatusEXT(const State &glState, + bool isCallValid, + GLenum returnValue); +angle::CallCapture CaptureGetnUniformfvEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + GLfloat *params); +angle::CallCapture CaptureGetnUniformivEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + GLint *params); +angle::CallCapture CaptureReadnPixelsEXT(const State &glState, + bool isCallValid, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + void *data); + +// GL_EXT_sRGB + +// GL_EXT_sRGB_write_control + +// GL_EXT_semaphore +angle::CallCapture CaptureDeleteSemaphoresEXT(const State &glState, + bool isCallValid, + GLsizei n, + const SemaphoreID *semaphoresPacked); +angle::CallCapture CaptureGenSemaphoresEXT(const State &glState, + bool isCallValid, + GLsizei n, + SemaphoreID *semaphoresPacked); +angle::CallCapture CaptureGetSemaphoreParameterui64vEXT(const State &glState, + bool isCallValid, + SemaphoreID semaphorePacked, + GLenum pname, + GLuint64 *params); +angle::CallCapture CaptureIsSemaphoreEXT(const State &glState, + bool isCallValid, + SemaphoreID semaphorePacked, + GLboolean returnValue); +angle::CallCapture CaptureSemaphoreParameterui64vEXT(const State &glState, + bool isCallValid, + SemaphoreID semaphorePacked, + GLenum pname, + const GLuint64 *params); +angle::CallCapture CaptureSignalSemaphoreEXT(const State &glState, + bool isCallValid, + SemaphoreID semaphorePacked, + GLuint numBufferBarriers, + const BufferID *buffersPacked, + GLuint numTextureBarriers, + const TextureID *texturesPacked, + const GLenum *dstLayouts); +angle::CallCapture CaptureWaitSemaphoreEXT(const State &glState, + bool isCallValid, + SemaphoreID semaphorePacked, + GLuint numBufferBarriers, + const BufferID *buffersPacked, + GLuint numTextureBarriers, + const TextureID *texturesPacked, + const GLenum *srcLayouts); + +// GL_EXT_semaphore_fd +angle::CallCapture CaptureImportSemaphoreFdEXT(const State &glState, + bool isCallValid, + SemaphoreID semaphorePacked, + HandleType handleTypePacked, + GLint fd); + +// GL_EXT_separate_shader_objects +angle::CallCapture CaptureActiveShaderProgramEXT(const State &glState, + bool isCallValid, + ProgramPipelineID pipelinePacked, + ShaderProgramID programPacked); +angle::CallCapture CaptureBindProgramPipelineEXT(const State &glState, + bool isCallValid, + ProgramPipelineID pipelinePacked); +angle::CallCapture CaptureCreateShaderProgramvEXT(const State &glState, + bool isCallValid, + ShaderType typePacked, + GLsizei count, + const GLchar **strings, + GLuint returnValue); +angle::CallCapture CaptureDeleteProgramPipelinesEXT(const State &glState, + bool isCallValid, + GLsizei n, + const ProgramPipelineID *pipelinesPacked); +angle::CallCapture CaptureGenProgramPipelinesEXT(const State &glState, + bool isCallValid, + GLsizei n, + ProgramPipelineID *pipelinesPacked); +angle::CallCapture CaptureGetProgramPipelineInfoLogEXT(const State &glState, + bool isCallValid, + ProgramPipelineID pipelinePacked, + GLsizei bufSize, + GLsizei *length, + GLchar *infoLog); +angle::CallCapture CaptureGetProgramPipelineivEXT(const State &glState, + bool isCallValid, + ProgramPipelineID pipelinePacked, + GLenum pname, + GLint *params); +angle::CallCapture CaptureIsProgramPipelineEXT(const State &glState, + bool isCallValid, + ProgramPipelineID pipelinePacked, + GLboolean returnValue); +angle::CallCapture CaptureProgramParameteriEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum pname, + GLint value); +angle::CallCapture CaptureProgramUniform1fEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLfloat v0); +angle::CallCapture CaptureProgramUniform1fvEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value); +angle::CallCapture CaptureProgramUniform1iEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLint v0); +angle::CallCapture CaptureProgramUniform1ivEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value); +angle::CallCapture CaptureProgramUniform1uiEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLuint v0); +angle::CallCapture CaptureProgramUniform1uivEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value); +angle::CallCapture CaptureProgramUniform2fEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLfloat v0, + GLfloat v1); +angle::CallCapture CaptureProgramUniform2fvEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value); +angle::CallCapture CaptureProgramUniform2iEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLint v0, + GLint v1); +angle::CallCapture CaptureProgramUniform2ivEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value); +angle::CallCapture CaptureProgramUniform2uiEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLuint v0, + GLuint v1); +angle::CallCapture CaptureProgramUniform2uivEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value); +angle::CallCapture CaptureProgramUniform3fEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLfloat v0, + GLfloat v1, + GLfloat v2); +angle::CallCapture CaptureProgramUniform3fvEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value); +angle::CallCapture CaptureProgramUniform3iEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLint v0, + GLint v1, + GLint v2); +angle::CallCapture CaptureProgramUniform3ivEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value); +angle::CallCapture CaptureProgramUniform3uiEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLuint v0, + GLuint v1, + GLuint v2); +angle::CallCapture CaptureProgramUniform3uivEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value); +angle::CallCapture CaptureProgramUniform4fEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLfloat v0, + GLfloat v1, + GLfloat v2, + GLfloat v3); +angle::CallCapture CaptureProgramUniform4fvEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value); +angle::CallCapture CaptureProgramUniform4iEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLint v0, + GLint v1, + GLint v2, + GLint v3); +angle::CallCapture CaptureProgramUniform4ivEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value); +angle::CallCapture CaptureProgramUniform4uiEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3); +angle::CallCapture CaptureProgramUniform4uivEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value); +angle::CallCapture CaptureProgramUniformMatrix2fvEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +angle::CallCapture CaptureProgramUniformMatrix2x3fvEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +angle::CallCapture CaptureProgramUniformMatrix2x4fvEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +angle::CallCapture CaptureProgramUniformMatrix3fvEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +angle::CallCapture CaptureProgramUniformMatrix3x2fvEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +angle::CallCapture CaptureProgramUniformMatrix3x4fvEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +angle::CallCapture CaptureProgramUniformMatrix4fvEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +angle::CallCapture CaptureProgramUniformMatrix4x2fvEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +angle::CallCapture CaptureProgramUniformMatrix4x3fvEXT(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +angle::CallCapture CaptureUseProgramStagesEXT(const State &glState, + bool isCallValid, + ProgramPipelineID pipelinePacked, + GLbitfield stages, + ShaderProgramID programPacked); +angle::CallCapture CaptureValidateProgramPipelineEXT(const State &glState, + bool isCallValid, + ProgramPipelineID pipelinePacked); + +// GL_EXT_shader_framebuffer_fetch + +// GL_EXT_shader_framebuffer_fetch_non_coherent +angle::CallCapture CaptureFramebufferFetchBarrierEXT(const State &glState, bool isCallValid); + +// GL_EXT_shader_io_blocks + +// GL_EXT_shader_non_constant_global_initializers + +// GL_EXT_shader_texture_lod + +// GL_EXT_shadow_samplers + +// GL_EXT_tessellation_shader +angle::CallCapture CapturePatchParameteriEXT(const State &glState, + bool isCallValid, + GLenum pname, + GLint value); + +// GL_EXT_texture_border_clamp +angle::CallCapture CaptureGetSamplerParameterIivEXT(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetSamplerParameterIuivEXT(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLuint *params); +angle::CallCapture CaptureGetTexParameterIivEXT(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetTexParameterIuivEXT(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLuint *params); +angle::CallCapture CaptureSamplerParameterIivEXT(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + const GLint *param); +angle::CallCapture CaptureSamplerParameterIuivEXT(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + const GLuint *param); +angle::CallCapture CaptureTexParameterIivEXT(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + const GLint *params); +angle::CallCapture CaptureTexParameterIuivEXT(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + const GLuint *params); + +// GL_EXT_texture_buffer +angle::CallCapture CaptureTexBufferEXT(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum internalformat, + BufferID bufferPacked); +angle::CallCapture CaptureTexBufferRangeEXT(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum internalformat, + BufferID bufferPacked, + GLintptr offset, + GLsizeiptr size); + +// GL_EXT_texture_compression_bptc + +// GL_EXT_texture_compression_dxt1 + +// GL_EXT_texture_compression_rgtc + +// GL_EXT_texture_compression_s3tc + +// GL_EXT_texture_compression_s3tc_srgb + +// GL_EXT_texture_cube_map_array + +// GL_EXT_texture_filter_anisotropic + +// GL_EXT_texture_format_BGRA8888 + +// GL_EXT_texture_format_sRGB_override + +// GL_EXT_texture_norm16 + +// GL_EXT_texture_rg + +// GL_EXT_texture_sRGB_R8 + +// GL_EXT_texture_sRGB_RG8 + +// GL_EXT_texture_sRGB_decode + +// GL_EXT_texture_storage +angle::CallCapture CaptureTexStorage1DEXT(const State &glState, + bool isCallValid, + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width); +angle::CallCapture CaptureTexStorage2DEXT(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height); +angle::CallCapture CaptureTexStorage3DEXT(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth); + +// GL_EXT_texture_type_2_10_10_10_REV + +// GL_EXT_unpack_subimage + +// GL_IMG_texture_compression_pvrtc + +// GL_IMG_texture_compression_pvrtc2 + +// GL_KHR_blend_equation_advanced +angle::CallCapture CaptureBlendBarrierKHR(const State &glState, bool isCallValid); + +// GL_KHR_debug +angle::CallCapture CaptureDebugMessageCallbackKHR(const State &glState, + bool isCallValid, + GLDEBUGPROCKHR callback, + const void *userParam); +angle::CallCapture CaptureDebugMessageControlKHR(const State &glState, + bool isCallValid, + GLenum source, + GLenum type, + GLenum severity, + GLsizei count, + const GLuint *ids, + GLboolean enabled); +angle::CallCapture CaptureDebugMessageInsertKHR(const State &glState, + bool isCallValid, + GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar *buf); +angle::CallCapture CaptureGetDebugMessageLogKHR(const State &glState, + bool isCallValid, + GLuint count, + GLsizei bufSize, + GLenum *sources, + GLenum *types, + GLuint *ids, + GLenum *severities, + GLsizei *lengths, + GLchar *messageLog, + GLuint returnValue); +angle::CallCapture CaptureGetObjectLabelKHR(const State &glState, + bool isCallValid, + GLenum identifier, + GLuint name, + GLsizei bufSize, + GLsizei *length, + GLchar *label); +angle::CallCapture CaptureGetObjectPtrLabelKHR(const State &glState, + bool isCallValid, + const void *ptr, + GLsizei bufSize, + GLsizei *length, + GLchar *label); +angle::CallCapture CaptureGetPointervKHR(const State &glState, + bool isCallValid, + GLenum pname, + void **params); +angle::CallCapture CaptureObjectLabelKHR(const State &glState, + bool isCallValid, + GLenum identifier, + GLuint name, + GLsizei length, + const GLchar *label); +angle::CallCapture CaptureObjectPtrLabelKHR(const State &glState, + bool isCallValid, + const void *ptr, + GLsizei length, + const GLchar *label); +angle::CallCapture CapturePopDebugGroupKHR(const State &glState, bool isCallValid); +angle::CallCapture CapturePushDebugGroupKHR(const State &glState, + bool isCallValid, + GLenum source, + GLuint id, + GLsizei length, + const GLchar *message); + +// GL_KHR_no_error + +// GL_KHR_parallel_shader_compile +angle::CallCapture CaptureMaxShaderCompilerThreadsKHR(const State &glState, + bool isCallValid, + GLuint count); + +// GL_KHR_robust_buffer_access_behavior + +// GL_KHR_texture_compression_astc_hdr + +// GL_KHR_texture_compression_astc_ldr + +// GL_KHR_texture_compression_astc_sliced_3d + +// GL_MESA_framebuffer_flip_y +angle::CallCapture CaptureFramebufferParameteriMESA(const State &glState, + bool isCallValid, + GLenum target, + GLenum pname, + GLint param); +angle::CallCapture CaptureGetFramebufferParameterivMESA(const State &glState, + bool isCallValid, + GLenum target, + GLenum pname, + GLint *params); + +// GL_NV_fence +angle::CallCapture CaptureDeleteFencesNV(const State &glState, + bool isCallValid, + GLsizei n, + const FenceNVID *fencesPacked); +angle::CallCapture CaptureFinishFenceNV(const State &glState, + bool isCallValid, + FenceNVID fencePacked); +angle::CallCapture CaptureGenFencesNV(const State &glState, + bool isCallValid, + GLsizei n, + FenceNVID *fencesPacked); +angle::CallCapture CaptureGetFenceivNV(const State &glState, + bool isCallValid, + FenceNVID fencePacked, + GLenum pname, + GLint *params); +angle::CallCapture CaptureIsFenceNV(const State &glState, + bool isCallValid, + FenceNVID fencePacked, + GLboolean returnValue); +angle::CallCapture CaptureSetFenceNV(const State &glState, + bool isCallValid, + FenceNVID fencePacked, + GLenum condition); +angle::CallCapture CaptureTestFenceNV(const State &glState, + bool isCallValid, + FenceNVID fencePacked, + GLboolean returnValue); + +// GL_NV_framebuffer_blit +angle::CallCapture CaptureBlitFramebufferNV(const State &glState, + bool isCallValid, + GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter); + +// GL_NV_pixel_buffer_object + +// GL_NV_read_depth + +// GL_NV_read_depth_stencil + +// GL_NV_read_stencil + +// GL_NV_robustness_video_memory_purge + +// GL_NV_shader_noperspective_interpolation + +// GL_OES_EGL_image +angle::CallCapture CaptureEGLImageTargetRenderbufferStorageOES(const State &glState, + bool isCallValid, + GLenum target, + GLeglImageOES image); +angle::CallCapture CaptureEGLImageTargetTexture2DOES(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLeglImageOES image); + +// GL_OES_EGL_image_external + +// GL_OES_EGL_image_external_essl3 + +// GL_OES_compressed_ETC1_RGB8_texture + +// GL_OES_compressed_paletted_texture + +// GL_OES_copy_image +angle::CallCapture CaptureCopyImageSubDataOES(const State &glState, + bool isCallValid, + GLuint srcName, + GLenum srcTarget, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLuint dstName, + GLenum dstTarget, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth); + +// GL_OES_depth24 + +// GL_OES_depth32 + +// GL_OES_depth_texture + +// GL_OES_draw_buffers_indexed +angle::CallCapture CaptureBlendEquationSeparateiOES(const State &glState, + bool isCallValid, + GLuint buf, + GLenum modeRGB, + GLenum modeAlpha); +angle::CallCapture CaptureBlendEquationiOES(const State &glState, + bool isCallValid, + GLuint buf, + GLenum mode); +angle::CallCapture CaptureBlendFuncSeparateiOES(const State &glState, + bool isCallValid, + GLuint buf, + GLenum srcRGB, + GLenum dstRGB, + GLenum srcAlpha, + GLenum dstAlpha); +angle::CallCapture CaptureBlendFunciOES(const State &glState, + bool isCallValid, + GLuint buf, + GLenum src, + GLenum dst); +angle::CallCapture CaptureColorMaskiOES(const State &glState, + bool isCallValid, + GLuint index, + GLboolean r, + GLboolean g, + GLboolean b, + GLboolean a); +angle::CallCapture CaptureDisableiOES(const State &glState, + bool isCallValid, + GLenum target, + GLuint index); +angle::CallCapture CaptureEnableiOES(const State &glState, + bool isCallValid, + GLenum target, + GLuint index); +angle::CallCapture CaptureIsEnablediOES(const State &glState, + bool isCallValid, + GLenum target, + GLuint index, + GLboolean returnValue); + +// GL_OES_draw_elements_base_vertex +angle::CallCapture CaptureDrawElementsBaseVertexOES(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLint basevertex); +angle::CallCapture CaptureDrawElementsInstancedBaseVertexOES(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLsizei instancecount, + GLint basevertex); +angle::CallCapture CaptureDrawRangeElementsBaseVertexOES(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLuint start, + GLuint end, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLint basevertex); + +// GL_OES_draw_texture +angle::CallCapture CaptureDrawTexfOES(const State &glState, + bool isCallValid, + GLfloat x, + GLfloat y, + GLfloat z, + GLfloat width, + GLfloat height); +angle::CallCapture CaptureDrawTexfvOES(const State &glState, + bool isCallValid, + const GLfloat *coords); +angle::CallCapture CaptureDrawTexiOES(const State &glState, + bool isCallValid, + GLint x, + GLint y, + GLint z, + GLint width, + GLint height); +angle::CallCapture CaptureDrawTexivOES(const State &glState, bool isCallValid, const GLint *coords); +angle::CallCapture CaptureDrawTexsOES(const State &glState, + bool isCallValid, + GLshort x, + GLshort y, + GLshort z, + GLshort width, + GLshort height); +angle::CallCapture CaptureDrawTexsvOES(const State &glState, + bool isCallValid, + const GLshort *coords); +angle::CallCapture CaptureDrawTexxOES(const State &glState, + bool isCallValid, + GLfixed x, + GLfixed y, + GLfixed z, + GLfixed width, + GLfixed height); +angle::CallCapture CaptureDrawTexxvOES(const State &glState, + bool isCallValid, + const GLfixed *coords); + +// GL_OES_element_index_uint + +// GL_OES_fbo_render_mipmap + +// GL_OES_framebuffer_object +angle::CallCapture CaptureBindFramebufferOES(const State &glState, + bool isCallValid, + GLenum target, + FramebufferID framebufferPacked); +angle::CallCapture CaptureBindRenderbufferOES(const State &glState, + bool isCallValid, + GLenum target, + RenderbufferID renderbufferPacked); +angle::CallCapture CaptureCheckFramebufferStatusOES(const State &glState, + bool isCallValid, + GLenum target, + GLenum returnValue); +angle::CallCapture CaptureDeleteFramebuffersOES(const State &glState, + bool isCallValid, + GLsizei n, + const FramebufferID *framebuffersPacked); +angle::CallCapture CaptureDeleteRenderbuffersOES(const State &glState, + bool isCallValid, + GLsizei n, + const RenderbufferID *renderbuffersPacked); +angle::CallCapture CaptureFramebufferRenderbufferOES(const State &glState, + bool isCallValid, + GLenum target, + GLenum attachment, + GLenum renderbuffertarget, + RenderbufferID renderbufferPacked); +angle::CallCapture CaptureFramebufferTexture2DOES(const State &glState, + bool isCallValid, + GLenum target, + GLenum attachment, + TextureTarget textargetPacked, + TextureID texturePacked, + GLint level); +angle::CallCapture CaptureGenFramebuffersOES(const State &glState, + bool isCallValid, + GLsizei n, + FramebufferID *framebuffersPacked); +angle::CallCapture CaptureGenRenderbuffersOES(const State &glState, + bool isCallValid, + GLsizei n, + RenderbufferID *renderbuffersPacked); +angle::CallCapture CaptureGenerateMipmapOES(const State &glState, + bool isCallValid, + TextureType targetPacked); +angle::CallCapture CaptureGetFramebufferAttachmentParameterivOES(const State &glState, + bool isCallValid, + GLenum target, + GLenum attachment, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetRenderbufferParameterivOES(const State &glState, + bool isCallValid, + GLenum target, + GLenum pname, + GLint *params); +angle::CallCapture CaptureIsFramebufferOES(const State &glState, + bool isCallValid, + FramebufferID framebufferPacked, + GLboolean returnValue); +angle::CallCapture CaptureIsRenderbufferOES(const State &glState, + bool isCallValid, + RenderbufferID renderbufferPacked, + GLboolean returnValue); +angle::CallCapture CaptureRenderbufferStorageOES(const State &glState, + bool isCallValid, + GLenum target, + GLenum internalformat, + GLsizei width, + GLsizei height); + +// GL_OES_geometry_shader +angle::CallCapture CaptureFramebufferTextureOES(const State &glState, + bool isCallValid, + GLenum target, + GLenum attachment, + TextureID texturePacked, + GLint level); + +// GL_OES_get_program_binary +angle::CallCapture CaptureGetProgramBinaryOES(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLsizei bufSize, + GLsizei *length, + GLenum *binaryFormat, + void *binary); +angle::CallCapture CaptureProgramBinaryOES(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum binaryFormat, + const void *binary, + GLint length); + +// GL_OES_mapbuffer +angle::CallCapture CaptureGetBufferPointervOES(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLenum pname, + void **params); +angle::CallCapture CaptureMapBufferOES(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLenum access, + void *returnValue); +angle::CallCapture CaptureUnmapBufferOES(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLboolean returnValue); + +// GL_OES_matrix_palette +angle::CallCapture CaptureCurrentPaletteMatrixOES(const State &glState, + bool isCallValid, + GLuint matrixpaletteindex); +angle::CallCapture CaptureLoadPaletteFromModelViewMatrixOES(const State &glState, bool isCallValid); +angle::CallCapture CaptureMatrixIndexPointerOES(const State &glState, + bool isCallValid, + GLint size, + GLenum type, + GLsizei stride, + const void *pointer); +angle::CallCapture CaptureWeightPointerOES(const State &glState, + bool isCallValid, + GLint size, + GLenum type, + GLsizei stride, + const void *pointer); + +// GL_OES_packed_depth_stencil + +// GL_OES_point_size_array +angle::CallCapture CapturePointSizePointerOES(const State &glState, + bool isCallValid, + VertexAttribType typePacked, + GLsizei stride, + const void *pointer); + +// GL_OES_point_sprite + +// GL_OES_primitive_bounding_box +angle::CallCapture CapturePrimitiveBoundingBoxOES(const State &glState, + bool isCallValid, + GLfloat minX, + GLfloat minY, + GLfloat minZ, + GLfloat minW, + GLfloat maxX, + GLfloat maxY, + GLfloat maxZ, + GLfloat maxW); + +// GL_OES_query_matrix +angle::CallCapture CaptureQueryMatrixxOES(const State &glState, + bool isCallValid, + GLfixed *mantissa, + GLint *exponent, + GLbitfield returnValue); + +// GL_OES_rgb8_rgba8 + +// GL_OES_sample_shading +angle::CallCapture CaptureMinSampleShadingOES(const State &glState, + bool isCallValid, + GLfloat value); + +// GL_OES_sample_variables + +// GL_OES_shader_image_atomic + +// GL_OES_shader_io_blocks + +// GL_OES_shader_multisample_interpolation + +// GL_OES_standard_derivatives + +// GL_OES_surfaceless_context + +// GL_OES_texture_3D +angle::CallCapture CaptureCompressedTexImage3DOES(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + const void *data); +angle::CallCapture CaptureCompressedTexSubImage3DOES(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const void *data); +angle::CallCapture CaptureCopyTexSubImage3DOES(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height); +angle::CallCapture CaptureFramebufferTexture3DOES(const State &glState, + bool isCallValid, + GLenum target, + GLenum attachment, + TextureTarget textargetPacked, + TextureID texturePacked, + GLint level, + GLint zoffset); +angle::CallCapture CaptureTexImage3DOES(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const void *pixels); +angle::CallCapture CaptureTexSubImage3DOES(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *pixels); + +// GL_OES_texture_border_clamp +angle::CallCapture CaptureGetSamplerParameterIivOES(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetSamplerParameterIuivOES(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLuint *params); +angle::CallCapture CaptureGetTexParameterIivOES(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetTexParameterIuivOES(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLuint *params); +angle::CallCapture CaptureSamplerParameterIivOES(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + const GLint *param); +angle::CallCapture CaptureSamplerParameterIuivOES(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + const GLuint *param); +angle::CallCapture CaptureTexParameterIivOES(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + const GLint *params); +angle::CallCapture CaptureTexParameterIuivOES(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + const GLuint *params); + +// GL_OES_texture_buffer +angle::CallCapture CaptureTexBufferOES(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum internalformat, + BufferID bufferPacked); +angle::CallCapture CaptureTexBufferRangeOES(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum internalformat, + BufferID bufferPacked, + GLintptr offset, + GLsizeiptr size); + +// GL_OES_texture_compression_astc + +// GL_OES_texture_cube_map +angle::CallCapture CaptureGetTexGenfvOES(const State &glState, + bool isCallValid, + GLenum coord, + GLenum pname, + GLfloat *params); +angle::CallCapture CaptureGetTexGenivOES(const State &glState, + bool isCallValid, + GLenum coord, + GLenum pname, + GLint *params); +angle::CallCapture CaptureGetTexGenxvOES(const State &glState, + bool isCallValid, + GLenum coord, + GLenum pname, + GLfixed *params); +angle::CallCapture CaptureTexGenfOES(const State &glState, + bool isCallValid, + GLenum coord, + GLenum pname, + GLfloat param); +angle::CallCapture CaptureTexGenfvOES(const State &glState, + bool isCallValid, + GLenum coord, + GLenum pname, + const GLfloat *params); +angle::CallCapture CaptureTexGeniOES(const State &glState, + bool isCallValid, + GLenum coord, + GLenum pname, + GLint param); +angle::CallCapture CaptureTexGenivOES(const State &glState, + bool isCallValid, + GLenum coord, + GLenum pname, + const GLint *params); +angle::CallCapture CaptureTexGenxOES(const State &glState, + bool isCallValid, + GLenum coord, + GLenum pname, + GLfixed param); +angle::CallCapture CaptureTexGenxvOES(const State &glState, + bool isCallValid, + GLenum coord, + GLenum pname, + const GLfixed *params); + +// GL_OES_texture_cube_map_array + +// GL_OES_texture_float + +// GL_OES_texture_float_linear + +// GL_OES_texture_half_float + +// GL_OES_texture_half_float_linear + +// GL_OES_texture_npot + +// GL_OES_texture_stencil8 + +// GL_OES_texture_storage_multisample_2d_array +angle::CallCapture CaptureTexStorage3DMultisampleOES(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedsamplelocations); + +// GL_OES_vertex_array_object +angle::CallCapture CaptureBindVertexArrayOES(const State &glState, + bool isCallValid, + VertexArrayID arrayPacked); +angle::CallCapture CaptureDeleteVertexArraysOES(const State &glState, + bool isCallValid, + GLsizei n, + const VertexArrayID *arraysPacked); +angle::CallCapture CaptureGenVertexArraysOES(const State &glState, + bool isCallValid, + GLsizei n, + VertexArrayID *arraysPacked); +angle::CallCapture CaptureIsVertexArrayOES(const State &glState, + bool isCallValid, + VertexArrayID arrayPacked, + GLboolean returnValue); + +// GL_OES_vertex_half_float + +// GL_OES_vertex_type_10_10_10_2 + +// GL_OVR_multiview +angle::CallCapture CaptureFramebufferTextureMultiviewOVR(const State &glState, + bool isCallValid, + GLenum target, + GLenum attachment, + TextureID texturePacked, + GLint level, + GLint baseViewIndex, + GLsizei numViews); + +// GL_OVR_multiview2 + +// GL_QCOM_shading_rate +angle::CallCapture CaptureShadingRateQCOM(const State &glState, bool isCallValid, GLenum rate); + +// Parameter Captures + +void CaptureDeletePerfMonitorsAMD_monitors(const State &glState, + bool isCallValid, + GLsizei n, + GLuint *monitors, + angle::ParamCapture *paramCapture); +void CaptureGenPerfMonitorsAMD_monitors(const State &glState, + bool isCallValid, + GLsizei n, + GLuint *monitors, + angle::ParamCapture *paramCapture); +void CaptureGetPerfMonitorCounterDataAMD_data(const State &glState, + bool isCallValid, + GLuint monitor, + GLenum pname, + GLsizei dataSize, + GLuint *data, + GLint *bytesWritten, + angle::ParamCapture *paramCapture); +void CaptureGetPerfMonitorCounterDataAMD_bytesWritten(const State &glState, + bool isCallValid, + GLuint monitor, + GLenum pname, + GLsizei dataSize, + GLuint *data, + GLint *bytesWritten, + angle::ParamCapture *paramCapture); +void CaptureGetPerfMonitorCounterInfoAMD_data(const State &glState, + bool isCallValid, + GLuint group, + GLuint counter, + GLenum pname, + void *data, + angle::ParamCapture *paramCapture); +void CaptureGetPerfMonitorCounterStringAMD_length(const State &glState, + bool isCallValid, + GLuint group, + GLuint counter, + GLsizei bufSize, + GLsizei *length, + GLchar *counterString, + angle::ParamCapture *paramCapture); +void CaptureGetPerfMonitorCounterStringAMD_counterString(const State &glState, + bool isCallValid, + GLuint group, + GLuint counter, + GLsizei bufSize, + GLsizei *length, + GLchar *counterString, + angle::ParamCapture *paramCapture); +void CaptureGetPerfMonitorCountersAMD_numCounters(const State &glState, + bool isCallValid, + GLuint group, + GLint *numCounters, + GLint *maxActiveCounters, + GLsizei counterSize, + GLuint *counters, + angle::ParamCapture *paramCapture); +void CaptureGetPerfMonitorCountersAMD_maxActiveCounters(const State &glState, + bool isCallValid, + GLuint group, + GLint *numCounters, + GLint *maxActiveCounters, + GLsizei counterSize, + GLuint *counters, + angle::ParamCapture *paramCapture); +void CaptureGetPerfMonitorCountersAMD_counters(const State &glState, + bool isCallValid, + GLuint group, + GLint *numCounters, + GLint *maxActiveCounters, + GLsizei counterSize, + GLuint *counters, + angle::ParamCapture *paramCapture); +void CaptureGetPerfMonitorGroupStringAMD_length(const State &glState, + bool isCallValid, + GLuint group, + GLsizei bufSize, + GLsizei *length, + GLchar *groupString, + angle::ParamCapture *paramCapture); +void CaptureGetPerfMonitorGroupStringAMD_groupString(const State &glState, + bool isCallValid, + GLuint group, + GLsizei bufSize, + GLsizei *length, + GLchar *groupString, + angle::ParamCapture *paramCapture); +void CaptureGetPerfMonitorGroupsAMD_numGroups(const State &glState, + bool isCallValid, + GLint *numGroups, + GLsizei groupsSize, + GLuint *groups, + angle::ParamCapture *paramCapture); +void CaptureGetPerfMonitorGroupsAMD_groups(const State &glState, + bool isCallValid, + GLint *numGroups, + GLsizei groupsSize, + GLuint *groups, + angle::ParamCapture *paramCapture); +void CaptureSelectPerfMonitorCountersAMD_counterList(const State &glState, + bool isCallValid, + GLuint monitor, + GLboolean enable, + GLuint group, + GLint numCounters, + GLuint *counterList, + angle::ParamCapture *paramCapture); +void CaptureDrawElementsInstancedBaseVertexBaseInstanceANGLE_indices( + const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const GLvoid *indices, + GLsizei instanceCount, + GLint baseVertex, + GLuint baseInstance, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawArraysInstancedBaseInstanceANGLE_firsts(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLint *firsts, + const GLsizei *counts, + const GLsizei *instanceCounts, + const GLuint *baseInstances, + GLsizei drawcount, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawArraysInstancedBaseInstanceANGLE_counts(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLint *firsts, + const GLsizei *counts, + const GLsizei *instanceCounts, + const GLuint *baseInstances, + GLsizei drawcount, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawArraysInstancedBaseInstanceANGLE_instanceCounts( + const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLint *firsts, + const GLsizei *counts, + const GLsizei *instanceCounts, + const GLuint *baseInstances, + GLsizei drawcount, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawArraysInstancedBaseInstanceANGLE_baseInstances( + const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLint *firsts, + const GLsizei *counts, + const GLsizei *instanceCounts, + const GLuint *baseInstances, + GLsizei drawcount, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE_counts( + const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLsizei *counts, + DrawElementsType typePacked, + const GLvoid *const *indices, + const GLsizei *instanceCounts, + const GLint *baseVertices, + const GLuint *baseInstances, + GLsizei drawcount, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE_indices( + const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLsizei *counts, + DrawElementsType typePacked, + const GLvoid *const *indices, + const GLsizei *instanceCounts, + const GLint *baseVertices, + const GLuint *baseInstances, + GLsizei drawcount, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE_instanceCounts( + const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLsizei *counts, + DrawElementsType typePacked, + const GLvoid *const *indices, + const GLsizei *instanceCounts, + const GLint *baseVertices, + const GLuint *baseInstances, + GLsizei drawcount, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE_baseVertices( + const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLsizei *counts, + DrawElementsType typePacked, + const GLvoid *const *indices, + const GLsizei *instanceCounts, + const GLint *baseVertices, + const GLuint *baseInstances, + GLsizei drawcount, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE_baseInstances( + const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLsizei *counts, + DrawElementsType typePacked, + const GLvoid *const *indices, + const GLsizei *instanceCounts, + const GLint *baseVertices, + const GLuint *baseInstances, + GLsizei drawcount, + angle::ParamCapture *paramCapture); +void CaptureGetTexImageANGLE_pixels(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLenum format, + GLenum type, + void *pixels, + angle::ParamCapture *paramCapture); +void CaptureGetCompressedTexImageANGLE_pixels(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + void *pixels, + angle::ParamCapture *paramCapture); +void CaptureGetRenderbufferImageANGLE_pixels(const State &glState, + bool isCallValid, + GLenum target, + GLenum format, + GLenum type, + void *pixels, + angle::ParamCapture *paramCapture); +void CaptureGetTexLevelParameterivANGLE_params(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexLevelParameterfvANGLE_params(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLenum pname, + GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureDrawElementsInstancedANGLE_indices(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLsizei primcount, + angle::ParamCapture *paramCapture); +void CaptureTexStorageMemFlags2DANGLE_imageCreateInfoPNext(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height, + MemoryObjectID memoryPacked, + GLuint64 offset, + GLbitfield createFlags, + GLbitfield usageFlags, + const void *imageCreateInfoPNext, + angle::ParamCapture *paramCapture); +void CaptureTexStorageMemFlags2DMultisampleANGLE_imageCreateInfoPNext( + const State &glState, + bool isCallValid, + TextureType targetPacked, + GLsizei samples, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLboolean fixedSampleLocations, + MemoryObjectID memoryPacked, + GLuint64 offset, + GLbitfield createFlags, + GLbitfield usageFlags, + const void *imageCreateInfoPNext, + angle::ParamCapture *paramCapture); +void CaptureTexStorageMemFlags3DANGLE_imageCreateInfoPNext(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth, + MemoryObjectID memoryPacked, + GLuint64 offset, + GLbitfield createFlags, + GLbitfield usageFlags, + const void *imageCreateInfoPNext, + angle::ParamCapture *paramCapture); +void CaptureTexStorageMemFlags3DMultisampleANGLE_imageCreateInfoPNext( + const State &glState, + bool isCallValid, + TextureType targetPacked, + GLsizei samples, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedSampleLocations, + MemoryObjectID memoryPacked, + GLuint64 offset, + GLbitfield createFlags, + GLbitfield usageFlags, + const void *imageCreateInfoPNext, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawArraysANGLE_firsts(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLint *firsts, + const GLsizei *counts, + GLsizei drawcount, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawArraysANGLE_counts(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLint *firsts, + const GLsizei *counts, + GLsizei drawcount, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawArraysInstancedANGLE_firsts(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLint *firsts, + const GLsizei *counts, + const GLsizei *instanceCounts, + GLsizei drawcount, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawArraysInstancedANGLE_counts(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLint *firsts, + const GLsizei *counts, + const GLsizei *instanceCounts, + GLsizei drawcount, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawArraysInstancedANGLE_instanceCounts(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLint *firsts, + const GLsizei *counts, + const GLsizei *instanceCounts, + GLsizei drawcount, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawElementsANGLE_counts(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLsizei *counts, + DrawElementsType typePacked, + const GLvoid *const *indices, + GLsizei drawcount, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawElementsANGLE_indices(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLsizei *counts, + DrawElementsType typePacked, + const GLvoid *const *indices, + GLsizei drawcount, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawElementsInstancedANGLE_counts(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLsizei *counts, + DrawElementsType typePacked, + const GLvoid *const *indices, + const GLsizei *instanceCounts, + GLsizei drawcount, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawElementsInstancedANGLE_indices(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLsizei *counts, + DrawElementsType typePacked, + const GLvoid *const *indices, + const GLsizei *instanceCounts, + GLsizei drawcount, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawElementsInstancedANGLE_instanceCounts(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLsizei *counts, + DrawElementsType typePacked, + const GLvoid *const *indices, + const GLsizei *instanceCounts, + GLsizei drawcount, + angle::ParamCapture *paramCapture); +void CaptureRequestExtensionANGLE_name(const State &glState, + bool isCallValid, + const GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureDisableExtensionANGLE_name(const State &glState, + bool isCallValid, + const GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureGetBooleanvRobustANGLE_length(const State &glState, + bool isCallValid, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLboolean *params, + angle::ParamCapture *paramCapture); +void CaptureGetBooleanvRobustANGLE_params(const State &glState, + bool isCallValid, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLboolean *params, + angle::ParamCapture *paramCapture); +void CaptureGetBufferParameterivRobustANGLE_length(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetBufferParameterivRobustANGLE_params(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetFloatvRobustANGLE_length(const State &glState, + bool isCallValid, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureGetFloatvRobustANGLE_params(const State &glState, + bool isCallValid, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureGetFramebufferAttachmentParameterivRobustANGLE_length( + const State &glState, + bool isCallValid, + GLenum target, + GLenum attachment, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetFramebufferAttachmentParameterivRobustANGLE_params( + const State &glState, + bool isCallValid, + GLenum target, + GLenum attachment, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetIntegervRobustANGLE_length(const State &glState, + bool isCallValid, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *data, + angle::ParamCapture *paramCapture); +void CaptureGetIntegervRobustANGLE_data(const State &glState, + bool isCallValid, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *data, + angle::ParamCapture *paramCapture); +void CaptureGetProgramivRobustANGLE_length(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetProgramivRobustANGLE_params(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetRenderbufferParameterivRobustANGLE_length(const State &glState, + bool isCallValid, + GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetRenderbufferParameterivRobustANGLE_params(const State &glState, + bool isCallValid, + GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetShaderivRobustANGLE_length(const State &glState, + bool isCallValid, + ShaderProgramID shaderPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetShaderivRobustANGLE_params(const State &glState, + bool isCallValid, + ShaderProgramID shaderPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexParameterfvRobustANGLE_length(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexParameterfvRobustANGLE_params(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexParameterivRobustANGLE_length(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexParameterivRobustANGLE_params(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetUniformfvRobustANGLE_length(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + GLsizei *length, + GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureGetUniformfvRobustANGLE_params(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + GLsizei *length, + GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureGetUniformivRobustANGLE_length(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetUniformivRobustANGLE_params(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetVertexAttribfvRobustANGLE_length(const State &glState, + bool isCallValid, + GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureGetVertexAttribfvRobustANGLE_params(const State &glState, + bool isCallValid, + GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureGetVertexAttribivRobustANGLE_length(const State &glState, + bool isCallValid, + GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetVertexAttribivRobustANGLE_params(const State &glState, + bool isCallValid, + GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetVertexAttribPointervRobustANGLE_length(const State &glState, + bool isCallValid, + GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + void **pointer, + angle::ParamCapture *paramCapture); +void CaptureGetVertexAttribPointervRobustANGLE_pointer(const State &glState, + bool isCallValid, + GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + void **pointer, + angle::ParamCapture *paramCapture); +void CaptureReadPixelsRobustANGLE_length(const State &glState, + bool isCallValid, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + GLsizei *length, + GLsizei *columns, + GLsizei *rows, + void *pixels, + angle::ParamCapture *paramCapture); +void CaptureReadPixelsRobustANGLE_columns(const State &glState, + bool isCallValid, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + GLsizei *length, + GLsizei *columns, + GLsizei *rows, + void *pixels, + angle::ParamCapture *paramCapture); +void CaptureReadPixelsRobustANGLE_rows(const State &glState, + bool isCallValid, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + GLsizei *length, + GLsizei *columns, + GLsizei *rows, + void *pixels, + angle::ParamCapture *paramCapture); +void CaptureReadPixelsRobustANGLE_pixels(const State &glState, + bool isCallValid, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + GLsizei *length, + GLsizei *columns, + GLsizei *rows, + void *pixels, + angle::ParamCapture *paramCapture); +void CaptureTexImage2DRobustANGLE_pixels(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels, + angle::ParamCapture *paramCapture); +void CaptureTexParameterfvRobustANGLE_params(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLsizei bufSize, + const GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureTexParameterivRobustANGLE_params(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLsizei bufSize, + const GLint *params, + angle::ParamCapture *paramCapture); +void CaptureTexSubImage2DRobustANGLE_pixels(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels, + angle::ParamCapture *paramCapture); +void CaptureTexImage3DRobustANGLE_pixels(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels, + angle::ParamCapture *paramCapture); +void CaptureTexSubImage3DRobustANGLE_pixels(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels, + angle::ParamCapture *paramCapture); +void CaptureCompressedTexImage2DRobustANGLE_data(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + GLsizei dataSize, + const GLvoid *data, + angle::ParamCapture *paramCapture); +void CaptureCompressedTexSubImage2DRobustANGLE_data(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLsizei xoffset, + GLsizei yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + GLsizei dataSize, + const GLvoid *data, + angle::ParamCapture *paramCapture); +void CaptureCompressedTexImage3DRobustANGLE_data(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + GLsizei dataSize, + const GLvoid *data, + angle::ParamCapture *paramCapture); +void CaptureCompressedTexSubImage3DRobustANGLE_data(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + GLsizei dataSize, + const GLvoid *data, + angle::ParamCapture *paramCapture); +void CaptureGetQueryivRobustANGLE_length(const State &glState, + bool isCallValid, + QueryType targetPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetQueryivRobustANGLE_params(const State &glState, + bool isCallValid, + QueryType targetPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetQueryObjectuivRobustANGLE_length(const State &glState, + bool isCallValid, + QueryID idPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params, + angle::ParamCapture *paramCapture); +void CaptureGetQueryObjectuivRobustANGLE_params(const State &glState, + bool isCallValid, + QueryID idPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params, + angle::ParamCapture *paramCapture); +void CaptureGetBufferPointervRobustANGLE_length(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + void **params, + angle::ParamCapture *paramCapture); +void CaptureGetBufferPointervRobustANGLE_params(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + void **params, + angle::ParamCapture *paramCapture); +void CaptureGetIntegeri_vRobustANGLE_length(const State &glState, + bool isCallValid, + GLenum target, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint *data, + angle::ParamCapture *paramCapture); +void CaptureGetIntegeri_vRobustANGLE_data(const State &glState, + bool isCallValid, + GLenum target, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint *data, + angle::ParamCapture *paramCapture); +void CaptureGetInternalformativRobustANGLE_length(const State &glState, + bool isCallValid, + GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetInternalformativRobustANGLE_params(const State &glState, + bool isCallValid, + GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetVertexAttribIivRobustANGLE_length(const State &glState, + bool isCallValid, + GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetVertexAttribIivRobustANGLE_params(const State &glState, + bool isCallValid, + GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetVertexAttribIuivRobustANGLE_length(const State &glState, + bool isCallValid, + GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params, + angle::ParamCapture *paramCapture); +void CaptureGetVertexAttribIuivRobustANGLE_params(const State &glState, + bool isCallValid, + GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params, + angle::ParamCapture *paramCapture); +void CaptureGetUniformuivRobustANGLE_length(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + GLsizei *length, + GLuint *params, + angle::ParamCapture *paramCapture); +void CaptureGetUniformuivRobustANGLE_params(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + GLsizei *length, + GLuint *params, + angle::ParamCapture *paramCapture); +void CaptureGetActiveUniformBlockivRobustANGLE_length(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformBlockIndex uniformBlockIndexPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetActiveUniformBlockivRobustANGLE_params(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformBlockIndex uniformBlockIndexPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetInteger64vRobustANGLE_length(const State &glState, + bool isCallValid, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint64 *data, + angle::ParamCapture *paramCapture); +void CaptureGetInteger64vRobustANGLE_data(const State &glState, + bool isCallValid, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint64 *data, + angle::ParamCapture *paramCapture); +void CaptureGetInteger64i_vRobustANGLE_length(const State &glState, + bool isCallValid, + GLenum target, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint64 *data, + angle::ParamCapture *paramCapture); +void CaptureGetInteger64i_vRobustANGLE_data(const State &glState, + bool isCallValid, + GLenum target, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint64 *data, + angle::ParamCapture *paramCapture); +void CaptureGetBufferParameteri64vRobustANGLE_length(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint64 *params, + angle::ParamCapture *paramCapture); +void CaptureGetBufferParameteri64vRobustANGLE_params(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint64 *params, + angle::ParamCapture *paramCapture); +void CaptureSamplerParameterivRobustANGLE_param(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLuint pname, + GLsizei bufSize, + const GLint *param, + angle::ParamCapture *paramCapture); +void CaptureSamplerParameterfvRobustANGLE_param(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLsizei bufSize, + const GLfloat *param, + angle::ParamCapture *paramCapture); +void CaptureGetSamplerParameterivRobustANGLE_length(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetSamplerParameterivRobustANGLE_params(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetSamplerParameterfvRobustANGLE_length(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureGetSamplerParameterfvRobustANGLE_params(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureGetFramebufferParameterivRobustANGLE_length(const State &glState, + bool isCallValid, + GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetFramebufferParameterivRobustANGLE_params(const State &glState, + bool isCallValid, + GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetProgramInterfaceivRobustANGLE_length(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum programInterface, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetProgramInterfaceivRobustANGLE_params(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum programInterface, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetBooleani_vRobustANGLE_length(const State &glState, + bool isCallValid, + GLenum target, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLboolean *data, + angle::ParamCapture *paramCapture); +void CaptureGetBooleani_vRobustANGLE_data(const State &glState, + bool isCallValid, + GLenum target, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLboolean *data, + angle::ParamCapture *paramCapture); +void CaptureGetMultisamplefvRobustANGLE_length(const State &glState, + bool isCallValid, + GLenum pname, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLfloat *val, + angle::ParamCapture *paramCapture); +void CaptureGetMultisamplefvRobustANGLE_val(const State &glState, + bool isCallValid, + GLenum pname, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLfloat *val, + angle::ParamCapture *paramCapture); +void CaptureGetTexLevelParameterivRobustANGLE_length(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexLevelParameterivRobustANGLE_params(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexLevelParameterfvRobustANGLE_length(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexLevelParameterfvRobustANGLE_params(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureGetPointervRobustANGLERobustANGLE_length(const State &glState, + bool isCallValid, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + void **params, + angle::ParamCapture *paramCapture); +void CaptureGetPointervRobustANGLERobustANGLE_params(const State &glState, + bool isCallValid, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + void **params, + angle::ParamCapture *paramCapture); +void CaptureReadnPixelsRobustANGLE_length(const State &glState, + bool isCallValid, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + GLsizei *length, + GLsizei *columns, + GLsizei *rows, + void *data, + angle::ParamCapture *paramCapture); +void CaptureReadnPixelsRobustANGLE_columns(const State &glState, + bool isCallValid, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + GLsizei *length, + GLsizei *columns, + GLsizei *rows, + void *data, + angle::ParamCapture *paramCapture); +void CaptureReadnPixelsRobustANGLE_rows(const State &glState, + bool isCallValid, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + GLsizei *length, + GLsizei *columns, + GLsizei *rows, + void *data, + angle::ParamCapture *paramCapture); +void CaptureReadnPixelsRobustANGLE_data(const State &glState, + bool isCallValid, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + GLsizei *length, + GLsizei *columns, + GLsizei *rows, + void *data, + angle::ParamCapture *paramCapture); +void CaptureGetnUniformfvRobustANGLE_length(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + GLsizei *length, + GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureGetnUniformfvRobustANGLE_params(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + GLsizei *length, + GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureGetnUniformivRobustANGLE_length(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetnUniformivRobustANGLE_params(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetnUniformuivRobustANGLE_length(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + GLsizei *length, + GLuint *params, + angle::ParamCapture *paramCapture); +void CaptureGetnUniformuivRobustANGLE_params(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + GLsizei *length, + GLuint *params, + angle::ParamCapture *paramCapture); +void CaptureTexParameterIivRobustANGLE_params(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLsizei bufSize, + const GLint *params, + angle::ParamCapture *paramCapture); +void CaptureTexParameterIuivRobustANGLE_params(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLsizei bufSize, + const GLuint *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexParameterIivRobustANGLE_length(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexParameterIivRobustANGLE_params(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexParameterIuivRobustANGLE_length(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexParameterIuivRobustANGLE_params(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params, + angle::ParamCapture *paramCapture); +void CaptureSamplerParameterIivRobustANGLE_param(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLsizei bufSize, + const GLint *param, + angle::ParamCapture *paramCapture); +void CaptureSamplerParameterIuivRobustANGLE_param(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLsizei bufSize, + const GLuint *param, + angle::ParamCapture *paramCapture); +void CaptureGetSamplerParameterIivRobustANGLE_length(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetSamplerParameterIivRobustANGLE_params(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetSamplerParameterIuivRobustANGLE_length(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params, + angle::ParamCapture *paramCapture); +void CaptureGetSamplerParameterIuivRobustANGLE_params(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params, + angle::ParamCapture *paramCapture); +void CaptureGetQueryObjectivRobustANGLE_length(const State &glState, + bool isCallValid, + QueryID idPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetQueryObjectivRobustANGLE_params(const State &glState, + bool isCallValid, + QueryID idPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetQueryObjecti64vRobustANGLE_length(const State &glState, + bool isCallValid, + QueryID idPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint64 *params, + angle::ParamCapture *paramCapture); +void CaptureGetQueryObjecti64vRobustANGLE_params(const State &glState, + bool isCallValid, + QueryID idPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint64 *params, + angle::ParamCapture *paramCapture); +void CaptureGetQueryObjectui64vRobustANGLE_length(const State &glState, + bool isCallValid, + QueryID idPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint64 *params, + angle::ParamCapture *paramCapture); +void CaptureGetQueryObjectui64vRobustANGLE_params(const State &glState, + bool isCallValid, + QueryID idPacked, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint64 *params, + angle::ParamCapture *paramCapture); +void CaptureBeginPixelLocalStorageANGLE_loadops(const State &glState, + bool isCallValid, + GLsizei planes, + const GLenum *loadops, + const void *cleardata, + angle::ParamCapture *paramCapture); +void CaptureBeginPixelLocalStorageANGLE_cleardata(const State &glState, + bool isCallValid, + GLsizei planes, + const GLenum *loadops, + const void *cleardata, + angle::ParamCapture *paramCapture); +void CaptureGetMultisamplefvANGLE_val(const State &glState, + bool isCallValid, + GLenum pname, + GLuint index, + GLfloat *val, + angle::ParamCapture *paramCapture); +void CaptureGetTranslatedShaderSourceANGLE_length(const State &glState, + bool isCallValid, + ShaderProgramID shaderPacked, + GLsizei bufSize, + GLsizei *length, + GLchar *source, + angle::ParamCapture *paramCapture); +void CaptureGetTranslatedShaderSourceANGLE_source(const State &glState, + bool isCallValid, + ShaderProgramID shaderPacked, + GLsizei bufSize, + GLsizei *length, + GLchar *source, + angle::ParamCapture *paramCapture); +void CaptureAcquireTexturesANGLE_texturesPacked(const State &glState, + bool isCallValid, + GLuint numTextures, + const TextureID *texturesPacked, + const GLenum *layouts, + angle::ParamCapture *paramCapture); +void CaptureAcquireTexturesANGLE_layouts(const State &glState, + bool isCallValid, + GLuint numTextures, + const TextureID *texturesPacked, + const GLenum *layouts, + angle::ParamCapture *paramCapture); +void CaptureReleaseTexturesANGLE_texturesPacked(const State &glState, + bool isCallValid, + GLuint numTextures, + const TextureID *texturesPacked, + GLenum *layouts, + angle::ParamCapture *paramCapture); +void CaptureReleaseTexturesANGLE_layouts(const State &glState, + bool isCallValid, + GLuint numTextures, + const TextureID *texturesPacked, + GLenum *layouts, + angle::ParamCapture *paramCapture); +void CaptureBindUniformLocationCHROMIUM_name(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + const GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureEGLImageTargetTexStorageEXT_attrib_list(const State &glState, + bool isCallValid, + GLenum target, + GLeglImageOES image, + const GLint *attrib_list, + angle::ParamCapture *paramCapture); +void CaptureEGLImageTargetTextureStorageEXT_attrib_list(const State &glState, + bool isCallValid, + GLuint texture, + GLeglImageOES image, + const GLint *attrib_list, + angle::ParamCapture *paramCapture); +void CaptureDrawElementsInstancedBaseInstanceEXT_indices(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLsizei instancecount, + GLuint baseinstance, + angle::ParamCapture *paramCapture); +void CaptureDrawElementsInstancedBaseVertexBaseInstanceEXT_indices( + const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLsizei instancecount, + GLint basevertex, + GLuint baseinstance, + angle::ParamCapture *paramCapture); +void CaptureBindFragDataLocationEXT_name(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLuint color, + const GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureBindFragDataLocationIndexedEXT_name(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLuint colorNumber, + GLuint index, + const GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureGetFragDataIndexEXT_name(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + const GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureGetProgramResourceLocationIndexEXT_name(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum programInterface, + const GLchar *name, + angle::ParamCapture *paramCapture); +void CaptureBufferStorageEXT_data(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLsizeiptr size, + const void *data, + GLbitfield flags, + angle::ParamCapture *paramCapture); +void CaptureGetObjectLabelEXT_length(const State &glState, + bool isCallValid, + GLenum type, + GLuint object, + GLsizei bufSize, + GLsizei *length, + GLchar *label, + angle::ParamCapture *paramCapture); +void CaptureGetObjectLabelEXT_label(const State &glState, + bool isCallValid, + GLenum type, + GLuint object, + GLsizei bufSize, + GLsizei *length, + GLchar *label, + angle::ParamCapture *paramCapture); +void CaptureLabelObjectEXT_label(const State &glState, + bool isCallValid, + GLenum type, + GLuint object, + GLsizei length, + const GLchar *label, + angle::ParamCapture *paramCapture); +void CaptureInsertEventMarkerEXT_marker(const State &glState, + bool isCallValid, + GLsizei length, + const GLchar *marker, + angle::ParamCapture *paramCapture); +void CapturePushGroupMarkerEXT_marker(const State &glState, + bool isCallValid, + GLsizei length, + const GLchar *marker, + angle::ParamCapture *paramCapture); +void CaptureDiscardFramebufferEXT_attachments(const State &glState, + bool isCallValid, + GLenum target, + GLsizei numAttachments, + const GLenum *attachments, + angle::ParamCapture *paramCapture); +void CaptureDeleteQueriesEXT_idsPacked(const State &glState, + bool isCallValid, + GLsizei n, + const QueryID *idsPacked, + angle::ParamCapture *paramCapture); +void CaptureGenQueriesEXT_idsPacked(const State &glState, + bool isCallValid, + GLsizei n, + QueryID *idsPacked, + angle::ParamCapture *paramCapture); +void CaptureGetInteger64vEXT_data(const State &glState, + bool isCallValid, + GLenum pname, + GLint64 *data, + angle::ParamCapture *paramCapture); +void CaptureGetQueryObjecti64vEXT_params(const State &glState, + bool isCallValid, + QueryID idPacked, + GLenum pname, + GLint64 *params, + angle::ParamCapture *paramCapture); +void CaptureGetQueryObjectivEXT_params(const State &glState, + bool isCallValid, + QueryID idPacked, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetQueryObjectui64vEXT_params(const State &glState, + bool isCallValid, + QueryID idPacked, + GLenum pname, + GLuint64 *params, + angle::ParamCapture *paramCapture); +void CaptureGetQueryObjectuivEXT_params(const State &glState, + bool isCallValid, + QueryID idPacked, + GLenum pname, + GLuint *params, + angle::ParamCapture *paramCapture); +void CaptureGetQueryivEXT_params(const State &glState, + bool isCallValid, + QueryType targetPacked, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureDrawBuffersEXT_bufs(const State &glState, + bool isCallValid, + GLsizei n, + const GLenum *bufs, + angle::ParamCapture *paramCapture); +void CaptureDrawElementsBaseVertexEXT_indices(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLint basevertex, + angle::ParamCapture *paramCapture); +void CaptureDrawElementsInstancedBaseVertexEXT_indices(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLsizei instancecount, + GLint basevertex, + angle::ParamCapture *paramCapture); +void CaptureDrawRangeElementsBaseVertexEXT_indices(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLuint start, + GLuint end, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLint basevertex, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawElementsBaseVertexEXT_count(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLsizei *count, + DrawElementsType typePacked, + const void *const *indices, + GLsizei drawcount, + const GLint *basevertex, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawElementsBaseVertexEXT_indices(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLsizei *count, + DrawElementsType typePacked, + const void *const *indices, + GLsizei drawcount, + const GLint *basevertex, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawElementsBaseVertexEXT_basevertex(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const GLsizei *count, + DrawElementsType typePacked, + const void *const *indices, + GLsizei drawcount, + const GLint *basevertex, + angle::ParamCapture *paramCapture); +void CaptureDrawElementsInstancedEXT_indices(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLsizei primcount, + angle::ParamCapture *paramCapture); +void CaptureCreateMemoryObjectsEXT_memoryObjectsPacked(const State &glState, + bool isCallValid, + GLsizei n, + MemoryObjectID *memoryObjectsPacked, + angle::ParamCapture *paramCapture); +void CaptureDeleteMemoryObjectsEXT_memoryObjectsPacked(const State &glState, + bool isCallValid, + GLsizei n, + const MemoryObjectID *memoryObjectsPacked, + angle::ParamCapture *paramCapture); +void CaptureGetMemoryObjectParameterivEXT_params(const State &glState, + bool isCallValid, + MemoryObjectID memoryObjectPacked, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetUnsignedBytevEXT_data(const State &glState, + bool isCallValid, + GLenum pname, + GLubyte *data, + angle::ParamCapture *paramCapture); +void CaptureGetUnsignedBytei_vEXT_data(const State &glState, + bool isCallValid, + GLenum target, + GLuint index, + GLubyte *data, + angle::ParamCapture *paramCapture); +void CaptureMemoryObjectParameterivEXT_params(const State &glState, + bool isCallValid, + MemoryObjectID memoryObjectPacked, + GLenum pname, + const GLint *params, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawArraysIndirectEXT_indirect(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + const void *indirect, + GLsizei drawcount, + GLsizei stride, + angle::ParamCapture *paramCapture); +void CaptureMultiDrawElementsIndirectEXT_indirect(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + DrawElementsType typePacked, + const void *indirect, + GLsizei drawcount, + GLsizei stride, + angle::ParamCapture *paramCapture); +void CaptureGetnUniformfvEXT_params(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureGetnUniformivEXT_params(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureReadnPixelsEXT_data(const State &glState, + bool isCallValid, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + void *data, + angle::ParamCapture *paramCapture); +void CaptureDeleteSemaphoresEXT_semaphoresPacked(const State &glState, + bool isCallValid, + GLsizei n, + const SemaphoreID *semaphoresPacked, + angle::ParamCapture *paramCapture); +void CaptureGenSemaphoresEXT_semaphoresPacked(const State &glState, + bool isCallValid, + GLsizei n, + SemaphoreID *semaphoresPacked, + angle::ParamCapture *paramCapture); +void CaptureGetSemaphoreParameterui64vEXT_params(const State &glState, + bool isCallValid, + SemaphoreID semaphorePacked, + GLenum pname, + GLuint64 *params, + angle::ParamCapture *paramCapture); +void CaptureSemaphoreParameterui64vEXT_params(const State &glState, + bool isCallValid, + SemaphoreID semaphorePacked, + GLenum pname, + const GLuint64 *params, + angle::ParamCapture *paramCapture); +void CaptureSignalSemaphoreEXT_buffersPacked(const State &glState, + bool isCallValid, + SemaphoreID semaphorePacked, + GLuint numBufferBarriers, + const BufferID *buffersPacked, + GLuint numTextureBarriers, + const TextureID *texturesPacked, + const GLenum *dstLayouts, + angle::ParamCapture *paramCapture); +void CaptureSignalSemaphoreEXT_texturesPacked(const State &glState, + bool isCallValid, + SemaphoreID semaphorePacked, + GLuint numBufferBarriers, + const BufferID *buffersPacked, + GLuint numTextureBarriers, + const TextureID *texturesPacked, + const GLenum *dstLayouts, + angle::ParamCapture *paramCapture); +void CaptureSignalSemaphoreEXT_dstLayouts(const State &glState, + bool isCallValid, + SemaphoreID semaphorePacked, + GLuint numBufferBarriers, + const BufferID *buffersPacked, + GLuint numTextureBarriers, + const TextureID *texturesPacked, + const GLenum *dstLayouts, + angle::ParamCapture *paramCapture); +void CaptureWaitSemaphoreEXT_buffersPacked(const State &glState, + bool isCallValid, + SemaphoreID semaphorePacked, + GLuint numBufferBarriers, + const BufferID *buffersPacked, + GLuint numTextureBarriers, + const TextureID *texturesPacked, + const GLenum *srcLayouts, + angle::ParamCapture *paramCapture); +void CaptureWaitSemaphoreEXT_texturesPacked(const State &glState, + bool isCallValid, + SemaphoreID semaphorePacked, + GLuint numBufferBarriers, + const BufferID *buffersPacked, + GLuint numTextureBarriers, + const TextureID *texturesPacked, + const GLenum *srcLayouts, + angle::ParamCapture *paramCapture); +void CaptureWaitSemaphoreEXT_srcLayouts(const State &glState, + bool isCallValid, + SemaphoreID semaphorePacked, + GLuint numBufferBarriers, + const BufferID *buffersPacked, + GLuint numTextureBarriers, + const TextureID *texturesPacked, + const GLenum *srcLayouts, + angle::ParamCapture *paramCapture); +void CaptureCreateShaderProgramvEXT_strings(const State &glState, + bool isCallValid, + ShaderType typePacked, + GLsizei count, + const GLchar **strings, + angle::ParamCapture *paramCapture); +void CaptureDeleteProgramPipelinesEXT_pipelinesPacked(const State &glState, + bool isCallValid, + GLsizei n, + const ProgramPipelineID *pipelinesPacked, + angle::ParamCapture *paramCapture); +void CaptureGenProgramPipelinesEXT_pipelinesPacked(const State &glState, + bool isCallValid, + GLsizei n, + ProgramPipelineID *pipelinesPacked, + angle::ParamCapture *paramCapture); +void CaptureGetProgramPipelineInfoLogEXT_length(const State &glState, + bool isCallValid, + ProgramPipelineID pipelinePacked, + GLsizei bufSize, + GLsizei *length, + GLchar *infoLog, + angle::ParamCapture *paramCapture); +void CaptureGetProgramPipelineInfoLogEXT_infoLog(const State &glState, + bool isCallValid, + ProgramPipelineID pipelinePacked, + GLsizei bufSize, + GLsizei *length, + GLchar *infoLog, + angle::ParamCapture *paramCapture); +void CaptureGetProgramPipelineivEXT_params(const State &glState, + bool isCallValid, + ProgramPipelineID pipelinePacked, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureProgramUniform1fvEXT_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniform1ivEXT_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniform1uivEXT_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniform2fvEXT_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniform2ivEXT_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniform2uivEXT_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniform3fvEXT_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniform3ivEXT_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniform3uivEXT_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniform4fvEXT_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniform4ivEXT_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniform4uivEXT_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniformMatrix2fvEXT_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniformMatrix2x3fvEXT_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniformMatrix2x4fvEXT_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniformMatrix3fvEXT_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniformMatrix3x2fvEXT_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniformMatrix3x4fvEXT_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniformMatrix4fvEXT_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniformMatrix4x2fvEXT_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureProgramUniformMatrix4x3fvEXT_value(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value, + angle::ParamCapture *paramCapture); +void CaptureGetSamplerParameterIivEXT_params(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetSamplerParameterIuivEXT_params(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLuint *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexParameterIivEXT_params(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexParameterIuivEXT_params(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLuint *params, + angle::ParamCapture *paramCapture); +void CaptureSamplerParameterIivEXT_param(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + const GLint *param, + angle::ParamCapture *paramCapture); +void CaptureSamplerParameterIuivEXT_param(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + const GLuint *param, + angle::ParamCapture *paramCapture); +void CaptureTexParameterIivEXT_params(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + const GLint *params, + angle::ParamCapture *paramCapture); +void CaptureTexParameterIuivEXT_params(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + const GLuint *params, + angle::ParamCapture *paramCapture); +void CaptureDebugMessageCallbackKHR_userParam(const State &glState, + bool isCallValid, + GLDEBUGPROCKHR callback, + const void *userParam, + angle::ParamCapture *paramCapture); +void CaptureDebugMessageControlKHR_ids(const State &glState, + bool isCallValid, + GLenum source, + GLenum type, + GLenum severity, + GLsizei count, + const GLuint *ids, + GLboolean enabled, + angle::ParamCapture *paramCapture); +void CaptureDebugMessageInsertKHR_buf(const State &glState, + bool isCallValid, + GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar *buf, + angle::ParamCapture *paramCapture); +void CaptureGetDebugMessageLogKHR_sources(const State &glState, + bool isCallValid, + GLuint count, + GLsizei bufSize, + GLenum *sources, + GLenum *types, + GLuint *ids, + GLenum *severities, + GLsizei *lengths, + GLchar *messageLog, + angle::ParamCapture *paramCapture); +void CaptureGetDebugMessageLogKHR_types(const State &glState, + bool isCallValid, + GLuint count, + GLsizei bufSize, + GLenum *sources, + GLenum *types, + GLuint *ids, + GLenum *severities, + GLsizei *lengths, + GLchar *messageLog, + angle::ParamCapture *paramCapture); +void CaptureGetDebugMessageLogKHR_ids(const State &glState, + bool isCallValid, + GLuint count, + GLsizei bufSize, + GLenum *sources, + GLenum *types, + GLuint *ids, + GLenum *severities, + GLsizei *lengths, + GLchar *messageLog, + angle::ParamCapture *paramCapture); +void CaptureGetDebugMessageLogKHR_severities(const State &glState, + bool isCallValid, + GLuint count, + GLsizei bufSize, + GLenum *sources, + GLenum *types, + GLuint *ids, + GLenum *severities, + GLsizei *lengths, + GLchar *messageLog, + angle::ParamCapture *paramCapture); +void CaptureGetDebugMessageLogKHR_lengths(const State &glState, + bool isCallValid, + GLuint count, + GLsizei bufSize, + GLenum *sources, + GLenum *types, + GLuint *ids, + GLenum *severities, + GLsizei *lengths, + GLchar *messageLog, + angle::ParamCapture *paramCapture); +void CaptureGetDebugMessageLogKHR_messageLog(const State &glState, + bool isCallValid, + GLuint count, + GLsizei bufSize, + GLenum *sources, + GLenum *types, + GLuint *ids, + GLenum *severities, + GLsizei *lengths, + GLchar *messageLog, + angle::ParamCapture *paramCapture); +void CaptureGetObjectLabelKHR_length(const State &glState, + bool isCallValid, + GLenum identifier, + GLuint name, + GLsizei bufSize, + GLsizei *length, + GLchar *label, + angle::ParamCapture *paramCapture); +void CaptureGetObjectLabelKHR_label(const State &glState, + bool isCallValid, + GLenum identifier, + GLuint name, + GLsizei bufSize, + GLsizei *length, + GLchar *label, + angle::ParamCapture *paramCapture); +void CaptureGetObjectPtrLabelKHR_ptr(const State &glState, + bool isCallValid, + const void *ptr, + GLsizei bufSize, + GLsizei *length, + GLchar *label, + angle::ParamCapture *paramCapture); +void CaptureGetObjectPtrLabelKHR_length(const State &glState, + bool isCallValid, + const void *ptr, + GLsizei bufSize, + GLsizei *length, + GLchar *label, + angle::ParamCapture *paramCapture); +void CaptureGetObjectPtrLabelKHR_label(const State &glState, + bool isCallValid, + const void *ptr, + GLsizei bufSize, + GLsizei *length, + GLchar *label, + angle::ParamCapture *paramCapture); +void CaptureGetPointervKHR_params(const State &glState, + bool isCallValid, + GLenum pname, + void **params, + angle::ParamCapture *paramCapture); +void CaptureObjectLabelKHR_label(const State &glState, + bool isCallValid, + GLenum identifier, + GLuint name, + GLsizei length, + const GLchar *label, + angle::ParamCapture *paramCapture); +void CaptureObjectPtrLabelKHR_ptr(const State &glState, + bool isCallValid, + const void *ptr, + GLsizei length, + const GLchar *label, + angle::ParamCapture *paramCapture); +void CaptureObjectPtrLabelKHR_label(const State &glState, + bool isCallValid, + const void *ptr, + GLsizei length, + const GLchar *label, + angle::ParamCapture *paramCapture); +void CapturePushDebugGroupKHR_message(const State &glState, + bool isCallValid, + GLenum source, + GLuint id, + GLsizei length, + const GLchar *message, + angle::ParamCapture *paramCapture); +void CaptureGetFramebufferParameterivMESA_params(const State &glState, + bool isCallValid, + GLenum target, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureDeleteFencesNV_fencesPacked(const State &glState, + bool isCallValid, + GLsizei n, + const FenceNVID *fencesPacked, + angle::ParamCapture *paramCapture); +void CaptureGenFencesNV_fencesPacked(const State &glState, + bool isCallValid, + GLsizei n, + FenceNVID *fencesPacked, + angle::ParamCapture *paramCapture); +void CaptureGetFenceivNV_params(const State &glState, + bool isCallValid, + FenceNVID fencePacked, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureDrawElementsBaseVertexOES_indices(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLint basevertex, + angle::ParamCapture *paramCapture); +void CaptureDrawElementsInstancedBaseVertexOES_indices(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLsizei instancecount, + GLint basevertex, + angle::ParamCapture *paramCapture); +void CaptureDrawRangeElementsBaseVertexOES_indices(const State &glState, + bool isCallValid, + PrimitiveMode modePacked, + GLuint start, + GLuint end, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLint basevertex, + angle::ParamCapture *paramCapture); +void CaptureDrawTexfvOES_coords(const State &glState, + bool isCallValid, + const GLfloat *coords, + angle::ParamCapture *paramCapture); +void CaptureDrawTexivOES_coords(const State &glState, + bool isCallValid, + const GLint *coords, + angle::ParamCapture *paramCapture); +void CaptureDrawTexsvOES_coords(const State &glState, + bool isCallValid, + const GLshort *coords, + angle::ParamCapture *paramCapture); +void CaptureDrawTexxvOES_coords(const State &glState, + bool isCallValid, + const GLfixed *coords, + angle::ParamCapture *paramCapture); +void CaptureDeleteFramebuffersOES_framebuffersPacked(const State &glState, + bool isCallValid, + GLsizei n, + const FramebufferID *framebuffersPacked, + angle::ParamCapture *paramCapture); +void CaptureDeleteRenderbuffersOES_renderbuffersPacked(const State &glState, + bool isCallValid, + GLsizei n, + const RenderbufferID *renderbuffersPacked, + angle::ParamCapture *paramCapture); +void CaptureGenFramebuffersOES_framebuffersPacked(const State &glState, + bool isCallValid, + GLsizei n, + FramebufferID *framebuffersPacked, + angle::ParamCapture *paramCapture); +void CaptureGenRenderbuffersOES_renderbuffersPacked(const State &glState, + bool isCallValid, + GLsizei n, + RenderbufferID *renderbuffersPacked, + angle::ParamCapture *paramCapture); +void CaptureGetFramebufferAttachmentParameterivOES_params(const State &glState, + bool isCallValid, + GLenum target, + GLenum attachment, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetRenderbufferParameterivOES_params(const State &glState, + bool isCallValid, + GLenum target, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetProgramBinaryOES_length(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLsizei bufSize, + GLsizei *length, + GLenum *binaryFormat, + void *binary, + angle::ParamCapture *paramCapture); +void CaptureGetProgramBinaryOES_binaryFormat(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLsizei bufSize, + GLsizei *length, + GLenum *binaryFormat, + void *binary, + angle::ParamCapture *paramCapture); +void CaptureGetProgramBinaryOES_binary(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLsizei bufSize, + GLsizei *length, + GLenum *binaryFormat, + void *binary, + angle::ParamCapture *paramCapture); +void CaptureProgramBinaryOES_binary(const State &glState, + bool isCallValid, + ShaderProgramID programPacked, + GLenum binaryFormat, + const void *binary, + GLint length, + angle::ParamCapture *paramCapture); +void CaptureGetBufferPointervOES_params(const State &glState, + bool isCallValid, + BufferBinding targetPacked, + GLenum pname, + void **params, + angle::ParamCapture *paramCapture); +void CaptureMatrixIndexPointerOES_pointer(const State &glState, + bool isCallValid, + GLint size, + GLenum type, + GLsizei stride, + const void *pointer, + angle::ParamCapture *paramCapture); +void CaptureWeightPointerOES_pointer(const State &glState, + bool isCallValid, + GLint size, + GLenum type, + GLsizei stride, + const void *pointer, + angle::ParamCapture *paramCapture); +void CapturePointSizePointerOES_pointer(const State &glState, + bool isCallValid, + VertexAttribType typePacked, + GLsizei stride, + const void *pointer, + angle::ParamCapture *paramCapture); +void CaptureQueryMatrixxOES_mantissa(const State &glState, + bool isCallValid, + GLfixed *mantissa, + GLint *exponent, + angle::ParamCapture *paramCapture); +void CaptureQueryMatrixxOES_exponent(const State &glState, + bool isCallValid, + GLfixed *mantissa, + GLint *exponent, + angle::ParamCapture *paramCapture); +void CaptureCompressedTexImage3DOES_data(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + const void *data, + angle::ParamCapture *paramCapture); +void CaptureCompressedTexSubImage3DOES_data(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const void *data, + angle::ParamCapture *paramCapture); +void CaptureTexImage3DOES_pixels(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const void *pixels, + angle::ParamCapture *paramCapture); +void CaptureTexSubImage3DOES_pixels(const State &glState, + bool isCallValid, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *pixels, + angle::ParamCapture *paramCapture); +void CaptureGetSamplerParameterIivOES_params(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetSamplerParameterIuivOES_params(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + GLuint *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexParameterIivOES_params(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexParameterIuivOES_params(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + GLuint *params, + angle::ParamCapture *paramCapture); +void CaptureSamplerParameterIivOES_param(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + const GLint *param, + angle::ParamCapture *paramCapture); +void CaptureSamplerParameterIuivOES_param(const State &glState, + bool isCallValid, + SamplerID samplerPacked, + GLenum pname, + const GLuint *param, + angle::ParamCapture *paramCapture); +void CaptureTexParameterIivOES_params(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + const GLint *params, + angle::ParamCapture *paramCapture); +void CaptureTexParameterIuivOES_params(const State &glState, + bool isCallValid, + TextureType targetPacked, + GLenum pname, + const GLuint *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexGenfvOES_params(const State &glState, + bool isCallValid, + GLenum coord, + GLenum pname, + GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexGenivOES_params(const State &glState, + bool isCallValid, + GLenum coord, + GLenum pname, + GLint *params, + angle::ParamCapture *paramCapture); +void CaptureGetTexGenxvOES_params(const State &glState, + bool isCallValid, + GLenum coord, + GLenum pname, + GLfixed *params, + angle::ParamCapture *paramCapture); +void CaptureTexGenfvOES_params(const State &glState, + bool isCallValid, + GLenum coord, + GLenum pname, + const GLfloat *params, + angle::ParamCapture *paramCapture); +void CaptureTexGenivOES_params(const State &glState, + bool isCallValid, + GLenum coord, + GLenum pname, + const GLint *params, + angle::ParamCapture *paramCapture); +void CaptureTexGenxvOES_params(const State &glState, + bool isCallValid, + GLenum coord, + GLenum pname, + const GLfixed *params, + angle::ParamCapture *paramCapture); +void CaptureDeleteVertexArraysOES_arraysPacked(const State &glState, + bool isCallValid, + GLsizei n, + const VertexArrayID *arraysPacked, + angle::ParamCapture *paramCapture); +void CaptureGenVertexArraysOES_arraysPacked(const State &glState, + bool isCallValid, + GLsizei n, + VertexArrayID *arraysPacked, + angle::ParamCapture *paramCapture); +} // namespace gl + +#endif // LIBANGLE_CAPTURE_GLES_EXT_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/capture/frame_capture_utils.h b/gfx/angle/checkout/src/libANGLE/capture/frame_capture_utils.h new file mode 100644 index 0000000000..18e2fe41cc --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/capture/frame_capture_utils.h @@ -0,0 +1,23 @@ +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// frame_capture_utils.h: +// ANGLE frame capture utils interface. +// +#ifndef FRAME_CAPTURE_UTILS_H_ +#define FRAME_CAPTURE_UTILS_H_ + +#include "libANGLE/Error.h" + +namespace gl +{ +class Context; +} // namespace gl + +namespace angle +{ +Result SerializeContextToString(const gl::Context *context, std::string *stringOut); +} // namespace angle +#endif // FRAME_CAPTURE_UTILS_H_ diff --git a/gfx/angle/checkout/src/libANGLE/capture/frame_capture_utils_autogen.h b/gfx/angle/checkout/src/libANGLE/capture/frame_capture_utils_autogen.h new file mode 100644 index 0000000000..9c76c2fc15 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/capture/frame_capture_utils_autogen.h @@ -0,0 +1,3257 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// frame_capture_utils_autogen.h: +// ANGLE Frame capture types and helper functions. + +#ifndef LIBANGLE_FRAME_CAPTURE_UTILS_AUTOGEN_H_ +#define LIBANGLE_FRAME_CAPTURE_UTILS_AUTOGEN_H_ + +#include "common/PackedEnums.h" + +namespace angle +{ +enum class ParamType +{ + TAHardwareBufferConstPointer, + TAlphaTestFunc, + TBufferBinding, + TBufferID, + TBufferIDConstPointer, + TBufferIDPointer, + TBufferUsage, + TClientVertexArrayType, + TCompositorTiming, + TCullFaceMode, + TDrawElementsType, + TEGLAttrib, + TEGLAttribKHR, + TEGLBoolean, + TEGLClientBuffer, + TEGLConfig, + TEGLContext, + TEGLDEBUGPROCKHR, + TEGLDeviceEXT, + TEGLDisplay, + TEGLFrameTokenANGLE, + TEGLGetBlobFuncANDROID, + TEGLImage, + TEGLLabelKHR, + TEGLNativeDisplayType, + TEGLNativePixmapType, + TEGLNativeWindowType, + TEGLObjectKHR, + TEGLSetBlobFuncANDROID, + TEGLStreamKHR, + TEGLSurface, + TEGLSync, + TEGLTime, + TEGLTimeKHR, + TEGLenum, + TEGLint, + TEGLnsecsANDROID, + TEGLuint64KHR, + TFenceNVID, + TFenceNVIDConstPointer, + TFenceNVIDPointer, + TFramebufferID, + TFramebufferIDConstPointer, + TFramebufferIDPointer, + TGLDEBUGPROC, + TGLDEBUGPROCKHR, + TGLbitfield, + TGLboolean, + TGLbooleanConstPointer, + TGLbooleanPointer, + TGLbyte, + TGLbyteConstPointer, + TGLcharConstPointer, + TGLcharConstPointerPointer, + TGLcharPointer, + TGLclampx, + TGLdouble, + TGLdoubleConstPointer, + TGLdoublePointer, + TGLeglClientBufferEXT, + TGLeglImageOES, + TGLenum, + TGLenumConstPointer, + TGLenumPointer, + TGLfixed, + TGLfixedConstPointer, + TGLfixedPointer, + TGLfloat, + TGLfloatConstPointer, + TGLfloatPointer, + TGLint, + TGLint64Pointer, + TGLintConstPointer, + TGLintPointer, + TGLintptr, + TGLintptrConstPointer, + TGLshort, + TGLshortConstPointer, + TGLsizei, + TGLsizeiConstPointer, + TGLsizeiPointer, + TGLsizeiptr, + TGLsizeiptrConstPointer, + TGLsync, + TGLubyte, + TGLubyteConstPointer, + TGLubytePointer, + TGLuint, + TGLuint64, + TGLuint64ConstPointer, + TGLuint64Pointer, + TGLuintConstPointer, + TGLuintPointer, + TGLushort, + TGLushortConstPointer, + TGLushortPointer, + TGLvoidConstPointer, + TGLvoidConstPointerPointer, + TGraphicsResetStatus, + THandleType, + TLightParameter, + TLogicalOperation, + TMaterialParameter, + TMatrixType, + TMemoryObjectID, + TMemoryObjectIDConstPointer, + TMemoryObjectIDPointer, + TObjectType, + TPointParameter, + TPrimitiveMode, + TProgramPipelineID, + TProgramPipelineIDConstPointer, + TProgramPipelineIDPointer, + TProvokingVertexConvention, + TQueryID, + TQueryIDConstPointer, + TQueryIDPointer, + TQueryType, + TRenderbufferID, + TRenderbufferIDConstPointer, + TRenderbufferIDPointer, + TSamplerID, + TSamplerIDConstPointer, + TSamplerIDPointer, + TSemaphoreID, + TSemaphoreIDConstPointer, + TSemaphoreIDPointer, + TShaderProgramID, + TShaderProgramIDConstPointer, + TShaderProgramIDPointer, + TShaderType, + TShadingModel, + TTextureEnvParameter, + TTextureEnvTarget, + TTextureID, + TTextureIDConstPointer, + TTextureIDPointer, + TTextureTarget, + TTextureType, + TTimestamp, + TTransformFeedbackID, + TTransformFeedbackIDConstPointer, + TTransformFeedbackIDPointer, + TUniformBlockIndex, + TUniformLocation, + TVertexArrayID, + TVertexArrayIDConstPointer, + TVertexArrayIDPointer, + TVertexAttribType, + TcharConstPointer, + TvoidConstPointer, + TvoidConstPointerPointer, + TvoidPointer, + TvoidPointerPointer, +}; + +constexpr uint32_t kParamTypeCount = 154; + +union ParamValue +{ + const AHardwareBuffer *AHardwareBufferConstPointerVal; + gl::AlphaTestFunc AlphaTestFuncVal; + gl::BufferBinding BufferBindingVal; + gl::BufferID BufferIDVal; + const gl::BufferID *BufferIDConstPointerVal; + gl::BufferID *BufferIDPointerVal; + gl::BufferUsage BufferUsageVal; + gl::ClientVertexArrayType ClientVertexArrayTypeVal; + egl::CompositorTiming CompositorTimingVal; + gl::CullFaceMode CullFaceModeVal; + gl::DrawElementsType DrawElementsTypeVal; + EGLAttrib EGLAttribVal; + EGLAttribKHR EGLAttribKHRVal; + EGLBoolean EGLBooleanVal; + EGLClientBuffer EGLClientBufferVal; + EGLConfig EGLConfigVal; + EGLContext EGLContextVal; + EGLDEBUGPROCKHR EGLDEBUGPROCKHRVal; + EGLDeviceEXT EGLDeviceEXTVal; + EGLDisplay EGLDisplayVal; + EGLFrameTokenANGLE EGLFrameTokenANGLEVal; + EGLGetBlobFuncANDROID EGLGetBlobFuncANDROIDVal; + EGLImage EGLImageVal; + EGLLabelKHR EGLLabelKHRVal; + EGLNativeDisplayType EGLNativeDisplayTypeVal; + EGLNativePixmapType EGLNativePixmapTypeVal; + EGLNativeWindowType EGLNativeWindowTypeVal; + EGLObjectKHR EGLObjectKHRVal; + EGLSetBlobFuncANDROID EGLSetBlobFuncANDROIDVal; + EGLStreamKHR EGLStreamKHRVal; + EGLSurface EGLSurfaceVal; + EGLSync EGLSyncVal; + EGLTime EGLTimeVal; + EGLTimeKHR EGLTimeKHRVal; + EGLenum EGLenumVal; + EGLint EGLintVal; + EGLnsecsANDROID EGLnsecsANDROIDVal; + EGLuint64KHR EGLuint64KHRVal; + gl::FenceNVID FenceNVIDVal; + const gl::FenceNVID *FenceNVIDConstPointerVal; + gl::FenceNVID *FenceNVIDPointerVal; + gl::FramebufferID FramebufferIDVal; + const gl::FramebufferID *FramebufferIDConstPointerVal; + gl::FramebufferID *FramebufferIDPointerVal; + GLDEBUGPROC GLDEBUGPROCVal; + GLDEBUGPROCKHR GLDEBUGPROCKHRVal; + GLbitfield GLbitfieldVal; + GLboolean GLbooleanVal; + const GLboolean *GLbooleanConstPointerVal; + GLboolean *GLbooleanPointerVal; + GLbyte GLbyteVal; + const GLbyte *GLbyteConstPointerVal; + const GLchar *GLcharConstPointerVal; + const GLchar *const *GLcharConstPointerPointerVal; + GLchar *GLcharPointerVal; + GLclampx GLclampxVal; + GLdouble GLdoubleVal; + const GLdouble *GLdoubleConstPointerVal; + GLdouble *GLdoublePointerVal; + GLeglClientBufferEXT GLeglClientBufferEXTVal; + GLeglImageOES GLeglImageOESVal; + GLenum GLenumVal; + const GLenum *GLenumConstPointerVal; + GLenum *GLenumPointerVal; + GLfixed GLfixedVal; + const GLfixed *GLfixedConstPointerVal; + GLfixed *GLfixedPointerVal; + GLfloat GLfloatVal; + const GLfloat *GLfloatConstPointerVal; + GLfloat *GLfloatPointerVal; + GLint GLintVal; + GLint64 *GLint64PointerVal; + const GLint *GLintConstPointerVal; + GLint *GLintPointerVal; + GLintptr GLintptrVal; + const GLintptr *GLintptrConstPointerVal; + GLshort GLshortVal; + const GLshort *GLshortConstPointerVal; + GLsizei GLsizeiVal; + const GLsizei *GLsizeiConstPointerVal; + GLsizei *GLsizeiPointerVal; + GLsizeiptr GLsizeiptrVal; + const GLsizeiptr *GLsizeiptrConstPointerVal; + GLsync GLsyncVal; + GLubyte GLubyteVal; + const GLubyte *GLubyteConstPointerVal; + GLubyte *GLubytePointerVal; + GLuint GLuintVal; + GLuint64 GLuint64Val; + const GLuint64 *GLuint64ConstPointerVal; + GLuint64 *GLuint64PointerVal; + const GLuint *GLuintConstPointerVal; + GLuint *GLuintPointerVal; + GLushort GLushortVal; + const GLushort *GLushortConstPointerVal; + GLushort *GLushortPointerVal; + const GLvoid *GLvoidConstPointerVal; + const GLvoid *const *GLvoidConstPointerPointerVal; + gl::GraphicsResetStatus GraphicsResetStatusVal; + gl::HandleType HandleTypeVal; + gl::LightParameter LightParameterVal; + gl::LogicalOperation LogicalOperationVal; + gl::MaterialParameter MaterialParameterVal; + gl::MatrixType MatrixTypeVal; + gl::MemoryObjectID MemoryObjectIDVal; + const gl::MemoryObjectID *MemoryObjectIDConstPointerVal; + gl::MemoryObjectID *MemoryObjectIDPointerVal; + egl::ObjectType ObjectTypeVal; + gl::PointParameter PointParameterVal; + gl::PrimitiveMode PrimitiveModeVal; + gl::ProgramPipelineID ProgramPipelineIDVal; + const gl::ProgramPipelineID *ProgramPipelineIDConstPointerVal; + gl::ProgramPipelineID *ProgramPipelineIDPointerVal; + gl::ProvokingVertexConvention ProvokingVertexConventionVal; + gl::QueryID QueryIDVal; + const gl::QueryID *QueryIDConstPointerVal; + gl::QueryID *QueryIDPointerVal; + gl::QueryType QueryTypeVal; + gl::RenderbufferID RenderbufferIDVal; + const gl::RenderbufferID *RenderbufferIDConstPointerVal; + gl::RenderbufferID *RenderbufferIDPointerVal; + gl::SamplerID SamplerIDVal; + const gl::SamplerID *SamplerIDConstPointerVal; + gl::SamplerID *SamplerIDPointerVal; + gl::SemaphoreID SemaphoreIDVal; + const gl::SemaphoreID *SemaphoreIDConstPointerVal; + gl::SemaphoreID *SemaphoreIDPointerVal; + gl::ShaderProgramID ShaderProgramIDVal; + const gl::ShaderProgramID *ShaderProgramIDConstPointerVal; + gl::ShaderProgramID *ShaderProgramIDPointerVal; + gl::ShaderType ShaderTypeVal; + gl::ShadingModel ShadingModelVal; + gl::TextureEnvParameter TextureEnvParameterVal; + gl::TextureEnvTarget TextureEnvTargetVal; + gl::TextureID TextureIDVal; + const gl::TextureID *TextureIDConstPointerVal; + gl::TextureID *TextureIDPointerVal; + gl::TextureTarget TextureTargetVal; + gl::TextureType TextureTypeVal; + egl::Timestamp TimestampVal; + gl::TransformFeedbackID TransformFeedbackIDVal; + const gl::TransformFeedbackID *TransformFeedbackIDConstPointerVal; + gl::TransformFeedbackID *TransformFeedbackIDPointerVal; + gl::UniformBlockIndex UniformBlockIndexVal; + gl::UniformLocation UniformLocationVal; + gl::VertexArrayID VertexArrayIDVal; + const gl::VertexArrayID *VertexArrayIDConstPointerVal; + gl::VertexArrayID *VertexArrayIDPointerVal; + gl::VertexAttribType VertexAttribTypeVal; + const char *charConstPointerVal; + const void *voidConstPointerVal; + const void *const *voidConstPointerPointerVal; + void *voidPointerVal; + void **voidPointerPointerVal; +}; + +template +T GetParamVal(const ParamValue &value); + +template <> +inline const AHardwareBuffer *GetParamVal(const ParamValue &value) +{ + return value.AHardwareBufferConstPointerVal; +} + +template <> +inline gl::AlphaTestFunc GetParamVal( + const ParamValue &value) +{ + return value.AlphaTestFuncVal; +} + +template <> +inline gl::BufferBinding GetParamVal( + const ParamValue &value) +{ + return value.BufferBindingVal; +} + +template <> +inline gl::BufferID GetParamVal(const ParamValue &value) +{ + return value.BufferIDVal; +} + +template <> +inline const gl::BufferID *GetParamVal( + const ParamValue &value) +{ + return value.BufferIDConstPointerVal; +} + +template <> +inline gl::BufferID *GetParamVal( + const ParamValue &value) +{ + return value.BufferIDPointerVal; +} + +template <> +inline gl::BufferUsage GetParamVal( + const ParamValue &value) +{ + return value.BufferUsageVal; +} + +template <> +inline gl::ClientVertexArrayType +GetParamVal(const ParamValue &value) +{ + return value.ClientVertexArrayTypeVal; +} + +template <> +inline egl::CompositorTiming GetParamVal( + const ParamValue &value) +{ + return value.CompositorTimingVal; +} + +template <> +inline gl::CullFaceMode GetParamVal( + const ParamValue &value) +{ + return value.CullFaceModeVal; +} + +template <> +inline gl::DrawElementsType GetParamVal( + const ParamValue &value) +{ + return value.DrawElementsTypeVal; +} + +template <> +inline EGLAttrib GetParamVal(const ParamValue &value) +{ + return value.EGLAttribVal; +} + +template <> +inline EGLAttribKHR GetParamVal(const ParamValue &value) +{ + return value.EGLAttribKHRVal; +} + +template <> +inline EGLBoolean GetParamVal(const ParamValue &value) +{ + return value.EGLBooleanVal; +} + +template <> +inline EGLClientBuffer GetParamVal( + const ParamValue &value) +{ + return value.EGLClientBufferVal; +} + +template <> +inline EGLConfig GetParamVal(const ParamValue &value) +{ + return value.EGLConfigVal; +} + +template <> +inline EGLContext GetParamVal(const ParamValue &value) +{ + return value.EGLContextVal; +} + +template <> +inline EGLDEBUGPROCKHR GetParamVal( + const ParamValue &value) +{ + return value.EGLDEBUGPROCKHRVal; +} + +template <> +inline EGLDeviceEXT GetParamVal(const ParamValue &value) +{ + return value.EGLDeviceEXTVal; +} + +template <> +inline EGLDisplay GetParamVal(const ParamValue &value) +{ + return value.EGLDisplayVal; +} + +template <> +inline EGLFrameTokenANGLE GetParamVal( + const ParamValue &value) +{ + return value.EGLFrameTokenANGLEVal; +} + +template <> +inline EGLGetBlobFuncANDROID GetParamVal( + const ParamValue &value) +{ + return value.EGLGetBlobFuncANDROIDVal; +} + +template <> +inline EGLImage GetParamVal(const ParamValue &value) +{ + return value.EGLImageVal; +} + +template <> +inline EGLLabelKHR GetParamVal(const ParamValue &value) +{ + return value.EGLLabelKHRVal; +} + +template <> +inline EGLNativeDisplayType GetParamVal( + const ParamValue &value) +{ + return value.EGLNativeDisplayTypeVal; +} + +template <> +inline EGLNativePixmapType GetParamVal( + const ParamValue &value) +{ + return value.EGLNativePixmapTypeVal; +} + +template <> +inline EGLNativeWindowType GetParamVal( + const ParamValue &value) +{ + return value.EGLNativeWindowTypeVal; +} + +template <> +inline EGLObjectKHR GetParamVal(const ParamValue &value) +{ + return value.EGLObjectKHRVal; +} + +template <> +inline EGLSetBlobFuncANDROID GetParamVal( + const ParamValue &value) +{ + return value.EGLSetBlobFuncANDROIDVal; +} + +template <> +inline EGLStreamKHR GetParamVal(const ParamValue &value) +{ + return value.EGLStreamKHRVal; +} + +template <> +inline EGLSurface GetParamVal(const ParamValue &value) +{ + return value.EGLSurfaceVal; +} + +template <> +inline EGLSync GetParamVal(const ParamValue &value) +{ + return value.EGLSyncVal; +} + +template <> +inline EGLTime GetParamVal(const ParamValue &value) +{ + return value.EGLTimeVal; +} + +template <> +inline EGLTimeKHR GetParamVal(const ParamValue &value) +{ + return value.EGLTimeKHRVal; +} + +template <> +inline EGLenum GetParamVal(const ParamValue &value) +{ + return value.EGLenumVal; +} + +template <> +inline EGLint GetParamVal(const ParamValue &value) +{ + return value.EGLintVal; +} + +template <> +inline EGLnsecsANDROID GetParamVal( + const ParamValue &value) +{ + return value.EGLnsecsANDROIDVal; +} + +template <> +inline EGLuint64KHR GetParamVal(const ParamValue &value) +{ + return value.EGLuint64KHRVal; +} + +template <> +inline gl::FenceNVID GetParamVal(const ParamValue &value) +{ + return value.FenceNVIDVal; +} + +template <> +inline const gl::FenceNVID *GetParamVal( + const ParamValue &value) +{ + return value.FenceNVIDConstPointerVal; +} + +template <> +inline gl::FenceNVID *GetParamVal( + const ParamValue &value) +{ + return value.FenceNVIDPointerVal; +} + +template <> +inline gl::FramebufferID GetParamVal( + const ParamValue &value) +{ + return value.FramebufferIDVal; +} + +template <> +inline const gl::FramebufferID *GetParamVal(const ParamValue &value) +{ + return value.FramebufferIDConstPointerVal; +} + +template <> +inline gl::FramebufferID *GetParamVal( + const ParamValue &value) +{ + return value.FramebufferIDPointerVal; +} + +template <> +inline GLDEBUGPROC GetParamVal(const ParamValue &value) +{ + return value.GLDEBUGPROCVal; +} + +template <> +inline GLDEBUGPROCKHR GetParamVal( + const ParamValue &value) +{ + return value.GLDEBUGPROCKHRVal; +} + +template <> +inline GLbitfield GetParamVal(const ParamValue &value) +{ + return value.GLbitfieldVal; +} + +template <> +inline GLboolean GetParamVal(const ParamValue &value) +{ + return value.GLbooleanVal; +} + +template <> +inline const GLboolean *GetParamVal( + const ParamValue &value) +{ + return value.GLbooleanConstPointerVal; +} + +template <> +inline GLboolean *GetParamVal(const ParamValue &value) +{ + return value.GLbooleanPointerVal; +} + +template <> +inline GLbyte GetParamVal(const ParamValue &value) +{ + return value.GLbyteVal; +} + +template <> +inline const GLbyte *GetParamVal( + const ParamValue &value) +{ + return value.GLbyteConstPointerVal; +} + +template <> +inline const GLchar *GetParamVal( + const ParamValue &value) +{ + return value.GLcharConstPointerVal; +} + +template <> +inline const GLchar *const * +GetParamVal(const ParamValue &value) +{ + return value.GLcharConstPointerPointerVal; +} + +template <> +inline GLchar *GetParamVal(const ParamValue &value) +{ + return value.GLcharPointerVal; +} + +template <> +inline GLclampx GetParamVal(const ParamValue &value) +{ + return value.GLclampxVal; +} + +template <> +inline GLdouble GetParamVal(const ParamValue &value) +{ + return value.GLdoubleVal; +} + +template <> +inline const GLdouble *GetParamVal( + const ParamValue &value) +{ + return value.GLdoubleConstPointerVal; +} + +template <> +inline GLdouble *GetParamVal(const ParamValue &value) +{ + return value.GLdoublePointerVal; +} + +template <> +inline GLeglClientBufferEXT GetParamVal( + const ParamValue &value) +{ + return value.GLeglClientBufferEXTVal; +} + +template <> +inline GLeglImageOES GetParamVal(const ParamValue &value) +{ + return value.GLeglImageOESVal; +} + +template <> +inline GLenum GetParamVal(const ParamValue &value) +{ + return value.GLenumVal; +} + +template <> +inline const GLenum *GetParamVal( + const ParamValue &value) +{ + return value.GLenumConstPointerVal; +} + +template <> +inline GLenum *GetParamVal(const ParamValue &value) +{ + return value.GLenumPointerVal; +} + +template <> +inline GLfixed GetParamVal(const ParamValue &value) +{ + return value.GLfixedVal; +} + +template <> +inline const GLfixed *GetParamVal( + const ParamValue &value) +{ + return value.GLfixedConstPointerVal; +} + +template <> +inline GLfixed *GetParamVal(const ParamValue &value) +{ + return value.GLfixedPointerVal; +} + +template <> +inline GLfloat GetParamVal(const ParamValue &value) +{ + return value.GLfloatVal; +} + +template <> +inline const GLfloat *GetParamVal( + const ParamValue &value) +{ + return value.GLfloatConstPointerVal; +} + +template <> +inline GLfloat *GetParamVal(const ParamValue &value) +{ + return value.GLfloatPointerVal; +} + +template <> +inline GLint GetParamVal(const ParamValue &value) +{ + return value.GLintVal; +} + +template <> +inline GLint64 *GetParamVal(const ParamValue &value) +{ + return value.GLint64PointerVal; +} + +template <> +inline const GLint *GetParamVal( + const ParamValue &value) +{ + return value.GLintConstPointerVal; +} + +template <> +inline GLint *GetParamVal(const ParamValue &value) +{ + return value.GLintPointerVal; +} + +template <> +inline GLintptr GetParamVal(const ParamValue &value) +{ + return value.GLintptrVal; +} + +template <> +inline const GLintptr *GetParamVal( + const ParamValue &value) +{ + return value.GLintptrConstPointerVal; +} + +template <> +inline GLshort GetParamVal(const ParamValue &value) +{ + return value.GLshortVal; +} + +template <> +inline const GLshort *GetParamVal( + const ParamValue &value) +{ + return value.GLshortConstPointerVal; +} + +template <> +inline GLsizei GetParamVal(const ParamValue &value) +{ + return value.GLsizeiVal; +} + +template <> +inline const GLsizei *GetParamVal( + const ParamValue &value) +{ + return value.GLsizeiConstPointerVal; +} + +template <> +inline GLsizei *GetParamVal(const ParamValue &value) +{ + return value.GLsizeiPointerVal; +} + +template <> +inline GLsizeiptr GetParamVal(const ParamValue &value) +{ + return value.GLsizeiptrVal; +} + +template <> +inline const GLsizeiptr *GetParamVal( + const ParamValue &value) +{ + return value.GLsizeiptrConstPointerVal; +} + +template <> +inline GLsync GetParamVal(const ParamValue &value) +{ + return value.GLsyncVal; +} + +template <> +inline GLubyte GetParamVal(const ParamValue &value) +{ + return value.GLubyteVal; +} + +template <> +inline const GLubyte *GetParamVal( + const ParamValue &value) +{ + return value.GLubyteConstPointerVal; +} + +template <> +inline GLubyte *GetParamVal(const ParamValue &value) +{ + return value.GLubytePointerVal; +} + +template <> +inline GLuint GetParamVal(const ParamValue &value) +{ + return value.GLuintVal; +} + +template <> +inline GLuint64 GetParamVal(const ParamValue &value) +{ + return value.GLuint64Val; +} + +template <> +inline const GLuint64 *GetParamVal( + const ParamValue &value) +{ + return value.GLuint64ConstPointerVal; +} + +template <> +inline GLuint64 *GetParamVal(const ParamValue &value) +{ + return value.GLuint64PointerVal; +} + +template <> +inline const GLuint *GetParamVal( + const ParamValue &value) +{ + return value.GLuintConstPointerVal; +} + +template <> +inline GLuint *GetParamVal(const ParamValue &value) +{ + return value.GLuintPointerVal; +} + +template <> +inline GLushort GetParamVal(const ParamValue &value) +{ + return value.GLushortVal; +} + +template <> +inline const GLushort *GetParamVal( + const ParamValue &value) +{ + return value.GLushortConstPointerVal; +} + +template <> +inline GLushort *GetParamVal(const ParamValue &value) +{ + return value.GLushortPointerVal; +} + +template <> +inline const GLvoid *GetParamVal( + const ParamValue &value) +{ + return value.GLvoidConstPointerVal; +} + +template <> +inline const GLvoid *const * +GetParamVal(const ParamValue &value) +{ + return value.GLvoidConstPointerPointerVal; +} + +template <> +inline gl::GraphicsResetStatus +GetParamVal(const ParamValue &value) +{ + return value.GraphicsResetStatusVal; +} + +template <> +inline gl::HandleType GetParamVal(const ParamValue &value) +{ + return value.HandleTypeVal; +} + +template <> +inline gl::LightParameter GetParamVal( + const ParamValue &value) +{ + return value.LightParameterVal; +} + +template <> +inline gl::LogicalOperation GetParamVal( + const ParamValue &value) +{ + return value.LogicalOperationVal; +} + +template <> +inline gl::MaterialParameter GetParamVal( + const ParamValue &value) +{ + return value.MaterialParameterVal; +} + +template <> +inline gl::MatrixType GetParamVal(const ParamValue &value) +{ + return value.MatrixTypeVal; +} + +template <> +inline gl::MemoryObjectID GetParamVal( + const ParamValue &value) +{ + return value.MemoryObjectIDVal; +} + +template <> +inline const gl::MemoryObjectID *GetParamVal(const ParamValue &value) +{ + return value.MemoryObjectIDConstPointerVal; +} + +template <> +inline gl::MemoryObjectID *GetParamVal( + const ParamValue &value) +{ + return value.MemoryObjectIDPointerVal; +} + +template <> +inline egl::ObjectType GetParamVal(const ParamValue &value) +{ + return value.ObjectTypeVal; +} + +template <> +inline gl::PointParameter GetParamVal( + const ParamValue &value) +{ + return value.PointParameterVal; +} + +template <> +inline gl::PrimitiveMode GetParamVal( + const ParamValue &value) +{ + return value.PrimitiveModeVal; +} + +template <> +inline gl::ProgramPipelineID GetParamVal( + const ParamValue &value) +{ + return value.ProgramPipelineIDVal; +} + +template <> +inline const gl::ProgramPipelineID * +GetParamVal( + const ParamValue &value) +{ + return value.ProgramPipelineIDConstPointerVal; +} + +template <> +inline gl::ProgramPipelineID * +GetParamVal(const ParamValue &value) +{ + return value.ProgramPipelineIDPointerVal; +} + +template <> +inline gl::ProvokingVertexConvention +GetParamVal( + const ParamValue &value) +{ + return value.ProvokingVertexConventionVal; +} + +template <> +inline gl::QueryID GetParamVal(const ParamValue &value) +{ + return value.QueryIDVal; +} + +template <> +inline const gl::QueryID *GetParamVal( + const ParamValue &value) +{ + return value.QueryIDConstPointerVal; +} + +template <> +inline gl::QueryID *GetParamVal(const ParamValue &value) +{ + return value.QueryIDPointerVal; +} + +template <> +inline gl::QueryType GetParamVal(const ParamValue &value) +{ + return value.QueryTypeVal; +} + +template <> +inline gl::RenderbufferID GetParamVal( + const ParamValue &value) +{ + return value.RenderbufferIDVal; +} + +template <> +inline const gl::RenderbufferID *GetParamVal(const ParamValue &value) +{ + return value.RenderbufferIDConstPointerVal; +} + +template <> +inline gl::RenderbufferID *GetParamVal( + const ParamValue &value) +{ + return value.RenderbufferIDPointerVal; +} + +template <> +inline gl::SamplerID GetParamVal(const ParamValue &value) +{ + return value.SamplerIDVal; +} + +template <> +inline const gl::SamplerID *GetParamVal( + const ParamValue &value) +{ + return value.SamplerIDConstPointerVal; +} + +template <> +inline gl::SamplerID *GetParamVal( + const ParamValue &value) +{ + return value.SamplerIDPointerVal; +} + +template <> +inline gl::SemaphoreID GetParamVal( + const ParamValue &value) +{ + return value.SemaphoreIDVal; +} + +template <> +inline const gl::SemaphoreID * +GetParamVal(const ParamValue &value) +{ + return value.SemaphoreIDConstPointerVal; +} + +template <> +inline gl::SemaphoreID *GetParamVal( + const ParamValue &value) +{ + return value.SemaphoreIDPointerVal; +} + +template <> +inline gl::ShaderProgramID GetParamVal( + const ParamValue &value) +{ + return value.ShaderProgramIDVal; +} + +template <> +inline const gl::ShaderProgramID *GetParamVal(const ParamValue &value) +{ + return value.ShaderProgramIDConstPointerVal; +} + +template <> +inline gl::ShaderProgramID *GetParamVal( + const ParamValue &value) +{ + return value.ShaderProgramIDPointerVal; +} + +template <> +inline gl::ShaderType GetParamVal(const ParamValue &value) +{ + return value.ShaderTypeVal; +} + +template <> +inline gl::ShadingModel GetParamVal( + const ParamValue &value) +{ + return value.ShadingModelVal; +} + +template <> +inline gl::TextureEnvParameter +GetParamVal(const ParamValue &value) +{ + return value.TextureEnvParameterVal; +} + +template <> +inline gl::TextureEnvTarget GetParamVal( + const ParamValue &value) +{ + return value.TextureEnvTargetVal; +} + +template <> +inline gl::TextureID GetParamVal(const ParamValue &value) +{ + return value.TextureIDVal; +} + +template <> +inline const gl::TextureID *GetParamVal( + const ParamValue &value) +{ + return value.TextureIDConstPointerVal; +} + +template <> +inline gl::TextureID *GetParamVal( + const ParamValue &value) +{ + return value.TextureIDPointerVal; +} + +template <> +inline gl::TextureTarget GetParamVal( + const ParamValue &value) +{ + return value.TextureTargetVal; +} + +template <> +inline gl::TextureType GetParamVal( + const ParamValue &value) +{ + return value.TextureTypeVal; +} + +template <> +inline egl::Timestamp GetParamVal(const ParamValue &value) +{ + return value.TimestampVal; +} + +template <> +inline gl::TransformFeedbackID +GetParamVal(const ParamValue &value) +{ + return value.TransformFeedbackIDVal; +} + +template <> +inline const gl::TransformFeedbackID * +GetParamVal( + const ParamValue &value) +{ + return value.TransformFeedbackIDConstPointerVal; +} + +template <> +inline gl::TransformFeedbackID *GetParamVal(const ParamValue &value) +{ + return value.TransformFeedbackIDPointerVal; +} + +template <> +inline gl::UniformBlockIndex GetParamVal( + const ParamValue &value) +{ + return value.UniformBlockIndexVal; +} + +template <> +inline gl::UniformLocation GetParamVal( + const ParamValue &value) +{ + return value.UniformLocationVal; +} + +template <> +inline gl::VertexArrayID GetParamVal( + const ParamValue &value) +{ + return value.VertexArrayIDVal; +} + +template <> +inline const gl::VertexArrayID *GetParamVal(const ParamValue &value) +{ + return value.VertexArrayIDConstPointerVal; +} + +template <> +inline gl::VertexArrayID *GetParamVal( + const ParamValue &value) +{ + return value.VertexArrayIDPointerVal; +} + +template <> +inline gl::VertexAttribType GetParamVal( + const ParamValue &value) +{ + return value.VertexAttribTypeVal; +} + +template <> +inline const char *GetParamVal(const ParamValue &value) +{ + return value.charConstPointerVal; +} + +template <> +inline const void *GetParamVal(const ParamValue &value) +{ + return value.voidConstPointerVal; +} + +template <> +inline const void *const *GetParamVal( + const ParamValue &value) +{ + return value.voidConstPointerPointerVal; +} + +template <> +inline void *GetParamVal(const ParamValue &value) +{ + return value.voidPointerVal; +} + +template <> +inline void **GetParamVal(const ParamValue &value) +{ + return value.voidPointerPointerVal; +} + +template +T GetParamVal(const ParamValue &value) +{ + UNREACHABLE(); + return T(); +} + +template +T AccessParamValue(ParamType paramType, const ParamValue &value) +{ + switch (paramType) + { + case ParamType::TAHardwareBufferConstPointer: + return GetParamVal(value); + case ParamType::TAlphaTestFunc: + return GetParamVal(value); + case ParamType::TBufferBinding: + return GetParamVal(value); + case ParamType::TBufferID: + return GetParamVal(value); + case ParamType::TBufferIDConstPointer: + return GetParamVal(value); + case ParamType::TBufferIDPointer: + return GetParamVal(value); + case ParamType::TBufferUsage: + return GetParamVal(value); + case ParamType::TClientVertexArrayType: + return GetParamVal(value); + case ParamType::TCompositorTiming: + return GetParamVal(value); + case ParamType::TCullFaceMode: + return GetParamVal(value); + case ParamType::TDrawElementsType: + return GetParamVal(value); + case ParamType::TEGLAttrib: + return GetParamVal(value); + case ParamType::TEGLAttribKHR: + return GetParamVal(value); + case ParamType::TEGLBoolean: + return GetParamVal(value); + case ParamType::TEGLClientBuffer: + return GetParamVal(value); + case ParamType::TEGLConfig: + return GetParamVal(value); + case ParamType::TEGLContext: + return GetParamVal(value); + case ParamType::TEGLDEBUGPROCKHR: + return GetParamVal(value); + case ParamType::TEGLDeviceEXT: + return GetParamVal(value); + case ParamType::TEGLDisplay: + return GetParamVal(value); + case ParamType::TEGLFrameTokenANGLE: + return GetParamVal(value); + case ParamType::TEGLGetBlobFuncANDROID: + return GetParamVal(value); + case ParamType::TEGLImage: + return GetParamVal(value); + case ParamType::TEGLLabelKHR: + return GetParamVal(value); + case ParamType::TEGLNativeDisplayType: + return GetParamVal(value); + case ParamType::TEGLNativePixmapType: + return GetParamVal(value); + case ParamType::TEGLNativeWindowType: + return GetParamVal(value); + case ParamType::TEGLObjectKHR: + return GetParamVal(value); + case ParamType::TEGLSetBlobFuncANDROID: + return GetParamVal(value); + case ParamType::TEGLStreamKHR: + return GetParamVal(value); + case ParamType::TEGLSurface: + return GetParamVal(value); + case ParamType::TEGLSync: + return GetParamVal(value); + case ParamType::TEGLTime: + return GetParamVal(value); + case ParamType::TEGLTimeKHR: + return GetParamVal(value); + case ParamType::TEGLenum: + return GetParamVal(value); + case ParamType::TEGLint: + return GetParamVal(value); + case ParamType::TEGLnsecsANDROID: + return GetParamVal(value); + case ParamType::TEGLuint64KHR: + return GetParamVal(value); + case ParamType::TFenceNVID: + return GetParamVal(value); + case ParamType::TFenceNVIDConstPointer: + return GetParamVal(value); + case ParamType::TFenceNVIDPointer: + return GetParamVal(value); + case ParamType::TFramebufferID: + return GetParamVal(value); + case ParamType::TFramebufferIDConstPointer: + return GetParamVal(value); + case ParamType::TFramebufferIDPointer: + return GetParamVal(value); + case ParamType::TGLDEBUGPROC: + return GetParamVal(value); + case ParamType::TGLDEBUGPROCKHR: + return GetParamVal(value); + case ParamType::TGLbitfield: + return GetParamVal(value); + case ParamType::TGLboolean: + return GetParamVal(value); + case ParamType::TGLbooleanConstPointer: + return GetParamVal(value); + case ParamType::TGLbooleanPointer: + return GetParamVal(value); + case ParamType::TGLbyte: + return GetParamVal(value); + case ParamType::TGLbyteConstPointer: + return GetParamVal(value); + case ParamType::TGLcharConstPointer: + return GetParamVal(value); + case ParamType::TGLcharConstPointerPointer: + return GetParamVal(value); + case ParamType::TGLcharPointer: + return GetParamVal(value); + case ParamType::TGLclampx: + return GetParamVal(value); + case ParamType::TGLdouble: + return GetParamVal(value); + case ParamType::TGLdoubleConstPointer: + return GetParamVal(value); + case ParamType::TGLdoublePointer: + return GetParamVal(value); + case ParamType::TGLeglClientBufferEXT: + return GetParamVal(value); + case ParamType::TGLeglImageOES: + return GetParamVal(value); + case ParamType::TGLenum: + return GetParamVal(value); + case ParamType::TGLenumConstPointer: + return GetParamVal(value); + case ParamType::TGLenumPointer: + return GetParamVal(value); + case ParamType::TGLfixed: + return GetParamVal(value); + case ParamType::TGLfixedConstPointer: + return GetParamVal(value); + case ParamType::TGLfixedPointer: + return GetParamVal(value); + case ParamType::TGLfloat: + return GetParamVal(value); + case ParamType::TGLfloatConstPointer: + return GetParamVal(value); + case ParamType::TGLfloatPointer: + return GetParamVal(value); + case ParamType::TGLint: + return GetParamVal(value); + case ParamType::TGLint64Pointer: + return GetParamVal(value); + case ParamType::TGLintConstPointer: + return GetParamVal(value); + case ParamType::TGLintPointer: + return GetParamVal(value); + case ParamType::TGLintptr: + return GetParamVal(value); + case ParamType::TGLintptrConstPointer: + return GetParamVal(value); + case ParamType::TGLshort: + return GetParamVal(value); + case ParamType::TGLshortConstPointer: + return GetParamVal(value); + case ParamType::TGLsizei: + return GetParamVal(value); + case ParamType::TGLsizeiConstPointer: + return GetParamVal(value); + case ParamType::TGLsizeiPointer: + return GetParamVal(value); + case ParamType::TGLsizeiptr: + return GetParamVal(value); + case ParamType::TGLsizeiptrConstPointer: + return GetParamVal(value); + case ParamType::TGLsync: + return GetParamVal(value); + case ParamType::TGLubyte: + return GetParamVal(value); + case ParamType::TGLubyteConstPointer: + return GetParamVal(value); + case ParamType::TGLubytePointer: + return GetParamVal(value); + case ParamType::TGLuint: + return GetParamVal(value); + case ParamType::TGLuint64: + return GetParamVal(value); + case ParamType::TGLuint64ConstPointer: + return GetParamVal(value); + case ParamType::TGLuint64Pointer: + return GetParamVal(value); + case ParamType::TGLuintConstPointer: + return GetParamVal(value); + case ParamType::TGLuintPointer: + return GetParamVal(value); + case ParamType::TGLushort: + return GetParamVal(value); + case ParamType::TGLushortConstPointer: + return GetParamVal(value); + case ParamType::TGLushortPointer: + return GetParamVal(value); + case ParamType::TGLvoidConstPointer: + return GetParamVal(value); + case ParamType::TGLvoidConstPointerPointer: + return GetParamVal(value); + case ParamType::TGraphicsResetStatus: + return GetParamVal(value); + case ParamType::THandleType: + return GetParamVal(value); + case ParamType::TLightParameter: + return GetParamVal(value); + case ParamType::TLogicalOperation: + return GetParamVal(value); + case ParamType::TMaterialParameter: + return GetParamVal(value); + case ParamType::TMatrixType: + return GetParamVal(value); + case ParamType::TMemoryObjectID: + return GetParamVal(value); + case ParamType::TMemoryObjectIDConstPointer: + return GetParamVal(value); + case ParamType::TMemoryObjectIDPointer: + return GetParamVal(value); + case ParamType::TObjectType: + return GetParamVal(value); + case ParamType::TPointParameter: + return GetParamVal(value); + case ParamType::TPrimitiveMode: + return GetParamVal(value); + case ParamType::TProgramPipelineID: + return GetParamVal(value); + case ParamType::TProgramPipelineIDConstPointer: + return GetParamVal(value); + case ParamType::TProgramPipelineIDPointer: + return GetParamVal(value); + case ParamType::TProvokingVertexConvention: + return GetParamVal(value); + case ParamType::TQueryID: + return GetParamVal(value); + case ParamType::TQueryIDConstPointer: + return GetParamVal(value); + case ParamType::TQueryIDPointer: + return GetParamVal(value); + case ParamType::TQueryType: + return GetParamVal(value); + case ParamType::TRenderbufferID: + return GetParamVal(value); + case ParamType::TRenderbufferIDConstPointer: + return GetParamVal(value); + case ParamType::TRenderbufferIDPointer: + return GetParamVal(value); + case ParamType::TSamplerID: + return GetParamVal(value); + case ParamType::TSamplerIDConstPointer: + return GetParamVal(value); + case ParamType::TSamplerIDPointer: + return GetParamVal(value); + case ParamType::TSemaphoreID: + return GetParamVal(value); + case ParamType::TSemaphoreIDConstPointer: + return GetParamVal(value); + case ParamType::TSemaphoreIDPointer: + return GetParamVal(value); + case ParamType::TShaderProgramID: + return GetParamVal(value); + case ParamType::TShaderProgramIDConstPointer: + return GetParamVal(value); + case ParamType::TShaderProgramIDPointer: + return GetParamVal(value); + case ParamType::TShaderType: + return GetParamVal(value); + case ParamType::TShadingModel: + return GetParamVal(value); + case ParamType::TTextureEnvParameter: + return GetParamVal(value); + case ParamType::TTextureEnvTarget: + return GetParamVal(value); + case ParamType::TTextureID: + return GetParamVal(value); + case ParamType::TTextureIDConstPointer: + return GetParamVal(value); + case ParamType::TTextureIDPointer: + return GetParamVal(value); + case ParamType::TTextureTarget: + return GetParamVal(value); + case ParamType::TTextureType: + return GetParamVal(value); + case ParamType::TTimestamp: + return GetParamVal(value); + case ParamType::TTransformFeedbackID: + return GetParamVal(value); + case ParamType::TTransformFeedbackIDConstPointer: + return GetParamVal(value); + case ParamType::TTransformFeedbackIDPointer: + return GetParamVal(value); + case ParamType::TUniformBlockIndex: + return GetParamVal(value); + case ParamType::TUniformLocation: + return GetParamVal(value); + case ParamType::TVertexArrayID: + return GetParamVal(value); + case ParamType::TVertexArrayIDConstPointer: + return GetParamVal(value); + case ParamType::TVertexArrayIDPointer: + return GetParamVal(value); + case ParamType::TVertexAttribType: + return GetParamVal(value); + case ParamType::TcharConstPointer: + return GetParamVal(value); + case ParamType::TvoidConstPointer: + return GetParamVal(value); + case ParamType::TvoidConstPointerPointer: + return GetParamVal(value); + case ParamType::TvoidPointer: + return GetParamVal(value); + case ParamType::TvoidPointerPointer: + return GetParamVal(value); + } + UNREACHABLE(); + return T(); +} + +template +void SetParamVal(T valueIn, ParamValue *valueOut); + +template <> +inline void SetParamVal(const AHardwareBuffer *valueIn, + ParamValue *valueOut) +{ + valueOut->AHardwareBufferConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(gl::AlphaTestFunc valueIn, ParamValue *valueOut) +{ + valueOut->AlphaTestFuncVal = valueIn; +} + +template <> +inline void SetParamVal(gl::BufferBinding valueIn, ParamValue *valueOut) +{ + valueOut->BufferBindingVal = valueIn; +} + +template <> +inline void SetParamVal(gl::BufferID valueIn, ParamValue *valueOut) +{ + valueOut->BufferIDVal = valueIn; +} + +template <> +inline void SetParamVal(const gl::BufferID *valueIn, + ParamValue *valueOut) +{ + valueOut->BufferIDConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(gl::BufferID *valueIn, ParamValue *valueOut) +{ + valueOut->BufferIDPointerVal = valueIn; +} + +template <> +inline void SetParamVal(gl::BufferUsage valueIn, ParamValue *valueOut) +{ + valueOut->BufferUsageVal = valueIn; +} + +template <> +inline void SetParamVal(gl::ClientVertexArrayType valueIn, + ParamValue *valueOut) +{ + valueOut->ClientVertexArrayTypeVal = valueIn; +} + +template <> +inline void SetParamVal(egl::CompositorTiming valueIn, + ParamValue *valueOut) +{ + valueOut->CompositorTimingVal = valueIn; +} + +template <> +inline void SetParamVal(gl::CullFaceMode valueIn, ParamValue *valueOut) +{ + valueOut->CullFaceModeVal = valueIn; +} + +template <> +inline void SetParamVal(gl::DrawElementsType valueIn, + ParamValue *valueOut) +{ + valueOut->DrawElementsTypeVal = valueIn; +} + +template <> +inline void SetParamVal(EGLAttrib valueIn, ParamValue *valueOut) +{ + valueOut->EGLAttribVal = valueIn; +} + +template <> +inline void SetParamVal(EGLAttribKHR valueIn, ParamValue *valueOut) +{ + valueOut->EGLAttribKHRVal = valueIn; +} + +template <> +inline void SetParamVal(EGLBoolean valueIn, ParamValue *valueOut) +{ + valueOut->EGLBooleanVal = valueIn; +} + +template <> +inline void SetParamVal(EGLClientBuffer valueIn, ParamValue *valueOut) +{ + valueOut->EGLClientBufferVal = valueIn; +} + +template <> +inline void SetParamVal(EGLConfig valueIn, ParamValue *valueOut) +{ + valueOut->EGLConfigVal = valueIn; +} + +template <> +inline void SetParamVal(EGLContext valueIn, ParamValue *valueOut) +{ + valueOut->EGLContextVal = valueIn; +} + +template <> +inline void SetParamVal(EGLDEBUGPROCKHR valueIn, ParamValue *valueOut) +{ + valueOut->EGLDEBUGPROCKHRVal = valueIn; +} + +template <> +inline void SetParamVal(EGLDeviceEXT valueIn, ParamValue *valueOut) +{ + valueOut->EGLDeviceEXTVal = valueIn; +} + +template <> +inline void SetParamVal(EGLDisplay valueIn, ParamValue *valueOut) +{ + valueOut->EGLDisplayVal = valueIn; +} + +template <> +inline void SetParamVal(EGLFrameTokenANGLE valueIn, + ParamValue *valueOut) +{ + valueOut->EGLFrameTokenANGLEVal = valueIn; +} + +template <> +inline void SetParamVal(EGLGetBlobFuncANDROID valueIn, + ParamValue *valueOut) +{ + valueOut->EGLGetBlobFuncANDROIDVal = valueIn; +} + +template <> +inline void SetParamVal(EGLImage valueIn, ParamValue *valueOut) +{ + valueOut->EGLImageVal = valueIn; +} + +template <> +inline void SetParamVal(EGLLabelKHR valueIn, ParamValue *valueOut) +{ + valueOut->EGLLabelKHRVal = valueIn; +} + +template <> +inline void SetParamVal(EGLNativeDisplayType valueIn, + ParamValue *valueOut) +{ + valueOut->EGLNativeDisplayTypeVal = valueIn; +} + +template <> +inline void SetParamVal(EGLNativePixmapType valueIn, + ParamValue *valueOut) +{ + valueOut->EGLNativePixmapTypeVal = valueIn; +} + +template <> +inline void SetParamVal(EGLNativeWindowType valueIn, + ParamValue *valueOut) +{ + valueOut->EGLNativeWindowTypeVal = valueIn; +} + +template <> +inline void SetParamVal(EGLObjectKHR valueIn, ParamValue *valueOut) +{ + valueOut->EGLObjectKHRVal = valueIn; +} + +template <> +inline void SetParamVal(EGLSetBlobFuncANDROID valueIn, + ParamValue *valueOut) +{ + valueOut->EGLSetBlobFuncANDROIDVal = valueIn; +} + +template <> +inline void SetParamVal(EGLStreamKHR valueIn, ParamValue *valueOut) +{ + valueOut->EGLStreamKHRVal = valueIn; +} + +template <> +inline void SetParamVal(EGLSurface valueIn, ParamValue *valueOut) +{ + valueOut->EGLSurfaceVal = valueIn; +} + +template <> +inline void SetParamVal(EGLSync valueIn, ParamValue *valueOut) +{ + valueOut->EGLSyncVal = valueIn; +} + +template <> +inline void SetParamVal(EGLTime valueIn, ParamValue *valueOut) +{ + valueOut->EGLTimeVal = valueIn; +} + +template <> +inline void SetParamVal(EGLTimeKHR valueIn, ParamValue *valueOut) +{ + valueOut->EGLTimeKHRVal = valueIn; +} + +template <> +inline void SetParamVal(EGLenum valueIn, ParamValue *valueOut) +{ + valueOut->EGLenumVal = valueIn; +} + +template <> +inline void SetParamVal(EGLint valueIn, ParamValue *valueOut) +{ + valueOut->EGLintVal = valueIn; +} + +template <> +inline void SetParamVal(EGLnsecsANDROID valueIn, ParamValue *valueOut) +{ + valueOut->EGLnsecsANDROIDVal = valueIn; +} + +template <> +inline void SetParamVal(EGLuint64KHR valueIn, ParamValue *valueOut) +{ + valueOut->EGLuint64KHRVal = valueIn; +} + +template <> +inline void SetParamVal(gl::FenceNVID valueIn, ParamValue *valueOut) +{ + valueOut->FenceNVIDVal = valueIn; +} + +template <> +inline void SetParamVal(const gl::FenceNVID *valueIn, + ParamValue *valueOut) +{ + valueOut->FenceNVIDConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(gl::FenceNVID *valueIn, ParamValue *valueOut) +{ + valueOut->FenceNVIDPointerVal = valueIn; +} + +template <> +inline void SetParamVal(gl::FramebufferID valueIn, ParamValue *valueOut) +{ + valueOut->FramebufferIDVal = valueIn; +} + +template <> +inline void SetParamVal(const gl::FramebufferID *valueIn, + ParamValue *valueOut) +{ + valueOut->FramebufferIDConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(gl::FramebufferID *valueIn, + ParamValue *valueOut) +{ + valueOut->FramebufferIDPointerVal = valueIn; +} + +template <> +inline void SetParamVal(GLDEBUGPROC valueIn, ParamValue *valueOut) +{ + valueOut->GLDEBUGPROCVal = valueIn; +} + +template <> +inline void SetParamVal(GLDEBUGPROCKHR valueIn, ParamValue *valueOut) +{ + valueOut->GLDEBUGPROCKHRVal = valueIn; +} + +template <> +inline void SetParamVal(GLbitfield valueIn, ParamValue *valueOut) +{ + valueOut->GLbitfieldVal = valueIn; +} + +template <> +inline void SetParamVal(GLboolean valueIn, ParamValue *valueOut) +{ + valueOut->GLbooleanVal = valueIn; +} + +template <> +inline void SetParamVal(const GLboolean *valueIn, + ParamValue *valueOut) +{ + valueOut->GLbooleanConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(GLboolean *valueIn, ParamValue *valueOut) +{ + valueOut->GLbooleanPointerVal = valueIn; +} + +template <> +inline void SetParamVal(GLbyte valueIn, ParamValue *valueOut) +{ + valueOut->GLbyteVal = valueIn; +} + +template <> +inline void SetParamVal(const GLbyte *valueIn, ParamValue *valueOut) +{ + valueOut->GLbyteConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(const GLchar *valueIn, ParamValue *valueOut) +{ + valueOut->GLcharConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(const GLchar *const *valueIn, + ParamValue *valueOut) +{ + valueOut->GLcharConstPointerPointerVal = valueIn; +} + +template <> +inline void SetParamVal(GLchar *valueIn, ParamValue *valueOut) +{ + valueOut->GLcharPointerVal = valueIn; +} + +template <> +inline void SetParamVal(GLclampx valueIn, ParamValue *valueOut) +{ + valueOut->GLclampxVal = valueIn; +} + +template <> +inline void SetParamVal(GLdouble valueIn, ParamValue *valueOut) +{ + valueOut->GLdoubleVal = valueIn; +} + +template <> +inline void SetParamVal(const GLdouble *valueIn, + ParamValue *valueOut) +{ + valueOut->GLdoubleConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(GLdouble *valueIn, ParamValue *valueOut) +{ + valueOut->GLdoublePointerVal = valueIn; +} + +template <> +inline void SetParamVal(GLeglClientBufferEXT valueIn, + ParamValue *valueOut) +{ + valueOut->GLeglClientBufferEXTVal = valueIn; +} + +template <> +inline void SetParamVal(GLeglImageOES valueIn, ParamValue *valueOut) +{ + valueOut->GLeglImageOESVal = valueIn; +} + +template <> +inline void SetParamVal(GLenum valueIn, ParamValue *valueOut) +{ + valueOut->GLenumVal = valueIn; +} + +template <> +inline void SetParamVal(const GLenum *valueIn, ParamValue *valueOut) +{ + valueOut->GLenumConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(GLenum *valueIn, ParamValue *valueOut) +{ + valueOut->GLenumPointerVal = valueIn; +} + +template <> +inline void SetParamVal(GLfixed valueIn, ParamValue *valueOut) +{ + valueOut->GLfixedVal = valueIn; +} + +template <> +inline void SetParamVal(const GLfixed *valueIn, + ParamValue *valueOut) +{ + valueOut->GLfixedConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(GLfixed *valueIn, ParamValue *valueOut) +{ + valueOut->GLfixedPointerVal = valueIn; +} + +template <> +inline void SetParamVal(GLfloat valueIn, ParamValue *valueOut) +{ + valueOut->GLfloatVal = valueIn; +} + +template <> +inline void SetParamVal(const GLfloat *valueIn, + ParamValue *valueOut) +{ + valueOut->GLfloatConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(GLfloat *valueIn, ParamValue *valueOut) +{ + valueOut->GLfloatPointerVal = valueIn; +} + +template <> +inline void SetParamVal(GLint valueIn, ParamValue *valueOut) +{ + valueOut->GLintVal = valueIn; +} + +template <> +inline void SetParamVal(GLint64 *valueIn, ParamValue *valueOut) +{ + valueOut->GLint64PointerVal = valueIn; +} + +template <> +inline void SetParamVal(const GLint *valueIn, ParamValue *valueOut) +{ + valueOut->GLintConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(GLint *valueIn, ParamValue *valueOut) +{ + valueOut->GLintPointerVal = valueIn; +} + +template <> +inline void SetParamVal(GLintptr valueIn, ParamValue *valueOut) +{ + valueOut->GLintptrVal = valueIn; +} + +template <> +inline void SetParamVal(const GLintptr *valueIn, + ParamValue *valueOut) +{ + valueOut->GLintptrConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(GLshort valueIn, ParamValue *valueOut) +{ + valueOut->GLshortVal = valueIn; +} + +template <> +inline void SetParamVal(const GLshort *valueIn, + ParamValue *valueOut) +{ + valueOut->GLshortConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(GLsizei valueIn, ParamValue *valueOut) +{ + valueOut->GLsizeiVal = valueIn; +} + +template <> +inline void SetParamVal(const GLsizei *valueIn, + ParamValue *valueOut) +{ + valueOut->GLsizeiConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(GLsizei *valueIn, ParamValue *valueOut) +{ + valueOut->GLsizeiPointerVal = valueIn; +} + +template <> +inline void SetParamVal(GLsizeiptr valueIn, ParamValue *valueOut) +{ + valueOut->GLsizeiptrVal = valueIn; +} + +template <> +inline void SetParamVal(const GLsizeiptr *valueIn, + ParamValue *valueOut) +{ + valueOut->GLsizeiptrConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(GLsync valueIn, ParamValue *valueOut) +{ + valueOut->GLsyncVal = valueIn; +} + +template <> +inline void SetParamVal(GLubyte valueIn, ParamValue *valueOut) +{ + valueOut->GLubyteVal = valueIn; +} + +template <> +inline void SetParamVal(const GLubyte *valueIn, + ParamValue *valueOut) +{ + valueOut->GLubyteConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(GLubyte *valueIn, ParamValue *valueOut) +{ + valueOut->GLubytePointerVal = valueIn; +} + +template <> +inline void SetParamVal(GLuint valueIn, ParamValue *valueOut) +{ + valueOut->GLuintVal = valueIn; +} + +template <> +inline void SetParamVal(GLuint64 valueIn, ParamValue *valueOut) +{ + valueOut->GLuint64Val = valueIn; +} + +template <> +inline void SetParamVal(const GLuint64 *valueIn, + ParamValue *valueOut) +{ + valueOut->GLuint64ConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(GLuint64 *valueIn, ParamValue *valueOut) +{ + valueOut->GLuint64PointerVal = valueIn; +} + +template <> +inline void SetParamVal(const GLuint *valueIn, ParamValue *valueOut) +{ + valueOut->GLuintConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(GLuint *valueIn, ParamValue *valueOut) +{ + valueOut->GLuintPointerVal = valueIn; +} + +template <> +inline void SetParamVal(GLushort valueIn, ParamValue *valueOut) +{ + valueOut->GLushortVal = valueIn; +} + +template <> +inline void SetParamVal(const GLushort *valueIn, + ParamValue *valueOut) +{ + valueOut->GLushortConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(GLushort *valueIn, ParamValue *valueOut) +{ + valueOut->GLushortPointerVal = valueIn; +} + +template <> +inline void SetParamVal(const GLvoid *valueIn, ParamValue *valueOut) +{ + valueOut->GLvoidConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(const GLvoid *const *valueIn, + ParamValue *valueOut) +{ + valueOut->GLvoidConstPointerPointerVal = valueIn; +} + +template <> +inline void SetParamVal(gl::GraphicsResetStatus valueIn, + ParamValue *valueOut) +{ + valueOut->GraphicsResetStatusVal = valueIn; +} + +template <> +inline void SetParamVal(gl::HandleType valueIn, ParamValue *valueOut) +{ + valueOut->HandleTypeVal = valueIn; +} + +template <> +inline void SetParamVal(gl::LightParameter valueIn, + ParamValue *valueOut) +{ + valueOut->LightParameterVal = valueIn; +} + +template <> +inline void SetParamVal(gl::LogicalOperation valueIn, + ParamValue *valueOut) +{ + valueOut->LogicalOperationVal = valueIn; +} + +template <> +inline void SetParamVal(gl::MaterialParameter valueIn, + ParamValue *valueOut) +{ + valueOut->MaterialParameterVal = valueIn; +} + +template <> +inline void SetParamVal(gl::MatrixType valueIn, ParamValue *valueOut) +{ + valueOut->MatrixTypeVal = valueIn; +} + +template <> +inline void SetParamVal(gl::MemoryObjectID valueIn, + ParamValue *valueOut) +{ + valueOut->MemoryObjectIDVal = valueIn; +} + +template <> +inline void SetParamVal(const gl::MemoryObjectID *valueIn, + ParamValue *valueOut) +{ + valueOut->MemoryObjectIDConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(gl::MemoryObjectID *valueIn, + ParamValue *valueOut) +{ + valueOut->MemoryObjectIDPointerVal = valueIn; +} + +template <> +inline void SetParamVal(egl::ObjectType valueIn, ParamValue *valueOut) +{ + valueOut->ObjectTypeVal = valueIn; +} + +template <> +inline void SetParamVal(gl::PointParameter valueIn, + ParamValue *valueOut) +{ + valueOut->PointParameterVal = valueIn; +} + +template <> +inline void SetParamVal(gl::PrimitiveMode valueIn, ParamValue *valueOut) +{ + valueOut->PrimitiveModeVal = valueIn; +} + +template <> +inline void SetParamVal(gl::ProgramPipelineID valueIn, + ParamValue *valueOut) +{ + valueOut->ProgramPipelineIDVal = valueIn; +} + +template <> +inline void SetParamVal( + const gl::ProgramPipelineID *valueIn, + ParamValue *valueOut) +{ + valueOut->ProgramPipelineIDConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(gl::ProgramPipelineID *valueIn, + ParamValue *valueOut) +{ + valueOut->ProgramPipelineIDPointerVal = valueIn; +} + +template <> +inline void SetParamVal( + gl::ProvokingVertexConvention valueIn, + ParamValue *valueOut) +{ + valueOut->ProvokingVertexConventionVal = valueIn; +} + +template <> +inline void SetParamVal(gl::QueryID valueIn, ParamValue *valueOut) +{ + valueOut->QueryIDVal = valueIn; +} + +template <> +inline void SetParamVal(const gl::QueryID *valueIn, + ParamValue *valueOut) +{ + valueOut->QueryIDConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(gl::QueryID *valueIn, ParamValue *valueOut) +{ + valueOut->QueryIDPointerVal = valueIn; +} + +template <> +inline void SetParamVal(gl::QueryType valueIn, ParamValue *valueOut) +{ + valueOut->QueryTypeVal = valueIn; +} + +template <> +inline void SetParamVal(gl::RenderbufferID valueIn, + ParamValue *valueOut) +{ + valueOut->RenderbufferIDVal = valueIn; +} + +template <> +inline void SetParamVal(const gl::RenderbufferID *valueIn, + ParamValue *valueOut) +{ + valueOut->RenderbufferIDConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(gl::RenderbufferID *valueIn, + ParamValue *valueOut) +{ + valueOut->RenderbufferIDPointerVal = valueIn; +} + +template <> +inline void SetParamVal(gl::SamplerID valueIn, ParamValue *valueOut) +{ + valueOut->SamplerIDVal = valueIn; +} + +template <> +inline void SetParamVal(const gl::SamplerID *valueIn, + ParamValue *valueOut) +{ + valueOut->SamplerIDConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(gl::SamplerID *valueIn, ParamValue *valueOut) +{ + valueOut->SamplerIDPointerVal = valueIn; +} + +template <> +inline void SetParamVal(gl::SemaphoreID valueIn, ParamValue *valueOut) +{ + valueOut->SemaphoreIDVal = valueIn; +} + +template <> +inline void SetParamVal(const gl::SemaphoreID *valueIn, + ParamValue *valueOut) +{ + valueOut->SemaphoreIDConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(gl::SemaphoreID *valueIn, + ParamValue *valueOut) +{ + valueOut->SemaphoreIDPointerVal = valueIn; +} + +template <> +inline void SetParamVal(gl::ShaderProgramID valueIn, + ParamValue *valueOut) +{ + valueOut->ShaderProgramIDVal = valueIn; +} + +template <> +inline void SetParamVal(const gl::ShaderProgramID *valueIn, + ParamValue *valueOut) +{ + valueOut->ShaderProgramIDConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(gl::ShaderProgramID *valueIn, + ParamValue *valueOut) +{ + valueOut->ShaderProgramIDPointerVal = valueIn; +} + +template <> +inline void SetParamVal(gl::ShaderType valueIn, ParamValue *valueOut) +{ + valueOut->ShaderTypeVal = valueIn; +} + +template <> +inline void SetParamVal(gl::ShadingModel valueIn, ParamValue *valueOut) +{ + valueOut->ShadingModelVal = valueIn; +} + +template <> +inline void SetParamVal(gl::TextureEnvParameter valueIn, + ParamValue *valueOut) +{ + valueOut->TextureEnvParameterVal = valueIn; +} + +template <> +inline void SetParamVal(gl::TextureEnvTarget valueIn, + ParamValue *valueOut) +{ + valueOut->TextureEnvTargetVal = valueIn; +} + +template <> +inline void SetParamVal(gl::TextureID valueIn, ParamValue *valueOut) +{ + valueOut->TextureIDVal = valueIn; +} + +template <> +inline void SetParamVal(const gl::TextureID *valueIn, + ParamValue *valueOut) +{ + valueOut->TextureIDConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(gl::TextureID *valueIn, ParamValue *valueOut) +{ + valueOut->TextureIDPointerVal = valueIn; +} + +template <> +inline void SetParamVal(gl::TextureTarget valueIn, ParamValue *valueOut) +{ + valueOut->TextureTargetVal = valueIn; +} + +template <> +inline void SetParamVal(gl::TextureType valueIn, ParamValue *valueOut) +{ + valueOut->TextureTypeVal = valueIn; +} + +template <> +inline void SetParamVal(egl::Timestamp valueIn, ParamValue *valueOut) +{ + valueOut->TimestampVal = valueIn; +} + +template <> +inline void SetParamVal(gl::TransformFeedbackID valueIn, + ParamValue *valueOut) +{ + valueOut->TransformFeedbackIDVal = valueIn; +} + +template <> +inline void SetParamVal( + const gl::TransformFeedbackID *valueIn, + ParamValue *valueOut) +{ + valueOut->TransformFeedbackIDConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(gl::TransformFeedbackID *valueIn, + ParamValue *valueOut) +{ + valueOut->TransformFeedbackIDPointerVal = valueIn; +} + +template <> +inline void SetParamVal(gl::UniformBlockIndex valueIn, + ParamValue *valueOut) +{ + valueOut->UniformBlockIndexVal = valueIn; +} + +template <> +inline void SetParamVal(gl::UniformLocation valueIn, + ParamValue *valueOut) +{ + valueOut->UniformLocationVal = valueIn; +} + +template <> +inline void SetParamVal(gl::VertexArrayID valueIn, ParamValue *valueOut) +{ + valueOut->VertexArrayIDVal = valueIn; +} + +template <> +inline void SetParamVal(const gl::VertexArrayID *valueIn, + ParamValue *valueOut) +{ + valueOut->VertexArrayIDConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(gl::VertexArrayID *valueIn, + ParamValue *valueOut) +{ + valueOut->VertexArrayIDPointerVal = valueIn; +} + +template <> +inline void SetParamVal(gl::VertexAttribType valueIn, + ParamValue *valueOut) +{ + valueOut->VertexAttribTypeVal = valueIn; +} + +template <> +inline void SetParamVal(const char *valueIn, ParamValue *valueOut) +{ + valueOut->charConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(const void *valueIn, ParamValue *valueOut) +{ + valueOut->voidConstPointerVal = valueIn; +} + +template <> +inline void SetParamVal(const void *const *valueIn, + ParamValue *valueOut) +{ + valueOut->voidConstPointerPointerVal = valueIn; +} + +template <> +inline void SetParamVal(void *valueIn, ParamValue *valueOut) +{ + valueOut->voidPointerVal = valueIn; +} + +template <> +inline void SetParamVal(void **valueIn, ParamValue *valueOut) +{ + valueOut->voidPointerPointerVal = valueIn; +} + +template +void SetParamVal(T valueIn, ParamValue *valueOut) +{ + UNREACHABLE(); +} + +template +void InitParamValue(ParamType paramType, T valueIn, ParamValue *valueOut) +{ + switch (paramType) + { + case ParamType::TAHardwareBufferConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TAlphaTestFunc: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TBufferBinding: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TBufferID: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TBufferIDConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TBufferIDPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TBufferUsage: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TClientVertexArrayType: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TCompositorTiming: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TCullFaceMode: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TDrawElementsType: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TEGLAttrib: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TEGLAttribKHR: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TEGLBoolean: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TEGLClientBuffer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TEGLConfig: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TEGLContext: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TEGLDEBUGPROCKHR: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TEGLDeviceEXT: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TEGLDisplay: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TEGLFrameTokenANGLE: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TEGLGetBlobFuncANDROID: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TEGLImage: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TEGLLabelKHR: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TEGLNativeDisplayType: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TEGLNativePixmapType: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TEGLNativeWindowType: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TEGLObjectKHR: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TEGLSetBlobFuncANDROID: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TEGLStreamKHR: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TEGLSurface: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TEGLSync: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TEGLTime: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TEGLTimeKHR: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TEGLenum: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TEGLint: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TEGLnsecsANDROID: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TEGLuint64KHR: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TFenceNVID: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TFenceNVIDConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TFenceNVIDPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TFramebufferID: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TFramebufferIDConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TFramebufferIDPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLDEBUGPROC: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLDEBUGPROCKHR: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLbitfield: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLboolean: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLbooleanConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLbooleanPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLbyte: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLbyteConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLcharConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLcharConstPointerPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLcharPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLclampx: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLdouble: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLdoubleConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLdoublePointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLeglClientBufferEXT: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLeglImageOES: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLenum: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLenumConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLenumPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLfixed: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLfixedConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLfixedPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLfloat: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLfloatConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLfloatPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLint: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLint64Pointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLintConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLintPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLintptr: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLintptrConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLshort: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLshortConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLsizei: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLsizeiConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLsizeiPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLsizeiptr: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLsizeiptrConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLsync: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLubyte: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLubyteConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLubytePointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLuint: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLuint64: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLuint64ConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLuint64Pointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLuintConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLuintPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLushort: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLushortConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLushortPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLvoidConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGLvoidConstPointerPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TGraphicsResetStatus: + SetParamVal(valueIn, valueOut); + break; + case ParamType::THandleType: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TLightParameter: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TLogicalOperation: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TMaterialParameter: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TMatrixType: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TMemoryObjectID: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TMemoryObjectIDConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TMemoryObjectIDPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TObjectType: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TPointParameter: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TPrimitiveMode: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TProgramPipelineID: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TProgramPipelineIDConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TProgramPipelineIDPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TProvokingVertexConvention: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TQueryID: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TQueryIDConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TQueryIDPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TQueryType: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TRenderbufferID: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TRenderbufferIDConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TRenderbufferIDPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TSamplerID: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TSamplerIDConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TSamplerIDPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TSemaphoreID: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TSemaphoreIDConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TSemaphoreIDPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TShaderProgramID: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TShaderProgramIDConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TShaderProgramIDPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TShaderType: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TShadingModel: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TTextureEnvParameter: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TTextureEnvTarget: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TTextureID: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TTextureIDConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TTextureIDPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TTextureTarget: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TTextureType: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TTimestamp: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TTransformFeedbackID: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TTransformFeedbackIDConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TTransformFeedbackIDPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TUniformBlockIndex: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TUniformLocation: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TVertexArrayID: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TVertexArrayIDConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TVertexArrayIDPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TVertexAttribType: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TcharConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TvoidConstPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TvoidConstPointerPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TvoidPointer: + SetParamVal(valueIn, valueOut); + break; + case ParamType::TvoidPointerPointer: + SetParamVal(valueIn, valueOut); + break; + } +} + +struct CallCapture; +struct ParamCapture; + +void WriteParamCaptureReplay(std::ostream &os, const CallCapture &call, const ParamCapture ¶m); +const char *ParamTypeToString(ParamType paramType); + +enum class ResourceIDType +{ + Buffer, + FenceNV, + Framebuffer, + MemoryObject, + ProgramPipeline, + Query, + Renderbuffer, + Sampler, + Semaphore, + ShaderProgram, + Texture, + TransformFeedback, + VertexArray, + EnumCount, + InvalidEnum = EnumCount +}; + +ResourceIDType GetResourceIDTypeFromParamType(ParamType paramType); +const char *GetResourceIDTypeName(ResourceIDType resourceIDType); + +template +struct GetResourceIDTypeFromType; + +template <> +struct GetResourceIDTypeFromType +{ + static constexpr ResourceIDType IDType = ResourceIDType::Buffer; +}; + +template <> +struct GetResourceIDTypeFromType +{ + static constexpr ResourceIDType IDType = ResourceIDType::FenceNV; +}; + +template <> +struct GetResourceIDTypeFromType +{ + static constexpr ResourceIDType IDType = ResourceIDType::Framebuffer; +}; + +template <> +struct GetResourceIDTypeFromType +{ + static constexpr ResourceIDType IDType = ResourceIDType::MemoryObject; +}; + +template <> +struct GetResourceIDTypeFromType +{ + static constexpr ResourceIDType IDType = ResourceIDType::ProgramPipeline; +}; + +template <> +struct GetResourceIDTypeFromType +{ + static constexpr ResourceIDType IDType = ResourceIDType::Query; +}; + +template <> +struct GetResourceIDTypeFromType +{ + static constexpr ResourceIDType IDType = ResourceIDType::Renderbuffer; +}; + +template <> +struct GetResourceIDTypeFromType +{ + static constexpr ResourceIDType IDType = ResourceIDType::Sampler; +}; + +template <> +struct GetResourceIDTypeFromType +{ + static constexpr ResourceIDType IDType = ResourceIDType::Semaphore; +}; + +template <> +struct GetResourceIDTypeFromType +{ + static constexpr ResourceIDType IDType = ResourceIDType::ShaderProgram; +}; + +template <> +struct GetResourceIDTypeFromType +{ + static constexpr ResourceIDType IDType = ResourceIDType::Texture; +}; + +template <> +struct GetResourceIDTypeFromType +{ + static constexpr ResourceIDType IDType = ResourceIDType::TransformFeedback; +}; + +template <> +struct GetResourceIDTypeFromType +{ + static constexpr ResourceIDType IDType = ResourceIDType::VertexArray; +}; + +} // namespace angle + +#endif // LIBANGLE_FRAME_CAPTURE_UTILS_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/capture/frame_capture_utils_mock.cpp b/gfx/angle/checkout/src/libANGLE/capture/frame_capture_utils_mock.cpp new file mode 100644 index 0000000000..f136a3c17d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/capture/frame_capture_utils_mock.cpp @@ -0,0 +1,19 @@ +// +// Copyright 2021 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// frame_capture_utils_mock.cpp: +// ANGLE frame capture util stub implementation. +// + +#include "libANGLE/capture/frame_capture_utils.h" + +namespace angle +{ +Result SerializeContextToString(const gl::Context *context, std::string *stringOut) +{ + *stringOut = "SerializationNotAvailable"; + return angle::Result::Continue; +} +} // namespace angle diff --git a/gfx/angle/checkout/src/libANGLE/capture/gl_enum_utils.h b/gfx/angle/checkout/src/libANGLE/capture/gl_enum_utils.h new file mode 100644 index 0000000000..1fac416138 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/capture/gl_enum_utils.h @@ -0,0 +1,32 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// gl_enum_utils.h: +// Utility functions for converting GLenums to string. + +#ifndef LIBANGLE_GL_ENUM_UTILS_H_ +#define LIBANGLE_GL_ENUM_UTILS_H_ + +#include +#include + +#include "libANGLE/capture/gl_enum_utils_autogen.h" + +namespace gl +{ +const char *GLbooleanToString(unsigned int value); +const char *GLenumToString(GLESEnum enumGroup, unsigned int value); +const char *GLenumToString(BigGLEnum enumGroup, unsigned int value); +std::string GLbitfieldToString(GLESEnum enumGroup, unsigned int value); +std::string GLbitfieldToString(BigGLEnum enumGroup, unsigned int value); +void OutputGLenumString(std::ostream &out, GLESEnum enumGroup, unsigned int value); +void OutputGLenumString(std::ostream &out, BigGLEnum enumGroup, unsigned int value); +void OutputGLbitfieldString(std::ostream &out, GLESEnum enumGroup, unsigned int value); +const char *GLinternalFormatToString(unsigned int format); + +extern const char kUnknownGLenumString[]; +} // namespace gl + +#endif // LIBANGLE_GL_ENUM_UTILS_H_ diff --git a/gfx/angle/checkout/src/libANGLE/capture/gl_enum_utils_autogen.h b/gfx/angle/checkout/src/libANGLE/capture/gl_enum_utils_autogen.h new file mode 100644 index 0000000000..6d0fe3da3e --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/capture/gl_enum_utils_autogen.h @@ -0,0 +1,419 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_gl_enum_utils.py using data from gl.xml and gl_angle_ext.xml. +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// gl_enum_utils_autogen.h: +// mapping of GLenum value to string. + +#ifndef LIBANGLE_GL_ENUM_UTILS_AUTOGEN_H_ +#define LIBANGLE_GL_ENUM_UTILS_AUTOGEN_H_ + +namespace gl +{ +enum class GLESEnum +{ + AccumOp, + AllEnums, + AlphaFunction, + AtomicCounterBufferPName, + AttribMask, + AttributeType, + BindTransformFeedbackTarget, + BinormalPointerTypeEXT, + BlendEquationModeEXT, + BlendingFactor, + BlitFramebufferFilter, + Boolean, + Buffer, + BufferAccessARB, + BufferPNameARB, + BufferPointerNameARB, + BufferStorageMask, + BufferStorageTarget, + BufferTargetARB, + BufferUsageARB, + ClampColorModeARB, + ClearBufferMask, + ClipPlaneName, + ColorBuffer, + ColorMaterialParameter, + ColorPointerType, + CombinerBiasNV, + CombinerComponentUsageNV, + CombinerPortionNV, + CombinerScaleNV, + ContainerType, + ContextFlagMask, + CopyBufferSubDataTarget, + CopyImageSubDataTarget, + DebugSeverity, + DebugSource, + DebugType, + DepthFunction, + DepthStencilTextureMode, + DrawBufferMode, + DrawElementsType, + ElementPointerTypeATI, + EnableCap, + ErrorCode, + ExternalHandleType, + FenceConditionNV, + FenceParameterNameNV, + FogCoordinatePointerType, + FogMode, + FogPName, + FogParameter, + FogPointerTypeEXT, + FogPointerTypeIBM, + FragmentLightParameterSGIX, + FragmentShaderDestMaskATI, + FragmentShaderDestModMaskATI, + FragmentShaderGenericSourceATI, + FragmentShaderTextureSourceATI, + FragmentShaderValueRepATI, + FramebufferAttachment, + FramebufferAttachmentParameterName, + FramebufferParameterName, + FramebufferStatus, + FramebufferTarget, + FrontFaceDirection, + GetFramebufferParameter, + GetMultisamplePNameNV, + GetPName, + GetPointervPName, + GetTextureParameter, + GraphicsResetStatus, + HintMode, + HintTarget, + IndexFunctionEXT, + IndexPointerType, + InternalFormat, + InternalFormatPName, + InvalidateFramebufferAttachment, + LightEnvModeSGIX, + LightModelParameter, + LightName, + LightParameter, + ListNameType, + LogicOp, + MapBufferAccessMask, + MapTypeNV, + MaterialParameter, + MatrixIndexPointerTypeARB, + MatrixMode, + MemoryBarrierMask, + MemoryObjectParameterName, + NormalPointerType, + ObjectIdentifier, + PatchParameterName, + PathColor, + PathColorFormat, + PathFillMode, + PathFontStyle, + PathGenMode, + PathTransformType, + PipelineParameterName, + PixelCopyType, + PixelFormat, + PixelStoreParameter, + PixelTexGenModeSGIX, + PixelTransferParameter, + PixelType, + PointParameterNameARB, + PrecisionType, + PrimitiveType, + ProgramInterface, + ProgramInterfacePName, + ProgramParameterPName, + ProgramPropertyARB, + ProgramResourceProperty, + QueryCounterTarget, + QueryObjectParameterName, + QueryParameterName, + QueryTarget, + ReadBufferMode, + RenderbufferParameterName, + RenderbufferTarget, + ReplacementCodeTypeSUN, + SamplerParameterF, + SamplerParameterI, + ScalarType, + SecondaryColorPointerTypeIBM, + SemaphoreParameterName, + ShaderBinaryFormat, + ShaderParameterName, + ShaderType, + ShadingModel, + ShadingRateQCOM, + SizedInternalFormat, + StencilFunction, + StencilOp, + StringName, + SubroutineParameterName, + SyncBehaviorFlags, + SyncCondition, + SyncObjectMask, + SyncParameterName, + SyncStatus, + TangentPointerTypeEXT, + TexCoordPointerType, + TextureCompareMode, + TextureCoordName, + TextureEnvMode, + TextureEnvParameter, + TextureEnvTarget, + TextureGenParameter, + TextureLayout, + TextureMagFilter, + TextureMinFilter, + TextureParameterName, + TextureSwizzle, + TextureTarget, + TextureUnit, + TextureWrapMode, + TransformFeedbackBufferMode, + TransformFeedbackPName, + TriangleFace, + UniformBlockPName, + UniformPName, + UniformType, + UseProgramStageMask, + VertexArrayPName, + VertexAttribEnum, + VertexAttribIType, + VertexAttribPointerPropertyARB, + VertexAttribPointerType, + VertexAttribPropertyARB, + VertexAttribType, + VertexBufferObjectUsage, + VertexPointerType, + VertexProvokingMode, + VertexShaderTextureUnitParameter, + VertexShaderWriteMaskEXT, + VertexWeightPointerTypeEXT, + WeightPointerTypeARB +}; + +enum class BigGLEnum +{ + AccumOp, + AllEnums, + AlphaFunction, + AtomicCounterBufferPName, + AttribMask, + AttributeType, + BindTransformFeedbackTarget, + BinormalPointerTypeEXT, + BlendEquationModeEXT, + BlendingFactor, + BlitFramebufferFilter, + Boolean, + Buffer, + BufferAccessARB, + BufferPNameARB, + BufferPointerNameARB, + BufferStorageMask, + BufferStorageTarget, + BufferTargetARB, + BufferUsageARB, + ClampColorModeARB, + ClampColorTargetARB, + ClearBufferMask, + ClientAttribMask, + ClipControlDepth, + ClipControlOrigin, + ClipPlaneName, + ColorBuffer, + ColorMaterialParameter, + ColorPointerType, + ColorTableTarget, + ColorTableTargetSGI, + CombinerBiasNV, + CombinerComponentUsageNV, + CombinerPortionNV, + CombinerScaleNV, + ConditionalRenderMode, + ContainerType, + ContextFlagMask, + ContextProfileMask, + ConvolutionTarget, + ConvolutionTargetEXT, + CopyBufferSubDataTarget, + CopyImageSubDataTarget, + DebugSeverity, + DebugSource, + DebugType, + DepthFunction, + DepthStencilTextureMode, + DrawBufferMode, + DrawElementsType, + ElementPointerTypeATI, + EnableCap, + ErrorCode, + ExternalHandleType, + FeedBackToken, + FeedbackType, + FenceConditionNV, + FenceParameterNameNV, + FogCoordSrc, + FogCoordinatePointerType, + FogMode, + FogPName, + FogParameter, + FogPointerTypeEXT, + FogPointerTypeIBM, + FragmentLightParameterSGIX, + FragmentShaderDestMaskATI, + FragmentShaderDestModMaskATI, + FragmentShaderGenericSourceATI, + FragmentShaderTextureSourceATI, + FragmentShaderValueRepATI, + FramebufferAttachment, + FramebufferAttachmentParameterName, + FramebufferParameterName, + FramebufferStatus, + FramebufferTarget, + FrontFaceDirection, + GetFramebufferParameter, + GetMapQuery, + GetMultisamplePNameNV, + GetPName, + GetPointervPName, + GetTextureParameter, + GraphicsResetStatus, + HintMode, + HintTarget, + HistogramTarget, + HistogramTargetEXT, + IndexFunctionEXT, + IndexMaterialParameterEXT, + IndexPointerType, + InterleavedArrayFormat, + InternalFormat, + InternalFormatPName, + InvalidateFramebufferAttachment, + LightEnvModeSGIX, + LightModelColorControl, + LightModelParameter, + LightName, + LightParameter, + LightTextureModeEXT, + ListMode, + ListNameType, + LogicOp, + MapBufferAccessMask, + MapQuery, + MapTarget, + MapTypeNV, + MaterialParameter, + MatrixIndexPointerTypeARB, + MatrixMode, + MemoryBarrierMask, + MemoryObjectParameterName, + MeshMode1, + MeshMode2, + MinmaxTarget, + MinmaxTargetEXT, + NormalPointerType, + ObjectIdentifier, + PatchParameterName, + PathColor, + PathColorFormat, + PathFillMode, + PathFontStyle, + PathGenMode, + PathTransformType, + PipelineParameterName, + PixelCopyType, + PixelFormat, + PixelMap, + PixelStoreParameter, + PixelTexGenModeSGIX, + PixelTransferParameter, + PixelType, + PointParameterNameARB, + PolygonMode, + PrecisionType, + PrimitiveType, + ProgramInterface, + ProgramInterfacePName, + ProgramParameterPName, + ProgramPropertyARB, + ProgramResourceProperty, + ProgramStagePName, + QueryCounterTarget, + QueryObjectParameterName, + QueryParameterName, + QueryTarget, + ReadBufferMode, + RenderbufferParameterName, + RenderbufferTarget, + RenderingMode, + ReplacementCodeTypeSUN, + SamplerParameterF, + SamplerParameterI, + ScalarType, + SecondaryColorPointerTypeIBM, + SemaphoreParameterName, + SeparableTarget, + SeparableTargetEXT, + ShaderBinaryFormat, + ShaderParameterName, + ShaderType, + ShadingModel, + SizedInternalFormat, + StencilFunction, + StencilOp, + StringName, + SubroutineParameterName, + SyncBehaviorFlags, + SyncCondition, + SyncObjectMask, + SyncParameterName, + SyncStatus, + TangentPointerTypeEXT, + TexCoordPointerType, + TextureCompareMode, + TextureCoordName, + TextureEnvMode, + TextureEnvParameter, + TextureEnvTarget, + TextureGenMode, + TextureGenParameter, + TextureLayout, + TextureMagFilter, + TextureMinFilter, + TextureParameterName, + TextureSwizzle, + TextureTarget, + TextureUnit, + TextureWrapMode, + TransformFeedbackBufferMode, + TransformFeedbackPName, + TriangleFace, + UniformBlockPName, + UniformPName, + UniformType, + UseProgramStageMask, + VertexArrayPName, + VertexAttribEnum, + VertexAttribIType, + VertexAttribLType, + VertexAttribPointerPropertyARB, + VertexAttribPointerType, + VertexAttribPropertyARB, + VertexAttribType, + VertexBufferObjectUsage, + VertexPointerType, + VertexProvokingMode, + VertexShaderTextureUnitParameter, + VertexShaderWriteMaskEXT, + VertexWeightPointerTypeEXT, + WeightPointerTypeARB +}; +} // namespace gl + +#endif // LIBANGLE_GL_ENUM_UTILS_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/entry_points_utils.h b/gfx/angle/checkout/src/libANGLE/entry_points_utils.h new file mode 100644 index 0000000000..c5a3178308 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/entry_points_utils.h @@ -0,0 +1,127 @@ +// +// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// entry_point_utils: +// These helpers are used in GL/GLES entry point routines. + +#ifndef LIBANGLE_ENTRY_POINT_UTILS_H_ +#define LIBANGLE_ENTRY_POINT_UTILS_H_ + +#include "angle_gl.h" +#include "common/Optional.h" +#include "common/PackedEnums.h" +#include "common/angleutils.h" +#include "common/entry_points_enum_autogen.h" +#include "common/mathutil.h" +#include "libANGLE/Context.h" +#include "libANGLE/Display.h" + +namespace gl +{ +// A template struct for determining the default value to return for each entry point. +template +struct DefaultReturnValue; + +// Default return values for each basic return type. +template +struct DefaultReturnValue +{ + static constexpr GLint kValue = -1; +}; + +// This doubles as the GLenum return value. +template +struct DefaultReturnValue +{ + static constexpr GLuint kValue = 0; +}; + +template +struct DefaultReturnValue +{ + static constexpr GLboolean kValue = GL_FALSE; +}; + +template +struct DefaultReturnValue +{ + static constexpr ShaderProgramID kValue = {0}; +}; + +// Catch-all rules for pointer types. +template +struct DefaultReturnValue +{ + static constexpr const PointerType *kValue = nullptr; +}; + +template +struct DefaultReturnValue +{ + static constexpr PointerType *kValue = nullptr; +}; + +// Overloaded to return invalid index +template <> +struct DefaultReturnValue +{ + static constexpr GLuint kValue = GL_INVALID_INDEX; +}; + +// Specialized enum error value. +template <> +struct DefaultReturnValue +{ + static constexpr GLenum kValue = GL_WAIT_FAILED; +}; + +// glTestFenceNV should still return TRUE for an invalid fence. +template <> +struct DefaultReturnValue +{ + static constexpr GLboolean kValue = GL_TRUE; +}; + +template +constexpr ANGLE_INLINE ReturnType GetDefaultReturnValue() +{ + return DefaultReturnValue::kValue; +} + +#if ANGLE_CAPTURE_ENABLED +# define ANGLE_CAPTURE_GL(Func, ...) CaptureCallToFrameCapture(Capture##Func, __VA_ARGS__) +# define ANGLE_CAPTURE_EGL(Func, ...) CaptureCallToCaptureEGL(Capture##Func, __VA_ARGS__) +#else +# define ANGLE_CAPTURE_GL(...) +# define ANGLE_CAPTURE_EGL(...) +#endif // ANGLE_CAPTURE_ENABLED + +#define EGL_EVENT(EP, FMT, ...) EVENT(nullptr, EGL##EP, FMT, ##__VA_ARGS__) + +inline int CID(const Context *context) +{ + return context == nullptr ? 0 : static_cast(context->id().value); +} +} // namespace gl + +namespace egl +{ +inline int CID(EGLDisplay display, EGLContext context) +{ + auto *displayPtr = reinterpret_cast(display); + if (!Display::isValidDisplay(displayPtr)) + { + return -1; + } + auto *contextPtr = reinterpret_cast(context); + if (!displayPtr->isValidContext(contextPtr)) + { + return -1; + } + return gl::CID(contextPtr); +} +} // namespace egl + +#endif // LIBANGLE_ENTRY_POINT_UTILS_H_ diff --git a/gfx/angle/checkout/src/libANGLE/es3_copy_conversion_table_autogen.cpp b/gfx/angle/checkout/src/libANGLE/es3_copy_conversion_table_autogen.cpp new file mode 100644 index 0000000000..3647445c50 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/es3_copy_conversion_table_autogen.cpp @@ -0,0 +1,171 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_copy_conversion_table.py using data from es3_copy_conversion_formats.json. +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// format_map: +// Determining the sized internal format from a (format,type) pair. +// Also check es3 format combinations for validity. + +#include "angle_gl.h" +#include "common/debug.h" + +namespace gl +{ + +bool ValidES3CopyConversion(GLenum textureFormat, GLenum framebufferFormat) +{ + switch (textureFormat) + { + case GL_ALPHA: + switch (framebufferFormat) + { + case GL_BGRA_EXT: + case GL_RGBA: + return true; + default: + break; + } + break; + + case GL_BGRA_EXT: + switch (framebufferFormat) + { + case GL_BGRA_EXT: + return true; + default: + break; + } + break; + + case GL_LUMINANCE: + switch (framebufferFormat) + { + case GL_BGRA_EXT: + case GL_RED: + case GL_RG: + case GL_RGB: + case GL_RGBA: + return true; + default: + break; + } + break; + + case GL_LUMINANCE_ALPHA: + switch (framebufferFormat) + { + case GL_BGRA_EXT: + case GL_RGBA: + return true; + default: + break; + } + break; + + case GL_RED: + switch (framebufferFormat) + { + case GL_BGRA_EXT: + case GL_RED: + case GL_RG: + case GL_RGB: + case GL_RGBA: + return true; + default: + break; + } + break; + + case GL_RED_INTEGER: + switch (framebufferFormat) + { + case GL_RED_INTEGER: + case GL_RGBA_INTEGER: + case GL_RGB_INTEGER: + case GL_RG_INTEGER: + return true; + default: + break; + } + break; + + case GL_RG: + switch (framebufferFormat) + { + case GL_BGRA_EXT: + case GL_RG: + case GL_RGB: + case GL_RGBA: + return true; + default: + break; + } + break; + + case GL_RGB: + switch (framebufferFormat) + { + case GL_BGRA_EXT: + case GL_RGB: + case GL_RGBA: + return true; + default: + break; + } + break; + + case GL_RGBA: + switch (framebufferFormat) + { + case GL_BGRA_EXT: + case GL_RGBA: + return true; + default: + break; + } + break; + + case GL_RGBA_INTEGER: + switch (framebufferFormat) + { + case GL_RGBA_INTEGER: + return true; + default: + break; + } + break; + + case GL_RGB_INTEGER: + switch (framebufferFormat) + { + case GL_RGBA_INTEGER: + case GL_RGB_INTEGER: + return true; + default: + break; + } + break; + + case GL_RG_INTEGER: + switch (framebufferFormat) + { + case GL_RGBA_INTEGER: + case GL_RGB_INTEGER: + case GL_RG_INTEGER: + return true; + default: + break; + } + break; + + default: + break; + } + + return false; +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/features.h b/gfx/angle/checkout/src/libANGLE/features.h new file mode 100644 index 0000000000..0a8891e822 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/features.h @@ -0,0 +1,56 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef LIBANGLE_FEATURES_H_ +#define LIBANGLE_FEATURES_H_ + +#include "common/platform.h" + +#define ANGLE_DISABLED 0 +#define ANGLE_ENABLED 1 + +// Feature defaults + +// Direct3D9EX +// The "Debug This Pixel..." feature in PIX often fails when using the +// D3D9Ex interfaces. In order to get debug pixel to work on a Vista/Win 7 +// machine, define "ANGLE_D3D9EX=0" in your project file. +#if !defined(ANGLE_D3D9EX) +# define ANGLE_D3D9EX ANGLE_ENABLED +#endif + +// Vsync +// ENABLED allows Vsync to be configured at runtime +// DISABLED disallows Vsync +#if !defined(ANGLE_VSYNC) +# define ANGLE_VSYNC ANGLE_ENABLED +#endif + +// Append HLSL assembly to shader debug info. Defaults to enabled in Debug and off in Release. +#if !defined(ANGLE_APPEND_ASSEMBLY_TO_SHADER_DEBUG_INFO) +# if !defined(NDEBUG) +# define ANGLE_APPEND_ASSEMBLY_TO_SHADER_DEBUG_INFO ANGLE_ENABLED +# else +# define ANGLE_APPEND_ASSEMBLY_TO_SHADER_DEBUG_INFO ANGLE_DISABLED +# endif // !defined(NDEBUG) +#endif // !defined(ANGLE_APPEND_ASSEMBLY_TO_SHADER_DEBUG_INFO) + +// Program link validation of precisions for uniforms. This feature was +// requested by developers to allow non-conformant shaders to be used which +// contain mismatched precisions. +// ENABLED validate that precision for uniforms match between vertex and fragment shaders +// DISABLED allow precision for uniforms to differ between vertex and fragment shaders +#if !defined(ANGLE_PROGRAM_LINK_VALIDATE_UNIFORM_PRECISION) +# define ANGLE_PROGRAM_LINK_VALIDATE_UNIFORM_PRECISION ANGLE_ENABLED +#endif + +// Controls if our threading code uses std::async or falls back to single-threaded operations. +// Note that we can't easily use std::async in UWPs due to UWP threading restrictions. +#if !defined(ANGLE_STD_ASYNC_WORKERS) && !defined(ANGLE_ENABLE_WINDOWS_UWP) +# define ANGLE_STD_ASYNC_WORKERS ANGLE_ENABLED +#endif // !defined(ANGLE_STD_ASYNC_WORKERS) && & !defined(ANGLE_ENABLE_WINDOWS_UWP) + +#endif // LIBANGLE_FEATURES_H_ diff --git a/gfx/angle/checkout/src/libANGLE/format_map_autogen.cpp b/gfx/angle/checkout/src/libANGLE/format_map_autogen.cpp new file mode 100644 index 0000000000..4685bb8931 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/format_map_autogen.cpp @@ -0,0 +1,1781 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_format_map.py using data from format_map_data.json. +// ES3 format info from es3_format_type_combinations.json. +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// format_map: +// Determining the sized internal format from a (format,type) pair. +// Also check es3 format combinations for validity. + +#include "angle_gl.h" +#include "common/debug.h" + +namespace gl +{ + +GLenum GetSizedFormatInternal(GLenum format, GLenum type) +{ + switch (format) + { + case GL_ALPHA: + switch (type) + { + case GL_FLOAT: + return GL_ALPHA32F_EXT; + case GL_HALF_FLOAT: + return GL_ALPHA16F_EXT; + case GL_HALF_FLOAT_OES: + return GL_ALPHA16F_EXT; + case GL_UNSIGNED_BYTE: + return GL_ALPHA8_EXT; + default: + break; + } + break; + + case GL_BGRA_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_BGRA8_EXT; + case GL_UNSIGNED_INT_2_10_10_10_REV: + return GL_BGR10_A2_ANGLEX; + case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: + return GL_BGR5_A1_ANGLEX; + case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: + return GL_BGRA4_ANGLEX; + case GL_UNSIGNED_SHORT_5_6_5: + return GL_BGR565_ANGLEX; + default: + break; + } + break; + + case GL_COMPRESSED_RED_GREEN_RGTC2_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_RED_GREEN_RGTC2_EXT; + default: + break; + } + break; + + case GL_COMPRESSED_RED_RGTC1_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_RED_RGTC1_EXT; + default: + break; + } + break; + + case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_RGBA_BPTC_UNORM_EXT; + default: + break; + } + break; + + case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; + default: + break; + } + break; + + case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; + default: + break; + } + break; + + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + default: + break; + } + break; + + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE; + default: + break; + } + break; + + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE; + default: + break; + } + break; + + case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT; + default: + break; + } + break; + + case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT; + default: + break; + } + break; + + case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG; + default: + break; + } + break; + + case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG; + default: + break; + } + break; + + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + default: + break; + } + break; + + case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT; + default: + break; + } + break; + + case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_SIGNED_RED_RGTC1_EXT; + default: + break; + } + break; + + case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT; + default: + break; + } + break; + + case GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT; + default: + break; + } + break; + + case GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT; + default: + break; + } + break; + + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT; + default: + break; + } + break; + + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT; + default: + break; + } + break; + + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; + default: + break; + } + break; + + case GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT; + default: + break; + } + break; + + case GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT; + default: + break; + } + break; + + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_SRGB_S3TC_DXT1_EXT; + default: + break; + } + break; + + case GL_DEPTH_COMPONENT: + switch (type) + { + case GL_FLOAT: + return GL_DEPTH_COMPONENT32F; + case GL_UNSIGNED_INT: + return GL_DEPTH_COMPONENT32_OES; + case GL_UNSIGNED_INT_24_8: + return GL_DEPTH24_STENCIL8; + case GL_UNSIGNED_SHORT: + return GL_DEPTH_COMPONENT16; + default: + break; + } + break; + + case GL_DEPTH_STENCIL: + switch (type) + { + case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: + return GL_DEPTH32F_STENCIL8; + case GL_UNSIGNED_INT_24_8: + return GL_DEPTH24_STENCIL8; + default: + break; + } + break; + + case GL_LUMINANCE: + switch (type) + { + case GL_FLOAT: + return GL_LUMINANCE32F_EXT; + case GL_HALF_FLOAT: + return GL_LUMINANCE16F_EXT; + case GL_HALF_FLOAT_OES: + return GL_LUMINANCE16F_EXT; + case GL_UNSIGNED_BYTE: + return GL_LUMINANCE8_EXT; + default: + break; + } + break; + + case GL_LUMINANCE_ALPHA: + switch (type) + { + case GL_FLOAT: + return GL_LUMINANCE_ALPHA32F_EXT; + case GL_HALF_FLOAT: + return GL_LUMINANCE_ALPHA16F_EXT; + case GL_HALF_FLOAT_OES: + return GL_LUMINANCE_ALPHA16F_EXT; + case GL_UNSIGNED_BYTE: + return GL_LUMINANCE8_ALPHA8_EXT; + default: + break; + } + break; + + case GL_RED: + switch (type) + { + case GL_BYTE: + return GL_R8_SNORM; + case GL_FLOAT: + return GL_R32F; + case GL_HALF_FLOAT: + return GL_R16F; + case GL_HALF_FLOAT_OES: + return GL_R16F; + case GL_SHORT: + return GL_R16_SNORM_EXT; + case GL_UNSIGNED_BYTE: + return GL_R8; + case GL_UNSIGNED_SHORT: + return GL_R16_EXT; + default: + break; + } + break; + + case GL_RED_INTEGER: + switch (type) + { + case GL_BYTE: + return GL_R8I; + case GL_INT: + return GL_R32I; + case GL_SHORT: + return GL_R16I; + case GL_UNSIGNED_BYTE: + return GL_R8UI; + case GL_UNSIGNED_INT: + return GL_R32UI; + case GL_UNSIGNED_SHORT: + return GL_R16UI; + default: + break; + } + break; + + case GL_RG: + switch (type) + { + case GL_BYTE: + return GL_RG8_SNORM; + case GL_FLOAT: + return GL_RG32F; + case GL_HALF_FLOAT: + return GL_RG16F; + case GL_HALF_FLOAT_OES: + return GL_RG16F; + case GL_SHORT: + return GL_RG16_SNORM_EXT; + case GL_UNSIGNED_BYTE: + return GL_RG8; + case GL_UNSIGNED_SHORT: + return GL_RG16_EXT; + default: + break; + } + break; + + case GL_RGB: + switch (type) + { + case GL_BYTE: + return GL_RGB8_SNORM; + case GL_FLOAT: + return GL_RGB32F; + case GL_HALF_FLOAT: + return GL_RGB16F; + case GL_HALF_FLOAT_OES: + return GL_RGB16F; + case GL_SHORT: + return GL_RGB16_SNORM_EXT; + case GL_UNSIGNED_BYTE: + return GL_RGB8; + case GL_UNSIGNED_INT_10F_11F_11F_REV: + return GL_R11F_G11F_B10F; + case GL_UNSIGNED_INT_2_10_10_10_REV: + return GL_RGB10_UNORM_ANGLEX; + case GL_UNSIGNED_INT_5_9_9_9_REV: + return GL_RGB9_E5; + case GL_UNSIGNED_SHORT: + return GL_RGB16_EXT; + case GL_UNSIGNED_SHORT_5_6_5: + return GL_RGB565; + default: + break; + } + break; + + case GL_RGBA: + switch (type) + { + case GL_BYTE: + return GL_RGBA8_SNORM; + case GL_FLOAT: + return GL_RGBA32F; + case GL_HALF_FLOAT: + return GL_RGBA16F; + case GL_HALF_FLOAT_OES: + return GL_RGBA16F; + case GL_SHORT: + return GL_RGBA16_SNORM_EXT; + case GL_UNSIGNED_BYTE: + return GL_RGBA8; + case GL_UNSIGNED_INT_2_10_10_10_REV: + return GL_RGB10_A2; + case GL_UNSIGNED_SHORT: + return GL_RGBA16_EXT; + case GL_UNSIGNED_SHORT_4_4_4_4: + return GL_RGBA4; + case GL_UNSIGNED_SHORT_5_5_5_1: + return GL_RGB5_A1; + default: + break; + } + break; + + case GL_RGBA_INTEGER: + switch (type) + { + case GL_BYTE: + return GL_RGBA8I; + case GL_INT: + return GL_RGBA32I; + case GL_SHORT: + return GL_RGBA16I; + case GL_UNSIGNED_BYTE: + return GL_RGBA8UI; + case GL_UNSIGNED_INT: + return GL_RGBA32UI; + case GL_UNSIGNED_INT_2_10_10_10_REV: + return GL_RGB10_A2UI; + case GL_UNSIGNED_SHORT: + return GL_RGBA16UI; + default: + break; + } + break; + + case GL_RGB_INTEGER: + switch (type) + { + case GL_BYTE: + return GL_RGB8I; + case GL_INT: + return GL_RGB32I; + case GL_SHORT: + return GL_RGB16I; + case GL_UNSIGNED_BYTE: + return GL_RGB8UI; + case GL_UNSIGNED_INT: + return GL_RGB32UI; + case GL_UNSIGNED_SHORT: + return GL_RGB16UI; + default: + break; + } + break; + + case GL_RG_INTEGER: + switch (type) + { + case GL_BYTE: + return GL_RG8I; + case GL_INT: + return GL_RG32I; + case GL_SHORT: + return GL_RG16I; + case GL_UNSIGNED_BYTE: + return GL_RG8UI; + case GL_UNSIGNED_INT: + return GL_RG32UI; + case GL_UNSIGNED_SHORT: + return GL_RG16UI; + default: + break; + } + break; + + case GL_SRGB_ALPHA_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_SRGB8_ALPHA8; + default: + break; + } + break; + + case GL_SRGB_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_SRGB8; + default: + break; + } + break; + + case GL_STENCIL: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_STENCIL_INDEX8; + default: + break; + } + break; + + case GL_STENCIL_INDEX_OES: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_STENCIL_INDEX8; + default: + break; + } + break; + + case GL_NONE: + return GL_NONE; + + default: + break; + } + + return GL_NONE; +} + +bool ValidES3Format(GLenum format) +{ + switch (format) + { + case GL_ALPHA: + case GL_BGRA_EXT: + case GL_DEPTH_COMPONENT: + case GL_DEPTH_STENCIL: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_RED: + case GL_RED_INTEGER: + case GL_RG: + case GL_RGB: + case GL_RGBA: + case GL_RGBA_INTEGER: + case GL_RGB_INTEGER: + case GL_RG_INTEGER: + case GL_SRGB_ALPHA_EXT: + case GL_SRGB_EXT: + case GL_STENCIL_INDEX: + return true; + + default: + return false; + } +} + +bool ValidES3Type(GLenum type) +{ + switch (type) + { + case GL_BYTE: + case GL_FLOAT: + case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: + case GL_HALF_FLOAT: + case GL_HALF_FLOAT_OES: + case GL_INT: + case GL_SHORT: + case GL_UNSIGNED_BYTE: + case GL_UNSIGNED_INT: + case GL_UNSIGNED_INT_10F_11F_11F_REV: + case GL_UNSIGNED_INT_24_8: + case GL_UNSIGNED_INT_2_10_10_10_REV: + case GL_UNSIGNED_INT_5_9_9_9_REV: + case GL_UNSIGNED_SHORT: + case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_5_6_5: + return true; + + default: + return false; + } +} + +bool ValidES3FormatCombination(GLenum format, GLenum type, GLenum internalFormat) +{ + ASSERT(ValidES3Format(format) && ValidES3Type(type)); + + switch (format) + { + case GL_ALPHA: + switch (type) + { + case GL_FLOAT: + { + switch (internalFormat) + { + case GL_ALPHA: + case GL_ALPHA32F_EXT: + return true; + default: + break; + } + break; + } + case GL_HALF_FLOAT: + { + switch (internalFormat) + { + case GL_ALPHA: + case GL_ALPHA16F_EXT: + return true; + default: + break; + } + break; + } + case GL_HALF_FLOAT_OES: + { + switch (internalFormat) + { + case GL_ALPHA: + case GL_ALPHA16F_EXT: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_BYTE: + { + switch (internalFormat) + { + case GL_ALPHA: + case GL_ALPHA8_EXT: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + case GL_BGRA_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + { + switch (internalFormat) + { + case GL_BGRA_EXT: + case GL_BGRA8_EXT: + case GL_BGRA4_ANGLEX: + case GL_BGR5_A1_ANGLEX: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: + { + switch (internalFormat) + { + case GL_BGR5_A1_ANGLEX: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: + { + switch (internalFormat) + { + case GL_BGRA4_ANGLEX: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + case GL_DEPTH_COMPONENT: + switch (type) + { + case GL_FLOAT: + { + switch (internalFormat) + { + case GL_DEPTH_COMPONENT32F: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_INT: + { + switch (internalFormat) + { + case GL_DEPTH_COMPONENT24: + case GL_DEPTH_COMPONENT16: + case GL_DEPTH_COMPONENT: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_INT_24_8: + { + switch (internalFormat) + { + case GL_DEPTH_COMPONENT32_OES: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_SHORT: + { + switch (internalFormat) + { + case GL_DEPTH_COMPONENT16: + case GL_DEPTH_COMPONENT: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + case GL_DEPTH_STENCIL: + switch (type) + { + case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: + { + switch (internalFormat) + { + case GL_DEPTH32F_STENCIL8: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_INT_24_8: + { + switch (internalFormat) + { + case GL_DEPTH_STENCIL: + case GL_DEPTH24_STENCIL8: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + case GL_LUMINANCE: + switch (type) + { + case GL_FLOAT: + { + switch (internalFormat) + { + case GL_LUMINANCE: + case GL_LUMINANCE32F_EXT: + return true; + default: + break; + } + break; + } + case GL_HALF_FLOAT: + { + switch (internalFormat) + { + case GL_LUMINANCE: + case GL_LUMINANCE16F_EXT: + return true; + default: + break; + } + break; + } + case GL_HALF_FLOAT_OES: + { + switch (internalFormat) + { + case GL_LUMINANCE: + case GL_LUMINANCE16F_EXT: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_BYTE: + { + switch (internalFormat) + { + case GL_LUMINANCE: + case GL_LUMINANCE8_EXT: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + case GL_LUMINANCE_ALPHA: + switch (type) + { + case GL_FLOAT: + { + switch (internalFormat) + { + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE_ALPHA32F_EXT: + return true; + default: + break; + } + break; + } + case GL_HALF_FLOAT: + { + switch (internalFormat) + { + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE_ALPHA16F_EXT: + return true; + default: + break; + } + break; + } + case GL_HALF_FLOAT_OES: + { + switch (internalFormat) + { + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE_ALPHA16F_EXT: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_BYTE: + { + switch (internalFormat) + { + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE8_ALPHA8_EXT: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + case GL_RED: + switch (type) + { + case GL_BYTE: + { + switch (internalFormat) + { + case GL_R8_SNORM: + return true; + default: + break; + } + break; + } + case GL_FLOAT: + { + switch (internalFormat) + { + case GL_R32F: + case GL_R16F: + case GL_RED: + return true; + default: + break; + } + break; + } + case GL_HALF_FLOAT: + { + switch (internalFormat) + { + case GL_R16F: + case GL_RED: + return true; + default: + break; + } + break; + } + case GL_HALF_FLOAT_OES: + { + switch (internalFormat) + { + case GL_R16F: + case GL_RED: + return true; + default: + break; + } + break; + } + case GL_SHORT: + { + switch (internalFormat) + { + case GL_R16_SNORM_EXT: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_BYTE: + { + switch (internalFormat) + { + case GL_R8: + case GL_RED: + case GL_SR8_EXT: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_SHORT: + { + switch (internalFormat) + { + case GL_R16_EXT: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + case GL_RED_INTEGER: + switch (type) + { + case GL_BYTE: + { + switch (internalFormat) + { + case GL_R8I: + return true; + default: + break; + } + break; + } + case GL_INT: + { + switch (internalFormat) + { + case GL_R32I: + return true; + default: + break; + } + break; + } + case GL_SHORT: + { + switch (internalFormat) + { + case GL_R16I: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_BYTE: + { + switch (internalFormat) + { + case GL_R8UI: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_INT: + { + switch (internalFormat) + { + case GL_R32UI: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_SHORT: + { + switch (internalFormat) + { + case GL_R16UI: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + case GL_RG: + switch (type) + { + case GL_BYTE: + { + switch (internalFormat) + { + case GL_RG8_SNORM: + return true; + default: + break; + } + break; + } + case GL_FLOAT: + { + switch (internalFormat) + { + case GL_RG32F: + case GL_RG16F: + case GL_RG: + return true; + default: + break; + } + break; + } + case GL_HALF_FLOAT: + { + switch (internalFormat) + { + case GL_RG16F: + case GL_RG: + return true; + default: + break; + } + break; + } + case GL_HALF_FLOAT_OES: + { + switch (internalFormat) + { + case GL_RG16F: + case GL_RG: + return true; + default: + break; + } + break; + } + case GL_SHORT: + { + switch (internalFormat) + { + case GL_RG16_SNORM_EXT: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_BYTE: + { + switch (internalFormat) + { + case GL_RG8: + case GL_RG: + case GL_SRG8_EXT: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_SHORT: + { + switch (internalFormat) + { + case GL_RG16_EXT: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + case GL_RGB: + switch (type) + { + case GL_BYTE: + { + switch (internalFormat) + { + case GL_RGB8_SNORM: + return true; + default: + break; + } + break; + } + case GL_FLOAT: + { + switch (internalFormat) + { + case GL_RGB32F: + case GL_RGB16F: + case GL_R11F_G11F_B10F: + case GL_RGB9_E5: + case GL_RGB: + return true; + default: + break; + } + break; + } + case GL_HALF_FLOAT: + { + switch (internalFormat) + { + case GL_RGB16F: + case GL_R11F_G11F_B10F: + case GL_RGB9_E5: + return true; + default: + break; + } + break; + } + case GL_HALF_FLOAT_OES: + { + switch (internalFormat) + { + case GL_RGB16F: + case GL_R11F_G11F_B10F: + case GL_RGB9_E5: + case GL_RGB: + return true; + default: + break; + } + break; + } + case GL_SHORT: + { + switch (internalFormat) + { + case GL_RGB16_SNORM_EXT: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_BYTE: + { + switch (internalFormat) + { + case GL_RGB8: + case GL_RGB565: + case GL_SRGB8: + case GL_RGB: + case GL_RGBX8_ANGLE: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_INT_10F_11F_11F_REV: + { + switch (internalFormat) + { + case GL_R11F_G11F_B10F: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_INT_2_10_10_10_REV: + { + switch (internalFormat) + { + case GL_RGB: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_INT_5_9_9_9_REV: + { + switch (internalFormat) + { + case GL_RGB9_E5: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_SHORT: + { + switch (internalFormat) + { + case GL_RGB16_EXT: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_SHORT_5_6_5: + { + switch (internalFormat) + { + case GL_RGB565: + case GL_RGB: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + case GL_RGBA: + switch (type) + { + case GL_BYTE: + { + switch (internalFormat) + { + case GL_RGBA8_SNORM: + return true; + default: + break; + } + break; + } + case GL_FLOAT: + { + switch (internalFormat) + { + case GL_RGBA32F: + case GL_RGBA16F: + case GL_RGBA: + return true; + default: + break; + } + break; + } + case GL_HALF_FLOAT: + { + switch (internalFormat) + { + case GL_RGBA16F: + return true; + default: + break; + } + break; + } + case GL_HALF_FLOAT_OES: + { + switch (internalFormat) + { + case GL_RGBA16F: + case GL_RGBA: + return true; + default: + break; + } + break; + } + case GL_SHORT: + { + switch (internalFormat) + { + case GL_RGBA16_SNORM_EXT: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_BYTE: + { + switch (internalFormat) + { + case GL_RGBA8: + case GL_RGB5_A1: + case GL_RGBA4: + case GL_SRGB8_ALPHA8: + case GL_RGBA: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_INT_2_10_10_10_REV: + { + switch (internalFormat) + { + case GL_RGB10_A2: + case GL_RGB5_A1: + case GL_RGBA: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_SHORT: + { + switch (internalFormat) + { + case GL_RGBA16_EXT: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_SHORT_4_4_4_4: + { + switch (internalFormat) + { + case GL_RGBA4: + case GL_RGBA: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_SHORT_5_5_5_1: + { + switch (internalFormat) + { + case GL_RGB5_A1: + case GL_RGBA: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + case GL_RGBA_INTEGER: + switch (type) + { + case GL_BYTE: + { + switch (internalFormat) + { + case GL_RGBA8I: + return true; + default: + break; + } + break; + } + case GL_INT: + { + switch (internalFormat) + { + case GL_RGBA32I: + return true; + default: + break; + } + break; + } + case GL_SHORT: + { + switch (internalFormat) + { + case GL_RGBA16I: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_BYTE: + { + switch (internalFormat) + { + case GL_RGBA8UI: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_INT: + { + switch (internalFormat) + { + case GL_RGBA32UI: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_INT_2_10_10_10_REV: + { + switch (internalFormat) + { + case GL_RGB10_A2UI: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_SHORT: + { + switch (internalFormat) + { + case GL_RGBA16UI: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + case GL_RGB_INTEGER: + switch (type) + { + case GL_BYTE: + { + switch (internalFormat) + { + case GL_RGB8I: + return true; + default: + break; + } + break; + } + case GL_INT: + { + switch (internalFormat) + { + case GL_RGB32I: + return true; + default: + break; + } + break; + } + case GL_SHORT: + { + switch (internalFormat) + { + case GL_RGB16I: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_BYTE: + { + switch (internalFormat) + { + case GL_RGB8UI: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_INT: + { + switch (internalFormat) + { + case GL_RGB32UI: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_SHORT: + { + switch (internalFormat) + { + case GL_RGB16UI: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + case GL_RG_INTEGER: + switch (type) + { + case GL_BYTE: + { + switch (internalFormat) + { + case GL_RG8I: + return true; + default: + break; + } + break; + } + case GL_INT: + { + switch (internalFormat) + { + case GL_RG32I: + return true; + default: + break; + } + break; + } + case GL_SHORT: + { + switch (internalFormat) + { + case GL_RG16I: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_BYTE: + { + switch (internalFormat) + { + case GL_RG8UI: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_INT: + { + switch (internalFormat) + { + case GL_RG32UI: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_SHORT: + { + switch (internalFormat) + { + case GL_RG16UI: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + case GL_SRGB_ALPHA_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + { + switch (internalFormat) + { + case GL_SRGB_ALPHA_EXT: + case GL_SRGB8_ALPHA8_EXT: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + case GL_SRGB_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + { + switch (internalFormat) + { + case GL_SRGB_EXT: + case GL_SRGB8: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + case GL_STENCIL_INDEX: + switch (type) + { + case GL_UNSIGNED_BYTE: + { + switch (internalFormat) + { + case GL_STENCIL_INDEX8: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + default: + UNREACHABLE(); + break; + } + + return false; +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/format_map_desktop.cpp b/gfx/angle/checkout/src/libANGLE/format_map_desktop.cpp new file mode 100644 index 0000000000..17122af6a7 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/format_map_desktop.cpp @@ -0,0 +1,128 @@ +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// format_map_desktop: +// Determining the sized internal format from a (format,type) pair. +// Also check DesktopGL format combinations for validity. + +#include "angle_gl.h" +#include "common/debug.h" +#include "formatutils.h" +#include "renderer/gl/functionsgl_enums.h" + +// TODO(http://anglebug.com/3730): switch ANGLE to generate its own GL enum types from gl.xml + +namespace gl +{ + +bool ValidDesktopFormat(GLenum format) +{ + switch (format) + { + case GL_STENCIL_INDEX: + case GL_DEPTH_COMPONENT: + case GL_DEPTH_STENCIL: + case GL_RED: + case GL_GREEN: + case GL_BLUE: + case GL_RG: + case GL_RGB: + case GL_RGBA: + case GL_BGR: + case GL_BGRA: + case GL_RED_INTEGER: + case GL_GREEN_INTEGER: + case GL_BLUE_INTEGER: + case GL_RG_INTEGER: + case GL_RGB_INTEGER: + case GL_RGBA_INTEGER: + case GL_BGR_INTEGER: + case GL_BGRA_INTEGER: + return true; + + default: + return false; + } +} + +bool ValidDesktopType(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + case GL_BYTE: + case GL_UNSIGNED_SHORT: + case GL_SHORT: + case GL_UNSIGNED_INT: + case GL_INT: + case GL_HALF_FLOAT: + case GL_FLOAT: + case GL_UNSIGNED_BYTE_3_3_2: + case GL_UNSIGNED_BYTE_2_3_3_REV: + case GL_UNSIGNED_SHORT_5_6_5: + case GL_UNSIGNED_SHORT_5_6_5_REV: + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + case GL_UNSIGNED_INT_10_10_10_2: + case GL_UNSIGNED_INT_2_10_10_10_REV: + case GL_UNSIGNED_INT_24_8: + case GL_UNSIGNED_INT_10F_11F_11F_REV: + case GL_UNSIGNED_INT_5_9_9_9_REV: + case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: + return true; + + default: + return false; + } +} + +// From OpenGL 4.6 spec section 8.4 +bool ValidDesktopFormatCombination(GLenum format, GLenum type, GLenum internalFormat) +{ + ASSERT(ValidDesktopFormat(format) && ValidDesktopType(type)); + const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type); + const InternalFormat &formatInfo = GetInternalFormatInfo(format, type); + + switch (format) + { + case GL_RED_INTEGER: + case GL_GREEN_INTEGER: + case GL_BLUE_INTEGER: + case GL_RG_INTEGER: + case GL_RGB_INTEGER: + case GL_RGBA_INTEGER: + case GL_BGR_INTEGER: + case GL_BGRA_INTEGER: + switch (type) + { + case GL_HALF_FLOAT: + case GL_FLOAT: + case GL_UNSIGNED_INT_10F_11F_11F_REV: + case GL_UNSIGNED_INT_5_9_9_9_REV: + return false; + default: + break; + } + if (!internalFormatInfo.isInt()) + return false; + break; + default: + // format is not an integer + if (internalFormatInfo.isInt()) + return false; + + if (formatInfo.isDepthOrStencil() != internalFormatInfo.isDepthOrStencil()) + return false; + + if (format == GL_STENCIL_INDEX && internalFormat != GL_STENCIL_INDEX) + return false; + break; + } + + return true; +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/formatutils.cpp b/gfx/angle/checkout/src/libANGLE/formatutils.cpp new file mode 100644 index 0000000000..76273f3be3 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/formatutils.cpp @@ -0,0 +1,3220 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// formatutils.cpp: Queries for GL image formats. + +#include "libANGLE/formatutils.h" + +#include "anglebase/no_destructor.h" +#include "common/mathutil.h" +#include "gpu_info_util/SystemInfo.h" +#include "libANGLE/Context.h" +#include "libANGLE/Framebuffer.h" + +using namespace angle; + +namespace gl +{ + +// ES2 requires that format is equal to internal format at all glTex*Image2D entry points and the +// implementation can decide the true, sized, internal format. The ES2FormatMap determines the +// internal format for all valid format and type combinations. +GLenum GetSizedFormatInternal(GLenum format, GLenum type); + +namespace +{ +bool CheckedMathResult(const CheckedNumeric &value, GLuint *resultOut) +{ + if (!value.IsValid()) + { + return false; + } + else + { + *resultOut = value.ValueOrDie(); + return true; + } +} + +constexpr uint32_t PackTypeInfo(GLuint bytes, bool specialized) +{ + // static_assert within constexpr requires c++17 + // static_assert(isPow2(bytes)); + return bytes | (rx::Log2(bytes) << 8) | (specialized << 16); +} + +} // anonymous namespace + +FormatType::FormatType() : format(GL_NONE), type(GL_NONE) {} + +FormatType::FormatType(GLenum format_, GLenum type_) : format(format_), type(type_) {} + +bool FormatType::operator<(const FormatType &other) const +{ + if (format != other.format) + return format < other.format; + return type < other.type; +} + +bool operator<(const Type &a, const Type &b) +{ + return memcmp(&a, &b, sizeof(Type)) < 0; +} + +// Information about internal formats +static bool AlwaysSupported(const Version &, const Extensions &) +{ + return true; +} + +static bool NeverSupported(const Version &, const Extensions &) +{ + return false; +} + +static bool RequireES1(const Version &clientVersion, const Extensions &extensions) +{ + return clientVersion.major == 1; +} + +template +static bool RequireES(const Version &clientVersion, const Extensions &) +{ + return clientVersion >= Version(minCoreGLMajorVersion, minCoreGLMinorVersion); +} + +// Check support for a single extension +template +static bool RequireExt(const Version &, const Extensions &extensions) +{ + return extensions.*bool1; +} + +// Check for a minimum client version or a single extension +template +static bool RequireESOrExt(const Version &clientVersion, const Extensions &extensions) +{ + return clientVersion >= Version(minCoreGLMajorVersion, minCoreGLMinorVersion) || + extensions.*bool1; +} + +// Check for a minimum client version or two extensions +template +static bool RequireESOrExtAndExt(const Version &clientVersion, const Extensions &extensions) +{ + return clientVersion >= Version(minCoreGLMajorVersion, minCoreGLMinorVersion) || + (extensions.*bool1 && extensions.*bool2); +} + +// Check for a minimum client version or at least one of two extensions +template +static bool RequireESOrExtOrExt(const Version &clientVersion, const Extensions &extensions) +{ + return clientVersion >= Version(minCoreGLMajorVersion, minCoreGLMinorVersion) || + extensions.*bool1 || extensions.*bool2; +} + +// Check support for two extensions +template +static bool RequireExtAndExt(const Version &, const Extensions &extensions) +{ + return extensions.*bool1 && extensions.*bool2; +} + +// Check support for either of two extensions +template +static bool RequireExtOrExt(const Version &, const Extensions &extensions) +{ + return extensions.*bool1 || extensions.*bool2; +} + +// Check support for any of three extensions +template +static bool RequireExtOrExtOrExt(const Version &, const Extensions &extensions) +{ + return extensions.*bool1 || extensions.*bool2 || extensions.*bool3; +} + +// R8, RG8 +static bool SizedRGSupport(const Version &clientVersion, const Extensions &extensions) +{ + return clientVersion >= Version(3, 0) || + (extensions.textureStorageEXT && extensions.textureRgEXT); +} + +// R16F, RG16F with HALF_FLOAT_OES type +static bool SizedHalfFloatOESRGSupport(const Version &clientVersion, const Extensions &extensions) +{ + return extensions.textureStorageEXT && extensions.textureHalfFloatOES && + extensions.textureRgEXT; +} + +static bool SizedHalfFloatOESRGTextureAttachmentSupport(const Version &clientVersion, + const Extensions &extensions) +{ + return SizedHalfFloatOESRGSupport(clientVersion, extensions) && + extensions.colorBufferHalfFloatEXT; +} + +// R16F, RG16F with either HALF_FLOAT_OES or HALF_FLOAT types +static bool SizedHalfFloatRGSupport(const Version &clientVersion, const Extensions &extensions) +{ + // HALF_FLOAT + if (clientVersion >= Version(3, 0)) + { + return true; + } + // HALF_FLOAT_OES + else + { + return SizedHalfFloatOESRGSupport(clientVersion, extensions); + } +} + +static bool SizedHalfFloatRGTextureAttachmentSupport(const Version &clientVersion, + const Extensions &extensions) +{ + // HALF_FLOAT + if (clientVersion >= Version(3, 0)) + { + // WebGL 2 supports EXT_color_buffer_half_float. + return extensions.colorBufferFloatEXT || + (extensions.webglCompatibilityANGLE && extensions.colorBufferHalfFloatEXT); + } + // HALF_FLOAT_OES + else + { + return SizedHalfFloatOESRGTextureAttachmentSupport(clientVersion, extensions); + } +} + +static bool SizedHalfFloatRGRenderbufferSupport(const Version &clientVersion, + const Extensions &extensions) +{ + return (clientVersion >= Version(3, 0) || + (extensions.textureHalfFloatOES && extensions.textureRgEXT)) && + (extensions.colorBufferFloatEXT || extensions.colorBufferHalfFloatEXT); +} + +// RGB16F, RGBA16F with HALF_FLOAT_OES type +static bool SizedHalfFloatOESSupport(const Version &clientVersion, const Extensions &extensions) +{ + return extensions.textureStorageEXT && extensions.textureHalfFloatOES; +} + +static bool SizedHalfFloatOESTextureAttachmentSupport(const Version &clientVersion, + const Extensions &extensions) +{ + return SizedHalfFloatOESSupport(clientVersion, extensions) && + extensions.colorBufferHalfFloatEXT; +} + +// RGB16F, RGBA16F with either HALF_FLOAT_OES or HALF_FLOAT types +static bool SizedHalfFloatSupport(const Version &clientVersion, const Extensions &extensions) +{ + // HALF_FLOAT + if (clientVersion >= Version(3, 0)) + { + return true; + } + // HALF_FLOAT_OES + else + { + return SizedHalfFloatOESSupport(clientVersion, extensions); + } +} + +static bool SizedHalfFloatFilterSupport(const Version &clientVersion, const Extensions &extensions) +{ + // HALF_FLOAT + if (clientVersion >= Version(3, 0)) + { + return true; + } + // HALF_FLOAT_OES + else + { + return extensions.textureHalfFloatLinearOES; + } +} + +static bool SizedHalfFloatRGBTextureAttachmentSupport(const Version &clientVersion, + const Extensions &extensions) +{ + // HALF_FLOAT + if (clientVersion >= Version(3, 0)) + { + // It is unclear how EXT_color_buffer_half_float applies to ES3.0 and above, however, + // dEQP GLES3 es3fFboColorbufferTests.cpp verifies that texture attachment of GL_RGB16F + // is possible, so assume that all GLES implementations support it. + // The WebGL version of the extension explicitly forbids RGB formats. + return extensions.colorBufferHalfFloatEXT && !extensions.webglCompatibilityANGLE; + } + // HALF_FLOAT_OES + else + { + return SizedHalfFloatOESTextureAttachmentSupport(clientVersion, extensions); + } +} + +static bool SizedHalfFloatRGBRenderbufferSupport(const Version &clientVersion, + const Extensions &extensions) +{ + return !extensions.webglCompatibilityANGLE && + ((clientVersion >= Version(3, 0) || extensions.textureHalfFloatOES) && + extensions.colorBufferHalfFloatEXT); +} + +static bool SizedHalfFloatRGBATextureAttachmentSupport(const Version &clientVersion, + const Extensions &extensions) +{ + // HALF_FLOAT + if (clientVersion >= Version(3, 0)) + { + // WebGL 2 supports EXT_color_buffer_half_float. + return extensions.colorBufferFloatEXT || + (extensions.webglCompatibilityANGLE && extensions.colorBufferHalfFloatEXT); + } + // HALF_FLOAT_OES + else + { + return SizedHalfFloatOESTextureAttachmentSupport(clientVersion, extensions); + } +} + +static bool SizedHalfFloatRGBARenderbufferSupport(const Version &clientVersion, + const Extensions &extensions) +{ + return (clientVersion >= Version(3, 0) || extensions.textureHalfFloatOES) && + (extensions.colorBufferFloatEXT || extensions.colorBufferHalfFloatEXT); +} + +// R32F, RG32F +static bool SizedFloatRGSupport(const Version &clientVersion, const Extensions &extensions) +{ + return clientVersion >= Version(3, 0) || + (extensions.textureStorageEXT && extensions.textureFloatOES && extensions.textureRgEXT); +} + +// RGB32F +static bool SizedFloatRGBSupport(const Version &clientVersion, const Extensions &extensions) +{ + return clientVersion >= Version(3, 0) || + (extensions.textureStorageEXT && extensions.textureFloatOES) || + extensions.colorBufferFloatRgbCHROMIUM; +} + +// RGBA32F +static bool SizedFloatRGBASupport(const Version &clientVersion, const Extensions &extensions) +{ + return clientVersion >= Version(3, 0) || + (extensions.textureStorageEXT && extensions.textureFloatOES) || + extensions.colorBufferFloatRgbaCHROMIUM; +} + +static bool SizedFloatRGBARenderableSupport(const Version &clientVersion, + const Extensions &extensions) +{ + // This logic is the same for both Renderbuffers and TextureAttachment. + return extensions.colorBufferFloatRgbaCHROMIUM || // ES2 + extensions.colorBufferFloatEXT; // ES3 +} + +static bool Float32BlendableSupport(const Version &clientVersion, const Extensions &extensions) +{ + // EXT_float_blend may be exposed on ES2 client contexts. Ensure that RGBA32F is renderable. + return (extensions.colorBufferFloatRgbaCHROMIUM || extensions.colorBufferFloatEXT) && + extensions.floatBlendEXT; +} + +template +static bool ETC2EACSupport(const Version &clientVersion, const Extensions &extensions) +{ + if (extensions.compressedTextureEtcANGLE) + { + return true; + } + + // ETC2/EAC formats are always available in ES 3.0+ but require an extension (checked above) + // in WebGL. If that extension is not available, hide these formats from WebGL contexts. + return !extensions.webglCompatibilityANGLE && + (clientVersion >= Version(3, 0) || extensions.*bool1); +} + +InternalFormat::InternalFormat() + : internalFormat(GL_NONE), + sized(false), + sizedInternalFormat(GL_NONE), + redBits(0), + greenBits(0), + blueBits(0), + luminanceBits(0), + alphaBits(0), + sharedBits(0), + depthBits(0), + stencilBits(0), + pixelBytes(0), + componentCount(0), + compressed(false), + compressedBlockWidth(0), + compressedBlockHeight(0), + compressedBlockDepth(0), + paletted(false), + paletteBits(0), + format(GL_NONE), + type(GL_NONE), + componentType(GL_NONE), + colorEncoding(GL_NONE), + textureSupport(NeverSupported), + filterSupport(NeverSupported), + textureAttachmentSupport(NeverSupported), + renderbufferSupport(NeverSupported), + blendSupport(NeverSupported) +{} + +InternalFormat::InternalFormat(const InternalFormat &other) = default; + +InternalFormat &InternalFormat::operator=(const InternalFormat &other) = default; + +bool InternalFormat::isLUMA() const +{ + return ((redBits + greenBits + blueBits + depthBits + stencilBits) == 0 && + (luminanceBits + alphaBits) > 0); +} + +GLenum InternalFormat::getReadPixelsFormat(const Extensions &extensions) const +{ + switch (format) + { + case GL_BGRA_EXT: + // BGRA textures may be enabled but calling glReadPixels with BGRA is disallowed without + // GL_EXT_texture_format_BGRA8888. Read as RGBA instead. + if (!extensions.readFormatBgraEXT) + { + return GL_RGBA; + } + return GL_BGRA_EXT; + + default: + return format; + } +} + +GLenum InternalFormat::getReadPixelsType(const Version &version) const +{ + switch (type) + { + case GL_HALF_FLOAT: + case GL_HALF_FLOAT_OES: + if (version < Version(3, 0)) + { + // The internal format may have a type of GL_HALF_FLOAT but when exposing this type + // as the IMPLEMENTATION_READ_TYPE, only HALF_FLOAT_OES is allowed by + // OES_texture_half_float. HALF_FLOAT becomes core in ES3 and is acceptable to use + // as an IMPLEMENTATION_READ_TYPE. + return GL_HALF_FLOAT_OES; + } + return GL_HALF_FLOAT; + + default: + return type; + } +} + +bool InternalFormat::supportSubImage() const +{ + return !CompressedFormatRequiresWholeImage(internalFormat); +} + +bool InternalFormat::isRequiredRenderbufferFormat(const Version &version) const +{ + // GLES 3.0.5 section 4.4.2.2: + // "Implementations are required to support the same internal formats for renderbuffers as the + // required formats for textures enumerated in section 3.8.3.1, with the exception of the color + // formats labelled "texture-only"." + if (!sized || compressed) + { + return false; + } + + // Luma formats. + if (isLUMA()) + { + return false; + } + + // Depth/stencil formats. + if (depthBits > 0 || stencilBits > 0) + { + // GLES 2.0.25 table 4.5. + // GLES 3.0.5 section 3.8.3.1. + // GLES 3.1 table 8.14. + + // Required formats in all versions. + switch (internalFormat) + { + case GL_DEPTH_COMPONENT16: + case GL_STENCIL_INDEX8: + // Note that STENCIL_INDEX8 is not mentioned in GLES 3.0.5 section 3.8.3.1, but it + // is in section 4.4.2.2. + return true; + default: + break; + } + if (version.major < 3) + { + return false; + } + // Required formats in GLES 3.0 and up. + switch (internalFormat) + { + case GL_DEPTH_COMPONENT32F: + case GL_DEPTH_COMPONENT24: + case GL_DEPTH32F_STENCIL8: + case GL_DEPTH24_STENCIL8: + return true; + default: + return false; + } + } + + // RGBA formats. + // GLES 2.0.25 table 4.5. + // GLES 3.0.5 section 3.8.3.1. + // GLES 3.1 table 8.13. + + // Required formats in all versions. + switch (internalFormat) + { + case GL_RGBA4: + case GL_RGB5_A1: + case GL_RGB565: + return true; + default: + break; + } + if (version.major < 3) + { + return false; + } + + if (format == GL_BGRA_EXT) + { + return false; + } + + switch (componentType) + { + case GL_SIGNED_NORMALIZED: + case GL_FLOAT: + return false; + case GL_UNSIGNED_INT: + case GL_INT: + // Integer RGB formats are not required renderbuffer formats. + if (alphaBits == 0 && blueBits != 0) + { + return false; + } + // All integer R and RG formats are required. + // Integer RGBA formats including RGB10_A2_UI are required. + return true; + case GL_UNSIGNED_NORMALIZED: + if (internalFormat == GL_SRGB8) + { + return false; + } + return true; + default: + UNREACHABLE(); + return false; + } +} + +bool InternalFormat::isInt() const +{ + return componentType == GL_INT || componentType == GL_UNSIGNED_INT; +} + +bool InternalFormat::isDepthOrStencil() const +{ + return depthBits != 0 || stencilBits != 0; +} + +Format::Format(GLenum internalFormat) : Format(GetSizedInternalFormatInfo(internalFormat)) {} + +Format::Format(const InternalFormat &internalFormat) : info(&internalFormat) {} + +Format::Format(GLenum internalFormat, GLenum type) + : info(&GetInternalFormatInfo(internalFormat, type)) +{} + +Format::Format(const Format &other) = default; +Format &Format::operator=(const Format &other) = default; + +bool Format::valid() const +{ + return info->internalFormat != GL_NONE; +} + +// static +bool Format::SameSized(const Format &a, const Format &b) +{ + return a.info->sizedInternalFormat == b.info->sizedInternalFormat; +} + +static GLenum EquivalentBlitInternalFormat(GLenum internalformat) +{ + // BlitFramebuffer works if the color channels are identically + // sized, even if there is a swizzle (for example, blitting from a + // multisampled RGBA8 renderbuffer to a BGRA8 texture). This could + // be expanded and/or autogenerated if that is found necessary. + if (internalformat == GL_BGRA8_EXT) + { + return GL_RGBA8; + } + + // GL_ANGLE_rgbx_internal_format: Treat RGBX8 as RGB8, since the X channel is ignored. + if (internalformat == GL_RGBX8_ANGLE) + { + return GL_RGB8; + } + + // Treat ANGLE's BGRX8 as RGB8 since it's swizzled and the X channel is ignored. + if (internalformat == GL_BGRX8_ANGLEX) + { + return GL_RGB8; + } + + return internalformat; +} + +// static +bool Format::EquivalentForBlit(const Format &a, const Format &b) +{ + return (EquivalentBlitInternalFormat(a.info->sizedInternalFormat) == + EquivalentBlitInternalFormat(b.info->sizedInternalFormat)); +} + +// static +Format Format::Invalid() +{ + static Format invalid(GL_NONE, GL_NONE); + return invalid; +} + +std::ostream &operator<<(std::ostream &os, const Format &fmt) +{ + // TODO(ynovikov): return string representation when available + return FmtHex(os, fmt.info->sizedInternalFormat); +} + +bool InternalFormat::operator==(const InternalFormat &other) const +{ + // We assume all internal formats are unique if they have the same internal format and type + return internalFormat == other.internalFormat && type == other.type; +} + +bool InternalFormat::operator!=(const InternalFormat &other) const +{ + return !(*this == other); +} + +void InsertFormatInfo(InternalFormatInfoMap *map, const InternalFormat &formatInfo) +{ + ASSERT(!formatInfo.sized || (*map).count(formatInfo.internalFormat) == 0); + ASSERT((*map)[formatInfo.internalFormat].count(formatInfo.type) == 0); + (*map)[formatInfo.internalFormat][formatInfo.type] = formatInfo; +} + +// YuvFormatInfo implementation +YuvFormatInfo::YuvFormatInfo(GLenum internalFormat, const Extents &yPlaneExtent) +{ + ASSERT(gl::IsYuvFormat(internalFormat)); + ASSERT((gl::GetPlaneCount(internalFormat) > 0) && (gl::GetPlaneCount(internalFormat) <= 3)); + + glInternalFormat = internalFormat; + planeCount = gl::GetPlaneCount(internalFormat); + + // Chroma planes of a YUV format can be subsampled + int horizontalSubsampleFactor = 0; + int verticalSubsampleFactor = 0; + gl::GetSubSampleFactor(internalFormat, &horizontalSubsampleFactor, &verticalSubsampleFactor); + + // Compute plane Bpp + planeBpp[0] = gl::GetYPlaneBpp(internalFormat); + planeBpp[1] = gl::GetChromaPlaneBpp(internalFormat); + planeBpp[2] = (planeCount > 2) ? planeBpp[1] : 0; + + // Compute plane extent + planeExtent[0] = yPlaneExtent; + planeExtent[1] = {(yPlaneExtent.width / horizontalSubsampleFactor), + (yPlaneExtent.height / verticalSubsampleFactor), yPlaneExtent.depth}; + planeExtent[2] = (planeCount > 2) ? planeExtent[1] : Extents(); + + // Compute plane pitch + planePitch[0] = planeExtent[0].width * planeBpp[0]; + planePitch[1] = planeExtent[1].width * planeBpp[1]; + planePitch[2] = planeExtent[2].width * planeBpp[2]; + + // Compute plane size + planeSize[0] = planePitch[0] * planeExtent[0].height; + planeSize[1] = planePitch[1] * planeExtent[1].height; + planeSize[2] = planePitch[2] * planeExtent[2].height; + + // Compute plane offset + planeOffset[0] = 0; + planeOffset[1] = planeSize[0]; + planeOffset[2] = planeSize[0] + planeSize[1]; +} + +// YUV format related helpers +bool IsYuvFormat(GLenum format) +{ + switch (format) + { + case GL_G8_B8R8_2PLANE_420_UNORM_ANGLE: + case GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE: + case GL_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_ANGLE: + case GL_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_ANGLE: + case GL_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_ANGLE: + case GL_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_ANGLE: + case GL_G16_B16R16_2PLANE_420_UNORM_ANGLE: + case GL_G16_B16_R16_3PLANE_420_UNORM_ANGLE: + return true; + default: + return false; + } +} + +uint32_t GetPlaneCount(GLenum format) +{ + switch (format) + { + case GL_G8_B8R8_2PLANE_420_UNORM_ANGLE: + case GL_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_ANGLE: + case GL_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_ANGLE: + case GL_G16_B16R16_2PLANE_420_UNORM_ANGLE: + return 2; + case GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE: + case GL_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_ANGLE: + case GL_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_ANGLE: + case GL_G16_B16_R16_3PLANE_420_UNORM_ANGLE: + return 3; + default: + UNREACHABLE(); + return 0; + } +} + +uint32_t GetYPlaneBpp(GLenum format) +{ + switch (format) + { + case GL_G8_B8R8_2PLANE_420_UNORM_ANGLE: + case GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE: + return 1; + case GL_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_ANGLE: + case GL_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_ANGLE: + case GL_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_ANGLE: + case GL_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_ANGLE: + case GL_G16_B16R16_2PLANE_420_UNORM_ANGLE: + case GL_G16_B16_R16_3PLANE_420_UNORM_ANGLE: + return 2; + default: + UNREACHABLE(); + return 0; + } +} + +uint32_t GetChromaPlaneBpp(GLenum format) +{ + // 2 plane 420 YUV formats have CbCr channels interleaved. + // 3 plane 420 YUV formats have separate Cb and Cr planes. + switch (format) + { + case GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE: + return 1; + case GL_G8_B8R8_2PLANE_420_UNORM_ANGLE: + case GL_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_ANGLE: + case GL_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_ANGLE: + case GL_G16_B16_R16_3PLANE_420_UNORM_ANGLE: + return 2; + case GL_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_ANGLE: + case GL_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_ANGLE: + case GL_G16_B16R16_2PLANE_420_UNORM_ANGLE: + return 4; + default: + UNREACHABLE(); + return 0; + } +} + +void GetSubSampleFactor(GLenum format, int *horizontalSubsampleFactor, int *verticalSubsampleFactor) +{ + ASSERT(horizontalSubsampleFactor && verticalSubsampleFactor); + + switch (format) + { + case GL_G8_B8R8_2PLANE_420_UNORM_ANGLE: + case GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE: + case GL_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_ANGLE: + case GL_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_ANGLE: + case GL_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_ANGLE: + case GL_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_ANGLE: + case GL_G16_B16R16_2PLANE_420_UNORM_ANGLE: + case GL_G16_B16_R16_3PLANE_420_UNORM_ANGLE: + *horizontalSubsampleFactor = 2; + *verticalSubsampleFactor = 2; + break; + default: + UNREACHABLE(); + break; + } +} + +struct FormatBits +{ + constexpr GLuint pixelBytes() const + { + return (red + green + blue + alpha + shared + unused) / 8; + } + constexpr GLuint componentCount() const + { + return ((red > 0) ? 1 : 0) + ((green > 0) ? 1 : 0) + ((blue > 0) ? 1 : 0) + + ((alpha > 0) ? 1 : 0); + } + constexpr bool valid() const + { + return ((red + green + blue + alpha + shared + unused) % 8) == 0; + } + + GLuint red; + GLuint green; + GLuint blue; + GLuint alpha; + GLuint unused; + GLuint shared; +}; + +template +constexpr FormatBits FB() +{ + constexpr FormatBits formatBits = {red, green, blue, alpha, unused, shared}; + static_assert(formatBits.valid(), "Invalid FormatBits"); + return formatBits; +} + +void AddRGBAXFormat(InternalFormatInfoMap *map, + GLenum internalFormat, + bool sized, + const FormatBits &formatBits, + GLenum format, + GLenum type, + GLenum componentType, + bool srgb, + InternalFormat::SupportCheckFunction textureSupport, + InternalFormat::SupportCheckFunction filterSupport, + InternalFormat::SupportCheckFunction textureAttachmentSupport, + InternalFormat::SupportCheckFunction renderbufferSupport, + InternalFormat::SupportCheckFunction blendSupport) +{ + ASSERT(formatBits.valid()); + + InternalFormat formatInfo; + formatInfo.internalFormat = internalFormat; + formatInfo.sized = sized; + formatInfo.sizedInternalFormat = + sized ? internalFormat : GetSizedFormatInternal(internalFormat, type); + formatInfo.redBits = formatBits.red; + formatInfo.greenBits = formatBits.green; + formatInfo.blueBits = formatBits.blue; + formatInfo.alphaBits = formatBits.alpha; + formatInfo.sharedBits = formatBits.shared; + formatInfo.pixelBytes = formatBits.pixelBytes(); + formatInfo.componentCount = formatBits.componentCount(); + formatInfo.format = format; + formatInfo.type = type; + formatInfo.componentType = componentType; + formatInfo.colorEncoding = (srgb ? GL_SRGB : GL_LINEAR); + formatInfo.textureSupport = textureSupport; + formatInfo.filterSupport = filterSupport; + formatInfo.textureAttachmentSupport = textureAttachmentSupport; + formatInfo.renderbufferSupport = renderbufferSupport; + formatInfo.blendSupport = blendSupport; + + InsertFormatInfo(map, formatInfo); +} + +void AddRGBAFormat(InternalFormatInfoMap *map, + GLenum internalFormat, + bool sized, + GLuint red, + GLuint green, + GLuint blue, + GLuint alpha, + GLuint shared, + GLenum format, + GLenum type, + GLenum componentType, + bool srgb, + InternalFormat::SupportCheckFunction textureSupport, + InternalFormat::SupportCheckFunction filterSupport, + InternalFormat::SupportCheckFunction textureAttachmentSupport, + InternalFormat::SupportCheckFunction renderbufferSupport, + InternalFormat::SupportCheckFunction blendSupport) +{ + return AddRGBAXFormat(map, internalFormat, sized, {red, green, blue, alpha, 0, shared}, format, + type, componentType, srgb, textureSupport, filterSupport, + textureAttachmentSupport, renderbufferSupport, blendSupport); +} + +static void AddLUMAFormat(InternalFormatInfoMap *map, + GLenum internalFormat, + bool sized, + GLuint luminance, + GLuint alpha, + GLenum format, + GLenum type, + GLenum componentType, + InternalFormat::SupportCheckFunction textureSupport, + InternalFormat::SupportCheckFunction filterSupport, + InternalFormat::SupportCheckFunction textureAttachmentSupport, + InternalFormat::SupportCheckFunction renderbufferSupport, + InternalFormat::SupportCheckFunction blendSupport) +{ + InternalFormat formatInfo; + formatInfo.internalFormat = internalFormat; + formatInfo.sized = sized; + formatInfo.sizedInternalFormat = + sized ? internalFormat : GetSizedFormatInternal(internalFormat, type); + formatInfo.luminanceBits = luminance; + formatInfo.alphaBits = alpha; + formatInfo.pixelBytes = (luminance + alpha) / 8; + formatInfo.componentCount = ((luminance > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0); + formatInfo.format = format; + formatInfo.type = type; + formatInfo.componentType = componentType; + formatInfo.colorEncoding = GL_LINEAR; + formatInfo.textureSupport = textureSupport; + formatInfo.filterSupport = filterSupport; + formatInfo.textureAttachmentSupport = textureAttachmentSupport; + formatInfo.renderbufferSupport = renderbufferSupport; + formatInfo.blendSupport = blendSupport; + + InsertFormatInfo(map, formatInfo); +} + +void AddDepthStencilFormat(InternalFormatInfoMap *map, + GLenum internalFormat, + bool sized, + GLuint depthBits, + GLuint stencilBits, + GLuint unusedBits, + GLenum format, + GLenum type, + GLenum componentType, + InternalFormat::SupportCheckFunction textureSupport, + InternalFormat::SupportCheckFunction filterSupport, + InternalFormat::SupportCheckFunction textureAttachmentSupport, + InternalFormat::SupportCheckFunction renderbufferSupport, + InternalFormat::SupportCheckFunction blendSupport) +{ + InternalFormat formatInfo; + formatInfo.internalFormat = internalFormat; + formatInfo.sized = sized; + formatInfo.sizedInternalFormat = + sized ? internalFormat : GetSizedFormatInternal(internalFormat, type); + formatInfo.depthBits = depthBits; + formatInfo.stencilBits = stencilBits; + formatInfo.pixelBytes = (depthBits + stencilBits + unusedBits) / 8; + formatInfo.componentCount = ((depthBits > 0) ? 1 : 0) + ((stencilBits > 0) ? 1 : 0); + formatInfo.format = format; + formatInfo.type = type; + formatInfo.componentType = componentType; + formatInfo.colorEncoding = GL_LINEAR; + formatInfo.textureSupport = textureSupport; + formatInfo.filterSupport = filterSupport; + formatInfo.textureAttachmentSupport = textureAttachmentSupport; + formatInfo.renderbufferSupport = renderbufferSupport; + formatInfo.blendSupport = blendSupport; + + InsertFormatInfo(map, formatInfo); +} + +void AddCompressedFormat(InternalFormatInfoMap *map, + GLenum internalFormat, + GLuint compressedBlockWidth, + GLuint compressedBlockHeight, + GLuint compressedBlockDepth, + GLuint compressedBlockSize, + GLuint componentCount, + bool srgb, + InternalFormat::SupportCheckFunction textureSupport, + InternalFormat::SupportCheckFunction filterSupport, + InternalFormat::SupportCheckFunction textureAttachmentSupport, + InternalFormat::SupportCheckFunction renderbufferSupport, + InternalFormat::SupportCheckFunction blendSupport) +{ + InternalFormat formatInfo; + formatInfo.internalFormat = internalFormat; + formatInfo.sized = true; + formatInfo.sizedInternalFormat = internalFormat; + formatInfo.compressedBlockWidth = compressedBlockWidth; + formatInfo.compressedBlockHeight = compressedBlockHeight; + formatInfo.compressedBlockDepth = compressedBlockDepth; + formatInfo.pixelBytes = compressedBlockSize / 8; + formatInfo.componentCount = componentCount; + formatInfo.format = internalFormat; + formatInfo.type = GL_UNSIGNED_BYTE; + formatInfo.componentType = GL_UNSIGNED_NORMALIZED; + formatInfo.colorEncoding = (srgb ? GL_SRGB : GL_LINEAR); + formatInfo.compressed = true; + formatInfo.textureSupport = textureSupport; + formatInfo.filterSupport = filterSupport; + formatInfo.textureAttachmentSupport = textureAttachmentSupport; + formatInfo.renderbufferSupport = renderbufferSupport; + formatInfo.blendSupport = blendSupport; + + InsertFormatInfo(map, formatInfo); +} + +void AddPalettedFormat(InternalFormatInfoMap *map, + GLenum internalFormat, + GLuint paletteBits, + GLuint pixelBytes, + GLenum format, + GLuint componentCount, + InternalFormat::SupportCheckFunction textureSupport, + InternalFormat::SupportCheckFunction filterSupport, + InternalFormat::SupportCheckFunction textureAttachmentSupport, + InternalFormat::SupportCheckFunction renderbufferSupport, + InternalFormat::SupportCheckFunction blendSupport) +{ + InternalFormat formatInfo; + formatInfo.internalFormat = internalFormat; + formatInfo.sized = true; + formatInfo.sizedInternalFormat = internalFormat; + formatInfo.paletteBits = paletteBits; + formatInfo.pixelBytes = pixelBytes; + formatInfo.componentCount = componentCount; + formatInfo.format = format; + formatInfo.type = GL_UNSIGNED_BYTE; + formatInfo.componentType = GL_UNSIGNED_NORMALIZED; + formatInfo.colorEncoding = GL_LINEAR; + formatInfo.paletted = true; + formatInfo.textureSupport = textureSupport; + formatInfo.filterSupport = filterSupport; + formatInfo.textureAttachmentSupport = textureAttachmentSupport; + formatInfo.renderbufferSupport = renderbufferSupport; + formatInfo.blendSupport = blendSupport; + + InsertFormatInfo(map, formatInfo); +} + +void AddYUVFormat(InternalFormatInfoMap *map, + GLenum internalFormat, + bool sized, + GLuint cr, + GLuint y, + GLuint cb, + GLuint alpha, + GLuint shared, + GLenum format, + GLenum type, + GLenum componentType, + bool srgb, + InternalFormat::SupportCheckFunction textureSupport, + InternalFormat::SupportCheckFunction filterSupport, + InternalFormat::SupportCheckFunction textureAttachmentSupport, + InternalFormat::SupportCheckFunction renderbufferSupport, + InternalFormat::SupportCheckFunction blendSupport) +{ + ASSERT(sized); + + InternalFormat formatInfo; + formatInfo.internalFormat = internalFormat; + formatInfo.sized = sized; + formatInfo.sizedInternalFormat = internalFormat; + formatInfo.redBits = cr; + formatInfo.greenBits = y; + formatInfo.blueBits = cb; + formatInfo.alphaBits = alpha; + formatInfo.sharedBits = shared; + formatInfo.pixelBytes = (cr + y + cb + alpha + shared) / 8; + formatInfo.componentCount = + ((cr > 0) ? 1 : 0) + ((y > 0) ? 1 : 0) + ((cb > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0); + formatInfo.format = format; + formatInfo.type = type; + formatInfo.componentType = componentType; + formatInfo.colorEncoding = (srgb ? GL_SRGB : GL_LINEAR); + formatInfo.textureSupport = textureSupport; + formatInfo.filterSupport = filterSupport; + formatInfo.textureAttachmentSupport = textureAttachmentSupport; + formatInfo.renderbufferSupport = renderbufferSupport; + formatInfo.blendSupport = blendSupport; + + InsertFormatInfo(map, formatInfo); +} + +// Notes: +// 1. "Texture supported" includes all the means by which texture can be created, however, +// GL_EXT_texture_storage in ES2 is a special case, when only glTexStorage* is allowed. +// The assumption is that ES2 validation will not check textureSupport for sized formats. +// +// 2. Sized half float types are a combination of GL_HALF_FLOAT and GL_HALF_FLOAT_OES support, +// due to a limitation that only one type for sized formats is allowed. +// +// TODO(ynovikov): http://anglebug.com/2846 Verify support fields of BGRA, depth, stencil +// and compressed formats. Perform texturable check as part of filterable and attachment checks. +static InternalFormatInfoMap BuildInternalFormatInfoMap() +{ + InternalFormatInfoMap map; + + // From ES 3.0.1 spec, table 3.12 + map[GL_NONE][GL_NONE] = InternalFormat(); + + // clang-format off + + // | Internal format |sized| R | G | B | A |S | Format | Type | Component type | SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend + AddRGBAFormat(&map, GL_R8, true, 8, 0, 0, 0, 0, GL_RED, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, SizedRGSupport, AlwaysSupported, SizedRGSupport, RequireESOrExt<3, 0, &Extensions::textureRgEXT>, RequireESOrExt<3, 0, &Extensions::textureRgEXT>); + AddRGBAFormat(&map, GL_R8_SNORM, true, 8, 0, 0, 0, 0, GL_RED, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3, 0>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RG8, true, 8, 8, 0, 0, 0, GL_RG, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, SizedRGSupport, AlwaysSupported, SizedRGSupport, RequireESOrExt<3, 0, &Extensions::textureRgEXT>, RequireESOrExt<3, 0, &Extensions::textureRgEXT>); + AddRGBAFormat(&map, GL_RG8_SNORM, true, 8, 8, 0, 0, 0, GL_RG, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3, 0>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB8, true, 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, 0, &Extensions::textureStorageEXT>, AlwaysSupported, RequireESOrExt<3, 0, &Extensions::textureStorageEXT>, RequireESOrExt<3, 0, &Extensions::rgb8Rgba8OES>, RequireESOrExt<3, 0, &Extensions::rgb8Rgba8OES>); + AddRGBAFormat(&map, GL_RGB8_SNORM, true, 8, 8, 8, 0, 0, GL_RGB, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3, 0>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB565, true, 5, 6, 5, 0, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, 0, &Extensions::textureStorageEXT>, AlwaysSupported, RequireESOrExt<3, 0, &Extensions::textureStorageEXT>, RequireES<2, 0>, RequireES<2, 0>); + AddRGBAFormat(&map, GL_RGBA4, true, 4, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, 0, &Extensions::textureStorageEXT>, AlwaysSupported, RequireESOrExt<3, 0, &Extensions::textureStorageEXT>, RequireES<2, 0>, RequireES<2, 0>); + AddRGBAFormat(&map, GL_RGB5_A1, true, 5, 5, 5, 1, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, 0, &Extensions::textureStorageEXT>, AlwaysSupported, RequireESOrExt<3, 0, &Extensions::textureStorageEXT>, RequireES<2, 0>, RequireES<2, 0>); + AddRGBAFormat(&map, GL_RGBA8, true, 8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, 0, &Extensions::textureStorageEXT>, AlwaysSupported, RequireESOrExt<3, 0, &Extensions::textureStorageEXT>, RequireESOrExt<3, 0, &Extensions::rgb8Rgba8OES>, RequireESOrExt<3, 0, &Extensions::rgb8Rgba8OES>); + AddRGBAFormat(&map, GL_RGBA8_SNORM, true, 8, 8, 8, 8, 0, GL_RGBA, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3, 0>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB10_A2UI, true, 10, 10, 10, 2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_SRGB8, true, 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireES<3, 0>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_SRGB8_ALPHA8, true, 8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireESOrExt<3, 0, &Extensions::sRGBEXT>, AlwaysSupported, RequireES<3, 0>, RequireESOrExt<3, 0, &Extensions::sRGBEXT>, RequireESOrExt<3, 0, &Extensions::sRGBEXT>); + AddRGBAFormat(&map, GL_R11F_G11F_B10F, true, 11, 11, 10, 0, 0, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_FLOAT, false, RequireES<3, 0>, AlwaysSupported, RequireExt<&Extensions::colorBufferFloatEXT>, RequireExt<&Extensions::colorBufferFloatEXT>, RequireExt<&Extensions::colorBufferFloatEXT>); + AddRGBAFormat(&map, GL_RGB9_E5, true, 9, 9, 9, 0, 5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT, false, RequireES<3, 0>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_R8I, true, 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_BYTE, GL_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_R8UI, true, 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_R16I, true, 16, 0, 0, 0, 0, GL_RED_INTEGER, GL_SHORT, GL_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_R16UI, true, 16, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_R32I, true, 32, 0, 0, 0, 0, GL_RED_INTEGER, GL_INT, GL_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_R32UI, true, 32, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_RG8I, true, 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_BYTE, GL_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_RG8UI, true, 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_RG16I, true, 16, 16, 0, 0, 0, GL_RG_INTEGER, GL_SHORT, GL_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_RG16UI, true, 16, 16, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_RG32I, true, 32, 32, 0, 0, 0, GL_RG_INTEGER, GL_INT, GL_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_RG32UI, true, 32, 32, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_RGB8I, true, 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_BYTE, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB8UI, true, 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB16I, true, 16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_SHORT, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB16UI, true, 16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB32I, true, 32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_INT, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB32UI, true, 32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGBA8I, true, 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_BYTE, GL_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_RGBA8UI, true, 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_RGBA16I, true, 16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_SHORT, GL_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_RGBA16UI, true, 16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_RGBA32I, true, 32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_INT, GL_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_RGBA32UI, true, 32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + + AddRGBAFormat(&map, GL_BGRA8_EXT, true, 8, 8, 8, 8, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888EXT>, AlwaysSupported, RequireExt<&Extensions::textureFormatBGRA8888EXT>, RequireExt<&Extensions::textureFormatBGRA8888EXT>, RequireExt<&Extensions::textureFormatBGRA8888EXT>); + AddRGBAFormat(&map, GL_BGRA4_ANGLEX, true, 4, 4, 4, 4, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888EXT>, AlwaysSupported, RequireExt<&Extensions::textureFormatBGRA8888EXT>, RequireExt<&Extensions::textureFormatBGRA8888EXT>, RequireExt<&Extensions::textureFormatBGRA8888EXT>); + AddRGBAFormat(&map, GL_BGR5_A1_ANGLEX, true, 5, 5, 5, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888EXT>, AlwaysSupported, RequireExt<&Extensions::textureFormatBGRA8888EXT>, RequireExt<&Extensions::textureFormatBGRA8888EXT>, RequireExt<&Extensions::textureFormatBGRA8888EXT>); + + // Special format that is used for D3D textures that are used within ANGLE via the + // EGL_ANGLE_d3d_texture_client_buffer extension. We don't allow uploading texture images with + // this format, but textures in this format can be created from D3D textures, and filtering them + // and rendering to them is allowed. + AddRGBAFormat(&map, GL_BGRA8_SRGB_ANGLEX, true, 8, 8, 8, 8, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, NeverSupported, AlwaysSupported, AlwaysSupported, AlwaysSupported, AlwaysSupported); + + // Special format which is not really supported, so always false for all supports. + AddRGBAFormat(&map, GL_BGR565_ANGLEX, true, 5, 6, 5, 0, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_NORMALIZED, false, NeverSupported, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_BGR10_A2_ANGLEX, true, 10, 10, 10, 2, 0, GL_BGRA_EXT, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_NORMALIZED, false, NeverSupported, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + + // Special format to emulate RGB8 with RGBA8 within ANGLE. + AddRGBAFormat(&map, GL_RGBX8_ANGLE, true, 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported, AlwaysSupported, NeverSupported); + + // Special format to emulate BGR8 with BGRA8 within ANGLE. + AddRGBAFormat(&map, GL_BGRX8_ANGLEX, true, 8, 8, 8, 0, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, NeverSupported, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + + // This format is supported on ES 2.0 with two extensions, so keep it out-of-line to not widen the table above even more. + // | Internal format |sized| R | G | B | A |S | Format | Type | Component type | SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend + AddRGBAFormat(&map, GL_RGB10_A2, true, 10, 10, 10, 2, 0, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_NORMALIZED, false, RequireESOrExtAndExt<3, 0, &Extensions::textureStorageEXT, &Extensions::textureType2101010REVEXT>, AlwaysSupported, RequireES<3, 0>, RequireES<3, 0>, RequireES<3, 0>); + + // Floating point formats + // | Internal format |sized| R | G | B | A |S | Format | Type | Component type | SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend + // It's not possible to have two entries per sized format. + // E.g. for GL_RG16F, one with GL_HALF_FLOAT type and the other with GL_HALF_FLOAT_OES type. + // So, GL_HALF_FLOAT type formats conditions are merged with GL_HALF_FLOAT_OES type conditions. + AddRGBAFormat(&map, GL_R16F, true, 16, 0, 0, 0, 0, GL_RED, GL_HALF_FLOAT, GL_FLOAT, false, SizedHalfFloatRGSupport, SizedHalfFloatFilterSupport, SizedHalfFloatRGTextureAttachmentSupport, SizedHalfFloatRGRenderbufferSupport, SizedHalfFloatRGRenderbufferSupport); + AddRGBAFormat(&map, GL_RG16F, true, 16, 16, 0, 0, 0, GL_RG, GL_HALF_FLOAT, GL_FLOAT, false, SizedHalfFloatRGSupport, SizedHalfFloatFilterSupport, SizedHalfFloatRGTextureAttachmentSupport, SizedHalfFloatRGRenderbufferSupport, SizedHalfFloatRGRenderbufferSupport); + AddRGBAFormat(&map, GL_RGB16F, true, 16, 16, 16, 0, 0, GL_RGB, GL_HALF_FLOAT, GL_FLOAT, false, SizedHalfFloatSupport, SizedHalfFloatFilterSupport, SizedHalfFloatRGBTextureAttachmentSupport, SizedHalfFloatRGBRenderbufferSupport, SizedHalfFloatRGBRenderbufferSupport); + AddRGBAFormat(&map, GL_RGBA16F, true, 16, 16, 16, 16, 0, GL_RGBA, GL_HALF_FLOAT, GL_FLOAT, false, SizedHalfFloatSupport, SizedHalfFloatFilterSupport, SizedHalfFloatRGBATextureAttachmentSupport, SizedHalfFloatRGBARenderbufferSupport, SizedHalfFloatRGBARenderbufferSupport); + AddRGBAFormat(&map, GL_R32F, true, 32, 0, 0, 0, 0, GL_RED, GL_FLOAT, GL_FLOAT, false, SizedFloatRGSupport, RequireExt<&Extensions::textureFloatLinearOES>, RequireExt<&Extensions::colorBufferFloatEXT>, RequireExt<&Extensions::colorBufferFloatEXT>, Float32BlendableSupport); + AddRGBAFormat(&map, GL_RG32F, true, 32, 32, 0, 0, 0, GL_RG, GL_FLOAT, GL_FLOAT, false, SizedFloatRGSupport, RequireExt<&Extensions::textureFloatLinearOES>, RequireExt<&Extensions::colorBufferFloatEXT>, RequireExt<&Extensions::colorBufferFloatEXT>, Float32BlendableSupport); + AddRGBAFormat(&map, GL_RGB32F, true, 32, 32, 32, 0, 0, GL_RGB, GL_FLOAT, GL_FLOAT, false, SizedFloatRGBSupport, RequireExt<&Extensions::textureFloatLinearOES>, RequireExt<&Extensions::colorBufferFloatRgbCHROMIUM>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGBA32F, true, 32, 32, 32, 32, 0, GL_RGBA, GL_FLOAT, GL_FLOAT, false, SizedFloatRGBASupport, RequireExt<&Extensions::textureFloatLinearOES>, SizedFloatRGBARenderableSupport, SizedFloatRGBARenderableSupport, Float32BlendableSupport); + + // ANGLE Depth stencil formats + // | Internal format |sized| D |S | X | Format | Type | Component type | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend + AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT16, true, 16, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, RequireESOrExtOrExt<3, 0, &Extensions::depthTextureANGLE, &Extensions::depthTextureOES>, RequireESOrExtOrExt<3, 0, &Extensions::depthTextureANGLE, &Extensions::depthTextureOES>, RequireES<1, 0>, RequireES<1, 0>, RequireES<1, 0>); + AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT24, true, 24, 0, 8, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireES<3, 0>, RequireESOrExt<3, 0, &Extensions::depthTextureANGLE>, RequireES<3, 0>, RequireESOrExt<3, 0, &Extensions::depth24OES>, RequireESOrExt<3, 0, &Extensions::depth24OES>); + AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT32F, true, 32, 0, 0, GL_DEPTH_COMPONENT, GL_FLOAT, GL_FLOAT, RequireES<3, 0>, RequireESOrExt<3, 0, &Extensions::depthTextureANGLE>, RequireES<3, 0>, RequireES<3, 0>, RequireES<3, 0>); + AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT32_OES, true, 32, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>, AlwaysSupported, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>, RequireExtOrExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES, &Extensions::depth32OES>, RequireExtOrExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES, &Extensions::depth32OES>); + AddDepthStencilFormat(&map, GL_DEPTH24_STENCIL8, true, 24, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_NORMALIZED, RequireESOrExtOrExt<3, 0, &Extensions::depthTextureANGLE, &Extensions::packedDepthStencilOES>, AlwaysSupported, RequireESOrExtOrExt<3, 0, &Extensions::depthTextureANGLE, &Extensions::packedDepthStencilOES>, RequireESOrExtOrExt<3, 0, &Extensions::depthTextureANGLE, &Extensions::packedDepthStencilOES>, RequireESOrExtOrExt<3, 0, &Extensions::depthTextureANGLE, &Extensions::packedDepthStencilOES>); + AddDepthStencilFormat(&map, GL_DEPTH32F_STENCIL8, true, 32, 8, 24, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_FLOAT, RequireESOrExt<3, 0, &Extensions::depthBufferFloat2NV>, AlwaysSupported, RequireESOrExt<3, 0, &Extensions::depthBufferFloat2NV>, RequireESOrExt<3, 0, &Extensions::depthBufferFloat2NV>, RequireESOrExt<3, 0, &Extensions::depthBufferFloat2NV>); + // STENCIL_INDEX8 is special-cased, see around the bottom of the list. + + // Luminance alpha formats + // | Internal format |sized| L | A | Format | Type | Component type | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend + AddLUMAFormat(&map, GL_ALPHA8_EXT, true, 0, 8, GL_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExt<&Extensions::textureStorageEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddLUMAFormat(&map, GL_LUMINANCE8_EXT, true, 8, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExt<&Extensions::textureStorageEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddLUMAFormat(&map, GL_LUMINANCE8_ALPHA8_EXT, true, 8, 8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExt<&Extensions::textureStorageEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddLUMAFormat(&map, GL_ALPHA16F_EXT, true, 0, 16, GL_ALPHA, GL_HALF_FLOAT_OES, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorageEXT, &Extensions::textureHalfFloatOES>, RequireExt<&Extensions::textureHalfFloatLinearOES>, NeverSupported, NeverSupported, NeverSupported); + AddLUMAFormat(&map, GL_LUMINANCE16F_EXT, true, 16, 0, GL_LUMINANCE, GL_HALF_FLOAT_OES, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorageEXT, &Extensions::textureHalfFloatOES>, RequireExt<&Extensions::textureHalfFloatLinearOES>, NeverSupported, NeverSupported, NeverSupported); + AddLUMAFormat(&map, GL_LUMINANCE_ALPHA16F_EXT, true, 16, 16, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorageEXT, &Extensions::textureHalfFloatOES>, RequireExt<&Extensions::textureHalfFloatLinearOES>, NeverSupported, NeverSupported, NeverSupported); + AddLUMAFormat(&map, GL_ALPHA32F_EXT, true, 0, 32, GL_ALPHA, GL_FLOAT, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorageEXT, &Extensions::textureFloatOES>, RequireExt<&Extensions::textureFloatLinearOES>, NeverSupported, NeverSupported, NeverSupported); + AddLUMAFormat(&map, GL_LUMINANCE32F_EXT, true, 32, 0, GL_LUMINANCE, GL_FLOAT, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorageEXT, &Extensions::textureFloatOES>, RequireExt<&Extensions::textureFloatLinearOES>, NeverSupported, NeverSupported, NeverSupported); + AddLUMAFormat(&map, GL_LUMINANCE_ALPHA32F_EXT, true, 32, 32, GL_LUMINANCE_ALPHA, GL_FLOAT, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorageEXT, &Extensions::textureFloatOES>, RequireExt<&Extensions::textureFloatLinearOES>, NeverSupported, NeverSupported, NeverSupported); + + // Compressed formats, From ES 3.0.1 spec, table 3.16 + // | Internal format |W |H |D | BS |CC| SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend + AddCompressedFormat(&map, GL_COMPRESSED_R11_EAC, 4, 4, 1, 64, 1, false, ETC2EACSupport<&Extensions::compressedEACR11UnsignedTextureOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SIGNED_R11_EAC, 4, 4, 1, 64, 1, false, ETC2EACSupport<&Extensions::compressedEACR11SignedTextureOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RG11_EAC, 4, 4, 1, 128, 2, false, ETC2EACSupport<&Extensions::compressedEACRG11UnsignedTextureOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SIGNED_RG11_EAC, 4, 4, 1, 128, 2, false, ETC2EACSupport<&Extensions::compressedEACRG11SignedTextureOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGB8_ETC2, 4, 4, 1, 64, 3, false, ETC2EACSupport<&Extensions::compressedETC2RGB8TextureOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ETC2, 4, 4, 1, 64, 3, true, ETC2EACSupport<&Extensions::compressedETC2SRGB8TextureOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, 4, 4, 1, 64, 4, false, ETC2EACSupport<&Extensions::compressedETC2PunchthroughARGBA8TextureOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, 4, 4, 1, 64, 4, true, ETC2EACSupport<&Extensions::compressedETC2PunchthroughASRGB8AlphaTextureOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA8_ETC2_EAC, 4, 4, 1, 128, 4, false, ETC2EACSupport<&Extensions::compressedETC2RGBA8TextureOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, 4, 4, 1, 128, 4, true, ETC2EACSupport<&Extensions::compressedETC2SRGB8Alpha8TextureOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + + // From GL_EXT_texture_compression_dxt1 + // | Internal format |W |H |D | BS |CC| SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend + AddCompressedFormat(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 1, 64, 3, false, RequireExt<&Extensions::textureCompressionDxt1EXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 4, 4, 1, 64, 4, false, RequireExt<&Extensions::textureCompressionDxt1EXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + + // From GL_ANGLE_texture_compression_dxt3 + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, 4, 4, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionDxt3ANGLE>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + + // From GL_ANGLE_texture_compression_dxt5 + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, 4, 4, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionDxt5ANGLE>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + + // From GL_OES_compressed_ETC1_RGB8_texture + AddCompressedFormat(&map, GL_ETC1_RGB8_OES, 4, 4, 1, 64, 3, false, RequireExt<&Extensions::compressedETC1RGB8TextureOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + + // From GL_EXT_texture_compression_s3tc_srgb + // | Internal format |W |H |D | BS |CC|SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend + AddCompressedFormat(&map, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, 4, 4, 1, 64, 3, true, RequireExt<&Extensions::textureCompressionS3tcSrgbEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 4, 4, 1, 64, 4, true, RequireExt<&Extensions::textureCompressionS3tcSrgbEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 4, 4, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionS3tcSrgbEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 4, 4, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionS3tcSrgbEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + + // From GL_KHR_texture_compression_astc_ldr and KHR_texture_compression_astc_hdr and GL_OES_texture_compression_astc + // | Internal format | W | H |D | BS |CC| SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_4x4_KHR, 4, 4, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_5x4_KHR, 5, 4, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_5x5_KHR, 5, 5, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_6x5_KHR, 6, 5, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_6x6_KHR, 6, 6, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_8x5_KHR, 8, 5, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_8x6_KHR, 8, 6, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_8x8_KHR, 8, 8, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_10x5_KHR, 10, 5, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_10x6_KHR, 10, 6, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_10x8_KHR, 10, 8, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_10x10_KHR, 10, 10, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_12x10_KHR, 12, 10, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_12x12_KHR, 12, 12, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, 4, 4, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, 5, 4, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, 5, 5, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, 6, 5, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, 6, 6, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, 8, 5, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, 8, 6, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, 8, 8, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, 10, 5, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, 10, 6, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, 10, 8, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, 10, 10, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, 12, 10, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, 12, 12, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_3x3x3_OES, 3, 3, 3, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_4x3x3_OES, 4, 3, 3, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_4x4x3_OES, 4, 4, 3, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_4x4x4_OES, 4, 4, 4, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_5x4x4_OES, 5, 4, 4, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_5x5x4_OES, 5, 5, 4, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_5x5x5_OES, 5, 5, 5, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_6x5x5_OES, 6, 5, 5, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_6x6x5_OES, 6, 6, 5, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_6x6x6_OES, 6, 6, 6, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES, 3, 3, 3, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES, 4, 3, 3, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES, 4, 4, 3, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES, 4, 4, 4, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES, 5, 4, 4, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES, 5, 5, 4, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES, 5, 5, 5, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES, 6, 5, 5, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES, 6, 6, 5, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES, 6, 6, 6, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + + // From EXT_texture_compression_rgtc + // | Internal format | W | H |D | BS |CC| SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend + AddCompressedFormat(&map, GL_COMPRESSED_RED_RGTC1_EXT, 4, 4, 1, 64, 1, false, RequireExt<&Extensions::textureCompressionRgtcEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SIGNED_RED_RGTC1_EXT, 4, 4, 1, 64, 1, false, RequireExt<&Extensions::textureCompressionRgtcEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RED_GREEN_RGTC2_EXT, 4, 4, 1, 128, 2, false, RequireExt<&Extensions::textureCompressionRgtcEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT, 4, 4, 1, 128, 2, false, RequireExt<&Extensions::textureCompressionRgtcEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + + // From EXT_texture_compression_bptc + // | Internal format | W | H |D | BS |CC| SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 4, 4, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionBptcEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT, 4, 4, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionBptcEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT, 4, 4, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionBptcEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT, 4, 4, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionBptcEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + + // Paletted formats + // | Internal format | | PS | Format | CC | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend + AddPalettedFormat(&map, GL_PALETTE4_RGB8_OES, 4, 3, GL_RGB, 3, RequireES1, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddPalettedFormat(&map, GL_PALETTE4_RGBA8_OES, 4, 4, GL_RGBA, 4, RequireES1, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddPalettedFormat(&map, GL_PALETTE4_R5_G6_B5_OES, 4, 2, GL_RGB, 3, RequireES1, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddPalettedFormat(&map, GL_PALETTE4_RGBA4_OES, 4, 2, GL_RGBA, 4, RequireES1, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddPalettedFormat(&map, GL_PALETTE4_RGB5_A1_OES, 4, 2, GL_RGBA, 4, RequireES1, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddPalettedFormat(&map, GL_PALETTE8_RGB8_OES, 8, 3, GL_RGB, 3, RequireES1, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddPalettedFormat(&map, GL_PALETTE8_RGBA8_OES, 8, 4, GL_RGBA, 4, RequireES1, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddPalettedFormat(&map, GL_PALETTE8_R5_G6_B5_OES, 8, 2, GL_RGB, 3, RequireES1, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddPalettedFormat(&map, GL_PALETTE8_RGBA4_OES, 8, 2, GL_RGBA, 4, RequireES1, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddPalettedFormat(&map, GL_PALETTE8_RGB5_A1_OES, 8, 2, GL_RGBA, 4, RequireES1, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + + // From GL_IMG_texture_compression_pvrtc + // | Internal format | W | H | D | BS |CC| SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend + AddCompressedFormat(&map, GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, 4, 4, 1, 64, 3, false, RequireExt<&Extensions::textureCompressionPvrtcIMG>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG, 8, 4, 1, 64, 3, false, RequireExt<&Extensions::textureCompressionPvrtcIMG>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, 4, 4, 1, 64, 4, false, RequireExt<&Extensions::textureCompressionPvrtcIMG>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, 8, 4, 1, 64, 4, false, RequireExt<&Extensions::textureCompressionPvrtcIMG>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + + // From GL_EXT_pvrtc_sRGB + // | Internal format | W | H | D | BS |CC| SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend + AddCompressedFormat(&map, GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT, 8, 4, 1, 64, 3, true, RequireExtAndExt<&Extensions::textureCompressionPvrtcIMG, &Extensions::pvrtcSRGBEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT, 4, 4, 1, 64, 3, true, RequireExtAndExt<&Extensions::textureCompressionPvrtcIMG, &Extensions::pvrtcSRGBEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT, 8, 4, 1, 64, 4, true, RequireExtAndExt<&Extensions::textureCompressionPvrtcIMG, &Extensions::pvrtcSRGBEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT, 4, 4, 1, 64, 4, true, RequireExtAndExt<&Extensions::textureCompressionPvrtcIMG, &Extensions::pvrtcSRGBEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + + // For STENCIL_INDEX8 we chose a normalized component type for the following reasons: + // - Multisampled buffer are disallowed for non-normalized integer component types and we want to support it for STENCIL_INDEX8 + // - All other stencil formats (all depth-stencil) are either float or normalized + // - It affects only validation of internalformat in RenderbufferStorageMultisample. + // | Internal format |sized|D |S |X | Format | Type | Component type | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend + AddDepthStencilFormat(&map, GL_STENCIL_INDEX8, true, 0, 8, 0, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireESOrExt<1, 0, &Extensions::textureStencil8OES>, NeverSupported, RequireESOrExt<1, 0, &Extensions::textureStencil8OES>, RequireES<1, 0>, RequireES<1, 0>); + + // From GL_ANGLE_lossy_etc_decode + // | Internal format |W |H |D |BS |CC| SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend + AddCompressedFormat(&map, GL_ETC1_RGB8_LOSSY_DECODE_ANGLE, 4, 4, 1, 64, 3, false, RequireExt<&Extensions::lossyEtcDecodeANGLE>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE, 4, 4, 1, 64, 3, false, RequireExt<&Extensions::lossyEtcDecodeANGLE>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE, 4, 4, 1, 64, 3, true, RequireExt<&Extensions::lossyEtcDecodeANGLE>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE, 4, 4, 1, 64, 3, false, RequireExt<&Extensions::lossyEtcDecodeANGLE>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE, 4, 4, 1, 64, 3, true, RequireExt<&Extensions::lossyEtcDecodeANGLE>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + + // From GL_EXT_texture_norm16 + // | Internal format |sized| R | G | B | A |S | Format | Type | Component type | SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend + AddRGBAFormat(&map, GL_R16_EXT, true, 16, 0, 0, 0, 0, GL_RED, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16EXT>, AlwaysSupported, RequireExt<&Extensions::textureNorm16EXT>, RequireExt<&Extensions::textureNorm16EXT>, RequireExt<&Extensions::textureNorm16EXT>); + AddRGBAFormat(&map, GL_R16_SNORM_EXT, true, 16, 0, 0, 0, 0, GL_RED, GL_SHORT, GL_SIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16EXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RG16_EXT, true, 16, 16, 0, 0, 0, GL_RG, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16EXT>, AlwaysSupported, RequireExt<&Extensions::textureNorm16EXT>, RequireExt<&Extensions::textureNorm16EXT>, RequireExt<&Extensions::textureNorm16EXT>); + AddRGBAFormat(&map, GL_RG16_SNORM_EXT, true, 16, 16, 0, 0, 0, GL_RG, GL_SHORT, GL_SIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16EXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB16_EXT, true, 16, 16, 16, 0, 0, GL_RGB, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16EXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB16_SNORM_EXT, true, 16, 16, 16, 0, 0, GL_RGB, GL_SHORT, GL_SIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16EXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGBA16_EXT, true, 16, 16, 16, 16, 0, GL_RGBA, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16EXT>, AlwaysSupported, RequireExt<&Extensions::textureNorm16EXT>, RequireExt<&Extensions::textureNorm16EXT>, RequireExt<&Extensions::textureNorm16EXT>); + AddRGBAFormat(&map, GL_RGBA16_SNORM_EXT, true, 16, 16, 16, 16, 0, GL_RGBA, GL_SHORT, GL_SIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16EXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + + // From EXT_texture_sRGB_R8 + // | Internal format |sized| R | G | B | A |S | Format | Type | Component type | SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend + AddRGBAFormat(&map, GL_SR8_EXT, true, 8, 0, 0, 0, 0, GL_RED, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireExt<&Extensions::textureSRGBR8EXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + + // From EXT_texture_sRGB_RG8 + // | Internal format |sized| R | G | B | A |S | Format | Type | Component type | SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend + AddRGBAFormat(&map, GL_SRG8_EXT, true, 8, 8, 0, 0, 0, GL_RG, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireExt<&Extensions::textureSRGBRG8EXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + + // From GL_EXT_texture_type_2_10_10_10_REV + // GL_RGB10_UNORM_ANGLEX is never used directly but needs to be in the list of all sized internal formats so that the backends can determine support. + // | Internal format |sized| R | G | B | A |S |X | Format | Type | Component type | SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend + AddRGBAXFormat(&map, GL_RGB10_UNORM_ANGLEX, true, FB<10, 10, 10, 0, 0, 2>(), GL_RGB, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_NORMALIZED, false, NeverSupported, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + + // Unsized formats + // | Internal format |sized | R | G | B | A |S |X | Format | Type | Component type | SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend + AddRGBAXFormat(&map, GL_RED, false, FB< 8, 0, 0, 0, 0, 0>(), GL_RED, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureRgEXT>, AlwaysSupported, RequireExt<&Extensions::textureRgEXT>, NeverSupported, NeverSupported); + AddRGBAXFormat(&map, GL_RED, false, FB< 8, 0, 0, 0, 0, 0>(), GL_RED, GL_BYTE, GL_SIGNED_NORMALIZED, false, NeverSupported, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAXFormat(&map, GL_RED, false, FB<16, 0, 0, 0, 0, 0>(), GL_RED, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16EXT>, AlwaysSupported, RequireExt<&Extensions::textureNorm16EXT>, NeverSupported, NeverSupported); + AddRGBAXFormat(&map, GL_RG, false, FB< 8, 8, 0, 0, 0, 0>(), GL_RG, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureRgEXT>, AlwaysSupported, RequireExt<&Extensions::textureRgEXT>, NeverSupported, NeverSupported); + AddRGBAXFormat(&map, GL_RG, false, FB< 8, 8, 0, 0, 0, 0>(), GL_RG, GL_BYTE, GL_SIGNED_NORMALIZED, false, NeverSupported, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAXFormat(&map, GL_RG, false, FB<16, 16, 0, 0, 0, 0>(), GL_RG, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16EXT>, AlwaysSupported, RequireExt<&Extensions::textureNorm16EXT>, NeverSupported, NeverSupported); + AddRGBAXFormat(&map, GL_RGB, false, FB< 8, 8, 8, 0, 0, 0>(), GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, RequireESOrExt<2, 0, &Extensions::framebufferObjectOES>, NeverSupported, NeverSupported); + AddRGBAXFormat(&map, GL_RGB, false, FB< 5, 6, 5, 0, 0, 0>(), GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, RequireESOrExt<2, 0, &Extensions::framebufferObjectOES>, NeverSupported, NeverSupported); + AddRGBAXFormat(&map, GL_RGB, false, FB< 8, 8, 8, 0, 0, 0>(), GL_RGB, GL_BYTE, GL_SIGNED_NORMALIZED, false, NeverSupported, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAXFormat(&map, GL_RGB, false, FB<10, 10, 10, 0, 0, 2>(), GL_RGB, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureType2101010REVEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAXFormat(&map, GL_RGBA, false, FB< 4, 4, 4, 4, 0, 0>(), GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, RequireESOrExt<2, 0, &Extensions::framebufferObjectOES>, NeverSupported, NeverSupported); + AddRGBAXFormat(&map, GL_RGBA, false, FB< 5, 5, 5, 1, 0, 0>(), GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, RequireESOrExt<2, 0, &Extensions::framebufferObjectOES>, NeverSupported, NeverSupported); + AddRGBAXFormat(&map, GL_RGBA, false, FB< 8, 8, 8, 8, 0, 0>(), GL_RGBA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, RequireESOrExt<2, 0, &Extensions::framebufferObjectOES>, NeverSupported, NeverSupported); + AddRGBAXFormat(&map, GL_RGBA, false, FB<16, 16, 16, 16, 0, 0>(), GL_RGBA, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16EXT>, AlwaysSupported, RequireExt<&Extensions::textureNorm16EXT>, NeverSupported, NeverSupported); + AddRGBAXFormat(&map, GL_RGBA, false, FB<10, 10, 10, 2, 0, 0>(), GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureType2101010REVEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAXFormat(&map, GL_RGBA, false, FB< 8, 8, 8, 8, 0, 0>(), GL_RGBA, GL_BYTE, GL_SIGNED_NORMALIZED, false, NeverSupported, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAXFormat(&map, GL_SRGB, false, FB< 8, 8, 8, 0, 0, 0>(), GL_SRGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireExt<&Extensions::sRGBEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAXFormat(&map, GL_SRGB_ALPHA_EXT, false, FB< 8, 8, 8, 8, 0, 0>(), GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireExt<&Extensions::sRGBEXT>, AlwaysSupported, RequireExt<&Extensions::sRGBEXT>, NeverSupported, NeverSupported); +#if (defined(ANGLE_PLATFORM_IOS) && !defined(ANGLE_PLATFORM_MACCATALYST)) || (defined(ANGLE_PLATFORM_MACCATALYST) && defined(ANGLE_CPU_ARM64)) + angle::SystemInfo info; + if (angle::GetSystemInfo(&info)) + { + if (info.needsEAGLOnMac) + { + // Using OpenGLES.framework. + AddRGBAFormat(&map, GL_BGRA_EXT, false, 8, 8, 8, 8, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireES<2, 0>, AlwaysSupported, RequireES<2, 0>, NeverSupported, NeverSupported); + } + else + { + // Using OpenGL.framework. + AddRGBAFormat(&map, GL_BGRA_EXT, false, 8, 8, 8, 8, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888EXT>, AlwaysSupported, RequireExt<&Extensions::textureFormatBGRA8888EXT>, NeverSupported, NeverSupported); + } + } +#else + AddRGBAFormat(&map, GL_BGRA_EXT, false, 8, 8, 8, 8, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888EXT>, AlwaysSupported, RequireExt<&Extensions::textureFormatBGRA8888EXT>, NeverSupported, NeverSupported); +#endif + + // Unsized integer formats + // |Internal format |sized | R | G | B | A |S | Format | Type | Component type | SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend + AddRGBAFormat(&map, GL_RED_INTEGER, false, 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_BYTE, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RED_INTEGER, false, 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RED_INTEGER, false, 16, 0, 0, 0, 0, GL_RED_INTEGER, GL_SHORT, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RED_INTEGER, false, 16, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RED_INTEGER, false, 32, 0, 0, 0, 0, GL_RED_INTEGER, GL_INT, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RED_INTEGER, false, 32, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RG_INTEGER, false, 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_BYTE, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RG_INTEGER, false, 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RG_INTEGER, false, 16, 16, 0, 0, 0, GL_RG_INTEGER, GL_SHORT, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RG_INTEGER, false, 16, 16, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RG_INTEGER, false, 32, 32, 0, 0, 0, GL_RG_INTEGER, GL_INT, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RG_INTEGER, false, 32, 32, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB_INTEGER, false, 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_BYTE, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB_INTEGER, false, 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB_INTEGER, false, 16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_SHORT, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB_INTEGER, false, 16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB_INTEGER, false, 32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_INT, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB_INTEGER, false, 32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGBA_INTEGER, false, 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_BYTE, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGBA_INTEGER, false, 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGBA_INTEGER, false, 16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_SHORT, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGBA_INTEGER, false, 16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGBA_INTEGER, false, 32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_INT, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGBA_INTEGER, false, 32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGBA_INTEGER, false, 10, 10, 10, 2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + + // Unsized floating point formats + // |Internal format |sized | R | G | B | A |S | Format | Type | Comp | SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend + AddRGBAFormat(&map, GL_RED, false, 16, 0, 0, 0, 0, GL_RED, GL_HALF_FLOAT, GL_FLOAT, false, NeverSupported, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RG, false, 16, 16, 0, 0, 0, GL_RG, GL_HALF_FLOAT, GL_FLOAT, false, NeverSupported, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB, false, 16, 16, 16, 0, 0, GL_RGB, GL_HALF_FLOAT, GL_FLOAT, false, NeverSupported, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGBA, false, 16, 16, 16, 16, 0, GL_RGBA, GL_HALF_FLOAT, GL_FLOAT, false, NeverSupported, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RED, false, 16, 0, 0, 0, 0, GL_RED, GL_HALF_FLOAT_OES, GL_FLOAT, false, RequireExtAndExt<&Extensions::textureHalfFloatOES, &Extensions::textureRgEXT>, RequireExt<&Extensions::textureHalfFloatLinearOES>, AlwaysSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RG, false, 16, 16, 0, 0, 0, GL_RG, GL_HALF_FLOAT_OES, GL_FLOAT, false, RequireExtAndExt<&Extensions::textureHalfFloatOES, &Extensions::textureRgEXT>, RequireExt<&Extensions::textureHalfFloatLinearOES>, AlwaysSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB, false, 16, 16, 16, 0, 0, GL_RGB, GL_HALF_FLOAT_OES, GL_FLOAT, false, RequireExt<&Extensions::textureHalfFloatOES>, RequireExt<&Extensions::textureHalfFloatLinearOES>, RequireExt<&Extensions::colorBufferHalfFloatEXT>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGBA, false, 16, 16, 16, 16, 0, GL_RGBA, GL_HALF_FLOAT_OES, GL_FLOAT, false, RequireExt<&Extensions::textureHalfFloatOES>, RequireExt<&Extensions::textureHalfFloatLinearOES>, RequireExt<&Extensions::colorBufferHalfFloatEXT>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RED, false, 32, 0, 0, 0, 0, GL_RED, GL_FLOAT, GL_FLOAT, false, RequireExtAndExt<&Extensions::textureFloatOES, &Extensions::textureRgEXT>, RequireExt<&Extensions::textureFloatLinearOES>, AlwaysSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RG, false, 32, 32, 0, 0, 0, GL_RG, GL_FLOAT, GL_FLOAT, false, RequireExtAndExt<&Extensions::textureFloatOES, &Extensions::textureRgEXT>, RequireExt<&Extensions::textureFloatLinearOES>, AlwaysSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB, false, 32, 32, 32, 0, 0, GL_RGB, GL_FLOAT, GL_FLOAT, false, RequireExt<&Extensions::textureFloatOES>, RequireExt<&Extensions::textureFloatLinearOES>, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB, false, 9, 9, 9, 0, 5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT, false, NeverSupported, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB, false, 11, 11, 10, 0, 0, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_FLOAT, false, NeverSupported, NeverSupported, NeverSupported, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGBA, false, 32, 32, 32, 32, 0, GL_RGBA, GL_FLOAT, GL_FLOAT, false, RequireExt<&Extensions::textureFloatOES>, RequireExt<&Extensions::textureFloatLinearOES>, NeverSupported, NeverSupported, NeverSupported); + + // Unsized luminance alpha formats + // | Internal format |sized | L | A | Format | Type | Component type | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend + AddLUMAFormat(&map, GL_ALPHA, false, 0, 8, GL_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, AlwaysSupported, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddLUMAFormat(&map, GL_LUMINANCE, false, 8, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, AlwaysSupported, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddLUMAFormat(&map, GL_LUMINANCE_ALPHA, false, 8, 8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, AlwaysSupported, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported); + AddLUMAFormat(&map, GL_ALPHA, false, 0, 16, GL_ALPHA, GL_HALF_FLOAT_OES, GL_FLOAT, RequireExt<&Extensions::textureHalfFloatOES>, RequireExt<&Extensions::textureHalfFloatLinearOES>, NeverSupported, NeverSupported, NeverSupported); + AddLUMAFormat(&map, GL_LUMINANCE, false, 16, 0, GL_LUMINANCE, GL_HALF_FLOAT_OES, GL_FLOAT, RequireExt<&Extensions::textureHalfFloatOES>, RequireExt<&Extensions::textureHalfFloatLinearOES>, NeverSupported, NeverSupported, NeverSupported); + AddLUMAFormat(&map, GL_LUMINANCE_ALPHA, false, 16, 16, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, GL_FLOAT, RequireExt<&Extensions::textureHalfFloatOES>, RequireExt<&Extensions::textureHalfFloatLinearOES>, NeverSupported, NeverSupported, NeverSupported); + AddLUMAFormat(&map, GL_ALPHA, false, 0, 32, GL_ALPHA, GL_FLOAT, GL_FLOAT, RequireExt<&Extensions::textureFloatOES>, RequireExt<&Extensions::textureFloatLinearOES>, NeverSupported, NeverSupported, NeverSupported); + AddLUMAFormat(&map, GL_LUMINANCE, false, 32, 0, GL_LUMINANCE, GL_FLOAT, GL_FLOAT, RequireExt<&Extensions::textureFloatOES>, RequireExt<&Extensions::textureFloatLinearOES>, NeverSupported, NeverSupported, NeverSupported); + AddLUMAFormat(&map, GL_LUMINANCE_ALPHA, false, 32, 32, GL_LUMINANCE_ALPHA, GL_FLOAT, GL_FLOAT, RequireExt<&Extensions::textureFloatOES>, RequireExt<&Extensions::textureFloatLinearOES>, NeverSupported, NeverSupported, NeverSupported); + + // Unsized depth stencil formats + // | Internal format |sized | D |S | X | Format | Type | Component type | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend + AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT, false, 16, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, RequireES<1, 0>, AlwaysSupported, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>); + AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT, false, 24, 0, 8, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireES<1, 0>, AlwaysSupported, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>); + AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT, false, 32, 0, 0, GL_DEPTH_COMPONENT, GL_FLOAT, GL_FLOAT, RequireES<1, 0>, AlwaysSupported, RequireES<1, 0>, RequireES<1, 0>, RequireES<1, 0>); + AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT, false, 24, 8, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_NORMALIZED, RequireESOrExt<3, 0, &Extensions::packedDepthStencilOES>, AlwaysSupported, RequireExtAndExt<&Extensions::packedDepthStencilOES, &Extensions::depthTextureANGLE>, RequireExtAndExt<&Extensions::packedDepthStencilOES, &Extensions::depthTextureANGLE>, RequireExtAndExt<&Extensions::packedDepthStencilOES, &Extensions::depthTextureANGLE>); + AddDepthStencilFormat(&map, GL_DEPTH_STENCIL, false, 24, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_NORMALIZED, RequireESOrExt<3, 0, &Extensions::packedDepthStencilOES>, AlwaysSupported, RequireExtAndExt<&Extensions::packedDepthStencilOES, &Extensions::depthTextureANGLE>, RequireExtAndExt<&Extensions::packedDepthStencilOES, &Extensions::depthTextureANGLE>, RequireExtAndExt<&Extensions::packedDepthStencilOES, &Extensions::depthTextureANGLE>); + AddDepthStencilFormat(&map, GL_DEPTH_STENCIL, false, 32, 8, 24, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_FLOAT, RequireESOrExt<3, 0, &Extensions::packedDepthStencilOES>, AlwaysSupported, RequireExt<&Extensions::packedDepthStencilOES>, RequireExt<&Extensions::packedDepthStencilOES>, RequireExt<&Extensions::packedDepthStencilOES>); + AddDepthStencilFormat(&map, GL_STENCIL, false, 0, 8, 0, GL_STENCIL, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireES<1, 0>, NeverSupported , RequireES<1, 0>, RequireES<1, 0>, RequireES<1, 0>); + AddDepthStencilFormat(&map, GL_STENCIL_INDEX, false, 0, 8, 0, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireES<3, 1>, NeverSupported , RequireES<3, 1>, RequireES<3, 1>, RequireES<3, 1>); + + // Non-standard YUV formats + // | Internal format | sized | Cr | Y | Cb | A | S | Format | Type | Comp | SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend + AddYUVFormat(&map, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, true, 8, 8, 8, 0, 0, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::yuvInternalFormatANGLE>, RequireExt<&Extensions::yuvInternalFormatANGLE>, RequireExt<&Extensions::yuvInternalFormatANGLE>, NeverSupported, NeverSupported); + AddYUVFormat(&map, GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE, true, 8, 8, 8, 0, 0, GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::yuvInternalFormatANGLE>, RequireExt<&Extensions::yuvInternalFormatANGLE>, RequireExt<&Extensions::yuvInternalFormatANGLE>, NeverSupported, NeverSupported); + +#if defined(ANGLE_PLATFORM_LINUX) + // From GL_OES_required_internalformat + // The |shared| bit shouldn't be 2. But given this hits assertion when bits + // are checked, it's fine to have this bit set as 2 as a workaround. + AddRGBAFormat(&map, GL_RGB10_EXT, true, 10, 10, 10, 0, 2, GL_RGB, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_NORMALIZED, false, RequireES<1, 0>, NeverSupported, RequireES<1, 0>, RequireES<1, 0>, NeverSupported); +#endif + // clang-format on + + return map; +} + +const InternalFormatInfoMap &GetInternalFormatMap() +{ + static const angle::base::NoDestructor formatMap( + BuildInternalFormatInfoMap()); + return *formatMap; +} + +int GetAndroidHardwareBufferFormatFromChannelSizes(const egl::AttributeMap &attribMap) +{ + // Retrieve channel size from attribute map. The default value should be 0, per spec. + GLuint redSize = static_cast(attribMap.getAsInt(EGL_RED_SIZE, 0)); + GLuint greenSize = static_cast(attribMap.getAsInt(EGL_GREEN_SIZE, 0)); + GLuint blueSize = static_cast(attribMap.getAsInt(EGL_BLUE_SIZE, 0)); + GLuint alphaSize = static_cast(attribMap.getAsInt(EGL_ALPHA_SIZE, 0)); + + GLenum glInternalFormat = 0; + for (GLenum sizedInternalFormat : angle::android::kSupportedSizedInternalFormats) + { + const gl::InternalFormat &internalFormat = GetSizedInternalFormatInfo(sizedInternalFormat); + ASSERT(internalFormat.internalFormat != GL_NONE && internalFormat.sized); + + if (internalFormat.isChannelSizeCompatible(redSize, greenSize, blueSize, alphaSize)) + { + glInternalFormat = sizedInternalFormat; + break; + } + } + + return (glInternalFormat != 0) + ? angle::android::GLInternalFormatToNativePixelFormat(glInternalFormat) + : 0; +} + +GLenum GetConfigColorBufferFormat(const egl::Config *config) +{ + GLenum componentType = GL_NONE; + switch (config->colorComponentType) + { + case EGL_COLOR_COMPONENT_TYPE_FIXED_EXT: + componentType = GL_UNSIGNED_NORMALIZED; + break; + case EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT: + componentType = GL_FLOAT; + break; + default: + UNREACHABLE(); + return GL_NONE; + } + + GLenum colorEncoding = GL_LINEAR; + + for (GLenum sizedInternalFormat : GetAllSizedInternalFormats()) + { + const gl::InternalFormat &internalFormat = GetSizedInternalFormatInfo(sizedInternalFormat); + + if (internalFormat.componentType == componentType && + internalFormat.colorEncoding == colorEncoding && + internalFormat.isChannelSizeCompatible(config->redSize, config->greenSize, + config->blueSize, config->alphaSize)) + { + return sizedInternalFormat; + } + } + + // Only expect to get here if there is no color bits in the config + ASSERT(config->redSize == 0 && config->greenSize == 0 && config->blueSize == 0 && + config->alphaSize == 0); + return GL_NONE; +} + +GLenum GetConfigDepthStencilBufferFormat(const egl::Config *config) +{ + GLenum componentType = GL_UNSIGNED_NORMALIZED; + + for (GLenum sizedInternalFormat : GetAllSizedInternalFormats()) + { + const gl::InternalFormat &internalFormat = GetSizedInternalFormatInfo(sizedInternalFormat); + + if (internalFormat.componentType == componentType && + static_cast(internalFormat.depthBits) == config->depthSize && + static_cast(internalFormat.stencilBits) == config->stencilSize) + { + return sizedInternalFormat; + } + } + + // Only expect to get here if there is no depth or stencil bits in the config + ASSERT(config->depthSize == 0 && config->stencilSize == 0); + return GL_NONE; +} + +static FormatSet BuildAllSizedInternalFormatSet() +{ + FormatSet result; + + for (const auto &internalFormat : GetInternalFormatMap()) + { + for (const auto &type : internalFormat.second) + { + if (type.second.sized) + { + // TODO(jmadill): Fix this hack. + if (internalFormat.first == GL_BGR565_ANGLEX) + continue; + + result.insert(internalFormat.first); + } + } + } + + return result; +} + +uint32_t GetPackedTypeInfo(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + case GL_BYTE: + { + static constexpr uint32_t kPacked = PackTypeInfo(1, false); + return kPacked; + } + case GL_UNSIGNED_SHORT: + case GL_SHORT: + case GL_HALF_FLOAT: + case GL_HALF_FLOAT_OES: + { + static constexpr uint32_t kPacked = PackTypeInfo(2, false); + return kPacked; + } + case GL_UNSIGNED_INT: + case GL_INT: + case GL_FLOAT: + { + static constexpr uint32_t kPacked = PackTypeInfo(4, false); + return kPacked; + } + case GL_UNSIGNED_SHORT_5_6_5: + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: + case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: + { + static constexpr uint32_t kPacked = PackTypeInfo(2, true); + return kPacked; + } + case GL_UNSIGNED_INT_2_10_10_10_REV: + case GL_UNSIGNED_INT_24_8: + case GL_UNSIGNED_INT_10F_11F_11F_REV: + case GL_UNSIGNED_INT_5_9_9_9_REV: + { + ASSERT(GL_UNSIGNED_INT_24_8_OES == GL_UNSIGNED_INT_24_8); + static constexpr uint32_t kPacked = PackTypeInfo(4, true); + return kPacked; + } + case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: + { + static constexpr uint32_t kPacked = PackTypeInfo(8, true); + return kPacked; + } + default: + { + return 0; + } + } +} + +const InternalFormat &GetSizedInternalFormatInfo(GLenum internalFormat) +{ + static const InternalFormat defaultInternalFormat; + const InternalFormatInfoMap &formatMap = GetInternalFormatMap(); + auto iter = formatMap.find(internalFormat); + + // Sized internal formats only have one type per entry + if (iter == formatMap.end() || iter->second.size() != 1) + { + return defaultInternalFormat; + } + + const InternalFormat &internalFormatInfo = iter->second.begin()->second; + if (!internalFormatInfo.sized) + { + return defaultInternalFormat; + } + + return internalFormatInfo; +} + +const InternalFormat &GetInternalFormatInfo(GLenum internalFormat, GLenum type) +{ + static const InternalFormat defaultInternalFormat; + const InternalFormatInfoMap &formatMap = GetInternalFormatMap(); + + auto internalFormatIter = formatMap.find(internalFormat); + if (internalFormatIter == formatMap.end()) + { + return defaultInternalFormat; + } + + // If the internal format is sized, simply return it without the type check. + if (internalFormatIter->second.size() == 1 && internalFormatIter->second.begin()->second.sized) + { + return internalFormatIter->second.begin()->second; + } + + auto typeIter = internalFormatIter->second.find(type); + if (typeIter == internalFormatIter->second.end()) + { + return defaultInternalFormat; + } + + return typeIter->second; +} + +GLuint InternalFormat::computePixelBytes(GLenum formatType) const +{ + const auto &typeInfo = GetTypeInfo(formatType); + GLuint components = typeInfo.specialInterpretation ? 1u : componentCount; + return components * typeInfo.bytes; +} + +bool InternalFormat::computeBufferRowLength(uint32_t width, uint32_t *resultOut) const +{ + CheckedNumeric checkedWidth(width); + + if (compressed) + { + angle::CheckedNumeric checkedRowLength = + rx::CheckedRoundUp(width, compressedBlockWidth); + + return CheckedMathResult(checkedRowLength, resultOut); + } + + return CheckedMathResult(checkedWidth, resultOut); +} + +bool InternalFormat::computeBufferImageHeight(uint32_t height, uint32_t *resultOut) const +{ + CheckedNumeric checkedHeight(height); + + if (compressed) + { + angle::CheckedNumeric checkedImageHeight = + rx::CheckedRoundUp(height, compressedBlockHeight); + + return CheckedMathResult(checkedImageHeight, resultOut); + } + + return CheckedMathResult(checkedHeight, resultOut); +} + +bool InternalFormat::computePalettedImageRowPitch(GLsizei width, GLuint *resultOut) const +{ + ASSERT(paletted); + switch (paletteBits) + { + case 4: + *resultOut = (width + 1) / 2; + return true; + case 8: + *resultOut = width; + return true; + default: + UNREACHABLE(); + return false; + } +} + +bool InternalFormat::computeRowPitch(GLenum formatType, + GLsizei width, + GLint alignment, + GLint rowLength, + GLuint *resultOut) const +{ + if (paletted) + { + return computePalettedImageRowPitch(width, resultOut); + } + + // Compressed images do not use pack/unpack parameters (rowLength). + if (compressed) + { + return computeCompressedImageSize(Extents(width, 1, 1), resultOut); + } + + CheckedNumeric checkedWidth(rowLength > 0 ? rowLength : width); + CheckedNumeric checkedRowBytes = checkedWidth * computePixelBytes(formatType); + + ASSERT(alignment > 0 && isPow2(alignment)); + CheckedNumeric checkedAlignment(alignment); + auto aligned = rx::roundUp(checkedRowBytes, checkedAlignment); + return CheckedMathResult(aligned, resultOut); +} + +bool InternalFormat::computeDepthPitch(GLsizei height, + GLint imageHeight, + GLuint rowPitch, + GLuint *resultOut) const +{ + // Compressed images do not use pack/unpack parameters (imageHeight). + CheckedNumeric pixelsHeight(!compressed && (imageHeight > 0) + ? static_cast(imageHeight) + : static_cast(height)); + + CheckedNumeric rowCount; + if (compressed) + { + CheckedNumeric checkedBlockHeight(compressedBlockHeight); + rowCount = (pixelsHeight + checkedBlockHeight - 1u) / checkedBlockHeight; + } + else + { + rowCount = pixelsHeight; + } + + CheckedNumeric checkedRowPitch(rowPitch); + + return CheckedMathResult(checkedRowPitch * rowCount, resultOut); +} + +bool InternalFormat::computeDepthPitch(GLenum formatType, + GLsizei width, + GLsizei height, + GLint alignment, + GLint rowLength, + GLint imageHeight, + GLuint *resultOut) const +{ + GLuint rowPitch = 0; + if (!computeRowPitch(formatType, width, alignment, rowLength, &rowPitch)) + { + return false; + } + return computeDepthPitch(height, imageHeight, rowPitch, resultOut); +} + +bool InternalFormat::computeCompressedImageSize(const Extents &size, GLuint *resultOut) const +{ + CheckedNumeric checkedWidth(size.width); + CheckedNumeric checkedHeight(size.height); + CheckedNumeric checkedDepth(size.depth); + + if (paletted) + { + ASSERT(!compressed); + + GLuint paletteSize = 1 << paletteBits; + GLuint paletteBytes = paletteSize * pixelBytes; + + GLuint rowPitch; + if (!computePalettedImageRowPitch(size.width, &rowPitch)) + { + return false; + } + + if (size.depth != 1) + { + return false; + } + + CheckedNumeric checkedPaletteBytes(paletteBytes); + CheckedNumeric checkedRowPitch(rowPitch); + + return CheckedMathResult(checkedPaletteBytes + checkedRowPitch * checkedHeight, resultOut); + } + + CheckedNumeric checkedBlockWidth(compressedBlockWidth); + CheckedNumeric checkedBlockHeight(compressedBlockHeight); + GLuint minBlockWidth, minBlockHeight; + std::tie(minBlockWidth, minBlockHeight) = getCompressedImageMinBlocks(); + + ASSERT(compressed); + auto numBlocksWide = (checkedWidth + checkedBlockWidth - 1u) / checkedBlockWidth; + auto numBlocksHigh = (checkedHeight + checkedBlockHeight - 1u) / checkedBlockHeight; + if (numBlocksWide.IsValid() && numBlocksWide.ValueOrDie() < minBlockWidth) + numBlocksWide = minBlockWidth; + if (numBlocksHigh.IsValid() && numBlocksHigh.ValueOrDie() < minBlockHeight) + numBlocksHigh = minBlockHeight; + auto bytes = numBlocksWide * numBlocksHigh * pixelBytes * checkedDepth; + return CheckedMathResult(bytes, resultOut); +} + +std::pair InternalFormat::getCompressedImageMinBlocks() const +{ + GLuint minBlockWidth = 0; + GLuint minBlockHeight = 0; + + // Per the specification, a PVRTC block needs information from the 3 nearest blocks. + // GL_IMG_texture_compression_pvrtc specifies the minimum size requirement in pixels, but + // ANGLE's texture tables are written in terms of blocks. The 4BPP formats use 4x4 blocks, and + // the 2BPP formats, 8x4 blocks. Therefore, both kinds of formats require a minimum of 2x2 + // blocks. + switch (internalFormat) + { + case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG: + case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG: + case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: + case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: + case GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT: + case GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT: + minBlockWidth = 2; + minBlockHeight = 2; + break; + + default: + break; + } + + return std::make_pair(minBlockWidth, minBlockHeight); +} + +bool InternalFormat::computeSkipBytes(GLenum formatType, + GLuint rowPitch, + GLuint depthPitch, + const PixelStoreStateBase &state, + bool is3D, + GLuint *resultOut) const +{ + CheckedNumeric checkedRowPitch(rowPitch); + CheckedNumeric checkedDepthPitch(depthPitch); + CheckedNumeric checkedSkipImages(static_cast(state.skipImages)); + CheckedNumeric checkedSkipRows(static_cast(state.skipRows)); + CheckedNumeric checkedSkipPixels(static_cast(state.skipPixels)); + CheckedNumeric checkedPixelBytes(computePixelBytes(formatType)); + auto checkedSkipImagesBytes = checkedSkipImages * checkedDepthPitch; + if (!is3D) + { + checkedSkipImagesBytes = 0; + } + auto skipBytes = checkedSkipImagesBytes + checkedSkipRows * checkedRowPitch + + checkedSkipPixels * checkedPixelBytes; + return CheckedMathResult(skipBytes, resultOut); +} + +bool InternalFormat::computePackUnpackEndByte(GLenum formatType, + const Extents &size, + const PixelStoreStateBase &state, + bool is3D, + GLuint *resultOut) const +{ + GLuint rowPitch = 0; + if (!computeRowPitch(formatType, size.width, state.alignment, state.rowLength, &rowPitch)) + { + return false; + } + + GLuint depthPitch = 0; + if (is3D && !computeDepthPitch(size.height, state.imageHeight, rowPitch, &depthPitch)) + { + return false; + } + + CheckedNumeric checkedCopyBytes(0); + if (compressed) + { + GLuint copyBytes = 0; + if (!computeCompressedImageSize(size, ©Bytes)) + { + return false; + } + checkedCopyBytes = copyBytes; + } + else if (size.height != 0 && (!is3D || size.depth != 0)) + { + CheckedNumeric bytes = computePixelBytes(formatType); + checkedCopyBytes += size.width * bytes; + + CheckedNumeric heightMinusOne = size.height - 1; + checkedCopyBytes += heightMinusOne * rowPitch; + + if (is3D) + { + CheckedNumeric depthMinusOne = size.depth - 1; + checkedCopyBytes += depthMinusOne * depthPitch; + } + } + + GLuint skipBytes = 0; + if (!computeSkipBytes(formatType, rowPitch, depthPitch, state, is3D, &skipBytes)) + { + return false; + } + + CheckedNumeric endByte = checkedCopyBytes + CheckedNumeric(skipBytes); + + return CheckedMathResult(endByte, resultOut); +} + +GLenum GetUnsizedFormat(GLenum internalFormat) +{ + auto sizedFormatInfo = GetSizedInternalFormatInfo(internalFormat); + if (sizedFormatInfo.internalFormat != GL_NONE) + { + return sizedFormatInfo.format; + } + + return internalFormat; +} + +bool CompressedFormatRequiresWholeImage(GLenum internalFormat) +{ + // List of compressed texture format that require that the sub-image size is equal to texture's + // respective mip level's size + return IsPVRTC1Format(internalFormat); +} + +void MaybeOverrideLuminance(GLenum &format, GLenum &type, GLenum actualFormat, GLenum actualType) +{ + gl::InternalFormat internalFormat = gl::GetInternalFormatInfo(format, type); + if (internalFormat.isLUMA()) + { + // Ensure the format and type are compatible + ASSERT(internalFormat.pixelBytes == + gl::GetInternalFormatInfo(actualFormat, actualType).pixelBytes); + + // For Luminance formats, override with the internal format. Since this is not + // renderable, our pixel pack routines don't handle it correctly. + format = actualFormat; + type = actualType; + } +} + +const FormatSet &GetAllSizedInternalFormats() +{ + static angle::base::NoDestructor formatSet(BuildAllSizedInternalFormatSet()); + return *formatSet; +} + +AttributeType GetAttributeType(GLenum enumValue) +{ + switch (enumValue) + { + case GL_FLOAT: + return ATTRIBUTE_FLOAT; + case GL_FLOAT_VEC2: + return ATTRIBUTE_VEC2; + case GL_FLOAT_VEC3: + return ATTRIBUTE_VEC3; + case GL_FLOAT_VEC4: + return ATTRIBUTE_VEC4; + case GL_INT: + return ATTRIBUTE_INT; + case GL_INT_VEC2: + return ATTRIBUTE_IVEC2; + case GL_INT_VEC3: + return ATTRIBUTE_IVEC3; + case GL_INT_VEC4: + return ATTRIBUTE_IVEC4; + case GL_UNSIGNED_INT: + return ATTRIBUTE_UINT; + case GL_UNSIGNED_INT_VEC2: + return ATTRIBUTE_UVEC2; + case GL_UNSIGNED_INT_VEC3: + return ATTRIBUTE_UVEC3; + case GL_UNSIGNED_INT_VEC4: + return ATTRIBUTE_UVEC4; + case GL_FLOAT_MAT2: + return ATTRIBUTE_MAT2; + case GL_FLOAT_MAT3: + return ATTRIBUTE_MAT3; + case GL_FLOAT_MAT4: + return ATTRIBUTE_MAT4; + case GL_FLOAT_MAT2x3: + return ATTRIBUTE_MAT2x3; + case GL_FLOAT_MAT2x4: + return ATTRIBUTE_MAT2x4; + case GL_FLOAT_MAT3x2: + return ATTRIBUTE_MAT3x2; + case GL_FLOAT_MAT3x4: + return ATTRIBUTE_MAT3x4; + case GL_FLOAT_MAT4x2: + return ATTRIBUTE_MAT4x2; + case GL_FLOAT_MAT4x3: + return ATTRIBUTE_MAT4x3; + default: + UNREACHABLE(); + return ATTRIBUTE_FLOAT; + } +} + +angle::FormatID GetVertexFormatID(VertexAttribType type, + GLboolean normalized, + GLuint components, + bool pureInteger) +{ + switch (type) + { + case VertexAttribType::Byte: + switch (components) + { + case 1: + if (pureInteger) + return angle::FormatID::R8_SINT; + if (normalized) + return angle::FormatID::R8_SNORM; + return angle::FormatID::R8_SSCALED; + case 2: + if (pureInteger) + return angle::FormatID::R8G8_SINT; + if (normalized) + return angle::FormatID::R8G8_SNORM; + return angle::FormatID::R8G8_SSCALED; + case 3: + if (pureInteger) + return angle::FormatID::R8G8B8_SINT; + if (normalized) + return angle::FormatID::R8G8B8_SNORM; + return angle::FormatID::R8G8B8_SSCALED; + case 4: + if (pureInteger) + return angle::FormatID::R8G8B8A8_SINT; + if (normalized) + return angle::FormatID::R8G8B8A8_SNORM; + return angle::FormatID::R8G8B8A8_SSCALED; + default: + UNREACHABLE(); + return angle::FormatID::NONE; + } + case VertexAttribType::UnsignedByte: + switch (components) + { + case 1: + if (pureInteger) + return angle::FormatID::R8_UINT; + if (normalized) + return angle::FormatID::R8_UNORM; + return angle::FormatID::R8_USCALED; + case 2: + if (pureInteger) + return angle::FormatID::R8G8_UINT; + if (normalized) + return angle::FormatID::R8G8_UNORM; + return angle::FormatID::R8G8_USCALED; + case 3: + if (pureInteger) + return angle::FormatID::R8G8B8_UINT; + if (normalized) + return angle::FormatID::R8G8B8_UNORM; + return angle::FormatID::R8G8B8_USCALED; + case 4: + if (pureInteger) + return angle::FormatID::R8G8B8A8_UINT; + if (normalized) + return angle::FormatID::R8G8B8A8_UNORM; + return angle::FormatID::R8G8B8A8_USCALED; + default: + UNREACHABLE(); + return angle::FormatID::NONE; + } + case VertexAttribType::Short: + switch (components) + { + case 1: + if (pureInteger) + return angle::FormatID::R16_SINT; + if (normalized) + return angle::FormatID::R16_SNORM; + return angle::FormatID::R16_SSCALED; + case 2: + if (pureInteger) + return angle::FormatID::R16G16_SINT; + if (normalized) + return angle::FormatID::R16G16_SNORM; + return angle::FormatID::R16G16_SSCALED; + case 3: + if (pureInteger) + return angle::FormatID::R16G16B16_SINT; + if (normalized) + return angle::FormatID::R16G16B16_SNORM; + return angle::FormatID::R16G16B16_SSCALED; + case 4: + if (pureInteger) + return angle::FormatID::R16G16B16A16_SINT; + if (normalized) + return angle::FormatID::R16G16B16A16_SNORM; + return angle::FormatID::R16G16B16A16_SSCALED; + default: + UNREACHABLE(); + return angle::FormatID::NONE; + } + case VertexAttribType::UnsignedShort: + switch (components) + { + case 1: + if (pureInteger) + return angle::FormatID::R16_UINT; + if (normalized) + return angle::FormatID::R16_UNORM; + return angle::FormatID::R16_USCALED; + case 2: + if (pureInteger) + return angle::FormatID::R16G16_UINT; + if (normalized) + return angle::FormatID::R16G16_UNORM; + return angle::FormatID::R16G16_USCALED; + case 3: + if (pureInteger) + return angle::FormatID::R16G16B16_UINT; + if (normalized) + return angle::FormatID::R16G16B16_UNORM; + return angle::FormatID::R16G16B16_USCALED; + case 4: + if (pureInteger) + return angle::FormatID::R16G16B16A16_UINT; + if (normalized) + return angle::FormatID::R16G16B16A16_UNORM; + return angle::FormatID::R16G16B16A16_USCALED; + default: + UNREACHABLE(); + return angle::FormatID::NONE; + } + case VertexAttribType::Int: + switch (components) + { + case 1: + if (pureInteger) + return angle::FormatID::R32_SINT; + if (normalized) + return angle::FormatID::R32_SNORM; + return angle::FormatID::R32_SSCALED; + case 2: + if (pureInteger) + return angle::FormatID::R32G32_SINT; + if (normalized) + return angle::FormatID::R32G32_SNORM; + return angle::FormatID::R32G32_SSCALED; + case 3: + if (pureInteger) + return angle::FormatID::R32G32B32_SINT; + if (normalized) + return angle::FormatID::R32G32B32_SNORM; + return angle::FormatID::R32G32B32_SSCALED; + case 4: + if (pureInteger) + return angle::FormatID::R32G32B32A32_SINT; + if (normalized) + return angle::FormatID::R32G32B32A32_SNORM; + return angle::FormatID::R32G32B32A32_SSCALED; + default: + UNREACHABLE(); + return angle::FormatID::NONE; + } + case VertexAttribType::UnsignedInt: + switch (components) + { + case 1: + if (pureInteger) + return angle::FormatID::R32_UINT; + if (normalized) + return angle::FormatID::R32_UNORM; + return angle::FormatID::R32_USCALED; + case 2: + if (pureInteger) + return angle::FormatID::R32G32_UINT; + if (normalized) + return angle::FormatID::R32G32_UNORM; + return angle::FormatID::R32G32_USCALED; + case 3: + if (pureInteger) + return angle::FormatID::R32G32B32_UINT; + if (normalized) + return angle::FormatID::R32G32B32_UNORM; + return angle::FormatID::R32G32B32_USCALED; + case 4: + if (pureInteger) + return angle::FormatID::R32G32B32A32_UINT; + if (normalized) + return angle::FormatID::R32G32B32A32_UNORM; + return angle::FormatID::R32G32B32A32_USCALED; + default: + UNREACHABLE(); + return angle::FormatID::NONE; + } + case VertexAttribType::Float: + switch (components) + { + case 1: + return angle::FormatID::R32_FLOAT; + case 2: + return angle::FormatID::R32G32_FLOAT; + case 3: + return angle::FormatID::R32G32B32_FLOAT; + case 4: + return angle::FormatID::R32G32B32A32_FLOAT; + default: + UNREACHABLE(); + return angle::FormatID::NONE; + } + case VertexAttribType::HalfFloat: + case VertexAttribType::HalfFloatOES: + switch (components) + { + case 1: + return angle::FormatID::R16_FLOAT; + case 2: + return angle::FormatID::R16G16_FLOAT; + case 3: + return angle::FormatID::R16G16B16_FLOAT; + case 4: + return angle::FormatID::R16G16B16A16_FLOAT; + default: + UNREACHABLE(); + return angle::FormatID::NONE; + } + case VertexAttribType::Fixed: + switch (components) + { + case 1: + return angle::FormatID::R32_FIXED; + case 2: + return angle::FormatID::R32G32_FIXED; + case 3: + return angle::FormatID::R32G32B32_FIXED; + case 4: + return angle::FormatID::R32G32B32A32_FIXED; + default: + UNREACHABLE(); + return angle::FormatID::NONE; + } + case VertexAttribType::Int2101010: + if (pureInteger) + return angle::FormatID::R10G10B10A2_SINT; + if (normalized) + return angle::FormatID::R10G10B10A2_SNORM; + return angle::FormatID::R10G10B10A2_SSCALED; + case VertexAttribType::UnsignedInt2101010: + if (pureInteger) + return angle::FormatID::R10G10B10A2_UINT; + if (normalized) + return angle::FormatID::R10G10B10A2_UNORM; + return angle::FormatID::R10G10B10A2_USCALED; + case VertexAttribType::Int1010102: + switch (components) + { + case 3: + if (pureInteger) + return angle::FormatID::X2R10G10B10_SINT_VERTEX; + if (normalized) + return angle::FormatID::X2R10G10B10_SNORM_VERTEX; + return angle::FormatID::X2R10G10B10_SSCALED_VERTEX; + case 4: + if (pureInteger) + return angle::FormatID::A2R10G10B10_SINT_VERTEX; + if (normalized) + return angle::FormatID::A2R10G10B10_SNORM_VERTEX; + return angle::FormatID::A2R10G10B10_SSCALED_VERTEX; + default: + UNREACHABLE(); + return angle::FormatID::NONE; + } + case VertexAttribType::UnsignedInt1010102: + switch (components) + { + case 3: + if (pureInteger) + return angle::FormatID::X2R10G10B10_UINT_VERTEX; + if (normalized) + return angle::FormatID::X2R10G10B10_UNORM_VERTEX; + return angle::FormatID::X2R10G10B10_USCALED_VERTEX; + + case 4: + if (pureInteger) + return angle::FormatID::A2R10G10B10_UINT_VERTEX; + if (normalized) + return angle::FormatID::A2R10G10B10_UNORM_VERTEX; + return angle::FormatID::A2R10G10B10_USCALED_VERTEX; + default: + UNREACHABLE(); + return angle::FormatID::NONE; + } + default: + UNREACHABLE(); + return angle::FormatID::NONE; + } +} + +angle::FormatID GetVertexFormatID(const VertexAttribute &attrib, VertexAttribType currentValueType) +{ + if (!attrib.enabled) + { + return GetCurrentValueFormatID(currentValueType); + } + return attrib.format->id; +} + +angle::FormatID GetCurrentValueFormatID(VertexAttribType currentValueType) +{ + switch (currentValueType) + { + case VertexAttribType::Float: + return angle::FormatID::R32G32B32A32_FLOAT; + case VertexAttribType::Int: + return angle::FormatID::R32G32B32A32_SINT; + case VertexAttribType::UnsignedInt: + return angle::FormatID::R32G32B32A32_UINT; + default: + UNREACHABLE(); + return angle::FormatID::NONE; + } +} + +const VertexFormat &GetVertexFormatFromID(angle::FormatID vertexFormatID) +{ + switch (vertexFormatID) + { + case angle::FormatID::R8_SSCALED: + { + static const VertexFormat format(GL_BYTE, GL_FALSE, 1, false); + return format; + } + case angle::FormatID::R8_SNORM: + { + static const VertexFormat format(GL_BYTE, GL_TRUE, 1, false); + return format; + } + case angle::FormatID::R8G8_SSCALED: + { + static const VertexFormat format(GL_BYTE, GL_FALSE, 2, false); + return format; + } + case angle::FormatID::R8G8_SNORM: + { + static const VertexFormat format(GL_BYTE, GL_TRUE, 2, false); + return format; + } + case angle::FormatID::R8G8B8_SSCALED: + { + static const VertexFormat format(GL_BYTE, GL_FALSE, 3, false); + return format; + } + case angle::FormatID::R8G8B8_SNORM: + { + static const VertexFormat format(GL_BYTE, GL_TRUE, 3, false); + return format; + } + case angle::FormatID::R8G8B8A8_SSCALED: + { + static const VertexFormat format(GL_BYTE, GL_FALSE, 4, false); + return format; + } + case angle::FormatID::R8G8B8A8_SNORM: + { + static const VertexFormat format(GL_BYTE, GL_TRUE, 4, false); + return format; + } + case angle::FormatID::R8_USCALED: + { + static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 1, false); + return format; + } + case angle::FormatID::R8_UNORM: + { + static const VertexFormat format(GL_UNSIGNED_BYTE, GL_TRUE, 1, false); + return format; + } + case angle::FormatID::R8G8_USCALED: + { + static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 2, false); + return format; + } + case angle::FormatID::R8G8_UNORM: + { + static const VertexFormat format(GL_UNSIGNED_BYTE, GL_TRUE, 2, false); + return format; + } + case angle::FormatID::R8G8B8_USCALED: + { + static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 3, false); + return format; + } + case angle::FormatID::R8G8B8_UNORM: + { + static const VertexFormat format(GL_UNSIGNED_BYTE, GL_TRUE, 3, false); + return format; + } + case angle::FormatID::R8G8B8A8_USCALED: + { + static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 4, false); + return format; + } + case angle::FormatID::R8G8B8A8_UNORM: + { + static const VertexFormat format(GL_UNSIGNED_BYTE, GL_TRUE, 4, false); + return format; + } + case angle::FormatID::R16_SSCALED: + { + static const VertexFormat format(GL_SHORT, GL_FALSE, 1, false); + return format; + } + case angle::FormatID::R16_SNORM: + { + static const VertexFormat format(GL_SHORT, GL_TRUE, 1, false); + return format; + } + case angle::FormatID::R16G16_SSCALED: + { + static const VertexFormat format(GL_SHORT, GL_FALSE, 2, false); + return format; + } + case angle::FormatID::R16G16_SNORM: + { + static const VertexFormat format(GL_SHORT, GL_TRUE, 2, false); + return format; + } + case angle::FormatID::R16G16B16_SSCALED: + { + static const VertexFormat format(GL_SHORT, GL_FALSE, 3, false); + return format; + } + case angle::FormatID::R16G16B16_SNORM: + { + static const VertexFormat format(GL_SHORT, GL_TRUE, 3, false); + return format; + } + case angle::FormatID::R16G16B16A16_SSCALED: + { + static const VertexFormat format(GL_SHORT, GL_FALSE, 4, false); + return format; + } + case angle::FormatID::R16G16B16A16_SNORM: + { + static const VertexFormat format(GL_SHORT, GL_TRUE, 4, false); + return format; + } + case angle::FormatID::R16_USCALED: + { + static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 1, false); + return format; + } + case angle::FormatID::R16_UNORM: + { + static const VertexFormat format(GL_UNSIGNED_SHORT, GL_TRUE, 1, false); + return format; + } + case angle::FormatID::R16G16_USCALED: + { + static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 2, false); + return format; + } + case angle::FormatID::R16G16_UNORM: + { + static const VertexFormat format(GL_UNSIGNED_SHORT, GL_TRUE, 2, false); + return format; + } + case angle::FormatID::R16G16B16_USCALED: + { + static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 3, false); + return format; + } + case angle::FormatID::R16G16B16_UNORM: + { + static const VertexFormat format(GL_UNSIGNED_SHORT, GL_TRUE, 3, false); + return format; + } + case angle::FormatID::R16G16B16A16_USCALED: + { + static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 4, false); + return format; + } + case angle::FormatID::R16G16B16A16_UNORM: + { + static const VertexFormat format(GL_UNSIGNED_SHORT, GL_TRUE, 4, false); + return format; + } + case angle::FormatID::R32_SSCALED: + { + static const VertexFormat format(GL_INT, GL_FALSE, 1, false); + return format; + } + case angle::FormatID::R32_SNORM: + { + static const VertexFormat format(GL_INT, GL_TRUE, 1, false); + return format; + } + case angle::FormatID::R32G32_SSCALED: + { + static const VertexFormat format(GL_INT, GL_FALSE, 2, false); + return format; + } + case angle::FormatID::R32G32_SNORM: + { + static const VertexFormat format(GL_INT, GL_TRUE, 2, false); + return format; + } + case angle::FormatID::R32G32B32_SSCALED: + { + static const VertexFormat format(GL_INT, GL_FALSE, 3, false); + return format; + } + case angle::FormatID::R32G32B32_SNORM: + { + static const VertexFormat format(GL_INT, GL_TRUE, 3, false); + return format; + } + case angle::FormatID::R32G32B32A32_SSCALED: + { + static const VertexFormat format(GL_INT, GL_FALSE, 4, false); + return format; + } + case angle::FormatID::R32G32B32A32_SNORM: + { + static const VertexFormat format(GL_INT, GL_TRUE, 4, false); + return format; + } + case angle::FormatID::R32_USCALED: + { + static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 1, false); + return format; + } + case angle::FormatID::R32_UNORM: + { + static const VertexFormat format(GL_UNSIGNED_INT, GL_TRUE, 1, false); + return format; + } + case angle::FormatID::R32G32_USCALED: + { + static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 2, false); + return format; + } + case angle::FormatID::R32G32_UNORM: + { + static const VertexFormat format(GL_UNSIGNED_INT, GL_TRUE, 2, false); + return format; + } + case angle::FormatID::R32G32B32_USCALED: + { + static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 3, false); + return format; + } + case angle::FormatID::R32G32B32_UNORM: + { + static const VertexFormat format(GL_UNSIGNED_INT, GL_TRUE, 3, false); + return format; + } + case angle::FormatID::R32G32B32A32_USCALED: + { + static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 4, false); + return format; + } + case angle::FormatID::R32G32B32A32_UNORM: + { + static const VertexFormat format(GL_UNSIGNED_INT, GL_TRUE, 4, false); + return format; + } + case angle::FormatID::R8_SINT: + { + static const VertexFormat format(GL_BYTE, GL_FALSE, 1, true); + return format; + } + case angle::FormatID::R8G8_SINT: + { + static const VertexFormat format(GL_BYTE, GL_FALSE, 2, true); + return format; + } + case angle::FormatID::R8G8B8_SINT: + { + static const VertexFormat format(GL_BYTE, GL_FALSE, 3, true); + return format; + } + case angle::FormatID::R8G8B8A8_SINT: + { + static const VertexFormat format(GL_BYTE, GL_FALSE, 4, true); + return format; + } + case angle::FormatID::R8_UINT: + { + static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 1, true); + return format; + } + case angle::FormatID::R8G8_UINT: + { + static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 2, true); + return format; + } + case angle::FormatID::R8G8B8_UINT: + { + static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 3, true); + return format; + } + case angle::FormatID::R8G8B8A8_UINT: + { + static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 4, true); + return format; + } + case angle::FormatID::R16_SINT: + { + static const VertexFormat format(GL_SHORT, GL_FALSE, 1, true); + return format; + } + case angle::FormatID::R16G16_SINT: + { + static const VertexFormat format(GL_SHORT, GL_FALSE, 2, true); + return format; + } + case angle::FormatID::R16G16B16_SINT: + { + static const VertexFormat format(GL_SHORT, GL_FALSE, 3, true); + return format; + } + case angle::FormatID::R16G16B16A16_SINT: + { + static const VertexFormat format(GL_SHORT, GL_FALSE, 4, true); + return format; + } + case angle::FormatID::R16_UINT: + { + static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 1, true); + return format; + } + case angle::FormatID::R16G16_UINT: + { + static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 2, true); + return format; + } + case angle::FormatID::R16G16B16_UINT: + { + static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 3, true); + return format; + } + case angle::FormatID::R16G16B16A16_UINT: + { + static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 4, true); + return format; + } + case angle::FormatID::R32_SINT: + { + static const VertexFormat format(GL_INT, GL_FALSE, 1, true); + return format; + } + case angle::FormatID::R32G32_SINT: + { + static const VertexFormat format(GL_INT, GL_FALSE, 2, true); + return format; + } + case angle::FormatID::R32G32B32_SINT: + { + static const VertexFormat format(GL_INT, GL_FALSE, 3, true); + return format; + } + case angle::FormatID::R32G32B32A32_SINT: + { + static const VertexFormat format(GL_INT, GL_FALSE, 4, true); + return format; + } + case angle::FormatID::R32_UINT: + { + static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 1, true); + return format; + } + case angle::FormatID::R32G32_UINT: + { + static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 2, true); + return format; + } + case angle::FormatID::R32G32B32_UINT: + { + static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 3, true); + return format; + } + case angle::FormatID::R32G32B32A32_UINT: + { + static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 4, true); + return format; + } + case angle::FormatID::R32_FIXED: + { + static const VertexFormat format(GL_FIXED, GL_FALSE, 1, false); + return format; + } + case angle::FormatID::R32G32_FIXED: + { + static const VertexFormat format(GL_FIXED, GL_FALSE, 2, false); + return format; + } + case angle::FormatID::R32G32B32_FIXED: + { + static const VertexFormat format(GL_FIXED, GL_FALSE, 3, false); + return format; + } + case angle::FormatID::R32G32B32A32_FIXED: + { + static const VertexFormat format(GL_FIXED, GL_FALSE, 4, false); + return format; + } + case angle::FormatID::R16_FLOAT: + { + static const VertexFormat format(GL_HALF_FLOAT, GL_FALSE, 1, false); + return format; + } + case angle::FormatID::R16G16_FLOAT: + { + static const VertexFormat format(GL_HALF_FLOAT, GL_FALSE, 2, false); + return format; + } + case angle::FormatID::R16G16B16_FLOAT: + { + static const VertexFormat format(GL_HALF_FLOAT, GL_FALSE, 3, false); + return format; + } + case angle::FormatID::R16G16B16A16_FLOAT: + { + static const VertexFormat format(GL_HALF_FLOAT, GL_FALSE, 4, false); + return format; + } + case angle::FormatID::R32_FLOAT: + { + static const VertexFormat format(GL_FLOAT, GL_FALSE, 1, false); + return format; + } + case angle::FormatID::R32G32_FLOAT: + { + static const VertexFormat format(GL_FLOAT, GL_FALSE, 2, false); + return format; + } + case angle::FormatID::R32G32B32_FLOAT: + { + static const VertexFormat format(GL_FLOAT, GL_FALSE, 3, false); + return format; + } + case angle::FormatID::R32G32B32A32_FLOAT: + { + static const VertexFormat format(GL_FLOAT, GL_FALSE, 4, false); + return format; + } + case angle::FormatID::R10G10B10A2_SSCALED: + { + static const VertexFormat format(GL_INT_2_10_10_10_REV, GL_FALSE, 4, false); + return format; + } + case angle::FormatID::R10G10B10A2_USCALED: + { + static const VertexFormat format(GL_UNSIGNED_INT_2_10_10_10_REV, GL_FALSE, 4, false); + return format; + } + case angle::FormatID::R10G10B10A2_SNORM: + { + static const VertexFormat format(GL_INT_2_10_10_10_REV, GL_TRUE, 4, false); + return format; + } + case angle::FormatID::R10G10B10A2_UNORM: + { + static const VertexFormat format(GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 4, false); + return format; + } + case angle::FormatID::R10G10B10A2_SINT: + { + static const VertexFormat format(GL_INT_2_10_10_10_REV, GL_FALSE, 4, true); + return format; + } + case angle::FormatID::R10G10B10A2_UINT: + { + static const VertexFormat format(GL_UNSIGNED_INT_2_10_10_10_REV, GL_FALSE, 4, true); + return format; + } + case angle::FormatID::A2R10G10B10_SSCALED_VERTEX: + { + static const VertexFormat format(GL_INT_10_10_10_2_OES, GL_FALSE, 4, false); + return format; + } + case angle::FormatID::A2R10G10B10_USCALED_VERTEX: + { + static const VertexFormat format(GL_UNSIGNED_INT_10_10_10_2_OES, GL_FALSE, 4, false); + return format; + } + case angle::FormatID::A2R10G10B10_SNORM_VERTEX: + { + static const VertexFormat format(GL_INT_10_10_10_2_OES, GL_TRUE, 4, false); + return format; + } + case angle::FormatID::A2R10G10B10_UNORM_VERTEX: + { + static const VertexFormat format(GL_UNSIGNED_INT_10_10_10_2_OES, GL_TRUE, 4, false); + return format; + } + case angle::FormatID::A2R10G10B10_SINT_VERTEX: + { + static const VertexFormat format(GL_INT_10_10_10_2_OES, GL_FALSE, 4, true); + return format; + } + case angle::FormatID::A2R10G10B10_UINT_VERTEX: + { + static const VertexFormat format(GL_UNSIGNED_INT_10_10_10_2_OES, GL_FALSE, 4, true); + return format; + } + case angle::FormatID::X2R10G10B10_SSCALED_VERTEX: + { + static const VertexFormat format(GL_INT_10_10_10_2_OES, GL_FALSE, 4, false); + return format; + } + case angle::FormatID::X2R10G10B10_USCALED_VERTEX: + { + static const VertexFormat format(GL_UNSIGNED_INT_10_10_10_2_OES, GL_FALSE, 4, false); + return format; + } + case angle::FormatID::X2R10G10B10_SNORM_VERTEX: + { + static const VertexFormat format(GL_INT_10_10_10_2_OES, GL_TRUE, 4, false); + return format; + } + case angle::FormatID::X2R10G10B10_UNORM_VERTEX: + { + static const VertexFormat format(GL_UNSIGNED_INT_10_10_10_2_OES, GL_TRUE, 4, false); + return format; + } + case angle::FormatID::X2R10G10B10_SINT_VERTEX: + { + static const VertexFormat format(GL_INT_10_10_10_2_OES, GL_FALSE, 4, true); + return format; + } + default: + { + static const VertexFormat format(GL_NONE, GL_FALSE, 0, false); + return format; + } + } +} + +size_t GetVertexFormatSize(angle::FormatID vertexFormatID) +{ + switch (vertexFormatID) + { + case angle::FormatID::R8_SSCALED: + case angle::FormatID::R8_SNORM: + case angle::FormatID::R8_USCALED: + case angle::FormatID::R8_UNORM: + case angle::FormatID::R8_SINT: + case angle::FormatID::R8_UINT: + return 1; + + case angle::FormatID::R8G8_SSCALED: + case angle::FormatID::R8G8_SNORM: + case angle::FormatID::R8G8_USCALED: + case angle::FormatID::R8G8_UNORM: + case angle::FormatID::R8G8_SINT: + case angle::FormatID::R8G8_UINT: + case angle::FormatID::R16_SSCALED: + case angle::FormatID::R16_SNORM: + case angle::FormatID::R16_USCALED: + case angle::FormatID::R16_UNORM: + case angle::FormatID::R16_SINT: + case angle::FormatID::R16_UINT: + case angle::FormatID::R16_FLOAT: + return 2; + + case angle::FormatID::R8G8B8_SSCALED: + case angle::FormatID::R8G8B8_SNORM: + case angle::FormatID::R8G8B8_USCALED: + case angle::FormatID::R8G8B8_UNORM: + case angle::FormatID::R8G8B8_SINT: + case angle::FormatID::R8G8B8_UINT: + return 3; + + case angle::FormatID::R8G8B8A8_SSCALED: + case angle::FormatID::R8G8B8A8_SNORM: + case angle::FormatID::R8G8B8A8_USCALED: + case angle::FormatID::R8G8B8A8_UNORM: + case angle::FormatID::R8G8B8A8_SINT: + case angle::FormatID::R8G8B8A8_UINT: + case angle::FormatID::R16G16_SSCALED: + case angle::FormatID::R16G16_SNORM: + case angle::FormatID::R16G16_USCALED: + case angle::FormatID::R16G16_UNORM: + case angle::FormatID::R16G16_SINT: + case angle::FormatID::R16G16_UINT: + case angle::FormatID::R32_SSCALED: + case angle::FormatID::R32_SNORM: + case angle::FormatID::R32_USCALED: + case angle::FormatID::R32_UNORM: + case angle::FormatID::R32_SINT: + case angle::FormatID::R32_UINT: + case angle::FormatID::R16G16_FLOAT: + case angle::FormatID::R32_FIXED: + case angle::FormatID::R32_FLOAT: + case angle::FormatID::R10G10B10A2_SSCALED: + case angle::FormatID::R10G10B10A2_USCALED: + case angle::FormatID::R10G10B10A2_SNORM: + case angle::FormatID::R10G10B10A2_UNORM: + case angle::FormatID::R10G10B10A2_SINT: + case angle::FormatID::R10G10B10A2_UINT: + case angle::FormatID::A2R10G10B10_SSCALED_VERTEX: + case angle::FormatID::A2R10G10B10_USCALED_VERTEX: + case angle::FormatID::A2R10G10B10_SINT_VERTEX: + case angle::FormatID::A2R10G10B10_UINT_VERTEX: + case angle::FormatID::A2R10G10B10_SNORM_VERTEX: + case angle::FormatID::A2R10G10B10_UNORM_VERTEX: + case angle::FormatID::X2R10G10B10_SSCALED_VERTEX: + case angle::FormatID::X2R10G10B10_USCALED_VERTEX: + case angle::FormatID::X2R10G10B10_SINT_VERTEX: + case angle::FormatID::X2R10G10B10_UINT_VERTEX: + case angle::FormatID::X2R10G10B10_SNORM_VERTEX: + case angle::FormatID::X2R10G10B10_UNORM_VERTEX: + return 4; + + case angle::FormatID::R16G16B16_SSCALED: + case angle::FormatID::R16G16B16_SNORM: + case angle::FormatID::R16G16B16_USCALED: + case angle::FormatID::R16G16B16_UNORM: + case angle::FormatID::R16G16B16_SINT: + case angle::FormatID::R16G16B16_UINT: + case angle::FormatID::R16G16B16_FLOAT: + return 6; + + case angle::FormatID::R16G16B16A16_SSCALED: + case angle::FormatID::R16G16B16A16_SNORM: + case angle::FormatID::R16G16B16A16_USCALED: + case angle::FormatID::R16G16B16A16_UNORM: + case angle::FormatID::R16G16B16A16_SINT: + case angle::FormatID::R16G16B16A16_UINT: + case angle::FormatID::R32G32_SSCALED: + case angle::FormatID::R32G32_SNORM: + case angle::FormatID::R32G32_USCALED: + case angle::FormatID::R32G32_UNORM: + case angle::FormatID::R32G32_SINT: + case angle::FormatID::R32G32_UINT: + case angle::FormatID::R16G16B16A16_FLOAT: + case angle::FormatID::R32G32_FIXED: + case angle::FormatID::R32G32_FLOAT: + return 8; + + case angle::FormatID::R32G32B32_SSCALED: + case angle::FormatID::R32G32B32_SNORM: + case angle::FormatID::R32G32B32_USCALED: + case angle::FormatID::R32G32B32_UNORM: + case angle::FormatID::R32G32B32_SINT: + case angle::FormatID::R32G32B32_UINT: + case angle::FormatID::R32G32B32_FIXED: + case angle::FormatID::R32G32B32_FLOAT: + return 12; + + case angle::FormatID::R32G32B32A32_SSCALED: + case angle::FormatID::R32G32B32A32_SNORM: + case angle::FormatID::R32G32B32A32_USCALED: + case angle::FormatID::R32G32B32A32_UNORM: + case angle::FormatID::R32G32B32A32_SINT: + case angle::FormatID::R32G32B32A32_UINT: + case angle::FormatID::R32G32B32A32_FIXED: + case angle::FormatID::R32G32B32A32_FLOAT: + return 16; + + case angle::FormatID::NONE: + default: + UNREACHABLE(); + return 0; + } +} + +angle::FormatID ConvertFormatSignedness(const angle::Format &format) +{ + switch (format.id) + { + // 1 byte signed to unsigned + case angle::FormatID::R8_SINT: + return angle::FormatID::R8_UINT; + case angle::FormatID::R8_SNORM: + return angle::FormatID::R8_UNORM; + case angle::FormatID::R8_SSCALED: + return angle::FormatID::R8_USCALED; + case angle::FormatID::R8G8_SINT: + return angle::FormatID::R8G8_UINT; + case angle::FormatID::R8G8_SNORM: + return angle::FormatID::R8G8_UNORM; + case angle::FormatID::R8G8_SSCALED: + return angle::FormatID::R8G8_USCALED; + case angle::FormatID::R8G8B8_SINT: + return angle::FormatID::R8G8B8_UINT; + case angle::FormatID::R8G8B8_SNORM: + return angle::FormatID::R8G8B8_UNORM; + case angle::FormatID::R8G8B8_SSCALED: + return angle::FormatID::R8G8B8_USCALED; + case angle::FormatID::R8G8B8A8_SINT: + return angle::FormatID::R8G8B8A8_UINT; + case angle::FormatID::R8G8B8A8_SNORM: + return angle::FormatID::R8G8B8A8_UNORM; + case angle::FormatID::R8G8B8A8_SSCALED: + return angle::FormatID::R8G8B8A8_USCALED; + // 1 byte unsigned to signed + case angle::FormatID::R8_UINT: + return angle::FormatID::R8_SINT; + case angle::FormatID::R8_UNORM: + return angle::FormatID::R8_SNORM; + case angle::FormatID::R8_USCALED: + return angle::FormatID::R8_SSCALED; + case angle::FormatID::R8G8_UINT: + return angle::FormatID::R8G8_SINT; + case angle::FormatID::R8G8_UNORM: + return angle::FormatID::R8G8_SNORM; + case angle::FormatID::R8G8_USCALED: + return angle::FormatID::R8G8_SSCALED; + case angle::FormatID::R8G8B8_UINT: + return angle::FormatID::R8G8B8_SINT; + case angle::FormatID::R8G8B8_UNORM: + return angle::FormatID::R8G8B8_SNORM; + case angle::FormatID::R8G8B8_USCALED: + return angle::FormatID::R8G8B8_SSCALED; + case angle::FormatID::R8G8B8A8_UINT: + return angle::FormatID::R8G8B8A8_SINT; + case angle::FormatID::R8G8B8A8_UNORM: + return angle::FormatID::R8G8B8A8_SNORM; + case angle::FormatID::R8G8B8A8_USCALED: + return angle::FormatID::R8G8B8A8_SSCALED; + // 2 byte signed to unsigned + case angle::FormatID::R16_SINT: + return angle::FormatID::R16_UINT; + case angle::FormatID::R16_SNORM: + return angle::FormatID::R16_UNORM; + case angle::FormatID::R16_SSCALED: + return angle::FormatID::R16_USCALED; + case angle::FormatID::R16G16_SINT: + return angle::FormatID::R16G16_UINT; + case angle::FormatID::R16G16_SNORM: + return angle::FormatID::R16G16_UNORM; + case angle::FormatID::R16G16_SSCALED: + return angle::FormatID::R16G16_USCALED; + case angle::FormatID::R16G16B16_SINT: + return angle::FormatID::R16G16B16_UINT; + case angle::FormatID::R16G16B16_SNORM: + return angle::FormatID::R16G16B16_UNORM; + case angle::FormatID::R16G16B16_SSCALED: + return angle::FormatID::R16G16B16_USCALED; + case angle::FormatID::R16G16B16A16_SINT: + return angle::FormatID::R16G16B16A16_UINT; + case angle::FormatID::R16G16B16A16_SNORM: + return angle::FormatID::R16G16B16A16_UNORM; + case angle::FormatID::R16G16B16A16_SSCALED: + return angle::FormatID::R16G16B16A16_USCALED; + // 2 byte unsigned to signed + case angle::FormatID::R16_UINT: + return angle::FormatID::R16_SINT; + case angle::FormatID::R16_UNORM: + return angle::FormatID::R16_SNORM; + case angle::FormatID::R16_USCALED: + return angle::FormatID::R16_SSCALED; + case angle::FormatID::R16G16_UINT: + return angle::FormatID::R16G16_SINT; + case angle::FormatID::R16G16_UNORM: + return angle::FormatID::R16G16_SNORM; + case angle::FormatID::R16G16_USCALED: + return angle::FormatID::R16G16_SSCALED; + case angle::FormatID::R16G16B16_UINT: + return angle::FormatID::R16G16B16_SINT; + case angle::FormatID::R16G16B16_UNORM: + return angle::FormatID::R16G16B16_SNORM; + case angle::FormatID::R16G16B16_USCALED: + return angle::FormatID::R16G16B16_SSCALED; + case angle::FormatID::R16G16B16A16_UINT: + return angle::FormatID::R16G16B16A16_SINT; + case angle::FormatID::R16G16B16A16_UNORM: + return angle::FormatID::R16G16B16A16_SNORM; + case angle::FormatID::R16G16B16A16_USCALED: + return angle::FormatID::R16G16B16A16_SSCALED; + // 4 byte signed to unsigned + case angle::FormatID::R32_SINT: + return angle::FormatID::R32_UINT; + case angle::FormatID::R32_SNORM: + return angle::FormatID::R32_UNORM; + case angle::FormatID::R32_SSCALED: + return angle::FormatID::R32_USCALED; + case angle::FormatID::R32G32_SINT: + return angle::FormatID::R32G32_UINT; + case angle::FormatID::R32G32_SNORM: + return angle::FormatID::R32G32_UNORM; + case angle::FormatID::R32G32_SSCALED: + return angle::FormatID::R32G32_USCALED; + case angle::FormatID::R32G32B32_SINT: + return angle::FormatID::R32G32B32_UINT; + case angle::FormatID::R32G32B32_SNORM: + return angle::FormatID::R32G32B32_UNORM; + case angle::FormatID::R32G32B32_SSCALED: + return angle::FormatID::R32G32B32_USCALED; + case angle::FormatID::R32G32B32A32_SINT: + return angle::FormatID::R32G32B32A32_UINT; + case angle::FormatID::R32G32B32A32_SNORM: + return angle::FormatID::R32G32B32A32_UNORM; + case angle::FormatID::R32G32B32A32_SSCALED: + return angle::FormatID::R32G32B32A32_USCALED; + // 4 byte unsigned to signed + case angle::FormatID::R32_UINT: + return angle::FormatID::R32_SINT; + case angle::FormatID::R32_UNORM: + return angle::FormatID::R32_SNORM; + case angle::FormatID::R32_USCALED: + return angle::FormatID::R32_SSCALED; + case angle::FormatID::R32G32_UINT: + return angle::FormatID::R32G32_SINT; + case angle::FormatID::R32G32_UNORM: + return angle::FormatID::R32G32_SNORM; + case angle::FormatID::R32G32_USCALED: + return angle::FormatID::R32G32_SSCALED; + case angle::FormatID::R32G32B32_UINT: + return angle::FormatID::R32G32B32_SINT; + case angle::FormatID::R32G32B32_UNORM: + return angle::FormatID::R32G32B32_SNORM; + case angle::FormatID::R32G32B32_USCALED: + return angle::FormatID::R32G32B32_SSCALED; + case angle::FormatID::R32G32B32A32_UINT: + return angle::FormatID::R32G32B32A32_SINT; + case angle::FormatID::R32G32B32A32_UNORM: + return angle::FormatID::R32G32B32A32_SNORM; + case angle::FormatID::R32G32B32A32_USCALED: + return angle::FormatID::R32G32B32A32_SSCALED; + // 1010102 signed to unsigned + case angle::FormatID::R10G10B10A2_SINT: + return angle::FormatID::R10G10B10A2_UINT; + case angle::FormatID::R10G10B10A2_SSCALED: + return angle::FormatID::R10G10B10A2_USCALED; + case angle::FormatID::R10G10B10A2_SNORM: + return angle::FormatID::R10G10B10A2_UNORM; + // 1010102 unsigned to signed + case angle::FormatID::R10G10B10A2_UINT: + return angle::FormatID::R10G10B10A2_SINT; + case angle::FormatID::R10G10B10A2_USCALED: + return angle::FormatID::R10G10B10A2_SSCALED; + case angle::FormatID::R10G10B10A2_UNORM: + return angle::FormatID::R10G10B10A2_SNORM; + default: + UNREACHABLE(); + return angle::FormatID::NONE; + } +} + +bool ValidES3InternalFormat(GLenum internalFormat) +{ + const InternalFormatInfoMap &formatMap = GetInternalFormatMap(); + return internalFormat != GL_NONE && formatMap.find(internalFormat) != formatMap.end(); +} + +VertexFormat::VertexFormat(GLenum typeIn, + GLboolean normalizedIn, + GLuint componentsIn, + bool pureIntegerIn) + : type(typeIn), normalized(normalizedIn), components(componentsIn), pureInteger(pureIntegerIn) +{ + // float -> !normalized + ASSERT(!(type == GL_FLOAT || type == GL_HALF_FLOAT || type == GL_FIXED) || + normalized == GL_FALSE); +} +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/formatutils.h b/gfx/angle/checkout/src/libANGLE/formatutils.h new file mode 100644 index 0000000000..64cc42ec1f --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/formatutils.h @@ -0,0 +1,577 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// formatutils.h: Queries for GL image formats. + +#ifndef LIBANGLE_FORMATUTILS_H_ +#define LIBANGLE_FORMATUTILS_H_ + +#include +#include +#include + +#include "angle_gl.h" +#include "common/android_util.h" +#include "libANGLE/Caps.h" +#include "libANGLE/Config.h" +#include "libANGLE/Error.h" +#include "libANGLE/Version.h" +#include "libANGLE/VertexAttribute.h" +#include "libANGLE/angletypes.h" + +namespace gl +{ +struct VertexAttribute; + +struct FormatType final +{ + FormatType(); + FormatType(GLenum format_, GLenum type_); + FormatType(const FormatType &other) = default; + FormatType &operator=(const FormatType &other) = default; + + bool operator<(const FormatType &other) const; + + GLenum format; + GLenum type; +}; + +struct Type +{ + Type() : bytes(0), bytesShift(0), specialInterpretation(0) {} + + explicit Type(uint32_t packedTypeInfo) + : bytes(packedTypeInfo & 0xff), + bytesShift((packedTypeInfo >> 8) & 0xff), + specialInterpretation((packedTypeInfo >> 16) & 1) + {} + + GLuint bytes; + GLuint bytesShift; // Bit shift by this value to effectively divide/multiply by "bytes" in a + // more optimal way + bool specialInterpretation; +}; + +uint32_t GetPackedTypeInfo(GLenum type); + +ANGLE_INLINE GLenum GetNonLinearFormat(const GLenum format) +{ + switch (format) + { + case GL_BGRA8_EXT: + return GL_BGRA8_SRGB_ANGLEX; + case GL_RGBA8: + return GL_SRGB8_ALPHA8; + case GL_RGB8: + case GL_BGRX8_ANGLEX: + case GL_RGBX8_ANGLE: + return GL_SRGB8; + case GL_RGBA16F: + return GL_RGBA16F; + default: + return GL_NONE; + } +} + +ANGLE_INLINE bool ColorspaceFormatOverride(const EGLenum colorspace, GLenum *rendertargetformat) +{ + // Override the rendertargetformat based on colorpsace + switch (colorspace) + { + case EGL_GL_COLORSPACE_LINEAR: // linear colorspace no translation needed + case EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT: // linear colorspace no translation needed + case EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT: // linear colorspace no translation needed + case EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT: // App, not the HW, will specify the + // transfer function + case EGL_GL_COLORSPACE_SCRGB_EXT: // App, not the HW, will specify the transfer function + // No translation + return true; + case EGL_GL_COLORSPACE_SRGB_KHR: + case EGL_GL_COLORSPACE_DISPLAY_P3_EXT: + { + GLenum nonLinearFormat = GetNonLinearFormat(*rendertargetformat); + if (nonLinearFormat != GL_NONE) + { + *rendertargetformat = nonLinearFormat; + return true; + } + else + { + return false; + } + } + break; + default: + UNREACHABLE(); + return false; + } +} + +ANGLE_INLINE const Type GetTypeInfo(GLenum type) +{ + return Type(GetPackedTypeInfo(type)); +} + +// This helpers use tricks based on the assumption that the type has certain values. +static_assert(static_cast(DrawElementsType::UnsignedByte) == 0, "Please update this code."); +static_assert(static_cast(DrawElementsType::UnsignedShort) == 1, + "Please update this code."); +static_assert(static_cast(DrawElementsType::UnsignedInt) == 2, "Please update this code."); +ANGLE_INLINE GLuint GetDrawElementsTypeSize(DrawElementsType type) +{ + return (1 << static_cast(type)); +} + +ANGLE_INLINE GLuint GetDrawElementsTypeShift(DrawElementsType type) +{ + return static_cast(type); +} + +// Information about an OpenGL internal format. Can be keyed on the internalFormat and type +// members. +struct InternalFormat +{ + InternalFormat(); + InternalFormat(const InternalFormat &other); + InternalFormat &operator=(const InternalFormat &other); + + GLuint computePixelBytes(GLenum formatType) const; + + [[nodiscard]] bool computeBufferRowLength(uint32_t width, uint32_t *resultOut) const; + [[nodiscard]] bool computeBufferImageHeight(uint32_t height, uint32_t *resultOut) const; + + [[nodiscard]] bool computeRowPitch(GLenum formatType, + GLsizei width, + GLint alignment, + GLint rowLength, + GLuint *resultOut) const; + [[nodiscard]] bool computeDepthPitch(GLsizei height, + GLint imageHeight, + GLuint rowPitch, + GLuint *resultOut) const; + [[nodiscard]] bool computeDepthPitch(GLenum formatType, + GLsizei width, + GLsizei height, + GLint alignment, + GLint rowLength, + GLint imageHeight, + GLuint *resultOut) const; + + [[nodiscard]] bool computePalettedImageRowPitch(GLsizei width, GLuint *resultOut) const; + + [[nodiscard]] bool computeCompressedImageSize(const Extents &size, GLuint *resultOut) const; + + [[nodiscard]] std::pair getCompressedImageMinBlocks() const; + + [[nodiscard]] bool computeSkipBytes(GLenum formatType, + GLuint rowPitch, + GLuint depthPitch, + const PixelStoreStateBase &state, + bool is3D, + GLuint *resultOut) const; + + [[nodiscard]] bool computePackUnpackEndByte(GLenum formatType, + const Extents &size, + const PixelStoreStateBase &state, + bool is3D, + GLuint *resultOut) const; + + bool isLUMA() const; + GLenum getReadPixelsFormat(const Extensions &extensions) const; + GLenum getReadPixelsType(const Version &version) const; + + // Support upload a portion of image? + bool supportSubImage() const; + + ANGLE_INLINE bool isChannelSizeCompatible(GLuint redSize, + GLuint greenSize, + GLuint blueSize, + GLuint alphaSize) const + { + // We only check for equality in all channel sizes + return ((redSize == redBits) && (greenSize == greenBits) && (blueSize == blueBits) && + (alphaSize == alphaBits)); + } + + // Return true if the format is a required renderbuffer format in the given version of the core + // spec. Note that it isn't always clear whether all the rules that apply to core required + // renderbuffer formats also apply to additional formats added by extensions. Because of this + // extension formats are conservatively not included. + bool isRequiredRenderbufferFormat(const Version &version) const; + + bool isInt() const; + bool isDepthOrStencil() const; + + bool operator==(const InternalFormat &other) const; + bool operator!=(const InternalFormat &other) const; + + GLenum internalFormat; + + bool sized; + GLenum sizedInternalFormat; + + GLuint redBits; + GLuint greenBits; + GLuint blueBits; + + GLuint luminanceBits; + + GLuint alphaBits; + GLuint sharedBits; + + GLuint depthBits; + GLuint stencilBits; + + GLuint pixelBytes; + + GLuint componentCount; + + bool compressed; + GLuint compressedBlockWidth; + GLuint compressedBlockHeight; + GLuint compressedBlockDepth; + + bool paletted; + GLuint paletteBits; + + GLenum format; + GLenum type; + + GLenum componentType; + GLenum colorEncoding; + + typedef bool (*SupportCheckFunction)(const Version &, const Extensions &); + SupportCheckFunction textureSupport; + SupportCheckFunction filterSupport; + SupportCheckFunction textureAttachmentSupport; // glFramebufferTexture2D + SupportCheckFunction renderbufferSupport; // glFramebufferRenderbuffer + SupportCheckFunction blendSupport; +}; + +// A "Format" wraps an InternalFormat struct, querying it from either a sized internal format or +// unsized internal format and type. +// TODO(geofflang): Remove this, it doesn't add any more information than the InternalFormat object. +struct Format +{ + // Sized types only. + explicit Format(GLenum internalFormat); + + // Sized or unsized types. + explicit Format(const InternalFormat &internalFormat); + Format(GLenum internalFormat, GLenum type); + + Format(const Format &other); + Format &operator=(const Format &other); + + bool valid() const; + + static Format Invalid(); + static bool SameSized(const Format &a, const Format &b); + static bool EquivalentForBlit(const Format &a, const Format &b); + + friend std::ostream &operator<<(std::ostream &os, const Format &fmt); + + // This is the sized info. + const InternalFormat *info; +}; + +const InternalFormat &GetSizedInternalFormatInfo(GLenum internalFormat); +const InternalFormat &GetInternalFormatInfo(GLenum internalFormat, GLenum type); + +// Strip sizing information from an internal format. Doesn't necessarily validate that the internal +// format is valid. +GLenum GetUnsizedFormat(GLenum internalFormat); + +// Return whether the compressed format requires whole image/mip level to be uploaded to texture. +bool CompressedFormatRequiresWholeImage(GLenum internalFormat); + +// In support of GetImage, check for LUMA formats and override with real format +void MaybeOverrideLuminance(GLenum &format, GLenum &type, GLenum actualFormat, GLenum actualType); + +typedef std::set FormatSet; +const FormatSet &GetAllSizedInternalFormats(); + +typedef angle::HashMap> InternalFormatInfoMap; +const InternalFormatInfoMap &GetInternalFormatMap(); + +int GetAndroidHardwareBufferFormatFromChannelSizes(const egl::AttributeMap &attribMap); + +GLenum GetConfigColorBufferFormat(const egl::Config *config); +GLenum GetConfigDepthStencilBufferFormat(const egl::Config *config); + +ANGLE_INLINE int GetNativeVisualID(const InternalFormat &internalFormat) +{ + int nativeVisualId = 0; +#if defined(ANGLE_PLATFORM_ANDROID) + nativeVisualId = + angle::android::GLInternalFormatToNativePixelFormat(internalFormat.internalFormat); +#endif +#if defined(ANGLE_PLATFORM_LINUX) && defined(ANGLE_USES_GBM) + nativeVisualId = angle::GLInternalFormatToGbmFourCCFormat(internalFormat.internalFormat); +#endif + + return nativeVisualId; +} + +// From the ESSL 3.00.4 spec: +// Vertex shader inputs can only be float, floating-point vectors, matrices, signed and unsigned +// integers and integer vectors. Vertex shader inputs cannot be arrays or structures. + +enum AttributeType +{ + ATTRIBUTE_FLOAT, + ATTRIBUTE_VEC2, + ATTRIBUTE_VEC3, + ATTRIBUTE_VEC4, + ATTRIBUTE_INT, + ATTRIBUTE_IVEC2, + ATTRIBUTE_IVEC3, + ATTRIBUTE_IVEC4, + ATTRIBUTE_UINT, + ATTRIBUTE_UVEC2, + ATTRIBUTE_UVEC3, + ATTRIBUTE_UVEC4, + ATTRIBUTE_MAT2, + ATTRIBUTE_MAT3, + ATTRIBUTE_MAT4, + ATTRIBUTE_MAT2x3, + ATTRIBUTE_MAT2x4, + ATTRIBUTE_MAT3x2, + ATTRIBUTE_MAT3x4, + ATTRIBUTE_MAT4x2, + ATTRIBUTE_MAT4x3, +}; + +AttributeType GetAttributeType(GLenum enumValue); + +typedef std::vector InputLayout; + +struct VertexFormat : private angle::NonCopyable +{ + VertexFormat(GLenum typeIn, GLboolean normalizedIn, GLuint componentsIn, bool pureIntegerIn); + + GLenum type; + GLboolean normalized; + GLuint components; + bool pureInteger; +}; + +angle::FormatID GetVertexFormatID(VertexAttribType type, + GLboolean normalized, + GLuint components, + bool pureInteger); + +angle::FormatID GetVertexFormatID(const VertexAttribute &attrib, VertexAttribType currentValueType); +angle::FormatID GetCurrentValueFormatID(VertexAttribType currentValueType); +const VertexFormat &GetVertexFormatFromID(angle::FormatID vertexFormatID); +size_t GetVertexFormatSize(angle::FormatID vertexFormatID); +angle::FormatID ConvertFormatSignedness(const angle::Format &format); + +ANGLE_INLINE bool IsS3TCFormat(const GLenum format) +{ + switch (format) + { + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + return true; + + default: + return false; + } +} + +ANGLE_INLINE bool IsRGTCFormat(const GLenum format) +{ + switch (format) + { + case GL_COMPRESSED_RED_RGTC1_EXT: + case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT: + case GL_COMPRESSED_RED_GREEN_RGTC2_EXT: + case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT: + return true; + + default: + return false; + } +} + +ANGLE_INLINE bool IsBPTCFormat(const GLenum format) +{ + switch (format) + { + case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT: + case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT: + case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT: + case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT: + return true; + + default: + return false; + } +} + +ANGLE_INLINE bool IsASTC2DFormat(const GLenum format) +{ + if ((format >= GL_COMPRESSED_RGBA_ASTC_4x4_KHR && + format <= GL_COMPRESSED_RGBA_ASTC_12x12_KHR) || + (format >= GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR && + format <= GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR)) + { + return true; + } + return false; +} + +ANGLE_INLINE bool IsETC1Format(const GLenum format) +{ + switch (format) + { + case GL_ETC1_RGB8_OES: + return true; + + default: + return false; + } +} + +ANGLE_INLINE bool IsETC2EACFormat(const GLenum format) +{ + // ES 3.1, Table 8.19 + switch (format) + { + case GL_COMPRESSED_R11_EAC: + case GL_COMPRESSED_SIGNED_R11_EAC: + case GL_COMPRESSED_RG11_EAC: + case GL_COMPRESSED_SIGNED_RG11_EAC: + case GL_COMPRESSED_RGB8_ETC2: + case GL_COMPRESSED_SRGB8_ETC2: + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case GL_COMPRESSED_RGBA8_ETC2_EAC: + case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: + return true; + + default: + return false; + } +} + +ANGLE_INLINE bool IsPVRTC1Format(const GLenum format) +{ + switch (format) + { + case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG: + case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG: + case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: + case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: + case GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT: + case GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT: + return true; + + default: + return false; + } +} + +ANGLE_INLINE bool IsBGRAFormat(const GLenum internalFormat) +{ + switch (internalFormat) + { + case GL_BGRA8_EXT: + case GL_BGRA4_ANGLEX: + case GL_BGR5_A1_ANGLEX: + case GL_BGRA8_SRGB_ANGLEX: + case GL_BGRX8_ANGLEX: + case GL_RGBX8_ANGLE: + case GL_BGR565_ANGLEX: + case GL_BGR10_A2_ANGLEX: + return true; + + default: + return false; + } +} + +// Check if an internal format is ever valid in ES3. Makes no checks about support for a specific +// context. +bool ValidES3InternalFormat(GLenum internalFormat); + +// Implemented in format_map_autogen.cpp +bool ValidES3Format(GLenum format); +bool ValidES3Type(GLenum type); +bool ValidES3FormatCombination(GLenum format, GLenum type, GLenum internalFormat); + +// Implemented in format_map_desktop.cpp +bool ValidDesktopFormat(GLenum format); +bool ValidDesktopType(GLenum type); +bool ValidDesktopFormatCombination(GLenum format, GLenum type, GLenum internalFormat); + +// Implemented in es3_copy_conversion_table_autogen.cpp +bool ValidES3CopyConversion(GLenum textureFormat, GLenum framebufferFormat); + +ANGLE_INLINE ComponentType GetVertexAttributeComponentType(bool pureInteger, VertexAttribType type) +{ + if (pureInteger) + { + switch (type) + { + case VertexAttribType::Byte: + case VertexAttribType::Short: + case VertexAttribType::Int: + return ComponentType::Int; + + case VertexAttribType::UnsignedByte: + case VertexAttribType::UnsignedShort: + case VertexAttribType::UnsignedInt: + return ComponentType::UnsignedInt; + + default: + UNREACHABLE(); + return ComponentType::NoType; + } + } + else + { + return ComponentType::Float; + } +} + +constexpr std::size_t kMaxYuvPlaneCount = 3; +template +using YuvPlaneArray = std::array; + +struct YuvFormatInfo +{ + // Sized types only. + YuvFormatInfo(GLenum internalFormat, const Extents &yPlaneExtent); + + GLenum glInternalFormat; + uint32_t planeCount; + YuvPlaneArray planeBpp; + YuvPlaneArray planeExtent; + YuvPlaneArray planePitch; + YuvPlaneArray planeSize; + YuvPlaneArray planeOffset; +}; + +bool IsYuvFormat(GLenum format); +uint32_t GetPlaneCount(GLenum format); +uint32_t GetYPlaneBpp(GLenum format); +uint32_t GetChromaPlaneBpp(GLenum format); +void GetSubSampleFactor(GLenum format, + int *horizontalSubsampleFactor, + int *verticalSubsampleFactor); +} // namespace gl + +#endif // LIBANGLE_FORMATUTILS_H_ diff --git a/gfx/angle/checkout/src/libANGLE/gles_extensions_autogen.cpp b/gfx/angle/checkout/src/libANGLE/gles_extensions_autogen.cpp new file mode 100644 index 0000000000..0caab7e0d9 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/gles_extensions_autogen.cpp @@ -0,0 +1,278 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_extensions.py using data from registry_xml.py and gl.xml +// +// Copyright 2021 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// gles_extensions_autogen.h: GLES extension strings information. + +#include "anglebase/no_destructor.h" +#include "libANGLE/Caps.h" + +namespace gl +{ +const ExtensionInfoMap &GetExtensionInfoMap() +{ + auto buildExtensionInfoMap = []() { + auto enableableExtension = [](ExtensionBool member) { + ExtensionInfo info; + info.Requestable = true; + info.ExtensionsMember = member; + return info; + }; + + auto enableableDisablableExtension = [&](ExtensionBool member) { + ExtensionInfo info = enableableExtension(member); + info.Disablable = true; + return info; + }; + + auto esOnlyExtension = [](ExtensionBool member) { + ExtensionInfo info; + info.ExtensionsMember = member; + return info; + }; + + // clang-format off + ExtensionInfoMap map; + + // GLES 2.0 extension strings + // -------------------------- + map["GL_EXT_base_instance"] = enableableExtension(&Extensions::baseInstanceEXT); + map["GL_KHR_blend_equation_advanced"] = esOnlyExtension(&Extensions::blendEquationAdvancedKHR); + map["GL_EXT_blend_func_extended"] = enableableExtension(&Extensions::blendFuncExtendedEXT); + map["GL_EXT_blend_minmax"] = enableableExtension(&Extensions::blendMinmaxEXT); + map["GL_EXT_buffer_storage"] = enableableExtension(&Extensions::bufferStorageEXT); + map["GL_EXT_clip_control"] = enableableExtension(&Extensions::clipControlEXT); + map["GL_EXT_clip_cull_distance"] = enableableExtension(&Extensions::clipCullDistanceEXT); + map["GL_APPLE_clip_distance"] = enableableExtension(&Extensions::clipDistanceAPPLE); + map["GL_EXT_color_buffer_float"] = enableableExtension(&Extensions::colorBufferFloatEXT); + map["GL_EXT_color_buffer_half_float"] = enableableExtension(&Extensions::colorBufferHalfFloatEXT); + map["GL_OES_compressed_EAC_R11_signed_texture"] = enableableExtension(&Extensions::compressedEACR11SignedTextureOES); + map["GL_OES_compressed_EAC_R11_unsigned_texture"] = enableableExtension(&Extensions::compressedEACR11UnsignedTextureOES); + map["GL_OES_compressed_EAC_RG11_signed_texture"] = enableableExtension(&Extensions::compressedEACRG11SignedTextureOES); + map["GL_OES_compressed_EAC_RG11_unsigned_texture"] = enableableExtension(&Extensions::compressedEACRG11UnsignedTextureOES); + map["GL_EXT_compressed_ETC1_RGB8_sub_texture"] = enableableExtension(&Extensions::compressedETC1RGB8SubTextureEXT); + map["GL_OES_compressed_ETC1_RGB8_texture"] = enableableExtension(&Extensions::compressedETC1RGB8TextureOES); + map["GL_OES_compressed_ETC2_punchthroughA_RGBA8_texture"] = enableableExtension(&Extensions::compressedETC2PunchthroughARGBA8TextureOES); + map["GL_OES_compressed_ETC2_punchthroughA_sRGB8_alpha_texture"] = enableableExtension(&Extensions::compressedETC2PunchthroughASRGB8AlphaTextureOES); + map["GL_OES_compressed_ETC2_RGB8_texture"] = enableableExtension(&Extensions::compressedETC2RGB8TextureOES); + map["GL_OES_compressed_ETC2_RGBA8_texture"] = enableableExtension(&Extensions::compressedETC2RGBA8TextureOES); + map["GL_OES_compressed_ETC2_sRGB8_alpha8_texture"] = enableableExtension(&Extensions::compressedETC2SRGB8Alpha8TextureOES); + map["GL_OES_compressed_ETC2_sRGB8_texture"] = enableableExtension(&Extensions::compressedETC2SRGB8TextureOES); + map["GL_OES_compressed_paletted_texture"] = enableableExtension(&Extensions::compressedPalettedTextureOES); + map["GL_EXT_copy_image"] = enableableExtension(&Extensions::copyImageEXT); + map["GL_OES_copy_image"] = enableableExtension(&Extensions::copyImageOES); + map["GL_KHR_debug"] = esOnlyExtension(&Extensions::debugKHR); + map["GL_EXT_debug_label"] = esOnlyExtension(&Extensions::debugLabelEXT); + map["GL_EXT_debug_marker"] = esOnlyExtension(&Extensions::debugMarkerEXT); + map["GL_OES_depth24"] = esOnlyExtension(&Extensions::depth24OES); + map["GL_OES_depth32"] = esOnlyExtension(&Extensions::depth32OES); + map["GL_NV_depth_buffer_float2"] = enableableExtension(&Extensions::depthBufferFloat2NV); + map["GL_ANGLE_depth_texture"] = esOnlyExtension(&Extensions::depthTextureANGLE); + map["GL_OES_depth_texture"] = esOnlyExtension(&Extensions::depthTextureOES); + map["GL_OES_depth_texture_cube_map"] = enableableExtension(&Extensions::depthTextureCubeMapOES); + map["GL_EXT_discard_framebuffer"] = esOnlyExtension(&Extensions::discardFramebufferEXT); + map["GL_EXT_disjoint_timer_query"] = enableableExtension(&Extensions::disjointTimerQueryEXT); + map["GL_EXT_draw_buffers"] = enableableExtension(&Extensions::drawBuffersEXT); + map["GL_EXT_draw_buffers_indexed"] = enableableExtension(&Extensions::drawBuffersIndexedEXT); + map["GL_OES_draw_buffers_indexed"] = enableableExtension(&Extensions::drawBuffersIndexedOES); + map["GL_EXT_draw_elements_base_vertex"] = enableableExtension(&Extensions::drawElementsBaseVertexEXT); + map["GL_OES_draw_elements_base_vertex"] = enableableExtension(&Extensions::drawElementsBaseVertexOES); + map["GL_OES_EGL_image"] = enableableExtension(&Extensions::EGLImageOES); + map["GL_EXT_EGL_image_array"] = enableableExtension(&Extensions::EGLImageArrayEXT); + map["GL_OES_EGL_image_external"] = enableableExtension(&Extensions::EGLImageExternalOES); + map["GL_OES_EGL_image_external_essl3"] = enableableExtension(&Extensions::EGLImageExternalEssl3OES); + map["GL_EXT_EGL_image_external_wrap_modes"] = enableableExtension(&Extensions::EGLImageExternalWrapModesEXT); + map["GL_EXT_EGL_image_storage"] = enableableExtension(&Extensions::EGLImageStorageEXT); + map["GL_NV_EGL_stream_consumer_external"] = enableableExtension(&Extensions::EGLStreamConsumerExternalNV); + map["GL_OES_EGL_sync"] = esOnlyExtension(&Extensions::EGLSyncOES); + map["GL_OES_element_index_uint"] = enableableExtension(&Extensions::elementIndexUintOES); + map["GL_ANDROID_extension_pack_es31a"] = esOnlyExtension(&Extensions::extensionPackEs31aANDROID); + map["GL_EXT_external_buffer"] = enableableExtension(&Extensions::externalBufferEXT); + map["GL_OES_fbo_render_mipmap"] = enableableExtension(&Extensions::fboRenderMipmapOES); + map["GL_NV_fence"] = esOnlyExtension(&Extensions::fenceNV); + map["GL_EXT_float_blend"] = enableableExtension(&Extensions::floatBlendEXT); + map["GL_EXT_frag_depth"] = enableableExtension(&Extensions::fragDepthEXT); + map["GL_ANGLE_framebuffer_blit"] = enableableExtension(&Extensions::framebufferBlitANGLE); + map["GL_NV_framebuffer_blit"] = enableableExtension(&Extensions::framebufferBlitNV); + map["GL_MESA_framebuffer_flip_y"] = enableableExtension(&Extensions::framebufferFlipYMESA); + map["GL_EXT_geometry_shader"] = enableableExtension(&Extensions::geometryShaderEXT); + map["GL_OES_geometry_shader"] = enableableExtension(&Extensions::geometryShaderOES); + map["GL_OES_get_program_binary"] = enableableExtension(&Extensions::getProgramBinaryOES); + map["GL_EXT_gpu_shader5"] = enableableExtension(&Extensions::gpuShader5EXT); + map["GL_ANGLE_instanced_arrays"] = enableableExtension(&Extensions::instancedArraysANGLE); + map["GL_EXT_instanced_arrays"] = enableableExtension(&Extensions::instancedArraysEXT); + map["GL_OES_mapbuffer"] = enableableExtension(&Extensions::mapbufferOES); + map["GL_EXT_map_buffer_range"] = enableableExtension(&Extensions::mapBufferRangeEXT); + map["GL_EXT_memory_object"] = enableableExtension(&Extensions::memoryObjectEXT); + map["GL_EXT_memory_object_fd"] = enableableExtension(&Extensions::memoryObjectFdEXT); + map["GL_EXT_multi_draw_indirect"] = enableableExtension(&Extensions::multiDrawIndirectEXT); + map["GL_EXT_multisample_compatibility"] = esOnlyExtension(&Extensions::multisampleCompatibilityEXT); + map["GL_EXT_multisampled_render_to_texture"] = enableableExtension(&Extensions::multisampledRenderToTextureEXT); + map["GL_EXT_multisampled_render_to_texture2"] = enableableExtension(&Extensions::multisampledRenderToTexture2EXT); + map["GL_OVR_multiview"] = enableableExtension(&Extensions::multiviewOVR); + map["GL_OVR_multiview2"] = enableableExtension(&Extensions::multiview2OVR); + map["GL_KHR_no_error"] = esOnlyExtension(&Extensions::noErrorKHR); + map["GL_EXT_occlusion_query_boolean"] = enableableExtension(&Extensions::occlusionQueryBooleanEXT); + map["GL_OES_packed_depth_stencil"] = esOnlyExtension(&Extensions::packedDepthStencilOES); + map["GL_ANGLE_pack_reverse_row_order"] = enableableExtension(&Extensions::packReverseRowOrderANGLE); + map["GL_NV_pack_subimage"] = enableableExtension(&Extensions::packSubimageNV); + map["GL_KHR_parallel_shader_compile"] = enableableExtension(&Extensions::parallelShaderCompileKHR); + map["GL_AMD_performance_monitor"] = esOnlyExtension(&Extensions::performanceMonitorAMD); + map["GL_NV_pixel_buffer_object"] = enableableExtension(&Extensions::pixelBufferObjectNV); + map["GL_EXT_primitive_bounding_box"] = esOnlyExtension(&Extensions::primitiveBoundingBoxEXT); + map["GL_OES_primitive_bounding_box"] = esOnlyExtension(&Extensions::primitiveBoundingBoxOES); + map["GL_EXT_protected_textures"] = enableableExtension(&Extensions::protectedTexturesEXT); + map["GL_EXT_pvrtc_sRGB"] = enableableExtension(&Extensions::pvrtcSRGBEXT); + map["GL_NV_read_depth"] = enableableExtension(&Extensions::readDepthNV); + map["GL_NV_read_depth_stencil"] = enableableExtension(&Extensions::readDepthStencilNV); + map["GL_EXT_read_format_bgra"] = enableableExtension(&Extensions::readFormatBgraEXT); + map["GL_NV_read_stencil"] = enableableExtension(&Extensions::readStencilNV); + map["GL_OES_rgb8_rgba8"] = enableableExtension(&Extensions::rgb8Rgba8OES); + map["GL_KHR_robust_buffer_access_behavior"] = esOnlyExtension(&Extensions::robustBufferAccessBehaviorKHR); + map["GL_EXT_robustness"] = esOnlyExtension(&Extensions::robustnessEXT); + map["GL_NV_robustness_video_memory_purge"] = esOnlyExtension(&Extensions::robustnessVideoMemoryPurgeNV); + map["GL_OES_sample_shading"] = enableableExtension(&Extensions::sampleShadingOES); + map["GL_OES_sample_variables"] = enableableExtension(&Extensions::sampleVariablesOES); + map["GL_EXT_semaphore"] = enableableExtension(&Extensions::semaphoreEXT); + map["GL_EXT_semaphore_fd"] = enableableExtension(&Extensions::semaphoreFdEXT); + map["GL_EXT_separate_shader_objects"] = enableableExtension(&Extensions::separateShaderObjectsEXT); + map["GL_EXT_shader_framebuffer_fetch"] = enableableExtension(&Extensions::shaderFramebufferFetchEXT); + map["GL_EXT_shader_framebuffer_fetch_non_coherent"] = enableableExtension(&Extensions::shaderFramebufferFetchNonCoherentEXT); + map["GL_OES_shader_image_atomic"] = enableableExtension(&Extensions::shaderImageAtomicOES); + map["GL_EXT_shader_io_blocks"] = enableableExtension(&Extensions::shaderIoBlocksEXT); + map["GL_OES_shader_io_blocks"] = enableableExtension(&Extensions::shaderIoBlocksOES); + map["GL_OES_shader_multisample_interpolation"] = enableableExtension(&Extensions::shaderMultisampleInterpolationOES); + map["GL_EXT_shader_non_constant_global_initializers"] = enableableExtension(&Extensions::shaderNonConstantGlobalInitializersEXT); + map["GL_NV_shader_noperspective_interpolation"] = enableableExtension(&Extensions::shaderNoperspectiveInterpolationNV); + map["GL_EXT_shader_texture_lod"] = enableableExtension(&Extensions::shaderTextureLodEXT); + map["GL_QCOM_shading_rate"] = enableableExtension(&Extensions::shadingRateQCOM); + map["GL_EXT_shadow_samplers"] = enableableExtension(&Extensions::shadowSamplersEXT); + map["GL_EXT_sRGB"] = enableableExtension(&Extensions::sRGBEXT); + map["GL_EXT_sRGB_write_control"] = esOnlyExtension(&Extensions::sRGBWriteControlEXT); + map["GL_OES_standard_derivatives"] = enableableExtension(&Extensions::standardDerivativesOES); + map["GL_OES_surfaceless_context"] = esOnlyExtension(&Extensions::surfacelessContextOES); + map["GL_ARB_sync"] = enableableExtension(&Extensions::syncARB); + map["GL_EXT_tessellation_shader"] = enableableExtension(&Extensions::tessellationShaderEXT); + map["GL_OES_texture_3D"] = enableableExtension(&Extensions::texture3DOES); + map["GL_EXT_texture_border_clamp"] = enableableExtension(&Extensions::textureBorderClampEXT); + map["GL_OES_texture_border_clamp"] = enableableExtension(&Extensions::textureBorderClampOES); + map["GL_EXT_texture_buffer"] = enableableExtension(&Extensions::textureBufferEXT); + map["GL_OES_texture_buffer"] = enableableExtension(&Extensions::textureBufferOES); + map["GL_OES_texture_compression_astc"] = enableableExtension(&Extensions::textureCompressionAstcOES); + map["GL_KHR_texture_compression_astc_hdr"] = enableableExtension(&Extensions::textureCompressionAstcHdrKHR); + map["GL_KHR_texture_compression_astc_ldr"] = enableableExtension(&Extensions::textureCompressionAstcLdrKHR); + map["GL_KHR_texture_compression_astc_sliced_3d"] = enableableExtension(&Extensions::textureCompressionAstcSliced3dKHR); + map["GL_EXT_texture_compression_bptc"] = enableableExtension(&Extensions::textureCompressionBptcEXT); + map["GL_EXT_texture_compression_dxt1"] = enableableExtension(&Extensions::textureCompressionDxt1EXT); + map["GL_IMG_texture_compression_pvrtc"] = enableableExtension(&Extensions::textureCompressionPvrtcIMG); + map["GL_IMG_texture_compression_pvrtc2"] = enableableExtension(&Extensions::textureCompressionPvrtc2IMG); + map["GL_EXT_texture_compression_rgtc"] = enableableExtension(&Extensions::textureCompressionRgtcEXT); + map["GL_EXT_texture_compression_s3tc"] = enableableExtension(&Extensions::textureCompressionS3tcEXT); + map["GL_EXT_texture_compression_s3tc_srgb"] = enableableExtension(&Extensions::textureCompressionS3tcSrgbEXT); + map["GL_EXT_texture_cube_map_array"] = enableableExtension(&Extensions::textureCubeMapArrayEXT); + map["GL_OES_texture_cube_map_array"] = enableableExtension(&Extensions::textureCubeMapArrayOES); + map["GL_EXT_texture_filter_anisotropic"] = enableableExtension(&Extensions::textureFilterAnisotropicEXT); + map["GL_OES_texture_float"] = enableableExtension(&Extensions::textureFloatOES); + map["GL_OES_texture_float_linear"] = enableableExtension(&Extensions::textureFloatLinearOES); + map["GL_EXT_texture_format_BGRA8888"] = enableableExtension(&Extensions::textureFormatBGRA8888EXT); + map["GL_EXT_texture_format_sRGB_override"] = esOnlyExtension(&Extensions::textureFormatSRGBOverrideEXT); + map["GL_OES_texture_half_float"] = enableableExtension(&Extensions::textureHalfFloatOES); + map["GL_OES_texture_half_float_linear"] = enableableExtension(&Extensions::textureHalfFloatLinearOES); + map["GL_EXT_texture_norm16"] = enableableExtension(&Extensions::textureNorm16EXT); + map["GL_OES_texture_npot"] = enableableExtension(&Extensions::textureNpotOES); + map["GL_EXT_texture_rg"] = enableableExtension(&Extensions::textureRgEXT); + map["GL_EXT_texture_sRGB_decode"] = esOnlyExtension(&Extensions::textureSRGBDecodeEXT); + map["GL_EXT_texture_sRGB_R8"] = enableableExtension(&Extensions::textureSRGBR8EXT); + map["GL_EXT_texture_sRGB_RG8"] = enableableExtension(&Extensions::textureSRGBRG8EXT); + map["GL_OES_texture_stencil8"] = enableableExtension(&Extensions::textureStencil8OES); + map["GL_EXT_texture_storage"] = enableableExtension(&Extensions::textureStorageEXT); + map["GL_OES_texture_storage_multisample_2d_array"] = enableableExtension(&Extensions::textureStorageMultisample2dArrayOES); + map["GL_EXT_texture_type_2_10_10_10_REV"] = enableableExtension(&Extensions::textureType2101010REVEXT); + map["GL_ANGLE_texture_usage"] = enableableExtension(&Extensions::textureUsageANGLE); + map["GL_ANGLE_translated_shader_source"] = esOnlyExtension(&Extensions::translatedShaderSourceANGLE); + map["GL_EXT_unpack_subimage"] = enableableExtension(&Extensions::unpackSubimageEXT); + map["GL_OES_vertex_array_object"] = enableableExtension(&Extensions::vertexArrayObjectOES); + map["GL_OES_vertex_half_float"] = enableableExtension(&Extensions::vertexHalfFloatOES); + map["GL_OES_vertex_type_10_10_10_2"] = enableableExtension(&Extensions::vertexType1010102OES); + map["GL_WEBGL_video_texture"] = enableableExtension(&Extensions::videoTextureWEBGL); + map["GL_EXT_YUV_target"] = enableableExtension(&Extensions::YUVTargetEXT); + + // ANGLE unofficial extension strings + // ---------------------------------- + map["GL_ANGLE_base_vertex_base_instance"] = enableableExtension(&Extensions::baseVertexBaseInstanceANGLE); + map["GL_ANGLE_base_vertex_base_instance_shader_builtin"] = enableableExtension(&Extensions::baseVertexBaseInstanceShaderBuiltinANGLE); + map["GL_CHROMIUM_bind_generates_resource"] = esOnlyExtension(&Extensions::bindGeneratesResourceCHROMIUM); + map["GL_CHROMIUM_bind_uniform_location"] = esOnlyExtension(&Extensions::bindUniformLocationCHROMIUM); + map["GL_ANGLE_client_arrays"] = esOnlyExtension(&Extensions::clientArraysANGLE); + map["GL_CHROMIUM_color_buffer_float_rgb"] = enableableExtension(&Extensions::colorBufferFloatRgbCHROMIUM); + map["GL_CHROMIUM_color_buffer_float_rgba"] = enableableExtension(&Extensions::colorBufferFloatRgbaCHROMIUM); + map["GL_ANGLE_compressed_texture_etc"] = enableableExtension(&Extensions::compressedTextureEtcANGLE); + map["GL_CHROMIUM_copy_compressed_texture"] = esOnlyExtension(&Extensions::copyCompressedTextureCHROMIUM); + map["GL_CHROMIUM_copy_texture"] = esOnlyExtension(&Extensions::copyTextureCHROMIUM); + map["GL_ANGLE_copy_texture_3d"] = enableableExtension(&Extensions::copyTexture3dANGLE); + map["GL_CHROMIUM_framebuffer_mixed_samples"] = esOnlyExtension(&Extensions::framebufferMixedSamplesCHROMIUM); + map["GL_ANGLE_framebuffer_multisample"] = enableableExtension(&Extensions::framebufferMultisampleANGLE); + map["GL_ANGLE_get_image"] = enableableExtension(&Extensions::getImageANGLE); + map["GL_ANGLE_get_serialized_context_string"] = esOnlyExtension(&Extensions::getSerializedContextStringANGLE); + map["GL_ANGLE_get_tex_level_parameter"] = enableableExtension(&Extensions::getTexLevelParameterANGLE); + map["GL_ANGLE_logic_op"] = enableableExtension(&Extensions::logicOpANGLE); + map["GL_CHROMIUM_lose_context"] = enableableExtension(&Extensions::loseContextCHROMIUM); + map["GL_ANGLE_lossy_etc_decode"] = enableableExtension(&Extensions::lossyEtcDecodeANGLE); + map["GL_ANGLE_memory_object_flags"] = enableableExtension(&Extensions::memoryObjectFlagsANGLE); + map["GL_ANGLE_memory_object_fuchsia"] = enableableExtension(&Extensions::memoryObjectFuchsiaANGLE); + map["GL_ANGLE_memory_size"] = enableableExtension(&Extensions::memorySizeANGLE); + map["GL_ANGLE_multi_draw"] = enableableExtension(&Extensions::multiDrawANGLE); + map["GL_ANGLE_multiview_multisample"] = enableableExtension(&Extensions::multiviewMultisampleANGLE); + map["GL_ANGLE_program_binary"] = esOnlyExtension(&Extensions::programBinaryANGLE); + map["GL_ANGLE_program_cache_control"] = esOnlyExtension(&Extensions::programCacheControlANGLE); + map["GL_ANGLE_provoking_vertex"] = enableableExtension(&Extensions::provokingVertexANGLE); + map["GL_ANGLE_read_only_depth_stencil_feedback_loops"] = enableableExtension(&Extensions::readOnlyDepthStencilFeedbackLoopsANGLE); + map["GL_ANGLE_relaxed_vertex_attribute_type"] = esOnlyExtension(&Extensions::relaxedVertexAttributeTypeANGLE); + map["GL_ANGLE_request_extension"] = esOnlyExtension(&Extensions::requestExtensionANGLE); + map["GL_ANGLE_rgbx_internal_format"] = esOnlyExtension(&Extensions::rgbxInternalFormatANGLE); + map["GL_ANGLE_robust_client_memory"] = esOnlyExtension(&Extensions::robustClientMemoryANGLE); + map["GL_ANGLE_robust_fragment_shader_output"] = enableableExtension(&Extensions::robustFragmentShaderOutputANGLE); + map["GL_ANGLE_robust_resource_initialization"] = esOnlyExtension(&Extensions::robustResourceInitializationANGLE); + map["GL_ANGLE_semaphore_fuchsia"] = enableableExtension(&Extensions::semaphoreFuchsiaANGLE); + map["GL_ANGLE_shader_pixel_local_storage"] = esOnlyExtension(&Extensions::shaderPixelLocalStorageANGLE); + map["GL_ANGLE_shader_pixel_local_storage_coherent"] = esOnlyExtension(&Extensions::shaderPixelLocalStorageCoherentANGLE); + map["GL_CHROMIUM_sync_query"] = enableableExtension(&Extensions::syncQueryCHROMIUM); + map["GL_ANGLE_texture_compression_dxt3"] = enableableExtension(&Extensions::textureCompressionDxt3ANGLE); + map["GL_ANGLE_texture_compression_dxt5"] = enableableExtension(&Extensions::textureCompressionDxt5ANGLE); + map["GL_ANGLE_texture_external_update"] = enableableExtension(&Extensions::textureExternalUpdateANGLE); + map["GL_CHROMIUM_texture_filtering_hint"] = enableableExtension(&Extensions::textureFilteringHintCHROMIUM); + map["GL_ANGLE_texture_multisample"] = enableableExtension(&Extensions::textureMultisampleANGLE); + map["GL_ANGLE_texture_rectangle"] = enableableDisablableExtension(&Extensions::textureRectangleANGLE); + map["GL_ANGLE_vulkan_image"] = enableableExtension(&Extensions::vulkanImageANGLE); + map["GL_ANGLE_webgl_compatibility"] = esOnlyExtension(&Extensions::webglCompatibilityANGLE); + map["GL_ANGLE_yuv_internal_format"] = enableableExtension(&Extensions::yuvInternalFormatANGLE); + + // GLES 1.0 and 1.1 extension strings + // ---------------------------------- + map["GL_OES_draw_texture"] = enableableExtension(&Extensions::drawTextureOES); + map["GL_OES_framebuffer_object"] = enableableExtension(&Extensions::framebufferObjectOES); + map["GL_OES_matrix_palette"] = enableableExtension(&Extensions::matrixPaletteOES); + map["GL_OES_point_size_array"] = enableableExtension(&Extensions::pointSizeArrayOES); + map["GL_OES_point_sprite"] = enableableExtension(&Extensions::pointSpriteOES); + map["GL_OES_query_matrix"] = enableableExtension(&Extensions::queryMatrixOES); + map["GL_OES_texture_cube_map"] = enableableExtension(&Extensions::textureCubeMapOES); + // clang-format on + +#if defined(ANGLE_ENABLE_ASSERTS) + // Verify all extension strings start with GL_ + for (const auto &extension : map) + { + ASSERT(extension.first.rfind("GL_", 0) == 0); + } +#endif + + return map; + }; + + static const angle::base::NoDestructor extensionInfo(buildExtensionInfoMap()); + return *extensionInfo; +} +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/gles_extensions_autogen.h b/gfx/angle/checkout/src/libANGLE/gles_extensions_autogen.h new file mode 100644 index 0000000000..00994189a3 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/gles_extensions_autogen.h @@ -0,0 +1,727 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_extensions.py using data from registry_xml.py and gl.xml +// +// Copyright 2021 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// gles_extensions_autogen.h: GLES extension information. + +#ifndef LIBANGLE_GLES_EXTENSIONS_AUTOGEN_H_ +#define LIBANGLE_GLES_EXTENSIONS_AUTOGEN_H_ + +namespace gl +{ +class TextureCapsMap; + +struct Extensions +{ + Extensions(); + Extensions(const Extensions &other); + + Extensions &operator=(const Extensions &other); + + // Generate a vector of supported extension strings + std::vector getStrings() const; + + // Set all texture related extension support based on the supported textures. + // Determines support for: + // GL_OES_packed_depth_stencil + // GL_OES_rgb8_rgba8 + // GL_EXT_texture_format_BGRA8888 + // GL_EXT_color_buffer_half_float, + // GL_OES_texture_half_float, GL_OES_texture_half_float_linear + // GL_OES_texture_float, GL_OES_texture_float_linear + // GL_EXT_texture_rg + // GL_EXT_texture_type_2_10_10_10_REV + // GL_EXT_texture_compression_dxt1, GL_ANGLE_texture_compression_dxt3, + // GL_ANGLE_texture_compression_dxt5 + // GL_KHR_texture_compression_astc_ldr, GL_OES_texture_compression_astc. + // NOTE: GL_KHR_texture_compression_astc_hdr must be enabled separately. Support for the + // HDR profile cannot be determined from the format enums alone. + // GL_OES_compressed_ETC1_RGB8_texture + // GL_EXT_sRGB + // GL_ANGLE_depth_texture, GL_OES_depth32 + // GL_EXT_color_buffer_float + // GL_EXT_texture_norm16 + // GL_EXT_texture_compression_bptc + // GL_EXT_texture_compression_rgtc + void setTextureExtensionSupport(const TextureCapsMap &textureCaps); + + // Helper functions + bool copyImageAny() const { return (copyImageEXT || copyImageOES); } + bool depthTextureAny() const { return (depthTextureANGLE || depthTextureOES); } + bool drawBuffersIndexedAny() const { return (drawBuffersIndexedEXT || drawBuffersIndexedOES); } + bool drawElementsBaseVertexAny() const + { + return (drawElementsBaseVertexEXT || drawElementsBaseVertexOES); + } + bool framebufferBlitAny() const { return (framebufferBlitANGLE || framebufferBlitNV); } + bool geometryShaderAny() const { return (geometryShaderEXT || geometryShaderOES); } + bool instancedArraysAny() const { return (instancedArraysANGLE || instancedArraysEXT); } + bool primitiveBoundingBoxAny() const + { + return (primitiveBoundingBoxEXT || primitiveBoundingBoxOES); + } + bool shaderIoBlocksAny() const { return (shaderIoBlocksEXT || shaderIoBlocksOES); } + bool textureBorderClampAny() const { return (textureBorderClampEXT || textureBorderClampOES); } + bool textureBufferAny() const { return (textureBufferEXT || textureBufferOES); } + bool textureCubeMapArrayAny() const + { + return (textureCubeMapArrayEXT || textureCubeMapArrayOES); + } + + // GLES 2.0+ extensions + // -------------------- + + // GL_EXT_base_instance + bool baseInstanceEXT = false; + + // GL_KHR_blend_equation_advanced + bool blendEquationAdvancedKHR = false; + + // GL_EXT_blend_func_extended + bool blendFuncExtendedEXT = false; + + // GL_EXT_blend_minmax + bool blendMinmaxEXT = false; + + // GL_EXT_buffer_storage + bool bufferStorageEXT = false; + + // GL_EXT_clip_control + bool clipControlEXT = false; + + // GL_EXT_clip_cull_distance + bool clipCullDistanceEXT = false; + + // GL_APPLE_clip_distance + bool clipDistanceAPPLE = false; + + // GL_EXT_color_buffer_float + bool colorBufferFloatEXT = false; + + // GL_EXT_color_buffer_half_float + bool colorBufferHalfFloatEXT = false; + + // GL_OES_compressed_EAC_R11_signed_texture + bool compressedEACR11SignedTextureOES = false; + + // GL_OES_compressed_EAC_R11_unsigned_texture + bool compressedEACR11UnsignedTextureOES = false; + + // GL_OES_compressed_EAC_RG11_signed_texture + bool compressedEACRG11SignedTextureOES = false; + + // GL_OES_compressed_EAC_RG11_unsigned_texture + bool compressedEACRG11UnsignedTextureOES = false; + + // GL_EXT_compressed_ETC1_RGB8_sub_texture + bool compressedETC1RGB8SubTextureEXT = false; + + // GL_OES_compressed_ETC1_RGB8_texture + bool compressedETC1RGB8TextureOES = false; + + // GL_OES_compressed_ETC2_punchthroughA_RGBA8_texture + bool compressedETC2PunchthroughARGBA8TextureOES = false; + + // GL_OES_compressed_ETC2_punchthroughA_sRGB8_alpha_texture + bool compressedETC2PunchthroughASRGB8AlphaTextureOES = false; + + // GL_OES_compressed_ETC2_RGB8_texture + bool compressedETC2RGB8TextureOES = false; + + // GL_OES_compressed_ETC2_RGBA8_texture + bool compressedETC2RGBA8TextureOES = false; + + // GL_OES_compressed_ETC2_sRGB8_alpha8_texture + bool compressedETC2SRGB8Alpha8TextureOES = false; + + // GL_OES_compressed_ETC2_sRGB8_texture + bool compressedETC2SRGB8TextureOES = false; + + // GL_OES_compressed_paletted_texture + bool compressedPalettedTextureOES = false; + + // GL_EXT_copy_image + bool copyImageEXT = false; + + // GL_OES_copy_image + bool copyImageOES = false; + + // GL_KHR_debug + bool debugKHR = false; + + // GL_EXT_debug_label + bool debugLabelEXT = false; + + // GL_EXT_debug_marker + bool debugMarkerEXT = false; + + // GL_OES_depth24 + bool depth24OES = false; + + // GL_OES_depth32 + bool depth32OES = false; + + // GL_NV_depth_buffer_float2 + bool depthBufferFloat2NV = false; + + // GL_ANGLE_depth_texture + bool depthTextureANGLE = false; + + // GL_OES_depth_texture + bool depthTextureOES = false; + + // GL_OES_depth_texture_cube_map + bool depthTextureCubeMapOES = false; + + // GL_EXT_discard_framebuffer + bool discardFramebufferEXT = false; + + // GL_EXT_disjoint_timer_query + bool disjointTimerQueryEXT = false; + + // GL_EXT_draw_buffers + bool drawBuffersEXT = false; + + // GL_EXT_draw_buffers_indexed + bool drawBuffersIndexedEXT = false; + + // GL_OES_draw_buffers_indexed + bool drawBuffersIndexedOES = false; + + // GL_EXT_draw_elements_base_vertex + bool drawElementsBaseVertexEXT = false; + + // GL_OES_draw_elements_base_vertex + bool drawElementsBaseVertexOES = false; + + // GL_OES_EGL_image + bool EGLImageOES = false; + + // GL_EXT_EGL_image_array + bool EGLImageArrayEXT = false; + + // GL_OES_EGL_image_external + bool EGLImageExternalOES = false; + + // GL_OES_EGL_image_external_essl3 + bool EGLImageExternalEssl3OES = false; + + // GL_EXT_EGL_image_external_wrap_modes + bool EGLImageExternalWrapModesEXT = false; + + // GL_EXT_EGL_image_storage + bool EGLImageStorageEXT = false; + + // GL_NV_EGL_stream_consumer_external + bool EGLStreamConsumerExternalNV = false; + + // GL_OES_EGL_sync + bool EGLSyncOES = false; + + // GL_OES_element_index_uint + bool elementIndexUintOES = false; + + // GL_ANDROID_extension_pack_es31a + bool extensionPackEs31aANDROID = false; + + // GL_EXT_external_buffer + bool externalBufferEXT = false; + + // GL_OES_fbo_render_mipmap + bool fboRenderMipmapOES = false; + + // GL_NV_fence + bool fenceNV = false; + + // GL_EXT_float_blend + bool floatBlendEXT = false; + + // GL_EXT_frag_depth + bool fragDepthEXT = false; + + // GL_ANGLE_framebuffer_blit + bool framebufferBlitANGLE = false; + + // GL_NV_framebuffer_blit + bool framebufferBlitNV = false; + + // GL_MESA_framebuffer_flip_y + bool framebufferFlipYMESA = false; + + // GL_EXT_geometry_shader + bool geometryShaderEXT = false; + + // GL_OES_geometry_shader + bool geometryShaderOES = false; + + // GL_OES_get_program_binary + bool getProgramBinaryOES = false; + + // GL_EXT_gpu_shader5 + bool gpuShader5EXT = false; + + // GL_ANGLE_instanced_arrays + bool instancedArraysANGLE = false; + + // GL_EXT_instanced_arrays + bool instancedArraysEXT = false; + + // GL_OES_mapbuffer + bool mapbufferOES = false; + + // GL_EXT_map_buffer_range + bool mapBufferRangeEXT = false; + + // GL_EXT_memory_object + bool memoryObjectEXT = false; + + // GL_EXT_memory_object_fd + bool memoryObjectFdEXT = false; + + // GL_EXT_multi_draw_indirect + bool multiDrawIndirectEXT = false; + + // GL_EXT_multisample_compatibility + bool multisampleCompatibilityEXT = false; + + // GL_EXT_multisampled_render_to_texture + bool multisampledRenderToTextureEXT = false; + + // GL_EXT_multisampled_render_to_texture2 + bool multisampledRenderToTexture2EXT = false; + + // GL_OVR_multiview + bool multiviewOVR = false; + + // GL_OVR_multiview2 + bool multiview2OVR = false; + + // GL_KHR_no_error + bool noErrorKHR = false; + + // GL_EXT_occlusion_query_boolean + bool occlusionQueryBooleanEXT = false; + + // GL_OES_packed_depth_stencil + bool packedDepthStencilOES = false; + + // GL_ANGLE_pack_reverse_row_order + bool packReverseRowOrderANGLE = false; + + // GL_NV_pack_subimage + bool packSubimageNV = false; + + // GL_KHR_parallel_shader_compile + bool parallelShaderCompileKHR = false; + + // GL_AMD_performance_monitor + bool performanceMonitorAMD = false; + + // GL_NV_pixel_buffer_object + bool pixelBufferObjectNV = false; + + // GL_EXT_primitive_bounding_box + bool primitiveBoundingBoxEXT = false; + + // GL_OES_primitive_bounding_box + bool primitiveBoundingBoxOES = false; + + // GL_EXT_protected_textures + bool protectedTexturesEXT = false; + + // GL_EXT_pvrtc_sRGB + bool pvrtcSRGBEXT = false; + + // GL_NV_read_depth + bool readDepthNV = false; + + // GL_NV_read_depth_stencil + bool readDepthStencilNV = false; + + // GL_EXT_read_format_bgra + bool readFormatBgraEXT = false; + + // GL_NV_read_stencil + bool readStencilNV = false; + + // GL_OES_rgb8_rgba8 + bool rgb8Rgba8OES = false; + + // GL_KHR_robust_buffer_access_behavior + bool robustBufferAccessBehaviorKHR = false; + + // GL_EXT_robustness + bool robustnessEXT = false; + + // GL_NV_robustness_video_memory_purge + bool robustnessVideoMemoryPurgeNV = false; + + // GL_OES_sample_shading + bool sampleShadingOES = false; + + // GL_OES_sample_variables + bool sampleVariablesOES = false; + + // GL_EXT_semaphore + bool semaphoreEXT = false; + + // GL_EXT_semaphore_fd + bool semaphoreFdEXT = false; + + // GL_EXT_separate_shader_objects + bool separateShaderObjectsEXT = false; + + // GL_EXT_shader_framebuffer_fetch + bool shaderFramebufferFetchEXT = false; + + // GL_EXT_shader_framebuffer_fetch_non_coherent + bool shaderFramebufferFetchNonCoherentEXT = false; + + // GL_OES_shader_image_atomic + bool shaderImageAtomicOES = false; + + // GL_EXT_shader_io_blocks + bool shaderIoBlocksEXT = false; + + // GL_OES_shader_io_blocks + bool shaderIoBlocksOES = false; + + // GL_OES_shader_multisample_interpolation + bool shaderMultisampleInterpolationOES = false; + + // GL_EXT_shader_non_constant_global_initializers + bool shaderNonConstantGlobalInitializersEXT = false; + + // GL_NV_shader_noperspective_interpolation + bool shaderNoperspectiveInterpolationNV = false; + + // GL_EXT_shader_texture_lod + bool shaderTextureLodEXT = false; + + // GL_QCOM_shading_rate + bool shadingRateQCOM = false; + + // GL_EXT_shadow_samplers + bool shadowSamplersEXT = false; + + // GL_EXT_sRGB + bool sRGBEXT = false; + + // GL_EXT_sRGB_write_control + bool sRGBWriteControlEXT = false; + + // GL_OES_standard_derivatives + bool standardDerivativesOES = false; + + // GL_OES_surfaceless_context + bool surfacelessContextOES = false; + + // GL_ARB_sync + bool syncARB = false; + + // GL_EXT_tessellation_shader + bool tessellationShaderEXT = false; + + // GL_OES_texture_3D + bool texture3DOES = false; + + // GL_EXT_texture_border_clamp + bool textureBorderClampEXT = false; + + // GL_OES_texture_border_clamp + bool textureBorderClampOES = false; + + // GL_EXT_texture_buffer + bool textureBufferEXT = false; + + // GL_OES_texture_buffer + bool textureBufferOES = false; + + // GL_OES_texture_compression_astc + bool textureCompressionAstcOES = false; + + // GL_KHR_texture_compression_astc_hdr + bool textureCompressionAstcHdrKHR = false; + + // GL_KHR_texture_compression_astc_ldr + bool textureCompressionAstcLdrKHR = false; + + // GL_KHR_texture_compression_astc_sliced_3d + bool textureCompressionAstcSliced3dKHR = false; + + // GL_EXT_texture_compression_bptc + bool textureCompressionBptcEXT = false; + + // GL_EXT_texture_compression_dxt1 + bool textureCompressionDxt1EXT = false; + + // GL_IMG_texture_compression_pvrtc + bool textureCompressionPvrtcIMG = false; + + // GL_IMG_texture_compression_pvrtc2 + bool textureCompressionPvrtc2IMG = false; + + // GL_EXT_texture_compression_rgtc + bool textureCompressionRgtcEXT = false; + + // GL_EXT_texture_compression_s3tc + bool textureCompressionS3tcEXT = false; + + // GL_EXT_texture_compression_s3tc_srgb + bool textureCompressionS3tcSrgbEXT = false; + + // GL_EXT_texture_cube_map_array + bool textureCubeMapArrayEXT = false; + + // GL_OES_texture_cube_map_array + bool textureCubeMapArrayOES = false; + + // GL_EXT_texture_filter_anisotropic + bool textureFilterAnisotropicEXT = false; + + // GL_OES_texture_float + bool textureFloatOES = false; + + // GL_OES_texture_float_linear + bool textureFloatLinearOES = false; + + // GL_EXT_texture_format_BGRA8888 + bool textureFormatBGRA8888EXT = false; + + // GL_EXT_texture_format_sRGB_override + bool textureFormatSRGBOverrideEXT = false; + + // GL_OES_texture_half_float + bool textureHalfFloatOES = false; + + // GL_OES_texture_half_float_linear + bool textureHalfFloatLinearOES = false; + + // GL_EXT_texture_norm16 + bool textureNorm16EXT = false; + + // GL_OES_texture_npot + bool textureNpotOES = false; + + // GL_EXT_texture_rg + bool textureRgEXT = false; + + // GL_EXT_texture_sRGB_decode + bool textureSRGBDecodeEXT = false; + + // GL_EXT_texture_sRGB_R8 + bool textureSRGBR8EXT = false; + + // GL_EXT_texture_sRGB_RG8 + bool textureSRGBRG8EXT = false; + + // GL_OES_texture_stencil8 + bool textureStencil8OES = false; + + // GL_EXT_texture_storage + bool textureStorageEXT = false; + + // GL_OES_texture_storage_multisample_2d_array + bool textureStorageMultisample2dArrayOES = false; + + // GL_EXT_texture_type_2_10_10_10_REV + bool textureType2101010REVEXT = false; + + // GL_ANGLE_texture_usage + bool textureUsageANGLE = false; + + // GL_ANGLE_translated_shader_source + bool translatedShaderSourceANGLE = false; + + // GL_EXT_unpack_subimage + bool unpackSubimageEXT = false; + + // GL_OES_vertex_array_object + bool vertexArrayObjectOES = false; + + // GL_OES_vertex_half_float + bool vertexHalfFloatOES = false; + + // GL_OES_vertex_type_10_10_10_2 + bool vertexType1010102OES = false; + + // GL_WEBGL_video_texture + bool videoTextureWEBGL = false; + + // GL_EXT_YUV_target + bool YUVTargetEXT = false; + + // ANGLE unofficial extensions + // --------------------------- + + // GL_ANGLE_base_vertex_base_instance + bool baseVertexBaseInstanceANGLE = false; + + // GL_ANGLE_base_vertex_base_instance_shader_builtin + bool baseVertexBaseInstanceShaderBuiltinANGLE = false; + + // GL_CHROMIUM_bind_generates_resource + bool bindGeneratesResourceCHROMIUM = false; + + // GL_CHROMIUM_bind_uniform_location + bool bindUniformLocationCHROMIUM = false; + + // GL_ANGLE_client_arrays + bool clientArraysANGLE = false; + + // GL_CHROMIUM_color_buffer_float_rgb + bool colorBufferFloatRgbCHROMIUM = false; + + // GL_CHROMIUM_color_buffer_float_rgba + bool colorBufferFloatRgbaCHROMIUM = false; + + // GL_ANGLE_compressed_texture_etc + bool compressedTextureEtcANGLE = false; + + // GL_CHROMIUM_copy_compressed_texture + bool copyCompressedTextureCHROMIUM = false; + + // GL_CHROMIUM_copy_texture + bool copyTextureCHROMIUM = false; + + // GL_ANGLE_copy_texture_3d + bool copyTexture3dANGLE = false; + + // GL_CHROMIUM_framebuffer_mixed_samples + bool framebufferMixedSamplesCHROMIUM = false; + + // GL_ANGLE_framebuffer_multisample + bool framebufferMultisampleANGLE = false; + + // GL_ANGLE_get_image + bool getImageANGLE = false; + + // GL_ANGLE_get_serialized_context_string + bool getSerializedContextStringANGLE = false; + + // GL_ANGLE_get_tex_level_parameter + bool getTexLevelParameterANGLE = false; + + // GL_ANGLE_logic_op + bool logicOpANGLE = false; + + // GL_CHROMIUM_lose_context + bool loseContextCHROMIUM = false; + + // GL_ANGLE_lossy_etc_decode + bool lossyEtcDecodeANGLE = false; + + // GL_ANGLE_memory_object_flags + bool memoryObjectFlagsANGLE = false; + + // GL_ANGLE_memory_object_fuchsia + bool memoryObjectFuchsiaANGLE = false; + + // GL_ANGLE_memory_size + bool memorySizeANGLE = false; + + // GL_ANGLE_multi_draw + bool multiDrawANGLE = false; + + // GL_ANGLE_multiview_multisample + bool multiviewMultisampleANGLE = false; + + // GL_ANGLE_program_binary + bool programBinaryANGLE = false; + + // GL_ANGLE_program_cache_control + bool programCacheControlANGLE = false; + + // GL_ANGLE_provoking_vertex + bool provokingVertexANGLE = false; + + // GL_ANGLE_read_only_depth_stencil_feedback_loops + bool readOnlyDepthStencilFeedbackLoopsANGLE = false; + + // GL_ANGLE_relaxed_vertex_attribute_type + bool relaxedVertexAttributeTypeANGLE = false; + + // GL_ANGLE_request_extension + bool requestExtensionANGLE = false; + + // GL_ANGLE_rgbx_internal_format + bool rgbxInternalFormatANGLE = false; + + // GL_ANGLE_robust_client_memory + bool robustClientMemoryANGLE = false; + + // GL_ANGLE_robust_fragment_shader_output + bool robustFragmentShaderOutputANGLE = false; + + // GL_ANGLE_robust_resource_initialization + bool robustResourceInitializationANGLE = false; + + // GL_ANGLE_semaphore_fuchsia + bool semaphoreFuchsiaANGLE = false; + + // GL_ANGLE_shader_pixel_local_storage + bool shaderPixelLocalStorageANGLE = false; + + // GL_ANGLE_shader_pixel_local_storage_coherent + bool shaderPixelLocalStorageCoherentANGLE = false; + + // GL_CHROMIUM_sync_query + bool syncQueryCHROMIUM = false; + + // GL_ANGLE_texture_compression_dxt3 + bool textureCompressionDxt3ANGLE = false; + + // GL_ANGLE_texture_compression_dxt5 + bool textureCompressionDxt5ANGLE = false; + + // GL_ANGLE_texture_external_update + bool textureExternalUpdateANGLE = false; + + // GL_CHROMIUM_texture_filtering_hint + bool textureFilteringHintCHROMIUM = false; + + // GL_ANGLE_texture_multisample + bool textureMultisampleANGLE = false; + + // GL_ANGLE_texture_rectangle + bool textureRectangleANGLE = false; + + // GL_ANGLE_vulkan_image + bool vulkanImageANGLE = false; + + // GL_ANGLE_webgl_compatibility + bool webglCompatibilityANGLE = false; + + // GL_ANGLE_yuv_internal_format + bool yuvInternalFormatANGLE = false; + + // GLES 1.0 and 1.1 extensions + // --------------------------- + + // GL_OES_draw_texture + bool drawTextureOES = false; + + // GL_OES_framebuffer_object + bool framebufferObjectOES = false; + + // GL_OES_matrix_palette + bool matrixPaletteOES = false; + + // GL_OES_point_size_array + bool pointSizeArrayOES = false; + + // GL_OES_point_sprite + bool pointSpriteOES = false; + + // GL_OES_query_matrix + bool queryMatrixOES = false; + + // GL_OES_texture_cube_map + bool textureCubeMapOES = false; +}; +} // namespace gl + +#endif // LIBANGLE_GLES_EXTENSIONS_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/histogram_macros.h b/gfx/angle/checkout/src/libANGLE/histogram_macros.h new file mode 100644 index 0000000000..cf27a895a1 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/histogram_macros.h @@ -0,0 +1,110 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// histogram_macros.h: +// Helpers for making histograms, to keep consistency with Chromium's +// histogram_macros.h. + +#ifndef LIBANGLE_HISTOGRAM_MACROS_H_ +#define LIBANGLE_HISTOGRAM_MACROS_H_ + +#include + +#define ANGLE_HISTOGRAM_TIMES(name, sample) ANGLE_HISTOGRAM_CUSTOM_TIMES(name, sample, 1, 10000, 50) + +#define ANGLE_HISTOGRAM_MEDIUM_TIMES(name, sample) \ + ANGLE_HISTOGRAM_CUSTOM_TIMES(name, sample, 10, 180000, 50) + +// Use this macro when times can routinely be much longer than 10 seconds. +#define ANGLE_HISTOGRAM_LONG_TIMES(name, sample) \ + ANGLE_HISTOGRAM_CUSTOM_TIMES(name, sample, 1, 3600000, 50) + +// Use this macro when times can routinely be much longer than 10 seconds and +// you want 100 buckets. +#define ANGLE_HISTOGRAM_LONG_TIMES_100(name, sample) \ + ANGLE_HISTOGRAM_CUSTOM_TIMES(name, sample, 1, 3600000, 100) + +// For folks that need real specific times, use this to select a precise range +// of times you want plotted, and the number of buckets you want used. +#define ANGLE_HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) \ + ANGLE_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) + +#define ANGLE_HISTOGRAM_COUNTS(name, sample) \ + ANGLE_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, 1000000, 50) + +#define ANGLE_HISTOGRAM_COUNTS_100(name, sample) \ + ANGLE_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, 100, 50) + +#define ANGLE_HISTOGRAM_COUNTS_10000(name, sample) \ + ANGLE_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, 10000, 50) + +#define ANGLE_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) \ + ANGLEPlatformCurrent()->histogramCustomCounts(ANGLEPlatformCurrent(), name, sample, min, max, \ + bucket_count) + +#define ANGLE_HISTOGRAM_PERCENTAGE(name, under_one_hundred) \ + ANGLE_HISTOGRAM_ENUMERATION(name, under_one_hundred, 101) + +#define ANGLE_HISTOGRAM_BOOLEAN(name, sample) \ + ANGLEPlatformCurrent()->histogramBoolean(ANGLEPlatformCurrent(), name, sample) + +#define ANGLE_HISTOGRAM_ENUMERATION(name, sample, boundary_value) \ + ANGLEPlatformCurrent()->histogramEnumeration(ANGLEPlatformCurrent(), name, sample, \ + boundary_value) + +#define ANGLE_HISTOGRAM_MEMORY_KB(name, sample) \ + ANGLE_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1000, 500000, 50) + +#define ANGLE_HISTOGRAM_MEMORY_MB(name, sample) \ + ANGLE_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, 1000, 50) + +#define ANGLE_HISTOGRAM_SPARSE_SLOWLY(name, sample) \ + ANGLEPlatformCurrent()->histogramSparse(ANGLEPlatformCurrent(), name, sample) + +// Scoped class which logs its time on this earth as a UMA statistic. This is +// recommended for when you want a histogram which measures the time it takes +// for a method to execute. This measures up to 10 seconds. +#define SCOPED_ANGLE_HISTOGRAM_TIMER(name) \ + SCOPED_ANGLE_HISTOGRAM_TIMER_EXPANDER(name, false, __COUNTER__) + +// Similar scoped histogram timer, but this uses ANGLE_HISTOGRAM_LONG_TIMES_100, +// which measures up to an hour, and uses 100 buckets. This is more expensive +// to store, so only use if this often takes >10 seconds. +#define SCOPED_ANGLE_HISTOGRAM_LONG_TIMER(name) \ + SCOPED_ANGLE_HISTOGRAM_TIMER_EXPANDER(name, true, __COUNTER__) + +// This nested macro is necessary to expand __COUNTER__ to an actual value. +#define SCOPED_ANGLE_HISTOGRAM_TIMER_EXPANDER(name, is_long, key) \ + SCOPED_ANGLE_HISTOGRAM_TIMER_UNIQUE(name, is_long, key) + +#define SCOPED_ANGLE_HISTOGRAM_TIMER_UNIQUE(name, is_long, key) \ + class [[nodiscard]] ScopedHistogramTimer##key \ + { \ + public: \ + ScopedHistogramTimer##key() \ + : constructed_(ANGLEPlatformCurrent()->currentTime(ANGLEPlatformCurrent())) \ + {} \ + ~ScopedHistogramTimer##key() \ + { \ + if (constructed_ == 0) \ + return; \ + auto *platform = ANGLEPlatformCurrent(); \ + double elapsed = platform->currentTime(platform) - constructed_; \ + int elapsedMS = static_cast(elapsed * 1000.0); \ + if (is_long) \ + { \ + ANGLE_HISTOGRAM_LONG_TIMES_100(name, elapsedMS); \ + } \ + else \ + { \ + ANGLE_HISTOGRAM_TIMES(name, elapsedMS); \ + } \ + } \ + \ + private: \ + double constructed_; \ + } scoped_histogram_timer_##key + +#endif // LIBANGLE_HISTOGRAM_MACROS_H_ diff --git a/gfx/angle/checkout/src/libANGLE/queryconversions.cpp b/gfx/angle/checkout/src/libANGLE/queryconversions.cpp new file mode 100644 index 0000000000..3c3ab45b7c --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/queryconversions.cpp @@ -0,0 +1,315 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// queryconversions.cpp: Implementation of state query cast conversions + +#include "libANGLE/queryconversions.h" + +#include + +#include "common/utilities.h" +#include "libANGLE/Context.h" + +namespace gl +{ + +namespace +{ + +GLint64 ExpandFloatToInteger(GLfloat value) +{ + return static_cast((static_cast(0xFFFFFFFFULL) * value - 1.0) / 2.0); +} + +template +QueryT CastFromStateValueToInt(GLenum pname, NativeT value) +{ + GLenum nativeType = GLTypeToGLenum::value; + + if (nativeType == GL_FLOAT) + { + // RGBA color values and DepthRangeF values are converted to integer using Equation 2.4 from + // Table 4.5 + switch (pname) + { + case GL_DEPTH_RANGE: + case GL_COLOR_CLEAR_VALUE: + case GL_DEPTH_CLEAR_VALUE: + case GL_BLEND_COLOR: + // GLES1 emulation: + // Also, several GLES1.x values need to be converted to integer with + // ExpandFloatToInteger rather than rounding. See GLES 1.1 spec 6.1.2 "Data + // Conversions". + case GL_ALPHA_TEST_REF: + case GL_CURRENT_COLOR: + return clampCast(ExpandFloatToInteger(static_cast(value))); + default: + return clampCast(std::round(value)); + } + } + + return clampCast(value); +} + +template +NativeT CastQueryValueToInt(GLenum pname, QueryT value) +{ + GLenum queryType = GLTypeToGLenum::value; + + if (queryType == GL_FLOAT) + { + // ARM devices cast float to uint differently than Intel. + // Basically, any negative floating point number becomes 0 + // when converted to unsigned int. Instead, convert to a signed + // int and then convert to unsigned int to "preserve the value" + // E.g. common case for tests is to pass in -1 as an invalid query + // value. If cast to a unsigned int it becomes 0 (GL_NONE) and is now + // a valid enum and negative tests fail. But converting to int + // and then to final unsigned int gives us 4294967295 (0xffffffff) + // which is what we want. + return static_cast(static_cast(std::round(value))); + } + + return static_cast(value); +} + +} // anonymous namespace + +GLint CastMaskValue(GLuint value) +{ + return clampCast(value); +} + +template +QueryT CastFromGLintStateValue(GLenum pname, InternalT value) +{ + return CastFromStateValue(pname, clampCast(value)); +} + +template GLfloat CastFromGLintStateValue(GLenum pname, GLenum value); +template GLint CastFromGLintStateValue(GLenum pname, GLenum value); +template GLint64 CastFromGLintStateValue(GLenum pname, GLenum value); +template GLuint CastFromGLintStateValue(GLenum pname, GLenum value); +template GLuint CastFromGLintStateValue(GLenum pname, GLint value); +template GLfloat CastFromGLintStateValue(GLenum pname, GLint value); +template GLint CastFromGLintStateValue(GLenum pname, GLint value); +template GLfloat CastFromGLintStateValue(GLenum pname, bool value); +template GLuint CastFromGLintStateValue(GLenum pname, bool value); +template GLint CastFromGLintStateValue(GLenum pname, bool value); + +template +QueryT CastFromStateValue(GLenum pname, NativeT value) +{ + GLenum queryType = GLTypeToGLenum::value; + + switch (queryType) + { + case GL_INT: + case GL_INT_64_ANGLEX: + case GL_UNSIGNED_INT: + case GL_UINT_64_ANGLEX: + return CastFromStateValueToInt(pname, value); + case GL_FLOAT: + return static_cast(value); + case GL_BOOL: + return static_cast(value == static_cast(0) ? GL_FALSE : GL_TRUE); + default: + UNREACHABLE(); + return 0; + } +} +template GLint CastFromStateValue(GLenum pname, GLint value); +template GLint CastFromStateValue(GLenum pname, GLint64 value); +template GLint64 CastFromStateValue(GLenum pname, GLint value); +template GLint64 CastFromStateValue(GLenum pname, GLint64 value); +template GLfloat CastFromStateValue(GLenum pname, GLint value); +template GLfloat CastFromStateValue(GLenum pname, GLuint value); +template GLfloat CastFromStateValue(GLenum pname, GLfloat value); +template GLint CastFromStateValue(GLenum pname, GLfloat value); +template GLuint CastFromStateValue(GLenum pname, GLfloat value); +template GLuint CastFromStateValue(GLenum pname, GLint value); +template GLuint CastFromStateValue(GLenum pname, GLuint value); +template GLint CastFromStateValue(GLenum pname, GLboolean value); +template GLint64 CastFromStateValue(GLenum pname, GLboolean value); +template GLint CastFromStateValue(GLenum pname, GLuint value); +template GLint64 CastFromStateValue(GLenum pname, GLuint value); +template GLuint64 CastFromStateValue(GLenum pname, GLuint value); + +template +NativeT CastQueryValueTo(GLenum pname, QueryT value) +{ + GLenum nativeType = GLTypeToGLenum::value; + + switch (nativeType) + { + case GL_INT: + case GL_INT_64_ANGLEX: + case GL_UNSIGNED_INT: + case GL_UINT_64_ANGLEX: + return CastQueryValueToInt(pname, value); + case GL_FLOAT: + return static_cast(value); + case GL_BOOL: + return static_cast(value == static_cast(0) ? GL_FALSE : GL_TRUE); + default: + UNREACHABLE(); + return 0; + } +} + +template GLint CastQueryValueTo(GLenum pname, GLfloat value); +template GLboolean CastQueryValueTo(GLenum pname, GLint value); +template GLint CastQueryValueTo(GLenum pname, GLint value); +template GLint CastQueryValueTo(GLenum pname, GLuint value); +template GLfloat CastQueryValueTo(GLenum pname, GLint value); +template GLfloat CastQueryValueTo(GLenum pname, GLuint value); +template GLfloat CastQueryValueTo(GLenum pname, GLfloat value); +template GLuint CastQueryValueTo(GLenum pname, GLint value); +template GLuint CastQueryValueTo(GLenum pname, GLuint value); +template GLuint CastQueryValueTo(GLenum pname, GLfloat value); + +template +void CastStateValues(const Context *context, + GLenum nativeType, + GLenum pname, + unsigned int numParams, + QueryT *outParams) +{ + if (nativeType == GL_INT) + { + std::vector intParams(numParams, 0); + context->getIntegervImpl(pname, intParams.data()); + + for (unsigned int i = 0; i < numParams; ++i) + { + outParams[i] = CastFromStateValue(pname, intParams[i]); + } + } + else if (nativeType == GL_BOOL) + { + std::vector boolParams(numParams, GL_FALSE); + context->getBooleanvImpl(pname, boolParams.data()); + + for (unsigned int i = 0; i < numParams; ++i) + { + outParams[i] = + (boolParams[i] == GL_FALSE ? static_cast(0) : static_cast(1)); + } + } + else if (nativeType == GL_FLOAT) + { + std::vector floatParams(numParams, 0.0f); + context->getFloatvImpl(pname, floatParams.data()); + + for (unsigned int i = 0; i < numParams; ++i) + { + outParams[i] = CastFromStateValue(pname, floatParams[i]); + } + } + else if (nativeType == GL_INT_64_ANGLEX) + { + std::vector int64Params(numParams, 0); + context->getInteger64vImpl(pname, int64Params.data()); + + for (unsigned int i = 0; i < numParams; ++i) + { + outParams[i] = CastFromStateValue(pname, int64Params[i]); + } + } + else + { + WARN() << "Application querying parameter that does not exist."; + } +} + +// Explicit template instantiation (how we export template functions in different files) +// The calls below will make CastStateValues successfully link with the GL state query types +// The GL state query API types are: bool, int, uint, float, int64, uint64 + +template void CastStateValues(const Context *, + GLenum, + GLenum, + unsigned int, + GLboolean *); +template void CastStateValues(const Context *, GLenum, GLenum, unsigned int, GLint *); +template void CastStateValues(const Context *, GLenum, GLenum, unsigned int, GLuint *); +template void CastStateValues(const Context *, GLenum, GLenum, unsigned int, GLfloat *); +template void CastStateValues(const Context *, GLenum, GLenum, unsigned int, GLint64 *); + +template +void CastIndexedStateValues(Context *context, + GLenum nativeType, + GLenum pname, + GLuint index, + unsigned int numParams, + QueryT *outParams) +{ + if (nativeType == GL_INT) + { + std::vector intParams(numParams, 0); + context->getIntegeri_v(pname, index, intParams.data()); + + for (unsigned int i = 0; i < numParams; ++i) + { + outParams[i] = CastFromStateValue(pname, intParams[i]); + } + } + else if (nativeType == GL_BOOL) + { + std::vector boolParams(numParams, GL_FALSE); + context->getBooleani_v(pname, index, boolParams.data()); + + for (unsigned int i = 0; i < numParams; ++i) + { + outParams[i] = + (boolParams[i] == GL_FALSE ? static_cast(0) : static_cast(1)); + } + } + else if (nativeType == GL_INT_64_ANGLEX) + { + std::vector int64Params(numParams, 0); + context->getInteger64i_v(pname, index, int64Params.data()); + + for (unsigned int i = 0; i < numParams; ++i) + { + outParams[i] = CastFromStateValue(pname, int64Params[i]); + } + } + else + UNREACHABLE(); +} + +template void CastIndexedStateValues(Context *, + GLenum, + GLenum, + GLuint index, + unsigned int, + GLboolean *); +template void CastIndexedStateValues(Context *, + GLenum, + GLenum, + GLuint index, + unsigned int, + GLint *); +template void CastIndexedStateValues(Context *, + GLenum, + GLenum, + GLuint index, + unsigned int, + GLuint *); +template void CastIndexedStateValues(Context *, + GLenum, + GLenum, + GLuint index, + unsigned int, + GLfloat *); +template void CastIndexedStateValues(Context *, + GLenum, + GLenum, + GLuint index, + unsigned int, + GLint64 *); +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/queryconversions.h b/gfx/angle/checkout/src/libANGLE/queryconversions.h new file mode 100644 index 0000000000..7784c33e73 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/queryconversions.h @@ -0,0 +1,138 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// queryconversions.h: Declaration of state query cast conversions + +#ifndef LIBANGLE_QUERY_CONVERSIONS_H_ +#define LIBANGLE_QUERY_CONVERSIONS_H_ + +#include "angle_gl.h" +#include "common/angleutils.h" + +namespace gl +{ +class Context; + +// Helper class for converting a GL type to a GLenum: +// We can't use CastStateValueEnum generally, because of GLboolean + GLubyte overlap. +// We restrict our use to CastFromStateValue and CastQueryValueTo, where it eliminates +// duplicate parameters. + +template +struct GLTypeToGLenum +{ + // static constexpr GLenum value; +}; + +template <> +struct GLTypeToGLenum +{ + static constexpr GLenum value = GL_INT; +}; +template <> +struct GLTypeToGLenum +{ + static constexpr GLenum value = GL_UNSIGNED_INT; +}; +template <> +struct GLTypeToGLenum +{ + static constexpr GLenum value = GL_BOOL; +}; +template <> +struct GLTypeToGLenum +{ + static constexpr GLenum value = GL_INT_64_ANGLEX; +}; +template <> +struct GLTypeToGLenum +{ + static constexpr GLenum value = GL_UINT_64_ANGLEX; +}; +template <> +struct GLTypeToGLenum +{ + static constexpr GLenum value = GL_FLOAT; +}; + +GLint CastMaskValue(GLuint value); + +template +QueryT CastFromGLintStateValue(GLenum pname, InternalT value); + +template +QueryT CastFromStateValue(GLenum pname, NativeT value); + +template +NativeT CastQueryValueTo(GLenum pname, QueryT value); + +template +GLenum ConvertToGLenum(GLenum pname, ParamType param) +{ + return static_cast(CastQueryValueTo(pname, param)); +} + +template +GLenum ConvertToGLenum(ParamType param) +{ + return ConvertToGLenum(GL_NONE, param); +} + +template +OutType ConvertGLenum(GLenum param) +{ + return static_cast(param); +} + +template +void ConvertGLenumValue(InType param, OutType *out) +{ + *out = ConvertGLenum(static_cast(param)); +} + +template +void ConvertPackedEnum(PackedEnumType param, OutType *out) +{ + *out = static_cast(ToGLenum(param)); +} + +template +GLint ConvertToGLint(ParamType param) +{ + return CastQueryValueTo(GL_NONE, param); +} + +template +bool ConvertToBool(ParamType param) +{ + return param != GL_FALSE; +} + +template +GLboolean ConvertToGLBoolean(ParamType param) +{ + return param ? GL_TRUE : GL_FALSE; +} + +// The GL state query API types are: bool, int, uint, float, int64, uint64 +template +void CastStateValues(const Context *context, + GLenum nativeType, + GLenum pname, + unsigned int numParams, + QueryT *outParams); + +// The GL state query API types are: bool, int, uint, float, int64, uint64 +template +void CastIndexedStateValues(Context *context, + GLenum nativeType, + GLenum pname, + GLuint index, + unsigned int numParams, + QueryT *outParams); +} // namespace gl + +#endif // LIBANGLE_QUERY_CONVERSIONS_H_ diff --git a/gfx/angle/checkout/src/libANGLE/queryutils.cpp b/gfx/angle/checkout/src/libANGLE/queryutils.cpp new file mode 100644 index 0000000000..56600eae9d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/queryutils.cpp @@ -0,0 +1,4525 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// queryutils.cpp: Utilities for querying values from GL objects + +#include "libANGLE/queryutils.h" + +#include + +#include "common/utilities.h" + +#include "libANGLE/Buffer.h" +#include "libANGLE/Config.h" +#include "libANGLE/Context.h" +#include "libANGLE/Display.h" +#include "libANGLE/EGLSync.h" +#include "libANGLE/Fence.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/GLES1State.h" +#include "libANGLE/MemoryObject.h" +#include "libANGLE/Program.h" +#include "libANGLE/Renderbuffer.h" +#include "libANGLE/Sampler.h" +#include "libANGLE/Shader.h" +#include "libANGLE/Surface.h" +#include "libANGLE/Texture.h" +#include "libANGLE/Uniform.h" +#include "libANGLE/VertexAttribute.h" +#include "libANGLE/queryconversions.h" + +namespace gl +{ + +namespace +{ + +template +ColorGeneric ConvertToColor(const GLfloat *params) +{ + if (isPureInteger) + { + UNREACHABLE(); + return ColorGeneric(ColorI()); + } + else + { + return ColorGeneric(ColorF::fromData(params)); + } +} + +template +ColorGeneric ConvertToColor(const GLint *params) +{ + if (isPureInteger) + { + return ColorGeneric(ColorI(params[0], params[1], params[2], params[3])); + } + else + { + return ColorGeneric(ColorF(normalizedToFloat(params[0]), normalizedToFloat(params[1]), + normalizedToFloat(params[2]), normalizedToFloat(params[3]))); + } +} + +template +ColorGeneric ConvertToColor(const GLuint *params) +{ + if (isPureInteger) + { + return ColorGeneric(ColorUI(params[0], params[1], params[2], params[3])); + } + else + { + UNREACHABLE(); + return ColorGeneric(ColorF()); + } +} + +template +void ConvertFromColor(const ColorGeneric &color, GLfloat *outParams) +{ + if (isPureInteger) + { + UNREACHABLE(); + } + else + { + color.colorF.writeData(outParams); + } +} + +template +void ConvertFromColor(const ColorGeneric &color, GLint *outParams) +{ + if (isPureInteger) + { + outParams[0] = color.colorI.red; + outParams[1] = color.colorI.green; + outParams[2] = color.colorI.blue; + outParams[3] = color.colorI.alpha; + } + else + { + outParams[0] = floatToNormalized(color.colorF.red); + outParams[1] = floatToNormalized(color.colorF.green); + outParams[2] = floatToNormalized(color.colorF.blue); + outParams[3] = floatToNormalized(color.colorF.alpha); + } +} + +template +void ConvertFromColor(const ColorGeneric &color, GLuint *outParams) +{ + if (isPureInteger) + { + constexpr unsigned int kMinValue = 0; + + outParams[0] = std::max(color.colorUI.red, kMinValue); + outParams[1] = std::max(color.colorUI.green, kMinValue); + outParams[2] = std::max(color.colorUI.blue, kMinValue); + outParams[3] = std::max(color.colorUI.alpha, kMinValue); + } + else + { + UNREACHABLE(); + } +} + +template +void QueryTexLevelParameterBase(const Texture *texture, + TextureTarget target, + GLint level, + GLenum pname, + ParamType *params) +{ + ASSERT(texture != nullptr); + const InternalFormat *info = texture->getTextureState().getImageDesc(target, level).format.info; + + switch (pname) + { + case GL_TEXTURE_RED_TYPE: + *params = CastFromGLintStateValue( + pname, info->redBits ? info->componentType : GL_NONE); + break; + case GL_TEXTURE_GREEN_TYPE: + *params = CastFromGLintStateValue( + pname, info->greenBits ? info->componentType : GL_NONE); + break; + case GL_TEXTURE_BLUE_TYPE: + *params = CastFromGLintStateValue( + pname, info->blueBits ? info->componentType : GL_NONE); + break; + case GL_TEXTURE_ALPHA_TYPE: + *params = CastFromGLintStateValue( + pname, info->alphaBits ? info->componentType : GL_NONE); + break; + case GL_TEXTURE_DEPTH_TYPE: + *params = CastFromGLintStateValue( + pname, info->depthBits ? info->componentType : GL_NONE); + break; + case GL_TEXTURE_RED_SIZE: + *params = CastFromGLintStateValue(pname, info->redBits); + break; + case GL_TEXTURE_GREEN_SIZE: + *params = CastFromGLintStateValue(pname, info->greenBits); + break; + case GL_TEXTURE_BLUE_SIZE: + *params = CastFromGLintStateValue(pname, info->blueBits); + break; + case GL_TEXTURE_ALPHA_SIZE: + *params = CastFromGLintStateValue(pname, info->alphaBits); + break; + case GL_TEXTURE_DEPTH_SIZE: + *params = CastFromGLintStateValue(pname, info->depthBits); + break; + case GL_TEXTURE_STENCIL_SIZE: + *params = CastFromGLintStateValue(pname, info->stencilBits); + break; + case GL_TEXTURE_SHARED_SIZE: + *params = CastFromGLintStateValue(pname, info->sharedBits); + break; + case GL_TEXTURE_INTERNAL_FORMAT: + *params = CastFromGLintStateValue( + pname, info->internalFormat ? info->internalFormat : GL_RGBA); + break; + case GL_TEXTURE_WIDTH: + *params = CastFromGLintStateValue( + pname, static_cast(texture->getWidth(target, level))); + break; + case GL_TEXTURE_HEIGHT: + *params = CastFromGLintStateValue( + pname, static_cast(texture->getHeight(target, level))); + break; + case GL_TEXTURE_DEPTH: + *params = CastFromGLintStateValue( + pname, static_cast(texture->getDepth(target, level))); + break; + case GL_TEXTURE_SAMPLES: + *params = CastFromStateValue(pname, texture->getSamples(target, level)); + break; + case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS: + *params = CastFromStateValue( + pname, static_cast(texture->getFixedSampleLocations(target, level))); + break; + case GL_TEXTURE_COMPRESSED: + *params = CastFromStateValue(pname, static_cast(info->compressed)); + break; + case GL_MEMORY_SIZE_ANGLE: + *params = + CastFromStateValue(pname, texture->getLevelMemorySize(target, level)); + break; + case GL_RESOURCE_INITIALIZED_ANGLE: + *params = CastFromGLintStateValue( + pname, texture->initState(GL_NONE, ImageIndex::MakeFromTarget(target, level)) == + InitState::Initialized); + break; + case GL_TEXTURE_BUFFER_DATA_STORE_BINDING: + *params = CastFromStateValue( + pname, static_cast(texture->getBuffer().id().value)); + break; + case GL_TEXTURE_BUFFER_OFFSET: + *params = CastFromStateValue( + pname, static_cast(texture->getBuffer().getOffset())); + break; + case GL_TEXTURE_BUFFER_SIZE: + *params = CastFromStateValue( + pname, static_cast(GetBoundBufferAvailableSize(texture->getBuffer()))); + break; + default: + UNREACHABLE(); + break; + } +} + +// This function is needed to handle fixed_point data. +// It can be used when some pname need special conversion from int/float/bool to fixed_point. +template +QueryT CastFromSpecialValue(GLenum pname, const ParamType param) +{ + if (isGLfixed) + { + return static_cast(ConvertFloatToFixed(CastFromStateValue(pname, param))); + } + else + { + return CastFromStateValue(pname, param); + } +} + +template +void QueryTexParameterBase(const Context *context, + const Texture *texture, + GLenum pname, + ParamType *params) +{ + ASSERT(texture != nullptr); + + switch (pname) + { + case GL_TEXTURE_MAG_FILTER: + *params = CastFromGLintStateValue(pname, texture->getMagFilter()); + break; + case GL_TEXTURE_MIN_FILTER: + *params = CastFromGLintStateValue(pname, texture->getMinFilter()); + break; + case GL_TEXTURE_WRAP_S: + *params = CastFromGLintStateValue(pname, texture->getWrapS()); + break; + case GL_TEXTURE_WRAP_T: + *params = CastFromGLintStateValue(pname, texture->getWrapT()); + break; + case GL_TEXTURE_WRAP_R: + *params = CastFromGLintStateValue(pname, texture->getWrapR()); + break; + case GL_TEXTURE_IMMUTABLE_FORMAT: + *params = CastFromGLintStateValue(pname, texture->getImmutableFormat()); + break; + case GL_TEXTURE_IMMUTABLE_LEVELS: + *params = CastFromGLintStateValue(pname, texture->getImmutableLevels()); + break; + case GL_TEXTURE_USAGE_ANGLE: + *params = CastFromGLintStateValue(pname, texture->getUsage()); + break; + case GL_TEXTURE_MAX_ANISOTROPY_EXT: + *params = + CastFromSpecialValue(pname, texture->getMaxAnisotropy()); + break; + case GL_TEXTURE_SWIZZLE_R: + *params = CastFromGLintStateValue(pname, texture->getSwizzleRed()); + break; + case GL_TEXTURE_SWIZZLE_G: + *params = CastFromGLintStateValue(pname, texture->getSwizzleGreen()); + break; + case GL_TEXTURE_SWIZZLE_B: + *params = CastFromGLintStateValue(pname, texture->getSwizzleBlue()); + break; + case GL_TEXTURE_SWIZZLE_A: + *params = CastFromGLintStateValue(pname, texture->getSwizzleAlpha()); + break; + case GL_TEXTURE_BASE_LEVEL: + *params = CastFromGLintStateValue(pname, texture->getBaseLevel()); + break; + case GL_TEXTURE_MAX_LEVEL: + *params = CastFromGLintStateValue(pname, texture->getMaxLevel()); + break; + case GL_TEXTURE_MIN_LOD: + *params = CastFromSpecialValue(pname, texture->getMinLod()); + break; + case GL_TEXTURE_MAX_LOD: + *params = CastFromSpecialValue(pname, texture->getMaxLod()); + break; + case GL_TEXTURE_COMPARE_MODE: + *params = CastFromGLintStateValue(pname, texture->getCompareMode()); + break; + case GL_TEXTURE_COMPARE_FUNC: + *params = CastFromGLintStateValue(pname, texture->getCompareFunc()); + break; + case GL_TEXTURE_SRGB_DECODE_EXT: + *params = CastFromGLintStateValue(pname, texture->getSRGBDecode()); + break; + case GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT: + *params = CastFromGLintStateValue(pname, texture->getSRGBOverride()); + break; + case GL_DEPTH_STENCIL_TEXTURE_MODE: + *params = + CastFromGLintStateValue(pname, texture->getDepthStencilTextureMode()); + break; + case GL_TEXTURE_CROP_RECT_OES: + { + const gl::Rectangle &crop = texture->getCrop(); + params[0] = CastFromSpecialValue(pname, crop.x); + params[1] = CastFromSpecialValue(pname, crop.y); + params[2] = CastFromSpecialValue(pname, crop.width); + params[3] = CastFromSpecialValue(pname, crop.height); + break; + } + case GL_GENERATE_MIPMAP: + *params = CastFromGLintStateValue(pname, texture->getGenerateMipmapHint()); + break; + case GL_MEMORY_SIZE_ANGLE: + *params = CastFromSpecialValue(pname, texture->getMemorySize()); + break; + case GL_TEXTURE_BORDER_COLOR: + ConvertFromColor(texture->getBorderColor(), params); + break; + case GL_TEXTURE_NATIVE_ID_ANGLE: + *params = CastFromSpecialValue(pname, texture->getNativeID()); + break; + case GL_IMPLEMENTATION_COLOR_READ_FORMAT: + *params = CastFromGLintStateValue( + pname, texture->getImplementationColorReadFormat(context)); + break; + case GL_IMPLEMENTATION_COLOR_READ_TYPE: + *params = CastFromGLintStateValue( + pname, texture->getImplementationColorReadType(context)); + break; + case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE: + *params = + CastFromGLintStateValue(pname, GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE); + break; + case GL_RESOURCE_INITIALIZED_ANGLE: + *params = CastFromGLintStateValue( + pname, texture->initState() == InitState::Initialized); + break; + case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: + *params = CastFromGLintStateValue( + pname, texture->getRequiredTextureImageUnits(context)); + break; + case GL_TEXTURE_PROTECTED_EXT: + *params = CastFromGLintStateValue(pname, texture->hasProtectedContent()); + break; + default: + UNREACHABLE(); + break; + } +} + +// this function is needed to handle OES_FIXED_POINT. +// Some pname values can take in GLfixed values and may need to be converted +template +ReturnType ConvertTexParam(GLenum pname, const ParamType param) +{ + if (isGLfixed) + { + return CastQueryValueTo(pname, + ConvertFixedToFloat(static_cast(param))); + } + else + { + return CastQueryValueTo(pname, param); + } +} + +template +void SetTexParameterBase(Context *context, Texture *texture, GLenum pname, const ParamType *params) +{ + ASSERT(texture != nullptr); + + switch (pname) + { + case GL_TEXTURE_WRAP_S: + texture->setWrapS(context, ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_WRAP_T: + texture->setWrapT(context, ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_WRAP_R: + texture->setWrapR(context, ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_MIN_FILTER: + texture->setMinFilter(context, ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_MAG_FILTER: + texture->setMagFilter(context, ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_USAGE_ANGLE: + texture->setUsage(context, ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_MAX_ANISOTROPY_EXT: + texture->setMaxAnisotropy(context, + ConvertTexParam(pname, params[0])); + break; + case GL_TEXTURE_COMPARE_MODE: + texture->setCompareMode(context, ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_COMPARE_FUNC: + texture->setCompareFunc(context, ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_SWIZZLE_R: + texture->setSwizzleRed(context, ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_SWIZZLE_G: + texture->setSwizzleGreen(context, ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_SWIZZLE_B: + texture->setSwizzleBlue(context, ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_SWIZZLE_A: + texture->setSwizzleAlpha(context, ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_BASE_LEVEL: + { + (void)(texture->setBaseLevel( + context, clampCast(CastQueryValueTo(pname, params[0])))); + break; + } + case GL_TEXTURE_MAX_LEVEL: + texture->setMaxLevel(context, + clampCast(CastQueryValueTo(pname, params[0]))); + break; + case GL_TEXTURE_MIN_LOD: + texture->setMinLod(context, CastQueryValueTo(pname, params[0])); + break; + case GL_TEXTURE_MAX_LOD: + texture->setMaxLod(context, CastQueryValueTo(pname, params[0])); + break; + case GL_DEPTH_STENCIL_TEXTURE_MODE: + texture->setDepthStencilTextureMode(context, ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_SRGB_DECODE_EXT: + texture->setSRGBDecode(context, ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT: + texture->setSRGBOverride(context, ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_CROP_RECT_OES: + texture->setCrop(gl::Rectangle(ConvertTexParam(pname, params[0]), + ConvertTexParam(pname, params[1]), + ConvertTexParam(pname, params[2]), + ConvertTexParam(pname, params[3]))); + break; + case GL_GENERATE_MIPMAP: + texture->setGenerateMipmapHint(ConvertToGLenum(params[0])); + break; + case GL_TEXTURE_BORDER_COLOR: + texture->setBorderColor(context, ConvertToColor(params)); + break; + case GL_RESOURCE_INITIALIZED_ANGLE: + texture->setInitState(ConvertToBool(params[0]) ? InitState::Initialized + : InitState::MayNeedInit); + break; + case GL_TEXTURE_PROTECTED_EXT: + texture->setProtectedContent(context, (params[0] == GL_TRUE)); + break; + default: + UNREACHABLE(); + break; + } +} + +template +void QuerySamplerParameterBase(const Sampler *sampler, GLenum pname, ParamType *params) +{ + switch (pname) + { + case GL_TEXTURE_MIN_FILTER: + *params = CastFromGLintStateValue(pname, sampler->getMinFilter()); + break; + case GL_TEXTURE_MAG_FILTER: + *params = CastFromGLintStateValue(pname, sampler->getMagFilter()); + break; + case GL_TEXTURE_WRAP_S: + *params = CastFromGLintStateValue(pname, sampler->getWrapS()); + break; + case GL_TEXTURE_WRAP_T: + *params = CastFromGLintStateValue(pname, sampler->getWrapT()); + break; + case GL_TEXTURE_WRAP_R: + *params = CastFromGLintStateValue(pname, sampler->getWrapR()); + break; + case GL_TEXTURE_MAX_ANISOTROPY_EXT: + *params = CastFromStateValue(pname, sampler->getMaxAnisotropy()); + break; + case GL_TEXTURE_MIN_LOD: + *params = CastFromStateValue(pname, sampler->getMinLod()); + break; + case GL_TEXTURE_MAX_LOD: + *params = CastFromStateValue(pname, sampler->getMaxLod()); + break; + case GL_TEXTURE_COMPARE_MODE: + *params = CastFromGLintStateValue(pname, sampler->getCompareMode()); + break; + case GL_TEXTURE_COMPARE_FUNC: + *params = CastFromGLintStateValue(pname, sampler->getCompareFunc()); + break; + case GL_TEXTURE_SRGB_DECODE_EXT: + *params = CastFromGLintStateValue(pname, sampler->getSRGBDecode()); + break; + case GL_TEXTURE_BORDER_COLOR: + ConvertFromColor(sampler->getBorderColor(), params); + break; + default: + UNREACHABLE(); + break; + } +} + +template +void SetSamplerParameterBase(Context *context, + Sampler *sampler, + GLenum pname, + const ParamType *params) +{ + switch (pname) + { + case GL_TEXTURE_WRAP_S: + sampler->setWrapS(context, ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_WRAP_T: + sampler->setWrapT(context, ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_WRAP_R: + sampler->setWrapR(context, ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_MIN_FILTER: + sampler->setMinFilter(context, ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_MAG_FILTER: + sampler->setMagFilter(context, ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_MAX_ANISOTROPY_EXT: + sampler->setMaxAnisotropy(context, CastQueryValueTo(pname, params[0])); + break; + case GL_TEXTURE_COMPARE_MODE: + sampler->setCompareMode(context, ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_COMPARE_FUNC: + sampler->setCompareFunc(context, ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_MIN_LOD: + sampler->setMinLod(context, CastQueryValueTo(pname, params[0])); + break; + case GL_TEXTURE_MAX_LOD: + sampler->setMaxLod(context, CastQueryValueTo(pname, params[0])); + break; + case GL_TEXTURE_SRGB_DECODE_EXT: + sampler->setSRGBDecode(context, ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_BORDER_COLOR: + sampler->setBorderColor(context, ConvertToColor(params)); + break; + default: + UNREACHABLE(); + break; + } + + sampler->onStateChange(angle::SubjectMessage::ContentsChanged); +} + +// Warning: you should ensure binding really matches attrib.bindingIndex before using this function. +template +void QueryVertexAttribBase(const VertexAttribute &attrib, + const VertexBinding &binding, + const CurrentDataType (¤tValueData)[CurrentValueCount], + GLenum pname, + ParamType *params) +{ + switch (pname) + { + case GL_CURRENT_VERTEX_ATTRIB: + for (size_t i = 0; i < CurrentValueCount; ++i) + { + params[i] = CastFromStateValue(pname, currentValueData[i]); + } + break; + case GL_VERTEX_ATTRIB_ARRAY_ENABLED: + *params = CastFromStateValue(pname, static_cast(attrib.enabled)); + break; + case GL_VERTEX_ATTRIB_ARRAY_SIZE: + *params = CastFromGLintStateValue(pname, attrib.format->channelCount); + break; + case GL_VERTEX_ATTRIB_ARRAY_STRIDE: + *params = CastFromGLintStateValue(pname, attrib.vertexAttribArrayStride); + break; + case GL_VERTEX_ATTRIB_ARRAY_TYPE: + *params = CastFromGLintStateValue( + pname, gl::ToGLenum(attrib.format->vertexAttribType)); + break; + case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: + *params = + CastFromStateValue(pname, static_cast(attrib.format->isNorm())); + break; + case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: + *params = CastFromGLintStateValue(pname, binding.getBuffer().id().value); + break; + case GL_VERTEX_ATTRIB_ARRAY_DIVISOR: + *params = CastFromStateValue(pname, binding.getDivisor()); + break; + case GL_VERTEX_ATTRIB_ARRAY_INTEGER: + *params = CastFromGLintStateValue(pname, attrib.format->isPureInt()); + break; + case GL_VERTEX_ATTRIB_BINDING: + *params = CastFromGLintStateValue(pname, attrib.bindingIndex); + break; + case GL_VERTEX_ATTRIB_RELATIVE_OFFSET: + *params = CastFromGLintStateValue(pname, attrib.relativeOffset); + break; + default: + UNREACHABLE(); + break; + } +} + +template +void QueryBufferParameterBase(const Buffer *buffer, GLenum pname, ParamType *params) +{ + ASSERT(buffer != nullptr); + + switch (pname) + { + case GL_BUFFER_USAGE: + *params = CastFromGLintStateValue(pname, ToGLenum(buffer->getUsage())); + break; + case GL_BUFFER_SIZE: + *params = CastFromStateValue(pname, buffer->getSize()); + break; + case GL_BUFFER_ACCESS_FLAGS: + *params = CastFromGLintStateValue(pname, buffer->getAccessFlags()); + break; + case GL_BUFFER_ACCESS_OES: + *params = CastFromGLintStateValue(pname, buffer->getAccess()); + break; + case GL_BUFFER_MAPPED: + *params = CastFromStateValue(pname, buffer->isMapped()); + break; + case GL_BUFFER_MAP_OFFSET: + *params = CastFromStateValue(pname, buffer->getMapOffset()); + break; + case GL_BUFFER_MAP_LENGTH: + *params = CastFromStateValue(pname, buffer->getMapLength()); + break; + case GL_MEMORY_SIZE_ANGLE: + *params = CastFromStateValue(pname, buffer->getMemorySize()); + break; + case GL_BUFFER_IMMUTABLE_STORAGE_EXT: + *params = CastFromStateValue(pname, buffer->isImmutable()); + break; + case GL_BUFFER_STORAGE_FLAGS_EXT: + *params = CastFromGLintStateValue(pname, buffer->getStorageExtUsageFlags()); + break; + case GL_RESOURCE_INITIALIZED_ANGLE: + *params = CastFromStateValue( + pname, ConvertToGLBoolean(buffer->initState() == InitState::Initialized)); + break; + default: + UNREACHABLE(); + break; + } +} + +GLint GetCommonVariableProperty(const sh::ShaderVariable &var, GLenum prop) +{ + switch (prop) + { + case GL_TYPE: + return clampCast(var.type); + + case GL_ARRAY_SIZE: + // Queryable variables are guaranteed not to be arrays of arrays or arrays of structs, + // see GLES 3.1 spec section 7.3.1.1 page 77. + return clampCast(var.getBasicTypeElementCount()); + + case GL_NAME_LENGTH: + // ES31 spec p84: This counts the terminating null char. + return clampCast(var.name.size() + 1u); + + default: + UNREACHABLE(); + return GL_INVALID_VALUE; + } +} + +GLint GetInputResourceProperty(const Program *program, GLuint index, GLenum prop) +{ + const sh::ShaderVariable &variable = program->getInputResource(index); + + switch (prop) + { + case GL_TYPE: + case GL_ARRAY_SIZE: + return GetCommonVariableProperty(variable, prop); + + case GL_NAME_LENGTH: + return clampCast(program->getInputResourceName(index).size() + 1u); + + case GL_LOCATION: + return variable.isBuiltIn() ? GL_INVALID_INDEX : variable.location; + + // The query is targeted at the set of active input variables used by the first shader stage + // of program. If program contains multiple shader stages then input variables from any + // stage other than the first will not be enumerated. Since we found the variable to get + // this far, we know it exists in the first attached shader stage. + case GL_REFERENCED_BY_VERTEX_SHADER: + return program->getState().getFirstAttachedShaderStageType() == ShaderType::Vertex; + case GL_REFERENCED_BY_FRAGMENT_SHADER: + return program->getState().getFirstAttachedShaderStageType() == ShaderType::Fragment; + case GL_REFERENCED_BY_COMPUTE_SHADER: + return program->getState().getFirstAttachedShaderStageType() == ShaderType::Compute; + case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT: + return program->getState().getFirstAttachedShaderStageType() == ShaderType::Geometry; + case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT: + return program->getState().getFirstAttachedShaderStageType() == ShaderType::TessControl; + case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT: + return program->getState().getFirstAttachedShaderStageType() == + ShaderType::TessEvaluation; + case GL_IS_PER_PATCH_EXT: + return variable.isPatch; + + default: + UNREACHABLE(); + return GL_INVALID_VALUE; + } +} + +GLint GetOutputResourceProperty(const Program *program, GLuint index, const GLenum prop) +{ + const sh::ShaderVariable &outputVariable = program->getOutputResource(index); + + switch (prop) + { + case GL_TYPE: + case GL_ARRAY_SIZE: + return GetCommonVariableProperty(outputVariable, prop); + + case GL_NAME_LENGTH: + return clampCast(program->getOutputResourceName(index).size() + 1u); + + case GL_LOCATION: + return outputVariable.location; + + case GL_LOCATION_INDEX_EXT: + // EXT_blend_func_extended + if (program->getState().getLastAttachedShaderStageType() == gl::ShaderType::Fragment) + { + return program->getFragDataIndex(outputVariable.name); + } + return GL_INVALID_INDEX; + + // The set of active user-defined outputs from the final shader stage in this program. If + // the final stage is a Fragment Shader, then this represents the fragment outputs that get + // written to individual color buffers. If the program only contains a Compute Shader, then + // there are no user-defined outputs. + case GL_REFERENCED_BY_VERTEX_SHADER: + return program->getState().getLastAttachedShaderStageType() == ShaderType::Vertex; + case GL_REFERENCED_BY_FRAGMENT_SHADER: + return program->getState().getLastAttachedShaderStageType() == ShaderType::Fragment; + case GL_REFERENCED_BY_COMPUTE_SHADER: + return program->getState().getLastAttachedShaderStageType() == ShaderType::Compute; + case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT: + return program->getState().getLastAttachedShaderStageType() == ShaderType::Geometry; + case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT: + return program->getState().getLastAttachedShaderStageType() == ShaderType::TessControl; + case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT: + return program->getState().getLastAttachedShaderStageType() == + ShaderType::TessEvaluation; + case GL_IS_PER_PATCH_EXT: + return outputVariable.isPatch; + + default: + UNREACHABLE(); + return GL_INVALID_VALUE; + } +} + +GLint GetTransformFeedbackVaryingResourceProperty(const Program *program, + GLuint index, + const GLenum prop) +{ + const auto &tfVariable = program->getTransformFeedbackVaryingResource(index); + switch (prop) + { + case GL_TYPE: + return clampCast(tfVariable.type); + + case GL_ARRAY_SIZE: + return clampCast(tfVariable.size()); + + case GL_NAME_LENGTH: + return clampCast(tfVariable.nameWithArrayIndex().size() + 1); + + default: + UNREACHABLE(); + return GL_INVALID_VALUE; + } +} + +GLint QueryProgramInterfaceActiveResources(const Program *program, GLenum programInterface) +{ + switch (programInterface) + { + case GL_PROGRAM_INPUT: + return clampCast(program->getState().getProgramInputs().size()); + + case GL_PROGRAM_OUTPUT: + return clampCast(program->getState().getOutputVariables().size()); + + case GL_UNIFORM: + return clampCast(program->getState().getUniforms().size()); + + case GL_UNIFORM_BLOCK: + return clampCast(program->getState().getUniformBlocks().size()); + + case GL_ATOMIC_COUNTER_BUFFER: + return clampCast(program->getState().getAtomicCounterBuffers().size()); + + case GL_BUFFER_VARIABLE: + return clampCast(program->getState().getBufferVariables().size()); + + case GL_SHADER_STORAGE_BLOCK: + return clampCast(program->getState().getShaderStorageBlocks().size()); + + case GL_TRANSFORM_FEEDBACK_VARYING: + return clampCast(program->getTransformFeedbackVaryingCount()); + + default: + UNREACHABLE(); + return 0; + } +} + +template +GLint FindMaxSize(const std::vector &resources, M member) +{ + GLint max = 0; + for (const T &resource : resources) + { + max = std::max(max, clampCast((resource.*member).size())); + } + return max; +} + +GLint QueryProgramInterfaceMaxNameLength(const Program *program, GLenum programInterface) +{ + GLint maxNameLength = 0; + switch (programInterface) + { + case GL_PROGRAM_INPUT: + maxNameLength = program->getInputResourceMaxNameSize(); + break; + + case GL_PROGRAM_OUTPUT: + maxNameLength = program->getOutputResourceMaxNameSize(); + break; + + case GL_UNIFORM: + maxNameLength = FindMaxSize(program->getState().getUniforms(), &LinkedUniform::name); + break; + + case GL_UNIFORM_BLOCK: + return program->getActiveUniformBlockMaxNameLength(); + + case GL_BUFFER_VARIABLE: + maxNameLength = + FindMaxSize(program->getState().getBufferVariables(), &BufferVariable::name); + break; + + case GL_SHADER_STORAGE_BLOCK: + return program->getActiveShaderStorageBlockMaxNameLength(); + + case GL_TRANSFORM_FEEDBACK_VARYING: + return clampCast(program->getTransformFeedbackVaryingMaxLength()); + + default: + UNREACHABLE(); + return 0; + } + // This length includes an extra character for the null terminator. + return (maxNameLength == 0 ? 0 : maxNameLength + 1); +} + +GLint QueryProgramInterfaceMaxNumActiveVariables(const Program *program, GLenum programInterface) +{ + switch (programInterface) + { + case GL_UNIFORM_BLOCK: + return FindMaxSize(program->getState().getUniformBlocks(), + &InterfaceBlock::memberIndexes); + case GL_ATOMIC_COUNTER_BUFFER: + return FindMaxSize(program->getState().getAtomicCounterBuffers(), + &AtomicCounterBuffer::memberIndexes); + + case GL_SHADER_STORAGE_BLOCK: + return FindMaxSize(program->getState().getShaderStorageBlocks(), + &InterfaceBlock::memberIndexes); + + default: + UNREACHABLE(); + return 0; + } +} + +GLenum GetUniformPropertyEnum(GLenum prop) +{ + switch (prop) + { + case GL_UNIFORM_TYPE: + return GL_TYPE; + case GL_UNIFORM_SIZE: + return GL_ARRAY_SIZE; + case GL_UNIFORM_NAME_LENGTH: + return GL_NAME_LENGTH; + case GL_UNIFORM_BLOCK_INDEX: + return GL_BLOCK_INDEX; + case GL_UNIFORM_OFFSET: + return GL_OFFSET; + case GL_UNIFORM_ARRAY_STRIDE: + return GL_ARRAY_STRIDE; + case GL_UNIFORM_MATRIX_STRIDE: + return GL_MATRIX_STRIDE; + case GL_UNIFORM_IS_ROW_MAJOR: + return GL_IS_ROW_MAJOR; + + default: + return prop; + } +} + +GLenum GetUniformBlockPropertyEnum(GLenum prop) +{ + switch (prop) + { + case GL_UNIFORM_BLOCK_BINDING: + return GL_BUFFER_BINDING; + + case GL_UNIFORM_BLOCK_DATA_SIZE: + return GL_BUFFER_DATA_SIZE; + + case GL_UNIFORM_BLOCK_NAME_LENGTH: + return GL_NAME_LENGTH; + + case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: + return GL_NUM_ACTIVE_VARIABLES; + + case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: + return GL_ACTIVE_VARIABLES; + + case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER: + return GL_REFERENCED_BY_VERTEX_SHADER; + + case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: + return GL_REFERENCED_BY_FRAGMENT_SHADER; + + default: + return prop; + } +} + +void GetShaderVariableBufferResourceProperty(const ShaderVariableBuffer &buffer, + GLenum pname, + GLint *params, + GLsizei bufSize, + GLsizei *outputPosition) + +{ + switch (pname) + { + case GL_BUFFER_BINDING: + params[(*outputPosition)++] = buffer.binding; + break; + case GL_BUFFER_DATA_SIZE: + params[(*outputPosition)++] = clampCast(buffer.dataSize); + break; + case GL_NUM_ACTIVE_VARIABLES: + params[(*outputPosition)++] = buffer.numActiveVariables(); + break; + case GL_ACTIVE_VARIABLES: + for (size_t memberIndex = 0; + memberIndex < buffer.memberIndexes.size() && *outputPosition < bufSize; + ++memberIndex) + { + params[(*outputPosition)++] = clampCast(buffer.memberIndexes[memberIndex]); + } + break; + case GL_REFERENCED_BY_VERTEX_SHADER: + params[(*outputPosition)++] = static_cast(buffer.isActive(ShaderType::Vertex)); + break; + case GL_REFERENCED_BY_FRAGMENT_SHADER: + params[(*outputPosition)++] = static_cast(buffer.isActive(ShaderType::Fragment)); + break; + case GL_REFERENCED_BY_COMPUTE_SHADER: + params[(*outputPosition)++] = static_cast(buffer.isActive(ShaderType::Compute)); + break; + case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT: + params[(*outputPosition)++] = static_cast(buffer.isActive(ShaderType::Geometry)); + break; + case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT: + params[(*outputPosition)++] = + static_cast(buffer.isActive(ShaderType::TessControl)); + break; + case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT: + params[(*outputPosition)++] = + static_cast(buffer.isActive(ShaderType::TessEvaluation)); + break; + default: + UNREACHABLE(); + break; + } +} + +void GetInterfaceBlockResourceProperty(const InterfaceBlock &block, + GLenum pname, + GLint *params, + GLsizei bufSize, + GLsizei *outputPosition) +{ + if (pname == GL_NAME_LENGTH) + { + params[(*outputPosition)++] = clampCast(block.nameWithArrayIndex().size() + 1); + return; + } + GetShaderVariableBufferResourceProperty(block, pname, params, bufSize, outputPosition); +} + +void GetUniformBlockResourceProperty(const Program *program, + GLuint blockIndex, + GLenum pname, + GLint *params, + GLsizei bufSize, + GLsizei *outputPosition) + +{ + ASSERT(*outputPosition < bufSize); + const auto &block = program->getUniformBlockByIndex(blockIndex); + GetInterfaceBlockResourceProperty(block, pname, params, bufSize, outputPosition); +} + +void GetShaderStorageBlockResourceProperty(const Program *program, + GLuint blockIndex, + GLenum pname, + GLint *params, + GLsizei bufSize, + GLsizei *outputPosition) + +{ + ASSERT(*outputPosition < bufSize); + const auto &block = program->getShaderStorageBlockByIndex(blockIndex); + GetInterfaceBlockResourceProperty(block, pname, params, bufSize, outputPosition); +} + +void GetAtomicCounterBufferResourceProperty(const Program *program, + GLuint index, + GLenum pname, + GLint *params, + GLsizei bufSize, + GLsizei *outputPosition) + +{ + ASSERT(*outputPosition < bufSize); + const auto &buffer = program->getState().getAtomicCounterBuffers()[index]; + GetShaderVariableBufferResourceProperty(buffer, pname, params, bufSize, outputPosition); +} + +bool IsTextureEnvEnumParameter(TextureEnvParameter pname) +{ + switch (pname) + { + case TextureEnvParameter::Mode: + case TextureEnvParameter::CombineRgb: + case TextureEnvParameter::CombineAlpha: + case TextureEnvParameter::Src0Rgb: + case TextureEnvParameter::Src1Rgb: + case TextureEnvParameter::Src2Rgb: + case TextureEnvParameter::Src0Alpha: + case TextureEnvParameter::Src1Alpha: + case TextureEnvParameter::Src2Alpha: + case TextureEnvParameter::Op0Rgb: + case TextureEnvParameter::Op1Rgb: + case TextureEnvParameter::Op2Rgb: + case TextureEnvParameter::Op0Alpha: + case TextureEnvParameter::Op1Alpha: + case TextureEnvParameter::Op2Alpha: + case TextureEnvParameter::PointCoordReplace: + return true; + default: + return false; + } +} + +void GetShaderProgramId(ProgramPipeline *programPipeline, ShaderType shaderType, GLint *params) +{ + ASSERT(params); + + *params = 0; + if (programPipeline) + { + const Program *program = programPipeline->getShaderProgram(shaderType); + if (program) + { + *params = program->id().value; + } + } +} + +} // namespace + +void QueryFramebufferAttachmentParameteriv(const Context *context, + const Framebuffer *framebuffer, + GLenum attachment, + GLenum pname, + GLint *params) +{ + ASSERT(framebuffer); + + const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(context, attachment); + + if (attachmentObject == nullptr) + { + // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE + // is NONE, then querying any other pname will generate INVALID_ENUM. + + // ES 3.0.2 spec pg 235 states that if the attachment type is none, + // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an + // INVALID_OPERATION for all other pnames + + switch (pname) + { + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: + *params = GL_NONE; + break; + + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: + *params = 0; + break; + + default: + UNREACHABLE(); + break; + } + + return; + } + + switch (pname) + { + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: + *params = attachmentObject->type(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: + *params = attachmentObject->id(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: + *params = attachmentObject->mipLevel(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: + { + TextureTarget face = attachmentObject->cubeMapFace(); + if (face != TextureTarget::InvalidEnum) + { + *params = ToGLenum(attachmentObject->cubeMapFace()); + } + else + { + // This happens when the attachment isn't a texture cube map face + *params = GL_NONE; + } + } + break; + + case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE: + *params = attachmentObject->getRedSize(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE: + *params = attachmentObject->getGreenSize(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE: + *params = attachmentObject->getBlueSize(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE: + *params = attachmentObject->getAlphaSize(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE: + *params = attachmentObject->getDepthSize(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE: + *params = attachmentObject->getStencilSize(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: + *params = attachmentObject->getComponentType(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: + *params = attachmentObject->getColorEncoding(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER: + *params = attachmentObject->layer(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR: + *params = attachmentObject->getNumViews(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR: + *params = attachmentObject->getBaseViewIndex(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT: + *params = attachmentObject->isLayered(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT: + if (attachmentObject->type() == GL_TEXTURE) + { + *params = attachmentObject->getSamples(); + } + else + { + *params = 0; + } + break; + + default: + UNREACHABLE(); + break; + } +} + +void QueryBufferParameteriv(const Buffer *buffer, GLenum pname, GLint *params) +{ + QueryBufferParameterBase(buffer, pname, params); +} + +void QueryBufferParameteri64v(const Buffer *buffer, GLenum pname, GLint64 *params) +{ + QueryBufferParameterBase(buffer, pname, params); +} + +void QueryBufferPointerv(const Buffer *buffer, GLenum pname, void **params) +{ + switch (pname) + { + case GL_BUFFER_MAP_POINTER: + *params = buffer->getMapPointer(); + break; + + default: + UNREACHABLE(); + break; + } +} + +void QueryProgramiv(Context *context, const Program *program, GLenum pname, GLint *params) +{ + ASSERT(program != nullptr || pname == GL_COMPLETION_STATUS_KHR); + + switch (pname) + { + case GL_DELETE_STATUS: + *params = program->isFlaggedForDeletion(); + return; + case GL_LINK_STATUS: + *params = program->isLinked(); + return; + case GL_COMPLETION_STATUS_KHR: + if (context->isContextLost()) + { + *params = GL_TRUE; + } + else + { + *params = program->isLinking() ? GL_FALSE : GL_TRUE; + } + return; + case GL_VALIDATE_STATUS: + *params = program->isValidated(); + return; + case GL_INFO_LOG_LENGTH: + *params = program->getExecutable().getInfoLogLength(); + return; + case GL_ATTACHED_SHADERS: + *params = program->getAttachedShadersCount(); + return; + case GL_ACTIVE_ATTRIBUTES: + *params = program->getActiveAttributeCount(); + return; + case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: + *params = program->getActiveAttributeMaxLength(); + return; + case GL_ACTIVE_UNIFORMS: + *params = program->getActiveUniformCount(); + return; + case GL_ACTIVE_UNIFORM_MAX_LENGTH: + *params = program->getActiveUniformMaxLength(); + return; + case GL_PROGRAM_BINARY_LENGTH_OES: + *params = context->getCaps().programBinaryFormats.empty() + ? 0 + : program->getBinaryLength(context); + return; + case GL_ACTIVE_UNIFORM_BLOCKS: + *params = program->getActiveUniformBlockCount(); + return; + case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: + *params = program->getActiveUniformBlockMaxNameLength(); + break; + case GL_TRANSFORM_FEEDBACK_BUFFER_MODE: + *params = program->getTransformFeedbackBufferMode(); + break; + case GL_TRANSFORM_FEEDBACK_VARYINGS: + *params = clampCast(program->getTransformFeedbackVaryingCount()); + break; + case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: + *params = program->getTransformFeedbackVaryingMaxLength(); + break; + case GL_PROGRAM_BINARY_RETRIEVABLE_HINT: + *params = program->getBinaryRetrievableHint(); + break; + case GL_PROGRAM_SEPARABLE: + // From es31cSeparateShaderObjsTests.cpp: + // ProgramParameteri PROGRAM_SEPARABLE + // NOTE: The query for PROGRAM_SEPARABLE must query latched + // state. In other words, the state of the binary after + // it was linked. So in the tests below, the queries + // should return the default state GL_FALSE since the + // program has no linked binary. + *params = program->isSeparable() && program->isLinked(); + break; + case GL_COMPUTE_WORK_GROUP_SIZE: + { + const sh::WorkGroupSize &localSize = program->getComputeShaderLocalSize(); + params[0] = localSize[0]; + params[1] = localSize[1]; + params[2] = localSize[2]; + } + break; + case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS: + *params = program->getActiveAtomicCounterBufferCount(); + break; + case GL_GEOMETRY_LINKED_INPUT_TYPE_EXT: + *params = ToGLenum(program->getGeometryShaderInputPrimitiveType()); + break; + case GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT: + *params = ToGLenum(program->getGeometryShaderOutputPrimitiveType()); + break; + case GL_GEOMETRY_LINKED_VERTICES_OUT_EXT: + *params = program->getGeometryShaderMaxVertices(); + break; + case GL_GEOMETRY_SHADER_INVOCATIONS_EXT: + *params = program->getGeometryShaderInvocations(); + break; + case GL_TESS_CONTROL_OUTPUT_VERTICES_EXT: + *params = program->getTessControlShaderVertices(); + break; + case GL_TESS_GEN_MODE_EXT: + *params = program->getTessGenMode(); + break; + case GL_TESS_GEN_SPACING_EXT: + *params = program->getTessGenSpacing() ? program->getTessGenSpacing() : GL_EQUAL; + break; + case GL_TESS_GEN_VERTEX_ORDER: + *params = program->getTessGenVertexOrder() ? program->getTessGenVertexOrder() : GL_CCW; + break; + case GL_TESS_GEN_POINT_MODE_EXT: + *params = program->getTessGenPointMode() ? GL_TRUE : GL_FALSE; + break; + default: + UNREACHABLE(); + break; + } +} + +void QueryRenderbufferiv(const Context *context, + const Renderbuffer *renderbuffer, + GLenum pname, + GLint *params) +{ + ASSERT(renderbuffer != nullptr); + + switch (pname) + { + case GL_RENDERBUFFER_WIDTH: + *params = renderbuffer->getWidth(); + break; + case GL_RENDERBUFFER_HEIGHT: + *params = renderbuffer->getHeight(); + break; + case GL_RENDERBUFFER_INTERNAL_FORMAT: + // Special case the WebGL 1 DEPTH_STENCIL format. + if (context->isWebGL1() && + renderbuffer->getFormat().info->internalFormat == GL_DEPTH24_STENCIL8) + { + *params = GL_DEPTH_STENCIL; + } + else + { + *params = renderbuffer->getFormat().info->internalFormat; + } + break; + case GL_RENDERBUFFER_RED_SIZE: + *params = renderbuffer->getRedSize(); + break; + case GL_RENDERBUFFER_GREEN_SIZE: + *params = renderbuffer->getGreenSize(); + break; + case GL_RENDERBUFFER_BLUE_SIZE: + *params = renderbuffer->getBlueSize(); + break; + case GL_RENDERBUFFER_ALPHA_SIZE: + *params = renderbuffer->getAlphaSize(); + break; + case GL_RENDERBUFFER_DEPTH_SIZE: + *params = renderbuffer->getDepthSize(); + break; + case GL_RENDERBUFFER_STENCIL_SIZE: + *params = renderbuffer->getStencilSize(); + break; + case GL_RENDERBUFFER_SAMPLES_ANGLE: + *params = renderbuffer->getState().getSamples(); + break; + case GL_MEMORY_SIZE_ANGLE: + *params = renderbuffer->getMemorySize(); + break; + case GL_IMPLEMENTATION_COLOR_READ_FORMAT: + *params = static_cast(renderbuffer->getImplementationColorReadFormat(context)); + break; + case GL_IMPLEMENTATION_COLOR_READ_TYPE: + *params = static_cast(renderbuffer->getImplementationColorReadType(context)); + break; + case GL_RESOURCE_INITIALIZED_ANGLE: + *params = (renderbuffer->initState(GL_NONE, ImageIndex()) == InitState::Initialized); + break; + default: + UNREACHABLE(); + break; + } +} + +void QueryShaderiv(const Context *context, Shader *shader, GLenum pname, GLint *params) +{ + ASSERT(shader != nullptr || pname == GL_COMPLETION_STATUS_KHR); + + switch (pname) + { + case GL_SHADER_TYPE: + *params = static_cast(ToGLenum(shader->getType())); + return; + case GL_DELETE_STATUS: + *params = shader->isFlaggedForDeletion(); + return; + case GL_COMPILE_STATUS: + *params = shader->isCompiled(context) ? GL_TRUE : GL_FALSE; + return; + case GL_COMPLETION_STATUS_KHR: + if (context->isContextLost()) + { + *params = GL_TRUE; + } + else + { + *params = shader->isCompleted() ? GL_TRUE : GL_FALSE; + } + return; + case GL_INFO_LOG_LENGTH: + *params = shader->getInfoLogLength(context); + return; + case GL_SHADER_SOURCE_LENGTH: + *params = shader->getSourceLength(); + return; + case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE: + *params = shader->getTranslatedSourceWithDebugInfoLength(context); + return; + default: + UNREACHABLE(); + break; + } +} + +void QueryTexLevelParameterfv(const Texture *texture, + TextureTarget target, + GLint level, + GLenum pname, + GLfloat *params) +{ + QueryTexLevelParameterBase(texture, target, level, pname, params); +} + +void QueryTexLevelParameteriv(const Texture *texture, + TextureTarget target, + GLint level, + GLenum pname, + GLint *params) +{ + QueryTexLevelParameterBase(texture, target, level, pname, params); +} + +void QueryTexParameterfv(const Context *context, + const Texture *texture, + GLenum pname, + GLfloat *params) +{ + QueryTexParameterBase(context, texture, pname, params); +} + +void QueryTexParameterxv(const Context *context, + const Texture *texture, + GLenum pname, + GLfixed *params) +{ + QueryTexParameterBase(context, texture, pname, params); +} + +void QueryTexParameteriv(const Context *context, + const Texture *texture, + GLenum pname, + GLint *params) +{ + QueryTexParameterBase(context, texture, pname, params); +} + +void QueryTexParameterIiv(const Context *context, + const Texture *texture, + GLenum pname, + GLint *params) +{ + QueryTexParameterBase(context, texture, pname, params); +} + +void QueryTexParameterIuiv(const Context *context, + const Texture *texture, + GLenum pname, + GLuint *params) +{ + QueryTexParameterBase(context, texture, pname, params); +} + +void QuerySamplerParameterfv(const Sampler *sampler, GLenum pname, GLfloat *params) +{ + QuerySamplerParameterBase(sampler, pname, params); +} + +void QuerySamplerParameteriv(const Sampler *sampler, GLenum pname, GLint *params) +{ + QuerySamplerParameterBase(sampler, pname, params); +} + +void QuerySamplerParameterIiv(const Sampler *sampler, GLenum pname, GLint *params) +{ + QuerySamplerParameterBase(sampler, pname, params); +} + +void QuerySamplerParameterIuiv(const Sampler *sampler, GLenum pname, GLuint *params) +{ + QuerySamplerParameterBase(sampler, pname, params); +} + +void QueryVertexAttribfv(const VertexAttribute &attrib, + const VertexBinding &binding, + const VertexAttribCurrentValueData ¤tValueData, + GLenum pname, + GLfloat *params) +{ + QueryVertexAttribBase(attrib, binding, currentValueData.Values.FloatValues, pname, params); +} + +void QueryVertexAttribiv(const VertexAttribute &attrib, + const VertexBinding &binding, + const VertexAttribCurrentValueData ¤tValueData, + GLenum pname, + GLint *params) +{ + QueryVertexAttribBase(attrib, binding, currentValueData.Values.FloatValues, pname, params); +} + +void QueryVertexAttribPointerv(const VertexAttribute &attrib, GLenum pname, void **pointer) +{ + switch (pname) + { + case GL_VERTEX_ATTRIB_ARRAY_POINTER: + *pointer = const_cast(attrib.pointer); + break; + + default: + UNREACHABLE(); + break; + } +} + +void QueryVertexAttribIiv(const VertexAttribute &attrib, + const VertexBinding &binding, + const VertexAttribCurrentValueData ¤tValueData, + GLenum pname, + GLint *params) +{ + QueryVertexAttribBase(attrib, binding, currentValueData.Values.IntValues, pname, params); +} + +void QueryVertexAttribIuiv(const VertexAttribute &attrib, + const VertexBinding &binding, + const VertexAttribCurrentValueData ¤tValueData, + GLenum pname, + GLuint *params) +{ + QueryVertexAttribBase(attrib, binding, currentValueData.Values.UnsignedIntValues, pname, + params); +} + +void QueryActiveUniformBlockiv(const Program *program, + UniformBlockIndex uniformBlockIndex, + GLenum pname, + GLint *params) +{ + GLenum prop = GetUniformBlockPropertyEnum(pname); + QueryProgramResourceiv(program, GL_UNIFORM_BLOCK, uniformBlockIndex, 1, &prop, + std::numeric_limits::max(), nullptr, params); +} + +void QueryInternalFormativ(const TextureCaps &format, GLenum pname, GLsizei bufSize, GLint *params) +{ + switch (pname) + { + case GL_NUM_SAMPLE_COUNTS: + if (bufSize != 0) + { + *params = clampCast(format.sampleCounts.size()); + } + break; + + case GL_SAMPLES: + { + size_t returnCount = std::min(bufSize, format.sampleCounts.size()); + auto sampleReverseIt = format.sampleCounts.rbegin(); + for (size_t sampleIndex = 0; sampleIndex < returnCount; ++sampleIndex) + { + params[sampleIndex] = *sampleReverseIt++; + } + } + break; + + default: + UNREACHABLE(); + break; + } +} + +void QueryFramebufferParameteriv(const Framebuffer *framebuffer, GLenum pname, GLint *params) +{ + ASSERT(framebuffer); + + switch (pname) + { + case GL_FRAMEBUFFER_DEFAULT_WIDTH: + *params = framebuffer->getDefaultWidth(); + break; + case GL_FRAMEBUFFER_DEFAULT_HEIGHT: + *params = framebuffer->getDefaultHeight(); + break; + case GL_FRAMEBUFFER_DEFAULT_SAMPLES: + *params = framebuffer->getDefaultSamples(); + break; + case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS: + *params = ConvertToGLBoolean(framebuffer->getDefaultFixedSampleLocations()); + break; + case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT: + *params = framebuffer->getDefaultLayers(); + break; + case GL_FRAMEBUFFER_FLIP_Y_MESA: + *params = ConvertToGLBoolean(framebuffer->getFlipY()); + break; + default: + UNREACHABLE(); + break; + } +} + +angle::Result QuerySynciv(const Context *context, + const Sync *sync, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *values) +{ + ASSERT(sync != nullptr || pname == GL_SYNC_STATUS); + + // All queries return one value, exit early if the buffer can't fit anything. + if (bufSize < 1) + { + if (length != nullptr) + { + *length = 0; + } + return angle::Result::Continue; + } + + switch (pname) + { + case GL_OBJECT_TYPE: + *values = clampCast(GL_SYNC_FENCE); + break; + case GL_SYNC_CONDITION: + *values = clampCast(sync->getCondition()); + break; + case GL_SYNC_FLAGS: + *values = clampCast(sync->getFlags()); + break; + case GL_SYNC_STATUS: + if (context->isContextLost()) + { + *values = GL_SIGNALED; + } + else + { + ANGLE_TRY(sync->getStatus(context, values)); + } + break; + + default: + UNREACHABLE(); + break; + } + + if (length != nullptr) + { + *length = 1; + } + + return angle::Result::Continue; +} + +void SetTexParameterx(Context *context, Texture *texture, GLenum pname, GLfixed param) +{ + SetTexParameterBase(context, texture, pname, ¶m); +} + +void SetTexParameterxv(Context *context, Texture *texture, GLenum pname, const GLfixed *params) +{ + SetTexParameterBase(context, texture, pname, params); +} + +void SetTexParameterf(Context *context, Texture *texture, GLenum pname, GLfloat param) +{ + SetTexParameterBase(context, texture, pname, ¶m); +} + +void SetTexParameterfv(Context *context, Texture *texture, GLenum pname, const GLfloat *params) +{ + SetTexParameterBase(context, texture, pname, params); +} + +void SetTexParameteri(Context *context, Texture *texture, GLenum pname, GLint param) +{ + SetTexParameterBase(context, texture, pname, ¶m); +} + +void SetTexParameteriv(Context *context, Texture *texture, GLenum pname, const GLint *params) +{ + SetTexParameterBase(context, texture, pname, params); +} + +void SetTexParameterIiv(Context *context, Texture *texture, GLenum pname, const GLint *params) +{ + SetTexParameterBase(context, texture, pname, params); +} + +void SetTexParameterIuiv(Context *context, Texture *texture, GLenum pname, const GLuint *params) +{ + SetTexParameterBase(context, texture, pname, params); +} + +void SetSamplerParameterf(Context *context, Sampler *sampler, GLenum pname, GLfloat param) +{ + SetSamplerParameterBase(context, sampler, pname, ¶m); +} + +void SetSamplerParameterfv(Context *context, Sampler *sampler, GLenum pname, const GLfloat *params) +{ + SetSamplerParameterBase(context, sampler, pname, params); +} + +void SetSamplerParameteri(Context *context, Sampler *sampler, GLenum pname, GLint param) +{ + SetSamplerParameterBase(context, sampler, pname, ¶m); +} + +void SetSamplerParameteriv(Context *context, Sampler *sampler, GLenum pname, const GLint *params) +{ + SetSamplerParameterBase(context, sampler, pname, params); +} + +void SetSamplerParameterIiv(Context *context, Sampler *sampler, GLenum pname, const GLint *params) +{ + SetSamplerParameterBase(context, sampler, pname, params); +} + +void SetSamplerParameterIuiv(Context *context, Sampler *sampler, GLenum pname, const GLuint *params) +{ + SetSamplerParameterBase(context, sampler, pname, params); +} + +void SetFramebufferParameteri(const Context *context, + Framebuffer *framebuffer, + GLenum pname, + GLint param) +{ + ASSERT(framebuffer); + + switch (pname) + { + case GL_FRAMEBUFFER_DEFAULT_WIDTH: + framebuffer->setDefaultWidth(context, param); + break; + case GL_FRAMEBUFFER_DEFAULT_HEIGHT: + framebuffer->setDefaultHeight(context, param); + break; + case GL_FRAMEBUFFER_DEFAULT_SAMPLES: + framebuffer->setDefaultSamples(context, param); + break; + case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS: + framebuffer->setDefaultFixedSampleLocations(context, ConvertToBool(param)); + break; + case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT: + framebuffer->setDefaultLayers(param); + break; + case GL_FRAMEBUFFER_FLIP_Y_MESA: + framebuffer->setFlipY(ConvertToBool(param)); + break; + default: + UNREACHABLE(); + break; + } +} + +void SetProgramParameteri(Program *program, GLenum pname, GLint value) +{ + ASSERT(program); + + switch (pname) + { + case GL_PROGRAM_BINARY_RETRIEVABLE_HINT: + program->setBinaryRetrievableHint(ConvertToBool(value)); + break; + case GL_PROGRAM_SEPARABLE: + program->setSeparable(ConvertToBool(value)); + break; + default: + UNREACHABLE(); + break; + } +} + +GLint GetUniformResourceProperty(const Program *program, GLuint index, const GLenum prop) +{ + const auto &uniform = program->getUniformByIndex(index); + GLenum resourceProp = GetUniformPropertyEnum(prop); + switch (resourceProp) + { + case GL_TYPE: + case GL_ARRAY_SIZE: + case GL_NAME_LENGTH: + return GetCommonVariableProperty(uniform, resourceProp); + + case GL_LOCATION: + return program->getUniformLocation(uniform.name).value; + + case GL_BLOCK_INDEX: + return (uniform.isAtomicCounter() ? -1 : uniform.bufferIndex); + + case GL_OFFSET: + return uniform.blockInfo.offset; + + case GL_ARRAY_STRIDE: + return uniform.blockInfo.arrayStride; + + case GL_MATRIX_STRIDE: + return uniform.blockInfo.matrixStride; + + case GL_IS_ROW_MAJOR: + return static_cast(uniform.blockInfo.isRowMajorMatrix); + + case GL_REFERENCED_BY_VERTEX_SHADER: + return uniform.isActive(ShaderType::Vertex); + + case GL_REFERENCED_BY_FRAGMENT_SHADER: + return uniform.isActive(ShaderType::Fragment); + + case GL_REFERENCED_BY_COMPUTE_SHADER: + return uniform.isActive(ShaderType::Compute); + + case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT: + return uniform.isActive(ShaderType::Geometry); + + case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT: + return uniform.isActive(ShaderType::TessControl); + + case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT: + return uniform.isActive(ShaderType::TessEvaluation); + + case GL_ATOMIC_COUNTER_BUFFER_INDEX: + return (uniform.isAtomicCounter() ? uniform.bufferIndex : -1); + + default: + UNREACHABLE(); + return 0; + } +} + +GLint GetBufferVariableResourceProperty(const Program *program, GLuint index, const GLenum prop) +{ + const BufferVariable &bufferVariable = program->getBufferVariableByIndex(index); + switch (prop) + { + case GL_TYPE: + case GL_ARRAY_SIZE: + case GL_NAME_LENGTH: + return GetCommonVariableProperty(bufferVariable, prop); + + case GL_BLOCK_INDEX: + return bufferVariable.bufferIndex; + + case GL_OFFSET: + return bufferVariable.blockInfo.offset; + + case GL_ARRAY_STRIDE: + return bufferVariable.blockInfo.arrayStride; + + case GL_MATRIX_STRIDE: + return bufferVariable.blockInfo.matrixStride; + + case GL_IS_ROW_MAJOR: + return static_cast(bufferVariable.blockInfo.isRowMajorMatrix); + + case GL_REFERENCED_BY_VERTEX_SHADER: + return bufferVariable.isActive(ShaderType::Vertex); + + case GL_REFERENCED_BY_FRAGMENT_SHADER: + return bufferVariable.isActive(ShaderType::Fragment); + + case GL_REFERENCED_BY_COMPUTE_SHADER: + return bufferVariable.isActive(ShaderType::Compute); + + case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT: + return bufferVariable.isActive(ShaderType::Geometry); + + case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT: + return bufferVariable.isActive(ShaderType::TessControl); + + case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT: + return bufferVariable.isActive(ShaderType::TessEvaluation); + + case GL_TOP_LEVEL_ARRAY_SIZE: + return bufferVariable.topLevelArraySize; + + case GL_TOP_LEVEL_ARRAY_STRIDE: + return bufferVariable.blockInfo.topLevelArrayStride; + + default: + UNREACHABLE(); + return 0; + } +} + +GLuint QueryProgramResourceIndex(const Program *program, + GLenum programInterface, + const GLchar *name) +{ + switch (programInterface) + { + case GL_PROGRAM_INPUT: + return program->getInputResourceIndex(name); + + case GL_PROGRAM_OUTPUT: + return program->getOutputResourceIndex(name); + + case GL_UNIFORM: + return program->getState().getUniformIndexFromName(name); + + case GL_BUFFER_VARIABLE: + return program->getState().getBufferVariableIndexFromName(name); + + case GL_SHADER_STORAGE_BLOCK: + return program->getShaderStorageBlockIndex(name); + + case GL_UNIFORM_BLOCK: + return program->getUniformBlockIndex(name); + + case GL_TRANSFORM_FEEDBACK_VARYING: + return program->getTransformFeedbackVaryingResourceIndex(name); + + default: + UNREACHABLE(); + return GL_INVALID_INDEX; + } +} + +void QueryProgramResourceName(const Context *context, + const Program *program, + GLenum programInterface, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name) +{ + switch (programInterface) + { + case GL_PROGRAM_INPUT: + program->getInputResourceName(index, bufSize, length, name); + break; + + case GL_PROGRAM_OUTPUT: + program->getOutputResourceName(index, bufSize, length, name); + break; + + case GL_UNIFORM: + program->getUniformResourceName(index, bufSize, length, name); + break; + + case GL_BUFFER_VARIABLE: + program->getBufferVariableResourceName(index, bufSize, length, name); + break; + + case GL_SHADER_STORAGE_BLOCK: + program->getActiveShaderStorageBlockName(index, bufSize, length, name); + break; + + case GL_UNIFORM_BLOCK: + program->getActiveUniformBlockName(context, {index}, bufSize, length, name); + break; + + case GL_TRANSFORM_FEEDBACK_VARYING: + program->getTransformFeedbackVarying(index, bufSize, length, nullptr, nullptr, name); + break; + + default: + UNREACHABLE(); + } +} + +GLint QueryProgramResourceLocation(const Program *program, + GLenum programInterface, + const GLchar *name) +{ + switch (programInterface) + { + case GL_PROGRAM_INPUT: + return program->getInputResourceLocation(name); + + case GL_PROGRAM_OUTPUT: + return program->getOutputResourceLocation(name); + + case GL_UNIFORM: + return program->getUniformLocation(name).value; + + default: + UNREACHABLE(); + return -1; + } +} + +void QueryProgramResourceiv(const Program *program, + GLenum programInterface, + UniformBlockIndex index, + GLsizei propCount, + const GLenum *props, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + if (!program->isLinked()) + { + return; + } + + if (length != nullptr) + { + *length = 0; + } + + if (bufSize == 0) + { + // No room to write the results + return; + } + + GLsizei pos = 0; + for (GLsizei i = 0; i < propCount; i++) + { + switch (programInterface) + { + case GL_PROGRAM_INPUT: + params[i] = GetInputResourceProperty(program, index.value, props[i]); + ++pos; + break; + + case GL_PROGRAM_OUTPUT: + params[i] = GetOutputResourceProperty(program, index.value, props[i]); + ++pos; + break; + + case GL_UNIFORM: + params[i] = GetUniformResourceProperty(program, index.value, props[i]); + ++pos; + break; + + case GL_BUFFER_VARIABLE: + params[i] = GetBufferVariableResourceProperty(program, index.value, props[i]); + ++pos; + break; + + case GL_UNIFORM_BLOCK: + GetUniformBlockResourceProperty(program, index.value, props[i], params, bufSize, + &pos); + break; + + case GL_SHADER_STORAGE_BLOCK: + GetShaderStorageBlockResourceProperty(program, index.value, props[i], params, + bufSize, &pos); + break; + + case GL_ATOMIC_COUNTER_BUFFER: + GetAtomicCounterBufferResourceProperty(program, index.value, props[i], params, + bufSize, &pos); + break; + + case GL_TRANSFORM_FEEDBACK_VARYING: + params[i] = + GetTransformFeedbackVaryingResourceProperty(program, index.value, props[i]); + ++pos; + break; + + default: + UNREACHABLE(); + params[i] = GL_INVALID_VALUE; + } + if (pos == bufSize) + { + // Most properties return one value, but GL_ACTIVE_VARIABLES returns an array of values. + // This checks not to break buffer bounds for such case. + break; + } + } + + if (length != nullptr) + { + *length = pos; + } +} + +void QueryProgramInterfaceiv(const Program *program, + GLenum programInterface, + GLenum pname, + GLint *params) +{ + switch (pname) + { + case GL_ACTIVE_RESOURCES: + *params = QueryProgramInterfaceActiveResources(program, programInterface); + break; + + case GL_MAX_NAME_LENGTH: + *params = QueryProgramInterfaceMaxNameLength(program, programInterface); + break; + + case GL_MAX_NUM_ACTIVE_VARIABLES: + *params = QueryProgramInterfaceMaxNumActiveVariables(program, programInterface); + break; + + default: + UNREACHABLE(); + } +} + +angle::Result SetMemoryObjectParameteriv(const Context *context, + MemoryObject *memoryObject, + GLenum pname, + const GLint *params) +{ + switch (pname) + { + case GL_DEDICATED_MEMORY_OBJECT_EXT: + ANGLE_TRY(memoryObject->setDedicatedMemory(context, ConvertToBool(params[0]))); + break; + + case GL_PROTECTED_MEMORY_OBJECT_EXT: + ANGLE_TRY(memoryObject->setProtectedMemory(context, ConvertToBool(params[0]))); + break; + + default: + UNREACHABLE(); + } + + return angle::Result::Continue; +} + +void QueryMemoryObjectParameteriv(const MemoryObject *memoryObject, GLenum pname, GLint *params) +{ + switch (pname) + { + case GL_DEDICATED_MEMORY_OBJECT_EXT: + *params = memoryObject->isDedicatedMemory(); + break; + + case GL_PROTECTED_MEMORY_OBJECT_EXT: + *params = memoryObject->isProtectedMemory(); + break; + + default: + UNREACHABLE(); + } +} + +ClientVertexArrayType ParamToVertexArrayType(GLenum param) +{ + switch (param) + { + case GL_VERTEX_ARRAY: + case GL_VERTEX_ARRAY_BUFFER_BINDING: + case GL_VERTEX_ARRAY_STRIDE: + case GL_VERTEX_ARRAY_SIZE: + case GL_VERTEX_ARRAY_TYPE: + case GL_VERTEX_ARRAY_POINTER: + return ClientVertexArrayType::Vertex; + case GL_NORMAL_ARRAY: + case GL_NORMAL_ARRAY_BUFFER_BINDING: + case GL_NORMAL_ARRAY_STRIDE: + case GL_NORMAL_ARRAY_TYPE: + case GL_NORMAL_ARRAY_POINTER: + return ClientVertexArrayType::Normal; + case GL_COLOR_ARRAY: + case GL_COLOR_ARRAY_BUFFER_BINDING: + case GL_COLOR_ARRAY_STRIDE: + case GL_COLOR_ARRAY_SIZE: + case GL_COLOR_ARRAY_TYPE: + case GL_COLOR_ARRAY_POINTER: + return ClientVertexArrayType::Color; + case GL_POINT_SIZE_ARRAY_OES: + case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES: + case GL_POINT_SIZE_ARRAY_STRIDE_OES: + case GL_POINT_SIZE_ARRAY_TYPE_OES: + case GL_POINT_SIZE_ARRAY_POINTER_OES: + return ClientVertexArrayType::PointSize; + case GL_TEXTURE_COORD_ARRAY: + case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING: + case GL_TEXTURE_COORD_ARRAY_STRIDE: + case GL_TEXTURE_COORD_ARRAY_SIZE: + case GL_TEXTURE_COORD_ARRAY_TYPE: + case GL_TEXTURE_COORD_ARRAY_POINTER: + return ClientVertexArrayType::TextureCoord; + default: + UNREACHABLE(); + return ClientVertexArrayType::InvalidEnum; + } +} + +void SetLightModelParameters(GLES1State *state, GLenum pname, const GLfloat *params) +{ + LightModelParameters &lightModel = state->lightModelParameters(); + + switch (pname) + { + case GL_LIGHT_MODEL_AMBIENT: + lightModel.color = ColorF::fromData(params); + break; + case GL_LIGHT_MODEL_TWO_SIDE: + lightModel.twoSided = *params == 1.0f ? true : false; + break; + default: + break; + } +} + +void GetLightModelParameters(const GLES1State *state, GLenum pname, GLfloat *params) +{ + const LightModelParameters &lightModel = state->lightModelParameters(); + + switch (pname) + { + case GL_LIGHT_MODEL_TWO_SIDE: + *params = lightModel.twoSided ? 1.0f : 0.0f; + break; + case GL_LIGHT_MODEL_AMBIENT: + lightModel.color.writeData(params); + break; + default: + break; + } +} + +bool IsLightModelTwoSided(const GLES1State *state) +{ + return state->lightModelParameters().twoSided; +} + +void SetLightParameters(GLES1State *state, + GLenum light, + LightParameter pname, + const GLfloat *params) +{ + uint32_t lightIndex = light - GL_LIGHT0; + + LightParameters &lightParams = state->lightParameters(lightIndex); + + switch (pname) + { + case LightParameter::Ambient: + lightParams.ambient = ColorF::fromData(params); + break; + case LightParameter::Diffuse: + lightParams.diffuse = ColorF::fromData(params); + break; + case LightParameter::Specular: + lightParams.specular = ColorF::fromData(params); + break; + case LightParameter::Position: + { + angle::Mat4 mv = state->getModelviewMatrix(); + angle::Vector4 transformedPos = + mv.product(angle::Vector4(params[0], params[1], params[2], params[3])); + lightParams.position[0] = transformedPos[0]; + lightParams.position[1] = transformedPos[1]; + lightParams.position[2] = transformedPos[2]; + lightParams.position[3] = transformedPos[3]; + } + break; + case LightParameter::SpotDirection: + { + angle::Mat4 mv = state->getModelviewMatrix(); + angle::Vector4 transformedPos = + mv.product(angle::Vector4(params[0], params[1], params[2], 0.0f)); + lightParams.direction[0] = transformedPos[0]; + lightParams.direction[1] = transformedPos[1]; + lightParams.direction[2] = transformedPos[2]; + } + break; + case LightParameter::SpotExponent: + lightParams.spotlightExponent = *params; + break; + case LightParameter::SpotCutoff: + lightParams.spotlightCutoffAngle = *params; + break; + case LightParameter::ConstantAttenuation: + lightParams.attenuationConst = *params; + break; + case LightParameter::LinearAttenuation: + lightParams.attenuationLinear = *params; + break; + case LightParameter::QuadraticAttenuation: + lightParams.attenuationQuadratic = *params; + break; + default: + return; + } +} + +void GetLightParameters(const GLES1State *state, + GLenum light, + LightParameter pname, + GLfloat *params) +{ + uint32_t lightIndex = light - GL_LIGHT0; + const LightParameters &lightParams = state->lightParameters(lightIndex); + + switch (pname) + { + case LightParameter::Ambient: + lightParams.ambient.writeData(params); + break; + case LightParameter::Diffuse: + lightParams.diffuse.writeData(params); + break; + case LightParameter::Specular: + lightParams.specular.writeData(params); + break; + case LightParameter::Position: + memcpy(params, lightParams.position.data(), 4 * sizeof(GLfloat)); + break; + case LightParameter::SpotDirection: + memcpy(params, lightParams.direction.data(), 3 * sizeof(GLfloat)); + break; + case LightParameter::SpotExponent: + *params = lightParams.spotlightExponent; + break; + case LightParameter::SpotCutoff: + *params = lightParams.spotlightCutoffAngle; + break; + case LightParameter::ConstantAttenuation: + *params = lightParams.attenuationConst; + break; + case LightParameter::LinearAttenuation: + *params = lightParams.attenuationLinear; + break; + case LightParameter::QuadraticAttenuation: + *params = lightParams.attenuationQuadratic; + break; + default: + break; + } +} + +void SetMaterialParameters(GLES1State *state, + GLenum face, + MaterialParameter pname, + const GLfloat *params) +{ + // Note: Ambient and diffuse colors are inherited from glColor when COLOR_MATERIAL is enabled, + // and can only be modified by this function if that is disabled: + // + // > the replaced values remain until changed by either sending a new color or by setting a + // > new material value when COLOR_MATERIAL is not currently enabled, to override that + // particular value. + + MaterialParameters &material = state->materialParameters(); + switch (pname) + { + case MaterialParameter::Ambient: + if (!state->isColorMaterialEnabled()) + { + material.ambient = ColorF::fromData(params); + } + break; + case MaterialParameter::Diffuse: + if (!state->isColorMaterialEnabled()) + { + material.diffuse = ColorF::fromData(params); + } + break; + case MaterialParameter::AmbientAndDiffuse: + if (!state->isColorMaterialEnabled()) + { + material.ambient = ColorF::fromData(params); + material.diffuse = ColorF::fromData(params); + } + break; + case MaterialParameter::Specular: + material.specular = ColorF::fromData(params); + break; + case MaterialParameter::Emission: + material.emissive = ColorF::fromData(params); + break; + case MaterialParameter::Shininess: + material.specularExponent = *params; + break; + default: + return; + } +} + +void GetMaterialParameters(const GLES1State *state, + GLenum face, + MaterialParameter pname, + GLfloat *params) +{ + const ColorF ¤tColor = state->getCurrentColor(); + const MaterialParameters &material = state->materialParameters(); + const bool colorMaterialEnabled = state->isColorMaterialEnabled(); + + switch (pname) + { + case MaterialParameter::Ambient: + if (colorMaterialEnabled) + { + currentColor.writeData(params); + } + else + { + material.ambient.writeData(params); + } + break; + case MaterialParameter::Diffuse: + if (colorMaterialEnabled) + { + currentColor.writeData(params); + } + else + { + material.diffuse.writeData(params); + } + break; + case MaterialParameter::Specular: + material.specular.writeData(params); + break; + case MaterialParameter::Emission: + material.emissive.writeData(params); + break; + case MaterialParameter::Shininess: + *params = material.specularExponent; + break; + default: + return; + } +} + +unsigned int GetLightModelParameterCount(GLenum pname) +{ + switch (pname) + { + case GL_LIGHT_MODEL_AMBIENT: + return 4; + case GL_LIGHT_MODEL_TWO_SIDE: + return 1; + default: + UNREACHABLE(); + return 0; + } +} + +unsigned int GetLightParameterCount(LightParameter pname) +{ + switch (pname) + { + case LightParameter::Ambient: + case LightParameter::Diffuse: + case LightParameter::AmbientAndDiffuse: + case LightParameter::Specular: + case LightParameter::Position: + return 4; + case LightParameter::SpotDirection: + return 3; + case LightParameter::SpotExponent: + case LightParameter::SpotCutoff: + case LightParameter::ConstantAttenuation: + case LightParameter::LinearAttenuation: + case LightParameter::QuadraticAttenuation: + return 1; + default: + UNREACHABLE(); + return 0; + } +} + +unsigned int GetMaterialParameterCount(MaterialParameter pname) +{ + switch (pname) + { + case MaterialParameter::Ambient: + case MaterialParameter::Diffuse: + case MaterialParameter::AmbientAndDiffuse: + case MaterialParameter::Specular: + case MaterialParameter::Emission: + return 4; + case MaterialParameter::Shininess: + return 1; + default: + UNREACHABLE(); + return 0; + } +} + +void SetFogParameters(GLES1State *state, GLenum pname, const GLfloat *params) +{ + FogParameters &fog = state->fogParameters(); + switch (pname) + { + case GL_FOG_MODE: + fog.mode = FromGLenum(static_cast(params[0])); + break; + case GL_FOG_DENSITY: + fog.density = params[0]; + break; + case GL_FOG_START: + fog.start = params[0]; + break; + case GL_FOG_END: + fog.end = params[0]; + break; + case GL_FOG_COLOR: + fog.color = ColorF::fromData(params); + break; + default: + return; + } +} + +void GetFogParameters(const GLES1State *state, GLenum pname, GLfloat *params) +{ + const FogParameters &fog = state->fogParameters(); + switch (pname) + { + case GL_FOG_MODE: + params[0] = static_cast(ToGLenum(fog.mode)); + break; + case GL_FOG_DENSITY: + params[0] = fog.density; + break; + case GL_FOG_START: + params[0] = fog.start; + break; + case GL_FOG_END: + params[0] = fog.end; + break; + case GL_FOG_COLOR: + fog.color.writeData(params); + break; + default: + return; + } +} + +unsigned int GetFogParameterCount(GLenum pname) +{ + switch (pname) + { + case GL_FOG_MODE: + case GL_FOG_DENSITY: + case GL_FOG_START: + case GL_FOG_END: + return 1; + case GL_FOG_COLOR: + return 4; + default: + return 0; + } +} + +unsigned int GetTextureEnvParameterCount(TextureEnvParameter pname) +{ + switch (pname) + { + case TextureEnvParameter::Mode: + case TextureEnvParameter::CombineRgb: + case TextureEnvParameter::CombineAlpha: + case TextureEnvParameter::Src0Rgb: + case TextureEnvParameter::Src1Rgb: + case TextureEnvParameter::Src2Rgb: + case TextureEnvParameter::Src0Alpha: + case TextureEnvParameter::Src1Alpha: + case TextureEnvParameter::Src2Alpha: + case TextureEnvParameter::Op0Rgb: + case TextureEnvParameter::Op1Rgb: + case TextureEnvParameter::Op2Rgb: + case TextureEnvParameter::Op0Alpha: + case TextureEnvParameter::Op1Alpha: + case TextureEnvParameter::Op2Alpha: + case TextureEnvParameter::RgbScale: + case TextureEnvParameter::AlphaScale: + case TextureEnvParameter::PointCoordReplace: + return 1; + case TextureEnvParameter::Color: + return 4; + default: + return 0; + } +} + +void ConvertTextureEnvFromInt(TextureEnvParameter pname, const GLint *input, GLfloat *output) +{ + if (IsTextureEnvEnumParameter(pname)) + { + ConvertGLenumValue(input[0], output); + return; + } + + switch (pname) + { + case TextureEnvParameter::RgbScale: + case TextureEnvParameter::AlphaScale: + output[0] = static_cast(input[0]); + break; + case TextureEnvParameter::Color: + for (int i = 0; i < 4; i++) + { + output[i] = input[i] / 255.0f; + } + break; + default: + UNREACHABLE(); + break; + } +} + +void ConvertTextureEnvFromFixed(TextureEnvParameter pname, const GLfixed *input, GLfloat *output) +{ + if (IsTextureEnvEnumParameter(pname)) + { + ConvertGLenumValue(input[0], output); + return; + } + + switch (pname) + { + case TextureEnvParameter::RgbScale: + case TextureEnvParameter::AlphaScale: + output[0] = ConvertFixedToFloat(input[0]); + break; + case TextureEnvParameter::Color: + for (int i = 0; i < 4; i++) + { + output[i] = ConvertFixedToFloat(input[i]); + } + break; + default: + UNREACHABLE(); + break; + } +} + +void ConvertTextureEnvToInt(TextureEnvParameter pname, const GLfloat *input, GLint *output) +{ + if (IsTextureEnvEnumParameter(pname)) + { + ConvertGLenumValue(input[0], output); + return; + } + + switch (pname) + { + case TextureEnvParameter::RgbScale: + case TextureEnvParameter::AlphaScale: + output[0] = static_cast(input[0]); + break; + case TextureEnvParameter::Color: + for (int i = 0; i < 4; i++) + { + output[i] = static_cast(input[i] * 255.0f); + } + break; + default: + UNREACHABLE(); + break; + } +} + +void ConvertTextureEnvToFixed(TextureEnvParameter pname, const GLfloat *input, GLfixed *output) +{ + if (IsTextureEnvEnumParameter(pname)) + { + ConvertGLenumValue(input[0], output); + return; + } + + switch (pname) + { + case TextureEnvParameter::RgbScale: + case TextureEnvParameter::AlphaScale: + output[0] = ConvertFloatToFixed(input[0]); + break; + case TextureEnvParameter::Color: + for (int i = 0; i < 4; i++) + { + output[i] = ConvertFloatToFixed(input[i]); + } + break; + default: + UNREACHABLE(); + break; + } +} + +void SetTextureEnv(unsigned int unit, + GLES1State *state, + TextureEnvTarget target, + TextureEnvParameter pname, + const GLfloat *params) +{ + TextureEnvironmentParameters &env = state->textureEnvironment(unit); + GLenum asEnum = ConvertToGLenum(params[0]); + + switch (target) + { + case TextureEnvTarget::Env: + switch (pname) + { + case TextureEnvParameter::Mode: + env.mode = FromGLenum(asEnum); + break; + case TextureEnvParameter::CombineRgb: + env.combineRgb = FromGLenum(asEnum); + break; + case TextureEnvParameter::CombineAlpha: + env.combineAlpha = FromGLenum(asEnum); + break; + case TextureEnvParameter::Src0Rgb: + env.src0Rgb = FromGLenum(asEnum); + break; + case TextureEnvParameter::Src1Rgb: + env.src1Rgb = FromGLenum(asEnum); + break; + case TextureEnvParameter::Src2Rgb: + env.src2Rgb = FromGLenum(asEnum); + break; + case TextureEnvParameter::Src0Alpha: + env.src0Alpha = FromGLenum(asEnum); + break; + case TextureEnvParameter::Src1Alpha: + env.src1Alpha = FromGLenum(asEnum); + break; + case TextureEnvParameter::Src2Alpha: + env.src2Alpha = FromGLenum(asEnum); + break; + case TextureEnvParameter::Op0Rgb: + env.op0Rgb = FromGLenum(asEnum); + break; + case TextureEnvParameter::Op1Rgb: + env.op1Rgb = FromGLenum(asEnum); + break; + case TextureEnvParameter::Op2Rgb: + env.op2Rgb = FromGLenum(asEnum); + break; + case TextureEnvParameter::Op0Alpha: + env.op0Alpha = FromGLenum(asEnum); + break; + case TextureEnvParameter::Op1Alpha: + env.op1Alpha = FromGLenum(asEnum); + break; + case TextureEnvParameter::Op2Alpha: + env.op2Alpha = FromGLenum(asEnum); + break; + case TextureEnvParameter::Color: + env.color = ColorF::fromData(params); + break; + case TextureEnvParameter::RgbScale: + env.rgbScale = params[0]; + break; + case TextureEnvParameter::AlphaScale: + env.alphaScale = params[0]; + break; + default: + UNREACHABLE(); + break; + } + break; + case TextureEnvTarget::PointSprite: + switch (pname) + { + case TextureEnvParameter::PointCoordReplace: + env.pointSpriteCoordReplace = static_cast(params[0]); + break; + default: + UNREACHABLE(); + break; + } + break; + default: + UNREACHABLE(); + break; + } +} + +void GetTextureEnv(unsigned int unit, + const GLES1State *state, + TextureEnvTarget target, + TextureEnvParameter pname, + GLfloat *params) +{ + const TextureEnvironmentParameters &env = state->textureEnvironment(unit); + + switch (target) + { + case TextureEnvTarget::Env: + switch (pname) + { + case TextureEnvParameter::Mode: + ConvertPackedEnum(env.mode, params); + break; + case TextureEnvParameter::CombineRgb: + ConvertPackedEnum(env.combineRgb, params); + break; + case TextureEnvParameter::CombineAlpha: + ConvertPackedEnum(env.combineAlpha, params); + break; + case TextureEnvParameter::Src0Rgb: + ConvertPackedEnum(env.src0Rgb, params); + break; + case TextureEnvParameter::Src1Rgb: + ConvertPackedEnum(env.src1Rgb, params); + break; + case TextureEnvParameter::Src2Rgb: + ConvertPackedEnum(env.src2Rgb, params); + break; + case TextureEnvParameter::Src0Alpha: + ConvertPackedEnum(env.src0Alpha, params); + break; + case TextureEnvParameter::Src1Alpha: + ConvertPackedEnum(env.src1Alpha, params); + break; + case TextureEnvParameter::Src2Alpha: + ConvertPackedEnum(env.src2Alpha, params); + break; + case TextureEnvParameter::Op0Rgb: + ConvertPackedEnum(env.op0Rgb, params); + break; + case TextureEnvParameter::Op1Rgb: + ConvertPackedEnum(env.op1Rgb, params); + break; + case TextureEnvParameter::Op2Rgb: + ConvertPackedEnum(env.op2Rgb, params); + break; + case TextureEnvParameter::Op0Alpha: + ConvertPackedEnum(env.op0Alpha, params); + break; + case TextureEnvParameter::Op1Alpha: + ConvertPackedEnum(env.op1Alpha, params); + break; + case TextureEnvParameter::Op2Alpha: + ConvertPackedEnum(env.op2Alpha, params); + break; + case TextureEnvParameter::Color: + env.color.writeData(params); + break; + case TextureEnvParameter::RgbScale: + *params = env.rgbScale; + break; + case TextureEnvParameter::AlphaScale: + *params = env.alphaScale; + break; + default: + UNREACHABLE(); + break; + } + break; + case TextureEnvTarget::PointSprite: + switch (pname) + { + case TextureEnvParameter::PointCoordReplace: + *params = static_cast(env.pointSpriteCoordReplace); + break; + default: + UNREACHABLE(); + break; + } + break; + default: + UNREACHABLE(); + break; + } +} + +unsigned int GetPointParameterCount(PointParameter pname) +{ + switch (pname) + { + case PointParameter::PointSizeMin: + case PointParameter::PointSizeMax: + case PointParameter::PointFadeThresholdSize: + return 1; + case PointParameter::PointDistanceAttenuation: + return 3; + default: + return 0; + } +} + +void SetPointParameter(GLES1State *state, PointParameter pname, const GLfloat *params) +{ + + PointParameters &pointParams = state->pointParameters(); + + switch (pname) + { + case PointParameter::PointSizeMin: + pointParams.pointSizeMin = params[0]; + break; + case PointParameter::PointSizeMax: + pointParams.pointSizeMax = params[0]; + break; + case PointParameter::PointFadeThresholdSize: + pointParams.pointFadeThresholdSize = params[0]; + break; + case PointParameter::PointDistanceAttenuation: + for (unsigned int i = 0; i < 3; i++) + { + pointParams.pointDistanceAttenuation[i] = params[i]; + } + break; + default: + UNREACHABLE(); + } +} + +void GetPointParameter(const GLES1State *state, PointParameter pname, GLfloat *params) +{ + const PointParameters &pointParams = state->pointParameters(); + + switch (pname) + { + case PointParameter::PointSizeMin: + params[0] = pointParams.pointSizeMin; + break; + case PointParameter::PointSizeMax: + params[0] = pointParams.pointSizeMax; + break; + case PointParameter::PointFadeThresholdSize: + params[0] = pointParams.pointFadeThresholdSize; + break; + case PointParameter::PointDistanceAttenuation: + for (unsigned int i = 0; i < 3; i++) + { + params[i] = pointParams.pointDistanceAttenuation[i]; + } + break; + default: + UNREACHABLE(); + } +} + +void SetPointSize(GLES1State *state, GLfloat size) +{ + PointParameters ¶ms = state->pointParameters(); + params.pointSize = size; +} + +void GetPointSize(const GLES1State *state, GLfloat *sizeOut) +{ + const PointParameters ¶ms = state->pointParameters(); + *sizeOut = params.pointSize; +} + +unsigned int GetTexParameterCount(GLenum pname) +{ + switch (pname) + { + case GL_TEXTURE_CROP_RECT_OES: + case GL_TEXTURE_BORDER_COLOR: + return 4; + case GL_TEXTURE_MAG_FILTER: + case GL_TEXTURE_MIN_FILTER: + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + case GL_TEXTURE_USAGE_ANGLE: + case GL_TEXTURE_MAX_ANISOTROPY_EXT: + case GL_TEXTURE_IMMUTABLE_FORMAT: + case GL_TEXTURE_WRAP_R: + case GL_TEXTURE_IMMUTABLE_LEVELS: + case GL_TEXTURE_SWIZZLE_R: + case GL_TEXTURE_SWIZZLE_G: + case GL_TEXTURE_SWIZZLE_B: + case GL_TEXTURE_SWIZZLE_A: + case GL_TEXTURE_BASE_LEVEL: + case GL_TEXTURE_MAX_LEVEL: + case GL_TEXTURE_MIN_LOD: + case GL_TEXTURE_MAX_LOD: + case GL_TEXTURE_COMPARE_MODE: + case GL_TEXTURE_COMPARE_FUNC: + case GL_TEXTURE_SRGB_DECODE_EXT: + case GL_DEPTH_STENCIL_TEXTURE_MODE: + case GL_TEXTURE_NATIVE_ID_ANGLE: + case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: + return 1; + default: + return 0; + } +} + +bool GetQueryParameterInfo(const State &glState, + GLenum pname, + GLenum *type, + unsigned int *numParams) +{ + const Caps &caps = glState.getCaps(); + const Extensions &extensions = glState.getExtensions(); + GLint clientMajorVersion = glState.getClientMajorVersion(); + EGLenum clientType = glState.getClientType(); + + // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation + // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due + // to the fact that it is stored internally as a float, and so would require conversion + // if returned from Context::getIntegerv. Since this conversion is already implemented + // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we + // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling + // application. + switch (pname) + { + case GL_COMPRESSED_TEXTURE_FORMATS: + { + *type = GL_INT; + *numParams = static_cast(caps.compressedTextureFormats.size()); + return true; + } + case GL_SHADER_BINARY_FORMATS: + { + *type = GL_INT; + *numParams = static_cast(caps.shaderBinaryFormats.size()); + return true; + } + + case GL_MAX_VERTEX_ATTRIBS: + case GL_MAX_VERTEX_UNIFORM_VECTORS: + case GL_MAX_VARYING_VECTORS: + case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: + case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: + case GL_MAX_TEXTURE_IMAGE_UNITS: + case GL_MAX_FRAGMENT_UNIFORM_VECTORS: + case GL_MAX_RENDERBUFFER_SIZE: + case GL_NUM_SHADER_BINARY_FORMATS: + case GL_NUM_COMPRESSED_TEXTURE_FORMATS: + case GL_ARRAY_BUFFER_BINDING: + case GL_FRAMEBUFFER_BINDING: // GL_FRAMEBUFFER_BINDING now equivalent to + // GL_DRAW_FRAMEBUFFER_BINDING + case GL_RENDERBUFFER_BINDING: + case GL_CURRENT_PROGRAM: + case GL_PACK_ALIGNMENT: + case GL_UNPACK_ALIGNMENT: + case GL_GENERATE_MIPMAP_HINT: + case GL_TEXTURE_FILTERING_HINT_CHROMIUM: + case GL_RED_BITS: + case GL_GREEN_BITS: + case GL_BLUE_BITS: + case GL_ALPHA_BITS: + case GL_DEPTH_BITS: + case GL_STENCIL_BITS: + case GL_ELEMENT_ARRAY_BUFFER_BINDING: + case GL_CULL_FACE_MODE: + case GL_FRONT_FACE: + case GL_ACTIVE_TEXTURE: + case GL_STENCIL_FUNC: + case GL_STENCIL_VALUE_MASK: + case GL_STENCIL_REF: + case GL_STENCIL_FAIL: + case GL_STENCIL_PASS_DEPTH_FAIL: + case GL_STENCIL_PASS_DEPTH_PASS: + case GL_STENCIL_BACK_FUNC: + case GL_STENCIL_BACK_VALUE_MASK: + case GL_STENCIL_BACK_REF: + case GL_STENCIL_BACK_FAIL: + case GL_STENCIL_BACK_PASS_DEPTH_FAIL: + case GL_STENCIL_BACK_PASS_DEPTH_PASS: + case GL_DEPTH_FUNC: + case GL_BLEND_SRC_RGB: + case GL_BLEND_SRC_ALPHA: + case GL_BLEND_DST_RGB: + case GL_BLEND_DST_ALPHA: + case GL_BLEND_EQUATION_RGB: + case GL_BLEND_EQUATION_ALPHA: + case GL_STENCIL_WRITEMASK: + case GL_STENCIL_BACK_WRITEMASK: + case GL_STENCIL_CLEAR_VALUE: + case GL_SUBPIXEL_BITS: + case GL_MAX_TEXTURE_SIZE: + case GL_MAX_CUBE_MAP_TEXTURE_SIZE: + case GL_SAMPLE_BUFFERS: + case GL_SAMPLES: + case GL_IMPLEMENTATION_COLOR_READ_TYPE: + case GL_IMPLEMENTATION_COLOR_READ_FORMAT: + case GL_TEXTURE_BINDING_2D: + case GL_TEXTURE_BINDING_CUBE_MAP: + case GL_RESET_NOTIFICATION_STRATEGY_EXT: + { + *type = GL_INT; + *numParams = 1; + return true; + } + case GL_PACK_REVERSE_ROW_ORDER_ANGLE: + { + if (!extensions.packReverseRowOrderANGLE) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + } + case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE: + case GL_TEXTURE_BINDING_RECTANGLE_ANGLE: + { + if (!extensions.textureRectangleANGLE) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + } + case GL_MAX_DRAW_BUFFERS_EXT: + case GL_MAX_COLOR_ATTACHMENTS_EXT: + { + if ((clientMajorVersion < 3) && !extensions.drawBuffersEXT) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + } + case GL_MAX_VIEWPORT_DIMS: + { + *type = GL_INT; + *numParams = 2; + return true; + } + case GL_VIEWPORT: + case GL_SCISSOR_BOX: + { + *type = GL_INT; + *numParams = 4; + return true; + } + case GL_SHADER_COMPILER: + case GL_SAMPLE_COVERAGE_INVERT: + case GL_DEPTH_WRITEMASK: + case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled, + case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries. + case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as + // bool-natural + case GL_SAMPLE_COVERAGE: + case GL_SCISSOR_TEST: + case GL_STENCIL_TEST: + case GL_DEPTH_TEST: + case GL_BLEND: + case GL_DITHER: + case GL_CONTEXT_ROBUST_ACCESS_EXT: + { + *type = GL_BOOL; + *numParams = 1; + return true; + } + case GL_COLOR_LOGIC_OP: + { + if (!extensions.logicOpANGLE) + { + return false; + } + *type = GL_BOOL; + *numParams = 1; + return true; + } + case GL_COLOR_WRITEMASK: + { + *type = GL_BOOL; + *numParams = 4; + return true; + } + case GL_POLYGON_OFFSET_FACTOR: + case GL_POLYGON_OFFSET_UNITS: + case GL_SAMPLE_COVERAGE_VALUE: + case GL_DEPTH_CLEAR_VALUE: + case GL_LINE_WIDTH: + { + *type = GL_FLOAT; + *numParams = 1; + return true; + } + case GL_ALIASED_LINE_WIDTH_RANGE: + case GL_ALIASED_POINT_SIZE_RANGE: + case GL_DEPTH_RANGE: + { + *type = GL_FLOAT; + *numParams = 2; + return true; + } + case GL_COLOR_CLEAR_VALUE: + case GL_BLEND_COLOR: + { + *type = GL_FLOAT; + *numParams = 4; + return true; + } + case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: + if (!extensions.textureFilterAnisotropicEXT) + { + return false; + } + *type = GL_FLOAT; + *numParams = 1; + return true; + case GL_TIMESTAMP_EXT: + if (!extensions.disjointTimerQueryEXT) + { + return false; + } + *type = GL_INT_64_ANGLEX; + *numParams = 1; + return true; + case GL_GPU_DISJOINT_EXT: + if (!extensions.disjointTimerQueryEXT) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + case GL_COVERAGE_MODULATION_CHROMIUM: + if (!extensions.framebufferMixedSamplesCHROMIUM) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + case GL_TEXTURE_BINDING_EXTERNAL_OES: + if (!extensions.EGLStreamConsumerExternalNV && !extensions.EGLImageExternalOES) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + case GL_MAX_CLIP_DISTANCES_EXT: // case GL_MAX_CLIP_PLANES + if (clientMajorVersion < 2) + { + break; + } + if (!extensions.clipDistanceAPPLE && !extensions.clipCullDistanceEXT) + { + // NOTE(hqle): if client version is 1. GL_MAX_CLIP_DISTANCES_EXT is equal + // to GL_MAX_CLIP_PLANES which is a valid enum. + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + case GL_MAX_CULL_DISTANCES_EXT: + case GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT: + if (!extensions.clipCullDistanceEXT) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + case GL_CLIP_ORIGIN_EXT: + case GL_CLIP_DEPTH_MODE_EXT: + if (!extensions.clipControlEXT) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + case GL_PRIMITIVE_BOUNDING_BOX: + if (!extensions.primitiveBoundingBoxAny()) + { + return false; + } + *type = GL_FLOAT; + *numParams = 8; + return true; + case GL_SHADING_RATE_QCOM: + if (!extensions.shadingRateQCOM) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + } + + if (clientType == EGL_OPENGL_API || + (clientType == EGL_OPENGL_ES_API && glState.getClientVersion() >= Version(3, 2))) + { + switch (pname) + { + case GL_CONTEXT_FLAGS: + { + *type = GL_INT; + *numParams = 1; + return true; + } + } + } + + if (clientType == EGL_OPENGL_API) + { + switch (pname) + { + case GL_CONTEXT_PROFILE_MASK: + { + *type = GL_INT; + *numParams = 1; + return true; + } + } + } + + if (extensions.debugKHR) + { + switch (pname) + { + case GL_DEBUG_LOGGED_MESSAGES: + case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH: + case GL_DEBUG_GROUP_STACK_DEPTH: + case GL_MAX_DEBUG_MESSAGE_LENGTH: + case GL_MAX_DEBUG_LOGGED_MESSAGES: + case GL_MAX_DEBUG_GROUP_STACK_DEPTH: + case GL_MAX_LABEL_LENGTH: + *type = GL_INT; + *numParams = 1; + return true; + + case GL_DEBUG_OUTPUT_SYNCHRONOUS: + case GL_DEBUG_OUTPUT: + *type = GL_BOOL; + *numParams = 1; + return true; + } + } + + if (extensions.multisampleCompatibilityEXT) + { + switch (pname) + { + case GL_MULTISAMPLE_EXT: + case GL_SAMPLE_ALPHA_TO_ONE_EXT: + *type = GL_BOOL; + *numParams = 1; + return true; + } + } + + if (extensions.bindGeneratesResourceCHROMIUM) + { + switch (pname) + { + case GL_BIND_GENERATES_RESOURCE_CHROMIUM: + *type = GL_BOOL; + *numParams = 1; + return true; + } + } + + if (extensions.clientArraysANGLE) + { + switch (pname) + { + case GL_CLIENT_ARRAYS_ANGLE: + *type = GL_BOOL; + *numParams = 1; + return true; + } + } + + if (extensions.sRGBWriteControlEXT) + { + switch (pname) + { + case GL_FRAMEBUFFER_SRGB_EXT: + *type = GL_BOOL; + *numParams = 1; + return true; + } + } + + if (extensions.robustResourceInitializationANGLE && + pname == GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE) + { + *type = GL_BOOL; + *numParams = 1; + return true; + } + + if (extensions.programCacheControlANGLE && pname == GL_PROGRAM_CACHE_ENABLED_ANGLE) + { + *type = GL_BOOL; + *numParams = 1; + return true; + } + + if (extensions.parallelShaderCompileKHR && pname == GL_MAX_SHADER_COMPILER_THREADS_KHR) + { + *type = GL_INT; + *numParams = 1; + return true; + } + + if (extensions.blendFuncExtendedEXT && pname == GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT) + { + *type = GL_INT; + *numParams = 1; + return true; + } + + if (extensions.robustFragmentShaderOutputANGLE && + pname == GL_ROBUST_FRAGMENT_SHADER_OUTPUT_ANGLE) + { + *type = GL_BOOL; + *numParams = 1; + return true; + } + + // Check for ES3.0+ parameter names which are also exposed as ES2 extensions + switch (pname) + { + // GL_DRAW_FRAMEBUFFER_BINDING equivalent to GL_FRAMEBUFFER_BINDING + case GL_READ_FRAMEBUFFER_BINDING: + if ((clientMajorVersion < 3) && !extensions.framebufferBlitAny()) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + + case GL_NUM_PROGRAM_BINARY_FORMATS_OES: + if ((clientMajorVersion < 3) && !extensions.getProgramBinaryOES) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + + case GL_PROGRAM_BINARY_FORMATS_OES: + if ((clientMajorVersion < 3) && !extensions.getProgramBinaryOES) + { + return false; + } + *type = GL_INT; + *numParams = static_cast(caps.programBinaryFormats.size()); + return true; + + case GL_PACK_ROW_LENGTH: + case GL_PACK_SKIP_ROWS: + case GL_PACK_SKIP_PIXELS: + if ((clientMajorVersion < 3) && !extensions.packSubimageNV) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + case GL_UNPACK_ROW_LENGTH: + case GL_UNPACK_SKIP_ROWS: + case GL_UNPACK_SKIP_PIXELS: + if ((clientMajorVersion < 3) && !extensions.unpackSubimageEXT) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + case GL_VERTEX_ARRAY_BINDING: + if ((clientMajorVersion < 3) && !extensions.vertexArrayObjectOES) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + case GL_PIXEL_PACK_BUFFER_BINDING: + case GL_PIXEL_UNPACK_BUFFER_BINDING: + if ((clientMajorVersion < 3) && !extensions.pixelBufferObjectNV) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + case GL_MAX_SAMPLES: + { + static_assert(GL_MAX_SAMPLES_ANGLE == GL_MAX_SAMPLES, + "GL_MAX_SAMPLES_ANGLE not equal to GL_MAX_SAMPLES"); + if ((clientMajorVersion < 3) && !(extensions.framebufferMultisampleANGLE || + extensions.multisampledRenderToTextureEXT)) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + + case GL_FRAGMENT_SHADER_DERIVATIVE_HINT: + if ((clientMajorVersion < 3) && !extensions.standardDerivativesOES) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + } + case GL_TEXTURE_BINDING_3D: + if ((clientMajorVersion < 3) && !extensions.texture3DOES) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + case GL_MAX_3D_TEXTURE_SIZE: + if ((clientMajorVersion < 3) && !extensions.texture3DOES) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + } + + if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT) + { + if ((glState.getClientVersion() < Version(3, 0)) && !extensions.drawBuffersEXT) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + } + + if ((extensions.multiview2OVR || extensions.multiviewOVR) && pname == GL_MAX_VIEWS_OVR) + { + *type = GL_INT; + *numParams = 1; + return true; + } + + if (extensions.provokingVertexANGLE && pname == GL_PROVOKING_VERTEX) + { + *type = GL_INT; + *numParams = 1; + return true; + } + + if (glState.getClientVersion() < Version(2, 0)) + { + switch (pname) + { + case GL_ALPHA_TEST_FUNC: + case GL_CLIENT_ACTIVE_TEXTURE: + case GL_MATRIX_MODE: + case GL_MAX_TEXTURE_UNITS: + case GL_MAX_MODELVIEW_STACK_DEPTH: + case GL_MAX_PROJECTION_STACK_DEPTH: + case GL_MAX_TEXTURE_STACK_DEPTH: + case GL_MAX_LIGHTS: + case GL_MAX_CLIP_PLANES: + case GL_VERTEX_ARRAY_STRIDE: + case GL_NORMAL_ARRAY_STRIDE: + case GL_COLOR_ARRAY_STRIDE: + case GL_TEXTURE_COORD_ARRAY_STRIDE: + case GL_VERTEX_ARRAY_SIZE: + case GL_COLOR_ARRAY_SIZE: + case GL_TEXTURE_COORD_ARRAY_SIZE: + case GL_VERTEX_ARRAY_TYPE: + case GL_NORMAL_ARRAY_TYPE: + case GL_COLOR_ARRAY_TYPE: + case GL_TEXTURE_COORD_ARRAY_TYPE: + case GL_VERTEX_ARRAY_BUFFER_BINDING: + case GL_NORMAL_ARRAY_BUFFER_BINDING: + case GL_COLOR_ARRAY_BUFFER_BINDING: + case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING: + case GL_POINT_SIZE_ARRAY_STRIDE_OES: + case GL_POINT_SIZE_ARRAY_TYPE_OES: + case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES: + case GL_SHADE_MODEL: + case GL_MODELVIEW_STACK_DEPTH: + case GL_PROJECTION_STACK_DEPTH: + case GL_TEXTURE_STACK_DEPTH: + case GL_LOGIC_OP_MODE: + case GL_BLEND_SRC: + case GL_BLEND_DST: + case GL_PERSPECTIVE_CORRECTION_HINT: + case GL_POINT_SMOOTH_HINT: + case GL_LINE_SMOOTH_HINT: + case GL_FOG_HINT: + *type = GL_INT; + *numParams = 1; + return true; + case GL_ALPHA_TEST_REF: + case GL_FOG_DENSITY: + case GL_FOG_START: + case GL_FOG_END: + case GL_FOG_MODE: + case GL_POINT_SIZE: + case GL_POINT_SIZE_MIN: + case GL_POINT_SIZE_MAX: + case GL_POINT_FADE_THRESHOLD_SIZE: + *type = GL_FLOAT; + *numParams = 1; + return true; + case GL_SMOOTH_POINT_SIZE_RANGE: + case GL_SMOOTH_LINE_WIDTH_RANGE: + *type = GL_FLOAT; + *numParams = 2; + return true; + case GL_CURRENT_COLOR: + case GL_CURRENT_TEXTURE_COORDS: + case GL_LIGHT_MODEL_AMBIENT: + case GL_FOG_COLOR: + *type = GL_FLOAT; + *numParams = 4; + return true; + case GL_CURRENT_NORMAL: + case GL_POINT_DISTANCE_ATTENUATION: + *type = GL_FLOAT; + *numParams = 3; + return true; + case GL_MODELVIEW_MATRIX: + case GL_PROJECTION_MATRIX: + case GL_TEXTURE_MATRIX: + *type = GL_FLOAT; + *numParams = 16; + return true; + case GL_LIGHT_MODEL_TWO_SIDE: + *type = GL_BOOL; + *numParams = 1; + return true; + } + } + + if (glState.getClientVersion() < Version(3, 0)) + { + return false; + } + + // Check for ES3.0+ parameter names + switch (pname) + { + case GL_MAX_UNIFORM_BUFFER_BINDINGS: + case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: + case GL_UNIFORM_BUFFER_BINDING: + case GL_TRANSFORM_FEEDBACK_BINDING: + case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: + case GL_COPY_READ_BUFFER_BINDING: + case GL_COPY_WRITE_BUFFER_BINDING: + case GL_SAMPLER_BINDING: + case GL_READ_BUFFER: + case GL_TEXTURE_BINDING_3D: + case GL_TEXTURE_BINDING_2D_ARRAY: + case GL_MAX_ARRAY_TEXTURE_LAYERS: + case GL_MAX_VERTEX_UNIFORM_BLOCKS: + case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: + case GL_MAX_COMBINED_UNIFORM_BLOCKS: + case GL_MAX_VERTEX_OUTPUT_COMPONENTS: + case GL_MAX_FRAGMENT_INPUT_COMPONENTS: + case GL_MAX_VARYING_COMPONENTS: + case GL_MAX_VERTEX_UNIFORM_COMPONENTS: + case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: + case GL_MIN_PROGRAM_TEXEL_OFFSET: + case GL_MAX_PROGRAM_TEXEL_OFFSET: + case GL_NUM_EXTENSIONS: + case GL_MAJOR_VERSION: + case GL_MINOR_VERSION: + case GL_MAX_ELEMENTS_INDICES: + case GL_MAX_ELEMENTS_VERTICES: + case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: + case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: + case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: + case GL_UNPACK_IMAGE_HEIGHT: + case GL_UNPACK_SKIP_IMAGES: + case GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES: + { + *type = GL_INT; + *numParams = 1; + return true; + } + + case GL_MAX_ELEMENT_INDEX: + case GL_MAX_UNIFORM_BLOCK_SIZE: + case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: + case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: + case GL_MAX_SERVER_WAIT_TIMEOUT: + { + *type = GL_INT_64_ANGLEX; + *numParams = 1; + return true; + } + + case GL_TRANSFORM_FEEDBACK_ACTIVE: + case GL_TRANSFORM_FEEDBACK_PAUSED: + case GL_PRIMITIVE_RESTART_FIXED_INDEX: + case GL_RASTERIZER_DISCARD: + { + *type = GL_BOOL; + *numParams = 1; + return true; + } + + case GL_MAX_TEXTURE_LOD_BIAS: + case GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_OES: + case GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_OES: + { + *type = GL_FLOAT; + *numParams = 1; + return true; + } + } + + if (extensions.requestExtensionANGLE) + { + switch (pname) + { + case GL_NUM_REQUESTABLE_EXTENSIONS_ANGLE: + *type = GL_INT; + *numParams = 1; + return true; + } + } + + if (extensions.textureMultisampleANGLE) + { + switch (pname) + { + case GL_MAX_COLOR_TEXTURE_SAMPLES_ANGLE: + case GL_MAX_INTEGER_SAMPLES_ANGLE: + case GL_MAX_DEPTH_TEXTURE_SAMPLES_ANGLE: + case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ANGLE: + case GL_MAX_SAMPLE_MASK_WORDS: + *type = GL_INT; + *numParams = 1; + return true; + } + } + + if (extensions.textureCubeMapArrayAny()) + { + switch (pname) + { + case GL_TEXTURE_BINDING_CUBE_MAP_ARRAY: + *type = GL_INT; + *numParams = 1; + return true; + } + } + + if (extensions.textureBufferAny()) + { + switch (pname) + { + case GL_TEXTURE_BUFFER_BINDING: + case GL_TEXTURE_BINDING_BUFFER: + case GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT: + case GL_MAX_TEXTURE_BUFFER_SIZE: + *type = GL_INT; + *numParams = 1; + return true; + } + } + + if (extensions.shaderPixelLocalStorageANGLE) + { + switch (pname) + { + case GL_MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE: + case GL_MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE_ANGLE: + case GL_MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES_ANGLE: + *type = GL_INT; + *numParams = 1; + return true; + case GL_PIXEL_LOCAL_STORAGE_ACTIVE_ANGLE: + *type = GL_BOOL; + *numParams = 1; + return true; + } + } + + if (glState.getClientVersion() < Version(3, 1)) + { + return false; + } + + // Check for ES3.1+ parameter names + switch (pname) + { + case GL_ATOMIC_COUNTER_BUFFER_BINDING: + case GL_DRAW_INDIRECT_BUFFER_BINDING: + case GL_DISPATCH_INDIRECT_BUFFER_BINDING: + case GL_MAX_FRAMEBUFFER_WIDTH: + case GL_MAX_FRAMEBUFFER_HEIGHT: + case GL_MAX_FRAMEBUFFER_SAMPLES: + case GL_MAX_SAMPLE_MASK_WORDS: + case GL_MAX_COLOR_TEXTURE_SAMPLES: + case GL_MAX_DEPTH_TEXTURE_SAMPLES: + case GL_MAX_INTEGER_SAMPLES: + case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET: + case GL_MAX_VERTEX_ATTRIB_BINDINGS: + case GL_MAX_VERTEX_ATTRIB_STRIDE: + case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS: + case GL_MAX_VERTEX_ATOMIC_COUNTERS: + case GL_MAX_VERTEX_IMAGE_UNIFORMS: + case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS: + case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS: + case GL_MAX_FRAGMENT_ATOMIC_COUNTERS: + case GL_MAX_FRAGMENT_IMAGE_UNIFORMS: + case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS: + case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET: + case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET: + case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS: + case GL_MAX_COMPUTE_UNIFORM_BLOCKS: + case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS: + case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE: + case GL_MAX_COMPUTE_UNIFORM_COMPONENTS: + case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS: + case GL_MAX_COMPUTE_ATOMIC_COUNTERS: + case GL_MAX_COMPUTE_IMAGE_UNIFORMS: + case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS: + case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS: + case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES: + case GL_MAX_UNIFORM_LOCATIONS: + case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS: + case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE: + case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS: + case GL_MAX_COMBINED_ATOMIC_COUNTERS: + case GL_MAX_IMAGE_UNITS: + case GL_MAX_COMBINED_IMAGE_UNIFORMS: + case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS: + case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS: + case GL_SHADER_STORAGE_BUFFER_BINDING: + case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT: + case GL_TEXTURE_BINDING_2D_MULTISAMPLE: + case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY: + case GL_PROGRAM_PIPELINE_BINDING: + *type = GL_INT; + *numParams = 1; + return true; + case GL_MAX_SHADER_STORAGE_BLOCK_SIZE: + *type = GL_INT_64_ANGLEX; + *numParams = 1; + return true; + case GL_SAMPLE_MASK: + case GL_SAMPLE_SHADING: + *type = GL_BOOL; + *numParams = 1; + return true; + case GL_MIN_SAMPLE_SHADING_VALUE: + *type = GL_FLOAT; + *numParams = 1; + return true; + } + + if (extensions.geometryShaderAny()) + { + switch (pname) + { + case GL_MAX_FRAMEBUFFER_LAYERS_EXT: + case GL_LAYER_PROVOKING_VERTEX_EXT: + case GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT: + case GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT: + case GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT: + case GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT: + case GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT: + case GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT: + case GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT: + case GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT: + case GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT: + case GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT: + case GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT: + case GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT: + case GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT: + *type = GL_INT; + *numParams = 1; + return true; + } + } + + if (extensions.tessellationShaderEXT) + { + switch (pname) + { + case GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED: + *type = GL_BOOL; + *numParams = 1; + return true; + case GL_PATCH_VERTICES: + case GL_MAX_PATCH_VERTICES_EXT: + case GL_MAX_TESS_GEN_LEVEL_EXT: + case GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_EXT: + case GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT: + case GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_EXT: + case GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_EXT: + case GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT: + case GL_MAX_TESS_PATCH_COMPONENTS_EXT: + case GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_EXT: + case GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_EXT: + case GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_EXT: + case GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_EXT: + case GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT: + case GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT: + case GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_EXT: + case GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT: + case GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_EXT: + case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_EXT: + case GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_EXT: + case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_EXT: + case GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_EXT: + case GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_EXT: + case GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_EXT: + case GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_EXT: + *type = GL_INT; + *numParams = 1; + return true; + } + } + + return false; +} + +void QueryProgramPipelineiv(const Context *context, + ProgramPipeline *programPipeline, + GLenum pname, + GLint *params) +{ + if (!params) + { + // Can't write the result anywhere, so just return immediately. + return; + } + + switch (pname) + { + case GL_ACTIVE_PROGRAM: + { + // the name of the active program object of the program pipeline object is returned in + // params + *params = 0; + if (programPipeline) + { + const Program *program = programPipeline->getActiveShaderProgram(); + if (program) + { + *params = program->id().value; + } + } + break; + } + + case GL_VERTEX_SHADER: + { + // the name of the current program object for the vertex shader type of the program + // pipeline object is returned in params + GetShaderProgramId(programPipeline, ShaderType::Vertex, params); + break; + } + + case GL_FRAGMENT_SHADER: + { + // the name of the current program object for the fragment shader type of the program + // pipeline object is returned in params + GetShaderProgramId(programPipeline, ShaderType::Fragment, params); + break; + } + + case GL_TESS_CONTROL_SHADER: + { + // the name of the current program object for the tessellation control shader type of + // the program pipeline object is returned in params + GetShaderProgramId(programPipeline, ShaderType::TessControl, params); + break; + } + + case GL_TESS_EVALUATION_SHADER: + { + // the name of the current program object for the tessellation evaluation shader type of + // the program pipeline object is returned in params + GetShaderProgramId(programPipeline, ShaderType::TessEvaluation, params); + break; + } + + case GL_COMPUTE_SHADER: + { + // the name of the current program object for the compute shader type of the program + // pipeline object is returned in params + GetShaderProgramId(programPipeline, ShaderType::Compute, params); + break; + } + + case GL_GEOMETRY_SHADER: + { + // the name of the current program object for the geometry shader type of the program + // pipeline object is returned in params + GetShaderProgramId(programPipeline, ShaderType::Geometry, params); + break; + } + + case GL_INFO_LOG_LENGTH: + { + // the length of the info log, including the null terminator, is returned in params. If + // there is no info log, zero is returned. + *params = 0; + if (programPipeline) + { + *params = programPipeline->getExecutable().getInfoLogLength(); + } + break; + } + + case GL_VALIDATE_STATUS: + { + // the validation status of pipeline, as determined by glValidateProgramPipeline, is + // returned in params + *params = 0; + if (programPipeline) + { + *params = programPipeline->isValid(); + } + break; + } + + default: + break; + } +} + +} // namespace gl + +namespace egl +{ + +void QueryConfigAttrib(const Config *config, EGLint attribute, EGLint *value) +{ + ASSERT(config != nullptr); + switch (attribute) + { + case EGL_BUFFER_SIZE: + *value = config->bufferSize; + break; + case EGL_ALPHA_SIZE: + *value = config->alphaSize; + break; + case EGL_BLUE_SIZE: + *value = config->blueSize; + break; + case EGL_GREEN_SIZE: + *value = config->greenSize; + break; + case EGL_RED_SIZE: + *value = config->redSize; + break; + case EGL_DEPTH_SIZE: + *value = config->depthSize; + break; + case EGL_STENCIL_SIZE: + *value = config->stencilSize; + break; + case EGL_CONFIG_CAVEAT: + *value = config->configCaveat; + break; + case EGL_CONFIG_ID: + *value = config->configID; + break; + case EGL_LEVEL: + *value = config->level; + break; + case EGL_NATIVE_RENDERABLE: + *value = config->nativeRenderable; + break; + case EGL_NATIVE_VISUAL_ID: + *value = config->nativeVisualID; + break; + case EGL_NATIVE_VISUAL_TYPE: + *value = config->nativeVisualType; + break; + case EGL_SAMPLES: + *value = config->samples; + break; + case EGL_SAMPLE_BUFFERS: + *value = config->sampleBuffers; + break; + case EGL_SURFACE_TYPE: + *value = config->surfaceType; + break; + case EGL_BIND_TO_TEXTURE_TARGET_ANGLE: + *value = config->bindToTextureTarget; + break; + case EGL_TRANSPARENT_TYPE: + *value = config->transparentType; + break; + case EGL_TRANSPARENT_BLUE_VALUE: + *value = config->transparentBlueValue; + break; + case EGL_TRANSPARENT_GREEN_VALUE: + *value = config->transparentGreenValue; + break; + case EGL_TRANSPARENT_RED_VALUE: + *value = config->transparentRedValue; + break; + case EGL_BIND_TO_TEXTURE_RGB: + *value = config->bindToTextureRGB; + break; + case EGL_BIND_TO_TEXTURE_RGBA: + *value = config->bindToTextureRGBA; + break; + case EGL_MIN_SWAP_INTERVAL: + *value = config->minSwapInterval; + break; + case EGL_MAX_SWAP_INTERVAL: + *value = config->maxSwapInterval; + break; + case EGL_LUMINANCE_SIZE: + *value = config->luminanceSize; + break; + case EGL_ALPHA_MASK_SIZE: + *value = config->alphaMaskSize; + break; + case EGL_COLOR_BUFFER_TYPE: + *value = config->colorBufferType; + break; + case EGL_RENDERABLE_TYPE: + *value = config->renderableType; + break; + case EGL_MATCH_NATIVE_PIXMAP: + *value = false; + UNIMPLEMENTED(); + break; + case EGL_CONFORMANT: + *value = config->conformant; + break; + case EGL_MAX_PBUFFER_WIDTH: + *value = config->maxPBufferWidth; + break; + case EGL_MAX_PBUFFER_HEIGHT: + *value = config->maxPBufferHeight; + break; + case EGL_MAX_PBUFFER_PIXELS: + *value = config->maxPBufferPixels; + break; + case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE: + *value = config->optimalOrientation; + break; + case EGL_COLOR_COMPONENT_TYPE_EXT: + *value = config->colorComponentType; + break; + case EGL_RECORDABLE_ANDROID: + *value = config->recordable; + break; + case EGL_FRAMEBUFFER_TARGET_ANDROID: + *value = config->framebufferTarget; + break; + case EGL_MATCH_FORMAT_KHR: + *value = config->matchFormat; + break; + default: + UNREACHABLE(); + break; + } +} + +void QueryContextAttrib(const gl::Context *context, EGLint attribute, EGLint *value) +{ + switch (attribute) + { + case EGL_CONFIG_ID: + if (context->getConfig() != EGL_NO_CONFIG_KHR) + { + *value = context->getConfig()->configID; + } + else + { + *value = 0; + } + break; + case EGL_CONTEXT_CLIENT_TYPE: + *value = context->getClientType(); + break; + case EGL_CONTEXT_CLIENT_VERSION: + *value = context->getClientMajorVersion(); + break; + case EGL_RENDER_BUFFER: + *value = context->getRenderBuffer(); + break; + case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE: + *value = context->isRobustResourceInitEnabled(); + break; + case EGL_CONTEXT_PRIORITY_LEVEL_IMG: + *value = static_cast(context->getContextPriority()); + break; + case EGL_PROTECTED_CONTENT_EXT: + *value = context->getState().hasProtectedContent(); + break; + default: + UNREACHABLE(); + break; + } +} + +egl::Error QuerySurfaceAttrib(const Display *display, + const gl::Context *context, + Surface *surface, + EGLint attribute, + EGLint *value) +{ + switch (attribute) + { + case EGL_GL_COLORSPACE: + *value = surface->getGLColorspace(); + break; + case EGL_VG_ALPHA_FORMAT: + *value = surface->getVGAlphaFormat(); + break; + case EGL_VG_COLORSPACE: + *value = surface->getVGColorspace(); + break; + case EGL_CONFIG_ID: + *value = surface->getConfig()->configID; + break; + case EGL_HEIGHT: + ANGLE_TRY(surface->getUserHeight(display, value)); + break; + case EGL_HORIZONTAL_RESOLUTION: + *value = surface->getHorizontalResolution(); + break; + case EGL_LARGEST_PBUFFER: + // The EGL spec states that value is not written if the surface is not a pbuffer + if (surface->getType() == EGL_PBUFFER_BIT) + { + *value = surface->getLargestPbuffer(); + } + break; + case EGL_MIPMAP_TEXTURE: + // The EGL spec states that value is not written if the surface is not a pbuffer + if (surface->getType() == EGL_PBUFFER_BIT) + { + *value = surface->getMipmapTexture(); + } + break; + case EGL_MIPMAP_LEVEL: + // The EGL spec states that value is not written if the surface is not a pbuffer + if (surface->getType() == EGL_PBUFFER_BIT) + { + *value = surface->getMipmapLevel(); + } + break; + case EGL_MULTISAMPLE_RESOLVE: + *value = surface->getMultisampleResolve(); + break; + case EGL_PIXEL_ASPECT_RATIO: + *value = surface->getPixelAspectRatio(); + break; + case EGL_RENDER_BUFFER: + *value = surface->getRenderBuffer(); + break; + case EGL_SWAP_BEHAVIOR: + *value = surface->getSwapBehavior(); + break; + case EGL_TEXTURE_FORMAT: + // The EGL spec states that value is not written if the surface is not a pbuffer + if (surface->getType() == EGL_PBUFFER_BIT) + { + *value = ToEGLenum(surface->getTextureFormat()); + } + break; + case EGL_TEXTURE_TARGET: + // The EGL spec states that value is not written if the surface is not a pbuffer + if (surface->getType() == EGL_PBUFFER_BIT) + { + *value = surface->getTextureTarget(); + } + break; + case EGL_VERTICAL_RESOLUTION: + *value = surface->getVerticalResolution(); + break; + case EGL_WIDTH: + ANGLE_TRY(surface->getUserWidth(display, value)); + break; + case EGL_POST_SUB_BUFFER_SUPPORTED_NV: + *value = surface->isPostSubBufferSupported(); + break; + case EGL_FIXED_SIZE_ANGLE: + *value = surface->isFixedSize(); + break; + case EGL_SURFACE_ORIENTATION_ANGLE: + *value = surface->getOrientation(); + break; + case EGL_DIRECT_COMPOSITION_ANGLE: + *value = surface->directComposition(); + break; + case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE: + *value = surface->isRobustResourceInitEnabled(); + break; + case EGL_TIMESTAMPS_ANDROID: + *value = surface->isTimestampsEnabled(); + break; + case EGL_BUFFER_AGE_EXT: + ANGLE_TRY(surface->getBufferAge(context, value)); + break; + case EGL_BITMAP_PITCH_KHR: + *value = surface->getBitmapPitch(); + break; + case EGL_BITMAP_ORIGIN_KHR: + *value = surface->getBitmapOrigin(); + break; + case EGL_BITMAP_PIXEL_RED_OFFSET_KHR: + *value = surface->getRedOffset(); + break; + case EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR: + *value = surface->getGreenOffset(); + break; + case EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR: + *value = surface->getBlueOffset(); + break; + case EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR: + *value = surface->getAlphaOffset(); + break; + case EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR: + *value = surface->getLuminanceOffset(); + break; + case EGL_BITMAP_PIXEL_SIZE_KHR: + *value = surface->getBitmapPixelSize(); + break; + case EGL_PROTECTED_CONTENT_EXT: + *value = surface->hasProtectedContent(); + break; + default: + UNREACHABLE(); + break; + } + return NoError(); +} + +egl::Error QuerySurfaceAttrib64KHR(const Display *display, + const gl::Context *context, + const Surface *surface, + EGLint attribute, + EGLAttribKHR *value) +{ + switch (attribute) + { + case EGL_BITMAP_PITCH_KHR: + *value = static_cast(surface->getBitmapPitch()); + break; + case EGL_BITMAP_ORIGIN_KHR: + *value = static_cast(surface->getBitmapOrigin()); + break; + case EGL_BITMAP_PIXEL_RED_OFFSET_KHR: + *value = static_cast(surface->getRedOffset()); + break; + case EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR: + *value = static_cast(surface->getGreenOffset()); + break; + case EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR: + *value = static_cast(surface->getBlueOffset()); + break; + case EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR: + *value = static_cast(surface->getAlphaOffset()); + break; + case EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR: + *value = static_cast(surface->getLuminanceOffset()); + break; + case EGL_BITMAP_PIXEL_SIZE_KHR: + *value = static_cast(surface->getBitmapPixelSize()); + break; + case EGL_BITMAP_POINTER_KHR: + *value = surface->getBitmapPointer(); + break; + default: + UNREACHABLE(); + break; + } + return NoError(); +} + +egl::Error SetSurfaceAttrib(Surface *surface, EGLint attribute, EGLint value) +{ + switch (attribute) + { + case EGL_MIPMAP_LEVEL: + surface->setMipmapLevel(value); + break; + case EGL_MULTISAMPLE_RESOLVE: + surface->setMultisampleResolve(value); + break; + case EGL_SWAP_BEHAVIOR: + surface->setSwapBehavior(value); + break; + case EGL_WIDTH: + surface->setFixedWidth(value); + break; + case EGL_HEIGHT: + surface->setFixedHeight(value); + break; + case EGL_TIMESTAMPS_ANDROID: + surface->setTimestampsEnabled(value != EGL_FALSE); + break; + case EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID: + return surface->setAutoRefreshEnabled(value == EGL_TRUE); + case EGL_RENDER_BUFFER: + return surface->setRenderBuffer(value); + default: + UNREACHABLE(); + break; + } + return NoError(); +} + +Error GetSyncAttrib(Display *display, Sync *sync, EGLint attribute, EGLint *value) +{ + switch (attribute) + { + case EGL_SYNC_TYPE_KHR: + *value = sync->getType(); + return NoError(); + + case EGL_SYNC_STATUS_KHR: + return sync->getStatus(display, value); + + case EGL_SYNC_CONDITION_KHR: + *value = sync->getCondition(); + return NoError(); + + default: + break; + } + + UNREACHABLE(); + return NoError(); +} +} // namespace egl diff --git a/gfx/angle/checkout/src/libANGLE/queryutils.h b/gfx/angle/checkout/src/libANGLE/queryutils.h new file mode 100644 index 0000000000..dfb3680e8c --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/queryutils.h @@ -0,0 +1,293 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// queryutils.h: Utilities for querying values from GL objects + +#ifndef LIBANGLE_QUERYUTILS_H_ +#define LIBANGLE_QUERYUTILS_H_ + +#include "angle_gl.h" +#include "common/PackedEnums.h" +#include "common/angleutils.h" +#include "libANGLE/Error.h" + +#include + +namespace gl +{ +class Buffer; +class Context; +class Sync; +class Framebuffer; +class GLES1State; +class Program; +class Renderbuffer; +class Sampler; +class Shader; +class State; +class Texture; +struct TextureCaps; +struct UniformBlock; +struct VertexAttribute; +class VertexBinding; +struct VertexAttribCurrentValueData; + +void QueryFramebufferAttachmentParameteriv(const Context *context, + const Framebuffer *framebuffer, + GLenum attachment, + GLenum pname, + GLint *params); +void QueryBufferParameteriv(const Buffer *buffer, GLenum pname, GLint *params); +void QueryBufferParameteri64v(const Buffer *buffer, GLenum pname, GLint64 *params); +void QueryBufferPointerv(const Buffer *buffer, GLenum pname, void **params); +void QueryProgramiv(Context *context, const Program *program, GLenum pname, GLint *params); +void QueryRenderbufferiv(const Context *context, + const Renderbuffer *renderbuffer, + GLenum pname, + GLint *params); +void QueryShaderiv(const Context *context, Shader *shader, GLenum pname, GLint *params); +void QueryTexLevelParameterfv(const Texture *texture, + TextureTarget target, + GLint level, + GLenum pname, + GLfloat *params); +void QueryTexLevelParameteriv(const Texture *texture, + TextureTarget target, + GLint level, + GLenum pname, + GLint *params); +void QueryTexParameterfv(const Context *context, + const Texture *texture, + GLenum pname, + GLfloat *params); +void QueryTexParameterxv(const Context *context, + const Texture *texture, + GLenum pname, + GLfixed *params); +void QueryTexParameteriv(const Context *context, + const Texture *texture, + GLenum pname, + GLint *params); +void QueryTexParameterIiv(const Context *context, + const Texture *texture, + GLenum pname, + GLint *params); +void QueryTexParameterIuiv(const Context *context, + const Texture *texture, + GLenum pname, + GLuint *params); +void QuerySamplerParameterfv(const Sampler *sampler, GLenum pname, GLfloat *params); +void QuerySamplerParameteriv(const Sampler *sampler, GLenum pname, GLint *params); +void QuerySamplerParameterIiv(const Sampler *sampler, GLenum pname, GLint *params); +void QuerySamplerParameterIuiv(const Sampler *sampler, GLenum pname, GLuint *params); + +// Warning: you should ensure binding really matches attrib.bindingIndex before using the following +// functions. +void QueryVertexAttribfv(const VertexAttribute &attrib, + const VertexBinding &binding, + const VertexAttribCurrentValueData ¤tValueData, + GLenum pname, + GLfloat *params); + +void QueryVertexAttribiv(const VertexAttribute &attrib, + const VertexBinding &binding, + const VertexAttribCurrentValueData ¤tValueData, + GLenum pname, + GLint *params); + +void QueryVertexAttribPointerv(const VertexAttribute &attrib, GLenum pname, void **pointer); + +void QueryVertexAttribIiv(const VertexAttribute &attrib, + const VertexBinding &binding, + const VertexAttribCurrentValueData ¤tValueData, + GLenum pname, + GLint *params); + +void QueryVertexAttribIuiv(const VertexAttribute &attrib, + const VertexBinding &binding, + const VertexAttribCurrentValueData ¤tValueData, + GLenum pname, + GLuint *params); + +void QueryActiveUniformBlockiv(const Program *program, + UniformBlockIndex uniformBlockIndex, + GLenum pname, + GLint *params); + +void QueryInternalFormativ(const TextureCaps &format, GLenum pname, GLsizei bufSize, GLint *params); + +void QueryFramebufferParameteriv(const Framebuffer *framebuffer, GLenum pname, GLint *params); + +angle::Result QuerySynciv(const Context *context, + const Sync *sync, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *values); + +void SetTexParameterf(Context *context, Texture *texture, GLenum pname, GLfloat param); +void SetTexParameterfv(Context *context, Texture *texture, GLenum pname, const GLfloat *params); +void SetTexParameteri(Context *context, Texture *texture, GLenum pname, GLint param); +void SetTexParameteriv(Context *context, Texture *texture, GLenum pname, const GLint *params); +void SetTexParameterIiv(Context *context, Texture *texture, GLenum pname, const GLint *params); +void SetTexParameterIuiv(Context *context, Texture *texture, GLenum pname, const GLuint *params); +void SetTexParameterx(Context *context, Texture *texture, GLenum pname, GLfixed param); +void SetTexParameterxv(Context *context, Texture *texture, GLenum pname, const GLfixed *params); + +void SetSamplerParameterf(Context *context, Sampler *sampler, GLenum pname, GLfloat param); +void SetSamplerParameterfv(Context *context, Sampler *sampler, GLenum pname, const GLfloat *params); +void SetSamplerParameteri(Context *context, Sampler *sampler, GLenum pname, GLint param); +void SetSamplerParameteriv(Context *context, Sampler *sampler, GLenum pname, const GLint *params); +void SetSamplerParameterIiv(Context *context, Sampler *sampler, GLenum pname, const GLint *params); +void SetSamplerParameterIuiv(Context *context, + Sampler *sampler, + GLenum pname, + const GLuint *params); + +void SetFramebufferParameteri(const Context *context, + Framebuffer *framebuffer, + GLenum pname, + GLint param); + +void SetProgramParameteri(Program *program, GLenum pname, GLint value); + +GLint GetUniformResourceProperty(const Program *program, GLuint index, const GLenum prop); + +GLuint QueryProgramResourceIndex(const Program *program, + GLenum programInterface, + const GLchar *name); + +void QueryProgramResourceName(const Context *context, + const Program *program, + GLenum programInterface, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name); + +GLint QueryProgramResourceLocation(const Program *program, + GLenum programInterface, + const GLchar *name); +void QueryProgramResourceiv(const Program *program, + GLenum programInterface, + UniformBlockIndex index, + GLsizei propCount, + const GLenum *props, + GLsizei bufSize, + GLsizei *length, + GLint *params); + +void QueryProgramInterfaceiv(const Program *program, + GLenum programInterface, + GLenum pname, + GLint *params); + +angle::Result SetMemoryObjectParameteriv(const Context *context, + MemoryObject *memoryObject, + GLenum pname, + const GLint *params); +void QueryMemoryObjectParameteriv(const MemoryObject *memoryObject, GLenum pname, GLint *params); + +// GLES1 emulation + +ClientVertexArrayType ParamToVertexArrayType(GLenum param); + +void SetLightParameters(GLES1State *state, + GLenum light, + LightParameter pname, + const GLfloat *params); +void GetLightParameters(const GLES1State *state, + GLenum light, + LightParameter pname, + GLfloat *params); + +void SetLightModelParameters(GLES1State *state, GLenum pname, const GLfloat *params); +void GetLightModelParameters(const GLES1State *state, GLenum pname, GLfloat *params); +bool IsLightModelTwoSided(const GLES1State *state); + +void SetMaterialParameters(GLES1State *state, + GLenum face, + MaterialParameter pname, + const GLfloat *params); +void GetMaterialParameters(const GLES1State *state, + GLenum face, + MaterialParameter pname, + GLfloat *params); + +unsigned int GetLightModelParameterCount(GLenum pname); +unsigned int GetLightParameterCount(LightParameter pname); +unsigned int GetMaterialParameterCount(MaterialParameter pname); + +void SetFogParameters(GLES1State *state, GLenum pname, const GLfloat *params); +void GetFogParameters(const GLES1State *state, GLenum pname, GLfloat *params); +unsigned int GetFogParameterCount(GLenum pname); + +unsigned int GetTextureEnvParameterCount(TextureEnvParameter pname); + +void ConvertTextureEnvFromInt(TextureEnvParameter pname, const GLint *input, GLfloat *output); +void ConvertTextureEnvFromFixed(TextureEnvParameter pname, const GLfixed *input, GLfloat *output); +void ConvertTextureEnvToInt(TextureEnvParameter pname, const GLfloat *input, GLint *output); +void ConvertTextureEnvToFixed(TextureEnvParameter pname, const GLfloat *input, GLfixed *output); + +void SetTextureEnv(unsigned int unit, + GLES1State *state, + TextureEnvTarget target, + TextureEnvParameter pname, + const GLfloat *params); +void GetTextureEnv(unsigned int unit, + const GLES1State *state, + TextureEnvTarget target, + TextureEnvParameter pname, + GLfloat *params); + +unsigned int GetPointParameterCount(PointParameter pname); + +void SetPointParameter(GLES1State *state, PointParameter pname, const GLfloat *params); +void GetPointParameter(const GLES1State *state, PointParameter pname, GLfloat *params); + +void SetPointSize(GLES1State *state, GLfloat size); +void GetPointSize(const GLES1State *state, GLfloat *sizeOut); + +unsigned int GetTexParameterCount(GLenum pname); + +bool GetQueryParameterInfo(const State &glState, + GLenum pname, + GLenum *type, + unsigned int *numParams); + +void QueryProgramPipelineiv(const Context *context, + ProgramPipeline *programPipeline, + GLenum pname, + GLint *params); +} // namespace gl + +namespace egl +{ +struct Config; +class Display; +class Surface; +class Sync; + +void QueryConfigAttrib(const Config *config, EGLint attribute, EGLint *value); + +void QueryContextAttrib(const gl::Context *context, EGLint attribute, EGLint *value); + +egl::Error QuerySurfaceAttrib(const Display *display, + const gl::Context *context, + Surface *surface, + EGLint attribute, + EGLint *value); +egl::Error SetSurfaceAttrib(Surface *surface, EGLint attribute, EGLint value); +Error GetSyncAttrib(Display *display, Sync *sync, EGLint attribute, EGLint *value); +egl::Error QuerySurfaceAttrib64KHR(const Display *display, + const gl::Context *context, + const Surface *surface, + EGLint attribute, + EGLAttribKHR *value); + +} // namespace egl + +#endif // LIBANGLE_QUERYUTILS_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/BufferImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/BufferImpl.cpp new file mode 100644 index 0000000000..9cd3c5b6f6 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/BufferImpl.cpp @@ -0,0 +1,39 @@ +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// BufferImpl.cpp: Implementation methods rx::BufferImpl class. + +#include "libANGLE/renderer/BufferImpl.h" + +namespace rx +{ + +angle::Result BufferImpl::getSubData(const gl::Context *context, + GLintptr offset, + GLsizeiptr size, + void *outData) +{ + UNREACHABLE(); + return angle::Result::Stop; +} + +angle::Result BufferImpl::setDataWithUsageFlags(const gl::Context *context, + gl::BufferBinding target, + GLeglClientBufferEXT clientBuffer, + const void *data, + size_t size, + gl::BufferUsage usage, + GLbitfield flags) +{ + return setData(context, target, data, size, usage); +} + +angle::Result BufferImpl::onLabelUpdate(const gl::Context *context) +{ + return angle::Result::Continue; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/BufferImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/BufferImpl.h new file mode 100644 index 0000000000..6238a4def3 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/BufferImpl.h @@ -0,0 +1,98 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// BufferImpl.h: Defines the abstract rx::BufferImpl class. + +#ifndef LIBANGLE_RENDERER_BUFFERIMPL_H_ +#define LIBANGLE_RENDERER_BUFFERIMPL_H_ + +#include "common/PackedEnums.h" +#include "common/angleutils.h" +#include "common/mathutil.h" +#include "libANGLE/Error.h" +#include "libANGLE/Observer.h" + +#include + +namespace gl +{ +class BufferState; +class Context; +} // namespace gl + +namespace rx +{ +// We use two set of Subject messages. The CONTENTS_CHANGED message is signaled whenever data +// changes, to trigger re-translation or other events. Some buffers only need to be updated when the +// underlying driver object changes - this is notified via the STORAGE_CHANGED message. +class BufferImpl : public angle::Subject +{ + public: + BufferImpl(const gl::BufferState &state) : mState(state) {} + ~BufferImpl() override {} + virtual void destroy(const gl::Context *context) {} + + virtual angle::Result setDataWithUsageFlags(const gl::Context *context, + gl::BufferBinding target, + GLeglClientBufferEXT clientBuffer, + const void *data, + size_t size, + gl::BufferUsage usage, + GLbitfield flags); + virtual angle::Result setData(const gl::Context *context, + gl::BufferBinding target, + const void *data, + size_t size, + gl::BufferUsage usage) = 0; + virtual angle::Result setSubData(const gl::Context *context, + gl::BufferBinding target, + const void *data, + size_t size, + size_t offset) = 0; + virtual angle::Result copySubData(const gl::Context *context, + BufferImpl *source, + GLintptr sourceOffset, + GLintptr destOffset, + GLsizeiptr size) = 0; + virtual angle::Result map(const gl::Context *context, GLenum access, void **mapPtr) = 0; + virtual angle::Result mapRange(const gl::Context *context, + size_t offset, + size_t length, + GLbitfield access, + void **mapPtr) = 0; + virtual angle::Result unmap(const gl::Context *context, GLboolean *result) = 0; + + virtual angle::Result getIndexRange(const gl::Context *context, + gl::DrawElementsType type, + size_t offset, + size_t count, + bool primitiveRestartEnabled, + gl::IndexRange *outRange) = 0; + + virtual angle::Result getSubData(const gl::Context *context, + GLintptr offset, + GLsizeiptr size, + void *outData); + + virtual angle::Result onLabelUpdate(const gl::Context *context); + + // Override if accurate native memory size information is available + virtual GLint64 getMemorySize() const; + + virtual void onDataChanged() {} + + protected: + const gl::BufferState &mState; +}; + +inline GLint64 BufferImpl::getMemorySize() const +{ + return 0; +} + +} // namespace rx + +#endif // LIBANGLE_RENDERER_BUFFERIMPL_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/CompilerImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/CompilerImpl.h new file mode 100644 index 0000000000..0e8c5192f2 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/CompilerImpl.h @@ -0,0 +1,32 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// CompilerImpl.h: Defines the rx::CompilerImpl class, an implementation interface +// for the gl::Compiler object. + +#include "GLSLANG/ShaderLang.h" +#include "common/angleutils.h" +#include "libANGLE/Error.h" + +#ifndef LIBANGLE_RENDERER_COMPILERIMPL_H_ +# define LIBANGLE_RENDERER_COMPILERIMPL_H_ + +namespace rx +{ + +class CompilerImpl : angle::NonCopyable +{ + public: + CompilerImpl() {} + virtual ~CompilerImpl() {} + + // TODO(jmadill): Expose translator built-in resources init method. + virtual ShShaderOutput getTranslatorOutputType() const = 0; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_COMPILERIMPL_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/ContextImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/ContextImpl.cpp new file mode 100644 index 0000000000..952d4ee37a --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/ContextImpl.cpp @@ -0,0 +1,88 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ContextImpl: +// Implementation-specific functionality associated with a GL Context. +// + +#include "libANGLE/renderer/ContextImpl.h" + +#include "common/third_party/base/anglebase/no_destructor.h" +#include "libANGLE/Context.h" + +namespace rx +{ +ContextImpl::ContextImpl(const gl::State &state, gl::ErrorSet *errorSet) + : mState(state), mMemoryProgramCache(nullptr), mErrors(errorSet) +{} + +ContextImpl::~ContextImpl() {} + +void ContextImpl::invalidateTexture(gl::TextureType target) +{ + UNREACHABLE(); +} + +angle::Result ContextImpl::onUnMakeCurrent(const gl::Context *context) +{ + return angle::Result::Continue; +} + +angle::Result ContextImpl::handleNoopDrawEvent() +{ + return angle::Result::Continue; +} + +void ContextImpl::setMemoryProgramCache(gl::MemoryProgramCache *memoryProgramCache) +{ + mMemoryProgramCache = memoryProgramCache; +} + +void ContextImpl::handleError(GLenum errorCode, + const char *message, + const char *file, + const char *function, + unsigned int line) +{ + std::stringstream errorStream; + errorStream << "Internal error: " << gl::FmtHex(errorCode) << ": " << message; + mErrors->handleError(errorCode, errorStream.str().c_str(), file, function, line); +} + +egl::ContextPriority ContextImpl::getContextPriority() const +{ + return egl::ContextPriority::Medium; +} + +egl::Error ContextImpl::releaseHighPowerGPU(gl::Context *) +{ + return egl::NoError(); +} + +egl::Error ContextImpl::reacquireHighPowerGPU(gl::Context *) +{ + return egl::NoError(); +} + +angle::Result ContextImpl::acquireTextures(const gl::Context *context, + const gl::TextureBarrierVector &textureBarriers) +{ + UNREACHABLE(); + return angle::Result::Stop; +} + +angle::Result ContextImpl::releaseTextures(const gl::Context *context, + gl::TextureBarrierVector *textureBarriers) +{ + UNREACHABLE(); + return angle::Result::Stop; +} + +const angle::PerfMonitorCounterGroups &ContextImpl::getPerfMonitorCounters() +{ + static angle::base::NoDestructor sCounters; + return *sCounters; +} +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/ContextImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/ContextImpl.h new file mode 100644 index 0000000000..3b167fe8b6 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/ContextImpl.h @@ -0,0 +1,274 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ContextImpl: +// Implementation-specific functionality associated with a GL Context. +// + +#ifndef LIBANGLE_RENDERER_CONTEXTIMPL_H_ +#define LIBANGLE_RENDERER_CONTEXTIMPL_H_ + +#include + +#include "common/angleutils.h" +#include "libANGLE/State.h" +#include "libANGLE/renderer/GLImplFactory.h" + +namespace gl +{ +class ErrorSet; +class MemoryProgramCache; +class Path; +class Semaphore; +struct Workarounds; +} // namespace gl + +namespace rx +{ +class ContextImpl : public GLImplFactory +{ + public: + ContextImpl(const gl::State &state, gl::ErrorSet *errorSet); + ~ContextImpl() override; + + virtual void onDestroy(const gl::Context *context) {} + + virtual angle::Result initialize() = 0; + + // Flush and finish. + virtual angle::Result flush(const gl::Context *context) = 0; + virtual angle::Result finish(const gl::Context *context) = 0; + + // Drawing methods. + virtual angle::Result drawArrays(const gl::Context *context, + gl::PrimitiveMode mode, + GLint first, + GLsizei count) = 0; + virtual angle::Result drawArraysInstanced(const gl::Context *context, + gl::PrimitiveMode mode, + GLint first, + GLsizei count, + GLsizei instanceCount) = 0; + // Necessary for Vulkan since gl_InstanceIndex includes baseInstance + virtual angle::Result drawArraysInstancedBaseInstance(const gl::Context *context, + gl::PrimitiveMode mode, + GLint first, + GLsizei count, + GLsizei instanceCount, + GLuint baseInstance) = 0; + + virtual angle::Result drawElements(const gl::Context *context, + gl::PrimitiveMode mode, + GLsizei count, + gl::DrawElementsType type, + const void *indices) = 0; + virtual angle::Result drawElementsBaseVertex(const gl::Context *context, + gl::PrimitiveMode mode, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + GLint baseVertex) = 0; + virtual angle::Result drawElementsInstanced(const gl::Context *context, + gl::PrimitiveMode mode, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + GLsizei instances) = 0; + virtual angle::Result drawElementsInstancedBaseVertex(const gl::Context *context, + gl::PrimitiveMode mode, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + GLsizei instances, + GLint baseVertex) = 0; + virtual angle::Result drawElementsInstancedBaseVertexBaseInstance(const gl::Context *context, + gl::PrimitiveMode mode, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + GLsizei instances, + GLint baseVertex, + GLuint baseInstance) = 0; + virtual angle::Result drawRangeElements(const gl::Context *context, + gl::PrimitiveMode mode, + GLuint start, + GLuint end, + GLsizei count, + gl::DrawElementsType type, + const void *indices) = 0; + virtual angle::Result drawRangeElementsBaseVertex(const gl::Context *context, + gl::PrimitiveMode mode, + GLuint start, + GLuint end, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + GLint baseVertex) = 0; + + virtual angle::Result drawArraysIndirect(const gl::Context *context, + gl::PrimitiveMode mode, + const void *indirect) = 0; + virtual angle::Result drawElementsIndirect(const gl::Context *context, + gl::PrimitiveMode mode, + gl::DrawElementsType type, + const void *indirect) = 0; + + // MultiDraw* impl added as we need workaround for promoting dynamic attributes in D3D backend + virtual angle::Result multiDrawArrays(const gl::Context *context, + gl::PrimitiveMode mode, + const GLint *firsts, + const GLsizei *counts, + GLsizei drawcount) = 0; + virtual angle::Result multiDrawArraysIndirect(const gl::Context *context, + gl::PrimitiveMode mode, + const void *indirect, + GLsizei drawcount, + GLsizei stride) = 0; + virtual angle::Result multiDrawArraysInstanced(const gl::Context *context, + gl::PrimitiveMode mode, + const GLint *firsts, + const GLsizei *counts, + const GLsizei *instanceCounts, + GLsizei drawcount) = 0; + virtual angle::Result multiDrawElements(const gl::Context *context, + gl::PrimitiveMode mode, + const GLsizei *counts, + gl::DrawElementsType type, + const GLvoid *const *indices, + GLsizei drawcount) = 0; + virtual angle::Result multiDrawElementsInstanced(const gl::Context *context, + gl::PrimitiveMode mode, + const GLsizei *counts, + gl::DrawElementsType type, + const GLvoid *const *indices, + const GLsizei *instanceCounts, + GLsizei drawcount) = 0; + virtual angle::Result multiDrawElementsIndirect(const gl::Context *context, + gl::PrimitiveMode mode, + gl::DrawElementsType type, + const void *indirect, + GLsizei drawcount, + GLsizei stride) = 0; + virtual angle::Result multiDrawArraysInstancedBaseInstance(const gl::Context *context, + gl::PrimitiveMode mode, + const GLint *firsts, + const GLsizei *counts, + const GLsizei *instanceCounts, + const GLuint *baseInstances, + GLsizei drawcount) = 0; + virtual angle::Result multiDrawElementsInstancedBaseVertexBaseInstance( + const gl::Context *context, + gl::PrimitiveMode mode, + const GLsizei *counts, + gl::DrawElementsType type, + const GLvoid *const *indices, + const GLsizei *instanceCounts, + const GLint *baseVertices, + const GLuint *baseInstances, + GLsizei drawcount) = 0; + + // Device loss + virtual gl::GraphicsResetStatus getResetStatus() = 0; + + // EXT_debug_marker + virtual angle::Result insertEventMarker(GLsizei length, const char *marker) = 0; + virtual angle::Result pushGroupMarker(GLsizei length, const char *marker) = 0; + virtual angle::Result popGroupMarker() = 0; + + // KHR_debug + virtual angle::Result pushDebugGroup(const gl::Context *context, + GLenum source, + GLuint id, + const std::string &message) = 0; + virtual angle::Result popDebugGroup(const gl::Context *context) = 0; + virtual angle::Result handleNoopDrawEvent(); + + // KHR_parallel_shader_compile + virtual void setMaxShaderCompilerThreads(GLuint count) {} + + // GL_ANGLE_texture_storage_external + virtual void invalidateTexture(gl::TextureType target); + + // EXT_shader_framebuffer_fetch_non_coherent + virtual void framebufferFetchBarrier() {} + + // KHR_blend_equation_advanced + virtual void blendBarrier() {} + + // State sync with dirty bits. + virtual angle::Result syncState(const gl::Context *context, + const gl::State::DirtyBits &dirtyBits, + const gl::State::DirtyBits &bitMask, + gl::Command command) = 0; + + // Disjoint timer queries + virtual GLint getGPUDisjoint() = 0; + virtual GLint64 getTimestamp() = 0; + + // Context switching + virtual angle::Result onMakeCurrent(const gl::Context *context) = 0; + virtual angle::Result onUnMakeCurrent(const gl::Context *context); + + // Native capabilities, unmodified by gl::Context. + virtual gl::Caps getNativeCaps() const = 0; + virtual const gl::TextureCapsMap &getNativeTextureCaps() const = 0; + virtual const gl::Extensions &getNativeExtensions() const = 0; + virtual const gl::Limitations &getNativeLimitations() const = 0; + virtual ShPixelLocalStorageType getNativePixelLocalStorageType() const = 0; + + virtual angle::Result dispatchCompute(const gl::Context *context, + GLuint numGroupsX, + GLuint numGroupsY, + GLuint numGroupsZ) = 0; + virtual angle::Result dispatchComputeIndirect(const gl::Context *context, + GLintptr indirect) = 0; + + virtual angle::Result memoryBarrier(const gl::Context *context, GLbitfield barriers) = 0; + virtual angle::Result memoryBarrierByRegion(const gl::Context *context, + GLbitfield barriers) = 0; + + const gl::State &getState() const { return mState; } + int getClientMajorVersion() const { return mState.getClientMajorVersion(); } + int getClientMinorVersion() const { return mState.getClientMinorVersion(); } + const gl::Caps &getCaps() const { return mState.getCaps(); } + const gl::TextureCapsMap &getTextureCaps() const { return mState.getTextureCaps(); } + const gl::Extensions &getExtensions() const { return mState.getExtensions(); } + const gl::Limitations &getLimitations() const { return mState.getLimitations(); } + + // A common GL driver behaviour is to trigger dynamic shader recompilation on a draw call, + // based on the current render states. We store a mutable pointer to the program cache so + // on draw calls we can store the refreshed shaders in the cache. + void setMemoryProgramCache(gl::MemoryProgramCache *memoryProgramCache); + + void handleError(GLenum errorCode, + const char *message, + const char *file, + const char *function, + unsigned int line); + + virtual egl::ContextPriority getContextPriority() const; + + // EGL_ANGLE_power_preference implementation. + virtual egl::Error releaseHighPowerGPU(gl::Context *context); + virtual egl::Error reacquireHighPowerGPU(gl::Context *context); + + // GL_ANGLE_vulkan_image + virtual angle::Result acquireTextures(const gl::Context *context, + const gl::TextureBarrierVector &textureBarriers); + virtual angle::Result releaseTextures(const gl::Context *context, + gl::TextureBarrierVector *textureBarriers); + + // AMD_performance_monitor + virtual const angle::PerfMonitorCounterGroups &getPerfMonitorCounters(); + + protected: + const gl::State &mState; + gl::MemoryProgramCache *mMemoryProgramCache; + gl::ErrorSet *mErrors; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_CONTEXTIMPL_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/DeviceImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/DeviceImpl.cpp new file mode 100644 index 0000000000..109fc48477 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/DeviceImpl.cpp @@ -0,0 +1,18 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// DeviceImpl.cpp: Implementation methods of egl::Device + +#include "libANGLE/renderer/DeviceImpl.h" + +namespace rx +{ + +DeviceImpl::DeviceImpl() {} + +DeviceImpl::~DeviceImpl() {} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/DeviceImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/DeviceImpl.h new file mode 100644 index 0000000000..30cee7d514 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/DeviceImpl.h @@ -0,0 +1,42 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// DeviceImpl.h: Implementation methods of egl::Device + +#ifndef LIBANGLE_RENDERER_DEVICEIMPL_H_ +#define LIBANGLE_RENDERER_DEVICEIMPL_H_ + +#include "common/angleutils.h" +#include "libANGLE/Caps.h" +#include "libANGLE/Error.h" + +namespace egl +{ +class Display; +} + +namespace rx +{ +class DisplayImpl; + +class DeviceImpl : angle::NonCopyable +{ + public: + DeviceImpl(); + virtual ~DeviceImpl(); + + virtual egl::Error initialize() = 0; + + virtual egl::Error getAttribute(const egl::Display *display, + EGLint attribute, + void **outValue) = 0; + virtual EGLint getType() = 0; + virtual void generateExtensions(egl::DeviceExtensions *outExtensions) const = 0; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_DEVICEIMPL_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/DisplayImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/DisplayImpl.cpp new file mode 100644 index 0000000000..f07cd30517 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/DisplayImpl.cpp @@ -0,0 +1,168 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// DisplayImpl.cpp: Implementation methods of egl::Display + +#include "libANGLE/renderer/DisplayImpl.h" + +#include "libANGLE/Display.h" +#include "libANGLE/Surface.h" +#include "libANGLE/renderer/DeviceImpl.h" + +namespace rx +{ +namespace +{ +// For back-ends that do not implement EGLDevice. +class MockDevice : public DeviceImpl +{ + public: + MockDevice() = default; + egl::Error initialize() override { return egl::NoError(); } + egl::Error getAttribute(const egl::Display *display, EGLint attribute, void **outValue) override + { + UNREACHABLE(); + return egl::EglBadAttribute(); + } + EGLint getType() override + { + UNREACHABLE(); + return EGL_NONE; + } + void generateExtensions(egl::DeviceExtensions *outExtensions) const override + { + *outExtensions = egl::DeviceExtensions(); + } +}; +} // anonymous namespace + +DisplayImpl::DisplayImpl(const egl::DisplayState &state) + : mState(state), mExtensionsInitialized(false), mCapsInitialized(false), mBlobCache(nullptr) +{} + +DisplayImpl::~DisplayImpl() +{ + ASSERT(mState.surfaceSet.empty()); +} + +egl::Error DisplayImpl::prepareForCall() +{ + return egl::NoError(); +} + +egl::Error DisplayImpl::releaseThread() +{ + return egl::NoError(); +} + +const egl::DisplayExtensions &DisplayImpl::getExtensions() const +{ + if (!mExtensionsInitialized) + { + generateExtensions(&mExtensions); + mExtensionsInitialized = true; + } + + return mExtensions; +} + +egl::Error DisplayImpl::handleGPUSwitch() +{ + return egl::NoError(); +} + +egl::Error DisplayImpl::forceGPUSwitch(EGLint gpuIDHigh, EGLint gpuIDLow) +{ + return egl::NoError(); +} + +egl::Error DisplayImpl::validateClientBuffer(const egl::Config *configuration, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const egl::AttributeMap &attribs) const +{ + UNREACHABLE(); + return egl::EglBadDisplay() << "DisplayImpl::validateClientBuffer unimplemented."; +} + +egl::Error DisplayImpl::validateImageClientBuffer(const gl::Context *context, + EGLenum target, + EGLClientBuffer clientBuffer, + const egl::AttributeMap &attribs) const +{ + UNREACHABLE(); + return egl::EglBadDisplay() << "DisplayImpl::validateImageClientBuffer unimplemented."; +} + +egl::Error DisplayImpl::validatePixmap(const egl::Config *config, + EGLNativePixmapType pixmap, + const egl::AttributeMap &attributes) const +{ + UNREACHABLE(); + return egl::EglBadDisplay() << "DisplayImpl::valdiatePixmap unimplemented."; +} + +const egl::Caps &DisplayImpl::getCaps() const +{ + if (!mCapsInitialized) + { + generateCaps(&mCaps); + mCapsInitialized = true; + } + + return mCaps; +} + +DeviceImpl *DisplayImpl::createDevice() +{ + return new MockDevice(); +} + +bool DisplayImpl::isX11() const +{ + return false; +} + +bool DisplayImpl::isWayland() const +{ + return false; +} + +bool DisplayImpl::isGBM() const +{ + return false; +} + +bool DisplayImpl::supportsDmaBufFormat(EGLint format) const +{ + UNREACHABLE(); + return false; +} + +egl::Error DisplayImpl::queryDmaBufFormats(EGLint max_formats, EGLint *formats, EGLint *num_formats) +{ + UNREACHABLE(); + return egl::NoError(); +} + +egl::Error DisplayImpl::queryDmaBufModifiers(EGLint format, + EGLint max_modifiers, + EGLuint64KHR *modifiers, + EGLBoolean *external_only, + EGLint *num_modifiers) +{ + UNREACHABLE(); + return egl::NoError(); +} + +GLuint DisplayImpl::getNextSurfaceID() +{ + uint64_t id = mNextSurfaceID.generate().getValue(); + ASSERT(id <= 0xfffffffful); + return static_cast(id); +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/DisplayImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/DisplayImpl.h new file mode 100644 index 0000000000..0dea083f9e --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/DisplayImpl.h @@ -0,0 +1,169 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// DisplayImpl.h: Implementation methods of egl::Display + +#ifndef LIBANGLE_RENDERER_DISPLAYIMPL_H_ +#define LIBANGLE_RENDERER_DISPLAYIMPL_H_ + +#include "common/Optional.h" +#include "common/angleutils.h" +#include "libANGLE/Caps.h" +#include "libANGLE/Config.h" +#include "libANGLE/Error.h" +#include "libANGLE/Observer.h" +#include "libANGLE/Stream.h" +#include "libANGLE/Version.h" +#include "libANGLE/renderer/EGLImplFactory.h" +#include "platform/Feature.h" + +#include +#include + +namespace angle +{ +struct FrontendFeatures; +} // namespace angle + +namespace egl +{ +class AttributeMap; +class BlobCache; +class Display; +struct DisplayState; +struct Config; +class Surface; +class ImageSibling; +class Thread; +} // namespace egl + +namespace gl +{ +class Context; +} // namespace gl + +namespace rx +{ +class SurfaceImpl; +class ImageImpl; +struct ConfigDesc; +class DeviceImpl; +class StreamProducerImpl; + +class ShareGroupImpl : angle::NonCopyable +{ + public: + ShareGroupImpl() : mAnyContextWithRobustness(false) {} + virtual ~ShareGroupImpl() {} + virtual void onDestroy(const egl::Display *display) {} + + void onRobustContextAdd() { mAnyContextWithRobustness = true; } + bool hasAnyContextWithRobustness() const { return mAnyContextWithRobustness; } + + private: + // Whether any context in the share group has robustness enabled. If any context in the share + // group is robust, any program created in any context of the share group must have robustness + // enabled. This is because programs are shared between the share group contexts. + bool mAnyContextWithRobustness; +}; + +class DisplayImpl : public EGLImplFactory, public angle::Subject +{ + public: + DisplayImpl(const egl::DisplayState &state); + ~DisplayImpl() override; + + virtual egl::Error initialize(egl::Display *display) = 0; + virtual void terminate() = 0; + virtual egl::Error prepareForCall(); + virtual egl::Error releaseThread(); + + virtual egl::Error makeCurrent(egl::Display *display, + egl::Surface *drawSurface, + egl::Surface *readSurface, + gl::Context *context) = 0; + + virtual egl::ConfigSet generateConfigs() = 0; + + virtual bool testDeviceLost() = 0; + virtual egl::Error restoreLostDevice(const egl::Display *display) = 0; + + virtual bool isValidNativeWindow(EGLNativeWindowType window) const = 0; + virtual egl::Error validateClientBuffer(const egl::Config *configuration, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const egl::AttributeMap &attribs) const; + virtual egl::Error validateImageClientBuffer(const gl::Context *context, + EGLenum target, + EGLClientBuffer clientBuffer, + const egl::AttributeMap &attribs) const; + virtual egl::Error validatePixmap(const egl::Config *config, + EGLNativePixmapType pixmap, + const egl::AttributeMap &attributes) const; + + virtual std::string getRendererDescription() = 0; + virtual std::string getVendorString() = 0; + virtual std::string getVersionString(bool includeFullVersion) = 0; + + virtual DeviceImpl *createDevice(); + + virtual egl::Error waitClient(const gl::Context *context) = 0; + virtual egl::Error waitNative(const gl::Context *context, EGLint engine) = 0; + virtual gl::Version getMaxSupportedESVersion() const = 0; + virtual gl::Version getMaxConformantESVersion() const = 0; + // If desktop GL is not supported in any capacity for a given backend, this returns None. + virtual Optional getMaxSupportedDesktopVersion() const = 0; + const egl::Caps &getCaps() const; + + virtual void setBlobCacheFuncs(EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get) {} + + const egl::DisplayExtensions &getExtensions() const; + + void setBlobCache(egl::BlobCache *blobCache) { mBlobCache = blobCache; } + egl::BlobCache *getBlobCache() const { return mBlobCache; } + + virtual void initializeFrontendFeatures(angle::FrontendFeatures *features) const {} + + virtual void populateFeatureList(angle::FeatureList *features) = 0; + + const egl::DisplayState &getState() const { return mState; } + + virtual egl::Error handleGPUSwitch(); + virtual egl::Error forceGPUSwitch(EGLint gpuIDHigh, EGLint gpuIDLow); + + virtual bool isX11() const; + virtual bool isWayland() const; + virtual bool isGBM() const; + + virtual bool supportsDmaBufFormat(EGLint format) const; + virtual egl::Error queryDmaBufFormats(EGLint max_formats, EGLint *formats, EGLint *num_formats); + virtual egl::Error queryDmaBufModifiers(EGLint format, + EGLint max_modifiers, + EGLuint64KHR *modifiers, + EGLBoolean *external_only, + EGLint *num_modifiers); + GLuint getNextSurfaceID() override; + + protected: + const egl::DisplayState &mState; + + private: + virtual void generateExtensions(egl::DisplayExtensions *outExtensions) const = 0; + virtual void generateCaps(egl::Caps *outCaps) const = 0; + + mutable bool mExtensionsInitialized; + mutable egl::DisplayExtensions mExtensions; + + mutable bool mCapsInitialized; + mutable egl::Caps mCaps; + + egl::BlobCache *mBlobCache; + rx::AtomicSerialFactory mNextSurfaceID; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_DISPLAYIMPL_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/EGLImplFactory.h b/gfx/angle/checkout/src/libANGLE/renderer/EGLImplFactory.h new file mode 100644 index 0000000000..4d5308dc0e --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/EGLImplFactory.h @@ -0,0 +1,104 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// EGLImplFactory.h: +// Factory interface for EGL Impl objects. +// + +#ifndef LIBANGLE_RENDERER_EGLIMPLFACTORY_H_ +#define LIBANGLE_RENDERER_EGLIMPLFACTORY_H_ + +#include "libANGLE/Stream.h" + +namespace egl +{ +class AttributeMap; +struct Config; +class ImageSibling; +struct ImageState; +struct SurfaceState; +} // namespace egl + +namespace gl +{ +class Context; +class ErrorSet; +class State; +} // namespace gl + +namespace rx +{ +class ContextImpl; +class EGLSyncImpl; +class ImageImpl; +class ExternalImageSiblingImpl; +class SurfaceImpl; +class ShareGroupImpl; + +class EGLImplFactory : angle::NonCopyable +{ + public: + EGLImplFactory() {} + virtual ~EGLImplFactory() {} + + virtual SurfaceImpl *createWindowSurface(const egl::SurfaceState &state, + EGLNativeWindowType window, + const egl::AttributeMap &attribs) = 0; + virtual SurfaceImpl *createPbufferSurface(const egl::SurfaceState &state, + const egl::AttributeMap &attribs) = 0; + virtual SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const egl::AttributeMap &attribs) = 0; + virtual SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state, + NativePixmapType nativePixmap, + const egl::AttributeMap &attribs) = 0; + + virtual ImageImpl *createImage(const egl::ImageState &state, + const gl::Context *context, + EGLenum target, + const egl::AttributeMap &attribs) = 0; + + virtual ContextImpl *createContext(const gl::State &state, + gl::ErrorSet *errorSet, + const egl::Config *configuration, + const gl::Context *shareContext, + const egl::AttributeMap &attribs) = 0; + + virtual StreamProducerImpl *createStreamProducerD3DTexture( + egl::Stream::ConsumerType consumerType, + const egl::AttributeMap &attribs) = 0; + + virtual ExternalImageSiblingImpl *createExternalImageSibling(const gl::Context *context, + EGLenum target, + EGLClientBuffer buffer, + const egl::AttributeMap &attribs); + + virtual EGLSyncImpl *createSync(const egl::AttributeMap &attribs); + + virtual ShareGroupImpl *createShareGroup() = 0; + + virtual GLuint getNextSurfaceID() = 0; +}; + +inline ExternalImageSiblingImpl *EGLImplFactory::createExternalImageSibling( + const gl::Context *context, + EGLenum target, + EGLClientBuffer buffer, + const egl::AttributeMap &attribs) +{ + UNREACHABLE(); + return nullptr; +} + +inline EGLSyncImpl *EGLImplFactory::createSync(const egl::AttributeMap &attribs) +{ + UNREACHABLE(); + return nullptr; +} + +} // namespace rx + +#endif // LIBANGLE_RENDERER_EGLIMPLFACTORY_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/EGLReusableSync.cpp b/gfx/angle/checkout/src/libANGLE/renderer/EGLReusableSync.cpp new file mode 100644 index 0000000000..8441b028da --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/EGLReusableSync.cpp @@ -0,0 +1,116 @@ +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// EGLReusableSync.cpp: Implements the egl::ReusableSync class. + +#include "libANGLE/renderer/EGLReusableSync.h" + +#include "libANGLE/Context.h" +#include "libANGLE/renderer/ContextImpl.h" + +namespace rx +{ + +ReusableSync::ReusableSync(const egl::AttributeMap &attribs) + : EGLSyncImpl(), mStatus(EGL_UNSIGNALED) +{} + +void ReusableSync::onDestroy(const egl::Display *display) {} + +ReusableSync::~ReusableSync() +{ + // Release any waiting thread. + mCondVar.notify_all(); +} + +egl::Error ReusableSync::initialize(const egl::Display *display, + const gl::Context *context, + EGLenum type) +{ + return egl::NoError(); +} + +egl::Error ReusableSync::clientWait(const egl::Display *display, + const gl::Context *context, + EGLint flags, + EGLTime timeout, + EGLint *outResult) +{ + if (mStatus == EGL_SIGNALED) + { + *outResult = EGL_CONDITION_SATISFIED_KHR; + return egl::NoError(); + } + if (((flags & EGL_SYNC_FLUSH_COMMANDS_BIT) != 0) && (context != nullptr)) + { + angle::Result result = context->getImplementation()->flush(context); + if (result != angle::Result::Continue) + { + return ResultToEGL(result); + } + } + if (timeout == 0) + { + *outResult = EGL_TIMEOUT_EXPIRED_KHR; + return egl::NoError(); + } + + using NanoSeconds = std::chrono::duration; + NanoSeconds duration = (timeout == EGL_FOREVER) ? NanoSeconds::max() : NanoSeconds(timeout); + std::cv_status waitStatus = std::cv_status::no_timeout; + mMutex.lock(); + waitStatus = mCondVar.wait_for(mMutex, duration); + mMutex.unlock(); + + switch (waitStatus) + { + case std::cv_status::no_timeout: // Signaled. + *outResult = EGL_CONDITION_SATISFIED_KHR; + break; + case std::cv_status::timeout: // Timed-out. + *outResult = EGL_TIMEOUT_EXPIRED_KHR; + break; + default: + break; + } + return egl::NoError(); +} + +egl::Error ReusableSync::serverWait(const egl::Display *display, + const gl::Context *context, + EGLint flags) +{ + // Does not support server wait. + return egl::EglBadMatch(); +} + +egl::Error ReusableSync::signal(const egl::Display *display, + const gl::Context *context, + EGLint mode) +{ + if (mode == EGL_SIGNALED) + { + if (mStatus == EGL_UNSIGNALED) + { + // Release all threads. + mCondVar.notify_all(); + } + mStatus = EGL_SIGNALED; + } + else + { + mStatus = EGL_UNSIGNALED; + } + return egl::NoError(); +} + +egl::Error ReusableSync::getStatus(const egl::Display *display, EGLint *outStatus) +{ + *outStatus = mStatus; + return egl::NoError(); +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/EGLReusableSync.h b/gfx/angle/checkout/src/libANGLE/renderer/EGLReusableSync.h new file mode 100644 index 0000000000..12c972565d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/EGLReusableSync.h @@ -0,0 +1,54 @@ +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// EGL_KHR_reusable_sync + +#ifndef LIBANGLE_RENDERER_EGLREUSABLESYNC_H_ +#define LIBANGLE_RENDERER_EGLREUSABLESYNC_H_ + +#include "libANGLE/AttributeMap.h" +#include "libANGLE/renderer/EGLSyncImpl.h" + +#include "common/angleutils.h" + +#include + +namespace rx +{ + +class ReusableSync final : public EGLSyncImpl +{ + public: + ReusableSync(const egl::AttributeMap &attribs); + ~ReusableSync() override; + + void onDestroy(const egl::Display *display) override; + + egl::Error initialize(const egl::Display *display, + const gl::Context *context, + EGLenum type) override; + egl::Error clientWait(const egl::Display *display, + const gl::Context *context, + EGLint flags, + EGLTime timeout, + EGLint *outResult) override; + egl::Error serverWait(const egl::Display *display, + const gl::Context *context, + EGLint flags) override; + egl::Error signal(const egl::Display *display, + const gl::Context *context, + EGLint mode) override; + egl::Error getStatus(const egl::Display *display, EGLint *outStatus) override; + + private: + EGLint mStatus; + std::condition_variable mCondVar; + std::unique_lock mMutex; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_EGLREUSABLESYNC_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/EGLSyncImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/EGLSyncImpl.cpp new file mode 100644 index 0000000000..a62edce539 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/EGLSyncImpl.cpp @@ -0,0 +1,37 @@ +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// EGLSyncImpl.cpp: Implements the rx::EGLSyncImpl class. + +#include "libANGLE/renderer/EGLReusableSync.h" + +#include "angle_gl.h" + +#include "common/utilities.h" + +namespace rx +{ + +egl::Error EGLSyncImpl::signal(const egl::Display *display, const gl::Context *context, EGLint mode) +{ + UNREACHABLE(); + return egl::EglBadMatch(); +} + +egl::Error EGLSyncImpl::copyMetalSharedEventANGLE(const egl::Display *display, + void **eventOut) const +{ + UNREACHABLE(); + return egl::EglBadMatch(); +} + +egl::Error EGLSyncImpl::dupNativeFenceFD(const egl::Display *display, EGLint *fdOut) const +{ + UNREACHABLE(); + return egl::EglBadMatch(); +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/EGLSyncImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/EGLSyncImpl.h new file mode 100644 index 0000000000..1dee6d315b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/EGLSyncImpl.h @@ -0,0 +1,57 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// EGLSyncImpl.h: Defines the rx::EGLSyncImpl class. + +#ifndef LIBANGLE_RENDERER_EGLSYNCIMPL_H_ +#define LIBANGLE_RENDERER_EGLSYNCIMPL_H_ + +#include "libANGLE/Error.h" + +#include "common/angleutils.h" + +#include "angle_gl.h" + +namespace egl +{ +class Display; +} // namespace egl + +namespace gl +{ +class Context; +} // namespace gl + +namespace rx +{ +class EGLSyncImpl : angle::NonCopyable +{ + public: + EGLSyncImpl() {} + virtual ~EGLSyncImpl() {} + + virtual void onDestroy(const egl::Display *display) {} + + virtual egl::Error initialize(const egl::Display *display, + const gl::Context *context, + EGLenum type) = 0; + virtual egl::Error clientWait(const egl::Display *display, + const gl::Context *context, + EGLint flags, + EGLTime timeout, + EGLint *outResult) = 0; + virtual egl::Error serverWait(const egl::Display *display, + const gl::Context *context, + EGLint flags) = 0; + virtual egl::Error signal(const egl::Display *display, const gl::Context *context, EGLint mode); + virtual egl::Error getStatus(const egl::Display *display, EGLint *outStatus) = 0; + virtual egl::Error copyMetalSharedEventANGLE(const egl::Display *display, + void **outEvent) const; + virtual egl::Error dupNativeFenceFD(const egl::Display *display, EGLint *fdOut) const; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_EGLSYNCIMPL_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/FenceNVImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/FenceNVImpl.h new file mode 100644 index 0000000000..99c002ad2e --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/FenceNVImpl.h @@ -0,0 +1,38 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// FenceNVImpl.h: Defines the rx::FenceNVImpl class. + +#ifndef LIBANGLE_RENDERER_FENCENVIMPL_H_ +#define LIBANGLE_RENDERER_FENCENVIMPL_H_ + +#include "libANGLE/Error.h" + +#include "common/angleutils.h" + +#include "angle_gl.h" + +namespace gl +{ +class Context; +} // namespace gl + +namespace rx +{ +class FenceNVImpl : angle::NonCopyable +{ + public: + FenceNVImpl() {} + virtual ~FenceNVImpl() {} + + virtual void onDestroy(const gl::Context *context) = 0; + virtual angle::Result set(const gl::Context *context, GLenum condition) = 0; + virtual angle::Result test(const gl::Context *context, GLboolean *outFinished) = 0; + virtual angle::Result finish(const gl::Context *context) = 0; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_FENCENVIMPL_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/Format.h b/gfx/angle/checkout/src/libANGLE/renderer/Format.h new file mode 100644 index 0000000000..1974381f53 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/Format.h @@ -0,0 +1,238 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Format: +// A universal description of typed GPU storage. Across multiple +// renderer back-ends, there are common formats and some distinct +// permutations, this enum encapsulates them all. Formats apply to +// textures, but could also apply to any typed data. + +#ifndef LIBANGLE_RENDERER_FORMAT_H_ +#define LIBANGLE_RENDERER_FORMAT_H_ + +#include "libANGLE/renderer/FormatID_autogen.h" +#include "libANGLE/renderer/renderer_utils.h" + +namespace angle +{ +enum class FormatID; + +extern const Format gFormatInfoTable[]; + +struct Format final : private angle::NonCopyable +{ + inline constexpr Format(FormatID id, + GLenum glFormat, + GLenum fboFormat, + rx::MipGenerationFunction mipGen, + const rx::FastCopyFunctionMap &fastCopyFunctions, + rx::PixelReadFunction colorRead, + rx::PixelWriteFunction colorWrite, + GLenum componentType, + GLuint redBits, + GLuint greenBits, + GLuint blueBits, + GLuint alphaBits, + GLuint luminanceBits, + GLuint depthBits, + GLuint stencilBits, + GLuint pixelBytes, + GLuint componentAlignmentMask, + bool isBlock, + bool isFixed, + bool isScaled, + bool isSRGB, + bool isYUV, + gl::VertexAttribType vertexAttribType); + + static const Format &Get(FormatID id) { return gFormatInfoTable[static_cast(id)]; } + + static FormatID InternalFormatToID(GLenum internalFormat); + + constexpr bool hasDepthOrStencilBits() const; + constexpr bool isLUMA() const; + constexpr bool isBGRA() const; + + constexpr bool isSint() const; + constexpr bool isUint() const; + constexpr bool isSnorm() const; + constexpr bool isUnorm() const; + constexpr bool isFloat() const; + constexpr bool isVertexTypeHalfFloat() const; + + constexpr bool isInt() const { return isSint() || isUint(); } + constexpr bool isNorm() const { return isSnorm() || isUnorm(); } + constexpr bool isPureInt() const { return isInt() && !isScaled; } + + bool operator==(const Format &other) const { return this->id == other.id; } + + FormatID id; + + // The closest matching GL internal format for the storage this format uses. Note that this + // may be a different internal format than the one this ANGLE format is used for. + GLenum glInternalFormat; + + // The format we should report to the GL layer when querying implementation formats from a FBO. + // This might not be the same as the glInternalFormat, since some DXGI formats don't have + // matching GL format enums, like BGRA4, BGR5A1 and B5G6R6. + GLenum fboImplementationInternalFormat; + + rx::MipGenerationFunction mipGenerationFunction; + rx::PixelReadFunction pixelReadFunction; + rx::PixelWriteFunction pixelWriteFunction; + + // A map from a gl::FormatType to a fast pixel copy function for this format. + const rx::FastCopyFunctionMap &fastCopyFunctions; + + GLenum componentType; + + GLuint redBits; + GLuint greenBits; + GLuint blueBits; + GLuint alphaBits; + GLuint luminanceBits; + GLuint depthBits; + GLuint stencilBits; + + GLuint pixelBytes; + + // For 1-byte components, is 0x0. For 2-byte, is 0x1. For 4-byte, is 0x3. For all others, + // MAX_UINT. + GLuint componentAlignmentMask; + + GLuint channelCount; + + bool isBlock; + bool isFixed; + bool isScaled; + bool isSRGB; + bool isYUV; + + // For vertex formats only. Returns the "type" value for glVertexAttribPointer etc. + gl::VertexAttribType vertexAttribType; +}; + +constexpr GLuint GetChannelCount(GLuint redBits, + GLuint greenBits, + GLuint blueBits, + GLuint alphaBits, + GLuint luminanceBits, + GLuint depthBits, + GLuint stencilBits) +{ + return (redBits > 0 ? 1 : 0) + (greenBits > 0 ? 1 : 0) + (blueBits > 0 ? 1 : 0) + + (alphaBits > 0 ? 1 : 0) + (luminanceBits > 0 ? 1 : 0) + (depthBits > 0 ? 1 : 0) + + (stencilBits > 0 ? 1 : 0); +} + +constexpr Format::Format(FormatID id, + GLenum glFormat, + GLenum fboFormat, + rx::MipGenerationFunction mipGen, + const rx::FastCopyFunctionMap &fastCopyFunctions, + rx::PixelReadFunction colorRead, + rx::PixelWriteFunction colorWrite, + GLenum componentType, + GLuint redBits, + GLuint greenBits, + GLuint blueBits, + GLuint alphaBits, + GLuint luminanceBits, + GLuint depthBits, + GLuint stencilBits, + GLuint pixelBytes, + GLuint componentAlignmentMask, + bool isBlock, + bool isFixed, + bool isScaled, + bool isSRGB, + bool isYUV, + gl::VertexAttribType vertexAttribType) + : id(id), + glInternalFormat(glFormat), + fboImplementationInternalFormat(fboFormat), + mipGenerationFunction(mipGen), + pixelReadFunction(colorRead), + pixelWriteFunction(colorWrite), + fastCopyFunctions(fastCopyFunctions), + componentType(componentType), + redBits(redBits), + greenBits(greenBits), + blueBits(blueBits), + alphaBits(alphaBits), + luminanceBits(luminanceBits), + depthBits(depthBits), + stencilBits(stencilBits), + pixelBytes(pixelBytes), + componentAlignmentMask(componentAlignmentMask), + channelCount(GetChannelCount(redBits, + greenBits, + blueBits, + alphaBits, + luminanceBits, + depthBits, + stencilBits)), + isBlock(isBlock), + isFixed(isFixed), + isScaled(isScaled), + isSRGB(isSRGB), + isYUV(isYUV), + vertexAttribType(vertexAttribType) +{} + +constexpr bool Format::hasDepthOrStencilBits() const +{ + return depthBits > 0 || stencilBits > 0; +} + +constexpr bool Format::isLUMA() const +{ + // There's no format with G or B without R + ASSERT(redBits > 0 || (greenBits == 0 && blueBits == 0)); + return redBits == 0 && (luminanceBits > 0 || alphaBits > 0); +} + +constexpr bool Format::isBGRA() const +{ + return id == FormatID::B8G8R8A8_UNORM || id == FormatID::B8G8R8A8_UNORM_SRGB || + id == FormatID::B8G8R8A8_TYPELESS || id == FormatID::B8G8R8A8_TYPELESS_SRGB; +} + +constexpr bool Format::isSint() const +{ + return componentType == GL_INT; +} + +constexpr bool Format::isUint() const +{ + return componentType == GL_UNSIGNED_INT; +} + +constexpr bool Format::isSnorm() const +{ + return componentType == GL_SIGNED_NORMALIZED; +} + +constexpr bool Format::isUnorm() const +{ + return componentType == GL_UNSIGNED_NORMALIZED; +} + +constexpr bool Format::isFloat() const +{ + return componentType == GL_FLOAT; +} + +constexpr bool Format::isVertexTypeHalfFloat() const +{ + return vertexAttribType == gl::VertexAttribType::HalfFloat; +} + +template +using FormatMap = PackedEnumMap; + +} // namespace angle + +#endif // LIBANGLE_RENDERER_FORMAT_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/FormatID_autogen.h b/gfx/angle/checkout/src/libANGLE/renderer/FormatID_autogen.h new file mode 100644 index 0000000000..1e6ded8001 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/FormatID_autogen.h @@ -0,0 +1,264 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_angle_format_table.py using data from angle_format_data.json +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ANGLE format enumeration. + +#ifndef LIBANGLE_RENDERER_FORMATID_H_ +#define LIBANGLE_RENDERER_FORMATID_H_ + +#include + +namespace angle +{ + +enum class FormatID +{ + NONE, + D16_UNORM, + D24_UNORM_S8_UINT, + D24_UNORM_X8_UINT, + D32_FLOAT, + D32_FLOAT_S8X24_UINT, + D32_UNORM, + S8_UINT, + A16_FLOAT, + A1R5G5B5_UNORM, + A2R10G10B10_SINT_VERTEX, + A2R10G10B10_SNORM_VERTEX, + A2R10G10B10_SSCALED_VERTEX, + A2R10G10B10_UINT_VERTEX, + A2R10G10B10_UNORM_VERTEX, + A2R10G10B10_USCALED_VERTEX, + A32_FLOAT, + A8_UNORM, + ASTC_10x10_SRGB_BLOCK, + ASTC_10x10_UNORM_BLOCK, + ASTC_10x5_SRGB_BLOCK, + ASTC_10x5_UNORM_BLOCK, + ASTC_10x6_SRGB_BLOCK, + ASTC_10x6_UNORM_BLOCK, + ASTC_10x8_SRGB_BLOCK, + ASTC_10x8_UNORM_BLOCK, + ASTC_12x10_SRGB_BLOCK, + ASTC_12x10_UNORM_BLOCK, + ASTC_12x12_SRGB_BLOCK, + ASTC_12x12_UNORM_BLOCK, + ASTC_3x3x3_UNORM_BLOCK, + ASTC_3x3x3_UNORM_SRGB_BLOCK, + ASTC_4x3x3_UNORM_BLOCK, + ASTC_4x3x3_UNORM_SRGB_BLOCK, + ASTC_4x4_SRGB_BLOCK, + ASTC_4x4_UNORM_BLOCK, + ASTC_4x4x3_UNORM_BLOCK, + ASTC_4x4x3_UNORM_SRGB_BLOCK, + ASTC_4x4x4_UNORM_BLOCK, + ASTC_4x4x4_UNORM_SRGB_BLOCK, + ASTC_5x4_SRGB_BLOCK, + ASTC_5x4_UNORM_BLOCK, + ASTC_5x4x4_UNORM_BLOCK, + ASTC_5x4x4_UNORM_SRGB_BLOCK, + ASTC_5x5_SRGB_BLOCK, + ASTC_5x5_UNORM_BLOCK, + ASTC_5x5x4_UNORM_BLOCK, + ASTC_5x5x4_UNORM_SRGB_BLOCK, + ASTC_5x5x5_UNORM_BLOCK, + ASTC_5x5x5_UNORM_SRGB_BLOCK, + ASTC_6x5_SRGB_BLOCK, + ASTC_6x5_UNORM_BLOCK, + ASTC_6x5x5_UNORM_BLOCK, + ASTC_6x5x5_UNORM_SRGB_BLOCK, + ASTC_6x6_SRGB_BLOCK, + ASTC_6x6_UNORM_BLOCK, + ASTC_6x6x5_UNORM_BLOCK, + ASTC_6x6x5_UNORM_SRGB_BLOCK, + ASTC_6x6x6_UNORM_BLOCK, + ASTC_6x6x6_UNORM_SRGB_BLOCK, + ASTC_8x5_SRGB_BLOCK, + ASTC_8x5_UNORM_BLOCK, + ASTC_8x6_SRGB_BLOCK, + ASTC_8x6_UNORM_BLOCK, + ASTC_8x8_SRGB_BLOCK, + ASTC_8x8_UNORM_BLOCK, + B10G10R10A2_UNORM, + B4G4R4A4_UNORM, + B5G5R5A1_UNORM, + B5G6R5_UNORM, + B8G8R8A8_TYPELESS, + B8G8R8A8_TYPELESS_SRGB, + B8G8R8A8_UNORM, + B8G8R8A8_UNORM_SRGB, + B8G8R8X8_UNORM, + BC1_RGBA_UNORM_BLOCK, + BC1_RGBA_UNORM_SRGB_BLOCK, + BC1_RGB_UNORM_BLOCK, + BC1_RGB_UNORM_SRGB_BLOCK, + BC2_RGBA_UNORM_BLOCK, + BC2_RGBA_UNORM_SRGB_BLOCK, + BC3_RGBA_UNORM_BLOCK, + BC3_RGBA_UNORM_SRGB_BLOCK, + BC4_RED_SNORM_BLOCK, + BC4_RED_UNORM_BLOCK, + BC5_RG_SNORM_BLOCK, + BC5_RG_UNORM_BLOCK, + BC6H_RGB_SFLOAT_BLOCK, + BC6H_RGB_UFLOAT_BLOCK, + BC7_RGBA_UNORM_BLOCK, + BC7_RGBA_UNORM_SRGB_BLOCK, + EAC_R11G11_SNORM_BLOCK, + EAC_R11G11_UNORM_BLOCK, + EAC_R11_SNORM_BLOCK, + EAC_R11_UNORM_BLOCK, + ETC1_LOSSY_DECODE_R8G8B8_UNORM_BLOCK, + ETC1_R8G8B8_UNORM_BLOCK, + ETC2_R8G8B8A1_SRGB_BLOCK, + ETC2_R8G8B8A1_UNORM_BLOCK, + ETC2_R8G8B8A8_SRGB_BLOCK, + ETC2_R8G8B8A8_UNORM_BLOCK, + ETC2_R8G8B8_SRGB_BLOCK, + ETC2_R8G8B8_UNORM_BLOCK, + G8_B8R8_2PLANE_420_UNORM, + G8_B8_R8_3PLANE_420_UNORM, + L16A16_FLOAT, + L16_FLOAT, + L32A32_FLOAT, + L32_FLOAT, + L8A8_UNORM, + L8_UNORM, + PALETTE4_R4G4B4A4_UNORM, + PALETTE4_R5G5B5A1_UNORM, + PALETTE4_R5G6B5_UNORM, + PALETTE4_R8G8B8A8_UNORM, + PALETTE4_R8G8B8_UNORM, + PALETTE8_R4G4B4A4_UNORM, + PALETTE8_R5G5B5A1_UNORM, + PALETTE8_R5G6B5_UNORM, + PALETTE8_R8G8B8A8_UNORM, + PALETTE8_R8G8B8_UNORM, + PVRTC1_RGBA_2BPP_UNORM_BLOCK, + PVRTC1_RGBA_2BPP_UNORM_SRGB_BLOCK, + PVRTC1_RGBA_4BPP_UNORM_BLOCK, + PVRTC1_RGBA_4BPP_UNORM_SRGB_BLOCK, + PVRTC1_RGB_2BPP_UNORM_BLOCK, + PVRTC1_RGB_2BPP_UNORM_SRGB_BLOCK, + PVRTC1_RGB_4BPP_UNORM_BLOCK, + PVRTC1_RGB_4BPP_UNORM_SRGB_BLOCK, + R10G10B10A2_SINT, + R10G10B10A2_SNORM, + R10G10B10A2_SSCALED, + R10G10B10A2_UINT, + R10G10B10A2_UNORM, + R10G10B10A2_USCALED, + R10G10B10X2_UNORM, + R11G11B10_FLOAT, + R16G16B16A16_FLOAT, + R16G16B16A16_SINT, + R16G16B16A16_SNORM, + R16G16B16A16_SSCALED, + R16G16B16A16_UINT, + R16G16B16A16_UNORM, + R16G16B16A16_USCALED, + R16G16B16_FLOAT, + R16G16B16_SINT, + R16G16B16_SNORM, + R16G16B16_SSCALED, + R16G16B16_UINT, + R16G16B16_UNORM, + R16G16B16_USCALED, + R16G16_FLOAT, + R16G16_SINT, + R16G16_SNORM, + R16G16_SSCALED, + R16G16_UINT, + R16G16_UNORM, + R16G16_USCALED, + R16_FLOAT, + R16_SINT, + R16_SNORM, + R16_SSCALED, + R16_UINT, + R16_UNORM, + R16_USCALED, + R32G32B32A32_FIXED, + R32G32B32A32_FLOAT, + R32G32B32A32_SINT, + R32G32B32A32_SNORM, + R32G32B32A32_SSCALED, + R32G32B32A32_UINT, + R32G32B32A32_UNORM, + R32G32B32A32_USCALED, + R32G32B32_FIXED, + R32G32B32_FLOAT, + R32G32B32_SINT, + R32G32B32_SNORM, + R32G32B32_SSCALED, + R32G32B32_UINT, + R32G32B32_UNORM, + R32G32B32_USCALED, + R32G32_FIXED, + R32G32_FLOAT, + R32G32_SINT, + R32G32_SNORM, + R32G32_SSCALED, + R32G32_UINT, + R32G32_UNORM, + R32G32_USCALED, + R32_FIXED, + R32_FLOAT, + R32_SINT, + R32_SNORM, + R32_SSCALED, + R32_UINT, + R32_UNORM, + R32_USCALED, + R4G4B4A4_UNORM, + R5G5B5A1_UNORM, + R5G6B5_UNORM, + R8G8B8A8_SINT, + R8G8B8A8_SNORM, + R8G8B8A8_SSCALED, + R8G8B8A8_TYPELESS, + R8G8B8A8_TYPELESS_SRGB, + R8G8B8A8_UINT, + R8G8B8A8_UNORM, + R8G8B8A8_UNORM_SRGB, + R8G8B8A8_USCALED, + R8G8B8X8_UNORM, + R8G8B8_SINT, + R8G8B8_SNORM, + R8G8B8_SSCALED, + R8G8B8_UINT, + R8G8B8_UNORM, + R8G8B8_UNORM_SRGB, + R8G8B8_USCALED, + R8G8_SINT, + R8G8_SNORM, + R8G8_SSCALED, + R8G8_UINT, + R8G8_UNORM, + R8G8_UNORM_SRGB, + R8G8_USCALED, + R8_SINT, + R8_SNORM, + R8_SSCALED, + R8_UINT, + R8_UNORM, + R8_UNORM_SRGB, + R8_USCALED, + R9G9B9E5_SHAREDEXP, + X2R10G10B10_SINT_VERTEX, + X2R10G10B10_SNORM_VERTEX, + X2R10G10B10_SSCALED_VERTEX, + X2R10G10B10_UINT_VERTEX, + X2R10G10B10_UNORM_VERTEX, + X2R10G10B10_USCALED_VERTEX +}; + +constexpr uint32_t kNumANGLEFormats = 238; + +} // namespace angle + +#endif // LIBANGLE_RENDERER_FORMATID_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/Format_table_autogen.cpp b/gfx/angle/checkout/src/libANGLE/renderer/Format_table_autogen.cpp new file mode 100644 index 0000000000..df700ab74f --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/Format_table_autogen.cpp @@ -0,0 +1,762 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_angle_format_table.py using data from angle_format_data.json +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ANGLE Format table: +// Queries for typed format information from the ANGLE format enum. + +#include "libANGLE/renderer/Format.h" + +#include "image_util/copyimage.h" +#include "image_util/generatemip.h" +#include "image_util/loadimage.h" + +namespace angle +{ + +static constexpr rx::FastCopyFunctionMap::Entry BGRAEntry = {angle::FormatID::R8G8B8A8_UNORM, + CopyBGRA8ToRGBA8}; +static constexpr rx::FastCopyFunctionMap BGRACopyFunctions = {&BGRAEntry, 1}; +static constexpr rx::FastCopyFunctionMap NoCopyFunctions; + +const Format gFormatInfoTable[] = { + // clang-format off + { FormatID::NONE, GL_NONE, GL_NONE, nullptr, NoCopyFunctions, nullptr, nullptr, GL_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, false, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::D16_UNORM, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT16, nullptr, NoCopyFunctions, ReadDepthStencil, WriteDepthStencil, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 16, 0, 2, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, nullptr, NoCopyFunctions, ReadDepthStencil, WriteDepthStencil, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 24, 8, 4, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::D24_UNORM_X8_UINT, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT24, nullptr, NoCopyFunctions, ReadDepthStencil, WriteDepthStencil, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 24, 0, 4, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, nullptr, NoCopyFunctions, ReadDepthStencil, WriteDepthStencil, GL_FLOAT, 0, 0, 0, 0, 0, 32, 0, 4, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::Float }, + { FormatID::D32_FLOAT_S8X24_UINT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, nullptr, NoCopyFunctions, ReadDepthStencil, WriteDepthStencil, GL_FLOAT, 0, 0, 0, 0, 0, 32, 8, 8, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::Float }, + { FormatID::D32_UNORM, GL_DEPTH_COMPONENT32_OES, GL_DEPTH_COMPONENT32_OES, nullptr, NoCopyFunctions, ReadDepthStencil, WriteDepthStencil, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 32, 0, 4, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::S8_UINT, GL_STENCIL_INDEX8, GL_STENCIL_INDEX8, nullptr, NoCopyFunctions, ReadDepthStencil, WriteDepthStencil, GL_UNSIGNED_INT, 0, 0, 0, 0, 0, 0, 8, 1, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::A16_FLOAT, GL_ALPHA16F_EXT, GL_ALPHA16F_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 0, 0, 0, 16, 0, 0, 0, 2, 1, false, false, false, false, false, gl::VertexAttribType::Float }, + { FormatID::A1R5G5B5_UNORM, GL_A1RGB5_ANGLEX, GL_A1RGB5_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 5, 5, 5, 1, 0, 0, 0, 2, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::A2R10G10B10_SINT_VERTEX, GL_INT_10_10_10_2_OES, GL_INT_10_10_10_2_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_INT, 10, 10, 10, 2, 0, 0, 0, 4, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::Int1010102 }, + { FormatID::A2R10G10B10_SNORM_VERTEX, GL_A2_RGB10_SNORM_ANGLEX, GL_A2_RGB10_SNORM_ANGLEX, nullptr, NoCopyFunctions, nullptr, nullptr, GL_SIGNED_NORMALIZED, 10, 10, 10, 2, 0, 0, 0, 4, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::Int1010102 }, + { FormatID::A2R10G10B10_SSCALED_VERTEX, GL_A2_RGB10_SSCALED_ANGLEX, GL_A2_RGB10_SSCALED_ANGLEX, nullptr, NoCopyFunctions, nullptr, nullptr, GL_INT, 10, 10, 10, 2, 0, 0, 0, 4, std::numeric_limits::max(), false, false, true, false, false, gl::VertexAttribType::Int1010102 }, + { FormatID::A2R10G10B10_UINT_VERTEX, GL_UNSIGNED_INT_10_10_10_2_OES, GL_UNSIGNED_INT_10_10_10_2_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_INT, 10, 10, 10, 2, 0, 0, 0, 4, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::UnsignedInt1010102 }, + { FormatID::A2R10G10B10_UNORM_VERTEX, GL_A2_RGB10_UNORM_ANGLEX, GL_A2_RGB10_UNORM_ANGLEX, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 10, 10, 10, 2, 0, 0, 0, 4, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::UnsignedInt1010102 }, + { FormatID::A2R10G10B10_USCALED_VERTEX, GL_A2_RGB10_USCALED_ANGLEX, GL_A2_RGB10_USCALED_ANGLEX, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_INT, 10, 10, 10, 2, 0, 0, 0, 4, std::numeric_limits::max(), false, false, true, false, false, gl::VertexAttribType::UnsignedInt1010102 }, + { FormatID::A32_FLOAT, GL_ALPHA32F_EXT, GL_ALPHA32F_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 0, 0, 0, 32, 0, 0, 0, 4, 3, false, false, false, false, false, gl::VertexAttribType::Float }, + { FormatID::A8_UNORM, GL_ALPHA8_EXT, GL_ALPHA8_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 8, 0, 0, 0, 1, 0, false, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_10x10_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_10x10_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_10x10_KHR, GL_COMPRESSED_RGBA_ASTC_10x10_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_10x5_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_10x5_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_10x5_KHR, GL_COMPRESSED_RGBA_ASTC_10x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_10x6_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_10x6_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_10x6_KHR, GL_COMPRESSED_RGBA_ASTC_10x6_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_10x8_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_10x8_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_10x8_KHR, GL_COMPRESSED_RGBA_ASTC_10x8_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_12x10_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_12x10_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_12x10_KHR, GL_COMPRESSED_RGBA_ASTC_12x10_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_12x12_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_12x12_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_12x12_KHR, GL_COMPRESSED_RGBA_ASTC_12x12_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_3x3x3_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_3x3x3_OES, GL_COMPRESSED_RGBA_ASTC_3x3x3_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_3x3x3_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_4x3x3_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_4x3x3_OES, GL_COMPRESSED_RGBA_ASTC_4x3x3_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_4x3x3_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_4x4_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_4x4_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_4x4_KHR, GL_COMPRESSED_RGBA_ASTC_4x4_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_4x4x3_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_4x4x3_OES, GL_COMPRESSED_RGBA_ASTC_4x4x3_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_4x4x3_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_4x4x4_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_4x4x4_OES, GL_COMPRESSED_RGBA_ASTC_4x4x4_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_4x4x4_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_5x4_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_5x4_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_5x4_KHR, GL_COMPRESSED_RGBA_ASTC_5x4_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_5x4x4_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_5x4x4_OES, GL_COMPRESSED_RGBA_ASTC_5x4x4_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_5x4x4_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_5x5_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_5x5_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_5x5_KHR, GL_COMPRESSED_RGBA_ASTC_5x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_5x5x4_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_5x5x4_OES, GL_COMPRESSED_RGBA_ASTC_5x5x4_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_5x5x4_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_5x5x5_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_5x5x5_OES, GL_COMPRESSED_RGBA_ASTC_5x5x5_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_5x5x5_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_6x5_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_6x5_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_6x5_KHR, GL_COMPRESSED_RGBA_ASTC_6x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_6x5x5_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_6x5x5_OES, GL_COMPRESSED_RGBA_ASTC_6x5x5_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_6x5x5_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_6x6_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_6x6_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_6x6_KHR, GL_COMPRESSED_RGBA_ASTC_6x6_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_6x6x5_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_6x6x5_OES, GL_COMPRESSED_RGBA_ASTC_6x6x5_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_6x6x5_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_6x6x6_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_6x6x6_OES, GL_COMPRESSED_RGBA_ASTC_6x6x6_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_6x6x6_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_8x5_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_8x5_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_8x5_KHR, GL_COMPRESSED_RGBA_ASTC_8x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_8x6_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_8x6_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_8x6_KHR, GL_COMPRESSED_RGBA_ASTC_8x6_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_8x8_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ASTC_8x8_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_8x8_KHR, GL_COMPRESSED_RGBA_ASTC_8x8_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::B10G10R10A2_UNORM, GL_BGR10_A2_ANGLEX, GL_BGR10_A2_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 10, 10, 10, 2, 0, 0, 0, 4, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::UnsignedInt2101010 }, + { FormatID::B4G4R4A4_UNORM, GL_BGRA4_ANGLEX, GL_RGBA4, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 4, 4, 4, 4, 0, 0, 0, 2, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::B5G5R5A1_UNORM, GL_BGR5_A1_ANGLEX, GL_RGB5_A1, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 5, 5, 5, 1, 0, 0, 0, 2, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::B5G6R5_UNORM, GL_BGR565_ANGLEX, GL_RGB565, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 5, 6, 5, 0, 0, 0, 0, 2, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::B8G8R8A8_TYPELESS, GL_BGRA8_EXT, GL_BGRA8_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 0, 4, 0, false, false, false, false, false, gl::VertexAttribType::UnsignedByte }, + { FormatID::B8G8R8A8_TYPELESS_SRGB, GL_BGRA8_SRGB_ANGLEX, GL_BGRA8_SRGB_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 0, 4, 0, false, false, false, true, false, gl::VertexAttribType::Byte }, + { FormatID::B8G8R8A8_UNORM, GL_BGRA8_EXT, GL_BGRA8_EXT, GenerateMip, BGRACopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 0, 4, 0, false, false, false, false, false, gl::VertexAttribType::UnsignedByte }, + { FormatID::B8G8R8A8_UNORM_SRGB, GL_BGRA8_SRGB_ANGLEX, GL_BGRA8_SRGB_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 0, 4, 0, false, false, false, true, false, gl::VertexAttribType::Byte }, + { FormatID::B8G8R8X8_UNORM, GL_BGRA8_EXT, GL_BGRA8_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 4, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::UnsignedByte }, + { FormatID::BC1_RGBA_UNORM_BLOCK, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 8, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::BC1_RGBA_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 8, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::BC1_RGB_UNORM_BLOCK, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 8, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::BC1_RGB_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 8, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::BC2_RGBA_UNORM_BLOCK, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::BC2_RGBA_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::BC3_RGBA_UNORM_BLOCK, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::BC3_RGBA_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::BC4_RED_SNORM_BLOCK, GL_COMPRESSED_SIGNED_RED_RGTC1_EXT, GL_COMPRESSED_SIGNED_RED_RGTC1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_SIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 8, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::BC4_RED_UNORM_BLOCK, GL_COMPRESSED_RED_RGTC1_EXT, GL_COMPRESSED_RED_RGTC1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 8, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::BC5_RG_SNORM_BLOCK, GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT, GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_SIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::BC5_RG_UNORM_BLOCK, GL_COMPRESSED_RED_GREEN_RGTC2_EXT, GL_COMPRESSED_RED_GREEN_RGTC2_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::BC6H_RGB_SFLOAT_BLOCK, GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT, GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_FLOAT, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::BC6H_RGB_UFLOAT_BLOCK, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_FLOAT, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::BC7_RGBA_UNORM_BLOCK, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::BC7_RGBA_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::EAC_R11G11_SNORM_BLOCK, GL_COMPRESSED_SIGNED_RG11_EAC, GL_COMPRESSED_SIGNED_RG11_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_SIGNED_NORMALIZED, 11, 11, 0, 0, 0, 0, 0, 16, 0, true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::EAC_R11G11_UNORM_BLOCK, GL_COMPRESSED_RG11_EAC, GL_COMPRESSED_RG11_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 11, 11, 0, 0, 0, 0, 0, 16, 0, true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::EAC_R11_SNORM_BLOCK, GL_COMPRESSED_SIGNED_R11_EAC, GL_COMPRESSED_SIGNED_R11_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_SIGNED_NORMALIZED, 11, 0, 0, 0, 0, 0, 0, 8, 0, true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::EAC_R11_UNORM_BLOCK, GL_COMPRESSED_R11_EAC, GL_COMPRESSED_R11_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 11, 0, 0, 0, 0, 0, 0, 8, 0, true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::ETC1_LOSSY_DECODE_R8G8B8_UNORM_BLOCK, GL_ETC1_RGB8_LOSSY_DECODE_ANGLE, GL_ETC1_RGB8_LOSSY_DECODE_ANGLE, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 8, 0, true, false, false, false, false, gl::VertexAttribType::UnsignedByte }, + { FormatID::ETC1_R8G8B8_UNORM_BLOCK, GL_ETC1_RGB8_OES, GL_ETC1_RGB8_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 8, 0, true, false, false, false, false, gl::VertexAttribType::UnsignedByte }, + { FormatID::ETC2_R8G8B8A1_SRGB_BLOCK, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 1, 0, 0, 0, 8, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::Byte }, + { FormatID::ETC2_R8G8B8A1_UNORM_BLOCK, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 1, 0, 0, 0, 8, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::UnsignedByte }, + { FormatID::ETC2_R8G8B8A8_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 0, 16, 0, true, false, false, true, false, gl::VertexAttribType::Byte }, + { FormatID::ETC2_R8G8B8A8_UNORM_BLOCK, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_COMPRESSED_RGBA8_ETC2_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 0, 16, 0, true, false, false, false, false, gl::VertexAttribType::UnsignedByte }, + { FormatID::ETC2_R8G8B8_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ETC2, GL_COMPRESSED_SRGB8_ETC2, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 8, 0, true, false, false, true, false, gl::VertexAttribType::Byte }, + { FormatID::ETC2_R8G8B8_UNORM_BLOCK, GL_COMPRESSED_RGB8_ETC2, GL_COMPRESSED_RGB8_ETC2, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 8, 0, true, false, false, false, false, gl::VertexAttribType::UnsignedByte }, + { FormatID::G8_B8R8_2PLANE_420_UNORM, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 3, 0, false, false, false, false, true, gl::VertexAttribType::UnsignedByte }, + { FormatID::G8_B8_R8_3PLANE_420_UNORM, GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE, GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 3, 0, false, false, false, false, true, gl::VertexAttribType::UnsignedByte }, + { FormatID::L16A16_FLOAT, GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA16F_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 0, 0, 0, 16, 16, 0, 0, 4, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::Float }, + { FormatID::L16_FLOAT, GL_LUMINANCE16F_EXT, GL_LUMINANCE16F_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 0, 0, 0, 0, 16, 0, 0, 2, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::Float }, + { FormatID::L32A32_FLOAT, GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA32F_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 0, 0, 0, 32, 32, 0, 0, 8, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::Float }, + { FormatID::L32_FLOAT, GL_LUMINANCE32F_EXT, GL_LUMINANCE32F_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 0, 0, 0, 0, 32, 0, 0, 4, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::Float }, + { FormatID::L8A8_UNORM, GL_LUMINANCE8_ALPHA8_EXT, GL_LUMINANCE8_ALPHA8_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 8, 8, 0, 0, 2, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::L8_UNORM, GL_LUMINANCE8_EXT, GL_LUMINANCE8_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 8, 0, 0, 1, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::PALETTE4_R4G4B4A4_UNORM, GL_PALETTE4_RGBA4_OES, GL_PALETTE4_RGBA4_OES, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 4, 4, 4, 4, 0, 0, 0, 3, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::PALETTE4_R5G5B5A1_UNORM, GL_PALETTE4_RGB5_A1_OES, GL_PALETTE4_RGB5_A1_OES, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 5, 5, 5, 1, 0, 0, 0, 3, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::PALETTE4_R5G6B5_UNORM, GL_PALETTE4_R5_G6_B5_OES, GL_PALETTE4_R5_G6_B5_OES, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 5, 6, 5, 0, 0, 0, 0, 3, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::PALETTE4_R8G8B8A8_UNORM, GL_PALETTE4_RGBA8_OES, GL_PALETTE4_RGBA8_OES, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 0, 5, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::UnsignedByte }, + { FormatID::PALETTE4_R8G8B8_UNORM, GL_PALETTE4_RGB8_OES, GL_PALETTE4_RGB8_OES, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 4, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::UnsignedByte }, + { FormatID::PALETTE8_R4G4B4A4_UNORM, GL_PALETTE8_RGBA4_OES, GL_PALETTE8_RGBA4_OES, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 4, 4, 4, 4, 0, 0, 0, 3, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::PALETTE8_R5G5B5A1_UNORM, GL_PALETTE8_RGB5_A1_OES, GL_PALETTE8_RGB5_A1_OES, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 5, 5, 5, 1, 0, 0, 0, 3, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::PALETTE8_R5G6B5_UNORM, GL_PALETTE8_R5_G6_B5_OES, GL_PALETTE8_R5_G6_B5_OES, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 5, 6, 5, 0, 0, 0, 0, 3, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::PALETTE8_R8G8B8A8_UNORM, GL_PALETTE8_RGBA8_OES, GL_PALETTE8_RGBA8_OES, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 0, 5, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::UnsignedByte }, + { FormatID::PALETTE8_R8G8B8_UNORM, GL_PALETTE8_RGB8_OES, GL_PALETTE8_RGB8_OES, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 4, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::UnsignedByte }, + { FormatID::PVRTC1_RGBA_2BPP_UNORM_BLOCK, GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 8, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::PVRTC1_RGBA_2BPP_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT, GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 8, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::PVRTC1_RGBA_4BPP_UNORM_BLOCK, GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 8, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::PVRTC1_RGBA_4BPP_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT, GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 8, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::PVRTC1_RGB_2BPP_UNORM_BLOCK, GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG, GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 8, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::PVRTC1_RGB_2BPP_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT, GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 8, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::PVRTC1_RGB_4BPP_UNORM_BLOCK, GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 8, std::numeric_limits::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::PVRTC1_RGB_4BPP_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT, GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 8, std::numeric_limits::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::R10G10B10A2_SINT, GL_RGB10_A2_SINT_ANGLEX, GL_RGB10_A2_SINT_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 10, 10, 10, 2, 0, 0, 0, 4, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::Int2101010 }, + { FormatID::R10G10B10A2_SNORM, GL_RGB10_A2_SNORM_ANGLEX, GL_RGB10_A2_SNORM_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_SIGNED_NORMALIZED, 10, 10, 10, 2, 0, 0, 0, 4, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::Int2101010 }, + { FormatID::R10G10B10A2_SSCALED, GL_RGB10_A2_SSCALED_ANGLEX, GL_RGB10_A2_SSCALED_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 10, 10, 10, 2, 0, 0, 0, 4, std::numeric_limits::max(), false, false, true, false, false, gl::VertexAttribType::Int2101010 }, + { FormatID::R10G10B10A2_UINT, GL_RGB10_A2UI, GL_RGB10_A2UI, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 10, 10, 10, 2, 0, 0, 0, 4, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::UnsignedInt2101010 }, + { FormatID::R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 10, 10, 10, 2, 0, 0, 0, 4, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::UnsignedInt2101010 }, + { FormatID::R10G10B10A2_USCALED, GL_RGB10_A2_USCALED_ANGLEX, GL_RGB10_A2_USCALED_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 10, 10, 10, 2, 0, 0, 0, 4, std::numeric_limits::max(), false, false, true, false, false, gl::VertexAttribType::UnsignedInt2101010 }, + { FormatID::R10G10B10X2_UNORM, GL_RGB10_UNORM_ANGLEX, GL_RGB10_UNORM_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 10, 10, 10, 0, 0, 0, 0, 4, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::UnsignedInt2101010 }, + { FormatID::R11G11B10_FLOAT, GL_R11F_G11F_B10F, GL_R11F_G11F_B10F, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 11, 11, 10, 0, 0, 0, 0, 4, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::Float }, + { FormatID::R16G16B16A16_FLOAT, GL_RGBA16F, GL_RGBA16F, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 16, 16, 16, 16, 0, 0, 0, 8, 1, false, false, false, false, false, gl::VertexAttribType::HalfFloat }, + { FormatID::R16G16B16A16_SINT, GL_RGBA16I, GL_RGBA16I, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 16, 16, 16, 16, 0, 0, 0, 8, 1, false, false, false, false, false, gl::VertexAttribType::Short }, + { FormatID::R16G16B16A16_SNORM, GL_RGBA16_SNORM_EXT, GL_RGBA16_SNORM_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_SIGNED_NORMALIZED, 16, 16, 16, 16, 0, 0, 0, 8, 1, false, false, false, false, false, gl::VertexAttribType::Short }, + { FormatID::R16G16B16A16_SSCALED, GL_RGBA16_SSCALED_ANGLEX, GL_RGBA16_SSCALED_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 16, 16, 16, 16, 0, 0, 0, 8, 1, false, false, true, false, false, gl::VertexAttribType::Short }, + { FormatID::R16G16B16A16_UINT, GL_RGBA16UI, GL_RGBA16UI, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 16, 16, 16, 16, 0, 0, 0, 8, 1, false, false, false, false, false, gl::VertexAttribType::UnsignedShort }, + { FormatID::R16G16B16A16_UNORM, GL_RGBA16_EXT, GL_RGBA16_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 16, 16, 16, 16, 0, 0, 0, 8, 1, false, false, false, false, false, gl::VertexAttribType::UnsignedShort }, + { FormatID::R16G16B16A16_USCALED, GL_RGBA16_USCALED_ANGLEX, GL_RGBA16_USCALED_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 16, 16, 16, 16, 0, 0, 0, 8, 1, false, false, true, false, false, gl::VertexAttribType::UnsignedShort }, + { FormatID::R16G16B16_FLOAT, GL_RGB16F, GL_RGB16F, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 16, 16, 16, 0, 0, 0, 0, 6, 1, false, false, false, false, false, gl::VertexAttribType::HalfFloat }, + { FormatID::R16G16B16_SINT, GL_RGB16I, GL_RGB16I, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 16, 16, 16, 0, 0, 0, 0, 6, 1, false, false, false, false, false, gl::VertexAttribType::Short }, + { FormatID::R16G16B16_SNORM, GL_RGB16_SNORM_EXT, GL_RGB16_SNORM_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_SIGNED_NORMALIZED, 16, 16, 16, 0, 0, 0, 0, 6, 1, false, false, false, false, false, gl::VertexAttribType::Short }, + { FormatID::R16G16B16_SSCALED, GL_RGB16_SSCALED_ANGLEX, GL_RGB16_SSCALED_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 16, 16, 16, 0, 0, 0, 0, 6, 1, false, false, true, false, false, gl::VertexAttribType::Short }, + { FormatID::R16G16B16_UINT, GL_RGB16UI, GL_RGB16UI, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 16, 16, 16, 0, 0, 0, 0, 6, 1, false, false, false, false, false, gl::VertexAttribType::UnsignedShort }, + { FormatID::R16G16B16_UNORM, GL_RGB16_EXT, GL_RGB16_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 16, 16, 16, 0, 0, 0, 0, 6, 1, false, false, false, false, false, gl::VertexAttribType::UnsignedShort }, + { FormatID::R16G16B16_USCALED, GL_RGB16_USCALED_ANGLEX, GL_RGB16_USCALED_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 16, 16, 16, 0, 0, 0, 0, 6, 1, false, false, true, false, false, gl::VertexAttribType::UnsignedShort }, + { FormatID::R16G16_FLOAT, GL_RG16F, GL_RG16F, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 16, 16, 0, 0, 0, 0, 0, 4, 1, false, false, false, false, false, gl::VertexAttribType::HalfFloat }, + { FormatID::R16G16_SINT, GL_RG16I, GL_RG16I, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 16, 16, 0, 0, 0, 0, 0, 4, 1, false, false, false, false, false, gl::VertexAttribType::Short }, + { FormatID::R16G16_SNORM, GL_RG16_SNORM_EXT, GL_RG16_SNORM_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_SIGNED_NORMALIZED, 16, 16, 0, 0, 0, 0, 0, 4, 1, false, false, false, false, false, gl::VertexAttribType::Short }, + { FormatID::R16G16_SSCALED, GL_RG16_SSCALED_ANGLEX, GL_RG16_SSCALED_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 16, 16, 0, 0, 0, 0, 0, 4, 1, false, false, true, false, false, gl::VertexAttribType::Short }, + { FormatID::R16G16_UINT, GL_RG16UI, GL_RG16UI, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 16, 16, 0, 0, 0, 0, 0, 4, 1, false, false, false, false, false, gl::VertexAttribType::UnsignedShort }, + { FormatID::R16G16_UNORM, GL_RG16_EXT, GL_RG16_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 16, 16, 0, 0, 0, 0, 0, 4, 1, false, false, false, false, false, gl::VertexAttribType::UnsignedShort }, + { FormatID::R16G16_USCALED, GL_RG16_USCALED_ANGLEX, GL_RG16_USCALED_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 16, 16, 0, 0, 0, 0, 0, 4, 1, false, false, true, false, false, gl::VertexAttribType::UnsignedShort }, + { FormatID::R16_FLOAT, GL_R16F, GL_R16F, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 16, 0, 0, 0, 0, 0, 0, 2, 1, false, false, false, false, false, gl::VertexAttribType::HalfFloat }, + { FormatID::R16_SINT, GL_R16I, GL_R16I, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 16, 0, 0, 0, 0, 0, 0, 2, 1, false, false, false, false, false, gl::VertexAttribType::Short }, + { FormatID::R16_SNORM, GL_R16_SNORM_EXT, GL_R16_SNORM_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_SIGNED_NORMALIZED, 16, 0, 0, 0, 0, 0, 0, 2, 1, false, false, false, false, false, gl::VertexAttribType::Short }, + { FormatID::R16_SSCALED, GL_R16_SSCALED_ANGLEX, GL_R16_SSCALED_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 16, 0, 0, 0, 0, 0, 0, 2, 1, false, false, true, false, false, gl::VertexAttribType::Short }, + { FormatID::R16_UINT, GL_R16UI, GL_R16UI, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 16, 0, 0, 0, 0, 0, 0, 2, 1, false, false, false, false, false, gl::VertexAttribType::UnsignedShort }, + { FormatID::R16_UNORM, GL_R16_EXT, GL_R16_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 16, 0, 0, 0, 0, 0, 0, 2, 1, false, false, false, false, false, gl::VertexAttribType::UnsignedShort }, + { FormatID::R16_USCALED, GL_R16_USCALED_ANGLEX, GL_R16_USCALED_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 16, 0, 0, 0, 0, 0, 0, 2, 1, false, false, true, false, false, gl::VertexAttribType::UnsignedShort }, + { FormatID::R32G32B32A32_FIXED, GL_RGBA32_FIXED_ANGLEX, GL_RGBA32_FIXED_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 32, 32, 32, 32, 0, 0, 0, 16, 3, false, true, false, false, false, gl::VertexAttribType::Fixed }, + { FormatID::R32G32B32A32_FLOAT, GL_RGBA32F, GL_RGBA32F, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 32, 32, 32, 32, 0, 0, 0, 16, 3, false, false, false, false, false, gl::VertexAttribType::Float }, + { FormatID::R32G32B32A32_SINT, GL_RGBA32I, GL_RGBA32I, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 32, 32, 32, 32, 0, 0, 0, 16, 3, false, false, false, false, false, gl::VertexAttribType::Int }, + { FormatID::R32G32B32A32_SNORM, GL_RGBA32_SNORM_ANGLEX, GL_RGBA32_SNORM_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_SIGNED_NORMALIZED, 32, 32, 32, 32, 0, 0, 0, 16, 3, false, false, false, false, false, gl::VertexAttribType::Int }, + { FormatID::R32G32B32A32_SSCALED, GL_RGBA32_SSCALED_ANGLEX, GL_RGBA32_SSCALED_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 32, 32, 32, 32, 0, 0, 0, 16, 3, false, false, true, false, false, gl::VertexAttribType::Int }, + { FormatID::R32G32B32A32_UINT, GL_RGBA32UI, GL_RGBA32UI, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 32, 32, 32, 32, 0, 0, 0, 16, 3, false, false, false, false, false, gl::VertexAttribType::UnsignedInt }, + { FormatID::R32G32B32A32_UNORM, GL_RGBA32_UNORM_ANGLEX, GL_RGBA32_UNORM_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 32, 32, 32, 32, 0, 0, 0, 16, 3, false, false, false, false, false, gl::VertexAttribType::UnsignedInt }, + { FormatID::R32G32B32A32_USCALED, GL_RGBA32_USCALED_ANGLEX, GL_RGBA32_USCALED_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 32, 32, 32, 32, 0, 0, 0, 16, 3, false, false, true, false, false, gl::VertexAttribType::UnsignedInt }, + { FormatID::R32G32B32_FIXED, GL_RGB32_FIXED_ANGLEX, GL_RGB32_FIXED_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 32, 32, 32, 0, 0, 0, 0, 12, 3, false, true, false, false, false, gl::VertexAttribType::Fixed }, + { FormatID::R32G32B32_FLOAT, GL_RGB32F, GL_RGB32F, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 32, 32, 32, 0, 0, 0, 0, 12, 3, false, false, false, false, false, gl::VertexAttribType::Float }, + { FormatID::R32G32B32_SINT, GL_RGB32I, GL_RGB32I, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 32, 32, 32, 0, 0, 0, 0, 12, 3, false, false, false, false, false, gl::VertexAttribType::Int }, + { FormatID::R32G32B32_SNORM, GL_RGB32_SNORM_ANGLEX, GL_RGB32_SNORM_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_SIGNED_NORMALIZED, 32, 32, 32, 0, 0, 0, 0, 12, 3, false, false, false, false, false, gl::VertexAttribType::Int }, + { FormatID::R32G32B32_SSCALED, GL_RGB32_SSCALED_ANGLEX, GL_RGB32_SSCALED_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 32, 32, 32, 0, 0, 0, 0, 12, 3, false, false, true, false, false, gl::VertexAttribType::Int }, + { FormatID::R32G32B32_UINT, GL_RGB32UI, GL_RGB32UI, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 32, 32, 32, 0, 0, 0, 0, 12, 3, false, false, false, false, false, gl::VertexAttribType::UnsignedInt }, + { FormatID::R32G32B32_UNORM, GL_RGB32_UNORM_ANGLEX, GL_RGB32_UNORM_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 32, 32, 32, 0, 0, 0, 0, 12, 3, false, false, false, false, false, gl::VertexAttribType::UnsignedInt }, + { FormatID::R32G32B32_USCALED, GL_RGB32_USCALED_ANGLEX, GL_RGB32_USCALED_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 32, 32, 32, 0, 0, 0, 0, 12, 3, false, false, true, false, false, gl::VertexAttribType::UnsignedInt }, + { FormatID::R32G32_FIXED, GL_RG32_FIXED_ANGLEX, GL_RG32_FIXED_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 32, 32, 0, 0, 0, 0, 0, 8, 3, false, true, false, false, false, gl::VertexAttribType::Fixed }, + { FormatID::R32G32_FLOAT, GL_RG32F, GL_RG32F, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 32, 32, 0, 0, 0, 0, 0, 8, 3, false, false, false, false, false, gl::VertexAttribType::Float }, + { FormatID::R32G32_SINT, GL_RG32I, GL_RG32I, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 32, 32, 0, 0, 0, 0, 0, 8, 3, false, false, false, false, false, gl::VertexAttribType::Int }, + { FormatID::R32G32_SNORM, GL_RG32_SNORM_ANGLEX, GL_RG32_SNORM_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_SIGNED_NORMALIZED, 32, 32, 0, 0, 0, 0, 0, 8, 3, false, false, false, false, false, gl::VertexAttribType::Int }, + { FormatID::R32G32_SSCALED, GL_RG32_SSCALED_ANGLEX, GL_RG32_SSCALED_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 32, 32, 0, 0, 0, 0, 0, 8, 3, false, false, true, false, false, gl::VertexAttribType::Int }, + { FormatID::R32G32_UINT, GL_RG32UI, GL_RG32UI, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 32, 32, 0, 0, 0, 0, 0, 8, 3, false, false, false, false, false, gl::VertexAttribType::UnsignedInt }, + { FormatID::R32G32_UNORM, GL_RG32_UNORM_ANGLEX, GL_RG32_UNORM_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 32, 32, 0, 0, 0, 0, 0, 8, 3, false, false, false, false, false, gl::VertexAttribType::UnsignedInt }, + { FormatID::R32G32_USCALED, GL_RG32_USCALED_ANGLEX, GL_RG32_USCALED_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 32, 32, 0, 0, 0, 0, 0, 8, 3, false, false, true, false, false, gl::VertexAttribType::UnsignedInt }, + { FormatID::R32_FIXED, GL_R32_FIXED_ANGLEX, GL_R32_FIXED_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 32, 0, 0, 0, 0, 0, 0, 4, 3, false, true, false, false, false, gl::VertexAttribType::Fixed }, + { FormatID::R32_FLOAT, GL_R32F, GL_R32F, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 32, 0, 0, 0, 0, 0, 0, 4, 3, false, false, false, false, false, gl::VertexAttribType::Float }, + { FormatID::R32_SINT, GL_R32I, GL_R32I, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 32, 0, 0, 0, 0, 0, 0, 4, 3, false, false, false, false, false, gl::VertexAttribType::Int }, + { FormatID::R32_SNORM, GL_R32_SNORM_ANGLEX, GL_R32_SNORM_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_SIGNED_NORMALIZED, 32, 0, 0, 0, 0, 0, 0, 4, 3, false, false, false, false, false, gl::VertexAttribType::Int }, + { FormatID::R32_SSCALED, GL_R32_SSCALED_ANGLEX, GL_R32_SSCALED_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 32, 0, 0, 0, 0, 0, 0, 4, 3, false, false, true, false, false, gl::VertexAttribType::Int }, + { FormatID::R32_UINT, GL_R32UI, GL_R32UI, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 32, 0, 0, 0, 0, 0, 0, 4, 3, false, false, false, false, false, gl::VertexAttribType::UnsignedInt }, + { FormatID::R32_UNORM, GL_R32_UNORM_ANGLEX, GL_R32_UNORM_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 32, 0, 0, 0, 0, 0, 0, 4, 3, false, false, false, false, false, gl::VertexAttribType::UnsignedInt }, + { FormatID::R32_USCALED, GL_R32_USCALED_ANGLEX, GL_R32_USCALED_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 32, 0, 0, 0, 0, 0, 0, 4, 3, false, false, true, false, false, gl::VertexAttribType::UnsignedInt }, + { FormatID::R4G4B4A4_UNORM, GL_RGBA4, GL_RGBA4, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 4, 4, 4, 4, 0, 0, 0, 2, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::R5G5B5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 5, 5, 5, 1, 0, 0, 0, 2, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::R5G6B5_UNORM, GL_RGB565, GL_RGB565, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 5, 6, 5, 0, 0, 0, 0, 2, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::R8G8B8A8_SINT, GL_RGBA8I, GL_RGBA8I, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 8, 8, 8, 8, 0, 0, 0, 4, 0, false, false, false, false, false, gl::VertexAttribType::Byte }, + { FormatID::R8G8B8A8_SNORM, GL_RGBA8_SNORM, GL_RGBA8_SNORM, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_SIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 0, 4, 0, false, false, false, false, false, gl::VertexAttribType::Byte }, + { FormatID::R8G8B8A8_SSCALED, GL_RGBA8_SSCALED_ANGLEX, GL_RGBA8_SSCALED_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 8, 8, 8, 8, 0, 0, 0, 4, 0, false, false, true, false, false, gl::VertexAttribType::Byte }, + { FormatID::R8G8B8A8_TYPELESS, GL_RGBA8, GL_RGBA8, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 0, 4, 0, false, false, false, false, false, gl::VertexAttribType::UnsignedByte }, + { FormatID::R8G8B8A8_TYPELESS_SRGB, GL_SRGB8_ALPHA8, GL_SRGB8_ALPHA8, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 0, 4, 0, false, false, false, true, false, gl::VertexAttribType::Byte }, + { FormatID::R8G8B8A8_UINT, GL_RGBA8UI, GL_RGBA8UI, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 8, 8, 8, 8, 0, 0, 0, 4, 0, false, false, false, false, false, gl::VertexAttribType::UnsignedByte }, + { FormatID::R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 0, 4, 0, false, false, false, false, false, gl::VertexAttribType::UnsignedByte }, + { FormatID::R8G8B8A8_UNORM_SRGB, GL_SRGB8_ALPHA8, GL_SRGB8_ALPHA8, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 0, 4, 0, false, false, false, true, false, gl::VertexAttribType::Byte }, + { FormatID::R8G8B8A8_USCALED, GL_RGBA8_USCALED_ANGLEX, GL_RGBA8_USCALED_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 8, 8, 8, 8, 0, 0, 0, 4, 0, false, false, true, false, false, gl::VertexAttribType::UnsignedByte }, + { FormatID::R8G8B8X8_UNORM, GL_RGBA8, GL_RGBA8, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 4, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::UnsignedByte }, + { FormatID::R8G8B8_SINT, GL_RGB8I, GL_RGB8I, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 8, 8, 8, 0, 0, 0, 0, 3, 0, false, false, false, false, false, gl::VertexAttribType::Byte }, + { FormatID::R8G8B8_SNORM, GL_RGB8_SNORM, GL_RGB8_SNORM, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_SIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 3, 0, false, false, false, false, false, gl::VertexAttribType::Byte }, + { FormatID::R8G8B8_SSCALED, GL_RGB8_SSCALED_ANGLEX, GL_RGB8_SSCALED_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 8, 8, 8, 0, 0, 0, 0, 3, 0, false, false, true, false, false, gl::VertexAttribType::Byte }, + { FormatID::R8G8B8_UINT, GL_RGB8UI, GL_RGB8UI, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 8, 8, 8, 0, 0, 0, 0, 3, 0, false, false, false, false, false, gl::VertexAttribType::UnsignedByte }, + { FormatID::R8G8B8_UNORM, GL_RGB8, GL_RGB8, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 3, 0, false, false, false, false, false, gl::VertexAttribType::UnsignedByte }, + { FormatID::R8G8B8_UNORM_SRGB, GL_SRGB8, GL_SRGB8, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 3, 0, false, false, false, true, false, gl::VertexAttribType::Byte }, + { FormatID::R8G8B8_USCALED, GL_RGB8_USCALED_ANGLEX, GL_RGB8_USCALED_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 8, 8, 8, 0, 0, 0, 0, 3, 0, false, false, true, false, false, gl::VertexAttribType::UnsignedByte }, + { FormatID::R8G8_SINT, GL_RG8I, GL_RG8I, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 8, 8, 0, 0, 0, 0, 0, 2, 0, false, false, false, false, false, gl::VertexAttribType::Byte }, + { FormatID::R8G8_SNORM, GL_RG8_SNORM, GL_RG8_SNORM, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_SIGNED_NORMALIZED, 8, 8, 0, 0, 0, 0, 0, 2, 0, false, false, false, false, false, gl::VertexAttribType::Byte }, + { FormatID::R8G8_SSCALED, GL_RG8_SSCALED_ANGLEX, GL_RG8_SSCALED_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 8, 8, 0, 0, 0, 0, 0, 2, 0, false, false, true, false, false, gl::VertexAttribType::Byte }, + { FormatID::R8G8_UINT, GL_RG8UI, GL_RG8UI, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 8, 8, 0, 0, 0, 0, 0, 2, 0, false, false, false, false, false, gl::VertexAttribType::UnsignedByte }, + { FormatID::R8G8_UNORM, GL_RG8, GL_RG8, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 8, 8, 0, 0, 0, 0, 0, 2, 0, false, false, false, false, false, gl::VertexAttribType::UnsignedByte }, + { FormatID::R8G8_UNORM_SRGB, GL_SRG8_EXT, GL_SRG8_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 8, 8, 0, 0, 0, 0, 0, 2, 0, false, false, false, true, false, gl::VertexAttribType::Byte }, + { FormatID::R8G8_USCALED, GL_RG8_USCALED_ANGLEX, GL_RG8_USCALED_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 8, 8, 0, 0, 0, 0, 0, 2, 0, false, false, true, false, false, gl::VertexAttribType::UnsignedByte }, + { FormatID::R8_SINT, GL_R8I, GL_R8I, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 8, 0, 0, 0, 0, 0, 0, 1, 0, false, false, false, false, false, gl::VertexAttribType::Byte }, + { FormatID::R8_SNORM, GL_R8_SNORM, GL_R8_SNORM, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_SIGNED_NORMALIZED, 8, 0, 0, 0, 0, 0, 0, 1, 0, false, false, false, false, false, gl::VertexAttribType::Byte }, + { FormatID::R8_SSCALED, GL_R8_SSCALED_ANGLEX, GL_R8_SSCALED_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 8, 0, 0, 0, 0, 0, 0, 1, 0, false, false, true, false, false, gl::VertexAttribType::Byte }, + { FormatID::R8_UINT, GL_R8UI, GL_R8UI, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 8, 0, 0, 0, 0, 0, 0, 1, 0, false, false, false, false, false, gl::VertexAttribType::UnsignedByte }, + { FormatID::R8_UNORM, GL_R8, GL_R8, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 8, 0, 0, 0, 0, 0, 0, 1, 0, false, false, false, false, false, gl::VertexAttribType::UnsignedByte }, + { FormatID::R8_UNORM_SRGB, GL_SR8_EXT, GL_SR8_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 8, 0, 0, 0, 0, 0, 0, 1, 0, false, false, false, true, false, gl::VertexAttribType::Byte }, + { FormatID::R8_USCALED, GL_R8_USCALED_ANGLEX, GL_R8_USCALED_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 8, 0, 0, 0, 0, 0, 0, 1, 0, false, false, true, false, false, gl::VertexAttribType::UnsignedByte }, + { FormatID::R9G9B9E5_SHAREDEXP, GL_RGB9_E5, GL_RGB9_E5, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 9, 9, 9, 0, 0, 0, 0, 4, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum }, + { FormatID::X2R10G10B10_SINT_VERTEX, GL_X2_RGB10_SINT_ANGLEX, GL_X2_RGB10_SINT_ANGLEX, nullptr, NoCopyFunctions, nullptr, nullptr, GL_INT, 10, 10, 10, 0, 0, 0, 0, 4, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::Int1010102 }, + { FormatID::X2R10G10B10_SNORM_VERTEX, GL_X2_RGB10_SNORM_ANGLEX, GL_X2_RGB10_SNORM_ANGLEX, nullptr, NoCopyFunctions, nullptr, nullptr, GL_SIGNED_NORMALIZED, 10, 10, 10, 0, 0, 0, 0, 4, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::Int1010102 }, + { FormatID::X2R10G10B10_SSCALED_VERTEX, GL_X2_RGB10_SSCALED_ANGLEX, GL_X2_RGB10_SSCALED_ANGLEX, nullptr, NoCopyFunctions, nullptr, nullptr, GL_INT, 10, 10, 10, 0, 0, 0, 0, 4, std::numeric_limits::max(), false, false, true, false, false, gl::VertexAttribType::Int1010102 }, + { FormatID::X2R10G10B10_UINT_VERTEX, GL_X2_RGB10_UINT_ANGLEX, GL_X2_RGB10_UINT_ANGLEX, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_INT, 10, 10, 10, 0, 0, 0, 0, 4, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::UnsignedInt1010102 }, + { FormatID::X2R10G10B10_UNORM_VERTEX, GL_X2_RGB10_UNORM_ANGLEX, GL_X2_RGB10_UNORM_ANGLEX, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 10, 10, 10, 0, 0, 0, 0, 4, std::numeric_limits::max(), false, false, false, false, false, gl::VertexAttribType::UnsignedInt1010102 }, + { FormatID::X2R10G10B10_USCALED_VERTEX, GL_X2_RGB10_USCALED_ANGLEX, GL_X2_RGB10_USCALED_ANGLEX, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_INT, 10, 10, 10, 0, 0, 0, 0, 4, std::numeric_limits::max(), false, false, true, false, false, gl::VertexAttribType::UnsignedInt1010102 }, + // clang-format on +}; + +// static +FormatID Format::InternalFormatToID(GLenum internalFormat) +{ + switch (internalFormat) + { + case GL_A1RGB5_ANGLEX: + return FormatID::A1R5G5B5_UNORM; + case GL_A2_RGB10_SNORM_ANGLEX: + return FormatID::A2R10G10B10_SNORM_VERTEX; + case GL_A2_RGB10_SSCALED_ANGLEX: + return FormatID::A2R10G10B10_SSCALED_VERTEX; + case GL_A2_RGB10_UNORM_ANGLEX: + return FormatID::A2R10G10B10_UNORM_VERTEX; + case GL_A2_RGB10_USCALED_ANGLEX: + return FormatID::A2R10G10B10_USCALED_VERTEX; + case GL_ALPHA16F_EXT: + return FormatID::A16_FLOAT; + case GL_ALPHA32F_EXT: + return FormatID::A32_FLOAT; + case GL_ALPHA8_EXT: + return FormatID::A8_UNORM; + case GL_BGR10_A2_ANGLEX: + return FormatID::B10G10R10A2_UNORM; + case GL_BGR565_ANGLEX: + return FormatID::B5G6R5_UNORM; + case GL_BGR5_A1_ANGLEX: + return FormatID::B5G5R5A1_UNORM; + case GL_BGRA4_ANGLEX: + return FormatID::B4G4R4A4_UNORM; + case GL_BGRA8_EXT: + return FormatID::B8G8R8A8_UNORM; + case GL_BGRA8_SRGB_ANGLEX: + return FormatID::B8G8R8A8_UNORM_SRGB; + case GL_BGRA8_TYPELESS_ANGLEX: + return FormatID::B8G8R8A8_TYPELESS; + case GL_BGRA8_TYPELESS_SRGB_ANGLEX: + return FormatID::B8G8R8A8_TYPELESS_SRGB; + case GL_BGRX8_ANGLEX: + return FormatID::B8G8R8X8_UNORM; + case GL_COMPRESSED_R11_EAC: + return FormatID::EAC_R11_UNORM_BLOCK; + case GL_COMPRESSED_RED_GREEN_RGTC2_EXT: + return FormatID::BC5_RG_UNORM_BLOCK; + case GL_COMPRESSED_RED_RGTC1_EXT: + return FormatID::BC4_RED_UNORM_BLOCK; + case GL_COMPRESSED_RG11_EAC: + return FormatID::EAC_R11G11_UNORM_BLOCK; + case GL_COMPRESSED_RGB8_ETC2: + return FormatID::ETC2_R8G8B8_UNORM_BLOCK; + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + return FormatID::ETC2_R8G8B8A1_UNORM_BLOCK; + case GL_COMPRESSED_RGBA8_ETC2_EAC: + return FormatID::ETC2_R8G8B8A8_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_ASTC_10x10_KHR: + return FormatID::ASTC_10x10_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_ASTC_10x5_KHR: + return FormatID::ASTC_10x5_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_ASTC_10x6_KHR: + return FormatID::ASTC_10x6_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_ASTC_10x8_KHR: + return FormatID::ASTC_10x8_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_ASTC_12x10_KHR: + return FormatID::ASTC_12x10_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_ASTC_12x12_KHR: + return FormatID::ASTC_12x12_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_ASTC_3x3x3_OES: + return FormatID::ASTC_3x3x3_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_ASTC_4x3x3_OES: + return FormatID::ASTC_4x3x3_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_ASTC_4x4_KHR: + return FormatID::ASTC_4x4_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_ASTC_4x4x3_OES: + return FormatID::ASTC_4x4x3_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_ASTC_4x4x4_OES: + return FormatID::ASTC_4x4x4_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_ASTC_5x4_KHR: + return FormatID::ASTC_5x4_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_ASTC_5x4x4_OES: + return FormatID::ASTC_5x4x4_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_ASTC_5x5_KHR: + return FormatID::ASTC_5x5_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_ASTC_5x5x4_OES: + return FormatID::ASTC_5x5x4_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_ASTC_5x5x5_OES: + return FormatID::ASTC_5x5x5_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_ASTC_6x5_KHR: + return FormatID::ASTC_6x5_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_ASTC_6x5x5_OES: + return FormatID::ASTC_6x5x5_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_ASTC_6x6_KHR: + return FormatID::ASTC_6x6_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_ASTC_6x6x5_OES: + return FormatID::ASTC_6x6x5_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_ASTC_6x6x6_OES: + return FormatID::ASTC_6x6x6_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_ASTC_8x5_KHR: + return FormatID::ASTC_8x5_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_ASTC_8x6_KHR: + return FormatID::ASTC_8x6_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_ASTC_8x8_KHR: + return FormatID::ASTC_8x8_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT: + return FormatID::BC7_RGBA_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: + return FormatID::PVRTC1_RGBA_2BPP_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: + return FormatID::PVRTC1_RGBA_4BPP_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + return FormatID::BC1_RGBA_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + return FormatID::BC2_RGBA_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + return FormatID::BC3_RGBA_UNORM_BLOCK; + case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT: + return FormatID::BC6H_RGB_SFLOAT_BLOCK; + case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT: + return FormatID::BC6H_RGB_UFLOAT_BLOCK; + case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG: + return FormatID::PVRTC1_RGB_2BPP_UNORM_BLOCK; + case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG: + return FormatID::PVRTC1_RGB_4BPP_UNORM_BLOCK; + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + return FormatID::BC1_RGB_UNORM_BLOCK; + case GL_COMPRESSED_SIGNED_R11_EAC: + return FormatID::EAC_R11_SNORM_BLOCK; + case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT: + return FormatID::BC5_RG_SNORM_BLOCK; + case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT: + return FormatID::BC4_RED_SNORM_BLOCK; + case GL_COMPRESSED_SIGNED_RG11_EAC: + return FormatID::EAC_R11G11_SNORM_BLOCK; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: + return FormatID::ASTC_10x10_SRGB_BLOCK; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: + return FormatID::ASTC_10x5_SRGB_BLOCK; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: + return FormatID::ASTC_10x6_SRGB_BLOCK; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: + return FormatID::ASTC_10x8_SRGB_BLOCK; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: + return FormatID::ASTC_12x10_SRGB_BLOCK; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: + return FormatID::ASTC_12x12_SRGB_BLOCK; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES: + return FormatID::ASTC_3x3x3_UNORM_SRGB_BLOCK; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES: + return FormatID::ASTC_4x3x3_UNORM_SRGB_BLOCK; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: + return FormatID::ASTC_4x4_SRGB_BLOCK; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES: + return FormatID::ASTC_4x4x3_UNORM_SRGB_BLOCK; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES: + return FormatID::ASTC_4x4x4_UNORM_SRGB_BLOCK; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: + return FormatID::ASTC_5x4_SRGB_BLOCK; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES: + return FormatID::ASTC_5x4x4_UNORM_SRGB_BLOCK; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: + return FormatID::ASTC_5x5_SRGB_BLOCK; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES: + return FormatID::ASTC_5x5x4_UNORM_SRGB_BLOCK; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES: + return FormatID::ASTC_5x5x5_UNORM_SRGB_BLOCK; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: + return FormatID::ASTC_6x5_SRGB_BLOCK; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES: + return FormatID::ASTC_6x5x5_UNORM_SRGB_BLOCK; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: + return FormatID::ASTC_6x6_SRGB_BLOCK; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES: + return FormatID::ASTC_6x6x5_UNORM_SRGB_BLOCK; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES: + return FormatID::ASTC_6x6x6_UNORM_SRGB_BLOCK; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: + return FormatID::ASTC_8x5_SRGB_BLOCK; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: + return FormatID::ASTC_8x6_SRGB_BLOCK; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: + return FormatID::ASTC_8x8_SRGB_BLOCK; + case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: + return FormatID::ETC2_R8G8B8A8_SRGB_BLOCK; + case GL_COMPRESSED_SRGB8_ETC2: + return FormatID::ETC2_R8G8B8_SRGB_BLOCK; + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + return FormatID::ETC2_R8G8B8A1_SRGB_BLOCK; + case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT: + return FormatID::BC7_RGBA_UNORM_SRGB_BLOCK; + case GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT: + return FormatID::PVRTC1_RGBA_2BPP_UNORM_SRGB_BLOCK; + case GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT: + return FormatID::PVRTC1_RGBA_4BPP_UNORM_SRGB_BLOCK; + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + return FormatID::BC1_RGBA_UNORM_SRGB_BLOCK; + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + return FormatID::BC2_RGBA_UNORM_SRGB_BLOCK; + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + return FormatID::BC3_RGBA_UNORM_SRGB_BLOCK; + case GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT: + return FormatID::PVRTC1_RGB_2BPP_UNORM_SRGB_BLOCK; + case GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT: + return FormatID::PVRTC1_RGB_4BPP_UNORM_SRGB_BLOCK; + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + return FormatID::BC1_RGB_UNORM_SRGB_BLOCK; + case GL_DEPTH24_STENCIL8: + return FormatID::D24_UNORM_S8_UINT; + case GL_DEPTH32F_STENCIL8: + return FormatID::D32_FLOAT_S8X24_UINT; + case GL_DEPTH_COMPONENT16: + return FormatID::D16_UNORM; + case GL_DEPTH_COMPONENT24: + return FormatID::D24_UNORM_X8_UINT; + case GL_DEPTH_COMPONENT32F: + return FormatID::D32_FLOAT; + case GL_DEPTH_COMPONENT32_OES: + return FormatID::D32_UNORM; + case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE: + return FormatID::ETC1_LOSSY_DECODE_R8G8B8_UNORM_BLOCK; + case GL_ETC1_RGB8_OES: + return FormatID::ETC1_R8G8B8_UNORM_BLOCK; + case GL_G8_B8R8_2PLANE_420_UNORM_ANGLE: + return FormatID::G8_B8R8_2PLANE_420_UNORM; + case GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE: + return FormatID::G8_B8_R8_3PLANE_420_UNORM; + case GL_INT_10_10_10_2_OES: + return FormatID::A2R10G10B10_SINT_VERTEX; + case GL_LUMINANCE16F_EXT: + return FormatID::L16_FLOAT; + case GL_LUMINANCE32F_EXT: + return FormatID::L32_FLOAT; + case GL_LUMINANCE8_ALPHA8_EXT: + return FormatID::L8A8_UNORM; + case GL_LUMINANCE8_EXT: + return FormatID::L8_UNORM; + case GL_LUMINANCE_ALPHA16F_EXT: + return FormatID::L16A16_FLOAT; + case GL_LUMINANCE_ALPHA32F_EXT: + return FormatID::L32A32_FLOAT; + case GL_NONE: + return FormatID::NONE; + case GL_PALETTE4_R5_G6_B5_OES: + return FormatID::PALETTE4_R5G6B5_UNORM; + case GL_PALETTE4_RGB5_A1_OES: + return FormatID::PALETTE4_R5G5B5A1_UNORM; + case GL_PALETTE4_RGB8_OES: + return FormatID::PALETTE4_R8G8B8_UNORM; + case GL_PALETTE4_RGBA4_OES: + return FormatID::PALETTE4_R4G4B4A4_UNORM; + case GL_PALETTE4_RGBA8_OES: + return FormatID::PALETTE4_R8G8B8A8_UNORM; + case GL_PALETTE8_R5_G6_B5_OES: + return FormatID::PALETTE8_R5G6B5_UNORM; + case GL_PALETTE8_RGB5_A1_OES: + return FormatID::PALETTE8_R5G5B5A1_UNORM; + case GL_PALETTE8_RGB8_OES: + return FormatID::PALETTE8_R8G8B8_UNORM; + case GL_PALETTE8_RGBA4_OES: + return FormatID::PALETTE8_R4G4B4A4_UNORM; + case GL_PALETTE8_RGBA8_OES: + return FormatID::PALETTE8_R8G8B8A8_UNORM; + case GL_R11F_G11F_B10F: + return FormatID::R11G11B10_FLOAT; + case GL_R16F: + return FormatID::R16_FLOAT; + case GL_R16I: + return FormatID::R16_SINT; + case GL_R16UI: + return FormatID::R16_UINT; + case GL_R16_EXT: + return FormatID::R16_UNORM; + case GL_R16_SNORM_EXT: + return FormatID::R16_SNORM; + case GL_R16_SSCALED_ANGLEX: + return FormatID::R16_SSCALED; + case GL_R16_USCALED_ANGLEX: + return FormatID::R16_USCALED; + case GL_R32F: + return FormatID::R32_FLOAT; + case GL_R32I: + return FormatID::R32_SINT; + case GL_R32UI: + return FormatID::R32_UINT; + case GL_R32_FIXED_ANGLEX: + return FormatID::R32_FIXED; + case GL_R32_SNORM_ANGLEX: + return FormatID::R32_SNORM; + case GL_R32_SSCALED_ANGLEX: + return FormatID::R32_SSCALED; + case GL_R32_UNORM_ANGLEX: + return FormatID::R32_UNORM; + case GL_R32_USCALED_ANGLEX: + return FormatID::R32_USCALED; + case GL_R8: + return FormatID::R8_UNORM; + case GL_R8I: + return FormatID::R8_SINT; + case GL_R8UI: + return FormatID::R8_UINT; + case GL_R8_SNORM: + return FormatID::R8_SNORM; + case GL_R8_SSCALED_ANGLEX: + return FormatID::R8_SSCALED; + case GL_R8_USCALED_ANGLEX: + return FormatID::R8_USCALED; + case GL_RG16F: + return FormatID::R16G16_FLOAT; + case GL_RG16I: + return FormatID::R16G16_SINT; + case GL_RG16UI: + return FormatID::R16G16_UINT; + case GL_RG16_EXT: + return FormatID::R16G16_UNORM; + case GL_RG16_SNORM_EXT: + return FormatID::R16G16_SNORM; + case GL_RG16_SSCALED_ANGLEX: + return FormatID::R16G16_SSCALED; + case GL_RG16_USCALED_ANGLEX: + return FormatID::R16G16_USCALED; + case GL_RG32F: + return FormatID::R32G32_FLOAT; + case GL_RG32I: + return FormatID::R32G32_SINT; + case GL_RG32UI: + return FormatID::R32G32_UINT; + case GL_RG32_FIXED_ANGLEX: + return FormatID::R32G32_FIXED; + case GL_RG32_SNORM_ANGLEX: + return FormatID::R32G32_SNORM; + case GL_RG32_SSCALED_ANGLEX: + return FormatID::R32G32_SSCALED; + case GL_RG32_UNORM_ANGLEX: + return FormatID::R32G32_UNORM; + case GL_RG32_USCALED_ANGLEX: + return FormatID::R32G32_USCALED; + case GL_RG8: + return FormatID::R8G8_UNORM; + case GL_RG8I: + return FormatID::R8G8_SINT; + case GL_RG8UI: + return FormatID::R8G8_UINT; + case GL_RG8_SNORM: + return FormatID::R8G8_SNORM; + case GL_RG8_SSCALED_ANGLEX: + return FormatID::R8G8_SSCALED; + case GL_RG8_USCALED_ANGLEX: + return FormatID::R8G8_USCALED; + case GL_RGB: + return FormatID::R8G8B8_UNORM; + case GL_RGB10_A2: + return FormatID::R10G10B10A2_UNORM; + case GL_RGB10_A2UI: + return FormatID::R10G10B10A2_UINT; + case GL_RGB10_A2_SINT_ANGLEX: + return FormatID::R10G10B10A2_SINT; + case GL_RGB10_A2_SNORM_ANGLEX: + return FormatID::R10G10B10A2_SNORM; + case GL_RGB10_A2_SSCALED_ANGLEX: + return FormatID::R10G10B10A2_SSCALED; + case GL_RGB10_A2_USCALED_ANGLEX: + return FormatID::R10G10B10A2_USCALED; + case GL_RGB10_UNORM_ANGLEX: + return FormatID::R10G10B10X2_UNORM; + case GL_RGB16F: + return FormatID::R16G16B16_FLOAT; + case GL_RGB16I: + return FormatID::R16G16B16_SINT; + case GL_RGB16UI: + return FormatID::R16G16B16_UINT; + case GL_RGB16_EXT: + return FormatID::R16G16B16_UNORM; + case GL_RGB16_SNORM_EXT: + return FormatID::R16G16B16_SNORM; + case GL_RGB16_SSCALED_ANGLEX: + return FormatID::R16G16B16_SSCALED; + case GL_RGB16_USCALED_ANGLEX: + return FormatID::R16G16B16_USCALED; + case GL_RGB32F: + return FormatID::R32G32B32_FLOAT; + case GL_RGB32I: + return FormatID::R32G32B32_SINT; + case GL_RGB32UI: + return FormatID::R32G32B32_UINT; + case GL_RGB32_FIXED_ANGLEX: + return FormatID::R32G32B32_FIXED; + case GL_RGB32_SNORM_ANGLEX: + return FormatID::R32G32B32_SNORM; + case GL_RGB32_SSCALED_ANGLEX: + return FormatID::R32G32B32_SSCALED; + case GL_RGB32_UNORM_ANGLEX: + return FormatID::R32G32B32_UNORM; + case GL_RGB32_USCALED_ANGLEX: + return FormatID::R32G32B32_USCALED; + case GL_RGB565: + return FormatID::R5G6B5_UNORM; + case GL_RGB5_A1: + return FormatID::R5G5B5A1_UNORM; + case GL_RGB8: + return FormatID::R8G8B8_UNORM; + case GL_RGB8I: + return FormatID::R8G8B8_SINT; + case GL_RGB8UI: + return FormatID::R8G8B8_UINT; + case GL_RGB8_SNORM: + return FormatID::R8G8B8_SNORM; + case GL_RGB8_SSCALED_ANGLEX: + return FormatID::R8G8B8_SSCALED; + case GL_RGB8_USCALED_ANGLEX: + return FormatID::R8G8B8_USCALED; + case GL_RGB9_E5: + return FormatID::R9G9B9E5_SHAREDEXP; + case GL_RGBA: + return FormatID::R8G8B8A8_UNORM; + case GL_RGBA16F: + return FormatID::R16G16B16A16_FLOAT; + case GL_RGBA16I: + return FormatID::R16G16B16A16_SINT; + case GL_RGBA16UI: + return FormatID::R16G16B16A16_UINT; + case GL_RGBA16_EXT: + return FormatID::R16G16B16A16_UNORM; + case GL_RGBA16_SNORM_EXT: + return FormatID::R16G16B16A16_SNORM; + case GL_RGBA16_SSCALED_ANGLEX: + return FormatID::R16G16B16A16_SSCALED; + case GL_RGBA16_USCALED_ANGLEX: + return FormatID::R16G16B16A16_USCALED; + case GL_RGBA32F: + return FormatID::R32G32B32A32_FLOAT; + case GL_RGBA32I: + return FormatID::R32G32B32A32_SINT; + case GL_RGBA32UI: + return FormatID::R32G32B32A32_UINT; + case GL_RGBA32_FIXED_ANGLEX: + return FormatID::R32G32B32A32_FIXED; + case GL_RGBA32_SNORM_ANGLEX: + return FormatID::R32G32B32A32_SNORM; + case GL_RGBA32_SSCALED_ANGLEX: + return FormatID::R32G32B32A32_SSCALED; + case GL_RGBA32_UNORM_ANGLEX: + return FormatID::R32G32B32A32_UNORM; + case GL_RGBA32_USCALED_ANGLEX: + return FormatID::R32G32B32A32_USCALED; + case GL_RGBA4: + return FormatID::R4G4B4A4_UNORM; + case GL_RGBA8: + return FormatID::R8G8B8A8_UNORM; + case GL_RGBA8I: + return FormatID::R8G8B8A8_SINT; + case GL_RGBA8UI: + return FormatID::R8G8B8A8_UINT; + case GL_RGBA8_SNORM: + return FormatID::R8G8B8A8_SNORM; + case GL_RGBA8_SSCALED_ANGLEX: + return FormatID::R8G8B8A8_SSCALED; + case GL_RGBA8_TYPELESS_ANGLEX: + return FormatID::R8G8B8A8_TYPELESS; + case GL_RGBA8_TYPELESS_SRGB_ANGLEX: + return FormatID::R8G8B8A8_TYPELESS_SRGB; + case GL_RGBA8_USCALED_ANGLEX: + return FormatID::R8G8B8A8_USCALED; + case GL_RGBX8_ANGLE: + return FormatID::R8G8B8X8_UNORM; + case GL_SR8_EXT: + return FormatID::R8_UNORM_SRGB; + case GL_SRG8_EXT: + return FormatID::R8G8_UNORM_SRGB; + case GL_SRGB8: + return FormatID::R8G8B8_UNORM_SRGB; + case GL_SRGB8_ALPHA8: + return FormatID::R8G8B8A8_UNORM_SRGB; + case GL_STENCIL_INDEX8: + return FormatID::S8_UINT; + case GL_UNSIGNED_INT_10_10_10_2_OES: + return FormatID::A2R10G10B10_UINT_VERTEX; + case GL_X2_RGB10_SINT_ANGLEX: + return FormatID::X2R10G10B10_SINT_VERTEX; + case GL_X2_RGB10_SNORM_ANGLEX: + return FormatID::X2R10G10B10_SNORM_VERTEX; + case GL_X2_RGB10_SSCALED_ANGLEX: + return FormatID::X2R10G10B10_SSCALED_VERTEX; + case GL_X2_RGB10_UINT_ANGLEX: + return FormatID::X2R10G10B10_UINT_VERTEX; + case GL_X2_RGB10_UNORM_ANGLEX: + return FormatID::X2R10G10B10_UNORM_VERTEX; + case GL_X2_RGB10_USCALED_ANGLEX: + return FormatID::X2R10G10B10_USCALED_VERTEX; + default: + return FormatID::NONE; + } +} + +const Format *GetFormatInfoTable() +{ + return gFormatInfoTable; +} +} // namespace angle diff --git a/gfx/angle/checkout/src/libANGLE/renderer/FramebufferAttachmentObjectImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/FramebufferAttachmentObjectImpl.h new file mode 100644 index 0000000000..0b5223ae5d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/FramebufferAttachmentObjectImpl.h @@ -0,0 +1,65 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// FramebufferAttachmentObjectImpl.h: +// Common ancenstor for all implementations of FBO attachable-objects. +// This means Surfaces, Textures and Renderbuffers. +// + +#ifndef LIBANGLE_RENDERER_FRAMEBUFFER_ATTACHMENT_OBJECT_IMPL_H_ +#define LIBANGLE_RENDERER_FRAMEBUFFER_ATTACHMENT_OBJECT_IMPL_H_ + +#include "libANGLE/ImageIndex.h" +#include "libANGLE/Observer.h" + +namespace gl +{ +class Context; +} // namespace gl + +namespace rx +{ +class FramebufferAttachmentRenderTarget; + +class FramebufferAttachmentObjectImpl : public angle::Subject +{ + public: + FramebufferAttachmentObjectImpl() {} + ~FramebufferAttachmentObjectImpl() override {} + + virtual angle::Result getAttachmentRenderTarget(const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex, + GLsizei samples, + FramebufferAttachmentRenderTarget **rtOut); + + virtual angle::Result initializeContents(const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex); +}; + +inline angle::Result FramebufferAttachmentObjectImpl::getAttachmentRenderTarget( + const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex, + GLsizei samples, + FramebufferAttachmentRenderTarget **rtOut) +{ + UNIMPLEMENTED(); + return angle::Result::Stop; +} + +inline angle::Result FramebufferAttachmentObjectImpl::initializeContents( + const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex) +{ + UNIMPLEMENTED(); + return angle::Result::Stop; +} + +} // namespace rx + +#endif // LIBANGLE_RENDERER_FRAMEBUFFER_ATTACHMENT_OBJECT_IMPL_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/FramebufferImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/FramebufferImpl.cpp new file mode 100644 index 0000000000..1cef167d9d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/FramebufferImpl.cpp @@ -0,0 +1,18 @@ +// +// Copyright 2022 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// FramebufferImpl.cpp: Implements the class methods for FramebufferImpl. + +#include "libANGLE/renderer/FramebufferImpl.h" + +namespace rx +{ + +angle::Result FramebufferImpl::onLabelUpdate(const gl::Context *context) +{ + return angle::Result::Continue; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/FramebufferImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/FramebufferImpl.h new file mode 100644 index 0000000000..0ecfaba4f2 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/FramebufferImpl.h @@ -0,0 +1,123 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// FramebufferImpl.h: Defines the abstract rx::FramebufferImpl class. + +#ifndef LIBANGLE_RENDERER_FRAMEBUFFERIMPL_H_ +#define LIBANGLE_RENDERER_FRAMEBUFFERIMPL_H_ + +#include "angle_gl.h" +#include "common/angleutils.h" +#include "libANGLE/Error.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/State.h" +#include "libANGLE/angletypes.h" + +namespace gl +{ +class Buffer; +class Framebuffer; +class FramebufferAttachment; +struct PixelPackState; +} // namespace gl + +namespace rx +{ +class DisplayImpl; + +class FramebufferImpl : angle::NonCopyable +{ + public: + explicit FramebufferImpl(const gl::FramebufferState &state) : mState(state) {} + virtual ~FramebufferImpl() {} + virtual void destroy(const gl::Context *context) {} + + virtual angle::Result discard(const gl::Context *context, + size_t count, + const GLenum *attachments) = 0; + virtual angle::Result invalidate(const gl::Context *context, + size_t count, + const GLenum *attachments) = 0; + virtual angle::Result invalidateSub(const gl::Context *context, + size_t count, + const GLenum *attachments, + const gl::Rectangle &area) = 0; + + virtual angle::Result clear(const gl::Context *context, GLbitfield mask) = 0; + virtual angle::Result clearBufferfv(const gl::Context *context, + GLenum buffer, + GLint drawbuffer, + const GLfloat *values) = 0; + virtual angle::Result clearBufferuiv(const gl::Context *context, + GLenum buffer, + GLint drawbuffer, + const GLuint *values) = 0; + virtual angle::Result clearBufferiv(const gl::Context *context, + GLenum buffer, + GLint drawbuffer, + const GLint *values) = 0; + virtual angle::Result clearBufferfi(const gl::Context *context, + GLenum buffer, + GLint drawbuffer, + GLfloat depth, + GLint stencil) = 0; + + virtual const gl::InternalFormat &getImplementationColorReadFormat( + const gl::Context *context) const; + virtual angle::Result readPixels(const gl::Context *context, + const gl::Rectangle &area, + GLenum format, + GLenum type, + const gl::PixelPackState &pack, + gl::Buffer *packBuffer, + void *pixels) = 0; + + virtual angle::Result blit(const gl::Context *context, + const gl::Rectangle &sourceArea, + const gl::Rectangle &destArea, + GLbitfield mask, + GLenum filter) = 0; + + virtual gl::FramebufferStatus checkStatus(const gl::Context *context) const = 0; + + virtual angle::Result syncState(const gl::Context *context, + GLenum binding, + const gl::Framebuffer::DirtyBits &dirtyBits, + gl::Command command) = 0; + + virtual angle::Result getSamplePosition(const gl::Context *context, + size_t index, + GLfloat *xy) const = 0; + + // Special configuration option for checkStatus(). Some back-ends don't require a syncState + // before calling checkStatus. In practice the GL back-end is the only config that needs + // syncState because it depends on the behaviour of the driver. Allowing the Vulkan and + // D3D back-ends to skip syncState lets us do more work in the syncState call. + virtual bool shouldSyncStateBeforeCheckStatus() const; + + virtual angle::Result onLabelUpdate(const gl::Context *context); + + const gl::FramebufferState &getState() const { return mState; } + + protected: + const gl::FramebufferState &mState; +}; + +inline bool FramebufferImpl::shouldSyncStateBeforeCheckStatus() const +{ + return false; +} + +// Default implementation returns the format specified in the attachment. +inline const gl::InternalFormat &FramebufferImpl::getImplementationColorReadFormat( + const gl::Context *context) const +{ + const gl::FramebufferAttachment *readAttachment = mState.getReadAttachment(); + return *readAttachment->getFormat().info; +} +} // namespace rx + +#endif // LIBANGLE_RENDERER_FRAMEBUFFERIMPL_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/GLImplFactory.h b/gfx/angle/checkout/src/libANGLE/renderer/GLImplFactory.h new file mode 100644 index 0000000000..1995197b06 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/GLImplFactory.h @@ -0,0 +1,116 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// GLImplFactory.h: +// Factory interface for OpenGL ES Impl objects. +// + +#ifndef LIBANGLE_RENDERER_GLIMPLFACTORY_H_ +#define LIBANGLE_RENDERER_GLIMPLFACTORY_H_ + +#include + +#include "angle_gl.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/Overlay.h" +#include "libANGLE/Program.h" +#include "libANGLE/ProgramPipeline.h" +#include "libANGLE/Renderbuffer.h" +#include "libANGLE/Shader.h" +#include "libANGLE/Texture.h" +#include "libANGLE/TransformFeedback.h" +#include "libANGLE/VertexArray.h" +#include "libANGLE/renderer/serial_utils.h" + +namespace gl +{ +class State; +} // namespace gl + +namespace rx +{ +class BufferImpl; +class CompilerImpl; +class ContextImpl; +class FenceNVImpl; +class SyncImpl; +class FramebufferImpl; +class MemoryObjectImpl; +class OverlayImpl; +class PathImpl; +class ProgramImpl; +class ProgramPipelineImpl; +class QueryImpl; +class RenderbufferImpl; +class SamplerImpl; +class SemaphoreImpl; +class ShaderImpl; +class TextureImpl; +class TransformFeedbackImpl; +class VertexArrayImpl; + +class GLImplFactory : angle::NonCopyable +{ + public: + GLImplFactory(); + virtual ~GLImplFactory(); + + // Shader creation + virtual CompilerImpl *createCompiler() = 0; + virtual ShaderImpl *createShader(const gl::ShaderState &data) = 0; + virtual ProgramImpl *createProgram(const gl::ProgramState &data) = 0; + + // Framebuffer creation + virtual FramebufferImpl *createFramebuffer(const gl::FramebufferState &data) = 0; + + // Texture creation + virtual TextureImpl *createTexture(const gl::TextureState &state) = 0; + + // Renderbuffer creation + virtual RenderbufferImpl *createRenderbuffer(const gl::RenderbufferState &state) = 0; + + // Buffer creation + virtual BufferImpl *createBuffer(const gl::BufferState &state) = 0; + + // Vertex Array creation + virtual VertexArrayImpl *createVertexArray(const gl::VertexArrayState &data) = 0; + + // Query and Fence creation + virtual QueryImpl *createQuery(gl::QueryType type) = 0; + virtual FenceNVImpl *createFenceNV() = 0; + virtual SyncImpl *createSync() = 0; + + // Transform Feedback creation + virtual TransformFeedbackImpl *createTransformFeedback( + const gl::TransformFeedbackState &state) = 0; + + // Sampler object creation + virtual SamplerImpl *createSampler(const gl::SamplerState &state) = 0; + + // Program Pipeline object creation + virtual ProgramPipelineImpl *createProgramPipeline(const gl::ProgramPipelineState &data) = 0; + + // Memory object creation + virtual MemoryObjectImpl *createMemoryObject() = 0; + + // Semaphore creation + virtual SemaphoreImpl *createSemaphore() = 0; + + // Overlay creation + virtual OverlayImpl *createOverlay(const gl::OverlayState &state) = 0; + + rx::Serial generateSerial() { return mSerialFactory.generate(); } + + private: + rx::SerialFactory mSerialFactory; +}; + +inline GLImplFactory::GLImplFactory() = default; + +inline GLImplFactory::~GLImplFactory() = default; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_GLIMPLFACTORY_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/ImageImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/ImageImpl.cpp new file mode 100644 index 0000000000..014b1d634d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/ImageImpl.cpp @@ -0,0 +1,30 @@ +// +// Copyright 2021 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ImageImpl.cpp: Defines the rx::ImageImpl class representing the EGLimage object. + +#include "libANGLE/renderer/ImageImpl.h" + +namespace rx +{ + +bool ExternalImageSiblingImpl::isCubeMap() const +{ + return false; +} + +uint32_t ExternalImageSiblingImpl::getLevelCount() const +{ + return 1; +} + +egl::Error ImageImpl::exportVkImage(void *vkImage, void *vkImageCreateInfo) +{ + UNIMPLEMENTED(); + return egl::EglBadAccess(); +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/ImageImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/ImageImpl.h new file mode 100644 index 0000000000..2a316610b3 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/ImageImpl.h @@ -0,0 +1,68 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ImageImpl.h: Defines the rx::ImageImpl class representing the EGLimage object. + +#ifndef LIBANGLE_RENDERER_IMAGEIMPL_H_ +#define LIBANGLE_RENDERER_IMAGEIMPL_H_ + +#include "common/angleutils.h" +#include "libANGLE/Error.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/FramebufferAttachmentObjectImpl.h" + +namespace gl +{ +class Context; +} // namespace gl + +namespace egl +{ +class Display; +class ImageSibling; +struct ImageState; +} // namespace egl + +namespace rx +{ +class ExternalImageSiblingImpl : public FramebufferAttachmentObjectImpl +{ + public: + ~ExternalImageSiblingImpl() override {} + + virtual egl::Error initialize(const egl::Display *display) = 0; + virtual void onDestroy(const egl::Display *display) {} + + virtual gl::Format getFormat() const = 0; + virtual bool isRenderable(const gl::Context *context) const = 0; + virtual bool isTexturable(const gl::Context *context) const = 0; + virtual bool isYUV() const = 0; + virtual bool isCubeMap() const; + virtual bool hasProtectedContent() const = 0; + virtual gl::Extents getSize() const = 0; + virtual size_t getSamples() const = 0; + virtual uint32_t getLevelCount() const; +}; + +class ImageImpl : angle::NonCopyable +{ + public: + ImageImpl(const egl::ImageState &state) : mState(state) {} + virtual ~ImageImpl() {} + virtual void onDestroy(const egl::Display *display) {} + + virtual egl::Error initialize(const egl::Display *display) = 0; + + virtual angle::Result orphan(const gl::Context *context, egl::ImageSibling *sibling) = 0; + + virtual egl::Error exportVkImage(void *vkImage, void *vkImageCreateInfo); + + protected: + const egl::ImageState &mState; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_IMAGEIMPL_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/MemoryObjectImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/MemoryObjectImpl.h new file mode 100644 index 0000000000..ce37dd3545 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/MemoryObjectImpl.h @@ -0,0 +1,47 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// MemoryObjectImpl.h: Implements the rx::MemoryObjectImpl class [EXT_external_objects] + +#ifndef LIBANGLE_RENDERER_MEMORYOBJECTIMPL_H_ +#define LIBANGLE_RENDERER_MEMORYOBJECTIMPL_H_ + +#include "angle_gl.h" +#include "common/PackedEnums.h" +#include "common/angleutils.h" +#include "libANGLE/Error.h" + +namespace gl +{ +class Context; +class MemoryObject; +} // namespace gl + +namespace rx +{ + +class MemoryObjectImpl : angle::NonCopyable +{ + public: + virtual ~MemoryObjectImpl() {} + + virtual void onDestroy(const gl::Context *context) = 0; + + virtual angle::Result setDedicatedMemory(const gl::Context *context, bool dedicatedMemory) = 0; + virtual angle::Result setProtectedMemory(const gl::Context *context, bool protectedMemory) = 0; + + virtual angle::Result importFd(gl::Context *context, + GLuint64 size, + gl::HandleType handleType, + GLint fd) = 0; + virtual angle::Result importZirconHandle(gl::Context *context, + GLuint64 size, + gl::HandleType handleType, + GLuint handle) = 0; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_MEMORYOBJECTIMPL_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/OverlayImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/OverlayImpl.h new file mode 100644 index 0000000000..fc1b1b0d58 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/OverlayImpl.h @@ -0,0 +1,42 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// OverlayImpl.h: Defines the abstract rx::OverlayImpl class. + +#ifndef LIBANGLE_RENDERER_OVERLAYIMPL_H_ +#define LIBANGLE_RENDERER_OVERLAYIMPL_H_ + +#include "common/PackedEnums.h" +#include "common/angleutils.h" +#include "common/mathutil.h" +#include "libANGLE/Error.h" +#include "libANGLE/Observer.h" + +#include + +namespace gl +{ +class Context; +class OverlayState; +} // namespace gl + +namespace rx +{ +class OverlayImpl : angle::NonCopyable +{ + public: + OverlayImpl(const gl::OverlayState &state) : mState(state) {} + virtual ~OverlayImpl() {} + + virtual void onDestroy(const gl::Context *context) {} + + protected: + const gl::OverlayState &mState; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_OVERLAYIMPL_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/ProgramImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/ProgramImpl.cpp new file mode 100644 index 0000000000..9ede4a882d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/ProgramImpl.cpp @@ -0,0 +1,18 @@ +// +// Copyright 2022 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ProgramImpl.cpp: Implements the class methods for ProgramImpl. + +#include "libANGLE/renderer/ProgramImpl.h" + +namespace rx +{ + +angle::Result ProgramImpl::onLabelUpdate(const gl::Context *context) +{ + return angle::Result::Continue; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/ProgramImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/ProgramImpl.h new file mode 100644 index 0000000000..22bd304856 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/ProgramImpl.h @@ -0,0 +1,176 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ProgramImpl.h: Defines the abstract rx::ProgramImpl class. + +#ifndef LIBANGLE_RENDERER_PROGRAMIMPL_H_ +#define LIBANGLE_RENDERER_PROGRAMIMPL_H_ + +#include "common/angleutils.h" +#include "libANGLE/BinaryStream.h" +#include "libANGLE/Constants.h" +#include "libANGLE/Program.h" +#include "libANGLE/Shader.h" + +#include + +namespace gl +{ +class Context; +struct ProgramLinkedResources; +} // namespace gl + +namespace sh +{ +struct BlockMemberInfo; +} + +namespace rx +{ + +// Provides a mechanism to access the result of asynchronous linking. +class LinkEvent : angle::NonCopyable +{ + public: + virtual ~LinkEvent() {} + + // Please be aware that these methods may be called under a gl::Context other + // than the one where the LinkEvent was created. + // + // Waits until the linking is actually done. Returns true if the linking + // succeeded, false otherwise. + virtual angle::Result wait(const gl::Context *context) = 0; + // Peeks whether the linking is still ongoing. + virtual bool isLinking() = 0; +}; + +// Wraps an already done linking. +class LinkEventDone final : public LinkEvent +{ + public: + LinkEventDone(angle::Result result) : mResult(result) {} + angle::Result wait(const gl::Context *context) override; + bool isLinking() override; + + private: + angle::Result mResult; +}; + +inline angle::Result LinkEventDone::wait(const gl::Context *context) +{ + return mResult; +} +inline bool LinkEventDone::isLinking() +{ + return false; +} + +class ProgramImpl : angle::NonCopyable +{ + public: + ProgramImpl(const gl::ProgramState &state) : mState(state) {} + virtual ~ProgramImpl() {} + virtual void destroy(const gl::Context *context) {} + + virtual std::unique_ptr load(const gl::Context *context, + gl::BinaryInputStream *stream, + gl::InfoLog &infoLog) = 0; + virtual void save(const gl::Context *context, gl::BinaryOutputStream *stream) = 0; + virtual void setBinaryRetrievableHint(bool retrievable) = 0; + virtual void setSeparable(bool separable) = 0; + + virtual std::unique_ptr link(const gl::Context *context, + const gl::ProgramLinkedResources &resources, + gl::InfoLog &infoLog, + const gl::ProgramMergedVaryings &mergedVaryings) = 0; + virtual GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) = 0; + + virtual void setUniform1fv(GLint location, GLsizei count, const GLfloat *v) = 0; + virtual void setUniform2fv(GLint location, GLsizei count, const GLfloat *v) = 0; + virtual void setUniform3fv(GLint location, GLsizei count, const GLfloat *v) = 0; + virtual void setUniform4fv(GLint location, GLsizei count, const GLfloat *v) = 0; + virtual void setUniform1iv(GLint location, GLsizei count, const GLint *v) = 0; + virtual void setUniform2iv(GLint location, GLsizei count, const GLint *v) = 0; + virtual void setUniform3iv(GLint location, GLsizei count, const GLint *v) = 0; + virtual void setUniform4iv(GLint location, GLsizei count, const GLint *v) = 0; + virtual void setUniform1uiv(GLint location, GLsizei count, const GLuint *v) = 0; + virtual void setUniform2uiv(GLint location, GLsizei count, const GLuint *v) = 0; + virtual void setUniform3uiv(GLint location, GLsizei count, const GLuint *v) = 0; + virtual void setUniform4uiv(GLint location, GLsizei count, const GLuint *v) = 0; + virtual void setUniformMatrix2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) = 0; + virtual void setUniformMatrix3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) = 0; + virtual void setUniformMatrix4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) = 0; + virtual void setUniformMatrix2x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) = 0; + virtual void setUniformMatrix3x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) = 0; + virtual void setUniformMatrix2x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) = 0; + virtual void setUniformMatrix4x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) = 0; + virtual void setUniformMatrix3x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) = 0; + virtual void setUniformMatrix4x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) = 0; + + // Done in the back-end to avoid having to keep a system copy of uniform data. + virtual void getUniformfv(const gl::Context *context, + GLint location, + GLfloat *params) const = 0; + virtual void getUniformiv(const gl::Context *context, GLint location, GLint *params) const = 0; + virtual void getUniformuiv(const gl::Context *context, + GLint location, + GLuint *params) const = 0; + + // Implementation-specific method for ignoring unreferenced uniforms. Some implementations may + // perform more extensive analysis and ignore some locations that ANGLE doesn't detect as + // unreferenced. This method is not required to be overriden by a back-end. + virtual void markUnusedUniformLocations(std::vector *uniformLocations, + std::vector *samplerBindings, + std::vector *imageBindings) + {} + + const gl::ProgramState &getState() const { return mState; } + + virtual angle::Result syncState(const gl::Context *context, + const gl::Program::DirtyBits &dirtyBits); + + virtual angle::Result onLabelUpdate(const gl::Context *context); + + protected: + const gl::ProgramState &mState; +}; + +inline angle::Result ProgramImpl::syncState(const gl::Context *context, + const gl::Program::DirtyBits &dirtyBits) +{ + return angle::Result::Continue; +} + +} // namespace rx + +#endif // LIBANGLE_RENDERER_PROGRAMIMPL_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/ProgramPipelineImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/ProgramPipelineImpl.cpp new file mode 100644 index 0000000000..c90fb11da0 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/ProgramPipelineImpl.cpp @@ -0,0 +1,26 @@ +// +// Copyright 2022 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ProgramPipelineImpl.cpp: Defines the abstract rx::ProgramPipelineImpl class. + +#include "libANGLE/renderer/ProgramPipelineImpl.h" + +namespace rx +{ + +angle::Result ProgramPipelineImpl::link(const gl::Context *context, + const gl::ProgramMergedVaryings &mergedVaryings, + const gl::ProgramVaryingPacking &varyingPacking) +{ + return angle::Result::Continue; +} + +angle::Result ProgramPipelineImpl::onLabelUpdate(const gl::Context *context) +{ + return angle::Result::Continue; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/ProgramPipelineImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/ProgramPipelineImpl.h new file mode 100644 index 0000000000..7f69571a9f --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/ProgramPipelineImpl.h @@ -0,0 +1,42 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ProgramPipelineImpl.h: Defines the abstract rx::ProgramPipelineImpl class. + +#ifndef LIBANGLE_RENDERER_PROGRAMPIPELINEIMPL_H_ +#define LIBANGLE_RENDERER_PROGRAMPIPELINEIMPL_H_ + +#include "common/angleutils.h" +#include "libANGLE/ProgramPipeline.h" + +namespace rx +{ +class ContextImpl; + +class ProgramPipelineImpl : public angle::NonCopyable +{ + public: + ProgramPipelineImpl(const gl::ProgramPipelineState &state) : mState(state) {} + virtual ~ProgramPipelineImpl() {} + virtual void destroy(const gl::Context *context) {} + + virtual angle::Result link(const gl::Context *context, + const gl::ProgramMergedVaryings &mergedVaryings, + const gl::ProgramVaryingPacking &varyingPacking); + + virtual void onProgramUniformUpdate(gl::ShaderType shaderType) {} + + virtual angle::Result onLabelUpdate(const gl::Context *context); + + const gl::ProgramPipelineState &getState() const { return mState; } + + protected: + const gl::ProgramPipelineState &mState; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_PROGRAMPIPELINEIMPL_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/QueryImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/QueryImpl.cpp new file mode 100644 index 0000000000..ed9497e2a3 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/QueryImpl.cpp @@ -0,0 +1,21 @@ +// +// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// QueryImpl.cpp: Defines the abstract rx::QueryImpl classes. + +#include "libANGLE/renderer/QueryImpl.h" + +namespace rx +{ + +void QueryImpl::onDestroy(const gl::Context *context) {} + +angle::Result QueryImpl::onLabelUpdate(const gl::Context *context) +{ + return angle::Result::Continue; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/QueryImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/QueryImpl.h new file mode 100644 index 0000000000..8e5e351418 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/QueryImpl.h @@ -0,0 +1,49 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// QueryImpl.h: Defines the abstract rx::QueryImpl class. + +#ifndef LIBANGLE_RENDERER_QUERYIMPL_H_ +#define LIBANGLE_RENDERER_QUERYIMPL_H_ + +#include "common/PackedEnums.h" +#include "common/angleutils.h" +#include "libANGLE/Error.h" + +namespace gl +{ +class Context; +} // namespace gl + +namespace rx +{ +class QueryImpl : angle::NonCopyable +{ + public: + explicit QueryImpl(gl::QueryType type) : mType(type) {} + virtual ~QueryImpl() {} + + virtual void onDestroy(const gl::Context *context); + + virtual angle::Result begin(const gl::Context *context) = 0; + virtual angle::Result end(const gl::Context *context) = 0; + virtual angle::Result queryCounter(const gl::Context *context) = 0; + virtual angle::Result getResult(const gl::Context *context, GLint *params) = 0; + virtual angle::Result getResult(const gl::Context *context, GLuint *params) = 0; + virtual angle::Result getResult(const gl::Context *context, GLint64 *params) = 0; + virtual angle::Result getResult(const gl::Context *context, GLuint64 *params) = 0; + virtual angle::Result isResultAvailable(const gl::Context *context, bool *available) = 0; + + virtual angle::Result onLabelUpdate(const gl::Context *context); + + gl::QueryType getType() const { return mType; } + + protected: + gl::QueryType mType; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_QUERYIMPL_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/RenderTargetCache.h b/gfx/angle/checkout/src/libANGLE/renderer/RenderTargetCache.h new file mode 100644 index 0000000000..ffc2a04492 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/RenderTargetCache.h @@ -0,0 +1,186 @@ +// +// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// RenderTargetCache: +// The RenderTargetCache pattern is used in the D3D9, D3D11 and Vulkan back-ends. It is a +// cache of the various back-end objects (RenderTargets) associated with each Framebuffer +// attachment, be they Textures, Renderbuffers, or Surfaces. The cache is updated in Framebuffer's +// syncState method. +// + +#ifndef LIBANGLE_RENDERER_RENDER_TARGET_CACHE_H_ +#define LIBANGLE_RENDERER_RENDER_TARGET_CACHE_H_ + +#include "libANGLE/Framebuffer.h" +#include "libANGLE/FramebufferAttachment.h" + +namespace rx +{ + +template +class RenderTargetCache final : angle::NonCopyable +{ + public: + RenderTargetCache(); + ~RenderTargetCache(); + + // Update all RenderTargets from the dirty bits. + angle::Result update(const gl::Context *context, + const gl::FramebufferState &state, + const gl::Framebuffer::DirtyBits &dirtyBits); + + // Update individual RenderTargets. + angle::Result updateReadColorRenderTarget(const gl::Context *context, + const gl::FramebufferState &state); + angle::Result updateColorRenderTarget(const gl::Context *context, + const gl::FramebufferState &state, + size_t colorIndex); + angle::Result updateDepthStencilRenderTarget(const gl::Context *context, + const gl::FramebufferState &state); + + using RenderTargetArray = gl::AttachmentArray; + + const RenderTargetArray &getColors() const; + RenderTargetT *getDepthStencil() const; + + RenderTargetT *getColorDraw(const gl::FramebufferState &state, size_t colorIndex) const; + RenderTargetT *getColorRead(const gl::FramebufferState &state) const; + + private: + angle::Result updateCachedRenderTarget(const gl::Context *context, + const gl::FramebufferAttachment *attachment, + RenderTargetT **cachedRenderTarget); + + RenderTargetT *mReadRenderTarget = nullptr; + gl::AttachmentArray mColorRenderTargets = {}; + // We only support a single Depth/Stencil RenderTarget currently. + RenderTargetT *mDepthStencilRenderTarget = nullptr; +}; + +template +RenderTargetCache::RenderTargetCache() = default; + +template +RenderTargetCache::~RenderTargetCache() = default; + +template +angle::Result RenderTargetCache::update(const gl::Context *context, + const gl::FramebufferState &state, + const gl::Framebuffer::DirtyBits &dirtyBits) +{ + for (auto dirtyBit : dirtyBits) + { + switch (dirtyBit) + { + case gl::Framebuffer::DIRTY_BIT_DEPTH_ATTACHMENT: + case gl::Framebuffer::DIRTY_BIT_STENCIL_ATTACHMENT: + ANGLE_TRY(updateDepthStencilRenderTarget(context, state)); + break; + case gl::Framebuffer::DIRTY_BIT_READ_BUFFER: + ANGLE_TRY(updateReadColorRenderTarget(context, state)); + break; + case gl::Framebuffer::DIRTY_BIT_DRAW_BUFFERS: + case gl::Framebuffer::DIRTY_BIT_DEFAULT_WIDTH: + case gl::Framebuffer::DIRTY_BIT_DEFAULT_HEIGHT: + case gl::Framebuffer::DIRTY_BIT_DEFAULT_SAMPLES: + case gl::Framebuffer::DIRTY_BIT_DEFAULT_FIXED_SAMPLE_LOCATIONS: + break; + default: + { + static_assert(gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 == 0, "FB dirty bits"); + if (dirtyBit < gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX) + { + size_t colorIndex = static_cast( + dirtyBit - gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0); + ANGLE_TRY(updateColorRenderTarget(context, state, colorIndex)); + } + break; + } + } + } + + return angle::Result::Continue; +} + +template +const gl::AttachmentArray &RenderTargetCache::getColors() const +{ + return mColorRenderTargets; +} + +template +RenderTargetT *RenderTargetCache::getDepthStencil() const +{ + return mDepthStencilRenderTarget; +} + +template +angle::Result RenderTargetCache::updateReadColorRenderTarget( + const gl::Context *context, + const gl::FramebufferState &state) +{ + return updateCachedRenderTarget(context, state.getReadAttachment(), &mReadRenderTarget); +} + +template +angle::Result RenderTargetCache::updateColorRenderTarget( + const gl::Context *context, + const gl::FramebufferState &state, + size_t colorIndex) +{ + // If the color render target we're updating is also the read buffer, make sure we update the + // read render target also so it's not stale. + if (state.getReadBufferState() != GL_NONE && state.getReadIndex() == colorIndex) + { + ANGLE_TRY(updateReadColorRenderTarget(context, state)); + } + + return updateCachedRenderTarget(context, state.getColorAttachment(colorIndex), + &mColorRenderTargets[colorIndex]); +} + +template +angle::Result RenderTargetCache::updateDepthStencilRenderTarget( + const gl::Context *context, + const gl::FramebufferState &state) +{ + return updateCachedRenderTarget(context, state.getDepthOrStencilAttachment(), + &mDepthStencilRenderTarget); +} + +template +angle::Result RenderTargetCache::updateCachedRenderTarget( + const gl::Context *context, + const gl::FramebufferAttachment *attachment, + RenderTargetT **cachedRenderTarget) +{ + RenderTargetT *newRenderTarget = nullptr; + if (attachment) + { + ASSERT(attachment->isAttached()); + ANGLE_TRY(attachment->getRenderTarget(context, attachment->getRenderToTextureSamples(), + &newRenderTarget)); + } + *cachedRenderTarget = newRenderTarget; + return angle::Result::Continue; +} + +template +RenderTargetT *RenderTargetCache::getColorDraw(const gl::FramebufferState &state, + size_t colorIndex) const +{ + return mColorRenderTargets[colorIndex]; +} + +template +RenderTargetT *RenderTargetCache::getColorRead( + const gl::FramebufferState &state) const +{ + return mReadRenderTarget; +} + +} // namespace rx + +#endif // LIBANGLE_RENDERER_RENDER_TARGET_CACHE_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/RenderbufferImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/RenderbufferImpl.cpp new file mode 100644 index 0000000000..c25f87e13e --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/RenderbufferImpl.cpp @@ -0,0 +1,19 @@ +// +// Copyright 2022 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// RenderbufferImpl.cpp: Defines the abstract rx::RenderbufferImpl class. + +#include "libANGLE/renderer/RenderbufferImpl.h" + +namespace rx +{ + +angle::Result RenderbufferImpl::onLabelUpdate(const gl::Context *context) +{ + return angle::Result::Continue; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/RenderbufferImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/RenderbufferImpl.h new file mode 100644 index 0000000000..94dd7b9da7 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/RenderbufferImpl.h @@ -0,0 +1,164 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// RenderbufferImpl.h: Defines the abstract class gl::RenderbufferImpl + +#ifndef LIBANGLE_RENDERER_RENDERBUFFERIMPL_H_ +#define LIBANGLE_RENDERER_RENDERBUFFERIMPL_H_ + +#include "angle_gl.h" +#include "common/angleutils.h" +#include "libANGLE/Error.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/renderer/FramebufferAttachmentObjectImpl.h" + +namespace gl +{ +struct PixelPackState; +class RenderbufferState; +} // namespace gl + +namespace egl +{ +class Image; +} // namespace egl + +namespace rx +{ + +class RenderbufferImpl : public FramebufferAttachmentObjectImpl +{ + public: + RenderbufferImpl(const gl::RenderbufferState &state) : mState(state) {} + ~RenderbufferImpl() override {} + virtual void onDestroy(const gl::Context *context) {} + + virtual angle::Result setStorage(const gl::Context *context, + GLenum internalformat, + GLsizei width, + GLsizei height) = 0; + virtual angle::Result setStorageMultisample(const gl::Context *context, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + gl::MultisamplingMode mode) = 0; + virtual angle::Result setStorageEGLImageTarget(const gl::Context *context, + egl::Image *image) = 0; + + virtual angle::Result copyRenderbufferSubData(const gl::Context *context, + const gl::Renderbuffer *srcBuffer, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth); + + virtual angle::Result copyTextureSubData(const gl::Context *context, + const gl::Texture *srcTexture, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth); + + virtual GLenum getColorReadFormat(const gl::Context *context); + virtual GLenum getColorReadType(const gl::Context *context); + + virtual angle::Result getRenderbufferImage(const gl::Context *context, + const gl::PixelPackState &packState, + gl::Buffer *packBuffer, + GLenum format, + GLenum type, + void *pixels); + + // Override if accurate native memory size information is available + virtual GLint getMemorySize() const; + + virtual angle::Result onLabelUpdate(const gl::Context *context); + + protected: + const gl::RenderbufferState &mState; +}; + +inline angle::Result RenderbufferImpl::copyRenderbufferSubData(const gl::Context *context, + const gl::Renderbuffer *srcBuffer, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth) +{ + UNREACHABLE(); + return angle::Result::Stop; +} + +inline angle::Result RenderbufferImpl::copyTextureSubData(const gl::Context *context, + const gl::Texture *srcTexture, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth) +{ + UNREACHABLE(); + return angle::Result::Stop; +} + +inline GLint RenderbufferImpl::getMemorySize() const +{ + return 0; +} + +inline GLenum RenderbufferImpl::getColorReadFormat(const gl::Context *context) +{ + UNREACHABLE(); + return GL_NONE; +} + +inline GLenum RenderbufferImpl::getColorReadType(const gl::Context *context) +{ + UNREACHABLE(); + return GL_NONE; +} + +inline angle::Result RenderbufferImpl::getRenderbufferImage(const gl::Context *context, + const gl::PixelPackState &packState, + gl::Buffer *packBuffer, + GLenum format, + GLenum type, + void *pixels) +{ + UNREACHABLE(); + return angle::Result::Stop; +} +} // namespace rx + +#endif // LIBANGLE_RENDERER_RENDERBUFFERIMPL_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/SamplerImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/SamplerImpl.h new file mode 100644 index 0000000000..2d0af8b0cc --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/SamplerImpl.h @@ -0,0 +1,44 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// SamplerImpl.h: Defines the abstract rx::SamplerImpl class. + +#ifndef LIBANGLE_RENDERER_SAMPLERIMPL_H_ +#define LIBANGLE_RENDERER_SAMPLERIMPL_H_ + +#include "common/angleutils.h" +#include "libANGLE/Error.h" +#include "libANGLE/Sampler.h" + +namespace gl +{ +class Context; +class SamplerState; +} // namespace gl + +namespace rx +{ + +class SamplerImpl : angle::NonCopyable +{ + public: + SamplerImpl(const gl::SamplerState &state) : mState(state) {} + virtual ~SamplerImpl() {} + + virtual void onDestroy(const gl::Context *context) + { + // Default implementation: no-op. + } + virtual angle::Result syncState(const gl::Context *context, const bool dirty) = 0; + + angle::Result onLabelUpdate(const gl::Context *context) { return angle::Result::Continue; } + + protected: + const gl::SamplerState &mState; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_SAMPLERIMPL_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/SemaphoreImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/SemaphoreImpl.h new file mode 100644 index 0000000000..5beeba0d0a --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/SemaphoreImpl.h @@ -0,0 +1,50 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// SemaphoreImpl.h: Implements the rx::SemaphoreImpl class [EXT_external_objects] + +#ifndef LIBANGLE_RENDERER_SEMAPHOREIMPL_H_ +#define LIBANGLE_RENDERER_SEMAPHOREIMPL_H_ + +#include "angle_gl.h" +#include "common/PackedEnums.h" +#include "common/angleutils.h" +#include "libANGLE/Error.h" +#include "libANGLE/angletypes.h" + +namespace gl +{ +class Context; +class Semaphore; +} // namespace gl + +namespace rx +{ + +class SemaphoreImpl : angle::NonCopyable +{ + public: + virtual ~SemaphoreImpl() {} + + virtual void onDestroy(const gl::Context *context) = 0; + + virtual angle::Result importFd(gl::Context *context, gl::HandleType handleType, GLint fd) = 0; + + virtual angle::Result importZirconHandle(gl::Context *context, + gl::HandleType handleType, + GLuint handle) = 0; + + virtual angle::Result wait(gl::Context *context, + const gl::BufferBarrierVector &bufferBarriers, + const gl::TextureBarrierVector &textureBarriers) = 0; + + virtual angle::Result signal(gl::Context *context, + const gl::BufferBarrierVector &bufferBarriers, + const gl::TextureBarrierVector &textureBarriers) = 0; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_SEMAPHOREIMPL_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/ShaderImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/ShaderImpl.cpp new file mode 100644 index 0000000000..eb20adcfde --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/ShaderImpl.cpp @@ -0,0 +1,105 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ShaderImpl.cpp: Implementation methods of ShaderImpl + +#include "libANGLE/renderer/ShaderImpl.h" + +#include "libANGLE/Context.h" +#include "libANGLE/trace.h" + +namespace rx +{ + +WaitableCompileEvent::WaitableCompileEvent(std::shared_ptr waitableEvent) + : mWaitableEvent(waitableEvent) +{} + +WaitableCompileEvent::~WaitableCompileEvent() +{ + mWaitableEvent.reset(); +} + +void WaitableCompileEvent::wait() +{ + mWaitableEvent->wait(); +} + +bool WaitableCompileEvent::isReady() +{ + return mWaitableEvent->isReady(); +} + +const std::string &WaitableCompileEvent::getInfoLog() +{ + return mInfoLog; +} + +class TranslateTask : public angle::Closure +{ + public: + TranslateTask(ShHandle handle, const ShCompileOptions &options, const std::string &source) + : mHandle(handle), mOptions(options), mSource(source), mResult(false) + {} + + void operator()() override + { + ANGLE_TRACE_EVENT1("gpu.angle", "TranslateTask::run", "source", mSource); + const char *source = mSource.c_str(); + mResult = sh::Compile(mHandle, &source, 1, mOptions); + } + + bool getResult() { return mResult; } + + ShHandle getHandle() { return mHandle; } + + private: + ShHandle mHandle; + ShCompileOptions mOptions; + std::string mSource; + bool mResult; +}; + +class WaitableCompileEventImpl final : public WaitableCompileEvent +{ + public: + WaitableCompileEventImpl(std::shared_ptr waitableEvent, + std::shared_ptr translateTask) + : WaitableCompileEvent(waitableEvent), mTranslateTask(translateTask) + {} + + bool getResult() override { return mTranslateTask->getResult(); } + + bool postTranslate(std::string *infoLog) override { return true; } + + private: + std::shared_ptr mTranslateTask; +}; + +std::shared_ptr ShaderImpl::compileImpl( + const gl::Context *context, + gl::ShCompilerInstance *compilerInstance, + const std::string &source, + ShCompileOptions *compileOptions) +{ +#if defined(ANGLE_ENABLE_ASSERTS) + compileOptions->validateAST = true; +#endif + + auto workerThreadPool = context->getShaderCompileThreadPool(); + auto translateTask = + std::make_shared(compilerInstance->getHandle(), *compileOptions, source); + + return std::make_shared( + angle::WorkerThreadPool::PostWorkerTask(workerThreadPool, translateTask), translateTask); +} + +angle::Result ShaderImpl::onLabelUpdate(const gl::Context *context) +{ + return angle::Result::Continue; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/ShaderImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/ShaderImpl.h new file mode 100644 index 0000000000..be50cc754b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/ShaderImpl.h @@ -0,0 +1,77 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ShaderImpl.h: Defines the abstract rx::ShaderImpl class. + +#ifndef LIBANGLE_RENDERER_SHADERIMPL_H_ +#define LIBANGLE_RENDERER_SHADERIMPL_H_ + +#include + +#include "common/angleutils.h" +#include "libANGLE/Shader.h" +#include "libANGLE/WorkerThread.h" + +namespace gl +{ +class ShCompilerInstance; +} // namespace gl + +namespace rx +{ + +using UpdateShaderStateFunctor = std::function; +class WaitableCompileEvent : public angle::WaitableEvent +{ + public: + WaitableCompileEvent(std::shared_ptr waitableEvent); + ~WaitableCompileEvent() override; + + void wait() override; + + bool isReady() override; + + virtual bool getResult() = 0; + + virtual bool postTranslate(std::string *infoLog) = 0; + + const std::string &getInfoLog(); + + protected: + std::shared_ptr mWaitableEvent; + std::string mInfoLog; +}; + +class ShaderImpl : angle::NonCopyable +{ + public: + ShaderImpl(const gl::ShaderState &state) : mState(state) {} + virtual ~ShaderImpl() {} + + virtual void destroy() {} + + virtual std::shared_ptr compile(const gl::Context *context, + gl::ShCompilerInstance *compilerInstance, + ShCompileOptions *options) = 0; + + virtual std::string getDebugInfo() const = 0; + + const gl::ShaderState &getState() const { return mState; } + + virtual angle::Result onLabelUpdate(const gl::Context *context); + + protected: + std::shared_ptr compileImpl(const gl::Context *context, + gl::ShCompilerInstance *compilerInstance, + const std::string &source, + ShCompileOptions *compileOptions); + + const gl::ShaderState &mState; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_SHADERIMPL_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/StreamProducerImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/StreamProducerImpl.h new file mode 100644 index 0000000000..e4a65e2812 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/StreamProducerImpl.h @@ -0,0 +1,40 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// StreamProducerImpl.h: Defines the abstract rx::StreamProducerImpl class. + +#ifndef LIBANGLE_RENDERER_STREAMPRODUCERIMPL_H_ +#define LIBANGLE_RENDERER_STREAMPRODUCERIMPL_H_ + +#include "common/angleutils.h" +#include "libANGLE/Stream.h" + +namespace rx +{ + +class StreamProducerImpl : angle::NonCopyable +{ + public: + explicit StreamProducerImpl() {} + virtual ~StreamProducerImpl() {} + + // Validates the ability for the producer to accept an arbitrary pointer to a frame. All + // pointers should be validated through this function before being used to produce a frame. + virtual egl::Error validateD3DTexture(const void *pointer, + const egl::AttributeMap &attributes) const = 0; + + // Constructs a frame from an arbitrary external pointer that points to producer specific frame + // data. Replaces the internal frame with the new one. + virtual void postD3DTexture(void *pointer, const egl::AttributeMap &attributes) = 0; + + // Returns an OpenGL texture interpretation of some frame attributes for the purpose of + // constructing an OpenGL texture from a frame. Depending on the producer and consumer, some + // frames may have multiple "planes" with different OpenGL texture representations. + virtual egl::Stream::GLTextureDescription getGLFrameDescription(int planeIndex) = 0; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_STREAMPRODUCERIMPL_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/SurfaceImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/SurfaceImpl.cpp new file mode 100644 index 0000000000..469ef6119f --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/SurfaceImpl.cpp @@ -0,0 +1,158 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// SurfaceImpl.cpp: Implementation of Surface stub method class + +#include "libANGLE/renderer/SurfaceImpl.h" + +namespace rx +{ + +SurfaceImpl::SurfaceImpl(const egl::SurfaceState &state) : mState(state) {} + +SurfaceImpl::~SurfaceImpl() {} + +egl::Error SurfaceImpl::makeCurrent(const gl::Context *context) +{ + return egl::NoError(); +} + +egl::Error SurfaceImpl::unMakeCurrent(const gl::Context *context) +{ + return egl::NoError(); +} + +egl::Error SurfaceImpl::prepareSwap(const gl::Context *) +{ + return angle::ResultToEGL(angle::Result::Continue); +} + +egl::Error SurfaceImpl::swapWithDamage(const gl::Context *context, + const EGLint *rects, + EGLint n_rects) +{ + UNREACHABLE(); + return egl::EglBadSurface() << "swapWithDamage implementation missing."; +} + +egl::Error SurfaceImpl::setPresentationTime(EGLnsecsANDROID time) +{ + UNREACHABLE(); + return egl::EglBadSurface() << "setPresentationTime implementation missing."; +} + +void SurfaceImpl::setFixedWidth(EGLint width) +{ + UNREACHABLE(); +} + +void SurfaceImpl::setFixedHeight(EGLint height) +{ + UNREACHABLE(); +} + +void SurfaceImpl::setTimestampsEnabled(bool enabled) +{ + UNREACHABLE(); +} + +const angle::Format *SurfaceImpl::getD3DTextureColorFormat() const +{ + UNREACHABLE(); + return nullptr; +} + +egl::SupportedCompositorTimings SurfaceImpl::getSupportedCompositorTimings() const +{ + UNREACHABLE(); + return egl::SupportedCompositorTimings(); +} + +egl::Error SurfaceImpl::getCompositorTiming(EGLint numTimestamps, + const EGLint *names, + EGLnsecsANDROID *values) const +{ + UNREACHABLE(); + return egl::EglBadDisplay(); +} + +egl::Error SurfaceImpl::getNextFrameId(EGLuint64KHR *frameId) const +{ + UNREACHABLE(); + return egl::EglBadDisplay(); +} + +egl::SupportedTimestamps SurfaceImpl::getSupportedTimestamps() const +{ + UNREACHABLE(); + return egl::SupportedTimestamps(); +} + +egl::Error SurfaceImpl::getFrameTimestamps(EGLuint64KHR frameId, + EGLint numTimestamps, + const EGLint *timestamps, + EGLnsecsANDROID *values) const +{ + UNREACHABLE(); + return egl::EglBadDisplay(); +} + +egl::Error SurfaceImpl::swapWithFrameToken(const gl::Context *context, + EGLFrameTokenANGLE frameToken) +{ + UNREACHABLE(); + return egl::EglBadDisplay(); +} + +egl::Error SurfaceImpl::getUserWidth(const egl::Display *display, EGLint *value) const +{ + *value = getWidth(); + return egl::NoError(); +} + +egl::Error SurfaceImpl::getUserHeight(const egl::Display *display, EGLint *value) const +{ + *value = getHeight(); + return egl::NoError(); +} + +egl::Error SurfaceImpl::getBufferAge(const gl::Context *context, EGLint *age) +{ + *age = 0; + return egl::NoError(); +} + +egl::Error SurfaceImpl::setAutoRefreshEnabled(bool enabled) +{ + return egl::EglBadMatch(); +} + +egl::Error SurfaceImpl::lockSurface(const egl::Display *display, + EGLint usageHint, + bool preservePixels, + uint8_t **bufferPtrOut, + EGLint *bufferPitchOut) +{ + UNREACHABLE(); + return egl::EglBadMatch(); +} + +egl::Error SurfaceImpl::unlockSurface(const egl::Display *display, bool preservePixels) +{ + UNREACHABLE(); + return egl::EglBadMatch(); +} + +EGLint SurfaceImpl::origin() const +{ + return EGL_LOWER_LEFT_KHR; +} + +egl::Error SurfaceImpl::setRenderBuffer(EGLint renderBuffer) +{ + return egl::NoError(); +} +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/SurfaceImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/SurfaceImpl.h new file mode 100644 index 0000000000..95952d096c --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/SurfaceImpl.h @@ -0,0 +1,136 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// SurfaceImpl.h: Implementation methods of egl::Surface + +#ifndef LIBANGLE_RENDERER_SURFACEIMPL_H_ +#define LIBANGLE_RENDERER_SURFACEIMPL_H_ + +#include +#include + +#include "common/angleutils.h" +#include "libANGLE/Error.h" +#include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/renderer/FramebufferAttachmentObjectImpl.h" + +namespace angle +{ +struct Format; +} + +namespace gl +{ +class Context; +class FramebufferState; +} // namespace gl + +namespace egl +{ +class Display; +struct Config; +struct SurfaceState; +class Thread; + +using SupportedTimestamps = angle::PackedEnumBitSet; +using SupportedCompositorTimings = angle::PackedEnumBitSet; +} // namespace egl + +namespace rx +{ +class SurfaceImpl : public FramebufferAttachmentObjectImpl +{ + public: + SurfaceImpl(const egl::SurfaceState &surfaceState); + ~SurfaceImpl() override; + virtual void destroy(const egl::Display *display) {} + + virtual egl::Error initialize(const egl::Display *display) = 0; + virtual egl::Error makeCurrent(const gl::Context *context); + virtual egl::Error unMakeCurrent(const gl::Context *context); + virtual egl::Error prepareSwap(const gl::Context *); + virtual egl::Error swap(const gl::Context *context) = 0; + virtual egl::Error swapWithDamage(const gl::Context *context, + const EGLint *rects, + EGLint n_rects); + virtual egl::Error swapWithFrameToken(const gl::Context *context, + EGLFrameTokenANGLE frameToken); + virtual egl::Error postSubBuffer(const gl::Context *context, + EGLint x, + EGLint y, + EGLint width, + EGLint height) = 0; + virtual egl::Error setPresentationTime(EGLnsecsANDROID time); + virtual egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) = 0; + virtual egl::Error bindTexImage(const gl::Context *context, + gl::Texture *texture, + EGLint buffer) = 0; + virtual egl::Error releaseTexImage(const gl::Context *context, EGLint buffer) = 0; + virtual egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) = 0; + virtual egl::Error getMscRate(EGLint *numerator, EGLint *denominator) = 0; + virtual void setSwapInterval(EGLint interval) = 0; + virtual void setFixedWidth(EGLint width); + virtual void setFixedHeight(EGLint height); + + // width and height can change with client window resizing + virtual EGLint getWidth() const = 0; + virtual EGLint getHeight() const = 0; + // Note: windows cannot be resized on Android. The approach requires + // calling vkGetPhysicalDeviceSurfaceCapabilitiesKHR. However, that is + // expensive; and there are troublesome timing issues for other parts of + // ANGLE (which cause test failures and crashes). Therefore, a + // special-Android-only path is created just for the querying of EGL_WIDTH + // and EGL_HEIGHT. + // https://issuetracker.google.com/issues/153329980 + virtual egl::Error getUserWidth(const egl::Display *display, EGLint *value) const; + virtual egl::Error getUserHeight(const egl::Display *display, EGLint *value) const; + + virtual EGLint isPostSubBufferSupported() const = 0; + virtual EGLint getSwapBehavior() const = 0; + + virtual egl::Error attachToFramebuffer(const gl::Context *context, + gl::Framebuffer *framebuffer) = 0; + virtual egl::Error detachFromFramebuffer(const gl::Context *context, + gl::Framebuffer *framebuffer) = 0; + + // Used to query color format from pbuffers created from D3D textures. + virtual const angle::Format *getD3DTextureColorFormat() const; + + // EGL_ANDROID_get_frame_timestamps + virtual void setTimestampsEnabled(bool enabled); + virtual egl::SupportedCompositorTimings getSupportedCompositorTimings() const; + virtual egl::Error getCompositorTiming(EGLint numTimestamps, + const EGLint *names, + EGLnsecsANDROID *values) const; + virtual egl::Error getNextFrameId(EGLuint64KHR *frameId) const; + virtual egl::SupportedTimestamps getSupportedTimestamps() const; + virtual egl::Error getFrameTimestamps(EGLuint64KHR frameId, + EGLint numTimestamps, + const EGLint *timestamps, + EGLnsecsANDROID *values) const; + virtual egl::Error getBufferAge(const gl::Context *context, EGLint *age); + + // EGL_ANDROID_front_buffer_auto_refresh + virtual egl::Error setAutoRefreshEnabled(bool enabled); + + // EGL_KHR_lock_surface3 + virtual egl::Error lockSurface(const egl::Display *display, + EGLint usageHint, + bool preservePixels, + uint8_t **bufferPtrOut, + EGLint *bufferPitchOut); + virtual egl::Error unlockSurface(const egl::Display *display, bool preservePixels); + virtual EGLint origin() const; + + virtual egl::Error setRenderBuffer(EGLint renderBuffer); + + protected: + const egl::SurfaceState &mState; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_SURFACEIMPL_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/SyncImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/SyncImpl.h new file mode 100644 index 0000000000..59811a62d7 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/SyncImpl.h @@ -0,0 +1,45 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// SyncImpl.h: Defines the rx::SyncImpl class. + +#ifndef LIBANGLE_RENDERER_FENCESYNCIMPL_H_ +#define LIBANGLE_RENDERER_FENCESYNCIMPL_H_ + +#include "libANGLE/Error.h" + +#include "common/angleutils.h" + +#include "angle_gl.h" + +namespace gl +{ +class Context; +} // namespace gl + +namespace rx +{ +class SyncImpl : angle::NonCopyable +{ + public: + SyncImpl() {} + virtual ~SyncImpl() {} + + virtual void onDestroy(const gl::Context *context) {} + + virtual angle::Result set(const gl::Context *context, GLenum condition, GLbitfield flags) = 0; + virtual angle::Result clientWait(const gl::Context *context, + GLbitfield flags, + GLuint64 timeout, + GLenum *outResult) = 0; + virtual angle::Result serverWait(const gl::Context *context, + GLbitfield flags, + GLuint64 timeout) = 0; + virtual angle::Result getStatus(const gl::Context *context, GLint *outResult) = 0; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_FENCESYNCIMPL_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/TextureImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/TextureImpl.cpp new file mode 100644 index 0000000000..7e69330e27 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/TextureImpl.cpp @@ -0,0 +1,200 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// TextureImpl.cpp: Defines the abstract rx::TextureImpl classes. + +#include "libANGLE/renderer/TextureImpl.h" + +namespace rx +{ +TextureImpl::TextureImpl(const gl::TextureState &state) : mState(state) {} + +TextureImpl::~TextureImpl() {} + +void TextureImpl::onDestroy(const gl::Context *context) {} + +angle::Result TextureImpl::copyTexture(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + GLenum type, + GLint sourceLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) +{ + UNREACHABLE(); + return angle::Result::Stop; +} + +angle::Result TextureImpl::copySubTexture(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Offset &destOffset, + GLint sourceLevel, + const gl::Box &sourceBox, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) +{ + UNREACHABLE(); + return angle::Result::Stop; +} + +angle::Result TextureImpl::copyRenderbufferSubData(const gl::Context *context, + const gl::Renderbuffer *srcBuffer, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth) +{ + UNREACHABLE(); + return angle::Result::Stop; +} + +angle::Result TextureImpl::copyTextureSubData(const gl::Context *context, + const gl::Texture *srcTexture, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth) +{ + UNREACHABLE(); + return angle::Result::Stop; +} + +angle::Result TextureImpl::copyCompressedTexture(const gl::Context *context, + const gl::Texture *source) +{ + UNREACHABLE(); + return angle::Result::Stop; +} + +angle::Result TextureImpl::copy3DTexture(const gl::Context *context, + gl::TextureTarget target, + GLenum internalFormat, + GLenum type, + GLint sourceLevel, + GLint destLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) +{ + UNREACHABLE(); + return angle::Result::Stop; +} + +angle::Result TextureImpl::copy3DSubTexture(const gl::Context *context, + const gl::TextureTarget target, + const gl::Offset &destOffset, + GLint sourceLevel, + GLint destLevel, + const gl::Box &srcBox, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) +{ + UNREACHABLE(); + return angle::Result::Stop; +} + +angle::Result TextureImpl::setImageExternal(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + const gl::Extents &size, + GLenum format, + GLenum type) +{ + UNREACHABLE(); + return angle::Result::Stop; +} + +angle::Result TextureImpl::setBuffer(const gl::Context *context, GLenum internalFormat) +{ + UNREACHABLE(); + return angle::Result::Stop; +} + +GLint TextureImpl::getMemorySize() const +{ + return 0; +} + +GLint TextureImpl::getLevelMemorySize(gl::TextureTarget target, GLint level) +{ + return 0; +} + +GLint TextureImpl::getNativeID() const +{ + UNREACHABLE(); + return 0; +} + +GLenum TextureImpl::getColorReadFormat(const gl::Context *context) +{ + UNREACHABLE(); + return GL_NONE; +} + +GLenum TextureImpl::getColorReadType(const gl::Context *context) +{ + UNREACHABLE(); + return GL_NONE; +} + +angle::Result TextureImpl::getTexImage(const gl::Context *context, + const gl::PixelPackState &packState, + gl::Buffer *packBuffer, + gl::TextureTarget target, + GLint level, + GLenum format, + GLenum type, + void *pixels) +{ + UNREACHABLE(); + return angle::Result::Stop; +} + +angle::Result TextureImpl::getCompressedTexImage(const gl::Context *context, + const gl::PixelPackState &packState, + gl::Buffer *packBuffer, + gl::TextureTarget target, + GLint level, + void *pixels) +{ + UNREACHABLE(); + return angle::Result::Stop; +} + +GLint TextureImpl::getRequiredExternalTextureImageUnits(const gl::Context *context) +{ + UNREACHABLE(); + return 0; +} + +angle::Result TextureImpl::onLabelUpdate(const gl::Context *context) +{ + return angle::Result::Continue; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/TextureImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/TextureImpl.h new file mode 100644 index 0000000000..368fba09c5 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/TextureImpl.h @@ -0,0 +1,254 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// TextureImpl.h: Defines the abstract rx::TextureImpl classes. + +#ifndef LIBANGLE_RENDERER_TEXTUREIMPL_H_ +#define LIBANGLE_RENDERER_TEXTUREIMPL_H_ + +#include + +#include "angle_gl.h" +#include "common/angleutils.h" +#include "libANGLE/Error.h" +#include "libANGLE/ImageIndex.h" +#include "libANGLE/Stream.h" +#include "libANGLE/Texture.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/renderer/FramebufferAttachmentObjectImpl.h" + +namespace egl +{ +class Surface; +class Image; +} // namespace egl + +namespace gl +{ +class Framebuffer; +class MemoryObject; +struct PixelUnpackState; +class TextureState; +} // namespace gl + +namespace rx +{ +class ContextImpl; + +class TextureImpl : public FramebufferAttachmentObjectImpl +{ + public: + TextureImpl(const gl::TextureState &state); + ~TextureImpl() override; + + virtual void onDestroy(const gl::Context *context); + + virtual angle::Result setImage(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + const gl::Extents &size, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels) = 0; + virtual angle::Result setSubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels) = 0; + + virtual angle::Result setCompressedImage(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + const gl::Extents &size, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) = 0; + virtual angle::Result setCompressedSubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) = 0; + + virtual angle::Result copyImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Rectangle &sourceArea, + GLenum internalFormat, + gl::Framebuffer *source) = 0; + virtual angle::Result copySubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + gl::Framebuffer *source) = 0; + + virtual angle::Result copyTexture(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + GLenum type, + GLint sourceLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source); + virtual angle::Result copySubTexture(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Offset &destOffset, + GLint sourceLevel, + const gl::Box &sourceBox, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source); + + virtual angle::Result copyRenderbufferSubData(const gl::Context *context, + const gl::Renderbuffer *srcBuffer, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth); + + virtual angle::Result copyTextureSubData(const gl::Context *context, + const gl::Texture *srcTexture, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth); + + virtual angle::Result copyCompressedTexture(const gl::Context *context, + const gl::Texture *source); + + virtual angle::Result copy3DTexture(const gl::Context *context, + gl::TextureTarget target, + GLenum internalFormat, + GLenum type, + GLint sourceLevel, + GLint destLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source); + virtual angle::Result copy3DSubTexture(const gl::Context *context, + const gl::TextureTarget target, + const gl::Offset &destOffset, + GLint sourceLevel, + GLint destLevel, + const gl::Box &srcBox, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source); + + virtual angle::Result setStorage(const gl::Context *context, + gl::TextureType type, + size_t levels, + GLenum internalFormat, + const gl::Extents &size) = 0; + + virtual angle::Result setStorageMultisample(const gl::Context *context, + gl::TextureType type, + GLsizei samples, + GLint internalformat, + const gl::Extents &size, + bool fixedSampleLocations) = 0; + + virtual angle::Result setStorageExternalMemory(const gl::Context *context, + gl::TextureType type, + size_t levels, + GLenum internalFormat, + const gl::Extents &size, + gl::MemoryObject *memoryObject, + GLuint64 offset, + GLbitfield createFlags, + GLbitfield usageFlags, + const void *imageCreateInfoPNext) = 0; + + virtual angle::Result setImageExternal(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + const gl::Extents &size, + GLenum format, + GLenum type); + + virtual angle::Result setEGLImageTarget(const gl::Context *context, + gl::TextureType type, + egl::Image *image) = 0; + + virtual angle::Result setImageExternal(const gl::Context *context, + gl::TextureType type, + egl::Stream *stream, + const egl::Stream::GLTextureDescription &desc) = 0; + + virtual angle::Result setBuffer(const gl::Context *context, GLenum internalFormat); + + virtual angle::Result generateMipmap(const gl::Context *context) = 0; + + virtual angle::Result setBaseLevel(const gl::Context *context, GLuint baseLevel) = 0; + + virtual angle::Result bindTexImage(const gl::Context *context, egl::Surface *surface) = 0; + virtual angle::Result releaseTexImage(const gl::Context *context) = 0; + + virtual angle::Result onLabelUpdate(const gl::Context *context); + + // Override if accurate native memory size information is available + virtual GLint getMemorySize() const; + virtual GLint getLevelMemorySize(gl::TextureTarget target, GLint level); + + virtual GLint getNativeID() const; + + virtual angle::Result syncState(const gl::Context *context, + const gl::Texture::DirtyBits &dirtyBits, + gl::Command source) = 0; + + virtual GLenum getColorReadFormat(const gl::Context *context); + virtual GLenum getColorReadType(const gl::Context *context); + + virtual angle::Result getTexImage(const gl::Context *context, + const gl::PixelPackState &packState, + gl::Buffer *packBuffer, + gl::TextureTarget target, + GLint level, + GLenum format, + GLenum type, + void *pixels); + + virtual angle::Result getCompressedTexImage(const gl::Context *context, + const gl::PixelPackState &packState, + gl::Buffer *packBuffer, + gl::TextureTarget target, + GLint level, + void *pixels); + + virtual GLint getRequiredExternalTextureImageUnits(const gl::Context *context); + + const gl::TextureState &getState() const { return mState; } + + protected: + const gl::TextureState &mState; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_TEXTUREIMPL_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/TransformFeedbackImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/TransformFeedbackImpl.cpp new file mode 100644 index 0000000000..183c496025 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/TransformFeedbackImpl.cpp @@ -0,0 +1,19 @@ +// +// Copyright 2022 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// TransformFeedbackImpl.cpp: Defines the abstract rx::TransformFeedbackImpl class. + +#include "libANGLE/renderer/TransformFeedbackImpl.h" + +namespace rx +{ + +angle::Result TransformFeedbackImpl::onLabelUpdate(const gl::Context *context) +{ + return angle::Result::Continue; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/TransformFeedbackImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/TransformFeedbackImpl.h new file mode 100644 index 0000000000..75ef6fdbf8 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/TransformFeedbackImpl.h @@ -0,0 +1,42 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// TransformFeedbackImpl.h: Defines the abstract rx::TransformFeedbackImpl class. + +#ifndef LIBANGLE_RENDERER_TRANSFORMFEEDBACKIMPL_H_ +#define LIBANGLE_RENDERER_TRANSFORMFEEDBACKIMPL_H_ + +#include "common/angleutils.h" +#include "libANGLE/TransformFeedback.h" + +namespace rx +{ + +class TransformFeedbackImpl : angle::NonCopyable +{ + public: + TransformFeedbackImpl(const gl::TransformFeedbackState &state) : mState(state) {} + virtual ~TransformFeedbackImpl() {} + virtual void onDestroy(const gl::Context *context) {} + + virtual angle::Result begin(const gl::Context *context, gl::PrimitiveMode primitiveMode) = 0; + virtual angle::Result end(const gl::Context *context) = 0; + virtual angle::Result pause(const gl::Context *context) = 0; + virtual angle::Result resume(const gl::Context *context) = 0; + + virtual angle::Result bindIndexedBuffer( + const gl::Context *context, + size_t index, + const gl::OffsetBindingPointer &binding) = 0; + + virtual angle::Result onLabelUpdate(const gl::Context *context); + + protected: + const gl::TransformFeedbackState &mState; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_TRANSFORMFEEDBACKIMPL_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/VertexArrayImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/VertexArrayImpl.cpp new file mode 100644 index 0000000000..b7cac20f78 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/VertexArrayImpl.cpp @@ -0,0 +1,18 @@ +// +// Copyright 2022 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// VertexArrayImpl.cpp: Implements the class methods for VertexArrayImpl. + +#include "libANGLE/renderer/VertexArrayImpl.h" + +namespace rx +{ + +angle::Result VertexArrayImpl::onLabelUpdate(const gl::Context *context) +{ + return angle::Result::Continue; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/VertexArrayImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/VertexArrayImpl.h new file mode 100644 index 0000000000..8e33c901c2 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/VertexArrayImpl.h @@ -0,0 +1,70 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// VertexAttribImpl.h: Defines the abstract rx::VertexAttribImpl class. + +#ifndef LIBANGLE_RENDERER_VERTEXARRAYIMPL_H_ +#define LIBANGLE_RENDERER_VERTEXARRAYIMPL_H_ + +#include "common/angleutils.h" +#include "libANGLE/Buffer.h" +#include "libANGLE/VertexArray.h" + +// This is a helper X macro for iterating over all dirty attribs/bindings. Useful for dirty bits. +static_assert(gl::MAX_VERTEX_ATTRIBS == 16, "Invalid max vertex attribs"); +static_assert(gl::MAX_VERTEX_ATTRIB_BINDINGS == 16, "Invalid max vertex bindings"); +#define ANGLE_VERTEX_INDEX_CASES(FUNC) \ + FUNC(0) \ + FUNC(1) \ + FUNC(2) \ + FUNC(3) \ + FUNC(4) \ + FUNC(5) FUNC(6) FUNC(7) FUNC(8) FUNC(9) FUNC(10) FUNC(11) FUNC(12) FUNC(13) FUNC(14) FUNC(15) + +namespace rx +{ +class ContextImpl; + +class VertexArrayImpl : angle::NonCopyable +{ + public: + VertexArrayImpl(const gl::VertexArrayState &state) : mState(state) {} + + // It's up to the implementation to reset the attrib and binding dirty bits. + // This is faster than the front-end having to clear all the bits after they have been scanned. + virtual angle::Result syncState(const gl::Context *context, + const gl::VertexArray::DirtyBits &dirtyBits, + gl::VertexArray::DirtyAttribBitsArray *attribBits, + gl::VertexArray::DirtyBindingBitsArray *bindingBits); + + virtual void destroy(const gl::Context *context) {} + virtual ~VertexArrayImpl() {} + + const gl::VertexArrayState &getState() const { return mState; } + + void setContentsObservers(gl::VertexArrayBufferContentsObservers *observers) + { + mContentsObservers = observers; + } + + virtual angle::Result onLabelUpdate(const gl::Context *context); + + protected: + const gl::VertexArrayState &mState; + gl::VertexArrayBufferContentsObservers *mContentsObservers = nullptr; +}; + +inline angle::Result VertexArrayImpl::syncState(const gl::Context *context, + const gl::VertexArray::DirtyBits &dirtyBits, + gl::VertexArray::DirtyAttribBitsArray *attribBits, + gl::VertexArray::DirtyBindingBitsArray *bindingBits) +{ + return angle::Result::Continue; +} + +} // namespace rx + +#endif // LIBANGLE_RENDERER_VERTEXARRAYIMPL_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/copyvertex.h b/gfx/angle/checkout/src/libANGLE/renderer/copyvertex.h new file mode 100644 index 0000000000..54624bb29b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/copyvertex.h @@ -0,0 +1,80 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// copyvertex.h: Defines vertex buffer copying and conversion functions + +#ifndef LIBANGLE_RENDERER_COPYVERTEX_H_ +#define LIBANGLE_RENDERER_COPYVERTEX_H_ + +#include "common/mathutil.h" + +namespace rx +{ + +using VertexCopyFunction = void (*)(const uint8_t *input, + size_t stride, + size_t count, + uint8_t *output); + +// 'alphaDefaultValueBits' gives the default value for the alpha channel (4th component) +template +void CopyNativeVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output); + +template +void Copy8SintTo16SintVertexData(const uint8_t *input, + size_t stride, + size_t count, + uint8_t *output); + +template +void Copy8SnormTo16SnormVertexData(const uint8_t *input, + size_t stride, + size_t count, + uint8_t *output); + +template +void Copy32FixedTo32FVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output); + +template +void CopyToFloatVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output); + +template +void Copy32FTo16FVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output); + +void CopyXYZ32FToXYZ9E5(const uint8_t *input, size_t stride, size_t count, uint8_t *output); + +void CopyXYZ32FToX11Y11B10F(const uint8_t *input, size_t stride, size_t count, uint8_t *output); + +template +void CopyXYZ10W2ToXYZWFloatVertexData(const uint8_t *input, + size_t stride, + size_t count, + uint8_t *output); + +template +void CopyXYZ10ToXYZWFloatVertexData(const uint8_t *input, + size_t stride, + size_t count, + uint8_t *output); + +template +void CopyW2XYZ10ToXYZWFloatVertexData(const uint8_t *input, + size_t stride, + size_t count, + uint8_t *output); + +} // namespace rx + +#include "copyvertex.inc.h" + +#endif // LIBANGLE_RENDERER_COPYVERTEX_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/copyvertex.inc.h b/gfx/angle/checkout/src/libANGLE/renderer/copyvertex.inc.h new file mode 100644 index 0000000000..3f1844e91c --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/copyvertex.inc.h @@ -0,0 +1,635 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// copyvertex.inc.h: Implementation of vertex buffer copying and conversion functions + +namespace rx +{ + +// Returns an aligned buffer to read the input from +template +inline const T *GetAlignedOffsetInput(const T *offsetInput, T *alignedElement) +{ + if (reinterpret_cast(offsetInput) % sizeof(T) != 0) + { + // Applications may pass in arbitrarily aligned buffers as input. + // Certain architectures have restrictions regarding unaligned reads. Specifically, we crash + // on armeabi-v7a devices with a SIGBUS error when performing such operations. arm64 and + // x86-64 devices do not appear to have such issues. + // + // The workaround is to detect if the input buffer is unaligned and if so, perform a + // byte-wise copy of the unaligned portion and a memcpy of the rest of the buffer. + uint8_t *alignedBuffer = reinterpret_cast(&alignedElement[0]); + uintptr_t unalignedInputStartAddress = reinterpret_cast(offsetInput); + constexpr size_t kAlignmentMinusOne = sizeof(T) - 1; + uintptr_t alignedInputStartAddress = + (reinterpret_cast(offsetInput) + kAlignmentMinusOne) & ~(kAlignmentMinusOne); + ASSERT(alignedInputStartAddress >= unalignedInputStartAddress); + + const size_t totalBytesToCopy = sizeof(T) * inputComponentCount; + const size_t unalignedBytesToCopy = alignedInputStartAddress - unalignedInputStartAddress; + ASSERT(totalBytesToCopy >= unalignedBytesToCopy); + + // byte-wise copy of unaligned portion + for (size_t i = 0; i < unalignedBytesToCopy; i++) + { + alignedBuffer[i] = reinterpret_cast(&offsetInput[0])[i]; + } + + // memcpy remaining buffer + memcpy(&alignedBuffer[unalignedBytesToCopy], + &reinterpret_cast(&offsetInput[0])[unalignedBytesToCopy], + totalBytesToCopy - unalignedBytesToCopy); + + return alignedElement; + } + else + { + return offsetInput; + } +} + +template +inline void CopyNativeVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output) +{ + const size_t attribSize = sizeof(T) * inputComponentCount; + + if (attribSize == stride && inputComponentCount == outputComponentCount) + { + memcpy(output, input, count * attribSize); + return; + } + + if (inputComponentCount == outputComponentCount) + { + for (size_t i = 0; i < count; i++) + { + const T *offsetInput = reinterpret_cast(input + (i * stride)); + T offsetInputAligned[inputComponentCount]; + offsetInput = + GetAlignedOffsetInput(offsetInput, &offsetInputAligned[0]); + + T *offsetOutput = reinterpret_cast(output) + i * outputComponentCount; + + memcpy(offsetOutput, offsetInput, attribSize); + } + return; + } + + const T defaultAlphaValue = gl::bitCast(alphaDefaultValueBits); + const size_t lastNonAlphaOutputComponent = std::min(outputComponentCount, 3); + + for (size_t i = 0; i < count; i++) + { + const T *offsetInput = reinterpret_cast(input + (i * stride)); + T offsetInputAligned[inputComponentCount]; + ASSERT(sizeof(offsetInputAligned) == attribSize); + offsetInput = + GetAlignedOffsetInput(offsetInput, &offsetInputAligned[0]); + + T *offsetOutput = reinterpret_cast(output) + i * outputComponentCount; + + memcpy(offsetOutput, offsetInput, attribSize); + + if (inputComponentCount < lastNonAlphaOutputComponent) + { + // Set the remaining G/B channels to 0. + size_t numComponents = (lastNonAlphaOutputComponent - inputComponentCount); + memset(&offsetOutput[inputComponentCount], 0, numComponents * sizeof(T)); + } + + if (inputComponentCount < outputComponentCount && outputComponentCount == 4) + { + // Set the remaining alpha channel to the defaultAlphaValue. + offsetOutput[3] = defaultAlphaValue; + } + } +} + +template +inline void Copy8SintTo16SintVertexData(const uint8_t *input, + size_t stride, + size_t count, + uint8_t *output) +{ + const size_t lastNonAlphaOutputComponent = std::min(outputComponentCount, 3); + + for (size_t i = 0; i < count; i++) + { + const GLbyte *offsetInput = reinterpret_cast(input + i * stride); + GLshort *offsetOutput = reinterpret_cast(output) + i * outputComponentCount; + + for (size_t j = 0; j < inputComponentCount; j++) + { + offsetOutput[j] = static_cast(offsetInput[j]); + } + + for (size_t j = inputComponentCount; j < lastNonAlphaOutputComponent; j++) + { + // Set remaining G/B channels to 0. + offsetOutput[j] = 0; + } + + if (inputComponentCount < outputComponentCount && outputComponentCount == 4) + { + // On integer formats, we must set the Alpha channel to 1 if it's unused. + offsetOutput[3] = 1; + } + } +} + +template +inline void Copy8SnormTo16SnormVertexData(const uint8_t *input, + size_t stride, + size_t count, + uint8_t *output) +{ + for (size_t i = 0; i < count; i++) + { + const GLbyte *offsetInput = reinterpret_cast(input + i * stride); + GLshort *offsetOutput = reinterpret_cast(output) + i * outputComponentCount; + + for (size_t j = 0; j < inputComponentCount; j++) + { + // The original GLbyte value ranges from -128 to +127 (INT8_MAX). + // When converted to GLshort, the value must be scaled to between -32768 and +32767 + // (INT16_MAX). + if (offsetInput[j] > 0) + { + offsetOutput[j] = + offsetInput[j] << 8 | offsetInput[j] << 1 | ((offsetInput[j] & 0x40) >> 6); + } + else + { + offsetOutput[j] = offsetInput[j] << 8; + } + } + + for (size_t j = inputComponentCount; j < std::min(outputComponentCount, 3); j++) + { + // Set remaining G/B channels to 0. + offsetOutput[j] = 0; + } + + if (inputComponentCount < outputComponentCount && outputComponentCount == 4) + { + // On normalized formats, we must set the Alpha channel to the max value if it's unused. + offsetOutput[3] = INT16_MAX; + } + } +} + +template +inline void Copy32FixedTo32FVertexData(const uint8_t *input, + size_t stride, + size_t count, + uint8_t *output) +{ + static const float divisor = 1.0f / (1 << 16); + + for (size_t i = 0; i < count; i++) + { + const uint8_t *offsetInput = input + i * stride; + float *offsetOutput = reinterpret_cast(output) + i * outputComponentCount; + + // GLfixed access must be 4-byte aligned on arm32, input and stride sometimes are not + if (reinterpret_cast(offsetInput) % sizeof(GLfixed) == 0) + { + for (size_t j = 0; j < inputComponentCount; j++) + { + offsetOutput[j] = + static_cast(reinterpret_cast(offsetInput)[j]) * divisor; + } + } + else + { + for (size_t j = 0; j < inputComponentCount; j++) + { + GLfixed alignedInput; + memcpy(&alignedInput, offsetInput + j * sizeof(GLfixed), sizeof(GLfixed)); + offsetOutput[j] = static_cast(alignedInput) * divisor; + } + } + + // 4-component output formats would need special padding in the alpha channel. + static_assert(!(inputComponentCount < 4 && outputComponentCount == 4), + "An inputComponentCount less than 4 and an outputComponentCount equal to 4 " + "is not supported."); + + for (size_t j = inputComponentCount; j < outputComponentCount; j++) + { + offsetOutput[j] = 0.0f; + } + } +} + +template +inline void CopyToFloatVertexData(const uint8_t *input, + size_t stride, + size_t count, + uint8_t *output) +{ + typedef std::numeric_limits NL; + typedef typename std::conditional::type outputType; + + for (size_t i = 0; i < count; i++) + { + const T *offsetInput = reinterpret_cast(input + (stride * i)); + outputType *offsetOutput = + reinterpret_cast(output) + i * outputComponentCount; + + T offsetInputAligned[inputComponentCount]; + offsetInput = + GetAlignedOffsetInput(offsetInput, &offsetInputAligned[0]); + + for (size_t j = 0; j < inputComponentCount; j++) + { + float result = 0; + + if (normalized) + { + if (NL::is_signed) + { + result = static_cast(offsetInput[j]) / static_cast(NL::max()); + result = result >= -1.0f ? result : -1.0f; + } + else + { + result = static_cast(offsetInput[j]) / static_cast(NL::max()); + } + } + else + { + result = static_cast(offsetInput[j]); + } + + if (toHalf) + { + offsetOutput[j] = gl::float32ToFloat16(result); + } + else + { + offsetOutput[j] = static_cast(result); + } + } + + for (size_t j = inputComponentCount; j < outputComponentCount; j++) + { + offsetOutput[j] = 0; + } + + if (inputComponentCount < 4 && outputComponentCount == 4) + { + if (toHalf) + { + offsetOutput[3] = gl::Float16One; + } + else + { + offsetOutput[3] = static_cast(gl::Float32One); + } + } + } +} + +template +void Copy32FTo16FVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output) +{ + const unsigned short kZero = gl::float32ToFloat16(0.0f); + const unsigned short kOne = gl::float32ToFloat16(1.0f); + + for (size_t i = 0; i < count; i++) + { + const float *offsetInput = reinterpret_cast(input + (stride * i)); + unsigned short *offsetOutput = + reinterpret_cast(output) + i * outputComponentCount; + + for (size_t j = 0; j < inputComponentCount; j++) + { + offsetOutput[j] = gl::float32ToFloat16(offsetInput[j]); + } + + for (size_t j = inputComponentCount; j < outputComponentCount; j++) + { + offsetOutput[j] = (j == 3) ? kOne : kZero; + } + } +} + +inline void CopyXYZ32FToXYZ9E5(const uint8_t *input, size_t stride, size_t count, uint8_t *output) +{ + for (size_t i = 0; i < count; i++) + { + const float *offsetInput = reinterpret_cast(input + (stride * i)); + unsigned int *offsetOutput = reinterpret_cast(output) + i; + + *offsetOutput = gl::convertRGBFloatsTo999E5(offsetInput[0], offsetInput[1], offsetInput[2]); + } +} + +inline void CopyXYZ32FToX11Y11B10F(const uint8_t *input, + size_t stride, + size_t count, + uint8_t *output) +{ + for (size_t i = 0; i < count; i++) + { + const float *offsetInput = reinterpret_cast(input + (stride * i)); + unsigned int *offsetOutput = reinterpret_cast(output) + i; + + *offsetOutput = gl::float32ToFloat11(offsetInput[0]) << 0 | + gl::float32ToFloat11(offsetInput[1]) << 11 | + gl::float32ToFloat10(offsetInput[2]) << 22; + } +} + +namespace priv +{ + +template +static inline void CopyPackedRGB(uint32_t data, uint8_t *output) +{ + const uint32_t rgbSignMask = 0x200; // 1 set at the 9 bit + const uint32_t negativeMask = 0xFFFFFC00; // All bits from 10 to 31 set to 1 + + if (toFloat || toHalf) + { + GLfloat finalValue = static_cast(data); + if (isSigned) + { + if (data & rgbSignMask) + { + int negativeNumber = data | negativeMask; + finalValue = static_cast(negativeNumber); + } + + if (normalized) + { + const int32_t maxValue = 0x1FF; // 1 set in bits 0 through 8 + const int32_t minValue = 0xFFFFFE01; // Inverse of maxValue + + // A 10-bit two's complement number has the possibility of being minValue - 1 but + // OpenGL's normalization rules dictate that it should be clamped to minValue in + // this case. + if (finalValue < minValue) + { + finalValue = minValue; + } + + const int32_t halfRange = (maxValue - minValue) >> 1; + finalValue = ((finalValue - minValue) / halfRange) - 1.0f; + } + } + else + { + if (normalized) + { + const uint32_t maxValue = 0x3FF; // 1 set in bits 0 through 9 + finalValue /= static_cast(maxValue); + } + } + + if (toHalf) + { + *reinterpret_cast(output) = gl::float32ToFloat16(finalValue); + } + else + { + *reinterpret_cast(output) = finalValue; + } + } + else + { + if (isSigned) + { + GLshort *intOutput = reinterpret_cast(output); + + if (data & rgbSignMask) + { + *intOutput = static_cast(data | negativeMask); + } + else + { + *intOutput = static_cast(data); + } + } + else + { + GLushort *uintOutput = reinterpret_cast(output); + *uintOutput = static_cast(data); + } + } +} + +template +inline void CopyPackedAlpha(uint32_t data, uint8_t *output) +{ + ASSERT(data >= 0 && data <= 3); + + if (toFloat || toHalf) + { + GLfloat finalValue = 0; + if (isSigned) + { + if (normalized) + { + switch (data) + { + case 0x0: + finalValue = 0.0f; + break; + case 0x1: + finalValue = 1.0f; + break; + case 0x2: + finalValue = -1.0f; + break; + case 0x3: + finalValue = -1.0f; + break; + default: + UNREACHABLE(); + } + } + else + { + switch (data) + { + case 0x0: + finalValue = 0.0f; + break; + case 0x1: + finalValue = 1.0f; + break; + case 0x2: + finalValue = -2.0f; + break; + case 0x3: + finalValue = -1.0f; + break; + default: + UNREACHABLE(); + } + } + } + else + { + if (normalized) + { + finalValue = data / 3.0f; + } + else + { + finalValue = static_cast(data); + } + } + + if (toHalf) + { + *reinterpret_cast(output) = gl::float32ToFloat16(finalValue); + } + else + { + *reinterpret_cast(output) = finalValue; + } + } + else + { + if (isSigned) + { + GLshort *intOutput = reinterpret_cast(output); + switch (data) + { + case 0x0: + *intOutput = 0; + break; + case 0x1: + *intOutput = 1; + break; + case 0x2: + *intOutput = -2; + break; + case 0x3: + *intOutput = -1; + break; + default: + UNREACHABLE(); + } + } + else + { + *reinterpret_cast(output) = static_cast(data); + } + } +} + +} // namespace priv + +template +inline void CopyXYZ10W2ToXYZWFloatVertexData(const uint8_t *input, + size_t stride, + size_t count, + uint8_t *output) +{ + const size_t outputComponentSize = toFloat && !toHalf ? 4 : 2; + const size_t componentCount = 4; + + const uint32_t rgbMask = 0x3FF; // 1 set in bits 0 through 9 + const size_t redShift = 0; // red is bits 0 through 9 + const size_t greenShift = 10; // green is bits 10 through 19 + const size_t blueShift = 20; // blue is bits 20 through 29 + + const uint32_t alphaMask = 0x3; // 1 set in bits 0 and 1 + const size_t alphaShift = 30; // Alpha is the 30 and 31 bits + + for (size_t i = 0; i < count; i++) + { + GLuint packedValue = *reinterpret_cast(input + (i * stride)); + uint8_t *offsetOutput = output + (i * outputComponentSize * componentCount); + + priv::CopyPackedRGB( + (packedValue >> redShift) & rgbMask, offsetOutput + (0 * outputComponentSize)); + priv::CopyPackedRGB( + (packedValue >> greenShift) & rgbMask, offsetOutput + (1 * outputComponentSize)); + priv::CopyPackedRGB( + (packedValue >> blueShift) & rgbMask, offsetOutput + (2 * outputComponentSize)); + priv::CopyPackedAlpha( + (packedValue >> alphaShift) & alphaMask, offsetOutput + (3 * outputComponentSize)); + } +} + +template +inline void CopyXYZ10ToXYZWFloatVertexData(const uint8_t *input, + size_t stride, + size_t count, + uint8_t *output) +{ + const size_t outputComponentSize = toHalf ? 2 : 4; + const size_t componentCount = 4; + + const uint32_t rgbMask = 0x3FF; // 1 set in bits 0 through 9 + const size_t redShift = 22; // red is bits 22 through 31 + const size_t greenShift = 12; // green is bits 12 through 21 + const size_t blueShift = 2; // blue is bits 2 through 11 + + const uint32_t alphaDefaultValueBits = normalized ? (isSigned ? 0x1 : 0x3) : 0x1; + + for (size_t i = 0; i < count; i++) + { + GLuint packedValue = *reinterpret_cast(input + (i * stride)); + uint8_t *offsetOutput = output + (i * outputComponentSize * componentCount); + + priv::CopyPackedRGB( + (packedValue >> redShift) & rgbMask, offsetOutput + (0 * outputComponentSize)); + priv::CopyPackedRGB( + (packedValue >> greenShift) & rgbMask, offsetOutput + (1 * outputComponentSize)); + priv::CopyPackedRGB( + (packedValue >> blueShift) & rgbMask, offsetOutput + (2 * outputComponentSize)); + priv::CopyPackedAlpha( + alphaDefaultValueBits, offsetOutput + (3 * outputComponentSize)); + } +} + +template +inline void CopyW2XYZ10ToXYZWFloatVertexData(const uint8_t *input, + size_t stride, + size_t count, + uint8_t *output) +{ + const size_t outputComponentSize = toHalf ? 2 : 4; + const size_t componentCount = 4; + + const uint32_t rgbMask = 0x3FF; // 1 set in bits 0 through 9 + const size_t redShift = 22; // red is bits 22 through 31 + const size_t greenShift = 12; // green is bits 12 through 21 + const size_t blueShift = 2; // blue is bits 2 through 11 + + const uint32_t alphaMask = 0x3; // 1 set in bits 0 and 1 + const size_t alphaShift = 0; // Alpha is the 30 and 31 bits + + for (size_t i = 0; i < count; i++) + { + GLuint packedValue = *reinterpret_cast(input + (i * stride)); + uint8_t *offsetOutput = output + (i * outputComponentSize * componentCount); + + priv::CopyPackedRGB( + (packedValue >> redShift) & rgbMask, offsetOutput + (0 * outputComponentSize)); + priv::CopyPackedRGB( + (packedValue >> greenShift) & rgbMask, offsetOutput + (1 * outputComponentSize)); + priv::CopyPackedRGB( + (packedValue >> blueShift) & rgbMask, offsetOutput + (2 * outputComponentSize)); + priv::CopyPackedAlpha( + (packedValue >> alphaShift) & alphaMask, offsetOutput + (3 * outputComponentSize)); + } +} +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/BufferD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/BufferD3D.cpp new file mode 100644 index 0000000000..464bd6d4a8 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/BufferD3D.cpp @@ -0,0 +1,191 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// BufferD3D.cpp Defines common functionality between the Buffer9 and Buffer11 classes. + +#include "libANGLE/renderer/d3d/BufferD3D.h" + +#include "common/mathutil.h" +#include "common/utilities.h" +#include "libANGLE/renderer/d3d/IndexBuffer.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" +#include "libANGLE/renderer/d3d/VertexBuffer.h" + +namespace rx +{ + +unsigned int BufferD3D::mNextSerial = 1; + +BufferD3D::BufferD3D(const gl::BufferState &state, BufferFactoryD3D *factory) + : BufferImpl(state), + mFactory(factory), + mStaticIndexBuffer(nullptr), + mStaticBufferCacheTotalSize(0), + mStaticVertexBufferOutOfDate(false), + mUnmodifiedDataUse(0), + mUsage(D3DBufferUsage::STATIC) +{ + updateSerial(); +} + +BufferD3D::~BufferD3D() +{ + SafeDelete(mStaticIndexBuffer); +} + +void BufferD3D::emptyStaticBufferCache() +{ + mStaticVertexBuffers.clear(); + mStaticBufferCacheTotalSize = 0; +} + +void BufferD3D::updateSerial() +{ + mSerial = mNextSerial++; +} + +void BufferD3D::updateD3DBufferUsage(const gl::Context *context, gl::BufferUsage usage) +{ + switch (usage) + { + case gl::BufferUsage::StaticCopy: + case gl::BufferUsage::StaticDraw: + case gl::BufferUsage::StaticRead: + case gl::BufferUsage::DynamicCopy: + case gl::BufferUsage::DynamicRead: + case gl::BufferUsage::StreamCopy: + case gl::BufferUsage::StreamRead: + mUsage = D3DBufferUsage::STATIC; + initializeStaticData(context); + break; + + case gl::BufferUsage::DynamicDraw: + case gl::BufferUsage::StreamDraw: + mUsage = D3DBufferUsage::DYNAMIC; + break; + default: + UNREACHABLE(); + } +} + +void BufferD3D::initializeStaticData(const gl::Context *context) +{ + if (mStaticVertexBuffers.empty()) + { + StaticVertexBufferInterface *newStaticBuffer = new StaticVertexBufferInterface(mFactory); + mStaticVertexBuffers.push_back( + std::unique_ptr(newStaticBuffer)); + } + if (!mStaticIndexBuffer) + { + mStaticIndexBuffer = new StaticIndexBufferInterface(mFactory); + } +} + +StaticIndexBufferInterface *BufferD3D::getStaticIndexBuffer() +{ + return mStaticIndexBuffer; +} + +StaticVertexBufferInterface *BufferD3D::getStaticVertexBuffer(const gl::VertexAttribute &attribute, + const gl::VertexBinding &binding) +{ + if (mStaticVertexBuffers.empty()) + { + // Early out if there aren't any static buffers at all + return nullptr; + } + + // Early out, the attribute can be added to mStaticVertexBuffer. + if (mStaticVertexBuffers.size() == 1 && mStaticVertexBuffers[0]->empty()) + { + return mStaticVertexBuffers[0].get(); + } + + // Cache size limiting: track the total allocated buffer sizes. + size_t currentTotalSize = 0; + + // At this point, see if any of the existing static buffers contains the attribute data + // If there is a cached static buffer that already contains the attribute, then return it + for (const auto &staticBuffer : mStaticVertexBuffers) + { + if (staticBuffer->matchesAttribute(attribute, binding)) + { + return staticBuffer.get(); + } + + currentTotalSize += staticBuffer->getBufferSize(); + } + + // Cache size limiting: Clean-up threshold is four times the base buffer size, with a minimum. + ASSERT(getSize() < std::numeric_limits::max() / 4u); + size_t sizeThreshold = std::max(getSize() * 4u, static_cast(0x1000u)); + + // If we're past the threshold, clear the buffer cache. Note that this will release buffers + // that are currenly bound, and in an edge case can even translate the same attribute twice + // in the same draw call. It will not delete currently bound buffers, however, because they + // are ref counted. + if (currentTotalSize > sizeThreshold) + { + emptyStaticBufferCache(); + } + + // At this point, we must create a new static buffer for the attribute data. + StaticVertexBufferInterface *newStaticBuffer = new StaticVertexBufferInterface(mFactory); + newStaticBuffer->setAttribute(attribute, binding); + mStaticVertexBuffers.push_back(std::unique_ptr(newStaticBuffer)); + return newStaticBuffer; +} + +void BufferD3D::invalidateStaticData(const gl::Context *context) +{ + emptyStaticBufferCache(); + + if (mStaticIndexBuffer && mStaticIndexBuffer->getBufferSize() != 0) + { + SafeDelete(mStaticIndexBuffer); + } + + // If the buffer was created with a static usage then we recreate the static + // buffers so that they are populated the next time we use this buffer. + if (mUsage == D3DBufferUsage::STATIC) + { + initializeStaticData(context); + } + + mUnmodifiedDataUse = 0; +} + +// Creates static buffers if sufficient used data has been left unmodified +void BufferD3D::promoteStaticUsage(const gl::Context *context, size_t dataSize) +{ + if (mUsage == D3DBufferUsage::DYNAMIC) + { + // Note: This is not a safe math operation. 'dataSize' can come from the app. + mUnmodifiedDataUse += dataSize; + + if (mUnmodifiedDataUse > 3 * getSize()) + { + updateD3DBufferUsage(context, gl::BufferUsage::StaticDraw); + } + } +} + +angle::Result BufferD3D::getIndexRange(const gl::Context *context, + gl::DrawElementsType type, + size_t offset, + size_t count, + bool primitiveRestartEnabled, + gl::IndexRange *outRange) +{ + const uint8_t *data = nullptr; + ANGLE_TRY(getData(context, &data)); + + *outRange = gl::ComputeIndexRange(type, data + offset, count, primitiveRestartEnabled); + return angle::Result::Continue; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/BufferD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/BufferD3D.h new file mode 100644 index 0000000000..19ea78c6eb --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/BufferD3D.h @@ -0,0 +1,89 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// BufferD3D.h: Defines the rx::BufferD3D class, an implementation of BufferImpl. + +#ifndef LIBANGLE_RENDERER_D3D_BUFFERD3D_H_ +#define LIBANGLE_RENDERER_D3D_BUFFERD3D_H_ + +#include "libANGLE/angletypes.h" +#include "libANGLE/renderer/BufferImpl.h" + +#include +#include + +namespace gl +{ +struct VertexAttribute; +class VertexBinding; +} // namespace gl + +namespace rx +{ +class BufferFactoryD3D; +class StaticIndexBufferInterface; +class StaticVertexBufferInterface; + +enum class D3DBufferUsage +{ + STATIC, + DYNAMIC, +}; + +class BufferD3D : public BufferImpl +{ + public: + BufferD3D(const gl::BufferState &state, BufferFactoryD3D *factory); + ~BufferD3D() override; + + unsigned int getSerial() const { return mSerial; } + + virtual size_t getSize() const = 0; + virtual bool supportsDirectBinding() const = 0; + virtual angle::Result markTransformFeedbackUsage(const gl::Context *context) = 0; + virtual angle::Result getData(const gl::Context *context, const uint8_t **outData) = 0; + + // Warning: you should ensure binding really matches attrib.bindingIndex before using this + // function. + StaticVertexBufferInterface *getStaticVertexBuffer(const gl::VertexAttribute &attribute, + const gl::VertexBinding &binding); + StaticIndexBufferInterface *getStaticIndexBuffer(); + + virtual void initializeStaticData(const gl::Context *context); + virtual void invalidateStaticData(const gl::Context *context); + + void promoteStaticUsage(const gl::Context *context, size_t dataSize); + + angle::Result getIndexRange(const gl::Context *context, + gl::DrawElementsType type, + size_t offset, + size_t count, + bool primitiveRestartEnabled, + gl::IndexRange *outRange) override; + + BufferFactoryD3D *getFactory() const { return mFactory; } + D3DBufferUsage getUsage() const { return mUsage; } + + protected: + void updateSerial(); + void updateD3DBufferUsage(const gl::Context *context, gl::BufferUsage usage); + void emptyStaticBufferCache(); + + BufferFactoryD3D *mFactory; + unsigned int mSerial; + static unsigned int mNextSerial; + + std::vector> mStaticVertexBuffers; + StaticIndexBufferInterface *mStaticIndexBuffer; + unsigned int mStaticBufferCacheTotalSize; + unsigned int mStaticVertexBufferOutOfDate; + size_t mUnmodifiedDataUse; + D3DBufferUsage mUsage; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_BUFFERD3D_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/CompilerD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/CompilerD3D.cpp new file mode 100644 index 0000000000..4656cf4d80 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/CompilerD3D.cpp @@ -0,0 +1,24 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// CompilerD3D: +// Implementation of the D3D compiler methods. +// + +#include "libANGLE/renderer/d3d/CompilerD3D.h" + +namespace rx +{ + +CompilerD3D::CompilerD3D(ShShaderOutput translatorOutputType) + : mTranslatorOutputType(translatorOutputType) +{} + +ShShaderOutput CompilerD3D::getTranslatorOutputType() const +{ + return mTranslatorOutputType; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/CompilerD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/CompilerD3D.h new file mode 100644 index 0000000000..3e1d01a0b9 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/CompilerD3D.h @@ -0,0 +1,32 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// CompilerD3D.h: Defines the rx::CompilerD3D class, an implementation of rx::CompilerImpl. + +#ifndef LIBANGLE_RENDERER_COMPILERD3D_H_ +#define LIBANGLE_RENDERER_COMPILERD3D_H_ + +#include "libANGLE/renderer/CompilerImpl.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" + +namespace rx +{ + +class CompilerD3D : public CompilerImpl +{ + public: + CompilerD3D(ShShaderOutput translatorOutputType); + ~CompilerD3D() override {} + + ShShaderOutput getTranslatorOutputType() const override; + + private: + ShShaderOutput mTranslatorOutputType; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_COMPILERD3D_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/ContextD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ContextD3D.h new file mode 100644 index 0000000000..d563672e67 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ContextD3D.h @@ -0,0 +1,24 @@ +// +// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ContextD3D: Shared common class for Context9 and Context11. + +#ifndef LIBANGLE_RENDERER_CONTEXTD3D_H_ +#define LIBANGLE_RENDERER_CONTEXTD3D_H_ + +#include "libANGLE/renderer/ContextImpl.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" + +namespace rx +{ +class ContextD3D : public ContextImpl, public d3d::Context +{ + public: + ContextD3D(const gl::State &state, gl::ErrorSet *errorSet) : ContextImpl(state, errorSet) {} + ~ContextD3D() override {} +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_CONTEXTD3D_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/DeviceD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DeviceD3D.cpp new file mode 100644 index 0000000000..79dfb094e3 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DeviceD3D.cpp @@ -0,0 +1,84 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// DeviceD3D.cpp: D3D implementation of egl::Device + +#include "libANGLE/renderer/d3d/DeviceD3D.h" + +#include "libANGLE/Device.h" +#include "libANGLE/Display.h" + +#include + +namespace rx +{ + +DeviceD3D::DeviceD3D(GLint deviceType, void *nativeDevice) + : mDevice(nativeDevice), mDeviceType(deviceType), mIsInitialized(false) +{} + +DeviceD3D::~DeviceD3D() +{ +#if defined(ANGLE_ENABLE_D3D11) + if (mIsInitialized && mDeviceType == EGL_D3D11_DEVICE_ANGLE) + { + // DeviceD3D holds a ref to an externally-sourced D3D11 device. We must release it. + ID3D11Device *device = static_cast(mDevice); + device->Release(); + } +#endif +} + +egl::Error DeviceD3D::getAttribute(const egl::Display *display, EGLint attribute, void **outValue) +{ + ASSERT(mIsInitialized); + ANGLE_UNUSED_VARIABLE(display); + // Validated at higher levels. + ASSERT(getType() == attribute); + *outValue = mDevice; + return egl::NoError(); +} + +egl::Error DeviceD3D::initialize() +{ + ASSERT(!mIsInitialized); + +#if defined(ANGLE_ENABLE_D3D11) + if (mDeviceType == EGL_D3D11_DEVICE_ANGLE) + { + // Validate the device + IUnknown *iunknown = static_cast(mDevice); + + ID3D11Device *d3dDevice = nullptr; + HRESULT hr = + iunknown->QueryInterface(__uuidof(ID3D11Device), reinterpret_cast(&d3dDevice)); + if (FAILED(hr)) + { + return egl::EglBadAttribute() << "Invalid D3D device passed into EGLDeviceEXT"; + } + + // The QI to ID3D11Device adds a ref to the D3D11 device. + // Deliberately don't release the ref here, so that the DeviceD3D holds a ref to the + // D3D11 device. + } +#endif + + mIsInitialized = true; + + return egl::NoError(); +} + +EGLint DeviceD3D::getType() +{ + return mDeviceType; +} + +void DeviceD3D::generateExtensions(egl::DeviceExtensions *outExtensions) const +{ + outExtensions->deviceD3D = true; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/DeviceD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DeviceD3D.h new file mode 100644 index 0000000000..c169eb7de5 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DeviceD3D.h @@ -0,0 +1,39 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// DeviceD3D.h: D3D implementation of egl::Device + +#ifndef LIBANGLE_RENDERER_D3D_DEVICED3D_H_ +#define LIBANGLE_RENDERER_D3D_DEVICED3D_H_ + +#include "libANGLE/Device.h" +#include "libANGLE/renderer/DeviceImpl.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" + +namespace rx +{ +class DeviceD3D : public DeviceImpl +{ + public: + DeviceD3D(EGLint deviceType, void *nativeDevice); + ~DeviceD3D() override; + + egl::Error initialize() override; + egl::Error getAttribute(const egl::Display *display, + EGLint attribute, + void **outValue) override; + EGLint getType() override; + void generateExtensions(egl::DeviceExtensions *outExtensions) const override; + + private: + void *mDevice; + EGLint mDeviceType; + bool mIsInitialized; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_DEVICED3D_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/DisplayD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DisplayD3D.cpp new file mode 100644 index 0000000000..35216fd4d2 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DisplayD3D.cpp @@ -0,0 +1,462 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// DisplayD3D.cpp: D3D implementation of egl::Display + +#include "libANGLE/renderer/d3d/DisplayD3D.h" + +#include + +#include "libANGLE/Config.h" +#include "libANGLE/Context.h" +#include "libANGLE/Display.h" +#include "libANGLE/Surface.h" +#include "libANGLE/Thread.h" +#include "libANGLE/histogram_macros.h" +#include "libANGLE/renderer/d3d/DeviceD3D.h" +#include "libANGLE/renderer/d3d/EGLImageD3D.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" +#include "libANGLE/renderer/d3d/SurfaceD3D.h" +#include "libANGLE/renderer/d3d/SwapChainD3D.h" + +#if !defined(ANGLE_DEFAULT_D3D11) +// Enables use of the Direct3D 11 API for a default display, when available +# define ANGLE_DEFAULT_D3D11 1 +#endif + +namespace rx +{ + +using CreateRendererD3DFunction = RendererD3D *(*)(egl::Display *); + +egl::Error CreateRendererD3D(egl::Display *display, RendererD3D **outRenderer) +{ + ASSERT(outRenderer != nullptr); + + std::vector rendererCreationFunctions; + + if (display->getPlatform() == EGL_PLATFORM_ANGLE_ANGLE) + { + const auto &attribMap = display->getAttributeMap(); + EGLNativeDisplayType nativeDisplay = display->getNativeDisplayId(); + + EGLint requestedDisplayType = static_cast( + attribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE)); + +#if defined(ANGLE_ENABLE_D3D11) + const auto addD3D11 = nativeDisplay == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE || + nativeDisplay == EGL_D3D11_ONLY_DISPLAY_ANGLE || + requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE; +#endif + +#if defined(ANGLE_ENABLE_D3D9) + const auto addD3D9 = nativeDisplay == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE || + requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE; +#endif + +#if ANGLE_DEFAULT_D3D11 +# if defined(ANGLE_ENABLE_D3D11) + if (addD3D11) + { + rendererCreationFunctions.push_back(CreateRenderer11); + } +# endif + +# if defined(ANGLE_ENABLE_D3D9) + if (addD3D9) + { + rendererCreationFunctions.push_back(CreateRenderer9); + } +# endif +#else +# if defined(ANGLE_ENABLE_D3D9) + if (addD3D9) + { + rendererCreationFunctions.push_back(CreateRenderer9); + } +# endif + +# if defined(ANGLE_ENABLE_D3D11) + if (addD3D11) + { + rendererCreationFunctions.push_back(CreateRenderer11); + } +# endif +#endif + + if (nativeDisplay != EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE && + nativeDisplay != EGL_D3D11_ONLY_DISPLAY_ANGLE && + requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE) + { + // The default display is requested, try the D3D9 and D3D11 renderers, order them using + // the definition of ANGLE_DEFAULT_D3D11 +#if ANGLE_DEFAULT_D3D11 +# if defined(ANGLE_ENABLE_D3D11) + rendererCreationFunctions.push_back(CreateRenderer11); +# endif +# if defined(ANGLE_ENABLE_D3D9) + rendererCreationFunctions.push_back(CreateRenderer9); +# endif +#else +# if defined(ANGLE_ENABLE_D3D9) + rendererCreationFunctions.push_back(CreateRenderer9); +# endif +# if defined(ANGLE_ENABLE_D3D11) + rendererCreationFunctions.push_back(CreateRenderer11); +# endif +#endif + } + } + else if (display->getPlatform() == EGL_PLATFORM_DEVICE_EXT) + { +#if defined(ANGLE_ENABLE_D3D11) + if (display->getDevice()->getType() == EGL_D3D11_DEVICE_ANGLE) + { + rendererCreationFunctions.push_back(CreateRenderer11); + } +#endif + } + else + { + UNIMPLEMENTED(); + } + + for (size_t i = 0; i < rendererCreationFunctions.size(); i++) + { + RendererD3D *renderer = rendererCreationFunctions[i](display); + egl::Error result = renderer->initialize(); + +#if defined(ANGLE_ENABLE_D3D11) + if (renderer->getRendererClass() == RENDERER_D3D11) + { + ASSERT(result.getID() >= 0 && result.getID() < NUM_D3D11_INIT_ERRORS); + ANGLE_HISTOGRAM_ENUMERATION("GPU.ANGLE.D3D11InitializeResult", result.getID(), + NUM_D3D11_INIT_ERRORS); + } +#endif + +#if defined(ANGLE_ENABLE_D3D9) + if (renderer->getRendererClass() == RENDERER_D3D9) + { + ASSERT(result.getID() >= 0 && result.getID() < NUM_D3D9_INIT_ERRORS); + ANGLE_HISTOGRAM_ENUMERATION("GPU.ANGLE.D3D9InitializeResult", result.getID(), + NUM_D3D9_INIT_ERRORS); + } +#endif + + if (!result.isError()) + { + *outRenderer = renderer; + return result; + } + + // Failed to create the renderer, try the next + SafeDelete(renderer); + ERR() << "Failed to create D3D renderer: " << result.getMessage(); + } + + return egl::EglNotInitialized() << "No available renderers."; +} + +DisplayD3D::DisplayD3D(const egl::DisplayState &state) : DisplayImpl(state), mRenderer(nullptr) {} + +SurfaceImpl *DisplayD3D::createWindowSurface(const egl::SurfaceState &state, + EGLNativeWindowType window, + const egl::AttributeMap &attribs) +{ + ASSERT(mRenderer != nullptr); + return new WindowSurfaceD3D(state, mRenderer, mDisplay, window, attribs); +} + +SurfaceImpl *DisplayD3D::createPbufferSurface(const egl::SurfaceState &state, + const egl::AttributeMap &attribs) +{ + ASSERT(mRenderer != nullptr); + return new PbufferSurfaceD3D(state, mRenderer, mDisplay, 0, nullptr, attribs); +} + +SurfaceImpl *DisplayD3D::createPbufferFromClientBuffer(const egl::SurfaceState &state, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const egl::AttributeMap &attribs) +{ + ASSERT(mRenderer != nullptr); + return new PbufferSurfaceD3D(state, mRenderer, mDisplay, buftype, clientBuffer, attribs); +} + +SurfaceImpl *DisplayD3D::createPixmapSurface(const egl::SurfaceState &state, + NativePixmapType nativePixmap, + const egl::AttributeMap &attribs) +{ + UNIMPLEMENTED(); + return nullptr; +} + +ImageImpl *DisplayD3D::createImage(const egl::ImageState &state, + const gl::Context *context, + EGLenum target, + const egl::AttributeMap &attribs) +{ + return new EGLImageD3D(state, target, attribs, mRenderer); +} + +DeviceImpl *DisplayD3D::createDevice() +{ + return mRenderer->createEGLDevice(); +} + +rx::ContextImpl *DisplayD3D::createContext(const gl::State &state, + gl::ErrorSet *errorSet, + const egl::Config *configuration, + const gl::Context *shareContext, + const egl::AttributeMap &attribs) +{ + ASSERT(mRenderer != nullptr); + return mRenderer->createContext(state, errorSet); +} + +StreamProducerImpl *DisplayD3D::createStreamProducerD3DTexture( + egl::Stream::ConsumerType consumerType, + const egl::AttributeMap &attribs) +{ + ASSERT(mRenderer != nullptr); + return mRenderer->createStreamProducerD3DTexture(consumerType, attribs); +} + +ExternalImageSiblingImpl *DisplayD3D::createExternalImageSibling(const gl::Context *context, + EGLenum target, + EGLClientBuffer buffer, + const egl::AttributeMap &attribs) +{ + ASSERT(mRenderer != nullptr); + return mRenderer->createExternalImageSibling(context, target, buffer, attribs); +} + +ShareGroupImpl *DisplayD3D::createShareGroup() +{ + return new ShareGroupD3D(); +} + +egl::Error DisplayD3D::makeCurrent(egl::Display *display, + egl::Surface *drawSurface, + egl::Surface *readSurface, + gl::Context *context) +{ + // Ensure the appropriate global DebugAnnotator is used + ASSERT(mRenderer != nullptr); + mRenderer->setGlobalDebugAnnotator(); + + return egl::NoError(); +} + +egl::Error DisplayD3D::initialize(egl::Display *display) +{ + ASSERT(mRenderer == nullptr && display != nullptr); + mDisplay = display; + ANGLE_TRY(CreateRendererD3D(display, &mRenderer)); + return egl::NoError(); +} + +void DisplayD3D::terminate() +{ + SafeDelete(mRenderer); +} + +egl::ConfigSet DisplayD3D::generateConfigs() +{ + ASSERT(mRenderer != nullptr); + return mRenderer->generateConfigs(); +} + +bool DisplayD3D::testDeviceLost() +{ + ASSERT(mRenderer != nullptr); + return mRenderer->testDeviceLost(); +} + +egl::Error DisplayD3D::restoreLostDevice(const egl::Display *display) +{ + // Release surface resources to make the Reset() succeed + for (egl::Surface *surface : mState.surfaceSet) + { + ASSERT(!surface->getBoundTexture()); + SurfaceD3D *surfaceD3D = GetImplAs(surface); + surfaceD3D->releaseSwapChain(); + } + + if (!mRenderer->resetDevice()) + { + return egl::EglBadAlloc(); + } + + // Restore any surfaces that may have been lost + for (const egl::Surface *surface : mState.surfaceSet) + { + SurfaceD3D *surfaceD3D = GetImplAs(surface); + + ANGLE_TRY(surfaceD3D->resetSwapChain(display)); + } + + return egl::NoError(); +} + +bool DisplayD3D::isValidNativeWindow(EGLNativeWindowType window) const +{ + return mRenderer->isValidNativeWindow(window); +} + +egl::Error DisplayD3D::validateClientBuffer(const egl::Config *config, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const egl::AttributeMap &attribs) const +{ + switch (buftype) + { + case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE: + return mRenderer->validateShareHandle(config, static_cast(clientBuffer), + attribs); + + case EGL_D3D_TEXTURE_ANGLE: + return mRenderer->getD3DTextureInfo(config, static_cast(clientBuffer), + attribs, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr); + + default: + return DisplayImpl::validateClientBuffer(config, buftype, clientBuffer, attribs); + } +} + +egl::Error DisplayD3D::validateImageClientBuffer(const gl::Context *context, + EGLenum target, + EGLClientBuffer clientBuffer, + const egl::AttributeMap &attribs) const +{ + switch (target) + { + case EGL_D3D11_TEXTURE_ANGLE: + { + return mRenderer->getD3DTextureInfo(nullptr, static_cast(clientBuffer), + attribs, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr); + } + + default: + return DisplayImpl::validateImageClientBuffer(context, target, clientBuffer, attribs); + } +} + +void DisplayD3D::generateExtensions(egl::DisplayExtensions *outExtensions) const +{ + mRenderer->generateDisplayExtensions(outExtensions); +} + +std::string DisplayD3D::getRendererDescription() +{ + if (mRenderer) + { + return mRenderer->getRendererDescription(); + } + return std::string(); +} + +std::string DisplayD3D::getVendorString() +{ + if (mRenderer) + { + return mRenderer->getVendorString(); + } + return std::string(); +} + +std::string DisplayD3D::getVersionString(bool includeFullVersion) +{ + if (mRenderer) + { + return mRenderer->getVersionString(includeFullVersion); + } + return std::string(); +} + +void DisplayD3D::generateCaps(egl::Caps *outCaps) const +{ + // Display must be initialized to generate caps + ASSERT(mRenderer != nullptr); + + outCaps->textureNPOT = mRenderer->getNativeExtensions().textureNpotOES; +} + +egl::Error DisplayD3D::waitClient(const gl::Context *context) +{ + for (egl::Surface *surface : mState.surfaceSet) + { + SurfaceD3D *surfaceD3D = GetImplAs(surface); + ANGLE_TRY(surfaceD3D->checkForOutOfDateSwapChain(this)); + } + + return egl::NoError(); +} + +egl::Error DisplayD3D::waitNative(const gl::Context *context, EGLint engine) +{ + egl::Surface *drawSurface = context->getCurrentDrawSurface(); + egl::Surface *readSurface = context->getCurrentReadSurface(); + + if (drawSurface != nullptr) + { + SurfaceD3D *drawSurfaceD3D = GetImplAs(drawSurface); + ANGLE_TRY(drawSurfaceD3D->checkForOutOfDateSwapChain(this)); + } + + if (readSurface != nullptr) + { + SurfaceD3D *readSurfaceD3D = GetImplAs(readSurface); + ANGLE_TRY(readSurfaceD3D->checkForOutOfDateSwapChain(this)); + } + + return egl::NoError(); +} + +gl::Version DisplayD3D::getMaxSupportedESVersion() const +{ + return mRenderer->getMaxSupportedESVersion(); +} + +gl::Version DisplayD3D::getMaxConformantESVersion() const +{ + return mRenderer->getMaxConformantESVersion(); +} + +Optional DisplayD3D::getMaxSupportedDesktopVersion() const +{ + return Optional::Invalid(); +} + +void DisplayD3D::handleResult(HRESULT hr, + const char *message, + const char *file, + const char *function, + unsigned int line) +{ + ASSERT(FAILED(hr)); + + std::stringstream errorStream; + errorStream << "Internal D3D11 error: " << gl::FmtHR(hr) << ", in " << file << ", " << function + << ":" << line << ". " << message; + + mStoredErrorString = errorStream.str(); +} + +void DisplayD3D::initializeFrontendFeatures(angle::FrontendFeatures *features) const +{ + mRenderer->initializeFrontendFeatures(features); +} + +void DisplayD3D::populateFeatureList(angle::FeatureList *features) +{ + mRenderer->getFeatures().populateFeatureList(features); +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/DisplayD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DisplayD3D.h new file mode 100644 index 0000000000..890658f5ea --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DisplayD3D.h @@ -0,0 +1,179 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// DisplayD3D.h: D3D implementation of egl::Display + +#ifndef LIBANGLE_RENDERER_D3D_DISPLAYD3D_H_ +#define LIBANGLE_RENDERER_D3D_DISPLAYD3D_H_ + +#include "libANGLE/Device.h" +#include "libANGLE/renderer/DisplayImpl.h" + +#include "libANGLE/renderer/d3d/RendererD3D.h" + +namespace rx +{ +class ShareGroupD3D : public ShareGroupImpl +{}; + +class DisplayD3D : public DisplayImpl, public d3d::Context +{ + public: + DisplayD3D(const egl::DisplayState &state); + + egl::Error initialize(egl::Display *display) override; + void terminate() override; + + // Surface creation + SurfaceImpl *createWindowSurface(const egl::SurfaceState &state, + EGLNativeWindowType window, + const egl::AttributeMap &attribs) override; + SurfaceImpl *createPbufferSurface(const egl::SurfaceState &state, + const egl::AttributeMap &attribs) override; + SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const egl::AttributeMap &attribs) override; + SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state, + NativePixmapType nativePixmap, + const egl::AttributeMap &attribs) override; + + ImageImpl *createImage(const egl::ImageState &state, + const gl::Context *context, + EGLenum target, + const egl::AttributeMap &attribs) override; + + ContextImpl *createContext(const gl::State &state, + gl::ErrorSet *errorSet, + const egl::Config *configuration, + const gl::Context *shareContext, + const egl::AttributeMap &attribs) override; + + StreamProducerImpl *createStreamProducerD3DTexture(egl::Stream::ConsumerType consumerType, + const egl::AttributeMap &attribs) override; + + ExternalImageSiblingImpl *createExternalImageSibling(const gl::Context *context, + EGLenum target, + EGLClientBuffer buffer, + const egl::AttributeMap &attribs) override; + + ShareGroupImpl *createShareGroup() override; + + egl::Error makeCurrent(egl::Display *display, + egl::Surface *drawSurface, + egl::Surface *readSurface, + gl::Context *context) override; + + egl::ConfigSet generateConfigs() override; + + bool testDeviceLost() override; + egl::Error restoreLostDevice(const egl::Display *display) override; + + bool isValidNativeWindow(EGLNativeWindowType window) const override; + egl::Error validateClientBuffer(const egl::Config *configuration, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const egl::AttributeMap &attribs) const override; + egl::Error validateImageClientBuffer(const gl::Context *context, + EGLenum target, + EGLClientBuffer clientBuffer, + const egl::AttributeMap &attribs) const override; + + DeviceImpl *createDevice() override; + + std::string getRendererDescription() override; + std::string getVendorString() override; + std::string getVersionString(bool includeFullVersion) override; + + egl::Error waitClient(const gl::Context *context) override; + egl::Error waitNative(const gl::Context *context, EGLint engine) override; + gl::Version getMaxSupportedESVersion() const override; + gl::Version getMaxConformantESVersion() const override; + Optional getMaxSupportedDesktopVersion() const override; + + void handleResult(HRESULT hr, + const char *message, + const char *file, + const char *function, + unsigned int line) override; + + const std::string &getStoredErrorString() const { return mStoredErrorString; } + + void initializeFrontendFeatures(angle::FrontendFeatures *features) const override; + + void populateFeatureList(angle::FeatureList *features) override; + + private: + void generateExtensions(egl::DisplayExtensions *outExtensions) const override; + void generateCaps(egl::Caps *outCaps) const override; + + egl::Display *mDisplay; + + rx::RendererD3D *mRenderer; + std::string mStoredErrorString; +}; + +// Possible reasons RendererD3D initialize can fail +enum D3D11InitError +{ + // The renderer loaded successfully + D3D11_INIT_SUCCESS = 0, + // Failed to load the ANGLE & D3D compiler libraries + D3D11_INIT_COMPILER_ERROR, + // Failed to load a necessary DLL (non-compiler) + D3D11_INIT_MISSING_DEP, + // CreateDevice returned E_INVALIDARG + D3D11_INIT_CREATEDEVICE_INVALIDARG, + // CreateDevice failed with an error other than invalid arg + D3D11_INIT_CREATEDEVICE_ERROR, + // DXGI 1.2 required but not found + D3D11_INIT_INCOMPATIBLE_DXGI, + // Other initialization error + D3D11_INIT_OTHER_ERROR, + // CreateDevice returned E_FAIL + D3D11_INIT_CREATEDEVICE_FAIL, + // CreateDevice returned E_NOTIMPL + D3D11_INIT_CREATEDEVICE_NOTIMPL, + // CreateDevice returned E_OUTOFMEMORY + D3D11_INIT_CREATEDEVICE_OUTOFMEMORY, + // CreateDevice returned DXGI_ERROR_INVALID_CALL + D3D11_INIT_CREATEDEVICE_INVALIDCALL, + // CreateDevice returned DXGI_ERROR_SDK_COMPONENT_MISSING + D3D11_INIT_CREATEDEVICE_COMPONENTMISSING, + // CreateDevice returned DXGI_ERROR_WAS_STILL_DRAWING + D3D11_INIT_CREATEDEVICE_WASSTILLDRAWING, + // CreateDevice returned DXGI_ERROR_NOT_CURRENTLY_AVAILABLE + D3D11_INIT_CREATEDEVICE_NOTAVAILABLE, + // CreateDevice returned DXGI_ERROR_DEVICE_HUNG + D3D11_INIT_CREATEDEVICE_DEVICEHUNG, + // CreateDevice returned NULL + D3D11_INIT_CREATEDEVICE_NULL, + NUM_D3D11_INIT_ERRORS +}; + +enum D3D9InitError +{ + D3D9_INIT_SUCCESS = 0, + // Failed to load the D3D or ANGLE compiler + D3D9_INIT_COMPILER_ERROR, + // Failed to load a necessary DLL + D3D9_INIT_MISSING_DEP, + // Device creation error + D3D9_INIT_CREATE_DEVICE_ERROR, + // System does not meet minimum shader spec + D3D9_INIT_UNSUPPORTED_VERSION, + // System does not support stretchrect from textures + D3D9_INIT_UNSUPPORTED_STRETCHRECT, + // A call returned out of memory or device lost + D3D9_INIT_OUT_OF_MEMORY, + // Other unspecified error + D3D9_INIT_OTHER_ERROR, + NUM_D3D9_INIT_ERRORS +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_DISPLAYD3D_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicHLSL.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicHLSL.cpp new file mode 100644 index 0000000000..b83c8bac6e --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicHLSL.cpp @@ -0,0 +1,1537 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// DynamicHLSL.cpp: Implementation for link and run-time HLSL generation +// + +#include "libANGLE/renderer/d3d/DynamicHLSL.h" + +#include "common/string_utils.h" +#include "common/utilities.h" +#include "compiler/translator/blocklayoutHLSL.h" +#include "libANGLE/Context.h" +#include "libANGLE/Program.h" +#include "libANGLE/Shader.h" +#include "libANGLE/VaryingPacking.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/ProgramD3D.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" +#include "libANGLE/renderer/d3d/ShaderD3D.h" + +using namespace gl; + +namespace rx +{ + +namespace +{ + +// kShaderStorageDeclarationString must be the same as outputHLSL. +constexpr const char kShaderStorageDeclarationString[] = + "// @@ SHADER STORAGE DECLARATION STRING @@"; + +const char *HLSLComponentTypeString(GLenum componentType) +{ + switch (componentType) + { + case GL_UNSIGNED_INT: + return "uint"; + case GL_INT: + return "int"; + case GL_UNSIGNED_NORMALIZED: + case GL_SIGNED_NORMALIZED: + case GL_FLOAT: + return "float"; + default: + UNREACHABLE(); + return "not-component-type"; + } +} + +void HLSLComponentTypeString(std::ostringstream &ostream, GLenum componentType, int componentCount) +{ + ostream << HLSLComponentTypeString(componentType); + if (componentCount > 1) + { + ostream << componentCount; + } +} + +const char *HLSLMatrixTypeString(GLenum type) +{ + switch (type) + { + case GL_FLOAT_MAT2: + return "float2x2"; + case GL_FLOAT_MAT3: + return "float3x3"; + case GL_FLOAT_MAT4: + return "float4x4"; + case GL_FLOAT_MAT2x3: + return "float2x3"; + case GL_FLOAT_MAT3x2: + return "float3x2"; + case GL_FLOAT_MAT2x4: + return "float2x4"; + case GL_FLOAT_MAT4x2: + return "float4x2"; + case GL_FLOAT_MAT3x4: + return "float3x4"; + case GL_FLOAT_MAT4x3: + return "float4x3"; + default: + UNREACHABLE(); + return "not-matrix-type"; + } +} + +void HLSLTypeString(std::ostringstream &ostream, GLenum type) +{ + if (gl::IsMatrixType(type)) + { + ostream << HLSLMatrixTypeString(type); + return; + } + + HLSLComponentTypeString(ostream, gl::VariableComponentType(type), + gl::VariableComponentCount(type)); +} + +const PixelShaderOutputVariable *FindOutputAtLocation( + const std::vector &outputVariables, + unsigned int location, + size_t index = 0) +{ + for (auto &outputVar : outputVariables) + { + if (outputVar.outputLocation == location && outputVar.outputIndex == index) + { + return &outputVar; + } + } + + return nullptr; +} + +void WriteArrayString(std::ostringstream &strstr, unsigned int i) +{ + static_assert(GL_INVALID_INDEX == UINT_MAX, + "GL_INVALID_INDEX must be equal to the max unsigned int."); + if (i == UINT_MAX) + { + return; + } + + strstr << "["; + strstr << i; + strstr << "]"; +} + +bool ReplaceShaderStorageDeclaration(const std::vector &shaderStorageBlocks, + std::string *hlsl, + size_t baseUAVRegister, + gl::ShaderType shaderType) +{ + std::string ssboHeader; + std::ostringstream out(ssboHeader); + for (const ShaderStorageBlock &ssbo : shaderStorageBlocks) + { + size_t uavRegister = baseUAVRegister + ssbo.registerIndex; + std::string name = ssbo.name; + if (ssbo.arraySize > 0) + { + for (unsigned int arrayIndex = 0; arrayIndex < ssbo.arraySize; arrayIndex++) + { + out << "RWByteAddressBuffer " + << "dx_" << name << "_" << arrayIndex << ": register(u" + << uavRegister + arrayIndex << ");\n"; + } + } + else + { + out << "RWByteAddressBuffer " + << "_" << name << ": register(u" << uavRegister << ");\n"; + } + } + if (out.str().empty()) + { + return true; + } + return angle::ReplaceSubstring(hlsl, kShaderStorageDeclarationString, out.str()); +} + +constexpr const char *VERTEX_ATTRIBUTE_STUB_STRING = "@@ VERTEX ATTRIBUTES @@"; +constexpr const char *VERTEX_OUTPUT_STUB_STRING = "@@ VERTEX OUTPUT @@"; +constexpr const char *PIXEL_OUTPUT_STUB_STRING = "@@ PIXEL OUTPUT @@"; +constexpr const char *PIXEL_MAIN_PARAMETERS_STUB_STRING = "@@ PIXEL MAIN PARAMETERS @@"; +constexpr const char *MAIN_PROLOGUE_STUB_STRING = "@@ MAIN PROLOGUE @@"; +} // anonymous namespace + +// BuiltinInfo implementation + +BuiltinInfo::BuiltinInfo() = default; +BuiltinInfo::~BuiltinInfo() = default; + +// DynamicHLSL implementation + +DynamicHLSL::DynamicHLSL(RendererD3D *const renderer) : mRenderer(renderer) {} + +std::string DynamicHLSL::generateVertexShaderForInputLayout( + const std::string &sourceShader, + const InputLayout &inputLayout, + const std::vector &shaderAttributes, + const std::vector &shaderStorageBlocks, + size_t baseUAVRegister) const +{ + std::ostringstream structStream; + std::ostringstream initStream; + + structStream << "struct VS_INPUT\n" + << "{\n"; + + int semanticIndex = 0; + unsigned int inputIndex = 0; + + // If gl_PointSize is used in the shader then pointsprites rendering is expected. + // If the renderer does not support Geometry shaders then Instanced PointSprite emulation + // must be used. + bool usesPointSize = sourceShader.find("GL_USES_POINT_SIZE") != std::string::npos; + bool useInstancedPointSpriteEmulation = + usesPointSize && mRenderer->getFeatures().useInstancedPointSpriteEmulation.enabled; + + // Instanced PointSprite emulation requires additional entries in the + // VS_INPUT structure to support the vertices that make up the quad vertices. + // These values must be in sync with the cooresponding values added during inputlayout creation + // in InputLayoutCache::applyVertexBuffers(). + // + // The additional entries must appear first in the VS_INPUT layout because + // Windows Phone 8 era devices require per vertex data to physically come + // before per instance data in the shader. + if (useInstancedPointSpriteEmulation) + { + structStream << " float3 spriteVertexPos : SPRITEPOSITION0;\n" + << " float2 spriteTexCoord : SPRITETEXCOORD0;\n"; + } + + for (size_t attributeIndex = 0; attributeIndex < shaderAttributes.size(); ++attributeIndex) + { + const sh::ShaderVariable &shaderAttribute = shaderAttributes[attributeIndex]; + if (!shaderAttribute.name.empty()) + { + ASSERT(inputIndex < MAX_VERTEX_ATTRIBS); + angle::FormatID vertexFormatID = + inputIndex < inputLayout.size() ? inputLayout[inputIndex] : angle::FormatID::NONE; + + // HLSL code for input structure + if (IsMatrixType(shaderAttribute.type)) + { + // Matrix types are always transposed + structStream << " " + << HLSLMatrixTypeString(TransposeMatrixType(shaderAttribute.type)); + } + else + { + if (shaderAttribute.name == "gl_InstanceID" || + shaderAttribute.name == "gl_VertexID") + { + // The input types of the instance ID and vertex ID in HLSL (uint) differs from + // the ones in ESSL (int). + structStream << " uint"; + } + else + { + GLenum componentType = mRenderer->getVertexComponentType(vertexFormatID); + + structStream << " "; + HLSLComponentTypeString(structStream, componentType, + VariableComponentCount(shaderAttribute.type)); + } + } + + structStream << " " << DecorateVariable(shaderAttribute.name) << " : "; + + if (shaderAttribute.name == "gl_InstanceID") + { + structStream << "SV_InstanceID"; + } + else if (shaderAttribute.name == "gl_VertexID") + { + structStream << "SV_VertexID"; + } + else + { + structStream << "TEXCOORD" << semanticIndex; + semanticIndex += VariableRegisterCount(shaderAttribute.type); + } + + structStream << ";\n"; + + // HLSL code for initialization + initStream << " " << DecorateVariable(shaderAttribute.name) << " = "; + + // Mismatched vertex attribute to vertex input may result in an undefined + // data reinterpretation (eg for pure integer->float, float->pure integer) + // TODO: issue warning with gl debug info extension, when supported + if (IsMatrixType(shaderAttribute.type) || + (mRenderer->getVertexConversionType(vertexFormatID) & VERTEX_CONVERT_GPU) != 0) + { + GenerateAttributeConversionHLSL(vertexFormatID, shaderAttribute, initStream); + } + else + { + initStream << "input." << DecorateVariable(shaderAttribute.name); + } + + if (shaderAttribute.name == "gl_VertexID") + { + // dx_VertexID contains the firstVertex offset + initStream << " + dx_VertexID"; + } + + initStream << ";\n"; + + inputIndex += VariableRowCount(TransposeMatrixType(shaderAttribute.type)); + } + } + + structStream << "};\n" + "\n" + "void initAttributes(VS_INPUT input)\n" + "{\n" + << initStream.str() << "}\n"; + + std::string vertexHLSL(sourceShader); + + bool success = + angle::ReplaceSubstring(&vertexHLSL, VERTEX_ATTRIBUTE_STUB_STRING, structStream.str()); + ASSERT(success); + + success = ReplaceShaderStorageDeclaration(shaderStorageBlocks, &vertexHLSL, baseUAVRegister, + gl::ShaderType::Vertex); + ASSERT(success); + + return vertexHLSL; +} + +std::string DynamicHLSL::generatePixelShaderForOutputSignature( + const std::string &sourceShader, + const std::vector &outputVariables, + bool usesFragDepth, + const std::vector &outputLayout, + const std::vector &shaderStorageBlocks, + size_t baseUAVRegister) const +{ + const int shaderModel = mRenderer->getMajorShaderModel(); + std::string targetSemantic = (shaderModel >= 4) ? "SV_TARGET" : "COLOR"; + std::string depthSemantic = (shaderModel >= 4) ? "SV_Depth" : "DEPTH"; + + std::ostringstream declarationStream; + std::ostringstream copyStream; + + declarationStream << "struct PS_OUTPUT\n" + "{\n"; + + size_t numOutputs = outputLayout.size(); + + // Workaround for HLSL 3.x: We can't do a depth/stencil only render, the runtime will complain. + if (numOutputs == 0 && (shaderModel == 3 || !mRenderer->getShaderModelSuffix().empty())) + { + numOutputs = 1u; + } + const PixelShaderOutputVariable defaultOutput(GL_FLOAT_VEC4, "unused", "float4(0, 0, 0, 1)", 0, + 0); + size_t outputIndex = 0; + + for (size_t layoutIndex = 0; layoutIndex < numOutputs; ++layoutIndex) + { + GLenum binding = outputLayout.empty() ? GL_COLOR_ATTACHMENT0 : outputLayout[layoutIndex]; + + if (binding != GL_NONE) + { + unsigned int location = (binding - GL_COLOR_ATTACHMENT0); + outputIndex = + layoutIndex > 0 && binding == outputLayout[layoutIndex - 1] ? outputIndex + 1 : 0; + + const PixelShaderOutputVariable *outputVariable = + outputLayout.empty() ? &defaultOutput + : FindOutputAtLocation(outputVariables, location, outputIndex); + + // OpenGL ES 3.0 spec $4.2.1 + // If [...] not all user-defined output variables are written, the values of fragment + // colors corresponding to unwritten variables are similarly undefined. + if (outputVariable) + { + declarationStream << " "; + HLSLTypeString(declarationStream, outputVariable->type); + declarationStream << " " << outputVariable->name << " : " << targetSemantic + << static_cast(layoutIndex) << ";\n"; + + copyStream << " output." << outputVariable->name << " = " + << outputVariable->source << ";\n"; + } + } + } + + if (usesFragDepth) + { + declarationStream << " float gl_Depth : " << depthSemantic << ";\n"; + copyStream << " output.gl_Depth = gl_Depth; \n"; + } + + declarationStream << "};\n" + "\n" + "PS_OUTPUT generateOutput()\n" + "{\n" + " PS_OUTPUT output;\n" + << copyStream.str() + << " return output;\n" + "}\n"; + + std::string pixelHLSL(sourceShader); + + bool success = + angle::ReplaceSubstring(&pixelHLSL, PIXEL_OUTPUT_STUB_STRING, declarationStream.str()); + ASSERT(success); + + success = ReplaceShaderStorageDeclaration(shaderStorageBlocks, &pixelHLSL, baseUAVRegister, + gl::ShaderType::Fragment); + ASSERT(success); + + return pixelHLSL; +} + +std::string DynamicHLSL::generateShaderForImage2DBindSignature( + ProgramD3D &programD3D, + const gl::ProgramState &programData, + gl::ShaderType shaderType, + const std::string &shaderHLSL, + std::vector &image2DUniforms, + const gl::ImageUnitTextureTypeMap &image2DBindLayout, + unsigned int baseUAVRegister) const +{ + if (image2DUniforms.empty()) + { + return shaderHLSL; + } + + return GenerateShaderForImage2DBindSignature(programD3D, programData, shaderType, shaderHLSL, + image2DUniforms, image2DBindLayout, + baseUAVRegister); +} + +void DynamicHLSL::generateVaryingLinkHLSL(const VaryingPacking &varyingPacking, + const BuiltinInfo &builtins, + bool programUsesPointSize, + std::ostringstream &hlslStream) const +{ + ASSERT(builtins.dxPosition.enabled); + hlslStream << "{\n" + << " float4 dx_Position : " << builtins.dxPosition.str() << ";\n"; + + if (builtins.glPosition.enabled) + { + hlslStream << " float4 gl_Position : " << builtins.glPosition.str() << ";\n"; + } + + if (builtins.glFragCoord.enabled) + { + hlslStream << " float4 gl_FragCoord : " << builtins.glFragCoord.str() << ";\n"; + } + + if (builtins.glPointCoord.enabled) + { + hlslStream << " float2 gl_PointCoord : " << builtins.glPointCoord.str() << ";\n"; + } + + if (builtins.glPointSize.enabled) + { + hlslStream << " float gl_PointSize : " << builtins.glPointSize.str() << ";\n"; + } + + if (builtins.glViewIDOVR.enabled) + { + hlslStream << " nointerpolation uint gl_ViewID_OVR : " << builtins.glViewIDOVR.str() + << ";\n"; + } + + std::string varyingSemantic = + GetVaryingSemantic(mRenderer->getMajorShaderModel(), programUsesPointSize); + + const auto ®isterInfos = varyingPacking.getRegisterList(); + for (GLuint registerIndex = 0u; registerIndex < registerInfos.size(); ++registerIndex) + { + const PackedVaryingRegister ®isterInfo = registerInfos[registerIndex]; + const auto &varying = registerInfo.packedVarying->varying(); + ASSERT(!varying.isStruct()); + + // TODO: Add checks to ensure D3D interpolation modifiers don't result in too many + // registers being used. + // For example, if there are N registers, and we have N vec3 varyings and 1 float + // varying, then D3D will pack them into N registers. + // If the float varying has the 'nointerpolation' modifier on it then we would need + // N + 1 registers, and D3D compilation will fail. + + switch (registerInfo.packedVarying->interpolation) + { + case sh::INTERPOLATION_SMOOTH: + hlslStream << " "; + break; + case sh::INTERPOLATION_FLAT: + hlslStream << " nointerpolation "; + break; + case sh::INTERPOLATION_CENTROID: + hlslStream << " centroid "; + break; + case sh::INTERPOLATION_SAMPLE: + hlslStream << " sample "; + break; + default: + UNREACHABLE(); + } + + GLenum transposedType = gl::TransposeMatrixType(varying.type); + GLenum componentType = gl::VariableComponentType(transposedType); + int columnCount = gl::VariableColumnCount(transposedType); + HLSLComponentTypeString(hlslStream, componentType, columnCount); + hlslStream << " v" << registerIndex << " : " << varyingSemantic << registerIndex << ";\n"; + } + + // Note that the following outputs need to be declared after the others. They are not included + // in pixel shader inputs even when they are in vertex/geometry shader outputs, and the pixel + // shader input struct must be a prefix of the vertex/geometry shader output struct. + + if (builtins.glViewportIndex.enabled) + { + hlslStream << " nointerpolation uint gl_ViewportIndex : " + << builtins.glViewportIndex.str() << ";\n"; + } + + if (builtins.glLayer.enabled) + { + hlslStream << " nointerpolation uint gl_Layer : " << builtins.glLayer.str() << ";\n"; + } + + hlslStream << "};\n"; +} + +void DynamicHLSL::generateShaderLinkHLSL(const gl::Context *context, + const gl::Caps &caps, + const gl::ProgramState &programData, + const ProgramD3DMetadata &programMetadata, + const VaryingPacking &varyingPacking, + const BuiltinVaryingsD3D &builtinsD3D, + gl::ShaderMap *shaderHLSL) const +{ + ASSERT(shaderHLSL); + ASSERT((*shaderHLSL)[gl::ShaderType::Vertex].empty() && + (*shaderHLSL)[gl::ShaderType::Fragment].empty()); + + gl::Shader *vertexShaderGL = programData.getAttachedShader(ShaderType::Vertex); + gl::Shader *fragmentShaderGL = programData.getAttachedShader(ShaderType::Fragment); + const int shaderModel = mRenderer->getMajorShaderModel(); + + const ShaderD3D *fragmentShader = nullptr; + if (fragmentShaderGL) + { + fragmentShader = GetImplAs(fragmentShaderGL); + } + + // usesViewScale() isn't supported in the D3D9 renderer + ASSERT(shaderModel >= 4 || !programMetadata.usesViewScale()); + + bool useInstancedPointSpriteEmulation = + programMetadata.usesPointSize() && + mRenderer->getFeatures().useInstancedPointSpriteEmulation.enabled; + + // Validation done in the compiler + ASSERT(!fragmentShader || !fragmentShader->usesFragColor() || !fragmentShader->usesFragData()); + + std::ostringstream vertexStream; + vertexStream << "struct VS_OUTPUT\n"; + const auto &vertexBuiltins = builtinsD3D[gl::ShaderType::Vertex]; + generateVaryingLinkHLSL(varyingPacking, vertexBuiltins, builtinsD3D.usesPointSize(), + vertexStream); + + // Instanced PointSprite emulation requires additional entries originally generated in the + // GeometryShader HLSL. These include pointsize clamp values. + if (useInstancedPointSpriteEmulation) + { + vertexStream << "static float minPointSize = " << static_cast(caps.minAliasedPointSize) + << ".0f;\n" + << "static float maxPointSize = " << static_cast(caps.maxAliasedPointSize) + << ".0f;\n"; + } + + std::ostringstream vertexGenerateOutput; + vertexGenerateOutput << "VS_OUTPUT generateOutput(VS_INPUT input)\n" + << "{\n" + << " VS_OUTPUT output;\n"; + + if (vertexBuiltins.glPosition.enabled) + { + vertexGenerateOutput << " output.gl_Position = gl_Position;\n"; + } + + if (vertexBuiltins.glViewIDOVR.enabled) + { + vertexGenerateOutput << " output.gl_ViewID_OVR = ViewID_OVR;\n"; + } + if (programMetadata.hasANGLEMultiviewEnabled() && programMetadata.canSelectViewInVertexShader()) + { + ASSERT(vertexBuiltins.glViewportIndex.enabled && vertexBuiltins.glLayer.enabled); + vertexGenerateOutput << " if (multiviewSelectViewportIndex)\n" + << " {\n" + << " output.gl_ViewportIndex = ViewID_OVR;\n" + << " } else {\n" + << " output.gl_ViewportIndex = 0;\n" + << " output.gl_Layer = ViewID_OVR;\n" + << " }\n"; + } + + // On D3D9 or D3D11 Feature Level 9, we need to emulate large viewports using dx_ViewAdjust. + if (shaderModel >= 4 && mRenderer->getShaderModelSuffix() == "") + { + vertexGenerateOutput << " output.dx_Position.x = gl_Position.x;\n"; + + if (programMetadata.usesViewScale()) + { + // This code assumes that dx_ViewScale.y = -1.0f when rendering to texture, and +1.0f + // when rendering to the default framebuffer. No other values are valid. + vertexGenerateOutput << " output.dx_Position.y = dx_ViewScale.y * gl_Position.y;\n"; + } + else + { + vertexGenerateOutput + << " output.dx_Position.y = clipControlOrigin * gl_Position.y;\n"; + } + + vertexGenerateOutput + << " if (clipControlZeroToOne)\n" + << " {\n" + << " output.dx_Position.z = gl_Position.z;\n" + << " } else {\n" + << " output.dx_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n" + << " }\n"; + + vertexGenerateOutput << " output.dx_Position.w = gl_Position.w;\n"; + } + else + { + vertexGenerateOutput << " output.dx_Position.x = gl_Position.x * dx_ViewAdjust.z + " + "dx_ViewAdjust.x * gl_Position.w;\n"; + + // If usesViewScale() is true and we're using the D3D11 renderer via Feature Level 9_*, + // then we need to multiply the gl_Position.y by the viewScale. + // usesViewScale() isn't supported when using the D3D9 renderer. + if (programMetadata.usesViewScale() && + (shaderModel >= 4 && mRenderer->getShaderModelSuffix() != "")) + { + vertexGenerateOutput << " output.dx_Position.y = dx_ViewScale.y * (gl_Position.y * " + "dx_ViewAdjust.w + dx_ViewAdjust.y * gl_Position.w);\n"; + } + else + { + vertexGenerateOutput << " output.dx_Position.y = clipControlOrigin * (gl_Position.y " + "* dx_ViewAdjust.w + " + "dx_ViewAdjust.y * gl_Position.w);\n"; + } + + vertexGenerateOutput + << " if (clipControlZeroToOne)\n" + << " {\n" + << " output.dx_Position.z = gl_Position.z;\n" + << " } else {\n" + << " output.dx_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n" + << " }\n"; + + vertexGenerateOutput << " output.dx_Position.w = gl_Position.w;\n"; + } + + // We don't need to output gl_PointSize if we use are emulating point sprites via instancing. + if (vertexBuiltins.glPointSize.enabled) + { + vertexGenerateOutput << " output.gl_PointSize = gl_PointSize;\n"; + } + + if (vertexBuiltins.glFragCoord.enabled) + { + vertexGenerateOutput << " output.gl_FragCoord = gl_Position;\n"; + } + + const auto ®isterInfos = varyingPacking.getRegisterList(); + for (GLuint registerIndex = 0u; registerIndex < registerInfos.size(); ++registerIndex) + { + const PackedVaryingRegister ®isterInfo = registerInfos[registerIndex]; + const auto &packedVarying = *registerInfo.packedVarying; + const auto &varying = *packedVarying.frontVarying.varying; + ASSERT(!varying.isStruct()); + + vertexGenerateOutput << " output.v" << registerIndex << " = "; + + if (packedVarying.isStructField()) + { + vertexGenerateOutput << DecorateVariable(packedVarying.frontVarying.parentStructName) + << "."; + } + + vertexGenerateOutput << DecorateVariable(varying.name); + + if (varying.isArray()) + { + WriteArrayString(vertexGenerateOutput, registerInfo.varyingArrayIndex); + } + + if (VariableRowCount(varying.type) > 1) + { + WriteArrayString(vertexGenerateOutput, registerInfo.varyingRowIndex); + } + + vertexGenerateOutput << ";\n"; + } + + // Instanced PointSprite emulation requires additional entries to calculate + // the final output vertex positions of the quad that represents each sprite. + if (useInstancedPointSpriteEmulation) + { + vertexGenerateOutput + << "\n" + << " gl_PointSize = clamp(gl_PointSize, minPointSize, maxPointSize);\n"; + + vertexGenerateOutput + << " output.dx_Position.x += (input.spriteVertexPos.x * gl_PointSize / " + "(dx_ViewCoords.x*2)) * output.dx_Position.w;"; + + if (programMetadata.usesViewScale()) + { + // Multiply by ViewScale to invert the rendering when appropriate + vertexGenerateOutput + << " output.dx_Position.y += (-dx_ViewScale.y * " + "input.spriteVertexPos.y * gl_PointSize / (dx_ViewCoords.y*2)) * " + "output.dx_Position.w;"; + } + else + { + vertexGenerateOutput + << " output.dx_Position.y += (input.spriteVertexPos.y * gl_PointSize / " + "(dx_ViewCoords.y*2)) * output.dx_Position.w;"; + } + + vertexGenerateOutput + << " output.dx_Position.z += input.spriteVertexPos.z * output.dx_Position.w;\n"; + + if (programMetadata.usesPointCoord()) + { + vertexGenerateOutput << "\n" + << " output.gl_PointCoord = input.spriteTexCoord;\n"; + } + } + + // Renderers that enable instanced pointsprite emulation require the vertex shader output member + // gl_PointCoord to be set to a default value if used without gl_PointSize. 0.5,0.5 is the same + // default value used in the generated pixel shader. + if (programMetadata.usesInsertedPointCoordValue()) + { + ASSERT(!useInstancedPointSpriteEmulation); + vertexGenerateOutput << "\n" + << " output.gl_PointCoord = float2(0.5, 0.5);\n"; + } + + vertexGenerateOutput << "\n" + << " return output;\n" + << "}"; + + if (vertexShaderGL) + { + std::string vertexSource = vertexShaderGL->getTranslatedSource(context); + angle::ReplaceSubstring(&vertexSource, std::string(MAIN_PROLOGUE_STUB_STRING), + " initAttributes(input);\n"); + angle::ReplaceSubstring(&vertexSource, std::string(VERTEX_OUTPUT_STUB_STRING), + vertexGenerateOutput.str()); + vertexStream << vertexSource; + } + + const auto &pixelBuiltins = builtinsD3D[gl::ShaderType::Fragment]; + + std::ostringstream pixelStream; + pixelStream << "struct PS_INPUT\n"; + generateVaryingLinkHLSL(varyingPacking, pixelBuiltins, builtinsD3D.usesPointSize(), + pixelStream); + pixelStream << "\n"; + + std::ostringstream pixelPrologue; + if (fragmentShader && fragmentShader->usesViewID()) + { + ASSERT(pixelBuiltins.glViewIDOVR.enabled); + pixelPrologue << " ViewID_OVR = input.gl_ViewID_OVR;\n"; + } + + if (pixelBuiltins.glFragCoord.enabled) + { + pixelPrologue << " float rhw = 1.0 / input.gl_FragCoord.w;\n"; + + // Certain Shader Models (4_0+ and 3_0) allow reading from dx_Position in the pixel shader. + // Other Shader Models (4_0_level_9_3 and 2_x) don't support this, so we emulate it using + // dx_ViewCoords. + // DComp usually gives us an offset at (0, 0), but this is not always the case. It is + // valid for DComp to give us an offset into the texture atlas. In that scenario, we + // need to offset gl_FragCoord using dx_FragCoordOffset to point to the correct location + // of the pixel. + if (shaderModel >= 4 && mRenderer->getShaderModelSuffix() == "") + { + pixelPrologue << " gl_FragCoord.x = input.dx_Position.x - dx_FragCoordOffset.x;\n" + << " gl_FragCoord.y = input.dx_Position.y - dx_FragCoordOffset.y;\n"; + } + else if (shaderModel == 3) + { + pixelPrologue + << " gl_FragCoord.x = input.dx_Position.x + 0.5 - dx_FragCoordOffset.x;\n" + << " gl_FragCoord.y = input.dx_Position.y + 0.5 - dx_FragCoordOffset.y;\n"; + } + else + { + // dx_ViewCoords contains the viewport width/2, height/2, center.x and center.y. See + // Renderer::setViewport() + pixelPrologue + << " gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_ViewCoords.x + " + "dx_ViewCoords.z - dx_FragCoordOffset.x;\n" + << " gl_FragCoord.y = (input.gl_FragCoord.y * rhw) * dx_ViewCoords.y + " + "dx_ViewCoords.w - dx_FragCoordOffset.y;\n"; + } + + if (programMetadata.usesViewScale()) + { + // For Feature Level 9_3 and below, we need to correct gl_FragCoord.y to account + // for dx_ViewScale. On Feature Level 10_0+, gl_FragCoord.y is calculated above using + // dx_ViewCoords and is always correct irrespective of dx_ViewScale's value. + // NOTE: usesViewScale() can only be true on D3D11 (i.e. Shader Model 4.0+). + if (shaderModel >= 4 && mRenderer->getShaderModelSuffix() == "") + { + // Some assumptions: + // - dx_ViewScale.y = -1.0f when rendering to texture + // - dx_ViewScale.y = +1.0f when rendering to the default framebuffer + // - gl_FragCoord.y has been set correctly above. + // + // When rendering to the backbuffer, the code inverts gl_FragCoord's y coordinate. + // This involves subtracting the y coordinate from the height of the area being + // rendered to. + // + // First we calculate the height of the area being rendered to: + // render_area_height = (2.0f / (1.0f - input.gl_FragCoord.y * rhw)) * + // gl_FragCoord.y + // + // Note that when we're rendering to default FB, we want our output to be + // equivalent to: + // "gl_FragCoord.y = render_area_height - gl_FragCoord.y" + // + // When we're rendering to a texture, we want our output to be equivalent to: + // "gl_FragCoord.y = gl_FragCoord.y;" + // + // If we set scale_factor = ((1.0f + dx_ViewScale.y) / 2.0f), then notice that + // - When rendering to default FB: scale_factor = 1.0f + // - When rendering to texture: scale_factor = 0.0f + // + // Therefore, we can get our desired output by setting: + // "gl_FragCoord.y = scale_factor * render_area_height - dx_ViewScale.y * + // gl_FragCoord.y" + // + // Simplifying, this becomes: + pixelPrologue + << " gl_FragCoord.y = (1.0f + dx_ViewScale.y) * gl_FragCoord.y /" + "(1.0f - input.gl_FragCoord.y * rhw) - dx_ViewScale.y * gl_FragCoord.y;\n"; + } + } + + pixelPrologue << " gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_DepthFront.x + " + "dx_DepthFront.y;\n" + << " gl_FragCoord.w = rhw;\n"; + } + + if (pixelBuiltins.glPointCoord.enabled && shaderModel >= 3) + { + pixelPrologue << " gl_PointCoord.x = input.gl_PointCoord.x;\n" + << " gl_PointCoord.y = 1.0 - input.gl_PointCoord.y;\n"; + } + + if (fragmentShader && fragmentShader->usesFrontFacing()) + { + if (shaderModel <= 3) + { + pixelPrologue << " gl_FrontFacing = (vFace * dx_DepthFront.z >= 0.0);\n"; + } + else + { + pixelPrologue << " gl_FrontFacing = isFrontFace;\n"; + } + } + + for (GLuint registerIndex = 0u; registerIndex < registerInfos.size(); ++registerIndex) + { + const PackedVaryingRegister ®isterInfo = registerInfos[registerIndex]; + const auto &packedVarying = *registerInfo.packedVarying; + + // Don't reference VS-only transform feedback varyings in the PS. + if (packedVarying.vertexOnly()) + { + continue; + } + + const auto &varying = *packedVarying.backVarying.varying; + ASSERT(!varying.isBuiltIn() && !varying.isStruct()); + + // Note that we're relying on that the active flag is set according to usage in the fragment + // shader. + if (!varying.active) + { + continue; + } + + pixelPrologue << " "; + + if (packedVarying.isStructField()) + { + pixelPrologue << DecorateVariable(packedVarying.backVarying.parentStructName) << "."; + } + + pixelPrologue << DecorateVariable(varying.name); + + if (varying.isArray()) + { + WriteArrayString(pixelPrologue, registerInfo.varyingArrayIndex); + } + + GLenum transposedType = TransposeMatrixType(varying.type); + if (VariableRowCount(transposedType) > 1) + { + WriteArrayString(pixelPrologue, registerInfo.varyingRowIndex); + } + + pixelPrologue << " = input.v" << registerIndex; + + switch (VariableColumnCount(transposedType)) + { + case 1: + pixelPrologue << ".x"; + break; + case 2: + pixelPrologue << ".xy"; + break; + case 3: + pixelPrologue << ".xyz"; + break; + case 4: + break; + default: + UNREACHABLE(); + } + pixelPrologue << ";\n"; + } + + if (fragmentShaderGL) + { + std::string pixelSource = fragmentShaderGL->getTranslatedSource(context); + + if (fragmentShader->usesFrontFacing()) + { + if (shaderModel >= 4) + { + angle::ReplaceSubstring(&pixelSource, + std::string(PIXEL_MAIN_PARAMETERS_STUB_STRING), + "PS_INPUT input, bool isFrontFace : SV_IsFrontFace"); + } + else + { + angle::ReplaceSubstring(&pixelSource, + std::string(PIXEL_MAIN_PARAMETERS_STUB_STRING), + "PS_INPUT input, float vFace : VFACE"); + } + } + else + { + angle::ReplaceSubstring(&pixelSource, std::string(PIXEL_MAIN_PARAMETERS_STUB_STRING), + "PS_INPUT input"); + } + + angle::ReplaceSubstring(&pixelSource, std::string(MAIN_PROLOGUE_STUB_STRING), + pixelPrologue.str()); + pixelStream << pixelSource; + } + + (*shaderHLSL)[gl::ShaderType::Vertex] = vertexStream.str(); + (*shaderHLSL)[gl::ShaderType::Fragment] = pixelStream.str(); +} + +std::string DynamicHLSL::generateGeometryShaderPreamble(const VaryingPacking &varyingPacking, + const BuiltinVaryingsD3D &builtinsD3D, + const bool hasANGLEMultiviewEnabled, + const bool selectViewInVS) const +{ + ASSERT(mRenderer->getMajorShaderModel() >= 4); + + std::ostringstream preambleStream; + + const auto &vertexBuiltins = builtinsD3D[gl::ShaderType::Vertex]; + + preambleStream << "struct GS_INPUT\n"; + generateVaryingLinkHLSL(varyingPacking, vertexBuiltins, builtinsD3D.usesPointSize(), + preambleStream); + preambleStream << "\n" + << "struct GS_OUTPUT\n"; + generateVaryingLinkHLSL(varyingPacking, builtinsD3D[gl::ShaderType::Geometry], + builtinsD3D.usesPointSize(), preambleStream); + preambleStream + << "\n" + << "void copyVertex(inout GS_OUTPUT output, GS_INPUT input, GS_INPUT flatinput)\n" + << "{\n" + << " output.gl_Position = input.gl_Position;\n"; + + if (vertexBuiltins.glPointSize.enabled) + { + preambleStream << " output.gl_PointSize = input.gl_PointSize;\n"; + } + + if (hasANGLEMultiviewEnabled) + { + preambleStream << " output.gl_ViewID_OVR = input.gl_ViewID_OVR;\n"; + if (selectViewInVS) + { + ASSERT(builtinsD3D[gl::ShaderType::Geometry].glViewportIndex.enabled && + builtinsD3D[gl::ShaderType::Geometry].glLayer.enabled); + + // If the view is already selected in the VS, then we just pass the gl_ViewportIndex and + // gl_Layer to the output. + preambleStream << " output.gl_ViewportIndex = input.gl_ViewportIndex;\n" + << " output.gl_Layer = input.gl_Layer;\n"; + } + } + + const auto ®isterInfos = varyingPacking.getRegisterList(); + for (GLuint registerIndex = 0u; registerIndex < registerInfos.size(); ++registerIndex) + { + const PackedVaryingRegister &varyingRegister = registerInfos[registerIndex]; + preambleStream << " output.v" << registerIndex << " = "; + if (varyingRegister.packedVarying->interpolation == sh::INTERPOLATION_FLAT) + { + preambleStream << "flat"; + } + preambleStream << "input.v" << registerIndex << "; \n"; + } + + if (vertexBuiltins.glFragCoord.enabled) + { + preambleStream << " output.gl_FragCoord = input.gl_FragCoord;\n"; + } + + // Only write the dx_Position if we aren't using point sprites + preambleStream << "#ifndef ANGLE_POINT_SPRITE_SHADER\n" + << " output.dx_Position = input.dx_Position;\n" + << "#endif // ANGLE_POINT_SPRITE_SHADER\n" + << "}\n"; + + if (hasANGLEMultiviewEnabled && !selectViewInVS) + { + ASSERT(builtinsD3D[gl::ShaderType::Geometry].glViewportIndex.enabled && + builtinsD3D[gl::ShaderType::Geometry].glLayer.enabled); + + // According to the HLSL reference, using SV_RenderTargetArrayIndex is only valid if the + // render target is an array resource. Because of this we do not write to gl_Layer if we are + // taking the side-by-side code path. We still select the viewport index in the layered code + // path as that is always valid. See: + // https://msdn.microsoft.com/en-us/library/windows/desktop/bb509647(v=vs.85).aspx + preambleStream << "\n" + << "void selectView(inout GS_OUTPUT output, GS_INPUT input)\n" + << "{\n" + << " if (multiviewSelectViewportIndex)\n" + << " {\n" + << " output.gl_ViewportIndex = input.gl_ViewID_OVR;\n" + << " } else {\n" + << " output.gl_ViewportIndex = 0;\n" + << " output.gl_Layer = input.gl_ViewID_OVR;\n" + << " }\n" + << "}\n"; + } + + return preambleStream.str(); +} + +std::string DynamicHLSL::generateGeometryShaderHLSL(const gl::Caps &caps, + gl::PrimitiveMode primitiveType, + const gl::ProgramState &programData, + const bool useViewScale, + const bool hasANGLEMultiviewEnabled, + const bool selectViewInVS, + const bool pointSpriteEmulation, + const std::string &preambleString) const +{ + ASSERT(mRenderer->getMajorShaderModel() >= 4); + + std::stringstream shaderStream; + + const bool pointSprites = (primitiveType == gl::PrimitiveMode::Points) && pointSpriteEmulation; + const bool usesPointCoord = preambleString.find("gl_PointCoord") != std::string::npos; + + const char *inputPT = nullptr; + const char *outputPT = nullptr; + int inputSize = 0; + int maxVertexOutput = 0; + + switch (primitiveType) + { + case gl::PrimitiveMode::Points: + inputPT = "point"; + inputSize = 1; + + if (pointSprites) + { + outputPT = "Triangle"; + maxVertexOutput = 4; + } + else + { + outputPT = "Point"; + maxVertexOutput = 1; + } + + break; + + case gl::PrimitiveMode::Lines: + case gl::PrimitiveMode::LineStrip: + case gl::PrimitiveMode::LineLoop: + inputPT = "line"; + outputPT = "Line"; + inputSize = 2; + maxVertexOutput = 2; + break; + + case gl::PrimitiveMode::Triangles: + case gl::PrimitiveMode::TriangleStrip: + case gl::PrimitiveMode::TriangleFan: + inputPT = "triangle"; + outputPT = "Triangle"; + inputSize = 3; + maxVertexOutput = 3; + break; + + default: + UNREACHABLE(); + break; + } + + if (pointSprites || hasANGLEMultiviewEnabled) + { + shaderStream << "cbuffer DriverConstants : register(b0)\n" + "{\n"; + + if (pointSprites) + { + shaderStream << " float4 dx_ViewCoords : packoffset(c1);\n"; + if (useViewScale) + { + shaderStream << " float2 dx_ViewScale : packoffset(c3.z);\n"; + } + } + + if (hasANGLEMultiviewEnabled) + { + // We have to add a value which we can use to keep track of which multi-view code path + // is to be selected in the GS. + shaderStream << " float multiviewSelectViewportIndex : packoffset(c4.x);\n"; + } + + shaderStream << "};\n\n"; + } + + if (pointSprites) + { + shaderStream << "#define ANGLE_POINT_SPRITE_SHADER\n" + "\n" + "static float2 pointSpriteCorners[] = \n" + "{\n" + " float2( 0.5f, -0.5f),\n" + " float2( 0.5f, 0.5f),\n" + " float2(-0.5f, -0.5f),\n" + " float2(-0.5f, 0.5f)\n" + "};\n" + "\n" + "static float2 pointSpriteTexcoords[] = \n" + "{\n" + " float2(1.0f, 1.0f),\n" + " float2(1.0f, 0.0f),\n" + " float2(0.0f, 1.0f),\n" + " float2(0.0f, 0.0f)\n" + "};\n" + "\n" + "static float minPointSize = " + << static_cast(caps.minAliasedPointSize) + << ".0f;\n" + "static float maxPointSize = " + << static_cast(caps.maxAliasedPointSize) << ".0f;\n" + << "\n"; + } + + shaderStream << preambleString << "\n" + << "[maxvertexcount(" << maxVertexOutput << ")]\n" + << "void main(" << inputPT << " GS_INPUT input[" << inputSize << "], "; + + if (primitiveType == gl::PrimitiveMode::TriangleStrip) + { + shaderStream << "uint primitiveID : SV_PrimitiveID, "; + } + + shaderStream << " inout " << outputPT << "Stream outStream)\n" + << "{\n" + << " GS_OUTPUT output = (GS_OUTPUT)0;\n"; + + if (primitiveType == gl::PrimitiveMode::TriangleStrip) + { + shaderStream << " uint lastVertexIndex = (primitiveID % 2 == 0 ? 2 : 1);\n"; + } + else + { + shaderStream << " uint lastVertexIndex = " << (inputSize - 1) << ";\n"; + } + + for (int vertexIndex = 0; vertexIndex < inputSize; ++vertexIndex) + { + shaderStream << " copyVertex(output, input[" << vertexIndex + << "], input[lastVertexIndex]);\n"; + if (hasANGLEMultiviewEnabled && !selectViewInVS) + { + shaderStream << " selectView(output, input[" << vertexIndex << "]);\n"; + } + if (!pointSprites) + { + ASSERT(inputSize == maxVertexOutput); + shaderStream << " outStream.Append(output);\n"; + } + } + + if (pointSprites) + { + shaderStream << "\n" + " float4 dx_Position = input[0].dx_Position;\n" + " float gl_PointSize = clamp(input[0].gl_PointSize, minPointSize, " + "maxPointSize);\n" + " float2 viewportScale = float2(1.0f / dx_ViewCoords.x, 1.0f / " + "dx_ViewCoords.y) * dx_Position.w;\n"; + + for (int corner = 0; corner < 4; corner++) + { + if (useViewScale) + { + shaderStream << " \n" + " output.dx_Position = dx_Position + float4(1.0f, " + "-dx_ViewScale.y, 1.0f, 1.0f)" + " * float4(pointSpriteCorners[" + << corner << "] * viewportScale * gl_PointSize, 0.0f, 0.0f);\n"; + } + else + { + shaderStream << "\n" + " output.dx_Position = dx_Position + float4(pointSpriteCorners[" + << corner << "] * viewportScale * gl_PointSize, 0.0f, 0.0f);\n"; + } + + if (usesPointCoord) + { + shaderStream << " output.gl_PointCoord = pointSpriteTexcoords[" << corner + << "];\n"; + } + + shaderStream << " outStream.Append(output);\n"; + } + } + + shaderStream << " \n" + " outStream.RestartStrip();\n" + "}\n"; + + return shaderStream.str(); +} + +// static +void DynamicHLSL::GenerateAttributeConversionHLSL(angle::FormatID vertexFormatID, + const sh::ShaderVariable &shaderAttrib, + std::ostringstream &outStream) +{ + // Matrix + if (IsMatrixType(shaderAttrib.type)) + { + outStream << "transpose(input." << DecorateVariable(shaderAttrib.name) << ")"; + return; + } + + GLenum shaderComponentType = VariableComponentType(shaderAttrib.type); + int shaderComponentCount = VariableComponentCount(shaderAttrib.type); + const gl::VertexFormat &vertexFormat = gl::GetVertexFormatFromID(vertexFormatID); + + // Perform integer to float conversion (if necessary) + if (shaderComponentType == GL_FLOAT && vertexFormat.type != GL_FLOAT) + { + // TODO: normalization for 32-bit integer formats + ASSERT(!vertexFormat.normalized && !vertexFormat.pureInteger); + outStream << "float" << shaderComponentCount << "(input." + << DecorateVariable(shaderAttrib.name) << ")"; + return; + } + + // No conversion necessary + outStream << "input." << DecorateVariable(shaderAttrib.name); +} + +void DynamicHLSL::getPixelShaderOutputKey(const gl::State &data, + const gl::ProgramState &programData, + const ProgramD3DMetadata &metadata, + std::vector *outPixelShaderKey) +{ + // Two cases when writing to gl_FragColor and using ESSL 1.0: + // - with a 3.0 context, the output color is copied to channel 0 + // - with a 2.0 context, the output color is broadcast to all channels + bool broadcast = metadata.usesBroadcast(data); + const unsigned int numRenderTargets = + (broadcast || metadata.usesMultipleFragmentOuts() + ? static_cast(data.getCaps().maxDrawBuffers) + : 1); + + if (!metadata.usesCustomOutVars()) + { + for (unsigned int renderTargetIndex = 0; renderTargetIndex < numRenderTargets; + renderTargetIndex++) + { + PixelShaderOutputVariable outputKeyVariable; + outputKeyVariable.type = GL_FLOAT_VEC4; + outputKeyVariable.name = "gl_Color" + Str(renderTargetIndex); + outputKeyVariable.source = + broadcast ? "gl_Color[0]" : "gl_Color[" + Str(renderTargetIndex) + "]"; + outputKeyVariable.outputLocation = renderTargetIndex; + + outPixelShaderKey->push_back(outputKeyVariable); + } + + if (metadata.usesSecondaryColor()) + { + for (unsigned int secondaryIndex = 0; + secondaryIndex < data.getCaps().maxDualSourceDrawBuffers; secondaryIndex++) + { + PixelShaderOutputVariable outputKeyVariable; + outputKeyVariable.type = GL_FLOAT_VEC4; + outputKeyVariable.name = "gl_SecondaryColor" + Str(secondaryIndex); + outputKeyVariable.source = "gl_SecondaryColor[" + Str(secondaryIndex) + "]"; + outputKeyVariable.outputLocation = secondaryIndex; + outputKeyVariable.outputIndex = 1; + + outPixelShaderKey->push_back(outputKeyVariable); + } + } + } + else + { + const ShaderD3D *fragmentShader = metadata.getFragmentShader(); + + if (!fragmentShader) + { + return; + } + + const auto &shaderOutputVars = fragmentShader->getState().getActiveOutputVariables(); + + for (size_t outputLocationIndex = 0u; + outputLocationIndex < programData.getOutputLocations().size(); ++outputLocationIndex) + { + const VariableLocation &outputLocation = + programData.getOutputLocations().at(outputLocationIndex); + if (!outputLocation.used()) + { + continue; + } + const sh::ShaderVariable &outputVariable = shaderOutputVars[outputLocation.index]; + const std::string &variableName = "out_" + outputVariable.name; + + // Fragment outputs can't be arrays of arrays. ESSL 3.10 section 4.3.6. + const std::string &elementString = + (outputVariable.isArray() ? Str(outputLocation.arrayIndex) : ""); + + ASSERT(outputVariable.active); + + PixelShaderOutputVariable outputKeyVariable; + outputKeyVariable.type = outputVariable.type; + outputKeyVariable.name = variableName + elementString; + outputKeyVariable.source = + variableName + + (outputVariable.isArray() ? ArrayString(outputLocation.arrayIndex) : ""); + outputKeyVariable.outputLocation = outputLocationIndex; + + outPixelShaderKey->push_back(outputKeyVariable); + } + + // Now generate any secondary outputs... + for (size_t outputLocationIndex = 0u; + outputLocationIndex < programData.getSecondaryOutputLocations().size(); + ++outputLocationIndex) + { + const VariableLocation &outputLocation = + programData.getSecondaryOutputLocations().at(outputLocationIndex); + if (!outputLocation.used()) + { + continue; + } + const sh::ShaderVariable &outputVariable = shaderOutputVars[outputLocation.index]; + const std::string &variableName = "out_" + outputVariable.name; + + // Fragment outputs can't be arrays of arrays. ESSL 3.10 section 4.3.6. + const std::string &elementString = + (outputVariable.isArray() ? Str(outputLocation.arrayIndex) : ""); + + ASSERT(outputVariable.active); + + PixelShaderOutputVariable outputKeyVariable; + outputKeyVariable.type = outputVariable.type; + outputKeyVariable.name = variableName + elementString; + outputKeyVariable.source = + variableName + + (outputVariable.isArray() ? ArrayString(outputLocation.arrayIndex) : ""); + outputKeyVariable.outputLocation = outputLocationIndex; + outputKeyVariable.outputIndex = 1; + + outPixelShaderKey->push_back(outputKeyVariable); + } + } +} + +// BuiltinVarying Implementation. +BuiltinVarying::BuiltinVarying() : enabled(false), index(0), systemValue(false) {} + +std::string BuiltinVarying::str() const +{ + return (systemValue ? semantic : (semantic + Str(index))); +} + +void BuiltinVarying::enableSystem(const std::string &systemValueSemantic) +{ + enabled = true; + semantic = systemValueSemantic; + systemValue = true; +} + +void BuiltinVarying::enable(const std::string &semanticVal, unsigned int indexVal) +{ + enabled = true; + semantic = semanticVal; + index = indexVal; +} + +// BuiltinVaryingsD3D Implementation. +BuiltinVaryingsD3D::BuiltinVaryingsD3D(const ProgramD3DMetadata &metadata, + const VaryingPacking &packing) +{ + updateBuiltins(gl::ShaderType::Vertex, metadata, packing); + updateBuiltins(gl::ShaderType::Fragment, metadata, packing); + int shaderModel = metadata.getRendererMajorShaderModel(); + if (shaderModel >= 4) + { + updateBuiltins(gl::ShaderType::Geometry, metadata, packing); + } + // In shader model >= 4, some builtins need to be the same in vertex and pixel shaders - input + // struct needs to be a prefix of output struct. + ASSERT(shaderModel < 4 || mBuiltinInfo[gl::ShaderType::Vertex].glPosition.enabled == + mBuiltinInfo[gl::ShaderType::Fragment].glPosition.enabled); + ASSERT(shaderModel < 4 || mBuiltinInfo[gl::ShaderType::Vertex].glFragCoord.enabled == + mBuiltinInfo[gl::ShaderType::Fragment].glFragCoord.enabled); + ASSERT(shaderModel < 4 || mBuiltinInfo[gl::ShaderType::Vertex].glPointCoord.enabled == + mBuiltinInfo[gl::ShaderType::Fragment].glPointCoord.enabled); + ASSERT(shaderModel < 4 || mBuiltinInfo[gl::ShaderType::Vertex].glPointSize.enabled == + mBuiltinInfo[gl::ShaderType::Fragment].glPointSize.enabled); + ASSERT(shaderModel < 4 || mBuiltinInfo[gl::ShaderType::Vertex].glViewIDOVR.enabled == + mBuiltinInfo[gl::ShaderType::Fragment].glViewIDOVR.enabled); +} + +BuiltinVaryingsD3D::~BuiltinVaryingsD3D() = default; + +void BuiltinVaryingsD3D::updateBuiltins(gl::ShaderType shaderType, + const ProgramD3DMetadata &metadata, + const VaryingPacking &packing) +{ + const std::string &userSemantic = GetVaryingSemantic(metadata.getRendererMajorShaderModel(), + metadata.usesSystemValuePointSize()); + + // Note that when enabling builtins only for specific shader stages in shader model >= 4, the + // code needs to ensure that the input struct of the shader stage is a prefix of the output + // struct of the previous stage. + + unsigned int reservedSemanticIndex = packing.getMaxSemanticIndex(); + + BuiltinInfo *builtins = &mBuiltinInfo[shaderType]; + + if (metadata.getRendererMajorShaderModel() >= 4) + { + builtins->dxPosition.enableSystem("SV_Position"); + } + else if (shaderType == gl::ShaderType::Fragment) + { + builtins->dxPosition.enableSystem("VPOS"); + } + else + { + builtins->dxPosition.enableSystem("POSITION"); + } + + if (metadata.usesTransformFeedbackGLPosition()) + { + builtins->glPosition.enable(userSemantic, reservedSemanticIndex++); + } + + if (metadata.usesFragCoord()) + { + builtins->glFragCoord.enable(userSemantic, reservedSemanticIndex++); + } + + if (shaderType == gl::ShaderType::Vertex ? metadata.addsPointCoordToVertexShader() + : metadata.usesPointCoord()) + { + // SM3 reserves the TEXCOORD semantic for point sprite texcoords (gl_PointCoord) + // In D3D11 we manually compute gl_PointCoord in the GS. + if (metadata.getRendererMajorShaderModel() >= 4) + { + builtins->glPointCoord.enable(userSemantic, reservedSemanticIndex++); + } + else + { + builtins->glPointCoord.enable("TEXCOORD", 0); + } + } + + if (metadata.hasANGLEMultiviewEnabled()) + { + // Although it is possible to compute gl_ViewID_OVR from the value of + // SV_ViewportArrayIndex or SV_RenderTargetArrayIndex and the multi-view state in the + // driver constant buffer, it is easier and cleaner to always pass it as a varying. + builtins->glViewIDOVR.enable(userSemantic, reservedSemanticIndex++); + + if (shaderType == gl::ShaderType::Vertex) + { + if (metadata.canSelectViewInVertexShader()) + { + builtins->glViewportIndex.enableSystem("SV_ViewportArrayIndex"); + builtins->glLayer.enableSystem("SV_RenderTargetArrayIndex"); + } + } + + if (shaderType == gl::ShaderType::Geometry) + { + // gl_Layer and gl_ViewportIndex are necessary so that we can write to either based on + // the multiview state in the driver constant buffer. + builtins->glViewportIndex.enableSystem("SV_ViewportArrayIndex"); + builtins->glLayer.enableSystem("SV_RenderTargetArrayIndex"); + } + } + + // Special case: do not include PSIZE semantic in HLSL 3 pixel shaders + if (metadata.usesSystemValuePointSize() && + (shaderType != gl::ShaderType::Fragment || metadata.getRendererMajorShaderModel() >= 4)) + { + builtins->glPointSize.enableSystem("PSIZE"); + } +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicHLSL.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicHLSL.h new file mode 100644 index 0000000000..3398bae8d7 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicHLSL.h @@ -0,0 +1,212 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// DynamicHLSL.h: Interface for link and run-time HLSL generation +// + +#ifndef LIBANGLE_RENDERER_D3D_DYNAMICHLSL_H_ +#define LIBANGLE_RENDERER_D3D_DYNAMICHLSL_H_ + +#include +#include + +#include "angle_gl.h" +#include "common/angleutils.h" +#include "libANGLE/Constants.h" +#include "libANGLE/Program.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/DynamicImage2DHLSL.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" + +namespace sh +{ +struct ShaderVariable; +} // namespace sh + +namespace gl +{ +class InfoLog; +struct VariableLocation; +class VaryingPacking; +struct VertexAttribute; +} // namespace gl + +namespace rx +{ +class ProgramD3DMetadata; +class ShaderD3D; +struct ShaderStorageBlock; + +// This class needs to match OutputHLSL::decorate +class DecorateVariable final : angle::NonCopyable +{ + public: + explicit DecorateVariable(const std::string &str) : mName(str) {} + const std::string &getName() const { return mName; } + + private: + const std::string &mName; +}; + +inline std::ostream &operator<<(std::ostream &o, const DecorateVariable &dv) +{ + if (dv.getName().compare(0, 3, "gl_") != 0) + { + o << "_"; + } + o << dv.getName(); + return o; +} + +struct PixelShaderOutputVariable +{ + PixelShaderOutputVariable() {} + PixelShaderOutputVariable(GLenum typeIn, + const std::string &nameIn, + const std::string &sourceIn, + size_t outputLocationIn, + size_t outputIndexIn) + : type(typeIn), + name(nameIn), + source(sourceIn), + outputLocation(outputLocationIn), + outputIndex(outputIndexIn) + {} + + GLenum type = GL_NONE; + std::string name; + std::string source; + size_t outputLocation = 0; + size_t outputIndex = 0; +}; + +struct BuiltinVarying final : private angle::NonCopyable +{ + BuiltinVarying(); + + std::string str() const; + void enableSystem(const std::string &systemValueSemantic); + void enable(const std::string &semanticVal, unsigned int indexVal); + + bool enabled; + std::string semantic; + unsigned int index; + bool systemValue; +}; + +struct BuiltinInfo +{ + BuiltinInfo(); + ~BuiltinInfo(); + + BuiltinVarying dxPosition; + BuiltinVarying glPosition; + BuiltinVarying glFragCoord; + BuiltinVarying glPointCoord; + BuiltinVarying glPointSize; + BuiltinVarying glViewIDOVR; + BuiltinVarying glViewportIndex; + BuiltinVarying glLayer; +}; + +inline std::string GetVaryingSemantic(int majorShaderModel, bool programUsesPointSize) +{ + // SM3 reserves the TEXCOORD semantic for point sprite texcoords (gl_PointCoord) + // In D3D11 we manually compute gl_PointCoord in the GS. + return ((programUsesPointSize && majorShaderModel < 4) ? "COLOR" : "TEXCOORD"); +} + +class BuiltinVaryingsD3D +{ + public: + BuiltinVaryingsD3D(const ProgramD3DMetadata &metadata, const gl::VaryingPacking &packing); + ~BuiltinVaryingsD3D(); + + bool usesPointSize() const { return mBuiltinInfo[gl::ShaderType::Vertex].glPointSize.enabled; } + + const BuiltinInfo &operator[](gl::ShaderType shaderType) const + { + return mBuiltinInfo[shaderType]; + } + BuiltinInfo &operator[](gl::ShaderType shaderType) { return mBuiltinInfo[shaderType]; } + + private: + void updateBuiltins(gl::ShaderType shaderType, + const ProgramD3DMetadata &metadata, + const gl::VaryingPacking &packing); + + gl::ShaderMap mBuiltinInfo; +}; + +class DynamicHLSL : angle::NonCopyable +{ + public: + explicit DynamicHLSL(RendererD3D *const renderer); + + std::string generateVertexShaderForInputLayout( + const std::string &sourceShader, + const gl::InputLayout &inputLayout, + const std::vector &shaderAttributes, + const std::vector &shaderStorageBlocks, + size_t baseUAVRegister) const; + std::string generatePixelShaderForOutputSignature( + const std::string &sourceShader, + const std::vector &outputVariables, + bool usesFragDepth, + const std::vector &outputLayout, + const std::vector &shaderStorageBlocks, + size_t baseUAVRegister) const; + std::string generateShaderForImage2DBindSignature( + ProgramD3D &programD3D, + const gl::ProgramState &programData, + gl::ShaderType shaderType, + const std::string &shaderHLSL, + std::vector &image2DUniforms, + const gl::ImageUnitTextureTypeMap &image2DBindLayout, + unsigned int baseUAVRegister) const; + void generateShaderLinkHLSL(const gl::Context *context, + const gl::Caps &caps, + const gl::ProgramState &programData, + const ProgramD3DMetadata &programMetadata, + const gl::VaryingPacking &varyingPacking, + const BuiltinVaryingsD3D &builtinsD3D, + gl::ShaderMap *shaderHLSL) const; + + std::string generateGeometryShaderPreamble(const gl::VaryingPacking &varyingPacking, + const BuiltinVaryingsD3D &builtinsD3D, + const bool hasANGLEMultiviewEnabled, + const bool selectViewInVS) const; + + std::string generateGeometryShaderHLSL(const gl::Caps &caps, + gl::PrimitiveMode primitiveType, + const gl::ProgramState &programData, + const bool useViewScale, + const bool hasANGLEMultiviewEnabled, + const bool selectViewInVS, + const bool pointSpriteEmulation, + const std::string &preambleString) const; + + void getPixelShaderOutputKey(const gl::State &data, + const gl::ProgramState &programData, + const ProgramD3DMetadata &metadata, + std::vector *outPixelShaderKey); + + private: + RendererD3D *const mRenderer; + + void generateVaryingLinkHLSL(const gl::VaryingPacking &varyingPacking, + const BuiltinInfo &builtins, + bool programUsesPointSize, + std::ostringstream &hlslStream) const; + + static void GenerateAttributeConversionHLSL(angle::FormatID vertexFormatID, + const sh::ShaderVariable &shaderAttrib, + std::ostringstream &outStream); +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_DYNAMICHLSL_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicImage2DHLSL.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicImage2DHLSL.cpp new file mode 100644 index 0000000000..cf775d0b46 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicImage2DHLSL.cpp @@ -0,0 +1,919 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// DynamicImage2DHLSL.cpp: Implementation for link and run-time HLSL generation +// + +#include "libANGLE/renderer/d3d/DynamicImage2DHLSL.h" + +#include "common/string_utils.h" +#include "libANGLE/renderer/d3d/ProgramD3D.h" +#include "libANGLE/renderer/d3d/ShaderD3D.h" + +using namespace gl; + +namespace rx +{ + +namespace +{ + +enum Image2DHLSLGroup +{ + IMAGE2D_R_FLOAT4, + IMAGE2D_MIN = IMAGE2D_R_FLOAT4, + IMAGE2D_R_UNORM, + IMAGE2D_R_SNORM, + IMAGE2D_R_UINT4, + IMAGE2D_R_INT4, + IMAGE2D_W_FLOAT4, + IMAGE2D_W_UNORM, + IMAGE2D_W_SNORM, + IMAGE2D_W_UINT4, + IMAGE2D_W_INT4, + IMAGE2D_UNKNOWN, + IMAGE2D_MAX = IMAGE2D_UNKNOWN +}; + +enum Image2DMethod +{ + IMAGE2DSIZE, + IMAGE2DLOAD, + IMAGE2DSTORE +}; + +Image2DHLSLGroup image2DHLSLGroup(const sh::ShaderVariable &uniform) +{ + GLenum format = uniform.imageUnitFormat; + bool readonly = uniform.readonly; + switch (uniform.type) + { + case GL_IMAGE_2D: + { + switch (format) + { + case GL_RGBA32F: + case GL_RGBA16F: + case GL_R32F: + return readonly ? IMAGE2D_R_FLOAT4 : IMAGE2D_W_FLOAT4; + case GL_RGBA8: + return readonly ? IMAGE2D_R_UNORM : IMAGE2D_W_UNORM; + case GL_RGBA8_SNORM: + return readonly ? IMAGE2D_R_SNORM : IMAGE2D_W_SNORM; + default: + UNREACHABLE(); + return IMAGE2D_UNKNOWN; + } + } + case GL_INT_IMAGE_2D: + { + switch (format) + { + case GL_RGBA32I: + case GL_RGBA16I: + case GL_RGBA8I: + case GL_R32I: + return readonly ? IMAGE2D_R_INT4 : IMAGE2D_W_INT4; + default: + UNREACHABLE(); + return IMAGE2D_UNKNOWN; + } + } + case GL_UNSIGNED_INT_IMAGE_2D: + { + switch (format) + { + case GL_RGBA32UI: + case GL_RGBA16UI: + case GL_RGBA8UI: + case GL_R32UI: + return readonly ? IMAGE2D_R_UINT4 : IMAGE2D_W_UINT4; + default: + UNREACHABLE(); + return IMAGE2D_UNKNOWN; + } + } + default: + UNREACHABLE(); + return IMAGE2D_UNKNOWN; + } +} + +std::string Image2DHLSLGroupSuffix(Image2DHLSLGroup group) +{ + switch (group) + { + case IMAGE2D_R_FLOAT4: + return "2D"; + case IMAGE2D_R_UNORM: + return "2D_unorm_float4_"; + case IMAGE2D_R_SNORM: + return "2D_snorm_float4_"; + case IMAGE2D_R_UINT4: + return "2D_uint4_"; + case IMAGE2D_R_INT4: + return "2D_int4_"; + case IMAGE2D_W_FLOAT4: + return "RW2D_float4_"; + case IMAGE2D_W_UNORM: + return "RW2D_unorm_float4_"; + case IMAGE2D_W_SNORM: + return "RW2D_snorm_float4_"; + case IMAGE2D_W_UINT4: + return "RW2D_uint4_"; + case IMAGE2D_W_INT4: + return "RW2D_int4_"; + default: + UNREACHABLE(); + } + + return ""; +} + +std::string Image2DHLSLTextureString(Image2DHLSLGroup group, + gl::TextureType type, + bool rasterOrdered) +{ + std::string textureString; + switch (group) + { + case IMAGE2D_R_FLOAT4: + case IMAGE2D_R_UNORM: + case IMAGE2D_R_SNORM: + case IMAGE2D_R_UINT4: + case IMAGE2D_R_INT4: + break; + case IMAGE2D_W_FLOAT4: + case IMAGE2D_W_UNORM: + case IMAGE2D_W_SNORM: + case IMAGE2D_W_UINT4: + case IMAGE2D_W_INT4: + textureString += rasterOrdered ? "RasterizerOrdered" : "RW"; + break; + default: + UNREACHABLE(); + } + + textureString += "Texture"; + + switch (type) + { + case gl::TextureType::_2D: + textureString += "2D"; + break; + case gl::TextureType::_3D: + textureString += "3D"; + break; + case gl::TextureType::_2DArray: + textureString += "2DArray"; + break; + default: + UNREACHABLE(); + } + + switch (group) + { + case IMAGE2D_R_FLOAT4: + case IMAGE2D_W_FLOAT4: + textureString += ""; + break; + case IMAGE2D_R_UNORM: + case IMAGE2D_W_UNORM: + textureString += ""; + break; + case IMAGE2D_R_SNORM: + case IMAGE2D_W_SNORM: + textureString += ""; + break; + case IMAGE2D_R_UINT4: + case IMAGE2D_W_UINT4: + textureString += ""; + break; + case IMAGE2D_R_INT4: + case IMAGE2D_W_INT4: + textureString += ""; + break; + default: + UNREACHABLE(); + } + + return textureString; +} + +std::string Image2DHLSLGroupOffsetPrefix(Image2DHLSLGroup group) +{ + switch (group) + { + case IMAGE2D_R_FLOAT4: + case IMAGE2D_R_UNORM: + case IMAGE2D_R_SNORM: + case IMAGE2D_R_UINT4: + case IMAGE2D_R_INT4: + return "readonlyImageIndexOffset"; + case IMAGE2D_W_FLOAT4: + case IMAGE2D_W_UNORM: + case IMAGE2D_W_SNORM: + case IMAGE2D_W_UINT4: + case IMAGE2D_W_INT4: + return "imageIndexOffset"; + default: + UNREACHABLE(); + } + + return ""; +} + +std::string Image2DHLSLGroupDeclarationPrefix(Image2DHLSLGroup group) +{ + switch (group) + { + case IMAGE2D_R_FLOAT4: + case IMAGE2D_R_UNORM: + case IMAGE2D_R_SNORM: + case IMAGE2D_R_UINT4: + case IMAGE2D_R_INT4: + return "readonlyImages"; + case IMAGE2D_W_FLOAT4: + case IMAGE2D_W_UNORM: + case IMAGE2D_W_SNORM: + case IMAGE2D_W_UINT4: + case IMAGE2D_W_INT4: + return "images"; + default: + UNREACHABLE(); + } + + return ""; +} + +std::string Image2DHLSLGroupRegisterSuffix(Image2DHLSLGroup group) +{ + switch (group) + { + case IMAGE2D_R_FLOAT4: + case IMAGE2D_R_UNORM: + case IMAGE2D_R_SNORM: + case IMAGE2D_R_UINT4: + case IMAGE2D_R_INT4: + return "t"; + case IMAGE2D_W_FLOAT4: + case IMAGE2D_W_UNORM: + case IMAGE2D_W_SNORM: + case IMAGE2D_W_UINT4: + case IMAGE2D_W_INT4: + return "u"; + default: + UNREACHABLE(); + } + + return ""; +} + +std::string Image2DHLSLGroupFunctionName(Image2DHLSLGroup group, Image2DMethod method) +{ + std::string name = "gl_image"; + name += Image2DHLSLGroupSuffix(group); + switch (method) + { + case IMAGE2DSIZE: + name += "Size"; + break; + case IMAGE2DLOAD: + name += "Load"; + break; + case IMAGE2DSTORE: + name += "Store"; + break; + default: + UNREACHABLE(); + } + + return name; +} + +std::string getImage2DGroupReturnType(Image2DHLSLGroup group, Image2DMethod method) +{ + switch (method) + { + case IMAGE2DSIZE: + return "int2"; + case IMAGE2DLOAD: + switch (group) + { + case IMAGE2D_R_FLOAT4: + case IMAGE2D_R_UNORM: + case IMAGE2D_R_SNORM: + case IMAGE2D_W_FLOAT4: + case IMAGE2D_W_UNORM: + case IMAGE2D_W_SNORM: + return "float4"; + case IMAGE2D_R_UINT4: + case IMAGE2D_W_UINT4: + return "uint4"; + case IMAGE2D_R_INT4: + case IMAGE2D_W_INT4: + return "int4"; + default: + UNREACHABLE(); + return "unknown group type"; + } + case IMAGE2DSTORE: + return "void"; + default: + UNREACHABLE(); + return "unknown image method"; + } +} + +std::string getImageMetadata(Image2DHLSLGroup group) +{ + switch (group) + { + case IMAGE2D_R_FLOAT4: + case IMAGE2D_R_UNORM: + case IMAGE2D_R_SNORM: + case IMAGE2D_R_UINT4: + case IMAGE2D_R_INT4: + return "readonlyImageMetadata[imageIndex - readonlyImageIndexStart]"; + case IMAGE2D_W_FLOAT4: + case IMAGE2D_W_UNORM: + case IMAGE2D_W_SNORM: + case IMAGE2D_W_UINT4: + case IMAGE2D_W_INT4: + return "imageMetadata[imageIndex - imageIndexStart]"; + default: + UNREACHABLE(); + return "unknown image method"; + } +} + +void OutputImage2DFunctionArgumentList(std::ostringstream &out, + Image2DHLSLGroup group, + Image2DMethod method) +{ + out << "uint imageIndex"; + + if (method == IMAGE2DLOAD || method == IMAGE2DSTORE) + { + out << ", int2 p"; + if (method == IMAGE2DSTORE) + { + switch (group) + { + case IMAGE2D_R_FLOAT4: + case IMAGE2D_R_UNORM: + case IMAGE2D_R_SNORM: + case IMAGE2D_W_FLOAT4: + case IMAGE2D_W_UNORM: + case IMAGE2D_W_SNORM: + out << ", float4 data"; + break; + case IMAGE2D_R_UINT4: + case IMAGE2D_W_UINT4: + out << ", uint4 data"; + break; + case IMAGE2D_R_INT4: + case IMAGE2D_W_INT4: + out << ", int4 data"; + break; + default: + UNREACHABLE(); + } + } + } +} + +void OutputImage2DSizeFunction(std::ostringstream &out, + Image2DHLSLGroup textureGroup, + unsigned int totalCount, + unsigned int texture2DCount, + unsigned int texture3DCount, + unsigned int texture2DArrayCount, + const std::string &offsetStr, + const std::string &declarationStr) +{ + out << getImage2DGroupReturnType(textureGroup, IMAGE2DSIZE) << " " + << Image2DHLSLGroupFunctionName(textureGroup, IMAGE2DSIZE) << "("; + OutputImage2DFunctionArgumentList(out, textureGroup, IMAGE2DSIZE); + out << ")\n" + "{\n"; + out << " uint width, height;\n"; + + if (texture2DCount > 0) + { + if (texture2DCount == totalCount) + { + out << " const uint index = imageIndex - " << offsetStr << "2D;\n"; + out << " " << declarationStr << "2D[index].GetDimensions(width, height);\n"; + } + else + { + out << " if (imageIndex >= " << offsetStr << "2D && imageIndex < " << offsetStr + << "2D + " << texture2DCount << ")\n"; + out << " {\n"; + out << " const uint index = imageIndex - " << offsetStr << "2D;\n"; + out << " " << declarationStr << "2D[index].GetDimensions(width, height);\n"; + out << " }\n"; + } + } + + if (texture3DCount > 0) + { + if (texture3DCount == totalCount) + { + out << " const uint index = imageIndex - " << offsetStr << "3D;\n"; + out << " uint depth;\n"; + out << " " << declarationStr << "3D[index].GetDimensions(width, height, depth);\n"; + } + else + { + if (texture2DArrayCount == 0) + { + out << " else\n"; + } + else + { + if (texture2DCount == 0) + { + out << " if "; + } + else + { + out << " else if"; + } + out << "(imageIndex >= " << offsetStr << "3D && imageIndex < " << offsetStr + << "3D + " << texture3DCount << ")\n"; + } + out << " {\n"; + out << " const uint index = imageIndex - " << offsetStr << "3D;\n"; + out << " uint depth;\n"; + out << " " << declarationStr + << "3D[index].GetDimensions(width, height, depth);\n"; + out << " }\n"; + } + } + + if (texture2DArrayCount > 0) + { + if (texture2DArrayCount == totalCount) + { + out << " const uint index = imageIndex - " << offsetStr << "2DArray;\n"; + out << " uint depth;\n"; + out << " " << declarationStr + << "2DArray[index].GetDimensions(width, height, depth);\n"; + } + else + { + out << " else\n"; + out << " {\n"; + out << " const uint index = imageIndex - " << offsetStr << "2DArray;\n"; + out << " uint depth;\n"; + out << " " << declarationStr + << "2DArray[index].GetDimensions(width, height, depth);\n"; + out << " }\n"; + } + } + out << " return int2(width, height);\n"; + + out << "}\n"; +} + +void OutputImage2DLoadFunction(std::ostringstream &out, + Image2DHLSLGroup textureGroup, + unsigned int totalCount, + unsigned int texture2DCount, + unsigned int texture3DCount, + unsigned int texture2DArrayCount, + const std::string &offsetStr, + const std::string &declarationStr) +{ + out << getImage2DGroupReturnType(textureGroup, IMAGE2DLOAD) << " " + << Image2DHLSLGroupFunctionName(textureGroup, IMAGE2DLOAD) << "("; + OutputImage2DFunctionArgumentList(out, textureGroup, IMAGE2DLOAD); + out << ")\n" + "{\n"; + + out << " " << getImage2DGroupReturnType(textureGroup, IMAGE2DLOAD) << " result;\n"; + + if (texture2DCount > 0) + { + if (texture2DCount == totalCount) + { + out << " const uint index = imageIndex - " << offsetStr << "2D;\n"; + out << " result = " << declarationStr << "2D[index][uint2(p.x, p.y)];\n"; + } + else + { + out << " if (imageIndex >= " << offsetStr << "2D && imageIndex < " << offsetStr + << "2D + " << texture2DCount << ")\n"; + out << " {\n"; + out << " const uint index = imageIndex - " << offsetStr << "2D;\n"; + out << " result = " << declarationStr << "2D[index][uint2(p.x, p.y)];\n"; + out << " }\n"; + } + } + + if (texture3DCount > 0) + { + if (texture3DCount == totalCount) + { + out << " const uint index = imageIndex - " << offsetStr << "3D;\n"; + out << " result = " << declarationStr << "3D[index][uint3(p.x, p.y, " + << getImageMetadata(textureGroup) << ".layer)];\n"; + } + else + { + if (texture2DArrayCount == 0) + { + out << " else\n"; + } + else + { + if (texture2DCount == 0) + { + out << " if "; + } + else + { + out << " else if"; + } + out << "(imageIndex >= " << offsetStr << "3D && imageIndex < " << offsetStr + << "3D + " << texture3DCount << ")\n"; + } + out << " {\n"; + out << " const uint index = imageIndex - " << offsetStr << "3D;\n"; + out << " result = " << declarationStr << "3D[index][uint3(p.x, p.y, " + << getImageMetadata(textureGroup) << ".layer)];\n"; + out << " }\n"; + } + } + + if (texture2DArrayCount > 0) + { + if (texture2DArrayCount == totalCount) + { + out << " const uint index = imageIndex - " << offsetStr << "2DArray;\n"; + out << " result = " << declarationStr << "2DArray[index][uint3(p.x, p.y, " + << getImageMetadata(textureGroup) << ".layer)];\n"; + } + else + { + out << " else\n"; + out << " {\n"; + out << " const uint index = imageIndex - " << offsetStr << "2DArray;\n"; + out << " result = " << declarationStr << "2DArray[index][uint3(p.x, p.y, " + << getImageMetadata(textureGroup) << ".layer)];\n"; + out << " }\n"; + } + } + + out << " return result;\n"; + out << "}\n"; +} + +void OutputImage2DStoreFunction(std::ostringstream &out, + Image2DHLSLGroup textureGroup, + unsigned int totalCount, + unsigned int texture2DCount, + unsigned int texture3DCount, + unsigned int texture2DArrayCount, + const std::string &offsetStr, + const std::string &declarationStr) +{ + out << getImage2DGroupReturnType(textureGroup, IMAGE2DSTORE) << " " + << Image2DHLSLGroupFunctionName(textureGroup, IMAGE2DSTORE) << "("; + OutputImage2DFunctionArgumentList(out, textureGroup, IMAGE2DSTORE); + out << ")\n" + "{\n"; + + if (texture2DCount > 0) + { + if (texture2DCount == totalCount) + { + out << " const uint index = imageIndex - " << offsetStr << "2D;\n"; + out << " " << declarationStr << "2D[index][uint2(p.x, p.y)] = data;\n"; + } + else + { + out << " if (imageIndex >= " << offsetStr << "2D && imageIndex < " << offsetStr + << "2D + " << texture2DCount << ")\n"; + out << " {\n"; + out << " const uint index = imageIndex - " << offsetStr << "2D;\n"; + out << " " << declarationStr << "2D[index][uint2(p.x, p.y)] = data;\n"; + out << " }\n"; + } + } + + if (texture3DCount > 0) + { + if (texture3DCount == totalCount) + { + out << " const uint index = imageIndex - " << offsetStr << "3D;\n"; + out << " " << declarationStr << "3D[index][uint3(p.x, p.y, " + << getImageMetadata(textureGroup) << ".layer)] = data;\n"; + } + else + { + if (texture2DArrayCount == 0) + { + out << " else\n"; + } + else + { + if (texture2DCount == 0) + { + out << " if "; + } + else + { + out << " else if"; + } + out << "(imageIndex >= " << offsetStr << "3D && imageIndex < " << offsetStr + << "3D + " << texture3DCount << ")\n"; + } + out << " {\n"; + out << " const uint index = imageIndex - " << offsetStr << "3D;\n"; + out << " " << declarationStr << "3D[index][uint3(p.x, p.y, " + << getImageMetadata(textureGroup) << ".layer)] = data;\n"; + out << " }\n"; + } + } + + if (texture2DArrayCount > 0) + { + if (texture2DArrayCount == totalCount) + { + out << " const uint index = imageIndex - " << offsetStr << "2DArray;\n"; + out << " " << declarationStr << "2DArray[index][uint3(p.x, p.y, " + << getImageMetadata(textureGroup) << ".layer)] = data;\n"; + } + else + { + out << " else\n"; + out << " {\n"; + out << " const uint index = imageIndex - " << offsetStr << "2DArray;\n"; + out << " " << declarationStr << "2DArray[index][uint3(p.x, p.y, " + << getImageMetadata(textureGroup) << ".layer)] = data;\n"; + out << " }\n"; + } + } + + out << "}\n"; +} + +unsigned int *GetImage2DRegisterIndex(Image2DHLSLGroup textureGroup, + unsigned int *groupTextureRegisterIndex, + unsigned int *groupRWTextureRegisterIndex) +{ + switch (textureGroup) + { + case IMAGE2D_R_FLOAT4: + case IMAGE2D_R_UNORM: + case IMAGE2D_R_SNORM: + case IMAGE2D_R_UINT4: + case IMAGE2D_R_INT4: + return groupTextureRegisterIndex; + case IMAGE2D_W_FLOAT4: + case IMAGE2D_W_UNORM: + case IMAGE2D_W_SNORM: + case IMAGE2D_W_UINT4: + case IMAGE2D_W_INT4: + return groupRWTextureRegisterIndex; + default: + UNREACHABLE(); + return nullptr; + } +} + +void OutputHLSLImage2DUniformGroup(ProgramD3D &programD3D, + const gl::ProgramState &programData, + gl::ShaderType shaderType, + std::ostringstream &out, + const Image2DHLSLGroup textureGroup, + const std::vector &group, + const gl::ImageUnitTextureTypeMap &image2DBindLayout, + unsigned int baseUAVRegister, + unsigned int *groupTextureRegisterIndex, + unsigned int *groupRWTextureRegisterIndex, + unsigned int *image2DTexture3D, + unsigned int *image2DTexture2DArray, + unsigned int *image2DTexture2D) +{ + if (group.empty()) + { + return; + } + + unsigned int texture2DCount = 0, texture3DCount = 0, texture2DArrayCount = 0; + bool texture2DRasterOrdered = false, texture3DRasterOrdered = false, + texture2DArrayRasterOrdered = false; + for (const sh::ShaderVariable &uniform : group) + { + if (!programD3D.hasNamedUniform(uniform.name)) + { + continue; + } + for (unsigned int index = 0; index < uniform.getArraySizeProduct(); index++) + { + switch (image2DBindLayout.at(uniform.binding + index)) + { + case gl::TextureType::_2D: + texture2DCount++; + texture2DRasterOrdered |= uniform.rasterOrdered; + break; + case gl::TextureType::_3D: + texture3DCount++; + texture3DRasterOrdered |= uniform.rasterOrdered; + break; + case gl::TextureType::_2DArray: + case gl::TextureType::CubeMap: + texture2DArrayCount++; + texture2DArrayRasterOrdered |= uniform.rasterOrdered; + break; + default: + UNREACHABLE(); + } + } + } + + unsigned int totalCount = texture2DCount + texture3DCount + texture2DArrayCount; + unsigned int *image2DRegisterIndex = GetImage2DRegisterIndex( + textureGroup, groupTextureRegisterIndex, groupRWTextureRegisterIndex); + unsigned int texture2DRegisterIndex = *image2DRegisterIndex; + unsigned int texture3DRegisterIndex = texture2DRegisterIndex + texture2DCount; + unsigned int texture2DArrayRegisterIndex = texture3DRegisterIndex + texture3DCount; + *image2DRegisterIndex += totalCount; + + std::string offsetStr = + Image2DHLSLGroupOffsetPrefix(textureGroup) + Image2DHLSLGroupSuffix(textureGroup); + std::string declarationStr = + Image2DHLSLGroupDeclarationPrefix(textureGroup) + Image2DHLSLGroupSuffix(textureGroup); + std::string registerStr = Image2DHLSLGroupRegisterSuffix(textureGroup); + if (texture2DCount > 0) + { + out << "static const uint " << offsetStr << "2D = " << texture2DRegisterIndex << ";\n"; + out << "uniform " + << Image2DHLSLTextureString(textureGroup, gl::TextureType::_2D, texture2DRasterOrdered) + << " " << declarationStr << "2D[" << texture2DCount << "]" + << " : register(" << registerStr << baseUAVRegister + texture2DRegisterIndex << ");\n"; + } + if (texture3DCount > 0) + { + out << "static const uint " << offsetStr << "3D = " << texture3DRegisterIndex << ";\n"; + out << "uniform " + << Image2DHLSLTextureString(textureGroup, gl::TextureType::_3D, texture3DRasterOrdered) + << " " << declarationStr << "3D[" << texture3DCount << "]" + << " : register(" << registerStr << baseUAVRegister + texture3DRegisterIndex << ");\n"; + } + if (texture2DArrayCount > 0) + { + out << "static const uint " << offsetStr << "2DArray = " << texture2DArrayRegisterIndex + << ";\n"; + out << "uniform " + << Image2DHLSLTextureString(textureGroup, gl::TextureType::_2DArray, + texture2DArrayRasterOrdered) + << " " << declarationStr << "2DArray[" << texture2DArrayCount << "]" + << " : register(" << registerStr << baseUAVRegister + texture2DArrayRegisterIndex + << ");\n"; + } + for (const sh::ShaderVariable &uniform : group) + { + if (!programD3D.hasNamedUniform(uniform.name)) + { + continue; + } + + out << "static const uint " << DecorateVariable(uniform.name) + << ArrayIndexString(uniform.arraySizes) << " = {"; + for (unsigned int index = 0; index < uniform.getArraySizeProduct(); index++) + { + if (index > 0) + { + out << ", "; + } + switch (image2DBindLayout.at(uniform.binding + index)) + { + case gl::TextureType::_2D: + { + out << texture2DRegisterIndex; + programD3D.assignImage2DRegisters(shaderType, texture2DRegisterIndex, + uniform.binding + index, uniform.readonly); + texture2DRegisterIndex++; + break; + } + case gl::TextureType::_3D: + { + out << texture3DRegisterIndex; + programD3D.assignImage2DRegisters(shaderType, texture3DRegisterIndex, + uniform.binding + index, uniform.readonly); + texture3DRegisterIndex++; + break; + } + case gl::TextureType::_2DArray: + case gl::TextureType::CubeMap: + { + out << texture2DArrayRegisterIndex; + programD3D.assignImage2DRegisters(shaderType, texture2DArrayRegisterIndex, + uniform.binding + index, uniform.readonly); + texture2DArrayRegisterIndex++; + break; + } + default: + UNREACHABLE(); + } + } + out << "};\n"; + } + + gl::Shader *shaderGL = programData.getAttachedShader(shaderType); + const ShaderD3D *shaderD3D = GetImplAs(shaderGL); + + if (shaderD3D->useImage2DFunction(Image2DHLSLGroupFunctionName(textureGroup, IMAGE2DSIZE))) + { + OutputImage2DSizeFunction(out, textureGroup, totalCount, texture2DCount, texture3DCount, + texture2DArrayCount, offsetStr, declarationStr); + } + if (shaderD3D->useImage2DFunction(Image2DHLSLGroupFunctionName(textureGroup, IMAGE2DLOAD))) + { + OutputImage2DLoadFunction(out, textureGroup, totalCount, texture2DCount, texture3DCount, + texture2DArrayCount, offsetStr, declarationStr); + } + if (shaderD3D->useImage2DFunction(Image2DHLSLGroupFunctionName(textureGroup, IMAGE2DSTORE))) + { + OutputImage2DStoreFunction(out, textureGroup, totalCount, texture2DCount, texture3DCount, + texture2DArrayCount, offsetStr, declarationStr); + } +} + +// kImage2DFunctionString must be the same as outputHLSL. +constexpr const char kImage2DFunctionString[] = "// @@ IMAGE2D DECLARATION FUNCTION STRING @@"; +} // anonymous namespace + +std::string GenerateShaderForImage2DBindSignature( + ProgramD3D &programD3D, + const gl::ProgramState &programData, + gl::ShaderType shaderType, + const std::string &shaderHLSL, + std::vector &image2DUniforms, + const gl::ImageUnitTextureTypeMap &image2DBindLayout, + unsigned int baseUAVRegister) +{ + std::vector> groupedImage2DUniforms(IMAGE2D_MAX + 1); + unsigned int image2DTexture3DCount = 0, image2DTexture2DArrayCount = 0; + for (sh::ShaderVariable &image2D : image2DUniforms) + { + for (unsigned int index = 0; index < image2D.getArraySizeProduct(); index++) + { + // Any image variable declared without a binding qualifier is initially bound to unit + // zero. + if (image2D.binding == -1) + { + image2D.binding = 0; + } + switch (image2DBindLayout.at(image2D.binding + index)) + { + case gl::TextureType::_2D: + break; + case gl::TextureType::_3D: + image2DTexture3DCount++; + break; + case gl::TextureType::_2DArray: + case gl::TextureType::CubeMap: + image2DTexture2DArrayCount++; + break; + default: + UNREACHABLE(); + } + } + Image2DHLSLGroup group = image2DHLSLGroup(image2D); + groupedImage2DUniforms[group].push_back(image2D); + } + + gl::Shader *shaderGL = programData.getAttachedShader(shaderType); + const ShaderD3D *shaderD3D = GetImplAs(shaderGL); + unsigned int groupTextureRegisterIndex = shaderD3D->getReadonlyImage2DRegisterIndex(); + unsigned int groupRWTextureRegisterIndex = shaderD3D->getImage2DRegisterIndex(); + unsigned int image2DTexture3DIndex = 0; + unsigned int image2DTexture2DArrayIndex = image2DTexture3DCount; + unsigned int image2DTexture2DIndex = image2DTexture3DCount + image2DTexture2DArrayCount; + std::ostringstream out; + + for (int groupId = IMAGE2D_MIN; groupId < IMAGE2D_MAX; ++groupId) + { + OutputHLSLImage2DUniformGroup( + programD3D, programData, shaderType, out, Image2DHLSLGroup(groupId), + groupedImage2DUniforms[groupId], image2DBindLayout, baseUAVRegister, + &groupTextureRegisterIndex, &groupRWTextureRegisterIndex, &image2DTexture3DIndex, + &image2DTexture2DArrayIndex, &image2DTexture2DIndex); + } + + std::string result = shaderHLSL; + bool success = angle::ReplaceSubstring(&result, kImage2DFunctionString, out.str()); + ASSERT(success); + + return result; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicImage2DHLSL.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicImage2DHLSL.h new file mode 100644 index 0000000000..6533c972f8 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicImage2DHLSL.h @@ -0,0 +1,28 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// DynamicImage2DHLSL.h: Interface for link and run-time HLSL generation +// + +#ifndef LIBANGLE_RENDERER_D3D_DYNAMICIMAGE2DHLSL_H_ +#define LIBANGLE_RENDERER_D3D_DYNAMICIMAGE2DHLSL_H_ + +#include "common/angleutils.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" + +namespace rx +{ +std::string GenerateShaderForImage2DBindSignature( + ProgramD3D &programD3D, + const gl::ProgramState &programData, + gl::ShaderType shaderType, + const std::string &shaderHLSL, + std::vector &image2DUniforms, + const gl::ImageUnitTextureTypeMap &image2DBindLayout, + unsigned int baseUAVRegister); + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_DYNAMICHLSL_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/EGLImageD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/EGLImageD3D.cpp new file mode 100644 index 0000000000..c2ff39ba24 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/EGLImageD3D.cpp @@ -0,0 +1,93 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// EGLImageD3D.cpp: Implements the rx::EGLImageD3D class, the D3D implementation of EGL images + +#include "libANGLE/renderer/d3d/EGLImageD3D.h" + +#include "common/debug.h" +#include "common/utilities.h" +#include "libANGLE/AttributeMap.h" +#include "libANGLE/Context.h" +#include "libANGLE/Texture.h" +#include "libANGLE/renderer/d3d/RenderTargetD3D.h" +#include "libANGLE/renderer/d3d/RenderbufferD3D.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" +#include "libANGLE/renderer/d3d/TextureD3D.h" +#include "libANGLE/renderer/d3d/TextureStorage.h" + +#include + +namespace rx +{ + +EGLImageD3D::EGLImageD3D(const egl::ImageState &state, + EGLenum target, + const egl::AttributeMap &attribs, + RendererD3D *renderer) + : ImageImpl(state), mRenderer(renderer), mRenderTarget(nullptr) +{ + ASSERT(renderer != nullptr); +} + +EGLImageD3D::~EGLImageD3D() +{ + SafeDelete(mRenderTarget); +} + +egl::Error EGLImageD3D::initialize(const egl::Display *display) +{ + return egl::NoError(); +} + +angle::Result EGLImageD3D::orphan(const gl::Context *context, egl::ImageSibling *sibling) +{ + if (sibling == mState.source) + { + ANGLE_TRY(copyToLocalRendertarget(context)); + } + + return angle::Result::Continue; +} + +angle::Result EGLImageD3D::getRenderTarget(const gl::Context *context, + RenderTargetD3D **outRT) const +{ + if (mState.source != nullptr) + { + ASSERT(!mRenderTarget); + FramebufferAttachmentRenderTarget *rt = nullptr; + ANGLE_TRY( + mState.source->getAttachmentRenderTarget(context, GL_NONE, mState.imageIndex, 0, &rt)); + *outRT = static_cast(rt); + return angle::Result::Continue; + } + + ASSERT(mRenderTarget); + *outRT = mRenderTarget; + return angle::Result::Continue; +} + +angle::Result EGLImageD3D::copyToLocalRendertarget(const gl::Context *context) +{ + ASSERT(mState.source != nullptr); + ASSERT(mRenderTarget == nullptr); + + RenderTargetD3D *curRenderTarget = nullptr; + ANGLE_TRY(getRenderTarget(context, &curRenderTarget)); + + { + std::unique_lock lock(mState.targetsLock); + // Invalidate FBOs with this Image attached. Only currently applies to D3D11. + for (egl::ImageSibling *target : mState.targets) + { + target->onStateChange(angle::SubjectMessage::SubjectChanged); + } + } + + return mRenderer->createRenderTargetCopy(context, curRenderTarget, &mRenderTarget); +} +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/EGLImageD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/EGLImageD3D.h new file mode 100644 index 0000000000..53c18739af --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/EGLImageD3D.h @@ -0,0 +1,55 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// EGLImageD3D.h: Defines the rx::EGLImageD3D class, the D3D implementation of EGL images + +#ifndef LIBANGLE_RENDERER_D3D_EGLIMAGED3D_H_ +#define LIBANGLE_RENDERER_D3D_EGLIMAGED3D_H_ + +#include "libANGLE/renderer/ImageImpl.h" + +namespace gl +{ +class Context; +} + +namespace egl +{ +class AttributeMap; +} + +namespace rx +{ +class FramebufferAttachmentObjectImpl; +class TextureD3D; +class RenderbufferD3D; +class RendererD3D; +class RenderTargetD3D; + +class EGLImageD3D final : public ImageImpl +{ + public: + EGLImageD3D(const egl::ImageState &state, + EGLenum target, + const egl::AttributeMap &attribs, + RendererD3D *renderer); + ~EGLImageD3D() override; + + egl::Error initialize(const egl::Display *display) override; + + angle::Result orphan(const gl::Context *context, egl::ImageSibling *sibling) override; + + angle::Result getRenderTarget(const gl::Context *context, RenderTargetD3D **outRT) const; + + private: + angle::Result copyToLocalRendertarget(const gl::Context *context); + + RendererD3D *mRenderer; + RenderTargetD3D *mRenderTarget; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_EGLIMAGED3D_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/FramebufferD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/FramebufferD3D.cpp new file mode 100644 index 0000000000..5a8279a586 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/FramebufferD3D.cpp @@ -0,0 +1,402 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// FramebufferD3D.cpp: Implements the DefaultAttachmentD3D and FramebufferD3D classes. + +#include "libANGLE/renderer/d3d/FramebufferD3D.h" + +#include "common/bitset_utils.h" +#include "libANGLE/Context.h" +#include "libANGLE/ErrorStrings.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/Surface.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/ContextImpl.h" +#include "libANGLE/renderer/d3d/ContextD3D.h" +#include "libANGLE/renderer/d3d/RenderTargetD3D.h" +#include "libANGLE/renderer/d3d/RenderbufferD3D.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" +#include "libANGLE/renderer/d3d/SurfaceD3D.h" +#include "libANGLE/renderer/d3d/SwapChainD3D.h" +#include "libANGLE/renderer/d3d/TextureD3D.h" + +namespace rx +{ + +namespace +{ + +ClearParameters GetClearParameters(const gl::State &state, GLbitfield mask) +{ + ClearParameters clearParams; + memset(&clearParams, 0, sizeof(ClearParameters)); + + clearParams.colorF = state.getColorClearValue(); + clearParams.colorType = GL_FLOAT; + clearParams.clearDepth = false; + clearParams.depthValue = state.getDepthClearValue(); + clearParams.clearStencil = false; + clearParams.stencilValue = state.getStencilClearValue(); + clearParams.stencilWriteMask = state.getDepthStencilState().stencilWritemask; + + const auto *framebufferObject = state.getDrawFramebuffer(); + const gl::Extents &framebufferSize = framebufferObject->getFirstNonNullAttachment()->getSize(); + const gl::Offset &surfaceTextureOffset = framebufferObject->getSurfaceTextureOffset(); + if (state.isScissorTestEnabled()) + { + clearParams.scissorEnabled = true; + clearParams.scissor = state.getScissor(); + clearParams.scissor.x = clearParams.scissor.x + surfaceTextureOffset.x; + clearParams.scissor.y = clearParams.scissor.y + surfaceTextureOffset.y; + } + else if (surfaceTextureOffset != gl::kOffsetZero) + { + clearParams.scissorEnabled = true; + clearParams.scissor = gl::Rectangle(surfaceTextureOffset.x, surfaceTextureOffset.y, + framebufferSize.width, framebufferSize.height); + } + + const bool clearColor = + (mask & GL_COLOR_BUFFER_BIT) && framebufferObject->hasEnabledDrawBuffer(); + if (clearColor) + { + clearParams.clearColor.set(); + } + else + { + clearParams.clearColor.reset(); + } + clearParams.colorMask = state.getBlendStateExt().getColorMaskBits(); + + if (mask & GL_DEPTH_BUFFER_BIT) + { + if (state.getDepthStencilState().depthMask && + framebufferObject->getDepthAttachment() != nullptr) + { + clearParams.clearDepth = true; + } + } + + if (mask & GL_STENCIL_BUFFER_BIT) + { + if (framebufferObject->getStencilAttachment() != nullptr && + framebufferObject->getStencilAttachment()->getStencilSize() > 0) + { + clearParams.clearStencil = true; + } + } + + return clearParams; +} +} // namespace + +ClearParameters::ClearParameters() = default; + +ClearParameters::ClearParameters(const ClearParameters &other) = default; + +FramebufferD3D::FramebufferD3D(const gl::FramebufferState &data, RendererD3D *renderer) + : FramebufferImpl(data), mRenderer(renderer), mMockAttachment() +{} + +FramebufferD3D::~FramebufferD3D() {} + +angle::Result FramebufferD3D::clear(const gl::Context *context, GLbitfield mask) +{ + ClearParameters clearParams = GetClearParameters(context->getState(), mask); + return clearImpl(context, clearParams); +} + +angle::Result FramebufferD3D::clearBufferfv(const gl::Context *context, + GLenum buffer, + GLint drawbuffer, + const GLfloat *values) +{ + // glClearBufferfv can be called to clear the color buffer or depth buffer + ClearParameters clearParams = GetClearParameters(context->getState(), 0); + + if (buffer == GL_COLOR) + { + for (unsigned int i = 0; i < clearParams.clearColor.size(); i++) + { + clearParams.clearColor[i] = (drawbuffer == static_cast(i)); + } + clearParams.colorF = gl::ColorF(values[0], values[1], values[2], values[3]); + clearParams.colorType = GL_FLOAT; + } + + if (buffer == GL_DEPTH) + { + clearParams.clearDepth = true; + clearParams.depthValue = values[0]; + } + + return clearImpl(context, clearParams); +} + +angle::Result FramebufferD3D::clearBufferuiv(const gl::Context *context, + GLenum buffer, + GLint drawbuffer, + const GLuint *values) +{ + // glClearBufferuiv can only be called to clear a color buffer + ClearParameters clearParams = GetClearParameters(context->getState(), 0); + for (unsigned int i = 0; i < clearParams.clearColor.size(); i++) + { + clearParams.clearColor[i] = (drawbuffer == static_cast(i)); + } + clearParams.colorUI = gl::ColorUI(values[0], values[1], values[2], values[3]); + clearParams.colorType = GL_UNSIGNED_INT; + + return clearImpl(context, clearParams); +} + +angle::Result FramebufferD3D::clearBufferiv(const gl::Context *context, + GLenum buffer, + GLint drawbuffer, + const GLint *values) +{ + // glClearBufferiv can be called to clear the color buffer or stencil buffer + ClearParameters clearParams = GetClearParameters(context->getState(), 0); + + if (buffer == GL_COLOR) + { + for (unsigned int i = 0; i < clearParams.clearColor.size(); i++) + { + clearParams.clearColor[i] = (drawbuffer == static_cast(i)); + } + clearParams.colorI = gl::ColorI(values[0], values[1], values[2], values[3]); + clearParams.colorType = GL_INT; + } + + if (buffer == GL_STENCIL) + { + clearParams.clearStencil = true; + clearParams.stencilValue = values[0]; + } + + return clearImpl(context, clearParams); +} + +angle::Result FramebufferD3D::clearBufferfi(const gl::Context *context, + GLenum buffer, + GLint drawbuffer, + GLfloat depth, + GLint stencil) +{ + // glClearBufferfi can only be called to clear a depth stencil buffer + ClearParameters clearParams = GetClearParameters(context->getState(), 0); + clearParams.clearDepth = true; + clearParams.depthValue = depth; + clearParams.clearStencil = true; + clearParams.stencilValue = stencil; + + return clearImpl(context, clearParams); +} + +angle::Result FramebufferD3D::readPixels(const gl::Context *context, + const gl::Rectangle &area, + GLenum format, + GLenum type, + const gl::PixelPackState &pack, + gl::Buffer *packBuffer, + void *pixels) +{ + // Clip read area to framebuffer. + const gl::Extents fbSize = getState().getReadPixelsAttachment(format)->getSize(); + const gl::Rectangle fbRect(0, 0, fbSize.width, fbSize.height); + gl::Rectangle clippedArea; + if (!ClipRectangle(area, fbRect, &clippedArea)) + { + // nothing to read + return angle::Result::Continue; + } + + const gl::InternalFormat &sizedFormatInfo = gl::GetInternalFormatInfo(format, type); + + ContextD3D *contextD3D = GetImplAs(context); + + GLuint outputPitch = 0; + ANGLE_CHECK_GL_MATH(contextD3D, + sizedFormatInfo.computeRowPitch(type, area.width, pack.alignment, + pack.rowLength, &outputPitch)); + + GLuint outputSkipBytes = 0; + ANGLE_CHECK_GL_MATH(contextD3D, sizedFormatInfo.computeSkipBytes(type, outputPitch, 0, pack, + false, &outputSkipBytes)); + outputSkipBytes += (clippedArea.x - area.x) * sizedFormatInfo.pixelBytes + + (clippedArea.y - area.y) * outputPitch; + + return readPixelsImpl(context, clippedArea, format, type, outputPitch, pack, packBuffer, + static_cast(pixels) + outputSkipBytes); +} + +angle::Result FramebufferD3D::blit(const gl::Context *context, + const gl::Rectangle &sourceArea, + const gl::Rectangle &destArea, + GLbitfield mask, + GLenum filter) +{ + const auto &glState = context->getState(); + const gl::Framebuffer *sourceFramebuffer = glState.getReadFramebuffer(); + const gl::Rectangle *scissor = glState.isScissorTestEnabled() ? &glState.getScissor() : nullptr; + ANGLE_TRY(blitImpl(context, sourceArea, destArea, scissor, (mask & GL_COLOR_BUFFER_BIT) != 0, + (mask & GL_DEPTH_BUFFER_BIT) != 0, (mask & GL_STENCIL_BUFFER_BIT) != 0, + filter, sourceFramebuffer)); + + return angle::Result::Continue; +} + +gl::FramebufferStatus FramebufferD3D::checkStatus(const gl::Context *context) const +{ + // if we have both a depth and stencil buffer, they must refer to the same object + // since we only support packed_depth_stencil and not separate depth and stencil + if (mState.hasSeparateDepthAndStencilAttachments()) + { + return gl::FramebufferStatus::Incomplete( + GL_FRAMEBUFFER_UNSUPPORTED, + gl::err::kFramebufferIncompleteUnsupportedSeparateDepthStencilBuffers); + } + + // D3D11 does not allow for overlapping RenderTargetViews. + // If WebGL compatibility is enabled, this has already been checked at a higher level. + ASSERT(!context->isWebGL() || mState.colorAttachmentsAreUniqueImages()); + if (!context->isWebGL()) + { + if (!mState.colorAttachmentsAreUniqueImages()) + { + return gl::FramebufferStatus::Incomplete( + GL_FRAMEBUFFER_UNSUPPORTED, + gl::err::kFramebufferIncompleteUnsupportedNonUniqueAttachments); + } + } + + // D3D requires all render targets to have the same dimensions. + if (!mState.attachmentsHaveSameDimensions()) + { + return gl::FramebufferStatus::Incomplete( + GL_FRAMEBUFFER_UNSUPPORTED, + gl::err::kFramebufferIncompleteUnsupportedMissmatchedDimensions); + } + + return gl::FramebufferStatus::Complete(); +} + +angle::Result FramebufferD3D::syncState(const gl::Context *context, + GLenum binding, + const gl::Framebuffer::DirtyBits &dirtyBits, + gl::Command command) +{ + if (!mColorAttachmentsForRender.valid()) + { + return angle::Result::Continue; + } + + for (auto dirtyBit : dirtyBits) + { + if ((dirtyBit >= gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 && + dirtyBit < gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX) || + dirtyBit == gl::Framebuffer::DIRTY_BIT_DRAW_BUFFERS) + { + mColorAttachmentsForRender.reset(); + } + } + + return angle::Result::Continue; +} + +const gl::AttachmentList &FramebufferD3D::getColorAttachmentsForRender(const gl::Context *context) +{ + gl::DrawBufferMask activeProgramOutputs = + context->getState().getProgram()->getExecutable().getActiveOutputVariablesMask(); + + if (mColorAttachmentsForRender.valid() && mCurrentActiveProgramOutputs == activeProgramOutputs) + { + return mColorAttachmentsForRender.value(); + } + + // Does not actually free memory + gl::AttachmentList colorAttachmentsForRender; + mColorAttachmentsForRenderMask.reset(); + + const auto &colorAttachments = mState.getColorAttachments(); + const auto &drawBufferStates = mState.getDrawBufferStates(); + const auto &features = mRenderer->getFeatures(); + + for (size_t attachmentIndex = 0; attachmentIndex < colorAttachments.size(); ++attachmentIndex) + { + GLenum drawBufferState = drawBufferStates[attachmentIndex]; + const gl::FramebufferAttachment &colorAttachment = colorAttachments[attachmentIndex]; + + if (colorAttachment.isAttached() && drawBufferState != GL_NONE && + activeProgramOutputs[attachmentIndex]) + { + ASSERT(drawBufferState == GL_BACK || + drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + attachmentIndex)); + colorAttachmentsForRender.push_back(&colorAttachment); + mColorAttachmentsForRenderMask.set(attachmentIndex); + } + else if (!features.mrtPerfWorkaround.enabled) + { + colorAttachmentsForRender.push_back(nullptr); + mColorAttachmentsForRenderMask.set(attachmentIndex); + } + } + + // When rendering with no render target on D3D, two bugs lead to incorrect behavior on Intel + // drivers < 4815. The rendering samples always pass neglecting discard statements in pixel + // shader. We add a mock texture as render target in such case. + if (mRenderer->getFeatures().addMockTextureNoRenderTarget.enabled && + colorAttachmentsForRender.empty() && activeProgramOutputs.any()) + { + static_assert(static_cast(activeProgramOutputs.size()) <= 32, + "Size of active program outputs should less or equal than 32."); + const GLuint activeProgramLocation = static_cast( + gl::ScanForward(static_cast(activeProgramOutputs.bits()))); + + if (mMockAttachment.isAttached() && + (mMockAttachment.getBinding() - GL_COLOR_ATTACHMENT0) == activeProgramLocation) + { + colorAttachmentsForRender.push_back(&mMockAttachment); + } + else + { + // Remove mock attachment to prevents us from leaking it, and the program may require + // it to be attached to a new binding point. + if (mMockAttachment.isAttached()) + { + mMockAttachment.detach(context, Serial()); + } + + gl::Texture *mockTex = nullptr; + // TODO(jmadill): Handle error if mock texture can't be created. + (void)mRenderer->getIncompleteTexture(context, gl::TextureType::_2D, &mockTex); + if (mockTex) + { + gl::ImageIndex index = gl::ImageIndex::Make2D(0); + mMockAttachment = gl::FramebufferAttachment( + context, GL_TEXTURE, GL_COLOR_ATTACHMENT0_EXT + activeProgramLocation, index, + mockTex, Serial()); + colorAttachmentsForRender.push_back(&mMockAttachment); + } + } + } + + mColorAttachmentsForRender = std::move(colorAttachmentsForRender); + mCurrentActiveProgramOutputs = activeProgramOutputs; + + return mColorAttachmentsForRender.value(); +} + +void FramebufferD3D::destroy(const gl::Context *context) +{ + if (mMockAttachment.isAttached()) + { + mMockAttachment.detach(context, Serial()); + } +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/FramebufferD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/FramebufferD3D.h new file mode 100644 index 0000000000..67e19bd4bc --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/FramebufferD3D.h @@ -0,0 +1,143 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// FramebufferD3D.h: Defines the DefaultAttachmentD3D and FramebufferD3D classes. + +#ifndef LIBANGLE_RENDERER_D3D_FRAMBUFFERD3D_H_ +#define LIBANGLE_RENDERER_D3D_FRAMBUFFERD3D_H_ + +#include +#include + +#include "common/Color.h" +#include "common/Optional.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/renderer/FramebufferImpl.h" + +namespace gl +{ +class FramebufferAttachment; +struct PixelPackState; + +typedef std::vector AttachmentList; +} // namespace gl + +namespace rx +{ +class RendererD3D; +class RenderTargetD3D; + +struct ClearParameters +{ + ClearParameters(); + ClearParameters(const ClearParameters &other); + + gl::DrawBufferMask clearColor; + gl::ColorF colorF; + gl::ColorI colorI; + gl::ColorUI colorUI; + GLenum colorType; + gl::BlendStateExt::ColorMaskStorage::Type colorMask; + + bool clearDepth; + float depthValue; + + bool clearStencil; + GLint stencilValue; + GLuint stencilWriteMask; + + bool scissorEnabled; + gl::Rectangle scissor; +}; + +class FramebufferD3D : public FramebufferImpl +{ + public: + FramebufferD3D(const gl::FramebufferState &data, RendererD3D *renderer); + ~FramebufferD3D() override; + + angle::Result clear(const gl::Context *context, GLbitfield mask) override; + angle::Result clearBufferfv(const gl::Context *context, + GLenum buffer, + GLint drawbuffer, + const GLfloat *values) override; + angle::Result clearBufferuiv(const gl::Context *context, + GLenum buffer, + GLint drawbuffer, + const GLuint *values) override; + angle::Result clearBufferiv(const gl::Context *context, + GLenum buffer, + GLint drawbuffer, + const GLint *values) override; + angle::Result clearBufferfi(const gl::Context *context, + GLenum buffer, + GLint drawbuffer, + GLfloat depth, + GLint stencil) override; + + angle::Result readPixels(const gl::Context *context, + const gl::Rectangle &area, + GLenum format, + GLenum type, + const gl::PixelPackState &pack, + gl::Buffer *packBuffer, + void *pixels) override; + + angle::Result blit(const gl::Context *context, + const gl::Rectangle &sourceArea, + const gl::Rectangle &destArea, + GLbitfield mask, + GLenum filter) override; + + gl::FramebufferStatus checkStatus(const gl::Context *context) const override; + + angle::Result syncState(const gl::Context *context, + GLenum binding, + const gl::Framebuffer::DirtyBits &dirtyBits, + gl::Command command) override; + + const gl::AttachmentList &getColorAttachmentsForRender(const gl::Context *context); + + const gl::DrawBufferMask getLastColorAttachmentsForRenderMask() const + { + return mColorAttachmentsForRenderMask; + } + + void destroy(const gl::Context *context) override; + + private: + virtual angle::Result clearImpl(const gl::Context *context, + const ClearParameters &clearParams) = 0; + + virtual angle::Result readPixelsImpl(const gl::Context *context, + const gl::Rectangle &area, + GLenum format, + GLenum type, + size_t outputPitch, + const gl::PixelPackState &pack, + gl::Buffer *packBuffer, + uint8_t *pixels) = 0; + + virtual angle::Result blitImpl(const gl::Context *context, + const gl::Rectangle &sourceArea, + const gl::Rectangle &destArea, + const gl::Rectangle *scissor, + bool blitRenderTarget, + bool blitDepth, + bool blitStencil, + GLenum filter, + const gl::Framebuffer *sourceFramebuffer) = 0; + + RendererD3D *mRenderer; + Optional mColorAttachmentsForRender; + gl::DrawBufferMask mCurrentActiveProgramOutputs; + gl::DrawBufferMask mColorAttachmentsForRenderMask; + + gl::FramebufferAttachment mMockAttachment; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_FRAMBUFFERD3D_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/HLSLCompiler.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/HLSLCompiler.cpp new file mode 100644 index 0000000000..e7260e403a --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/HLSLCompiler.cpp @@ -0,0 +1,387 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "libANGLE/renderer/d3d/HLSLCompiler.h" + +#include + +#include "common/system_utils.h" +#include "common/utilities.h" +#include "libANGLE/Context.h" +#include "libANGLE/Program.h" +#include "libANGLE/features.h" +#include "libANGLE/histogram_macros.h" +#include "libANGLE/renderer/d3d/ContextD3D.h" +#include "libANGLE/trace.h" + +namespace +{ +#if ANGLE_APPEND_ASSEMBLY_TO_SHADER_DEBUG_INFO == ANGLE_ENABLED +# ifdef CREATE_COMPILER_FLAG_INFO +# undef CREATE_COMPILER_FLAG_INFO +# endif + +# define CREATE_COMPILER_FLAG_INFO(flag) \ + { \ + flag, #flag \ + } + +struct CompilerFlagInfo +{ + UINT mFlag; + const char *mName; +}; + +CompilerFlagInfo CompilerFlagInfos[] = { + // NOTE: The data below is copied from d3dcompiler.h + // If something changes there it should be changed here as well + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_DEBUG), // (1 << 0) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_SKIP_VALIDATION), // (1 << 1) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_SKIP_OPTIMIZATION), // (1 << 2) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_PACK_MATRIX_ROW_MAJOR), // (1 << 3) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR), // (1 << 4) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_PARTIAL_PRECISION), // (1 << 5) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_FORCE_VS_SOFTWARE_NO_OPT), // (1 << 6) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_FORCE_PS_SOFTWARE_NO_OPT), // (1 << 7) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_NO_PRESHADER), // (1 << 8) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_AVOID_FLOW_CONTROL), // (1 << 9) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_PREFER_FLOW_CONTROL), // (1 << 10) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_ENABLE_STRICTNESS), // (1 << 11) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY), // (1 << 12) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_IEEE_STRICTNESS), // (1 << 13) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_OPTIMIZATION_LEVEL0), // (1 << 14) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_OPTIMIZATION_LEVEL1), // 0 + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_OPTIMIZATION_LEVEL2), // ((1 << 14) | (1 << 15)) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_OPTIMIZATION_LEVEL3), // (1 << 15) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_RESERVED16), // (1 << 16) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_RESERVED17), // (1 << 17) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_WARNINGS_ARE_ERRORS) // (1 << 18) +}; + +# undef CREATE_COMPILER_FLAG_INFO + +bool IsCompilerFlagSet(UINT mask, UINT flag) +{ + bool isFlagSet = IsMaskFlagSet(mask, flag); + + switch (flag) + { + case D3DCOMPILE_OPTIMIZATION_LEVEL0: + return isFlagSet && !IsMaskFlagSet(mask, UINT(D3DCOMPILE_OPTIMIZATION_LEVEL3)); + + case D3DCOMPILE_OPTIMIZATION_LEVEL1: + return (mask & D3DCOMPILE_OPTIMIZATION_LEVEL2) == UINT(0); + + case D3DCOMPILE_OPTIMIZATION_LEVEL3: + return isFlagSet && !IsMaskFlagSet(mask, UINT(D3DCOMPILE_OPTIMIZATION_LEVEL0)); + + default: + return isFlagSet; + } +} +#endif // ANGLE_APPEND_ASSEMBLY_TO_SHADER_DEBUG_INFO == ANGLE_ENABLED + +constexpr char kOldCompilerLibrary[] = "d3dcompiler_old.dll"; + +enum D3DCompilerLoadLibraryResult +{ + D3DCompilerDefaultLibrarySuccess, + D3DCompilerOldLibrarySuccess, + D3DCompilerFailure, + D3DCompilerEnumBoundary, +}; +} // anonymous namespace + +namespace rx +{ + +CompileConfig::CompileConfig() : flags(0), name() {} + +CompileConfig::CompileConfig(UINT flags, const std::string &name) : flags(flags), name(name) {} + +HLSLCompiler::HLSLCompiler() + : mInitialized(false), + mD3DCompilerModule(nullptr), + mD3DCompileFunc(nullptr), + mD3DDisassembleFunc(nullptr) +{} + +HLSLCompiler::~HLSLCompiler() +{ + release(); +} + +angle::Result HLSLCompiler::ensureInitialized(d3d::Context *context) +{ + if (mInitialized) + { + return angle::Result::Continue; + } + + ANGLE_TRACE_EVENT0("gpu.angle", "HLSLCompiler::initialize"); +#if !defined(ANGLE_ENABLE_WINDOWS_UWP) +# if defined(ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES) + // Find a D3DCompiler module that had already been loaded based on a predefined list of + // versions. + static const char *d3dCompilerNames[] = ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES; + + for (size_t i = 0; i < ArraySize(d3dCompilerNames); ++i) + { + if (GetModuleHandleExA(0, d3dCompilerNames[i], &mD3DCompilerModule)) + { + break; + } + } +# endif // ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES + + if (!mD3DCompilerModule) + { + // Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was + // built with. + mD3DCompilerModule = LoadLibraryA(D3DCOMPILER_DLL_A); + + if (mD3DCompilerModule) + { + ANGLE_HISTOGRAM_ENUMERATION("GPU.ANGLE.D3DCompilerLoadLibraryResult", + D3DCompilerDefaultLibrarySuccess, D3DCompilerEnumBoundary); + } + else + { + WARN() << "Failed to load HLSL compiler library. Using 'old' DLL."; + mD3DCompilerModule = LoadLibraryA(kOldCompilerLibrary); + if (mD3DCompilerModule) + { + ANGLE_HISTOGRAM_ENUMERATION("GPU.ANGLE.D3DCompilerLoadLibraryResult", + D3DCompilerOldLibrarySuccess, D3DCompilerEnumBoundary); + } + } + } + + if (!mD3DCompilerModule) + { + DWORD lastError = GetLastError(); + ERR() << "D3D Compiler LoadLibrary failed. GetLastError=" << lastError; + ANGLE_HISTOGRAM_ENUMERATION("GPU.ANGLE.D3DCompilerLoadLibraryResult", D3DCompilerFailure, + D3DCompilerEnumBoundary); + ANGLE_TRY_HR(context, E_OUTOFMEMORY, "LoadLibrary failed to load D3D Compiler DLL."); + } + + mD3DCompileFunc = + reinterpret_cast(GetProcAddress(mD3DCompilerModule, "D3DCompile")); + ASSERT(mD3DCompileFunc); + + mD3DDisassembleFunc = + reinterpret_cast(GetProcAddress(mD3DCompilerModule, "D3DDisassemble")); + ASSERT(mD3DDisassembleFunc); + +#else + // D3D Shader compiler is linked already into this module, so the export + // can be directly assigned. + mD3DCompilerModule = nullptr; + mD3DCompileFunc = reinterpret_cast(D3DCompile); + mD3DDisassembleFunc = reinterpret_cast(D3DDisassemble); +#endif + + ANGLE_CHECK_HR(context, mD3DCompileFunc, "Error finding D3DCompile entry point.", + E_OUTOFMEMORY); + + mInitialized = true; + return angle::Result::Continue; +} + +void HLSLCompiler::release() +{ + if (mInitialized) + { + FreeLibrary(mD3DCompilerModule); + mD3DCompilerModule = nullptr; + mD3DCompileFunc = nullptr; + mD3DDisassembleFunc = nullptr; + mInitialized = false; + } +} + +angle::Result HLSLCompiler::compileToBinary(d3d::Context *context, + gl::InfoLog &infoLog, + const std::string &hlsl, + const std::string &profile, + const std::vector &configs, + const D3D_SHADER_MACRO *overrideMacros, + ID3DBlob **outCompiledBlob, + std::string *outDebugInfo) +{ + ASSERT(mInitialized); + +#if !defined(ANGLE_ENABLE_WINDOWS_UWP) + ASSERT(mD3DCompilerModule); +#endif + ASSERT(mD3DCompileFunc); + +#if !defined(ANGLE_ENABLE_WINDOWS_UWP) && defined(ANGLE_ENABLE_DEBUG_TRACE) + std::string sourcePath = angle::CreateTemporaryFile().value(); + std::ostringstream stream; + stream << "#line 2 \"" << sourcePath << "\"\n\n" << hlsl; + std::string sourceText = stream.str(); + writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size()); +#endif + + const D3D_SHADER_MACRO *macros = overrideMacros ? overrideMacros : nullptr; + + for (size_t i = 0; i < configs.size(); ++i) + { + ID3DBlob *errorMessage = nullptr; + ID3DBlob *binary = nullptr; + HRESULT result = S_OK; + + { + ANGLE_TRACE_EVENT1("gpu.angle", "D3DCompile", "source", hlsl); + result = mD3DCompileFunc(hlsl.c_str(), hlsl.length(), gl::g_fakepath, macros, nullptr, + "main", profile.c_str(), configs[i].flags, 0, &binary, + &errorMessage); + } + + if (errorMessage) + { + std::string message = static_cast(errorMessage->GetBufferPointer()); + SafeRelease(errorMessage); + ANGLE_TRACE_EVENT1("gpu.angle", "D3DCompile::Error", "error", errorMessage); + + infoLog.appendSanitized(message.c_str()); + + // This produces unbelievable amounts of spam in about:gpu. + // WARN() << std::endl << hlsl; + + WARN() << std::endl << message; + + if (macros != nullptr) + { + constexpr const char *kLoopRelatedErrors[] = { + // "can't unroll loops marked with loop attribute" + "error X3531:", + + // "cannot have gradient operations inside loops with divergent flow control", + // even though it is counter-intuitive to disable unrolling for this error, some + // very long shaders have trouble deciding which loops to unroll and turning off + // forced unrolls allows them to compile properly. + "error X4014:", + + // "array index out of bounds", loop unrolling can result in invalid array + // access if the indices become constant, causing loops that may never be + // executed to generate compilation errors + "error X3504:", + }; + + bool hasLoopRelatedError = false; + for (const char *errorType : kLoopRelatedErrors) + { + if (message.find(errorType) != std::string::npos) + { + hasLoopRelatedError = true; + break; + } + } + + if (hasLoopRelatedError) + { + // Disable [loop] and [flatten] + macros = nullptr; + + // Retry without changing compiler flags + i--; + continue; + } + } + } + + if (SUCCEEDED(result)) + { + *outCompiledBlob = binary; + + (*outDebugInfo) += + "// COMPILER INPUT HLSL BEGIN\n\n" + hlsl + "\n// COMPILER INPUT HLSL END\n"; + +#if ANGLE_APPEND_ASSEMBLY_TO_SHADER_DEBUG_INFO == ANGLE_ENABLED + (*outDebugInfo) += "\n\n// ASSEMBLY BEGIN\n\n"; + (*outDebugInfo) += "// Compiler configuration: " + configs[i].name + "\n// Flags:\n"; + for (size_t fIx = 0; fIx < ArraySize(CompilerFlagInfos); ++fIx) + { + if (IsCompilerFlagSet(configs[i].flags, CompilerFlagInfos[fIx].mFlag)) + { + (*outDebugInfo) += std::string("// ") + CompilerFlagInfos[fIx].mName + "\n"; + } + } + + (*outDebugInfo) += "// Macros:\n"; + if (macros == nullptr) + { + (*outDebugInfo) += "// - : -\n"; + } + else + { + for (const D3D_SHADER_MACRO *mIt = macros; mIt->Name != nullptr; ++mIt) + { + (*outDebugInfo) += + std::string("// ") + mIt->Name + " : " + mIt->Definition + "\n"; + } + } + + std::string disassembly; + ANGLE_TRY(disassembleBinary(context, binary, &disassembly)); + (*outDebugInfo) += "\n" + disassembly + "\n// ASSEMBLY END\n"; +#endif // ANGLE_APPEND_ASSEMBLY_TO_SHADER_DEBUG_INFO == ANGLE_ENABLED + return angle::Result::Continue; + } + + if (result == E_OUTOFMEMORY) + { + *outCompiledBlob = nullptr; + ANGLE_TRY_HR(context, result, "HLSL compiler had an unexpected failure"); + } + + infoLog << "Warning: D3D shader compilation failed with " << configs[i].name << " flags. (" + << profile << ")"; + + if (i + 1 < configs.size()) + { + infoLog << " Retrying with " << configs[i + 1].name; + } + } + + // None of the configurations succeeded in compiling this shader but the compiler is still + // intact + *outCompiledBlob = nullptr; + return angle::Result::Continue; +} + +angle::Result HLSLCompiler::disassembleBinary(d3d::Context *context, + ID3DBlob *shaderBinary, + std::string *disassemblyOut) +{ + ANGLE_TRY(ensureInitialized(context)); + + // Retrieve disassembly + UINT flags = D3D_DISASM_ENABLE_DEFAULT_VALUE_PRINTS | D3D_DISASM_ENABLE_INSTRUCTION_NUMBERING; + ID3DBlob *disassembly = nullptr; + pD3DDisassemble disassembleFunc = reinterpret_cast(mD3DDisassembleFunc); + LPCVOID buffer = shaderBinary->GetBufferPointer(); + SIZE_T bufSize = shaderBinary->GetBufferSize(); + HRESULT result = disassembleFunc(buffer, bufSize, flags, "", &disassembly); + + if (SUCCEEDED(result)) + { + *disassemblyOut = std::string(static_cast(disassembly->GetBufferPointer())); + } + else + { + *disassemblyOut = ""; + } + + SafeRelease(disassembly); + + return angle::Result::Continue; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/HLSLCompiler.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/HLSLCompiler.h new file mode 100644 index 0000000000..98a17799cf --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/HLSLCompiler.h @@ -0,0 +1,74 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// HLSLCompiler: Wrapper for the D3DCompiler DLL. +// + +#ifndef LIBANGLE_RENDERER_D3D_HLSLCOMPILER_H_ +#define LIBANGLE_RENDERER_D3D_HLSLCOMPILER_H_ + +#include "libANGLE/Error.h" + +#include "common/angleutils.h" +#include "common/platform.h" + +#include +#include + +namespace gl +{ +class InfoLog; +} // namespace gl + +namespace rx +{ +namespace d3d +{ +class Context; +} // namespace d3d + +struct CompileConfig +{ + UINT flags; + std::string name; + + CompileConfig(); + CompileConfig(UINT flags, const std::string &name); +}; + +class HLSLCompiler : angle::NonCopyable +{ + public: + HLSLCompiler(); + ~HLSLCompiler(); + + void release(); + + // Attempt to compile a HLSL shader using the supplied configurations, may output a NULL + // compiled blob even if no GL errors are returned. + angle::Result compileToBinary(d3d::Context *context, + gl::InfoLog &infoLog, + const std::string &hlsl, + const std::string &profile, + const std::vector &configs, + const D3D_SHADER_MACRO *overrideMacros, + ID3DBlob **outCompiledBlob, + std::string *outDebugInfo); + + angle::Result disassembleBinary(d3d::Context *context, + ID3DBlob *shaderBinary, + std::string *disassemblyOut); + angle::Result ensureInitialized(d3d::Context *context); + + private: + bool mInitialized; + HMODULE mD3DCompilerModule; + pD3DCompile mD3DCompileFunc; + pD3DDisassemble mD3DDisassembleFunc; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_HLSLCOMPILER_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/ImageD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ImageD3D.cpp new file mode 100644 index 0000000000..67ad3aee70 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ImageD3D.cpp @@ -0,0 +1,56 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Image.h: Implements the rx::Image class, an abstract base class for the +// renderer-specific classes which will define the interface to the underlying +// surfaces or resources. + +#include "libANGLE/renderer/d3d/ImageD3D.h" + +namespace rx +{ + +ImageD3D::ImageD3D() + : mWidth(0), + mHeight(0), + mDepth(0), + mInternalFormat(GL_NONE), + mRenderable(false), + mType(gl::TextureType::InvalidEnum), + mDirty(false) +{} + +angle::Result ImageD3D::setManagedSurface2D(const gl::Context *context, + TextureStorage *storage, + int level) +{ + return angle::Result::Continue; +} + +angle::Result ImageD3D::setManagedSurfaceCube(const gl::Context *context, + TextureStorage *storage, + int face, + int level) +{ + return angle::Result::Continue; +} + +angle::Result ImageD3D::setManagedSurface3D(const gl::Context *context, + TextureStorage *storage, + int level) +{ + return angle::Result::Continue; +} + +angle::Result ImageD3D::setManagedSurface2DArray(const gl::Context *context, + TextureStorage *storage, + int layer, + int level) +{ + return angle::Result::Continue; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/ImageD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ImageD3D.h new file mode 100644 index 0000000000..ac58ca5cf6 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ImageD3D.h @@ -0,0 +1,105 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ImageD3D.h: Defines the rx::ImageD3D class, an abstract base class for the +// renderer-specific classes which will define the interface to the underlying +// surfaces or resources. + +#ifndef LIBANGLE_RENDERER_D3D_IMAGED3D_H_ +#define LIBANGLE_RENDERER_D3D_IMAGED3D_H_ + +#include "common/debug.h" + +#include "common/PackedEnums.h" +#include "libANGLE/Error.h" +#include "libANGLE/angletypes.h" + +namespace gl +{ +class Context; +class Framebuffer; +class ImageIndex; +struct PixelUnpackState; +} // namespace gl + +namespace rx +{ +class TextureStorage; +class RendererD3D; +class RenderTargetD3D; + +class ImageD3D : angle::NonCopyable +{ + public: + ImageD3D(); + virtual ~ImageD3D() {} + + GLsizei getWidth() const { return mWidth; } + GLsizei getHeight() const { return mHeight; } + GLsizei getDepth() const { return mDepth; } + GLenum getInternalFormat() const { return mInternalFormat; } + gl::TextureType getType() const { return mType; } + bool isRenderableFormat() const { return mRenderable; } + + void markDirty() { mDirty = true; } + void markClean() { mDirty = false; } + virtual bool isDirty() const = 0; + + virtual bool redefine(gl::TextureType type, + GLenum internalformat, + const gl::Extents &size, + bool forceRelease) = 0; + + virtual angle::Result loadData(const gl::Context *context, + const gl::Box &area, + const gl::PixelUnpackState &unpack, + GLenum type, + const void *input, + bool applySkipImages) = 0; + virtual angle::Result loadCompressedData(const gl::Context *context, + const gl::Box &area, + const void *input) = 0; + + virtual angle::Result setManagedSurface2D(const gl::Context *context, + TextureStorage *storage, + int level); + virtual angle::Result setManagedSurfaceCube(const gl::Context *context, + TextureStorage *storage, + int face, + int level); + virtual angle::Result setManagedSurface3D(const gl::Context *context, + TextureStorage *storage, + int level); + virtual angle::Result setManagedSurface2DArray(const gl::Context *context, + TextureStorage *storage, + int layer, + int level); + virtual angle::Result copyToStorage(const gl::Context *context, + TextureStorage *storage, + const gl::ImageIndex &index, + const gl::Box ®ion) = 0; + + virtual angle::Result copyFromTexStorage(const gl::Context *context, + const gl::ImageIndex &imageIndex, + TextureStorage *source) = 0; + virtual angle::Result copyFromFramebuffer(const gl::Context *context, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + const gl::Framebuffer *source) = 0; + + protected: + GLsizei mWidth; + GLsizei mHeight; + GLsizei mDepth; + GLenum mInternalFormat; + bool mRenderable; + gl::TextureType mType; + + bool mDirty; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_IMAGED3D_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexBuffer.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexBuffer.cpp new file mode 100644 index 0000000000..423067e67e --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexBuffer.cpp @@ -0,0 +1,183 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// IndexBuffer.cpp: Defines the abstract IndexBuffer class and IndexBufferInterface +// class with derivations, classes that perform graphics API agnostic index buffer operations. + +#include "libANGLE/renderer/d3d/IndexBuffer.h" + +#include "libANGLE/Context.h" +#include "libANGLE/renderer/d3d/ContextD3D.h" + +namespace rx +{ + +unsigned int IndexBuffer::mNextSerial = 1; + +IndexBuffer::IndexBuffer() +{ + updateSerial(); +} + +IndexBuffer::~IndexBuffer() {} + +unsigned int IndexBuffer::getSerial() const +{ + return mSerial; +} + +void IndexBuffer::updateSerial() +{ + mSerial = mNextSerial++; +} + +IndexBufferInterface::IndexBufferInterface(BufferFactoryD3D *factory, bool dynamic) +{ + mIndexBuffer = factory->createIndexBuffer(); + + mDynamic = dynamic; + mWritePosition = 0; +} + +IndexBufferInterface::~IndexBufferInterface() +{ + if (mIndexBuffer) + { + delete mIndexBuffer; + } +} + +gl::DrawElementsType IndexBufferInterface::getIndexType() const +{ + return mIndexBuffer->getIndexType(); +} + +unsigned int IndexBufferInterface::getBufferSize() const +{ + return mIndexBuffer->getBufferSize(); +} + +unsigned int IndexBufferInterface::getSerial() const +{ + return mIndexBuffer->getSerial(); +} + +angle::Result IndexBufferInterface::mapBuffer(const gl::Context *context, + unsigned int size, + void **outMappedMemory, + unsigned int *streamOffset) +{ + // Protect against integer overflow + bool check = (mWritePosition + size < mWritePosition); + ANGLE_CHECK(GetImplAs(context), !check, + "Mapping of internal index buffer would cause an integer overflow.", + GL_OUT_OF_MEMORY); + + angle::Result error = mIndexBuffer->mapBuffer(context, mWritePosition, size, outMappedMemory); + if (error == angle::Result::Stop) + { + if (outMappedMemory) + { + *outMappedMemory = nullptr; + } + return error; + } + + if (streamOffset) + { + *streamOffset = mWritePosition; + } + + mWritePosition += size; + return angle::Result::Continue; +} + +angle::Result IndexBufferInterface::unmapBuffer(const gl::Context *context) +{ + return mIndexBuffer->unmapBuffer(context); +} + +IndexBuffer *IndexBufferInterface::getIndexBuffer() const +{ + return mIndexBuffer; +} + +unsigned int IndexBufferInterface::getWritePosition() const +{ + return mWritePosition; +} + +void IndexBufferInterface::setWritePosition(unsigned int writePosition) +{ + mWritePosition = writePosition; +} + +angle::Result IndexBufferInterface::discard(const gl::Context *context) +{ + return mIndexBuffer->discard(context); +} + +angle::Result IndexBufferInterface::setBufferSize(const gl::Context *context, + unsigned int bufferSize, + gl::DrawElementsType indexType) +{ + if (mIndexBuffer->getBufferSize() == 0) + { + return mIndexBuffer->initialize(context, bufferSize, indexType, mDynamic); + } + else + { + return mIndexBuffer->setSize(context, bufferSize, indexType); + } +} + +StreamingIndexBufferInterface::StreamingIndexBufferInterface(BufferFactoryD3D *factory) + : IndexBufferInterface(factory, true) +{} + +StreamingIndexBufferInterface::~StreamingIndexBufferInterface() {} + +angle::Result StreamingIndexBufferInterface::reserveBufferSpace(const gl::Context *context, + unsigned int size, + gl::DrawElementsType indexType) +{ + unsigned int curBufferSize = getBufferSize(); + unsigned int writePos = getWritePosition(); + if (size > curBufferSize) + { + ANGLE_TRY(setBufferSize(context, std::max(size, 2 * curBufferSize), indexType)); + setWritePosition(0); + } + else if (writePos + size > curBufferSize || writePos + size < writePos) + { + ANGLE_TRY(discard(context)); + setWritePosition(0); + } + + return angle::Result::Continue; +} + +StaticIndexBufferInterface::StaticIndexBufferInterface(BufferFactoryD3D *factory) + : IndexBufferInterface(factory, false) +{} + +StaticIndexBufferInterface::~StaticIndexBufferInterface() {} + +angle::Result StaticIndexBufferInterface::reserveBufferSpace(const gl::Context *context, + unsigned int size, + gl::DrawElementsType indexType) +{ + unsigned int curSize = getBufferSize(); + if (curSize == 0) + { + return setBufferSize(context, size, indexType); + } + + ASSERT(curSize >= size && indexType == getIndexType()); + return angle::Result::Continue; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexBuffer.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexBuffer.h new file mode 100644 index 0000000000..7bab52a9f0 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexBuffer.h @@ -0,0 +1,125 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// IndexBuffer.h: Defines the abstract IndexBuffer class and IndexBufferInterface +// class with derivations, classes that perform graphics API agnostic index buffer operations. + +#ifndef LIBANGLE_RENDERER_D3D_INDEXBUFFER_H_ +#define LIBANGLE_RENDERER_D3D_INDEXBUFFER_H_ + +#include "common/PackedEnums.h" +#include "common/angleutils.h" +#include "libANGLE/Error.h" + +namespace gl +{ +class Context; +} // namespace gl + +namespace rx +{ +class BufferFactoryD3D; + +class IndexBuffer : angle::NonCopyable +{ + public: + IndexBuffer(); + virtual ~IndexBuffer(); + + virtual angle::Result initialize(const gl::Context *context, + unsigned int bufferSize, + gl::DrawElementsType indexType, + bool dynamic) = 0; + + virtual angle::Result mapBuffer(const gl::Context *context, + unsigned int offset, + unsigned int size, + void **outMappedMemory) = 0; + virtual angle::Result unmapBuffer(const gl::Context *context) = 0; + + virtual angle::Result discard(const gl::Context *context) = 0; + + virtual gl::DrawElementsType getIndexType() const = 0; + virtual unsigned int getBufferSize() const = 0; + virtual angle::Result setSize(const gl::Context *context, + unsigned int bufferSize, + gl::DrawElementsType indexType) = 0; + + unsigned int getSerial() const; + + protected: + void updateSerial(); + + private: + unsigned int mSerial; + static unsigned int mNextSerial; +}; + +class IndexBufferInterface : angle::NonCopyable +{ + public: + IndexBufferInterface(BufferFactoryD3D *factory, bool dynamic); + virtual ~IndexBufferInterface(); + + virtual angle::Result reserveBufferSpace(const gl::Context *context, + unsigned int size, + gl::DrawElementsType indexType) = 0; + + gl::DrawElementsType getIndexType() const; + unsigned int getBufferSize() const; + + unsigned int getSerial() const; + + angle::Result mapBuffer(const gl::Context *context, + unsigned int size, + void **outMappedMemory, + unsigned int *streamOffset); + angle::Result unmapBuffer(const gl::Context *context); + + IndexBuffer *getIndexBuffer() const; + + protected: + unsigned int getWritePosition() const; + void setWritePosition(unsigned int writePosition); + + angle::Result discard(const gl::Context *context); + + angle::Result setBufferSize(const gl::Context *context, + unsigned int bufferSize, + gl::DrawElementsType indexType); + + private: + IndexBuffer *mIndexBuffer; + + unsigned int mWritePosition; + bool mDynamic; +}; + +class StreamingIndexBufferInterface : public IndexBufferInterface +{ + public: + explicit StreamingIndexBufferInterface(BufferFactoryD3D *factory); + ~StreamingIndexBufferInterface() override; + + angle::Result reserveBufferSpace(const gl::Context *context, + unsigned int size, + gl::DrawElementsType indexType) override; +}; + +class StaticIndexBufferInterface : public IndexBufferInterface +{ + public: + explicit StaticIndexBufferInterface(BufferFactoryD3D *factory); + ~StaticIndexBufferInterface() override; + + angle::Result reserveBufferSpace(const gl::Context *context, + unsigned int size, + gl::DrawElementsType indexType) override; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_INDEXBUFFER_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexDataManager.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexDataManager.cpp new file mode 100644 index 0000000000..dd8f45342f --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexDataManager.cpp @@ -0,0 +1,318 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// IndexDataManager.cpp: Defines the IndexDataManager, a class that +// runs the Buffer translation process for index buffers. + +#include "libANGLE/renderer/d3d/IndexDataManager.h" + +#include "common/utilities.h" +#include "libANGLE/Buffer.h" +#include "libANGLE/Context.h" +#include "libANGLE/VertexArray.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/BufferD3D.h" +#include "libANGLE/renderer/d3d/ContextD3D.h" +#include "libANGLE/renderer/d3d/IndexBuffer.h" + +namespace rx +{ + +namespace +{ + +template +void ConvertIndexArray(const void *input, + gl::DrawElementsType sourceType, + void *output, + gl::DrawElementsType destinationType, + GLsizei count, + bool usePrimitiveRestartFixedIndex) +{ + const InputT *in = static_cast(input); + DestT *out = static_cast(output); + + if (usePrimitiveRestartFixedIndex) + { + InputT srcRestartIndex = static_cast(gl::GetPrimitiveRestartIndex(sourceType)); + DestT destRestartIndex = static_cast(gl::GetPrimitiveRestartIndex(destinationType)); + for (GLsizei i = 0; i < count; i++) + { + out[i] = (in[i] == srcRestartIndex ? destRestartIndex : static_cast(in[i])); + } + } + else + { + for (GLsizei i = 0; i < count; i++) + { + out[i] = static_cast(in[i]); + } + } +} + +void ConvertIndices(gl::DrawElementsType sourceType, + gl::DrawElementsType destinationType, + const void *input, + GLsizei count, + void *output, + bool usePrimitiveRestartFixedIndex) +{ + if (sourceType == destinationType) + { + const GLuint dstTypeSize = gl::GetDrawElementsTypeSize(destinationType); + memcpy(output, input, count * dstTypeSize); + return; + } + + if (sourceType == gl::DrawElementsType::UnsignedByte) + { + ASSERT(destinationType == gl::DrawElementsType::UnsignedShort); + ConvertIndexArray(input, sourceType, output, destinationType, count, + usePrimitiveRestartFixedIndex); + } + else if (sourceType == gl::DrawElementsType::UnsignedShort) + { + ASSERT(destinationType == gl::DrawElementsType::UnsignedInt); + ConvertIndexArray(input, sourceType, output, destinationType, count, + usePrimitiveRestartFixedIndex); + } + else + UNREACHABLE(); +} + +angle::Result StreamInIndexBuffer(const gl::Context *context, + IndexBufferInterface *buffer, + const void *data, + unsigned int count, + gl::DrawElementsType srcType, + gl::DrawElementsType dstType, + bool usePrimitiveRestartFixedIndex, + unsigned int *offset) +{ + const GLuint dstTypeBytesShift = gl::GetDrawElementsTypeShift(dstType); + + bool check = (count > (std::numeric_limits::max() >> dstTypeBytesShift)); + ANGLE_CHECK(GetImplAs(context), !check, + "Reserving indices exceeds the maximum buffer size.", GL_OUT_OF_MEMORY); + + unsigned int bufferSizeRequired = count << dstTypeBytesShift; + ANGLE_TRY(buffer->reserveBufferSpace(context, bufferSizeRequired, dstType)); + + void *output = nullptr; + ANGLE_TRY(buffer->mapBuffer(context, bufferSizeRequired, &output, offset)); + + ConvertIndices(srcType, dstType, data, count, output, usePrimitiveRestartFixedIndex); + + ANGLE_TRY(buffer->unmapBuffer(context)); + return angle::Result::Continue; +} +} // anonymous namespace + +// IndexDataManager implementation. +IndexDataManager::IndexDataManager(BufferFactoryD3D *factory) + : mFactory(factory), mStreamingBufferShort(), mStreamingBufferInt() +{} + +IndexDataManager::~IndexDataManager() {} + +void IndexDataManager::deinitialize() +{ + mStreamingBufferShort.reset(); + mStreamingBufferInt.reset(); +} + +// This function translates a GL-style indices into DX-style indices, with their description +// returned in translated. +// GL can specify vertex data in immediate mode (pointer to CPU array of indices), which is not +// possible in DX and requires streaming (Case 1). If the GL indices are specified with a buffer +// (Case 2), in a format supported by DX (subcase a) then all is good. +// When we have a buffer with an unsupported format (subcase b) then we need to do some translation: +// we will start by falling back to streaming, and after a while will start using a static +// translated copy of the index buffer. +angle::Result IndexDataManager::prepareIndexData(const gl::Context *context, + gl::DrawElementsType srcType, + gl::DrawElementsType dstType, + GLsizei count, + gl::Buffer *glBuffer, + const void *indices, + TranslatedIndexData *translated) +{ + GLuint srcTypeBytes = gl::GetDrawElementsTypeSize(srcType); + GLuint srcTypeShift = gl::GetDrawElementsTypeShift(srcType); + GLuint dstTypeShift = gl::GetDrawElementsTypeShift(dstType); + + BufferD3D *buffer = glBuffer ? GetImplAs(glBuffer) : nullptr; + + translated->indexType = dstType; + translated->srcIndexData.srcBuffer = buffer; + translated->srcIndexData.srcIndices = indices; + translated->srcIndexData.srcIndexType = srcType; + translated->srcIndexData.srcCount = count; + + // Context can be nullptr in perf tests. + bool primitiveRestartFixedIndexEnabled = + context ? context->getState().isPrimitiveRestartEnabled() : false; + + // Case 1: the indices are passed by pointer, which forces the streaming of index data + if (glBuffer == nullptr) + { + translated->storage = nullptr; + return streamIndexData(context, indices, count, srcType, dstType, + primitiveRestartFixedIndexEnabled, translated); + } + + // Case 2: the indices are already in a buffer + unsigned int offset = static_cast(reinterpret_cast(indices)); + ASSERT(srcTypeBytes * static_cast(count) + offset <= buffer->getSize()); + + bool offsetAligned = IsOffsetAligned(srcType, offset); + + // Case 2a: the buffer can be used directly + if (offsetAligned && buffer->supportsDirectBinding() && dstType == srcType) + { + translated->storage = buffer; + translated->indexBuffer = nullptr; + translated->serial = buffer->getSerial(); + translated->startIndex = (offset >> srcTypeShift); + translated->startOffset = offset; + return angle::Result::Continue; + } + + translated->storage = nullptr; + + // Case 2b: use a static translated copy or fall back to streaming + StaticIndexBufferInterface *staticBuffer = buffer->getStaticIndexBuffer(); + + bool staticBufferInitialized = staticBuffer && staticBuffer->getBufferSize() != 0; + bool staticBufferUsable = + staticBuffer && offsetAligned && staticBuffer->getIndexType() == dstType; + + if (staticBufferInitialized && !staticBufferUsable) + { + buffer->invalidateStaticData(context); + staticBuffer = nullptr; + } + + if (staticBuffer == nullptr || !offsetAligned) + { + const uint8_t *bufferData = nullptr; + ANGLE_TRY(buffer->getData(context, &bufferData)); + ASSERT(bufferData != nullptr); + + ANGLE_TRY(streamIndexData(context, bufferData + offset, count, srcType, dstType, + primitiveRestartFixedIndexEnabled, translated)); + buffer->promoteStaticUsage(context, count << srcTypeShift); + } + else + { + if (!staticBufferInitialized) + { + const uint8_t *bufferData = nullptr; + ANGLE_TRY(buffer->getData(context, &bufferData)); + ASSERT(bufferData != nullptr); + + unsigned int convertCount = + static_cast(buffer->getSize()) >> srcTypeShift; + ANGLE_TRY(StreamInIndexBuffer(context, staticBuffer, bufferData, convertCount, srcType, + dstType, primitiveRestartFixedIndexEnabled, nullptr)); + } + ASSERT(offsetAligned && staticBuffer->getIndexType() == dstType); + + translated->indexBuffer = staticBuffer->getIndexBuffer(); + translated->serial = staticBuffer->getSerial(); + translated->startIndex = (offset >> srcTypeShift); + translated->startOffset = (offset >> srcTypeShift) << dstTypeShift; + } + + return angle::Result::Continue; +} + +angle::Result IndexDataManager::streamIndexData(const gl::Context *context, + const void *data, + unsigned int count, + gl::DrawElementsType srcType, + gl::DrawElementsType dstType, + bool usePrimitiveRestartFixedIndex, + TranslatedIndexData *translated) +{ + const GLuint dstTypeShift = gl::GetDrawElementsTypeShift(dstType); + + IndexBufferInterface *indexBuffer = nullptr; + ANGLE_TRY(getStreamingIndexBuffer(context, dstType, &indexBuffer)); + ASSERT(indexBuffer != nullptr); + + unsigned int offset; + ANGLE_TRY(StreamInIndexBuffer(context, indexBuffer, data, count, srcType, dstType, + usePrimitiveRestartFixedIndex, &offset)); + + translated->indexBuffer = indexBuffer->getIndexBuffer(); + translated->serial = indexBuffer->getSerial(); + translated->startIndex = (offset >> dstTypeShift); + translated->startOffset = offset; + + return angle::Result::Continue; +} + +angle::Result IndexDataManager::getStreamingIndexBuffer(const gl::Context *context, + gl::DrawElementsType destinationIndexType, + IndexBufferInterface **outBuffer) +{ + ASSERT(outBuffer); + ASSERT(destinationIndexType == gl::DrawElementsType::UnsignedShort || + destinationIndexType == gl::DrawElementsType::UnsignedInt); + + auto &streamingBuffer = (destinationIndexType == gl::DrawElementsType::UnsignedInt) + ? mStreamingBufferInt + : mStreamingBufferShort; + + if (!streamingBuffer) + { + StreamingBuffer newBuffer(new StreamingIndexBufferInterface(mFactory)); + ANGLE_TRY(newBuffer->reserveBufferSpace(context, INITIAL_INDEX_BUFFER_SIZE, + destinationIndexType)); + streamingBuffer = std::move(newBuffer); + } + + *outBuffer = streamingBuffer.get(); + return angle::Result::Continue; +} + +angle::Result GetIndexTranslationDestType(const gl::Context *context, + GLsizei indexCount, + gl::DrawElementsType indexType, + const void *indices, + bool usePrimitiveRestartWorkaround, + gl::DrawElementsType *destTypeOut) +{ + // Avoid D3D11's primitive restart index value + // see http://msdn.microsoft.com/en-us/library/windows/desktop/bb205124(v=vs.85).aspx + if (usePrimitiveRestartWorkaround) + { + // Conservatively assume we need to translate the indices for draw indirect. + // This is a bit of a trick. We assume the count for an indirect draw is zero. + if (indexCount == 0) + { + *destTypeOut = gl::DrawElementsType::UnsignedInt; + return angle::Result::Continue; + } + + gl::IndexRange indexRange; + ANGLE_TRY(context->getState().getVertexArray()->getIndexRange( + context, indexType, indexCount, indices, &indexRange)); + if (indexRange.end == gl::GetPrimitiveRestartIndex(indexType)) + { + *destTypeOut = gl::DrawElementsType::UnsignedInt; + return angle::Result::Continue; + } + } + + *destTypeOut = (indexType == gl::DrawElementsType::UnsignedInt) + ? gl::DrawElementsType::UnsignedInt + : gl::DrawElementsType::UnsignedShort; + return angle::Result::Continue; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexDataManager.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexDataManager.h new file mode 100644 index 0000000000..53bfc721da --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexDataManager.h @@ -0,0 +1,112 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// IndexDataManager.h: Defines the IndexDataManager, a class that +// runs the Buffer translation process for index buffers. + +#ifndef LIBANGLE_INDEXDATAMANAGER_H_ +#define LIBANGLE_INDEXDATAMANAGER_H_ + +#include + +#include "common/angleutils.h" +#include "common/mathutil.h" +#include "libANGLE/Error.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" + +namespace +{ +enum +{ + INITIAL_INDEX_BUFFER_SIZE = 4096 * sizeof(GLuint) +}; +} + +namespace gl +{ +class Buffer; +} + +namespace rx +{ +class IndexBufferInterface; +class StaticIndexBufferInterface; +class StreamingIndexBufferInterface; +class IndexBuffer; +class BufferD3D; +class RendererD3D; + +struct SourceIndexData +{ + BufferD3D *srcBuffer; + const void *srcIndices; + unsigned int srcCount; + gl::DrawElementsType srcIndexType; + bool srcIndicesChanged; +}; + +struct TranslatedIndexData +{ + unsigned int startIndex; + unsigned int startOffset; // In bytes + + IndexBuffer *indexBuffer; + BufferD3D *storage; + gl::DrawElementsType indexType; + unsigned int serial; + + SourceIndexData srcIndexData; +}; + +class IndexDataManager : angle::NonCopyable +{ + public: + explicit IndexDataManager(BufferFactoryD3D *factory); + virtual ~IndexDataManager(); + + void deinitialize(); + + angle::Result prepareIndexData(const gl::Context *context, + gl::DrawElementsType srcType, + gl::DrawElementsType dstType, + GLsizei count, + gl::Buffer *glBuffer, + const void *indices, + TranslatedIndexData *translated); + + private: + angle::Result streamIndexData(const gl::Context *context, + const void *data, + unsigned int count, + gl::DrawElementsType srcType, + gl::DrawElementsType dstType, + bool usePrimitiveRestartFixedIndex, + TranslatedIndexData *translated); + angle::Result getStreamingIndexBuffer(const gl::Context *context, + gl::DrawElementsType destinationIndexType, + IndexBufferInterface **outBuffer); + + using StreamingBuffer = std::unique_ptr; + + BufferFactoryD3D *const mFactory; + std::unique_ptr mStreamingBufferShort; + std::unique_ptr mStreamingBufferInt; +}; + +angle::Result GetIndexTranslationDestType(const gl::Context *context, + GLsizei indexCount, + gl::DrawElementsType indexType, + const void *indices, + bool usePrimitiveRestartWorkaround, + gl::DrawElementsType *destTypeOut); + +ANGLE_INLINE bool IsOffsetAligned(gl::DrawElementsType elementType, unsigned int offset) +{ + return (offset % gl::GetDrawElementsTypeSize(elementType) == 0); +} +} // namespace rx + +#endif // LIBANGLE_INDEXDATAMANAGER_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/NativeWindowD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/NativeWindowD3D.cpp new file mode 100644 index 0000000000..a8543a06d7 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/NativeWindowD3D.cpp @@ -0,0 +1,19 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// NativeWindowD3D.cpp: Defines NativeWindowD3D, a class for managing and performing operations on +// an EGLNativeWindowType for the D3D renderers. + +#include "libANGLE/renderer/d3d/NativeWindowD3D.h" + +namespace rx +{ + +NativeWindowD3D::NativeWindowD3D(EGLNativeWindowType window) : mWindow(window) {} + +NativeWindowD3D::~NativeWindowD3D() {} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/NativeWindowD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/NativeWindowD3D.h new file mode 100644 index 0000000000..8560f16bde --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/NativeWindowD3D.h @@ -0,0 +1,38 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// NativeWindowD3D.h: Defines NativeWindowD3D, a class for managing and performing operations on an +// EGLNativeWindowType for the D3D renderers. + +#ifndef LIBANGLE_RENDERER_D3D_NATIVEWINDOWD3D_H_ +#define LIBANGLE_RENDERER_D3D_NATIVEWINDOWD3D_H_ + +#include "common/debug.h" +#include "common/platform.h" + +#include +#include "libANGLE/Config.h" + +namespace rx +{ +class NativeWindowD3D : angle::NonCopyable +{ + public: + NativeWindowD3D(EGLNativeWindowType window); + virtual ~NativeWindowD3D(); + + virtual bool initialize() = 0; + virtual bool getClientRect(LPRECT rect) const = 0; + virtual bool isIconic() const = 0; + + inline EGLNativeWindowType getNativeWindow() const { return mWindow; } + + private: + EGLNativeWindowType mWindow; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_NATIVEWINDOWD3D_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/ProgramD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ProgramD3D.cpp new file mode 100644 index 0000000000..b38ede4133 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ProgramD3D.cpp @@ -0,0 +1,3412 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ProgramD3D.cpp: Defines the rx::ProgramD3D class which implements rx::ProgramImpl. + +#include "libANGLE/renderer/d3d/ProgramD3D.h" + +#include "common/MemoryBuffer.h" +#include "common/bitset_utils.h" +#include "common/string_utils.h" +#include "common/utilities.h" +#include "libANGLE/Context.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/Program.h" +#include "libANGLE/ProgramLinkedResources.h" +#include "libANGLE/Uniform.h" +#include "libANGLE/VertexArray.h" +#include "libANGLE/features.h" +#include "libANGLE/queryconversions.h" +#include "libANGLE/renderer/ContextImpl.h" +#include "libANGLE/renderer/d3d/ContextD3D.h" +#include "libANGLE/renderer/d3d/DynamicHLSL.h" +#include "libANGLE/renderer/d3d/FramebufferD3D.h" +#include "libANGLE/renderer/d3d/ShaderD3D.h" +#include "libANGLE/renderer/d3d/ShaderExecutableD3D.h" +#include "libANGLE/renderer/d3d/VertexDataManager.h" +#include "libANGLE/renderer/renderer_utils.h" +#include "libANGLE/trace.h" + +using namespace angle; + +namespace rx +{ + +namespace +{ + +void GetDefaultInputLayoutFromShader(const gl::Context *context, + gl::Shader *vertexShader, + gl::InputLayout *inputLayoutOut) +{ + inputLayoutOut->clear(); + + if (!vertexShader) + { + return; + } + + for (const sh::ShaderVariable &shaderAttr : vertexShader->getActiveAttributes(context)) + { + if (shaderAttr.type != GL_NONE) + { + GLenum transposedType = gl::TransposeMatrixType(shaderAttr.type); + + for (size_t rowIndex = 0; + static_cast(rowIndex) < gl::VariableRowCount(transposedType); ++rowIndex) + { + GLenum componentType = gl::VariableComponentType(transposedType); + GLuint components = static_cast(gl::VariableColumnCount(transposedType)); + bool pureInt = (componentType != GL_FLOAT); + + gl::VertexAttribType attribType = + gl::FromGLenum(componentType); + + angle::FormatID defaultID = + gl::GetVertexFormatID(attribType, GL_FALSE, components, pureInt); + + inputLayoutOut->push_back(defaultID); + } + } + } +} + +size_t GetMaxOutputIndex(const std::vector &shaderOutputVars, + size_t location) +{ + size_t maxIndex = 0; + for (auto &outputVar : shaderOutputVars) + { + if (outputVar.outputLocation == location) + { + maxIndex = std::max(maxIndex, outputVar.outputIndex); + } + } + return maxIndex; +} + +void GetDefaultOutputLayoutFromShader( + const std::vector &shaderOutputVars, + std::vector *outputLayoutOut) +{ + outputLayoutOut->clear(); + + if (!shaderOutputVars.empty()) + { + size_t location = shaderOutputVars[0].outputLocation; + size_t maxIndex = GetMaxOutputIndex(shaderOutputVars, location); + outputLayoutOut->assign(maxIndex + 1, + GL_COLOR_ATTACHMENT0 + static_cast(location)); + } +} + +void GetDefaultImage2DBindLayoutFromShader(const std::vector &image2DUniforms, + gl::ImageUnitTextureTypeMap *image2DBindLayout) +{ + image2DBindLayout->clear(); + + for (const sh::ShaderVariable &image2D : image2DUniforms) + { + if (gl::IsImage2DType(image2D.type)) + { + if (image2D.binding == -1) + { + image2DBindLayout->insert(std::make_pair(0, gl::TextureType::_2D)); + } + else + { + for (unsigned int index = 0; index < image2D.getArraySizeProduct(); index++) + { + image2DBindLayout->insert( + std::make_pair(image2D.binding + index, gl::TextureType::_2D)); + } + } + } + } +} + +gl::PrimitiveMode GetGeometryShaderTypeFromDrawMode(gl::PrimitiveMode drawMode) +{ + switch (drawMode) + { + // Uses the point sprite geometry shader. + case gl::PrimitiveMode::Points: + return gl::PrimitiveMode::Points; + + // All line drawing uses the same geometry shader. + case gl::PrimitiveMode::Lines: + case gl::PrimitiveMode::LineStrip: + case gl::PrimitiveMode::LineLoop: + return gl::PrimitiveMode::Lines; + + // The triangle fan primitive is emulated with strips in D3D11. + case gl::PrimitiveMode::Triangles: + case gl::PrimitiveMode::TriangleFan: + return gl::PrimitiveMode::Triangles; + + // Special case for triangle strips. + case gl::PrimitiveMode::TriangleStrip: + return gl::PrimitiveMode::TriangleStrip; + + default: + UNREACHABLE(); + return gl::PrimitiveMode::InvalidEnum; + } +} + +bool HasFlatInterpolationVarying(const std::vector &varyings) +{ + // Note: this assumes nested structs can only be packed with one interpolation. + for (const auto &varying : varyings) + { + if (varying.interpolation == sh::INTERPOLATION_FLAT) + { + return true; + } + } + + return false; +} + +bool FindFlatInterpolationVaryingPerShader(const gl::Context *context, gl::Shader *shader) +{ + ASSERT(shader); + switch (shader->getType()) + { + case gl::ShaderType::Vertex: + return HasFlatInterpolationVarying(shader->getOutputVaryings(context)); + case gl::ShaderType::Fragment: + return HasFlatInterpolationVarying(shader->getInputVaryings(context)); + case gl::ShaderType::Geometry: + return HasFlatInterpolationVarying(shader->getInputVaryings(context)) || + HasFlatInterpolationVarying(shader->getOutputVaryings(context)); + default: + UNREACHABLE(); + return false; + } +} + +bool FindFlatInterpolationVarying(const gl::Context *context, + const gl::ShaderMap &shaders) +{ + for (gl::ShaderType shaderType : gl::kAllGraphicsShaderTypes) + { + gl::Shader *shader = shaders[shaderType]; + if (!shader) + { + continue; + } + + if (FindFlatInterpolationVaryingPerShader(context, shader)) + { + return true; + } + } + + return false; +} + +// Helper class that gathers uniform info from the default uniform block. +class UniformEncodingVisitorD3D : public sh::BlockEncoderVisitor +{ + public: + UniformEncodingVisitorD3D(gl::ShaderType shaderType, + HLSLRegisterType registerType, + sh::BlockLayoutEncoder *encoder, + D3DUniformMap *uniformMapOut) + : sh::BlockEncoderVisitor("", "", encoder), + mShaderType(shaderType), + mRegisterType(registerType), + mUniformMapOut(uniformMapOut) + {} + + void visitNamedOpaqueObject(const sh::ShaderVariable &sampler, + const std::string &name, + const std::string &mappedName, + const std::vector &arraySizes) override + { + auto uniformMapEntry = mUniformMapOut->find(name); + if (uniformMapEntry == mUniformMapOut->end()) + { + (*mUniformMapOut)[name] = + new D3DUniform(sampler.type, mRegisterType, name, sampler.arraySizes, true); + } + } + + void encodeVariable(const sh::ShaderVariable &variable, + const sh::BlockMemberInfo &variableInfo, + const std::string &name, + const std::string &mappedName) override + { + auto uniformMapEntry = mUniformMapOut->find(name); + D3DUniform *d3dUniform = nullptr; + + if (uniformMapEntry != mUniformMapOut->end()) + { + d3dUniform = uniformMapEntry->second; + } + else + { + d3dUniform = + new D3DUniform(variable.type, mRegisterType, name, variable.arraySizes, true); + (*mUniformMapOut)[name] = d3dUniform; + } + + d3dUniform->registerElement = static_cast( + sh::BlockLayoutEncoder::GetBlockRegisterElement(variableInfo)); + unsigned int reg = + static_cast(sh::BlockLayoutEncoder::GetBlockRegister(variableInfo)); + + ASSERT(mShaderType != gl::ShaderType::InvalidEnum); + d3dUniform->mShaderRegisterIndexes[mShaderType] = reg; + } + + private: + gl::ShaderType mShaderType; + HLSLRegisterType mRegisterType; + D3DUniformMap *mUniformMapOut; +}; + +class HLSLBlockLayoutEncoderFactory : public gl::CustomBlockLayoutEncoderFactory +{ + public: + sh::BlockLayoutEncoder *makeEncoder() override + { + return new sh::HLSLBlockEncoder(sh::HLSLBlockEncoder::ENCODE_PACKED, false); + } +}; +} // anonymous namespace + +// D3DUniform Implementation + +D3DUniform::D3DUniform(GLenum type, + HLSLRegisterType reg, + const std::string &nameIn, + const std::vector &arraySizesIn, + bool defaultBlock) + : typeInfo(gl::GetUniformTypeInfo(type)), + name(nameIn), + arraySizes(arraySizesIn), + mShaderData({}), + regType(reg), + registerCount(0), + registerElement(0) +{ + mShaderRegisterIndexes.fill(GL_INVALID_INDEX); + + // We use data storage for default block uniforms to cache values that are sent to D3D during + // rendering + // Uniform blocks/buffers are treated separately by the Renderer (ES3 path only) + if (defaultBlock) + { + // Use the row count as register count, will work for non-square matrices. + registerCount = typeInfo.rowCount * getArraySizeProduct(); + } +} + +D3DUniform::~D3DUniform() {} + +unsigned int D3DUniform::getArraySizeProduct() const +{ + return gl::ArraySizeProduct(arraySizes); +} + +const uint8_t *D3DUniform::getDataPtrToElement(size_t elementIndex) const +{ + ASSERT((!isArray() && elementIndex == 0) || + (isArray() && elementIndex < getArraySizeProduct())); + + if (isSampler()) + { + return reinterpret_cast(&mSamplerData[elementIndex]); + } + + return firstNonNullData() + (elementIndex > 0 ? (typeInfo.internalSize * elementIndex) : 0u); +} + +bool D3DUniform::isSampler() const +{ + return typeInfo.isSampler; +} + +bool D3DUniform::isImage() const +{ + return typeInfo.isImageType; +} + +bool D3DUniform::isImage2D() const +{ + return gl::IsImage2DType(typeInfo.type); +} + +bool D3DUniform::isReferencedByShader(gl::ShaderType shaderType) const +{ + return mShaderRegisterIndexes[shaderType] != GL_INVALID_INDEX; +} + +const uint8_t *D3DUniform::firstNonNullData() const +{ + if (!mSamplerData.empty()) + { + return reinterpret_cast(mSamplerData.data()); + } + + for (gl::ShaderType shaderType : gl::AllShaderTypes()) + { + if (mShaderData[shaderType]) + { + return mShaderData[shaderType]; + } + } + + UNREACHABLE(); + return nullptr; +} + +// D3DInterfaceBlock Implementation +D3DInterfaceBlock::D3DInterfaceBlock() +{ + mShaderRegisterIndexes.fill(GL_INVALID_INDEX); +} + +D3DInterfaceBlock::D3DInterfaceBlock(const D3DInterfaceBlock &other) = default; + +D3DUniformBlock::D3DUniformBlock() +{ + mUseStructuredBuffers.fill(false); + mByteWidths.fill(0u); + mStructureByteStrides.fill(0u); +} + +D3DUniformBlock::D3DUniformBlock(const D3DUniformBlock &other) = default; + +// D3DVarying Implementation + +D3DVarying::D3DVarying() : semanticIndex(0), componentCount(0), outputSlot(0) {} + +D3DVarying::D3DVarying(const std::string &semanticNameIn, + unsigned int semanticIndexIn, + unsigned int componentCountIn, + unsigned int outputSlotIn) + : semanticName(semanticNameIn), + semanticIndex(semanticIndexIn), + componentCount(componentCountIn), + outputSlot(outputSlotIn) +{} + +// ProgramD3DMetadata Implementation + +ProgramD3DMetadata::ProgramD3DMetadata(RendererD3D *renderer, + const gl::ShaderMap &attachedShaders, + EGLenum clientType) + : mRendererMajorShaderModel(renderer->getMajorShaderModel()), + mShaderModelSuffix(renderer->getShaderModelSuffix()), + mUsesInstancedPointSpriteEmulation( + renderer->getFeatures().useInstancedPointSpriteEmulation.enabled), + mUsesViewScale(renderer->presentPathFastEnabled()), + mCanSelectViewInVertexShader(renderer->canSelectViewInVertexShader()), + mAttachedShaders(attachedShaders), + mClientType(clientType) +{} + +ProgramD3DMetadata::~ProgramD3DMetadata() = default; + +int ProgramD3DMetadata::getRendererMajorShaderModel() const +{ + return mRendererMajorShaderModel; +} + +bool ProgramD3DMetadata::usesBroadcast(const gl::State &data) const +{ + const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Fragment]; + return (shader && shader->usesFragColor() && shader->usesMultipleRenderTargets() && + data.getClientMajorVersion() < 3); +} + +bool ProgramD3DMetadata::usesSecondaryColor() const +{ + const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Fragment]; + return (shader && shader->usesSecondaryColor()); +} + +bool ProgramD3DMetadata::usesFragDepth() const +{ + const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Fragment]; + return (shader && shader->usesFragDepth()); +} + +bool ProgramD3DMetadata::usesPointCoord() const +{ + const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Fragment]; + return (shader && shader->usesPointCoord()); +} + +bool ProgramD3DMetadata::usesFragCoord() const +{ + const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Fragment]; + return (shader && shader->usesFragCoord()); +} + +bool ProgramD3DMetadata::usesPointSize() const +{ + const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Vertex]; + return (shader && shader->usesPointSize()); +} + +bool ProgramD3DMetadata::usesInsertedPointCoordValue() const +{ + return (!usesPointSize() || !mUsesInstancedPointSpriteEmulation) && usesPointCoord() && + mRendererMajorShaderModel >= 4; +} + +bool ProgramD3DMetadata::usesViewScale() const +{ + return mUsesViewScale; +} + +bool ProgramD3DMetadata::hasANGLEMultiviewEnabled() const +{ + const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Vertex]; + return (shader && shader->hasANGLEMultiviewEnabled()); +} + +bool ProgramD3DMetadata::usesVertexID() const +{ + const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Vertex]; + return (shader && shader->usesVertexID()); +} + +bool ProgramD3DMetadata::usesViewID() const +{ + const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Fragment]; + return (shader && shader->usesViewID()); +} + +bool ProgramD3DMetadata::canSelectViewInVertexShader() const +{ + return mCanSelectViewInVertexShader; +} + +bool ProgramD3DMetadata::addsPointCoordToVertexShader() const +{ + // PointSprite emulation requiress that gl_PointCoord is present in the vertex shader + // VS_OUTPUT structure to ensure compatibility with the generated PS_INPUT of the pixel shader. + // Even with a geometry shader, the app can render triangles or lines and reference + // gl_PointCoord in the fragment shader, requiring us to provide a placeholder value. For + // simplicity, we always add this to the vertex shader when the fragment shader + // references gl_PointCoord, even if we could skip it in the geometry shader. + return (mUsesInstancedPointSpriteEmulation && usesPointCoord()) || + usesInsertedPointCoordValue(); +} + +bool ProgramD3DMetadata::usesTransformFeedbackGLPosition() const +{ + // gl_Position only needs to be outputted from the vertex shader if transform feedback is + // active. This isn't supported on D3D11 Feature Level 9_3, so we don't output gl_Position from + // the vertex shader in this case. This saves us 1 output vector. + return !(mRendererMajorShaderModel >= 4 && mShaderModelSuffix != ""); +} + +bool ProgramD3DMetadata::usesSystemValuePointSize() const +{ + return !mUsesInstancedPointSpriteEmulation && usesPointSize(); +} + +bool ProgramD3DMetadata::usesMultipleFragmentOuts() const +{ + const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Fragment]; + return (shader && shader->usesMultipleRenderTargets()); +} + +bool ProgramD3DMetadata::usesCustomOutVars() const +{ + + const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Vertex]; + int version = shader ? shader->getState().getShaderVersion() : -1; + + switch (mClientType) + { + case EGL_OPENGL_API: + return version >= 130; + default: + return version >= 300; + } +} + +const ShaderD3D *ProgramD3DMetadata::getFragmentShader() const +{ + return mAttachedShaders[gl::ShaderType::Fragment]; +} + +// ProgramD3D::GetExecutableTask class +class ProgramD3D::GetExecutableTask : public Closure, public d3d::Context +{ + public: + GetExecutableTask(const gl::Context *context, ProgramD3D *program) + : mProgram(program), mContext(context) + {} + + virtual angle::Result run() = 0; + + void operator()() override { mResult = run(); } + + angle::Result getResult() const { return mResult; } + const gl::InfoLog &getInfoLog() const { return mInfoLog; } + ShaderExecutableD3D *getExecutable() { return mExecutable; } + + void handleResult(HRESULT hr, + const char *message, + const char *file, + const char *function, + unsigned int line) override + { + mStoredHR = hr; + mStoredMessage = message; + mStoredFile = file; + mStoredFunction = function; + mStoredLine = line; + } + + void popError(d3d::Context *context) + { + ASSERT(mStoredFile); + ASSERT(mStoredFunction); + context->handleResult(mStoredHR, mStoredMessage.c_str(), mStoredFile, mStoredFunction, + mStoredLine); + } + + protected: + ProgramD3D *mProgram = nullptr; + angle::Result mResult = angle::Result::Continue; + gl::InfoLog mInfoLog; + ShaderExecutableD3D *mExecutable = nullptr; + HRESULT mStoredHR = S_OK; + std::string mStoredMessage; + const char *mStoredFile = nullptr; + const char *mStoredFunction = nullptr; + unsigned int mStoredLine = 0; + const gl::Context *mContext = nullptr; +}; + +// ProgramD3D Implementation + +ProgramD3D::VertexExecutable::VertexExecutable(const gl::InputLayout &inputLayout, + const Signature &signature, + ShaderExecutableD3D *shaderExecutable) + : mInputs(inputLayout), mSignature(signature), mShaderExecutable(shaderExecutable) +{} + +ProgramD3D::VertexExecutable::~VertexExecutable() +{ + SafeDelete(mShaderExecutable); +} + +// static +ProgramD3D::VertexExecutable::HLSLAttribType ProgramD3D::VertexExecutable::GetAttribType( + GLenum type) +{ + switch (type) + { + case GL_INT: + return HLSLAttribType::SIGNED_INT; + case GL_UNSIGNED_INT: + return HLSLAttribType::UNSIGNED_INT; + case GL_SIGNED_NORMALIZED: + case GL_UNSIGNED_NORMALIZED: + case GL_FLOAT: + return HLSLAttribType::FLOAT; + default: + UNREACHABLE(); + return HLSLAttribType::FLOAT; + } +} + +// static +void ProgramD3D::VertexExecutable::getSignature(RendererD3D *renderer, + const gl::InputLayout &inputLayout, + Signature *signatureOut) +{ + signatureOut->assign(inputLayout.size(), HLSLAttribType::FLOAT); + + for (size_t index = 0; index < inputLayout.size(); ++index) + { + angle::FormatID vertexFormatID = inputLayout[index]; + if (vertexFormatID == angle::FormatID::NONE) + continue; + + VertexConversionType conversionType = renderer->getVertexConversionType(vertexFormatID); + if ((conversionType & VERTEX_CONVERT_GPU) == 0) + continue; + + GLenum componentType = renderer->getVertexComponentType(vertexFormatID); + (*signatureOut)[index] = GetAttribType(componentType); + } +} + +bool ProgramD3D::VertexExecutable::matchesSignature(const Signature &signature) const +{ + size_t limit = std::max(mSignature.size(), signature.size()); + for (size_t index = 0; index < limit; ++index) + { + // treat undefined indexes as FLOAT + auto a = index < signature.size() ? signature[index] : HLSLAttribType::FLOAT; + auto b = index < mSignature.size() ? mSignature[index] : HLSLAttribType::FLOAT; + if (a != b) + return false; + } + + return true; +} + +ProgramD3D::PixelExecutable::PixelExecutable(const std::vector &outputSignature, + ShaderExecutableD3D *shaderExecutable) + : mOutputSignature(outputSignature), mShaderExecutable(shaderExecutable) +{} + +ProgramD3D::PixelExecutable::~PixelExecutable() +{ + SafeDelete(mShaderExecutable); +} + +ProgramD3D::ComputeExecutable::ComputeExecutable( + const gl::ImageUnitTextureTypeMap &signature, + std::unique_ptr shaderExecutable) + : mSignature(signature), mShaderExecutable(std::move(shaderExecutable)) +{} + +ProgramD3D::ComputeExecutable::~ComputeExecutable() {} + +ProgramD3D::Sampler::Sampler() + : active(false), logicalTextureUnit(0), textureType(gl::TextureType::_2D) +{} + +ProgramD3D::Image::Image() : active(false), logicalImageUnit(0) {} + +unsigned int ProgramD3D::mCurrentSerial = 1; + +ProgramD3D::ProgramD3D(const gl::ProgramState &state, RendererD3D *renderer) + : ProgramImpl(state), + mRenderer(renderer), + mDynamicHLSL(nullptr), + mUsesPointSize(false), + mUsesFlatInterpolation(false), + mUsedShaderSamplerRanges({}), + mDirtySamplerMapping(true), + mUsedImageRange({}), + mUsedReadonlyImageRange({}), + mUsedAtomicCounterRange({}), + mSerial(issueSerial()) +{ + mDynamicHLSL = new DynamicHLSL(renderer); +} + +ProgramD3D::~ProgramD3D() +{ + reset(); + SafeDelete(mDynamicHLSL); +} + +bool ProgramD3D::usesPointSpriteEmulation() const +{ + return mUsesPointSize && mRenderer->getMajorShaderModel() >= 4; +} + +bool ProgramD3D::usesGeometryShaderForPointSpriteEmulation() const +{ + return usesPointSpriteEmulation() && !usesInstancedPointSpriteEmulation(); +} + +bool ProgramD3D::usesGetDimensionsIgnoresBaseLevel() const +{ + return mRenderer->getFeatures().getDimensionsIgnoresBaseLevel.enabled; +} + +bool ProgramD3D::usesGeometryShader(const gl::State &state, const gl::PrimitiveMode drawMode) const +{ + if (mHasANGLEMultiviewEnabled && !mRenderer->canSelectViewInVertexShader()) + { + return true; + } + if (drawMode != gl::PrimitiveMode::Points) + { + if (!mUsesFlatInterpolation) + { + return false; + } + return state.getProvokingVertex() == gl::ProvokingVertexConvention::LastVertexConvention; + } + return usesGeometryShaderForPointSpriteEmulation(); +} + +bool ProgramD3D::usesInstancedPointSpriteEmulation() const +{ + return mRenderer->getFeatures().useInstancedPointSpriteEmulation.enabled; +} + +GLint ProgramD3D::getSamplerMapping(gl::ShaderType type, + unsigned int samplerIndex, + const gl::Caps &caps) const +{ + GLint logicalTextureUnit = -1; + + ASSERT(type != gl::ShaderType::InvalidEnum); + + ASSERT(samplerIndex < static_cast(caps.maxShaderTextureImageUnits[type])); + + const auto &samplers = mShaderSamplers[type]; + if (samplerIndex < samplers.size() && samplers[samplerIndex].active) + { + logicalTextureUnit = samplers[samplerIndex].logicalTextureUnit; + } + + if (logicalTextureUnit >= 0 && logicalTextureUnit < caps.maxCombinedTextureImageUnits) + { + return logicalTextureUnit; + } + + return -1; +} + +// Returns the texture type for a given Direct3D 9 sampler type and +// index (0-15 for the pixel shader and 0-3 for the vertex shader). +gl::TextureType ProgramD3D::getSamplerTextureType(gl::ShaderType type, + unsigned int samplerIndex) const +{ + ASSERT(type != gl::ShaderType::InvalidEnum); + + const auto &samplers = mShaderSamplers[type]; + ASSERT(samplerIndex < samplers.size()); + ASSERT(samplers[samplerIndex].active); + + return samplers[samplerIndex].textureType; +} + +gl::RangeUI ProgramD3D::getUsedSamplerRange(gl::ShaderType type) const +{ + ASSERT(type != gl::ShaderType::InvalidEnum); + return mUsedShaderSamplerRanges[type]; +} + +ProgramD3D::SamplerMapping ProgramD3D::updateSamplerMapping() +{ + if (!mDirtySamplerMapping) + { + return SamplerMapping::WasClean; + } + + mDirtySamplerMapping = false; + + // Retrieve sampler uniform values + for (const D3DUniform *d3dUniform : mD3DUniforms) + { + if (!d3dUniform->isSampler()) + continue; + + int count = d3dUniform->getArraySizeProduct(); + + for (gl::ShaderType shaderType : gl::AllShaderTypes()) + { + if (!d3dUniform->isReferencedByShader(shaderType)) + { + continue; + } + + unsigned int firstIndex = d3dUniform->mShaderRegisterIndexes[shaderType]; + + std::vector &samplers = mShaderSamplers[shaderType]; + for (int i = 0; i < count; i++) + { + unsigned int samplerIndex = firstIndex + i; + + if (samplerIndex < samplers.size()) + { + ASSERT(samplers[samplerIndex].active); + samplers[samplerIndex].logicalTextureUnit = d3dUniform->mSamplerData[i]; + } + } + } + } + + return SamplerMapping::WasDirty; +} + +GLint ProgramD3D::getImageMapping(gl::ShaderType type, + unsigned int imageIndex, + bool readonly, + const gl::Caps &caps) const +{ + GLint logicalImageUnit = -1; + ASSERT(imageIndex < static_cast(caps.maxImageUnits)); + if (readonly && imageIndex < mReadonlyImages[type].size() && + mReadonlyImages[type][imageIndex].active) + { + logicalImageUnit = mReadonlyImages[type][imageIndex].logicalImageUnit; + } + else if (imageIndex < mImages[type].size() && mImages[type][imageIndex].active) + { + logicalImageUnit = mImages[type][imageIndex].logicalImageUnit; + } + + if (logicalImageUnit >= 0 && logicalImageUnit < caps.maxImageUnits) + { + return logicalImageUnit; + } + + return -1; +} + +gl::RangeUI ProgramD3D::getUsedImageRange(gl::ShaderType type, bool readonly) const +{ + return readonly ? mUsedReadonlyImageRange[type] : mUsedImageRange[type]; +} + +class ProgramD3D::LoadBinaryTask : public ProgramD3D::GetExecutableTask +{ + public: + LoadBinaryTask(const gl::Context *context, + ProgramD3D *program, + gl::BinaryInputStream *stream, + gl::InfoLog &infoLog) + : ProgramD3D::GetExecutableTask(context, program) + { + ASSERT(mProgram); + ASSERT(stream); + + // Copy the remaining data from the stream locally so that the client can't modify it when + // loading off thread. + size_t dataSize = stream->remainingSize(); + mDataCopySucceeded = mStreamData.resize(dataSize); + if (mDataCopySucceeded) + { + memcpy(mStreamData.data(), stream->data() + stream->offset(), dataSize); + } + } + + angle::Result run() override + { + ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::LoadBinaryTask::run"); + if (!mDataCopySucceeded) + { + mInfoLog << "Failed to copy program binary data to local buffer."; + return angle::Result::Incomplete; + } + + gl::BinaryInputStream stream(mStreamData.data(), mStreamData.size()); + return mProgram->loadBinaryShaderExecutables(this, &stream, mInfoLog); + } + + private: + bool mDataCopySucceeded; + angle::MemoryBuffer mStreamData; +}; + +class ProgramD3D::LoadBinaryLinkEvent final : public LinkEvent +{ + public: + LoadBinaryLinkEvent(const gl::Context *context, + std::shared_ptr workerPool, + ProgramD3D *program, + gl::BinaryInputStream *stream, + gl::InfoLog &infoLog) + : mTask(std::make_shared(context, program, stream, infoLog)), + mWaitableEvent(angle::WorkerThreadPool::PostWorkerTask(workerPool, mTask)) + {} + + angle::Result wait(const gl::Context *context) override + { + mWaitableEvent->wait(); + + // Continue and Incomplete are not errors. For Stop, pass the error to the ContextD3D. + if (mTask->getResult() != angle::Result::Stop) + { + return angle::Result::Continue; + } + + ContextD3D *contextD3D = GetImplAs(context); + mTask->popError(contextD3D); + return angle::Result::Stop; + } + + bool isLinking() override { return !mWaitableEvent->isReady(); } + + private: + std::shared_ptr mTask; + std::shared_ptr mWaitableEvent; +}; + +std::unique_ptr ProgramD3D::load(const gl::Context *context, + gl::BinaryInputStream *stream, + gl::InfoLog &infoLog) +{ + + // TODO(jmadill): Use Renderer from contextImpl. + + reset(); + + DeviceIdentifier binaryDeviceIdentifier = {}; + stream->readBytes(reinterpret_cast(&binaryDeviceIdentifier), + sizeof(DeviceIdentifier)); + + DeviceIdentifier identifier = mRenderer->getAdapterIdentifier(); + if (memcmp(&identifier, &binaryDeviceIdentifier, sizeof(DeviceIdentifier)) != 0) + { + infoLog << "Invalid program binary, device configuration has changed."; + return nullptr; + } + + int compileFlags = stream->readInt(); + if (compileFlags != ANGLE_COMPILE_OPTIMIZATION_LEVEL) + { + infoLog << "Mismatched compilation flags."; + return nullptr; + } + + for (int &index : mAttribLocationToD3DSemantic) + { + stream->readInt(&index); + } + + for (gl::ShaderType shaderType : gl::AllShaderTypes()) + { + size_t samplerCount = stream->readInt(); + for (size_t sampleIndex = 0; sampleIndex < samplerCount; ++sampleIndex) + { + Sampler sampler; + stream->readBool(&sampler.active); + stream->readInt(&sampler.logicalTextureUnit); + stream->readEnum(&sampler.textureType); + mShaderSamplers[shaderType].push_back(sampler); + } + + unsigned int samplerRangeLow, samplerRangeHigh; + stream->readInt(&samplerRangeLow); + stream->readInt(&samplerRangeHigh); + mUsedShaderSamplerRanges[shaderType] = gl::RangeUI(samplerRangeLow, samplerRangeHigh); + } + + for (gl::ShaderType shaderType : {gl::ShaderType::Compute, gl::ShaderType::Fragment}) + { + size_t imageCount = stream->readInt(); + for (size_t imageIndex = 0; imageIndex < imageCount; ++imageIndex) + { + Image image; + stream->readBool(&image.active); + stream->readInt(&image.logicalImageUnit); + mImages[shaderType].push_back(image); + } + + size_t readonlyImageCount = stream->readInt(); + for (size_t imageIndex = 0; imageIndex < readonlyImageCount; ++imageIndex) + { + Image image; + stream->readBool(&image.active); + stream->readInt(&image.logicalImageUnit); + mReadonlyImages[shaderType].push_back(image); + } + + unsigned int imageRangeLow, imageRangeHigh, readonlyImageRangeLow, readonlyImageRangeHigh; + stream->readInt(&imageRangeLow); + stream->readInt(&imageRangeHigh); + stream->readInt(&readonlyImageRangeLow); + stream->readInt(&readonlyImageRangeHigh); + mUsedImageRange[shaderType] = gl::RangeUI(imageRangeLow, imageRangeHigh); + mUsedReadonlyImageRange[shaderType] = + gl::RangeUI(readonlyImageRangeLow, readonlyImageRangeHigh); + + unsigned int atomicCounterRangeLow, atomicCounterRangeHigh; + stream->readInt(&atomicCounterRangeLow); + stream->readInt(&atomicCounterRangeHigh); + mUsedAtomicCounterRange[shaderType] = + gl::RangeUI(atomicCounterRangeLow, atomicCounterRangeHigh); + } + + size_t shaderStorageBlockCount = stream->readInt(); + if (stream->error()) + { + infoLog << "Invalid program binary."; + return nullptr; + } + + ASSERT(mD3DShaderStorageBlocks.empty()); + for (size_t blockIndex = 0; blockIndex < shaderStorageBlockCount; ++blockIndex) + { + D3DInterfaceBlock shaderStorageBlock; + for (gl::ShaderType shaderType : gl::AllShaderTypes()) + { + stream->readInt(&shaderStorageBlock.mShaderRegisterIndexes[shaderType]); + } + mD3DShaderStorageBlocks.push_back(shaderStorageBlock); + } + + for (gl::ShaderType shaderType : {gl::ShaderType::Compute, gl::ShaderType::Fragment}) + { + size_t image2DUniformCount = stream->readInt(); + if (stream->error()) + { + infoLog << "Invalid program binary."; + return nullptr; + } + + ASSERT(mImage2DUniforms[shaderType].empty()); + for (size_t image2DUniformIndex = 0; image2DUniformIndex < image2DUniformCount; + ++image2DUniformIndex) + { + sh::ShaderVariable image2Duniform; + gl::LoadShaderVar(stream, &image2Duniform); + mImage2DUniforms[shaderType].push_back(image2Duniform); + } + } + + for (unsigned int ii = 0; ii < gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS; ++ii) + { + unsigned int index = stream->readInt(); + mComputeAtomicCounterBufferRegisterIndices[ii] = index; + } + + size_t uniformCount = stream->readInt(); + if (stream->error()) + { + infoLog << "Invalid program binary."; + return nullptr; + } + + const auto &linkedUniforms = mState.getUniforms(); + ASSERT(mD3DUniforms.empty()); + for (size_t uniformIndex = 0; uniformIndex < uniformCount; uniformIndex++) + { + const gl::LinkedUniform &linkedUniform = linkedUniforms[uniformIndex]; + + D3DUniform *d3dUniform = + new D3DUniform(linkedUniform.type, HLSLRegisterType::None, linkedUniform.name, + linkedUniform.arraySizes, linkedUniform.isInDefaultBlock()); + stream->readEnum(&d3dUniform->regType); + for (gl::ShaderType shaderType : gl::AllShaderTypes()) + { + stream->readInt(&d3dUniform->mShaderRegisterIndexes[shaderType]); + } + stream->readInt(&d3dUniform->registerCount); + stream->readInt(&d3dUniform->registerElement); + + mD3DUniforms.push_back(d3dUniform); + } + + size_t blockCount = stream->readInt(); + if (stream->error()) + { + infoLog << "Invalid program binary."; + return nullptr; + } + + ASSERT(mD3DUniformBlocks.empty()); + for (size_t blockIndex = 0; blockIndex < blockCount; ++blockIndex) + { + D3DUniformBlock uniformBlock; + for (gl::ShaderType shaderType : gl::AllShaderTypes()) + { + stream->readInt(&uniformBlock.mShaderRegisterIndexes[shaderType]); + stream->readBool(&uniformBlock.mUseStructuredBuffers[shaderType]); + stream->readInt(&uniformBlock.mByteWidths[shaderType]); + stream->readInt(&uniformBlock.mStructureByteStrides[shaderType]); + } + mD3DUniformBlocks.push_back(uniformBlock); + } + + size_t streamOutVaryingCount = stream->readInt(); + mStreamOutVaryings.resize(streamOutVaryingCount); + for (size_t varyingIndex = 0; varyingIndex < streamOutVaryingCount; ++varyingIndex) + { + D3DVarying *varying = &mStreamOutVaryings[varyingIndex]; + + stream->readString(&varying->semanticName); + stream->readInt(&varying->semanticIndex); + stream->readInt(&varying->componentCount); + stream->readInt(&varying->outputSlot); + } + + for (gl::ShaderType shaderType : gl::AllShaderTypes()) + { + stream->readString(&mShaderHLSL[shaderType]); + stream->readBytes(reinterpret_cast(&mShaderWorkarounds[shaderType]), + sizeof(CompilerWorkaroundsD3D)); + } + + stream->readBool(&mUsesFragDepth); + stream->readBool(&mHasANGLEMultiviewEnabled); + stream->readBool(&mUsesVertexID); + stream->readBool(&mUsesViewID); + stream->readBool(&mUsesPointSize); + stream->readBool(&mUsesFlatInterpolation); + + const size_t pixelShaderKeySize = stream->readInt(); + mPixelShaderKey.resize(pixelShaderKeySize); + for (size_t pixelShaderKeyIndex = 0; pixelShaderKeyIndex < pixelShaderKeySize; + pixelShaderKeyIndex++) + { + stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].type); + stream->readString(&mPixelShaderKey[pixelShaderKeyIndex].name); + stream->readString(&mPixelShaderKey[pixelShaderKeyIndex].source); + stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].outputLocation); + stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].outputIndex); + } + + stream->readString(&mGeometryShaderPreamble); + + return std::make_unique(context, context->getWorkerThreadPool(), this, + stream, infoLog); +} + +angle::Result ProgramD3D::loadBinaryShaderExecutables(d3d::Context *contextD3D, + gl::BinaryInputStream *stream, + gl::InfoLog &infoLog) +{ + const unsigned char *binary = reinterpret_cast(stream->data()); + + bool separateAttribs = (mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS); + + size_t vertexShaderCount = stream->readInt(); + for (size_t vertexShaderIndex = 0; vertexShaderIndex < vertexShaderCount; vertexShaderIndex++) + { + size_t inputLayoutSize = stream->readInt(); + gl::InputLayout inputLayout(inputLayoutSize, angle::FormatID::NONE); + + for (size_t inputIndex = 0; inputIndex < inputLayoutSize; inputIndex++) + { + inputLayout[inputIndex] = stream->readEnum(); + } + + size_t vertexShaderSize = stream->readInt(); + const unsigned char *vertexShaderFunction = binary + stream->offset(); + + ShaderExecutableD3D *shaderExecutable = nullptr; + + ANGLE_TRY(mRenderer->loadExecutable(contextD3D, vertexShaderFunction, vertexShaderSize, + gl::ShaderType::Vertex, mStreamOutVaryings, + separateAttribs, &shaderExecutable)); + + if (!shaderExecutable) + { + infoLog << "Could not create vertex shader."; + return angle::Result::Incomplete; + } + + // generated converted input layout + VertexExecutable::Signature signature; + VertexExecutable::getSignature(mRenderer, inputLayout, &signature); + + // add new binary + mVertexExecutables.push_back(std::unique_ptr( + new VertexExecutable(inputLayout, signature, shaderExecutable))); + + stream->skip(vertexShaderSize); + } + + size_t pixelShaderCount = stream->readInt(); + for (size_t pixelShaderIndex = 0; pixelShaderIndex < pixelShaderCount; pixelShaderIndex++) + { + size_t outputCount = stream->readInt(); + std::vector outputs(outputCount); + for (size_t outputIndex = 0; outputIndex < outputCount; outputIndex++) + { + stream->readInt(&outputs[outputIndex]); + } + + size_t pixelShaderSize = stream->readInt(); + const unsigned char *pixelShaderFunction = binary + stream->offset(); + ShaderExecutableD3D *shaderExecutable = nullptr; + + ANGLE_TRY(mRenderer->loadExecutable(contextD3D, pixelShaderFunction, pixelShaderSize, + gl::ShaderType::Fragment, mStreamOutVaryings, + separateAttribs, &shaderExecutable)); + + if (!shaderExecutable) + { + infoLog << "Could not create pixel shader."; + return angle::Result::Incomplete; + } + + // add new binary + mPixelExecutables.push_back( + std::unique_ptr(new PixelExecutable(outputs, shaderExecutable))); + + stream->skip(pixelShaderSize); + } + + for (std::unique_ptr &geometryExe : mGeometryExecutables) + { + size_t geometryShaderSize = stream->readInt(); + if (geometryShaderSize == 0) + { + continue; + } + + const unsigned char *geometryShaderFunction = binary + stream->offset(); + + ShaderExecutableD3D *geometryExecutable = nullptr; + ANGLE_TRY(mRenderer->loadExecutable(contextD3D, geometryShaderFunction, geometryShaderSize, + gl::ShaderType::Geometry, mStreamOutVaryings, + separateAttribs, &geometryExecutable)); + + if (!geometryExecutable) + { + infoLog << "Could not create geometry shader."; + return angle::Result::Incomplete; + } + + geometryExe.reset(geometryExecutable); + + stream->skip(geometryShaderSize); + } + + size_t computeShaderCount = stream->readInt(); + for (size_t computeShaderIndex = 0; computeShaderIndex < computeShaderCount; + computeShaderIndex++) + { + size_t signatureCount = stream->readInt(); + gl::ImageUnitTextureTypeMap signatures; + for (size_t signatureIndex = 0; signatureIndex < signatureCount; signatureIndex++) + { + unsigned int imageUint; + gl::TextureType textureType; + stream->readInt(&imageUint); + stream->readEnum(&textureType); + signatures.insert(std::pair(imageUint, textureType)); + } + + size_t computeShaderSize = stream->readInt(); + const unsigned char *computeShaderFunction = binary + stream->offset(); + + ShaderExecutableD3D *computeExecutable = nullptr; + ANGLE_TRY(mRenderer->loadExecutable(contextD3D, computeShaderFunction, computeShaderSize, + gl::ShaderType::Compute, std::vector(), + false, &computeExecutable)); + + if (!computeExecutable) + { + infoLog << "Could not create compute shader."; + return angle::Result::Incomplete; + } + + // add new binary + mComputeExecutables.push_back(std::unique_ptr(new ComputeExecutable( + signatures, std::unique_ptr(computeExecutable)))); + + stream->skip(computeShaderSize); + } + + size_t bindLayoutCount = stream->readInt(); + for (size_t bindLayoutIndex = 0; bindLayoutIndex < bindLayoutCount; bindLayoutIndex++) + { + mImage2DBindLayoutCache[gl::ShaderType::Compute].insert( + std::pair(stream->readInt(), + gl::TextureType::_2D)); + } + + initializeUniformStorage(mState.getExecutable().getLinkedShaderStages()); + + dirtyAllUniforms(); + + return angle::Result::Continue; +} + +void ProgramD3D::save(const gl::Context *context, gl::BinaryOutputStream *stream) +{ + // Output the DeviceIdentifier before we output any shader code + // When we load the binary again later, we can validate the device identifier before trying to + // compile any HLSL + DeviceIdentifier binaryIdentifier = mRenderer->getAdapterIdentifier(); + stream->writeBytes(reinterpret_cast(&binaryIdentifier), + sizeof(DeviceIdentifier)); + + stream->writeInt(ANGLE_COMPILE_OPTIMIZATION_LEVEL); + + for (int d3dSemantic : mAttribLocationToD3DSemantic) + { + stream->writeInt(d3dSemantic); + } + + for (gl::ShaderType shaderType : gl::AllShaderTypes()) + { + stream->writeInt(mShaderSamplers[shaderType].size()); + for (unsigned int i = 0; i < mShaderSamplers[shaderType].size(); ++i) + { + stream->writeBool(mShaderSamplers[shaderType][i].active); + stream->writeInt(mShaderSamplers[shaderType][i].logicalTextureUnit); + stream->writeEnum(mShaderSamplers[shaderType][i].textureType); + } + + stream->writeInt(mUsedShaderSamplerRanges[shaderType].low()); + stream->writeInt(mUsedShaderSamplerRanges[shaderType].high()); + } + + for (gl::ShaderType shaderType : {gl::ShaderType::Compute, gl::ShaderType::Fragment}) + { + stream->writeInt(mImages[shaderType].size()); + for (size_t imageIndex = 0; imageIndex < mImages[shaderType].size(); ++imageIndex) + { + stream->writeBool(mImages[shaderType][imageIndex].active); + stream->writeInt(mImages[shaderType][imageIndex].logicalImageUnit); + } + + stream->writeInt(mReadonlyImages[shaderType].size()); + for (size_t imageIndex = 0; imageIndex < mReadonlyImages[shaderType].size(); ++imageIndex) + { + stream->writeBool(mReadonlyImages[shaderType][imageIndex].active); + stream->writeInt(mReadonlyImages[shaderType][imageIndex].logicalImageUnit); + } + + stream->writeInt(mUsedImageRange[shaderType].low()); + stream->writeInt(mUsedImageRange[shaderType].high()); + stream->writeInt(mUsedReadonlyImageRange[shaderType].low()); + stream->writeInt(mUsedReadonlyImageRange[shaderType].high()); + stream->writeInt(mUsedAtomicCounterRange[shaderType].low()); + stream->writeInt(mUsedAtomicCounterRange[shaderType].high()); + } + + stream->writeInt(mD3DShaderStorageBlocks.size()); + for (const D3DInterfaceBlock &shaderStorageBlock : mD3DShaderStorageBlocks) + { + for (gl::ShaderType shaderType : gl::AllShaderTypes()) + { + stream->writeIntOrNegOne(shaderStorageBlock.mShaderRegisterIndexes[shaderType]); + } + } + + for (gl::ShaderType shaderType : {gl::ShaderType::Compute, gl::ShaderType::Fragment}) + { + stream->writeInt(mImage2DUniforms[shaderType].size()); + for (const sh::ShaderVariable &image2DUniform : mImage2DUniforms[shaderType]) + { + gl::WriteShaderVar(stream, image2DUniform); + } + } + + for (unsigned int ii = 0; ii < gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS; ++ii) + { + stream->writeInt(mComputeAtomicCounterBufferRegisterIndices[ii]); + } + + stream->writeInt(mD3DUniforms.size()); + for (const D3DUniform *uniform : mD3DUniforms) + { + // Type, name and arraySize are redundant, so aren't stored in the binary. + stream->writeEnum(uniform->regType); + for (gl::ShaderType shaderType : gl::AllShaderTypes()) + { + stream->writeIntOrNegOne(uniform->mShaderRegisterIndexes[shaderType]); + } + stream->writeInt(uniform->registerCount); + stream->writeInt(uniform->registerElement); + } + + stream->writeInt(mD3DUniformBlocks.size()); + for (const D3DUniformBlock &uniformBlock : mD3DUniformBlocks) + { + for (gl::ShaderType shaderType : gl::AllShaderTypes()) + { + stream->writeIntOrNegOne(uniformBlock.mShaderRegisterIndexes[shaderType]); + stream->writeBool(uniformBlock.mUseStructuredBuffers[shaderType]); + stream->writeInt(uniformBlock.mByteWidths[shaderType]); + stream->writeInt(uniformBlock.mStructureByteStrides[shaderType]); + } + } + + stream->writeInt(mStreamOutVaryings.size()); + for (const D3DVarying &varying : mStreamOutVaryings) + { + stream->writeString(varying.semanticName); + stream->writeInt(varying.semanticIndex); + stream->writeInt(varying.componentCount); + stream->writeInt(varying.outputSlot); + } + + for (gl::ShaderType shaderType : gl::AllShaderTypes()) + { + stream->writeString(mShaderHLSL[shaderType]); + stream->writeBytes(reinterpret_cast(&mShaderWorkarounds[shaderType]), + sizeof(CompilerWorkaroundsD3D)); + } + + stream->writeBool(mUsesFragDepth); + stream->writeBool(mHasANGLEMultiviewEnabled); + stream->writeBool(mUsesVertexID); + stream->writeBool(mUsesViewID); + stream->writeBool(mUsesPointSize); + stream->writeBool(mUsesFlatInterpolation); + + const std::vector &pixelShaderKey = mPixelShaderKey; + stream->writeInt(pixelShaderKey.size()); + for (size_t pixelShaderKeyIndex = 0; pixelShaderKeyIndex < pixelShaderKey.size(); + pixelShaderKeyIndex++) + { + const PixelShaderOutputVariable &variable = pixelShaderKey[pixelShaderKeyIndex]; + stream->writeInt(variable.type); + stream->writeString(variable.name); + stream->writeString(variable.source); + stream->writeInt(variable.outputLocation); + stream->writeInt(variable.outputIndex); + } + + stream->writeString(mGeometryShaderPreamble); + + stream->writeInt(mVertexExecutables.size()); + for (size_t vertexExecutableIndex = 0; vertexExecutableIndex < mVertexExecutables.size(); + vertexExecutableIndex++) + { + VertexExecutable *vertexExecutable = mVertexExecutables[vertexExecutableIndex].get(); + + const gl::InputLayout &inputLayout = vertexExecutable->inputs(); + stream->writeInt(inputLayout.size()); + + for (size_t inputIndex = 0; inputIndex < inputLayout.size(); inputIndex++) + { + stream->writeEnum(inputLayout[inputIndex]); + } + + size_t vertexShaderSize = vertexExecutable->shaderExecutable()->getLength(); + stream->writeInt(vertexShaderSize); + + const uint8_t *vertexBlob = vertexExecutable->shaderExecutable()->getFunction(); + stream->writeBytes(vertexBlob, vertexShaderSize); + } + + stream->writeInt(mPixelExecutables.size()); + for (size_t pixelExecutableIndex = 0; pixelExecutableIndex < mPixelExecutables.size(); + pixelExecutableIndex++) + { + PixelExecutable *pixelExecutable = mPixelExecutables[pixelExecutableIndex].get(); + + const std::vector &outputs = pixelExecutable->outputSignature(); + stream->writeInt(outputs.size()); + for (size_t outputIndex = 0; outputIndex < outputs.size(); outputIndex++) + { + stream->writeInt(outputs[outputIndex]); + } + + size_t pixelShaderSize = pixelExecutable->shaderExecutable()->getLength(); + stream->writeInt(pixelShaderSize); + + const uint8_t *pixelBlob = pixelExecutable->shaderExecutable()->getFunction(); + stream->writeBytes(pixelBlob, pixelShaderSize); + } + + for (auto const &geometryExecutable : mGeometryExecutables) + { + if (!geometryExecutable) + { + stream->writeInt(0); + continue; + } + + size_t geometryShaderSize = geometryExecutable->getLength(); + stream->writeInt(geometryShaderSize); + stream->writeBytes(geometryExecutable->getFunction(), geometryShaderSize); + } + + stream->writeInt(mComputeExecutables.size()); + for (size_t computeExecutableIndex = 0; computeExecutableIndex < mComputeExecutables.size(); + computeExecutableIndex++) + { + ComputeExecutable *computeExecutable = mComputeExecutables[computeExecutableIndex].get(); + + const gl::ImageUnitTextureTypeMap signatures = computeExecutable->signature(); + stream->writeInt(signatures.size()); + for (const auto &signature : signatures) + { + stream->writeInt(signature.first); + stream->writeEnum(signature.second); + } + + size_t computeShaderSize = computeExecutable->shaderExecutable()->getLength(); + stream->writeInt(computeShaderSize); + + const uint8_t *computeBlob = computeExecutable->shaderExecutable()->getFunction(); + stream->writeBytes(computeBlob, computeShaderSize); + } + + for (gl::ShaderType shaderType : {gl::ShaderType::Compute}) + { + stream->writeInt(mImage2DBindLayoutCache[shaderType].size()); + for (auto &image2DBindLayout : mImage2DBindLayoutCache[shaderType]) + { + stream->writeInt(image2DBindLayout.first); + } + } +} + +void ProgramD3D::setBinaryRetrievableHint(bool /* retrievable */) {} + +void ProgramD3D::setSeparable(bool /* separable */) {} + +angle::Result ProgramD3D::getPixelExecutableForCachedOutputLayout( + d3d::Context *context, + ShaderExecutableD3D **outExecutable, + gl::InfoLog *infoLog) +{ + if (mCachedPixelExecutableIndex.valid()) + { + *outExecutable = mPixelExecutables[mCachedPixelExecutableIndex.value()]->shaderExecutable(); + return angle::Result::Continue; + } + + std::string pixelHLSL = mDynamicHLSL->generatePixelShaderForOutputSignature( + mShaderHLSL[gl::ShaderType::Fragment], mPixelShaderKey, mUsesFragDepth, + mPixelShaderOutputLayoutCache, mShaderStorageBlocks[gl::ShaderType::Fragment], + mPixelShaderKey.size()); + + std::string finalPixelHLSL = mDynamicHLSL->generateShaderForImage2DBindSignature( + *this, mState, gl::ShaderType::Fragment, pixelHLSL, + mImage2DUniforms[gl::ShaderType::Fragment], + mImage2DBindLayoutCache[gl::ShaderType::Fragment], + static_cast(mPixelShaderKey.size())); + + // Generate new pixel executable + ShaderExecutableD3D *pixelExecutable = nullptr; + + gl::InfoLog tempInfoLog; + gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog; + + ANGLE_TRY(mRenderer->compileToExecutable( + context, *currentInfoLog, finalPixelHLSL, gl::ShaderType::Fragment, mStreamOutVaryings, + (mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS), + mShaderWorkarounds[gl::ShaderType::Fragment], &pixelExecutable)); + + if (pixelExecutable) + { + mPixelExecutables.push_back(std::unique_ptr( + new PixelExecutable(mPixelShaderOutputLayoutCache, pixelExecutable))); + mCachedPixelExecutableIndex = mPixelExecutables.size() - 1; + } + else if (!infoLog) + { + ERR() << "Error compiling dynamic pixel executable:" << std::endl + << tempInfoLog.str() << std::endl; + } + + *outExecutable = pixelExecutable; + return angle::Result::Continue; +} + +angle::Result ProgramD3D::getVertexExecutableForCachedInputLayout( + d3d::Context *context, + ShaderExecutableD3D **outExectuable, + gl::InfoLog *infoLog) +{ + if (mCachedVertexExecutableIndex.valid()) + { + *outExectuable = + mVertexExecutables[mCachedVertexExecutableIndex.value()]->shaderExecutable(); + return angle::Result::Continue; + } + + // Generate new dynamic layout with attribute conversions + std::string finalVertexHLSL = mDynamicHLSL->generateVertexShaderForInputLayout( + mShaderHLSL[gl::ShaderType::Vertex], mCachedInputLayout, mState.getProgramInputs(), + mShaderStorageBlocks[gl::ShaderType::Vertex], mPixelShaderKey.size()); + + // Generate new vertex executable + ShaderExecutableD3D *vertexExecutable = nullptr; + + gl::InfoLog tempInfoLog; + gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog; + + ANGLE_TRY(mRenderer->compileToExecutable( + context, *currentInfoLog, finalVertexHLSL, gl::ShaderType::Vertex, mStreamOutVaryings, + (mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS), + mShaderWorkarounds[gl::ShaderType::Vertex], &vertexExecutable)); + + if (vertexExecutable) + { + mVertexExecutables.push_back(std::unique_ptr( + new VertexExecutable(mCachedInputLayout, mCachedVertexSignature, vertexExecutable))); + mCachedVertexExecutableIndex = mVertexExecutables.size() - 1; + } + else if (!infoLog) + { + ERR() << "Error compiling dynamic vertex executable:" << std::endl + << tempInfoLog.str() << std::endl; + } + + *outExectuable = vertexExecutable; + return angle::Result::Continue; +} + +angle::Result ProgramD3D::getGeometryExecutableForPrimitiveType(d3d::Context *context, + const gl::State &state, + gl::PrimitiveMode drawMode, + ShaderExecutableD3D **outExecutable, + gl::InfoLog *infoLog) +{ + if (outExecutable) + { + *outExecutable = nullptr; + } + + // Return a null shader if the current rendering doesn't use a geometry shader + if (!usesGeometryShader(state, drawMode)) + { + return angle::Result::Continue; + } + + gl::PrimitiveMode geometryShaderType = GetGeometryShaderTypeFromDrawMode(drawMode); + + if (mGeometryExecutables[geometryShaderType]) + { + if (outExecutable) + { + *outExecutable = mGeometryExecutables[geometryShaderType].get(); + } + return angle::Result::Continue; + } + const gl::Caps &caps = state.getCaps(); + std::string geometryHLSL = mDynamicHLSL->generateGeometryShaderHLSL( + caps, geometryShaderType, mState, mRenderer->presentPathFastEnabled(), + mHasANGLEMultiviewEnabled, mRenderer->canSelectViewInVertexShader(), + usesGeometryShaderForPointSpriteEmulation(), mGeometryShaderPreamble); + + gl::InfoLog tempInfoLog; + gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog; + + ShaderExecutableD3D *geometryExecutable = nullptr; + angle::Result result = mRenderer->compileToExecutable( + context, *currentInfoLog, geometryHLSL, gl::ShaderType::Geometry, mStreamOutVaryings, + (mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS), CompilerWorkaroundsD3D(), + &geometryExecutable); + + if (!infoLog && result == angle::Result::Stop) + { + ERR() << "Error compiling dynamic geometry executable:" << std::endl + << tempInfoLog.str() << std::endl; + } + + if (geometryExecutable != nullptr) + { + mGeometryExecutables[geometryShaderType].reset(geometryExecutable); + } + + if (outExecutable) + { + *outExecutable = mGeometryExecutables[geometryShaderType].get(); + } + return result; +} + +class ProgramD3D::GetVertexExecutableTask : public ProgramD3D::GetExecutableTask +{ + public: + GetVertexExecutableTask(const gl::Context *context, ProgramD3D *program) + : GetExecutableTask(context, program) + {} + angle::Result run() override + { + ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::GetVertexExecutableTask::run"); + + ANGLE_TRY(mProgram->getVertexExecutableForCachedInputLayout(this, &mExecutable, &mInfoLog)); + + return angle::Result::Continue; + } +}; + +void ProgramD3D::updateCachedInputLayoutFromShader(const gl::Context *context) +{ + GetDefaultInputLayoutFromShader(context, mState.getAttachedShader(gl::ShaderType::Vertex), + &mCachedInputLayout); + VertexExecutable::getSignature(mRenderer, mCachedInputLayout, &mCachedVertexSignature); + updateCachedVertexExecutableIndex(); +} + +class ProgramD3D::GetPixelExecutableTask : public ProgramD3D::GetExecutableTask +{ + public: + GetPixelExecutableTask(const gl::Context *context, ProgramD3D *program) + : GetExecutableTask(context, program) + {} + angle::Result run() override + { + ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::GetPixelExecutableTask::run"); + if (!mProgram->mState.getAttachedShader(gl::ShaderType::Fragment)) + { + return angle::Result::Continue; + } + + mProgram->updateCachedOutputLayoutFromShader(); + mProgram->updateCachedImage2DBindLayoutFromShader(gl::ShaderType::Fragment); + ANGLE_TRY(mProgram->getPixelExecutableForCachedOutputLayout(this, &mExecutable, &mInfoLog)); + + return angle::Result::Continue; + } +}; + +void ProgramD3D::updateCachedOutputLayoutFromShader() +{ + GetDefaultOutputLayoutFromShader(mPixelShaderKey, &mPixelShaderOutputLayoutCache); + updateCachedPixelExecutableIndex(); +} + +void ProgramD3D::updateCachedImage2DBindLayoutFromShader(gl::ShaderType shaderType) +{ + GetDefaultImage2DBindLayoutFromShader(mImage2DUniforms[shaderType], + &mImage2DBindLayoutCache[shaderType]); + switch (shaderType) + { + case gl::ShaderType::Compute: + updateCachedComputeExecutableIndex(); + break; + case gl::ShaderType::Fragment: + updateCachedPixelExecutableIndex(); + break; + case gl::ShaderType::Vertex: + updateCachedVertexExecutableIndex(); + break; + default: + ASSERT(false); + break; + } +} + +class ProgramD3D::GetGeometryExecutableTask : public ProgramD3D::GetExecutableTask +{ + public: + GetGeometryExecutableTask(const gl::Context *context, + ProgramD3D *program, + const gl::State &state) + : GetExecutableTask(context, program), mState(state) + {} + + angle::Result run() override + { + ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::GetGeometryExecutableTask::run"); + // Auto-generate the geometry shader here, if we expect to be using point rendering in + // D3D11. + if (mProgram->usesGeometryShader(mState, gl::PrimitiveMode::Points)) + { + ANGLE_TRY(mProgram->getGeometryExecutableForPrimitiveType( + this, mState, gl::PrimitiveMode::Points, &mExecutable, &mInfoLog)); + } + + return angle::Result::Continue; + } + + private: + const gl::State &mState; +}; + +class ProgramD3D::GetComputeExecutableTask : public ProgramD3D::GetExecutableTask +{ + public: + GetComputeExecutableTask(const gl::Context *context, ProgramD3D *program) + : GetExecutableTask(context, program) + {} + angle::Result run() override + { + ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::GetComputeExecutableTask::run"); + mProgram->updateCachedImage2DBindLayoutFromShader(gl::ShaderType::Compute); + ShaderExecutableD3D *computeExecutable = nullptr; + ANGLE_TRY(mProgram->getComputeExecutableForImage2DBindLayout( + mContext, this, &computeExecutable, &mInfoLog)); + + return computeExecutable ? angle::Result::Continue : angle::Result::Incomplete; + } +}; + +// The LinkEvent implementation for linking a rendering(VS, FS, GS) program. +class ProgramD3D::GraphicsProgramLinkEvent final : public LinkEvent +{ + public: + GraphicsProgramLinkEvent(gl::InfoLog &infoLog, + std::shared_ptr workerPool, + std::shared_ptr vertexTask, + std::shared_ptr pixelTask, + std::shared_ptr geometryTask, + bool useGS, + const ShaderD3D *vertexShader, + const ShaderD3D *fragmentShader) + : mInfoLog(infoLog), + mVertexTask(vertexTask), + mPixelTask(pixelTask), + mGeometryTask(geometryTask), + mWaitEvents({{std::shared_ptr( + angle::WorkerThreadPool::PostWorkerTask(workerPool, mVertexTask)), + std::shared_ptr( + angle::WorkerThreadPool::PostWorkerTask(workerPool, mPixelTask)), + std::shared_ptr( + angle::WorkerThreadPool::PostWorkerTask(workerPool, mGeometryTask))}}), + mUseGS(useGS), + mVertexShader(vertexShader), + mFragmentShader(fragmentShader) + {} + + angle::Result wait(const gl::Context *context) override + { + ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::GraphicsProgramLinkEvent::wait"); + WaitableEvent::WaitMany(&mWaitEvents); + + ANGLE_TRY(checkTask(context, mVertexTask.get())); + ANGLE_TRY(checkTask(context, mPixelTask.get())); + ANGLE_TRY(checkTask(context, mGeometryTask.get())); + + if (mVertexTask->getResult() == angle::Result::Incomplete || + mPixelTask->getResult() == angle::Result::Incomplete || + mGeometryTask->getResult() == angle::Result::Incomplete) + { + return angle::Result::Incomplete; + } + + ShaderExecutableD3D *defaultVertexExecutable = mVertexTask->getExecutable(); + ShaderExecutableD3D *defaultPixelExecutable = mPixelTask->getExecutable(); + ShaderExecutableD3D *pointGS = mGeometryTask->getExecutable(); + + if (mUseGS && pointGS) + { + // Geometry shaders are currently only used internally, so there is no corresponding + // shader object at the interface level. For now the geometry shader debug info is + // prepended to the vertex shader. + mVertexShader->appendDebugInfo("// GEOMETRY SHADER BEGIN\n\n"); + mVertexShader->appendDebugInfo(pointGS->getDebugInfo()); + mVertexShader->appendDebugInfo("\nGEOMETRY SHADER END\n\n\n"); + } + + if (defaultVertexExecutable) + { + mVertexShader->appendDebugInfo(defaultVertexExecutable->getDebugInfo()); + } + + if (defaultPixelExecutable) + { + mFragmentShader->appendDebugInfo(defaultPixelExecutable->getDebugInfo()); + } + + bool isLinked = (defaultVertexExecutable && defaultPixelExecutable && (!mUseGS || pointGS)); + if (!isLinked) + { + mInfoLog << "Failed to create D3D Shaders"; + } + return isLinked ? angle::Result::Continue : angle::Result::Incomplete; + } + + bool isLinking() override + { + for (auto &event : mWaitEvents) + { + if (!event->isReady()) + { + return true; + } + } + return false; + } + + private: + angle::Result checkTask(const gl::Context *context, ProgramD3D::GetExecutableTask *task) + { + if (!task->getInfoLog().empty()) + { + mInfoLog << task->getInfoLog().str(); + } + + // Continue and Incomplete are not errors. For Stop, pass the error to the ContextD3D. + if (task->getResult() != angle::Result::Stop) + { + return angle::Result::Continue; + } + + ContextD3D *contextD3D = GetImplAs(context); + task->popError(contextD3D); + return angle::Result::Stop; + } + + gl::InfoLog &mInfoLog; + std::shared_ptr mVertexTask; + std::shared_ptr mPixelTask; + std::shared_ptr mGeometryTask; + std::array, 3> mWaitEvents; + bool mUseGS; + const ShaderD3D *mVertexShader; + const ShaderD3D *mFragmentShader; +}; + +// The LinkEvent implementation for linking a computing program. +class ProgramD3D::ComputeProgramLinkEvent final : public LinkEvent +{ + public: + ComputeProgramLinkEvent(gl::InfoLog &infoLog, + std::shared_ptr computeTask, + std::shared_ptr event) + : mInfoLog(infoLog), mComputeTask(computeTask), mWaitEvent(event) + {} + + bool isLinking() override { return !mWaitEvent->isReady(); } + + angle::Result wait(const gl::Context *context) override + { + ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::ComputeProgramLinkEvent::wait"); + mWaitEvent->wait(); + + angle::Result result = mComputeTask->getResult(); + if (result != angle::Result::Continue) + { + mInfoLog << "Failed to create D3D compute shader."; + } + return result; + } + + private: + gl::InfoLog &mInfoLog; + std::shared_ptr mComputeTask; + std::shared_ptr mWaitEvent; +}; + +std::unique_ptr ProgramD3D::compileProgramExecutables(const gl::Context *context, + gl::InfoLog &infoLog) +{ + ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::compileProgramExecutables"); + // Ensure the compiler is initialized to avoid race conditions. + angle::Result result = mRenderer->ensureHLSLCompilerInitialized(GetImplAs(context)); + if (result != angle::Result::Continue) + { + return std::make_unique(result); + } + + auto vertexTask = std::make_shared(context, this); + auto pixelTask = std::make_shared(context, this); + auto geometryTask = + std::make_shared(context, this, context->getState()); + bool useGS = usesGeometryShader(context->getState(), gl::PrimitiveMode::Points); + gl::Shader *vertexShader = mState.getAttachedShader(gl::ShaderType::Vertex); + gl::Shader *fragmentShader = mState.getAttachedShader(gl::ShaderType::Fragment); + const ShaderD3D *vertexShaderD3D = vertexShader ? GetImplAs(vertexShader) : nullptr; + const ShaderD3D *fragmentShaderD3D = + fragmentShader ? GetImplAs(fragmentShader) : nullptr; + + return std::make_unique(infoLog, context->getWorkerThreadPool(), + vertexTask, pixelTask, geometryTask, useGS, + vertexShaderD3D, fragmentShaderD3D); +} + +std::unique_ptr ProgramD3D::compileComputeExecutable(const gl::Context *context, + gl::InfoLog &infoLog) +{ + ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::compileComputeExecutable"); + // Ensure the compiler is initialized to avoid race conditions. + angle::Result result = mRenderer->ensureHLSLCompilerInitialized(GetImplAs(context)); + if (result != angle::Result::Continue) + { + return std::make_unique(result); + } + auto computeTask = std::make_shared(context, this); + + std::shared_ptr waitableEvent; + + // TODO(jie.a.chen@intel.com): Fix the flaky bug. + // http://anglebug.com/3349 + bool compileInParallel = false; + if (!compileInParallel) + { + (*computeTask)(); + waitableEvent = std::make_shared(); + } + else + { + waitableEvent = + WorkerThreadPool::PostWorkerTask(context->getWorkerThreadPool(), computeTask); + } + + return std::make_unique(infoLog, computeTask, waitableEvent); +} + +angle::Result ProgramD3D::getComputeExecutableForImage2DBindLayout( + const gl::Context *glContext, + d3d::Context *context, + ShaderExecutableD3D **outExecutable, + gl::InfoLog *infoLog) +{ + ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::getComputeExecutableForImage2DBindLayout"); + if (mCachedComputeExecutableIndex.valid()) + { + *outExecutable = + mComputeExecutables[mCachedComputeExecutableIndex.value()]->shaderExecutable(); + return angle::Result::Continue; + } + + std::string computeHLSL = + mState.getAttachedShader(gl::ShaderType::Compute)->getTranslatedSource(glContext); + + std::string finalComputeHLSL = mDynamicHLSL->generateShaderForImage2DBindSignature( + *this, mState, gl::ShaderType::Compute, computeHLSL, + mImage2DUniforms[gl::ShaderType::Compute], mImage2DBindLayoutCache[gl::ShaderType::Compute], + 0u); + + // Generate new compute executable + ShaderExecutableD3D *computeExecutable = nullptr; + + gl::InfoLog tempInfoLog; + gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog; + + ANGLE_TRY(mRenderer->compileToExecutable(context, *currentInfoLog, finalComputeHLSL, + gl::ShaderType::Compute, std::vector(), + false, CompilerWorkaroundsD3D(), &computeExecutable)); + + if (computeExecutable) + { + mComputeExecutables.push_back(std::unique_ptr( + new ComputeExecutable(mImage2DBindLayoutCache[gl::ShaderType::Compute], + std::unique_ptr(computeExecutable)))); + mCachedComputeExecutableIndex = mComputeExecutables.size() - 1; + } + else if (!infoLog) + { + ERR() << "Error compiling dynamic compute executable:" << std::endl + << tempInfoLog.str() << std::endl; + } + *outExecutable = computeExecutable; + + return angle::Result::Continue; +} + +std::unique_ptr ProgramD3D::link(const gl::Context *context, + const gl::ProgramLinkedResources &resources, + gl::InfoLog &infoLog, + const gl::ProgramMergedVaryings & /*mergedVaryings*/) +{ + ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::link"); + const auto &data = context->getState(); + + reset(); + + gl::Shader *computeShader = mState.getAttachedShader(gl::ShaderType::Compute); + if (computeShader) + { + mShaderSamplers[gl::ShaderType::Compute].resize( + data.getCaps().maxShaderTextureImageUnits[gl::ShaderType::Compute]); + mImages[gl::ShaderType::Compute].resize(data.getCaps().maxImageUnits); + mReadonlyImages[gl::ShaderType::Compute].resize(data.getCaps().maxImageUnits); + + mShaderUniformsDirty.set(gl::ShaderType::Compute); + + linkResources(context, resources); + + for (const sh::ShaderVariable &uniform : computeShader->getUniforms(context)) + { + if (gl::IsImageType(uniform.type) && gl::IsImage2DType(uniform.type)) + { + mImage2DUniforms[gl::ShaderType::Compute].push_back(uniform); + } + } + + defineUniformsAndAssignRegisters(context); + + return compileComputeExecutable(context, infoLog); + } + else + { + gl::ShaderMap shadersD3D = {}; + for (gl::ShaderType shaderType : gl::kAllGraphicsShaderTypes) + { + if (gl::Shader *shader = mState.getAttachedShader(shaderType)) + { + shadersD3D[shaderType] = GetImplAs(mState.getAttachedShader(shaderType)); + + mShaderSamplers[shaderType].resize( + data.getCaps().maxShaderTextureImageUnits[shaderType]); + mImages[shaderType].resize(data.getCaps().maxImageUnits); + mReadonlyImages[shaderType].resize(data.getCaps().maxImageUnits); + + shadersD3D[shaderType]->generateWorkarounds(&mShaderWorkarounds[shaderType]); + + mShaderUniformsDirty.set(shaderType); + + const std::set &slowCompilingUniformBlockSet = + shadersD3D[shaderType]->getSlowCompilingUniformBlockSet(); + if (slowCompilingUniformBlockSet.size() > 0) + { + std::ostringstream stream; + stream << "You could get a better shader compiling performance if you re-write" + << " the uniform block(s)\n[ "; + for (const std::string &str : slowCompilingUniformBlockSet) + { + stream << str << " "; + } + stream << "]\nin the " << gl::GetShaderTypeString(shaderType) << " shader.\n"; + + stream << "You could get more details from " + "https://chromium.googlesource.com/angle/angle/+/refs/heads/main/" + "src/libANGLE/renderer/d3d/d3d11/" + "UniformBlockToStructuredBufferTranslation.md\n"; + ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_MEDIUM, + stream.str().c_str()); + } + + for (const sh::ShaderVariable &uniform : shader->getUniforms(context)) + { + if (gl::IsImageType(uniform.type) && gl::IsImage2DType(uniform.type)) + { + mImage2DUniforms[shaderType].push_back(uniform); + } + } + } + } + + if (mRenderer->getNativeLimitations().noFrontFacingSupport) + { + const ShaderD3D *fragmentShader = shadersD3D[gl::ShaderType::Fragment]; + if (fragmentShader && fragmentShader->usesFrontFacing()) + { + infoLog << "The current renderer doesn't support gl_FrontFacing"; + return std::make_unique(angle::Result::Incomplete); + } + } + + const gl::VaryingPacking &varyingPacking = + resources.varyingPacking.getOutputPacking(gl::ShaderType::Vertex); + + ProgramD3DMetadata metadata(mRenderer, shadersD3D, context->getClientType()); + BuiltinVaryingsD3D builtins(metadata, varyingPacking); + + mDynamicHLSL->generateShaderLinkHLSL(context, context->getCaps(), mState, metadata, + varyingPacking, builtins, &mShaderHLSL); + + const ShaderD3D *vertexShader = shadersD3D[gl::ShaderType::Vertex]; + mUsesPointSize = vertexShader && vertexShader->usesPointSize(); + mDynamicHLSL->getPixelShaderOutputKey(data, mState, metadata, &mPixelShaderKey); + mUsesFragDepth = metadata.usesFragDepth(); + mUsesVertexID = metadata.usesVertexID(); + mUsesViewID = metadata.usesViewID(); + mHasANGLEMultiviewEnabled = metadata.hasANGLEMultiviewEnabled(); + + // Cache if we use flat shading + mUsesFlatInterpolation = FindFlatInterpolationVarying(context, mState.getAttachedShaders()); + + if (mRenderer->getMajorShaderModel() >= 4) + { + mGeometryShaderPreamble = mDynamicHLSL->generateGeometryShaderPreamble( + varyingPacking, builtins, mHasANGLEMultiviewEnabled, + metadata.canSelectViewInVertexShader()); + } + + initAttribLocationsToD3DSemantic(context); + + defineUniformsAndAssignRegisters(context); + + gatherTransformFeedbackVaryings(varyingPacking, builtins[gl::ShaderType::Vertex]); + + linkResources(context, resources); + + if (mState.getAttachedShader(gl::ShaderType::Vertex)) + { + updateCachedInputLayoutFromShader(context); + } + + return compileProgramExecutables(context, infoLog); + } +} + +GLboolean ProgramD3D::validate(const gl::Caps & /*caps*/, gl::InfoLog * /*infoLog*/) +{ + // TODO(jmadill): Do something useful here? + return GL_TRUE; +} + +void ProgramD3D::initializeShaderStorageBlocks(const gl::Context *context) +{ + if (mState.getShaderStorageBlocks().empty()) + { + return; + } + + ASSERT(mD3DShaderStorageBlocks.empty()); + + // Assign registers and update sizes. + gl::ShaderMap shadersD3D = {}; + for (gl::ShaderType shaderType : gl::AllShaderTypes()) + { + shadersD3D[shaderType] = SafeGetImplAs(mState.getAttachedShader(shaderType)); + } + for (const gl::InterfaceBlock &shaderStorageBlock : mState.getShaderStorageBlocks()) + { + unsigned int shaderStorageBlockElement = + shaderStorageBlock.isArray ? shaderStorageBlock.arrayElement : 0; + D3DInterfaceBlock d3dShaderStorageBlock; + + for (gl::ShaderType shaderType : gl::AllShaderTypes()) + { + if (shaderStorageBlock.isActive(shaderType)) + { + ASSERT(shadersD3D[shaderType]); + unsigned int baseRegister = + shadersD3D[shaderType]->getShaderStorageBlockRegister(shaderStorageBlock.name); + + d3dShaderStorageBlock.mShaderRegisterIndexes[shaderType] = + baseRegister + shaderStorageBlockElement; + } + } + mD3DShaderStorageBlocks.push_back(d3dShaderStorageBlock); + } + + for (gl::ShaderType shaderType : gl::AllShaderTypes()) + { + gl::Shader *shader = mState.getAttachedShader(shaderType); + if (!shader) + { + continue; + } + ShaderD3D *shaderD3D = SafeGetImplAs(shader); + for (const sh::InterfaceBlock &ssbo : shader->getShaderStorageBlocks(context)) + { + if (!ssbo.active) + { + continue; + } + ShaderStorageBlock block; + block.name = !ssbo.instanceName.empty() ? ssbo.instanceName : ssbo.name; + block.arraySize = ssbo.isArray() ? ssbo.arraySize : 0; + block.registerIndex = shaderD3D->getShaderStorageBlockRegister(ssbo.name); + mShaderStorageBlocks[shaderType].push_back(block); + } + } +} + +void ProgramD3D::initializeUniformBlocks() +{ + if (mState.getUniformBlocks().empty()) + { + return; + } + + ASSERT(mD3DUniformBlocks.empty()); + + // Assign registers and update sizes. + gl::ShaderMap shadersD3D = {}; + for (gl::ShaderType shaderType : gl::AllShaderTypes()) + { + shadersD3D[shaderType] = SafeGetImplAs(mState.getAttachedShader(shaderType)); + } + + for (const gl::InterfaceBlock &uniformBlock : mState.getUniformBlocks()) + { + unsigned int uniformBlockElement = uniformBlock.isArray ? uniformBlock.arrayElement : 0; + + D3DUniformBlock d3dUniformBlock; + + for (gl::ShaderType shaderType : gl::AllShaderTypes()) + { + if (uniformBlock.isActive(shaderType)) + { + ASSERT(shadersD3D[shaderType]); + unsigned int baseRegister = + shadersD3D[shaderType]->getUniformBlockRegister(uniformBlock.name); + d3dUniformBlock.mShaderRegisterIndexes[shaderType] = + baseRegister + uniformBlockElement; + bool useStructuredBuffer = + shadersD3D[shaderType]->shouldUniformBlockUseStructuredBuffer( + uniformBlock.name); + if (useStructuredBuffer) + { + d3dUniformBlock.mUseStructuredBuffers[shaderType] = true; + d3dUniformBlock.mByteWidths[shaderType] = uniformBlock.dataSize; + d3dUniformBlock.mStructureByteStrides[shaderType] = + uniformBlock.firstFieldArraySize == 0u + ? uniformBlock.dataSize + : uniformBlock.dataSize / uniformBlock.firstFieldArraySize; + } + } + } + + mD3DUniformBlocks.push_back(d3dUniformBlock); + } +} + +void ProgramD3D::initializeUniformStorage(const gl::ShaderBitSet &availableShaderStages) +{ + // Compute total default block size + gl::ShaderMap shaderRegisters = {}; + for (const D3DUniform *d3dUniform : mD3DUniforms) + { + if (d3dUniform->isSampler()) + { + continue; + } + + for (gl::ShaderType shaderType : availableShaderStages) + { + if (d3dUniform->isReferencedByShader(shaderType)) + { + shaderRegisters[shaderType] = std::max( + shaderRegisters[shaderType], + d3dUniform->mShaderRegisterIndexes[shaderType] + d3dUniform->registerCount); + } + } + } + + // We only reset uniform storages for the shader stages available in the program (attached + // shaders in ProgramD3D::link() and linkedShaderStages in ProgramD3D::load()). + for (gl::ShaderType shaderType : availableShaderStages) + { + mShaderUniformStorages[shaderType].reset( + mRenderer->createUniformStorage(shaderRegisters[shaderType] * 16u)); + } + + // Iterate the uniforms again to assign data pointers to default block uniforms. + for (D3DUniform *d3dUniform : mD3DUniforms) + { + if (d3dUniform->isSampler()) + { + d3dUniform->mSamplerData.resize(d3dUniform->getArraySizeProduct(), 0); + continue; + } + + for (gl::ShaderType shaderType : availableShaderStages) + { + if (d3dUniform->isReferencedByShader(shaderType)) + { + d3dUniform->mShaderData[shaderType] = + mShaderUniformStorages[shaderType]->getDataPointer( + d3dUniform->mShaderRegisterIndexes[shaderType], + d3dUniform->registerElement); + } + } + } +} + +void ProgramD3D::updateUniformBufferCache(const gl::Caps &caps) +{ + if (mState.getUniformBlocks().empty()) + { + return; + } + + for (gl::ShaderType shaderType : gl::AllShaderTypes()) + { + mShaderUBOCaches[shaderType].clear(); + mShaderUBOCachesUseSB[shaderType].clear(); + } + + for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mD3DUniformBlocks.size(); + uniformBlockIndex++) + { + const D3DUniformBlock &uniformBlock = mD3DUniformBlocks[uniformBlockIndex]; + GLuint blockBinding = mState.getUniformBlockBinding(uniformBlockIndex); + + // Unnecessary to apply an unreferenced standard or shared UBO + for (gl::ShaderType shaderType : gl::AllShaderTypes()) + { + if (!uniformBlock.activeInShader(shaderType)) + { + continue; + } + + bool useStructuredBuffer = uniformBlock.mUseStructuredBuffers[shaderType]; + unsigned int registerIndex = uniformBlock.mShaderRegisterIndexes[shaderType]; + if (useStructuredBuffer) + { + D3DUBOCacheUseSB cacheUseSB; + cacheUseSB.registerIndex = registerIndex; + cacheUseSB.binding = blockBinding; + cacheUseSB.byteWidth = uniformBlock.mByteWidths[shaderType]; + cacheUseSB.structureByteStride = uniformBlock.mStructureByteStrides[shaderType]; + mShaderUBOCachesUseSB[shaderType].push_back(cacheUseSB); + } + else + { + ASSERT(registerIndex < + static_cast(caps.maxShaderUniformBlocks[shaderType])); + D3DUBOCache cache; + cache.registerIndex = registerIndex; + cache.binding = blockBinding; + mShaderUBOCaches[shaderType].push_back(cache); + } + } + } + + for (gl::ShaderType shaderType : gl::AllShaderTypes()) + { + GLuint uniformBlockCount = static_cast(mShaderUBOCaches[shaderType].size() + + mShaderUBOCachesUseSB[shaderType].size()); + ASSERT(uniformBlockCount <= + static_cast(caps.maxShaderUniformBlocks[shaderType])); + } +} + +unsigned int ProgramD3D::getAtomicCounterBufferRegisterIndex(GLuint binding, + gl::ShaderType shaderType) const +{ + if (shaderType != gl::ShaderType::Compute) + { + // Implement atomic counters for non-compute shaders + // http://anglebug.com/1729 + UNIMPLEMENTED(); + } + return mComputeAtomicCounterBufferRegisterIndices[binding]; +} + +unsigned int ProgramD3D::getShaderStorageBufferRegisterIndex(GLuint blockIndex, + gl::ShaderType shaderType) const +{ + return mD3DShaderStorageBlocks[blockIndex].mShaderRegisterIndexes[shaderType]; +} + +const std::vector &ProgramD3D::getShaderUniformBufferCache( + gl::ShaderType shaderType) const +{ + return mShaderUBOCaches[shaderType]; +} + +const std::vector &ProgramD3D::getShaderUniformBufferCacheUseSB( + gl::ShaderType shaderType) const +{ + return mShaderUBOCachesUseSB[shaderType]; +} + +void ProgramD3D::dirtyAllUniforms() +{ + mShaderUniformsDirty = mState.getExecutable().getLinkedShaderStages(); +} + +void ProgramD3D::markUniformsClean() +{ + mShaderUniformsDirty.reset(); +} + +void ProgramD3D::setUniform1fv(GLint location, GLsizei count, const GLfloat *v) +{ + setUniformInternal(location, count, v, GL_FLOAT); +} + +void ProgramD3D::setUniform2fv(GLint location, GLsizei count, const GLfloat *v) +{ + setUniformInternal(location, count, v, GL_FLOAT_VEC2); +} + +void ProgramD3D::setUniform3fv(GLint location, GLsizei count, const GLfloat *v) +{ + setUniformInternal(location, count, v, GL_FLOAT_VEC3); +} + +void ProgramD3D::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) +{ + setUniformInternal(location, count, v, GL_FLOAT_VEC4); +} + +void ProgramD3D::setUniformMatrix2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + setUniformMatrixfvInternal<2, 2>(location, count, transpose, value); +} + +void ProgramD3D::setUniformMatrix3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + setUniformMatrixfvInternal<3, 3>(location, count, transpose, value); +} + +void ProgramD3D::setUniformMatrix4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + setUniformMatrixfvInternal<4, 4>(location, count, transpose, value); +} + +void ProgramD3D::setUniformMatrix2x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + setUniformMatrixfvInternal<2, 3>(location, count, transpose, value); +} + +void ProgramD3D::setUniformMatrix3x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + setUniformMatrixfvInternal<3, 2>(location, count, transpose, value); +} + +void ProgramD3D::setUniformMatrix2x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + setUniformMatrixfvInternal<2, 4>(location, count, transpose, value); +} + +void ProgramD3D::setUniformMatrix4x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + setUniformMatrixfvInternal<4, 2>(location, count, transpose, value); +} + +void ProgramD3D::setUniformMatrix3x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + setUniformMatrixfvInternal<3, 4>(location, count, transpose, value); +} + +void ProgramD3D::setUniformMatrix4x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + setUniformMatrixfvInternal<4, 3>(location, count, transpose, value); +} + +void ProgramD3D::setUniform1iv(GLint location, GLsizei count, const GLint *v) +{ + setUniformInternal(location, count, v, GL_INT); +} + +void ProgramD3D::setUniform2iv(GLint location, GLsizei count, const GLint *v) +{ + setUniformInternal(location, count, v, GL_INT_VEC2); +} + +void ProgramD3D::setUniform3iv(GLint location, GLsizei count, const GLint *v) +{ + setUniformInternal(location, count, v, GL_INT_VEC3); +} + +void ProgramD3D::setUniform4iv(GLint location, GLsizei count, const GLint *v) +{ + setUniformInternal(location, count, v, GL_INT_VEC4); +} + +void ProgramD3D::setUniform1uiv(GLint location, GLsizei count, const GLuint *v) +{ + setUniformInternal(location, count, v, GL_UNSIGNED_INT); +} + +void ProgramD3D::setUniform2uiv(GLint location, GLsizei count, const GLuint *v) +{ + setUniformInternal(location, count, v, GL_UNSIGNED_INT_VEC2); +} + +void ProgramD3D::setUniform3uiv(GLint location, GLsizei count, const GLuint *v) +{ + setUniformInternal(location, count, v, GL_UNSIGNED_INT_VEC3); +} + +void ProgramD3D::setUniform4uiv(GLint location, GLsizei count, const GLuint *v) +{ + setUniformInternal(location, count, v, GL_UNSIGNED_INT_VEC4); +} + +void ProgramD3D::defineUniformsAndAssignRegisters(const gl::Context *context) +{ + D3DUniformMap uniformMap; + + gl::ShaderBitSet attachedShaders; + for (gl::ShaderType shaderType : gl::AllShaderTypes()) + { + gl::Shader *shader = mState.getAttachedShader(shaderType); + if (shader) + { + for (const sh::ShaderVariable &uniform : shader->getUniforms(context)) + { + if (uniform.active) + { + defineUniformBase(shader, uniform, &uniformMap); + } + } + + attachedShaders.set(shader->getType()); + } + } + + // Initialize the D3DUniform list to mirror the indexing of the GL layer. + for (const gl::LinkedUniform &glUniform : mState.getUniforms()) + { + if (!glUniform.isInDefaultBlock()) + continue; + + std::string name = glUniform.name; + if (glUniform.isArray()) + { + // In the program state, array uniform names include [0] as in the program resource + // spec. Here we don't include it. + // TODO(oetuaho@nvidia.com): consider using the same uniform naming here as in the GL + // layer. + ASSERT(angle::EndsWith(name, "[0]")); + name.resize(name.length() - 3); + } + auto mapEntry = uniformMap.find(name); + ASSERT(mapEntry != uniformMap.end()); + mD3DUniforms.push_back(mapEntry->second); + } + + assignAllSamplerRegisters(); + assignAllAtomicCounterRegisters(); + // Samplers and readonly images share shader input resource slot, adjust low value of + // readonly image range. + for (gl::ShaderType shaderType : {gl::ShaderType::Compute, gl::ShaderType::Fragment}) + { + mUsedReadonlyImageRange[shaderType] = + gl::RangeUI(mUsedShaderSamplerRanges[shaderType].high(), + mUsedShaderSamplerRanges[shaderType].high()); + // Atomic counter buffers and non-readonly images share input resource slots + mUsedImageRange[shaderType] = gl::RangeUI(mUsedAtomicCounterRange[shaderType].high(), + mUsedAtomicCounterRange[shaderType].high()); + } + assignAllImageRegisters(); + initializeUniformStorage(attachedShaders); +} + +void ProgramD3D::defineUniformBase(const gl::Shader *shader, + const sh::ShaderVariable &uniform, + D3DUniformMap *uniformMap) +{ + sh::StubBlockEncoder stubEncoder; + + // Samplers get their registers assigned in assignAllSamplerRegisters, and images get their + // registers assigned in assignAllImageRegisters. + if (gl::IsSamplerType(uniform.type)) + { + UniformEncodingVisitorD3D visitor(shader->getType(), HLSLRegisterType::Texture, + &stubEncoder, uniformMap); + sh::TraverseShaderVariable(uniform, false, &visitor); + return; + } + + if (gl::IsImageType(uniform.type)) + { + if (uniform.readonly) + { + UniformEncodingVisitorD3D visitor(shader->getType(), HLSLRegisterType::Texture, + &stubEncoder, uniformMap); + sh::TraverseShaderVariable(uniform, false, &visitor); + } + else + { + UniformEncodingVisitorD3D visitor( + shader->getType(), HLSLRegisterType::UnorderedAccessView, &stubEncoder, uniformMap); + sh::TraverseShaderVariable(uniform, false, &visitor); + } + mImageBindingMap[uniform.name] = uniform.binding; + return; + } + + if (uniform.isBuiltIn() && !uniform.isEmulatedBuiltIn()) + { + UniformEncodingVisitorD3D visitor(shader->getType(), HLSLRegisterType::None, &stubEncoder, + uniformMap); + sh::TraverseShaderVariable(uniform, false, &visitor); + return; + } + else if (gl::IsAtomicCounterType(uniform.type)) + { + UniformEncodingVisitorD3D visitor(shader->getType(), HLSLRegisterType::UnorderedAccessView, + &stubEncoder, uniformMap); + sh::TraverseShaderVariable(uniform, false, &visitor); + mAtomicBindingMap[uniform.name] = uniform.binding; + return; + } + + const ShaderD3D *shaderD3D = GetImplAs(shader); + unsigned int startRegister = shaderD3D->getUniformRegister(uniform.name); + ShShaderOutput outputType = shaderD3D->getCompilerOutputType(); + sh::HLSLBlockEncoder encoder(sh::HLSLBlockEncoder::GetStrategyFor(outputType), true); + encoder.skipRegisters(startRegister); + + UniformEncodingVisitorD3D visitor(shader->getType(), HLSLRegisterType::None, &encoder, + uniformMap); + sh::TraverseShaderVariable(uniform, false, &visitor); +} + +bool ProgramD3D::hasNamedUniform(const std::string &name) +{ + for (D3DUniform *d3dUniform : mD3DUniforms) + { + if (d3dUniform->name == name) + { + return true; + } + } + + return false; +} + +// Assume count is already clamped. +template +void ProgramD3D::setUniformImpl(D3DUniform *targetUniform, + const gl::VariableLocation &locationInfo, + GLsizei count, + const T *v, + uint8_t *targetState, + GLenum uniformType) +{ + const int components = targetUniform->typeInfo.componentCount; + const unsigned int arrayElementOffset = locationInfo.arrayIndex; + const int blockSize = 4; + + if (targetUniform->typeInfo.type == uniformType) + { + T *dest = reinterpret_cast(targetState) + arrayElementOffset * blockSize; + const T *source = v; + + // If the component is equal to the block size, we can optimize to a single memcpy. + // Otherwise, we have to do partial block writes. + if (components == blockSize) + { + memcpy(dest, source, components * count * sizeof(T)); + } + else + { + for (GLint i = 0; i < count; i++, dest += blockSize, source += components) + { + memcpy(dest, source, components * sizeof(T)); + } + } + } + else + { + ASSERT(targetUniform->typeInfo.type == gl::VariableBoolVectorType(uniformType)); + GLint *boolParams = reinterpret_cast(targetState) + arrayElementOffset * 4; + + for (GLint i = 0; i < count; i++) + { + GLint *dest = boolParams + (i * 4); + const T *source = v + (i * components); + + for (int c = 0; c < components; c++) + { + dest[c] = (source[c] == static_cast(0)) ? GL_FALSE : GL_TRUE; + } + } + } +} + +template +void ProgramD3D::setUniformInternal(GLint location, GLsizei count, const T *v, GLenum uniformType) +{ + const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location]; + D3DUniform *targetUniform = mD3DUniforms[locationInfo.index]; + + if (targetUniform->typeInfo.isSampler) + { + ASSERT(uniformType == GL_INT); + size_t size = count * sizeof(T); + GLint *dest = &targetUniform->mSamplerData[locationInfo.arrayIndex]; + if (memcmp(dest, v, size) != 0) + { + memcpy(dest, v, size); + mDirtySamplerMapping = true; + } + return; + } + + for (gl::ShaderType shaderType : gl::AllShaderTypes()) + { + uint8_t *targetState = targetUniform->mShaderData[shaderType]; + if (targetState) + { + setUniformImpl(targetUniform, locationInfo, count, v, targetState, uniformType); + mShaderUniformsDirty.set(shaderType); + } + } +} + +template +void ProgramD3D::setUniformMatrixfvInternal(GLint location, + GLsizei countIn, + GLboolean transpose, + const GLfloat *value) +{ + D3DUniform *targetUniform = getD3DUniformFromLocation(location); + const gl::VariableLocation &uniformLocation = mState.getUniformLocations()[location]; + unsigned int arrayElementOffset = uniformLocation.arrayIndex; + unsigned int elementCount = targetUniform->getArraySizeProduct(); + + for (gl::ShaderType shaderType : gl::AllShaderTypes()) + { + if (targetUniform->mShaderData[shaderType]) + { + SetFloatUniformMatrixHLSL::Run(arrayElementOffset, elementCount, countIn, + transpose, value, + targetUniform->mShaderData[shaderType]); + mShaderUniformsDirty.set(shaderType); + } + } +} + +void ProgramD3D::assignAllSamplerRegisters() +{ + for (size_t uniformIndex = 0; uniformIndex < mD3DUniforms.size(); ++uniformIndex) + { + if (mD3DUniforms[uniformIndex]->isSampler()) + { + assignSamplerRegisters(uniformIndex); + } + } +} + +void ProgramD3D::assignSamplerRegisters(size_t uniformIndex) +{ + D3DUniform *d3dUniform = mD3DUniforms[uniformIndex]; + ASSERT(d3dUniform->isSampler()); + // If the uniform is an array of arrays, then we have separate entries for each inner array in + // mD3DUniforms. However, the sampler register info is stored in the shader only for the + // outermost array. + std::vector subscripts; + const std::string baseName = gl::ParseResourceName(d3dUniform->name, &subscripts); + unsigned int registerOffset = + mState.getUniforms()[uniformIndex].parentArrayIndex() * d3dUniform->getArraySizeProduct(); + + bool hasUniform = false; + for (gl::ShaderType shaderType : gl::AllShaderTypes()) + { + if (!mState.getAttachedShader(shaderType)) + { + continue; + } + + const ShaderD3D *shaderD3D = GetImplAs(mState.getAttachedShader(shaderType)); + if (shaderD3D->hasUniform(baseName)) + { + d3dUniform->mShaderRegisterIndexes[shaderType] = + shaderD3D->getUniformRegister(baseName) + registerOffset; + ASSERT(d3dUniform->mShaderRegisterIndexes[shaderType] != GL_INVALID_VALUE); + + AssignSamplers(d3dUniform->mShaderRegisterIndexes[shaderType], d3dUniform->typeInfo, + d3dUniform->getArraySizeProduct(), mShaderSamplers[shaderType], + &mUsedShaderSamplerRanges[shaderType]); + hasUniform = true; + } + } + + ASSERT(hasUniform); +} + +// static +void ProgramD3D::AssignSamplers(unsigned int startSamplerIndex, + const gl::UniformTypeInfo &typeInfo, + unsigned int samplerCount, + std::vector &outSamplers, + gl::RangeUI *outUsedRange) +{ + unsigned int samplerIndex = startSamplerIndex; + + do + { + ASSERT(samplerIndex < outSamplers.size()); + Sampler *sampler = &outSamplers[samplerIndex]; + sampler->active = true; + sampler->textureType = gl::FromGLenum(typeInfo.textureType); + sampler->logicalTextureUnit = 0; + outUsedRange->extend(samplerIndex); + samplerIndex++; + } while (samplerIndex < startSamplerIndex + samplerCount); +} + +void ProgramD3D::assignAllImageRegisters() +{ + for (size_t uniformIndex = 0; uniformIndex < mD3DUniforms.size(); ++uniformIndex) + { + if (mD3DUniforms[uniformIndex]->isImage() && !mD3DUniforms[uniformIndex]->isImage2D()) + { + assignImageRegisters(uniformIndex); + } + } +} + +void ProgramD3D::assignAllAtomicCounterRegisters() +{ + if (mAtomicBindingMap.empty()) + { + return; + } + gl::ShaderType shaderType = gl::ShaderType::Compute; + const gl::Shader *computeShader = mState.getAttachedShader(shaderType); + if (computeShader) + { + const ShaderD3D *computeShaderD3D = GetImplAs(computeShader); + auto ®isterIndices = mComputeAtomicCounterBufferRegisterIndices; + for (auto &atomicBinding : mAtomicBindingMap) + { + ASSERT(computeShaderD3D->hasUniform(atomicBinding.first)); + unsigned int currentRegister = + computeShaderD3D->getUniformRegister(atomicBinding.first); + ASSERT(currentRegister != GL_INVALID_INDEX); + const int kBinding = atomicBinding.second; + + registerIndices[kBinding] = currentRegister; + + mUsedAtomicCounterRange[gl::ShaderType::Compute].extend(currentRegister); + } + } + else + { + // Implement atomic counters for non-compute shaders + // http://anglebug.com/1729 + UNIMPLEMENTED(); + } +} + +void ProgramD3D::assignImageRegisters(size_t uniformIndex) +{ + D3DUniform *d3dUniform = mD3DUniforms[uniformIndex]; + ASSERT(d3dUniform->isImage()); + // If the uniform is an array of arrays, then we have separate entries for each inner array in + // mD3DUniforms. However, the image register info is stored in the shader only for the + // outermost array. + std::vector subscripts; + const std::string baseName = gl::ParseResourceName(d3dUniform->name, &subscripts); + unsigned int registerOffset = + mState.getUniforms()[uniformIndex].parentArrayIndex() * d3dUniform->getArraySizeProduct(); + + const gl::Shader *computeShader = mState.getAttachedShader(gl::ShaderType::Compute); + if (computeShader) + { + const ShaderD3D *computeShaderD3D = + GetImplAs(mState.getAttachedShader(gl::ShaderType::Compute)); + ASSERT(computeShaderD3D->hasUniform(baseName)); + d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Compute] = + computeShaderD3D->getUniformRegister(baseName) + registerOffset; + ASSERT(d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Compute] != GL_INVALID_INDEX); + auto bindingIter = mImageBindingMap.find(baseName); + ASSERT(bindingIter != mImageBindingMap.end()); + if (d3dUniform->regType == HLSLRegisterType::Texture) + { + AssignImages(d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Compute], + bindingIter->second, d3dUniform->getArraySizeProduct(), + mReadonlyImages[gl::ShaderType::Compute], + &mUsedReadonlyImageRange[gl::ShaderType::Compute]); + } + else if (d3dUniform->regType == HLSLRegisterType::UnorderedAccessView) + { + AssignImages(d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Compute], + bindingIter->second, d3dUniform->getArraySizeProduct(), + mImages[gl::ShaderType::Compute], + &mUsedImageRange[gl::ShaderType::Compute]); + } + else + { + UNREACHABLE(); + } + } + else + { + // TODO(xinghua.cao@intel.com): Implement image variables in vertex shader and pixel shader. + UNIMPLEMENTED(); + } +} + +// static +void ProgramD3D::AssignImages(unsigned int startImageIndex, + int startLogicalImageUnit, + unsigned int imageCount, + std::vector &outImages, + gl::RangeUI *outUsedRange) +{ + unsigned int imageIndex = startImageIndex; + + // If declare without a binding qualifier, any uniform image variable (include all elements of + // unbound image array) shoud be bound to unit zero. + if (startLogicalImageUnit == -1) + { + ASSERT(imageIndex < outImages.size()); + Image *image = &outImages[imageIndex]; + image->active = true; + image->logicalImageUnit = 0; + outUsedRange->extend(imageIndex); + return; + } + + unsigned int logcalImageUnit = startLogicalImageUnit; + do + { + ASSERT(imageIndex < outImages.size()); + Image *image = &outImages[imageIndex]; + image->active = true; + image->logicalImageUnit = logcalImageUnit; + outUsedRange->extend(imageIndex); + imageIndex++; + logcalImageUnit++; + } while (imageIndex < startImageIndex + imageCount); +} + +void ProgramD3D::assignImage2DRegisters(gl::ShaderType shaderType, + unsigned int startImageIndex, + int startLogicalImageUnit, + bool readonly) +{ + if (readonly) + { + AssignImages(startImageIndex, startLogicalImageUnit, 1, mReadonlyImages[shaderType], + &mUsedReadonlyImageRange[shaderType]); + } + else + { + AssignImages(startImageIndex, startLogicalImageUnit, 1, mImages[shaderType], + &mUsedImageRange[shaderType]); + } +} + +void ProgramD3D::reset() +{ + mVertexExecutables.clear(); + mPixelExecutables.clear(); + mComputeExecutables.clear(); + + for (auto &geometryExecutable : mGeometryExecutables) + { + geometryExecutable.reset(nullptr); + } + + for (gl::ShaderType shaderType : gl::AllShaderTypes()) + { + mShaderHLSL[shaderType].clear(); + } + + mUsesFragDepth = false; + mHasANGLEMultiviewEnabled = false; + mUsesVertexID = false; + mUsesViewID = false; + mPixelShaderKey.clear(); + mUsesPointSize = false; + mUsesFlatInterpolation = false; + + SafeDeleteContainer(mD3DUniforms); + mD3DUniformBlocks.clear(); + mD3DShaderStorageBlocks.clear(); + mComputeAtomicCounterBufferRegisterIndices.fill({}); + + for (gl::ShaderType shaderType : gl::AllShaderTypes()) + { + mShaderUniformStorages[shaderType].reset(); + mShaderSamplers[shaderType].clear(); + mImages[shaderType].clear(); + mReadonlyImages[shaderType].clear(); + } + + mUsedShaderSamplerRanges.fill({0, 0}); + mUsedAtomicCounterRange.fill({0, 0}); + mDirtySamplerMapping = true; + mUsedImageRange.fill({0, 0}); + mUsedReadonlyImageRange.fill({0, 0}); + + mAttribLocationToD3DSemantic.fill(-1); + + mStreamOutVaryings.clear(); + + mGeometryShaderPreamble.clear(); + + markUniformsClean(); + + mCachedPixelExecutableIndex.reset(); + mCachedVertexExecutableIndex.reset(); +} + +unsigned int ProgramD3D::getSerial() const +{ + return mSerial; +} + +unsigned int ProgramD3D::issueSerial() +{ + return mCurrentSerial++; +} + +void ProgramD3D::initAttribLocationsToD3DSemantic(const gl::Context *context) +{ + gl::Shader *vertexShader = mState.getAttachedShader(gl::ShaderType::Vertex); + if (!vertexShader) + { + return; + } + + // Init semantic index + int semanticIndex = 0; + for (const sh::ShaderVariable &attribute : vertexShader->getActiveAttributes(context)) + { + int regCount = gl::VariableRegisterCount(attribute.type); + GLuint location = mState.getAttributeLocation(attribute.name); + ASSERT(location != std::numeric_limits::max()); + + for (int reg = 0; reg < regCount; ++reg) + { + mAttribLocationToD3DSemantic[location + reg] = semanticIndex++; + } + } +} + +void ProgramD3D::updateCachedInputLayout(Serial associatedSerial, const gl::State &state) +{ + if (mCurrentVertexArrayStateSerial == associatedSerial) + { + return; + } + + mCurrentVertexArrayStateSerial = associatedSerial; + mCachedInputLayout.clear(); + + const auto &vertexAttributes = state.getVertexArray()->getVertexAttributes(); + const gl::AttributesMask &attributesMask = + mState.getExecutable().getActiveAttribLocationsMask(); + + for (size_t locationIndex : attributesMask) + { + int d3dSemantic = mAttribLocationToD3DSemantic[locationIndex]; + + if (d3dSemantic != -1) + { + if (mCachedInputLayout.size() < static_cast(d3dSemantic + 1)) + { + mCachedInputLayout.resize(d3dSemantic + 1, angle::FormatID::NONE); + } + mCachedInputLayout[d3dSemantic] = + GetVertexFormatID(vertexAttributes[locationIndex], + state.getVertexAttribCurrentValue(locationIndex).Type); + } + } + + VertexExecutable::getSignature(mRenderer, mCachedInputLayout, &mCachedVertexSignature); + + updateCachedVertexExecutableIndex(); +} + +void ProgramD3D::updateCachedOutputLayout(const gl::Context *context, + const gl::Framebuffer *framebuffer) +{ + mPixelShaderOutputLayoutCache.clear(); + + FramebufferD3D *fboD3D = GetImplAs(framebuffer); + const auto &colorbuffers = fboD3D->getColorAttachmentsForRender(context); + + for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment) + { + const gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment]; + + if (colorbuffer) + { + auto binding = colorbuffer->getBinding() == GL_BACK ? GL_COLOR_ATTACHMENT0 + : colorbuffer->getBinding(); + size_t maxIndex = binding != GL_NONE ? GetMaxOutputIndex(mPixelShaderKey, + binding - GL_COLOR_ATTACHMENT0) + : 0; + mPixelShaderOutputLayoutCache.insert(mPixelShaderOutputLayoutCache.end(), maxIndex + 1, + binding); + } + else + { + mPixelShaderOutputLayoutCache.push_back(GL_NONE); + } + } + + updateCachedPixelExecutableIndex(); +} + +void ProgramD3D::updateCachedComputeImage2DBindLayout(const gl::Context *context) +{ + const auto &glState = context->getState(); + for (auto &image2DBindLayout : mImage2DBindLayoutCache[gl::ShaderType::Compute]) + { + const gl::ImageUnit &imageUnit = glState.getImageUnit(image2DBindLayout.first); + if (imageUnit.texture.get()) + { + image2DBindLayout.second = imageUnit.texture->getType(); + } + else + { + image2DBindLayout.second = gl::TextureType::_2D; + } + } + + updateCachedComputeExecutableIndex(); +} + +void ProgramD3D::gatherTransformFeedbackVaryings(const gl::VaryingPacking &varyingPacking, + const BuiltinInfo &builtins) +{ + const std::string &varyingSemantic = + GetVaryingSemantic(mRenderer->getMajorShaderModel(), usesPointSize()); + + // Gather the linked varyings that are used for transform feedback, they should all exist. + mStreamOutVaryings.clear(); + + const auto &tfVaryingNames = mState.getTransformFeedbackVaryingNames(); + for (unsigned int outputSlot = 0; outputSlot < static_cast(tfVaryingNames.size()); + ++outputSlot) + { + const auto &tfVaryingName = tfVaryingNames[outputSlot]; + if (tfVaryingName == "gl_Position") + { + if (builtins.glPosition.enabled) + { + mStreamOutVaryings.emplace_back(builtins.glPosition.semantic, + builtins.glPosition.index, 4, outputSlot); + } + } + else if (tfVaryingName == "gl_FragCoord") + { + if (builtins.glFragCoord.enabled) + { + mStreamOutVaryings.emplace_back(builtins.glFragCoord.semantic, + builtins.glFragCoord.index, 4, outputSlot); + } + } + else if (tfVaryingName == "gl_PointSize") + { + if (builtins.glPointSize.enabled) + { + mStreamOutVaryings.emplace_back("PSIZE", 0, 1, outputSlot); + } + } + else + { + const auto ®isterInfos = varyingPacking.getRegisterList(); + for (GLuint registerIndex = 0u; registerIndex < registerInfos.size(); ++registerIndex) + { + const auto ®isterInfo = registerInfos[registerIndex]; + const auto &varying = registerInfo.packedVarying->varying(); + GLenum transposedType = gl::TransposeMatrixType(varying.type); + int componentCount = gl::VariableColumnCount(transposedType); + ASSERT(!varying.isBuiltIn() && !varying.isStruct()); + + // There can be more than one register assigned to a particular varying, and each + // register needs its own stream out entry. + if (registerInfo.tfVaryingName() == tfVaryingName) + { + mStreamOutVaryings.emplace_back(varyingSemantic, registerIndex, componentCount, + outputSlot); + } + } + } + } +} + +D3DUniform *ProgramD3D::getD3DUniformFromLocation(GLint location) +{ + return mD3DUniforms[mState.getUniformLocations()[location].index]; +} + +const D3DUniform *ProgramD3D::getD3DUniformFromLocation(GLint location) const +{ + return mD3DUniforms[mState.getUniformLocations()[location].index]; +} + +bool ProgramD3D::hasVertexExecutableForCachedInputLayout() +{ + return mCachedVertexExecutableIndex.valid(); +} + +bool ProgramD3D::hasGeometryExecutableForPrimitiveType(const gl::State &state, + gl::PrimitiveMode drawMode) +{ + if (!usesGeometryShader(state, drawMode)) + { + // No shader necessary mean we have the required (null) executable. + return true; + } + + gl::PrimitiveMode geometryShaderType = GetGeometryShaderTypeFromDrawMode(drawMode); + return mGeometryExecutables[geometryShaderType].get() != nullptr; +} + +bool ProgramD3D::hasPixelExecutableForCachedOutputLayout() +{ + return mCachedPixelExecutableIndex.valid(); +} + +bool ProgramD3D::hasComputeExecutableForCachedImage2DBindLayout() +{ + return mCachedComputeExecutableIndex.valid(); +} + +template +void ProgramD3D::getUniformInternal(GLint location, DestT *dataOut) const +{ + const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location]; + const gl::LinkedUniform &uniform = mState.getUniforms()[locationInfo.index]; + + const D3DUniform *targetUniform = getD3DUniformFromLocation(location); + const uint8_t *srcPointer = targetUniform->getDataPtrToElement(locationInfo.arrayIndex); + + if (gl::IsMatrixType(uniform.type)) + { + GetMatrixUniform(uniform.type, dataOut, reinterpret_cast(srcPointer), true); + } + else + { + memcpy(dataOut, srcPointer, uniform.getElementSize()); + } +} + +void ProgramD3D::getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const +{ + getUniformInternal(location, params); +} + +void ProgramD3D::getUniformiv(const gl::Context *context, GLint location, GLint *params) const +{ + getUniformInternal(location, params); +} + +void ProgramD3D::getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const +{ + getUniformInternal(location, params); +} + +void ProgramD3D::updateCachedVertexExecutableIndex() +{ + mCachedVertexExecutableIndex.reset(); + for (size_t executableIndex = 0; executableIndex < mVertexExecutables.size(); executableIndex++) + { + if (mVertexExecutables[executableIndex]->matchesSignature(mCachedVertexSignature)) + { + mCachedVertexExecutableIndex = executableIndex; + break; + } + } +} + +void ProgramD3D::updateCachedPixelExecutableIndex() +{ + mCachedPixelExecutableIndex.reset(); + for (size_t executableIndex = 0; executableIndex < mPixelExecutables.size(); executableIndex++) + { + if (mPixelExecutables[executableIndex]->matchesSignature(mPixelShaderOutputLayoutCache)) + { + mCachedPixelExecutableIndex = executableIndex; + break; + } + } +} + +void ProgramD3D::updateCachedComputeExecutableIndex() +{ + mCachedComputeExecutableIndex.reset(); + for (size_t executableIndex = 0; executableIndex < mComputeExecutables.size(); + executableIndex++) + { + if (mComputeExecutables[executableIndex]->matchesSignature( + mImage2DBindLayoutCache[gl::ShaderType::Compute])) + { + mCachedComputeExecutableIndex = executableIndex; + break; + } + } +} + +void ProgramD3D::linkResources(const gl::Context *context, + const gl::ProgramLinkedResources &resources) +{ + HLSLBlockLayoutEncoderFactory hlslEncoderFactory; + gl::ProgramLinkedResourcesLinker linker(&hlslEncoderFactory); + + linker.linkResources(context, mState, resources); + + initializeUniformBlocks(); + initializeShaderStorageBlocks(context); +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/ProgramD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ProgramD3D.h new file mode 100644 index 0000000000..baa77fcb79 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ProgramD3D.h @@ -0,0 +1,613 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ProgramD3D.h: Defines the rx::ProgramD3D class which implements rx::ProgramImpl. + +#ifndef LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_ +#define LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_ + +#include +#include + +#include "compiler/translator/blocklayoutHLSL.h" +#include "libANGLE/Constants.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/ProgramImpl.h" +#include "libANGLE/renderer/d3d/DynamicHLSL.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" +#include "platform/FeaturesD3D_autogen.h" + +namespace rx +{ +class RendererD3D; +class UniformStorageD3D; +class ShaderExecutableD3D; + +#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL) +// WARNING: D3DCOMPILE_OPTIMIZATION_LEVEL3 may lead to a DX9 shader compiler hang. +// It should only be used selectively to work around specific bugs. +# define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL1 +#endif + +enum class HLSLRegisterType : uint8_t +{ + None = 0, + Texture = 1, + UnorderedAccessView = 2 +}; + +// Helper struct representing a single shader uniform +// TODO(jmadill): Make uniform blocks shared between all programs, so we don't need separate +// register indices. +struct D3DUniform : private angle::NonCopyable +{ + D3DUniform(GLenum type, + HLSLRegisterType reg, + const std::string &nameIn, + const std::vector &arraySizesIn, + bool defaultBlock); + ~D3DUniform(); + + bool isSampler() const; + bool isImage() const; + bool isImage2D() const; + bool isArray() const { return !arraySizes.empty(); } + unsigned int getArraySizeProduct() const; + bool isReferencedByShader(gl::ShaderType shaderType) const; + + const uint8_t *firstNonNullData() const; + const uint8_t *getDataPtrToElement(size_t elementIndex) const; + + // Duplicated from the GL layer + const gl::UniformTypeInfo &typeInfo; + std::string name; // Names of arrays don't include [0], unlike at the GL layer. + std::vector arraySizes; + + // Pointer to a system copies of the data. Separate pointers for each uniform storage type. + gl::ShaderMap mShaderData; + + // Register information. + HLSLRegisterType regType; + gl::ShaderMap mShaderRegisterIndexes; + unsigned int registerCount; + + // Register "elements" are used for uniform structs in ES3, to appropriately identify single + // uniforms + // inside aggregate types, which are packed according C-like structure rules. + unsigned int registerElement; + + // Special buffer for sampler values. + std::vector mSamplerData; +}; + +struct D3DInterfaceBlock +{ + D3DInterfaceBlock(); + D3DInterfaceBlock(const D3DInterfaceBlock &other); + + bool activeInShader(gl::ShaderType shaderType) const + { + return mShaderRegisterIndexes[shaderType] != GL_INVALID_INDEX; + } + + gl::ShaderMap mShaderRegisterIndexes; +}; + +struct D3DUniformBlock : D3DInterfaceBlock +{ + D3DUniformBlock(); + D3DUniformBlock(const D3DUniformBlock &other); + + gl::ShaderMap mUseStructuredBuffers; + gl::ShaderMap mByteWidths; + gl::ShaderMap mStructureByteStrides; +}; + +struct ShaderStorageBlock +{ + std::string name; + unsigned int arraySize = 0; + unsigned int registerIndex = 0; +}; + +struct D3DUBOCache +{ + unsigned int registerIndex; + int binding; +}; + +struct D3DUBOCacheUseSB : D3DUBOCache +{ + unsigned int byteWidth; + unsigned int structureByteStride; +}; + +struct D3DVarying final +{ + D3DVarying(); + D3DVarying(const std::string &semanticNameIn, + unsigned int semanticIndexIn, + unsigned int componentCountIn, + unsigned int outputSlotIn); + + D3DVarying(const D3DVarying &) = default; + D3DVarying &operator=(const D3DVarying &) = default; + + std::string semanticName; + unsigned int semanticIndex; + unsigned int componentCount; + unsigned int outputSlot; +}; + +class ProgramD3DMetadata final : angle::NonCopyable +{ + public: + ProgramD3DMetadata(RendererD3D *renderer, + const gl::ShaderMap &attachedShaders, + EGLenum clientType); + ~ProgramD3DMetadata(); + + int getRendererMajorShaderModel() const; + bool usesBroadcast(const gl::State &data) const; + bool usesSecondaryColor() const; + bool usesFragDepth() const; + bool usesPointCoord() const; + bool usesFragCoord() const; + bool usesPointSize() const; + bool usesInsertedPointCoordValue() const; + bool usesViewScale() const; + bool hasANGLEMultiviewEnabled() const; + bool usesVertexID() const; + bool usesViewID() const; + bool canSelectViewInVertexShader() const; + bool addsPointCoordToVertexShader() const; + bool usesTransformFeedbackGLPosition() const; + bool usesSystemValuePointSize() const; + bool usesMultipleFragmentOuts() const; + bool usesCustomOutVars() const; + const ShaderD3D *getFragmentShader() const; + + private: + const int mRendererMajorShaderModel; + const std::string mShaderModelSuffix; + const bool mUsesInstancedPointSpriteEmulation; + const bool mUsesViewScale; + const bool mCanSelectViewInVertexShader; + const gl::ShaderMap mAttachedShaders; + const EGLenum mClientType; +}; + +using D3DUniformMap = std::map; + +class ProgramD3D : public ProgramImpl +{ + public: + ProgramD3D(const gl::ProgramState &data, RendererD3D *renderer); + ~ProgramD3D() override; + + const std::vector &getPixelShaderKey() { return mPixelShaderKey; } + + GLint getSamplerMapping(gl::ShaderType type, + unsigned int samplerIndex, + const gl::Caps &caps) const; + gl::TextureType getSamplerTextureType(gl::ShaderType type, unsigned int samplerIndex) const; + gl::RangeUI getUsedSamplerRange(gl::ShaderType type) const; + + enum SamplerMapping + { + WasDirty, + WasClean, + }; + + SamplerMapping updateSamplerMapping(); + + GLint getImageMapping(gl::ShaderType type, + unsigned int imageIndex, + bool readonly, + const gl::Caps &caps) const; + gl::RangeUI getUsedImageRange(gl::ShaderType type, bool readonly) const; + + bool usesPointSize() const { return mUsesPointSize; } + bool usesPointSpriteEmulation() const; + bool usesGeometryShader(const gl::State &state, gl::PrimitiveMode drawMode) const; + bool usesGeometryShaderForPointSpriteEmulation() const; + bool usesGetDimensionsIgnoresBaseLevel() const; + bool usesInstancedPointSpriteEmulation() const; + + std::unique_ptr load(const gl::Context *context, + gl::BinaryInputStream *stream, + gl::InfoLog &infoLog) override; + void save(const gl::Context *context, gl::BinaryOutputStream *stream) override; + void setBinaryRetrievableHint(bool retrievable) override; + void setSeparable(bool separable) override; + + angle::Result getVertexExecutableForCachedInputLayout(d3d::Context *context, + ShaderExecutableD3D **outExectuable, + gl::InfoLog *infoLog); + angle::Result getGeometryExecutableForPrimitiveType(d3d::Context *errContext, + const gl::State &state, + gl::PrimitiveMode drawMode, + ShaderExecutableD3D **outExecutable, + gl::InfoLog *infoLog); + angle::Result getPixelExecutableForCachedOutputLayout(d3d::Context *context, + ShaderExecutableD3D **outExectuable, + gl::InfoLog *infoLog); + angle::Result getComputeExecutableForImage2DBindLayout(const gl::Context *glContext, + d3d::Context *context, + ShaderExecutableD3D **outExecutable, + gl::InfoLog *infoLog); + std::unique_ptr link(const gl::Context *context, + const gl::ProgramLinkedResources &resources, + gl::InfoLog &infoLog, + const gl::ProgramMergedVaryings &mergedVaryings) override; + GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override; + + void updateUniformBufferCache(const gl::Caps &caps); + + unsigned int getAtomicCounterBufferRegisterIndex(GLuint binding, + gl::ShaderType shaderType) const; + + unsigned int getShaderStorageBufferRegisterIndex(GLuint blockIndex, + gl::ShaderType shaderType) const; + const std::vector &getShaderUniformBufferCache(gl::ShaderType shaderType) const; + const std::vector &getShaderUniformBufferCacheUseSB( + gl::ShaderType shaderType) const; + + void dirtyAllUniforms(); + + void setUniform1fv(GLint location, GLsizei count, const GLfloat *v) override; + void setUniform2fv(GLint location, GLsizei count, const GLfloat *v) override; + void setUniform3fv(GLint location, GLsizei count, const GLfloat *v) override; + void setUniform4fv(GLint location, GLsizei count, const GLfloat *v) override; + void setUniform1iv(GLint location, GLsizei count, const GLint *v) override; + void setUniform2iv(GLint location, GLsizei count, const GLint *v) override; + void setUniform3iv(GLint location, GLsizei count, const GLint *v) override; + void setUniform4iv(GLint location, GLsizei count, const GLint *v) override; + void setUniform1uiv(GLint location, GLsizei count, const GLuint *v) override; + void setUniform2uiv(GLint location, GLsizei count, const GLuint *v) override; + void setUniform3uiv(GLint location, GLsizei count, const GLuint *v) override; + void setUniform4uiv(GLint location, GLsizei count, const GLuint *v) override; + void setUniformMatrix2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) override; + void setUniformMatrix3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) override; + void setUniformMatrix4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) override; + void setUniformMatrix2x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) override; + void setUniformMatrix3x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) override; + void setUniformMatrix2x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) override; + void setUniformMatrix4x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) override; + void setUniformMatrix3x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) override; + void setUniformMatrix4x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) override; + + void getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const override; + void getUniformiv(const gl::Context *context, GLint location, GLint *params) const override; + void getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const override; + + UniformStorageD3D *getShaderUniformStorage(gl::ShaderType shaderType) const + { + return mShaderUniformStorages[shaderType].get(); + } + + unsigned int getSerial() const; + + const AttribIndexArray &getAttribLocationToD3DSemantics() const + { + return mAttribLocationToD3DSemantic; + } + + void updateCachedInputLayout(Serial associatedSerial, const gl::State &state); + void updateCachedOutputLayout(const gl::Context *context, const gl::Framebuffer *framebuffer); + void updateCachedComputeImage2DBindLayout(const gl::Context *context); + + bool isSamplerMappingDirty() { return mDirtySamplerMapping; } + + // Checks if we need to recompile certain shaders. + bool hasVertexExecutableForCachedInputLayout(); + bool hasGeometryExecutableForPrimitiveType(const gl::State &state, gl::PrimitiveMode drawMode); + bool hasPixelExecutableForCachedOutputLayout(); + bool hasComputeExecutableForCachedImage2DBindLayout(); + + bool anyShaderUniformsDirty() const { return mShaderUniformsDirty.any(); } + + bool areShaderUniformsDirty(gl::ShaderType shaderType) const + { + return mShaderUniformsDirty[shaderType]; + } + const std::vector &getD3DUniforms() const { return mD3DUniforms; } + void markUniformsClean(); + + const gl::ProgramState &getState() const { return mState; } + + bool hasShaderStage(gl::ShaderType shaderType) const + { + return mState.getExecutable().getLinkedShaderStages()[shaderType]; + } + + void assignImage2DRegisters(gl::ShaderType shaderType, + unsigned int startImageIndex, + int startLogicalImageUnit, + bool readonly); + bool hasNamedUniform(const std::string &name); + + bool usesVertexID() const { return mUsesVertexID; } + + private: + // These forward-declared tasks are used for multi-thread shader compiles. + class GetExecutableTask; + class GetVertexExecutableTask; + class GetPixelExecutableTask; + class GetGeometryExecutableTask; + class GetComputeExecutableTask; + class GraphicsProgramLinkEvent; + class ComputeProgramLinkEvent; + + class LoadBinaryTask; + class LoadBinaryLinkEvent; + + class VertexExecutable + { + public: + enum HLSLAttribType + { + FLOAT, + UNSIGNED_INT, + SIGNED_INT, + }; + + typedef std::vector Signature; + + VertexExecutable(const gl::InputLayout &inputLayout, + const Signature &signature, + ShaderExecutableD3D *shaderExecutable); + ~VertexExecutable(); + + bool matchesSignature(const Signature &signature) const; + static void getSignature(RendererD3D *renderer, + const gl::InputLayout &inputLayout, + Signature *signatureOut); + + const gl::InputLayout &inputs() const { return mInputs; } + const Signature &signature() const { return mSignature; } + ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable; } + + private: + static HLSLAttribType GetAttribType(GLenum type); + + gl::InputLayout mInputs; + Signature mSignature; + ShaderExecutableD3D *mShaderExecutable; + }; + + class PixelExecutable + { + public: + PixelExecutable(const std::vector &outputSignature, + ShaderExecutableD3D *shaderExecutable); + ~PixelExecutable(); + + bool matchesSignature(const std::vector &signature) const + { + return mOutputSignature == signature; + } + + const std::vector &outputSignature() const { return mOutputSignature; } + ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable; } + + private: + std::vector mOutputSignature; + ShaderExecutableD3D *mShaderExecutable; + }; + + class ComputeExecutable + { + public: + ComputeExecutable(const gl::ImageUnitTextureTypeMap &signature, + std::unique_ptr shaderExecutable); + ~ComputeExecutable(); + + bool matchesSignature(const gl::ImageUnitTextureTypeMap &signature) const + { + return mSignature == signature; + } + + const gl::ImageUnitTextureTypeMap &signature() const { return mSignature; } + ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable.get(); } + + private: + gl::ImageUnitTextureTypeMap mSignature; + std::unique_ptr mShaderExecutable; + }; + + struct Sampler + { + Sampler(); + + bool active; + GLint logicalTextureUnit; + gl::TextureType textureType; + }; + + struct Image + { + Image(); + bool active; + GLint logicalImageUnit; + }; + + void initializeUniformStorage(const gl::ShaderBitSet &availableShaderStages); + + void defineUniformsAndAssignRegisters(const gl::Context *context); + void defineUniformBase(const gl::Shader *shader, + const sh::ShaderVariable &uniform, + D3DUniformMap *uniformMap); + void assignAllSamplerRegisters(); + void assignSamplerRegisters(size_t uniformIndex); + + static void AssignSamplers(unsigned int startSamplerIndex, + const gl::UniformTypeInfo &typeInfo, + unsigned int samplerCount, + std::vector &outSamplers, + gl::RangeUI *outUsedRange); + + void assignAllImageRegisters(); + void assignAllAtomicCounterRegisters(); + void assignImageRegisters(size_t uniformIndex); + static void AssignImages(unsigned int startImageIndex, + int startLogicalImageUnit, + unsigned int imageCount, + std::vector &outImages, + gl::RangeUI *outUsedRange); + + template + void getUniformInternal(GLint location, DestT *dataOut) const; + + template + void setUniformImpl(D3DUniform *targetUniform, + const gl::VariableLocation &locationInfo, + GLsizei count, + const T *v, + uint8_t *targetData, + GLenum uniformType); + + template + void setUniformInternal(GLint location, GLsizei count, const T *v, GLenum uniformType); + + template + void setUniformMatrixfvInternal(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + + std::unique_ptr compileProgramExecutables(const gl::Context *context, + gl::InfoLog &infoLog); + std::unique_ptr compileComputeExecutable(const gl::Context *context, + gl::InfoLog &infoLog); + + angle::Result loadBinaryShaderExecutables(d3d::Context *contextD3D, + gl::BinaryInputStream *stream, + gl::InfoLog &infoLog); + + void gatherTransformFeedbackVaryings(const gl::VaryingPacking &varyings, + const BuiltinInfo &builtins); + D3DUniform *getD3DUniformFromLocation(GLint location); + const D3DUniform *getD3DUniformFromLocation(GLint location) const; + + void initAttribLocationsToD3DSemantic(const gl::Context *context); + + void reset(); + void initializeUniformBlocks(); + void initializeShaderStorageBlocks(const gl::Context *context); + + void updateCachedInputLayoutFromShader(const gl::Context *context); + void updateCachedOutputLayoutFromShader(); + void updateCachedImage2DBindLayoutFromShader(gl::ShaderType shaderType); + void updateCachedVertexExecutableIndex(); + void updateCachedPixelExecutableIndex(); + void updateCachedComputeExecutableIndex(); + + void linkResources(const gl::Context *context, const gl::ProgramLinkedResources &resources); + + RendererD3D *mRenderer; + DynamicHLSL *mDynamicHLSL; + + std::vector> mVertexExecutables; + std::vector> mPixelExecutables; + angle::PackedEnumMap> + mGeometryExecutables; + std::vector> mComputeExecutables; + + gl::ShaderMap mShaderHLSL; + gl::ShaderMap mShaderWorkarounds; + + bool mUsesFragDepth; + bool mHasANGLEMultiviewEnabled; + bool mUsesVertexID; + bool mUsesViewID; + std::vector mPixelShaderKey; + + // Common code for all dynamic geometry shaders. Consists mainly of the GS input and output + // structures, built from the linked varying info. We store the string itself instead of the + // packed varyings for simplicity. + std::string mGeometryShaderPreamble; + + bool mUsesPointSize; + bool mUsesFlatInterpolation; + + gl::ShaderMap> mShaderUniformStorages; + + gl::ShaderMap> mShaderSamplers; + gl::ShaderMap mUsedShaderSamplerRanges; + bool mDirtySamplerMapping; + + gl::ShaderMap> mImages; + gl::ShaderMap> mReadonlyImages; + gl::ShaderMap mUsedImageRange; + gl::ShaderMap mUsedReadonlyImageRange; + gl::ShaderMap mUsedAtomicCounterRange; + + // Cache for pixel shader output layout to save reallocations. + std::vector mPixelShaderOutputLayoutCache; + Optional mCachedPixelExecutableIndex; + + AttribIndexArray mAttribLocationToD3DSemantic; + + unsigned int mSerial; + + gl::ShaderMap> mShaderUBOCaches; + gl::ShaderMap> mShaderUBOCachesUseSB; + VertexExecutable::Signature mCachedVertexSignature; + gl::InputLayout mCachedInputLayout; + Optional mCachedVertexExecutableIndex; + + std::vector mStreamOutVaryings; + std::vector mD3DUniforms; + std::map mImageBindingMap; + std::map mAtomicBindingMap; + std::vector mD3DUniformBlocks; + std::vector mD3DShaderStorageBlocks; + gl::ShaderMap> mShaderStorageBlocks; + std::array + mComputeAtomicCounterBufferRegisterIndices; + + gl::ShaderMap> mImage2DUniforms; + gl::ShaderMap mImage2DBindLayoutCache; + Optional mCachedComputeExecutableIndex; + + gl::ShaderBitSet mShaderUniformsDirty; + + static unsigned int issueSerial(); + static unsigned int mCurrentSerial; + + Serial mCurrentVertexArrayStateSerial; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderTargetD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderTargetD3D.cpp new file mode 100644 index 0000000000..4529a9d84e --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderTargetD3D.cpp @@ -0,0 +1,31 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// RenderTargetD3D.cpp: Implements serial handling for rx::RenderTargetD3D + +#include "libANGLE/renderer/d3d/RenderTargetD3D.h" + +namespace rx +{ +unsigned int RenderTargetD3D::mCurrentSerial = 1; + +RenderTargetD3D::RenderTargetD3D() : mSerial(issueSerials(1)) {} + +RenderTargetD3D::~RenderTargetD3D() {} + +unsigned int RenderTargetD3D::getSerial() const +{ + return mSerial; +} + +unsigned int RenderTargetD3D::issueSerials(unsigned int count) +{ + unsigned int firstSerial = mCurrentSerial; + mCurrentSerial += count; + return firstSerial; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderTargetD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderTargetD3D.h new file mode 100644 index 0000000000..b5bed63bcd --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderTargetD3D.h @@ -0,0 +1,44 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// RenderTargetD3D.h: Defines an abstract wrapper class to manage IDirect3DSurface9 +// and ID3D11View objects belonging to renderbuffers and renderable textures. + +#ifndef LIBANGLE_RENDERER_D3D_RENDERTARGETD3D_H_ +#define LIBANGLE_RENDERER_D3D_RENDERTARGETD3D_H_ + +#include "common/angleutils.h" +#include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/angletypes.h" + +namespace rx +{ + +class RenderTargetD3D : public FramebufferAttachmentRenderTarget +{ + public: + RenderTargetD3D(); + ~RenderTargetD3D() override; + + virtual GLsizei getWidth() const = 0; + virtual GLsizei getHeight() const = 0; + virtual GLsizei getDepth() const = 0; + virtual GLenum getInternalFormat() const = 0; + virtual GLsizei getSamples() const = 0; + gl::Extents getExtents() const { return gl::Extents(getWidth(), getHeight(), getDepth()); } + bool isMultisampled() const { return getSamples() > 0; } + + virtual unsigned int getSerial() const; + static unsigned int issueSerials(unsigned int count); + + private: + const unsigned int mSerial; + static unsigned int mCurrentSerial; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_RENDERTARGETD3D_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp new file mode 100644 index 0000000000..9114b88f3f --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp @@ -0,0 +1,126 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// RenderbufferD3d.cpp: Implements the RenderbufferD3D class, a specialization of RenderbufferImpl + +#include "libANGLE/renderer/d3d/RenderbufferD3D.h" + +#include "libANGLE/Context.h" +#include "libANGLE/Image.h" +#include "libANGLE/renderer/d3d/ContextD3D.h" +#include "libANGLE/renderer/d3d/EGLImageD3D.h" +#include "libANGLE/renderer/d3d/RenderTargetD3D.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" + +namespace rx +{ +RenderbufferD3D::RenderbufferD3D(const gl::RenderbufferState &state, RendererD3D *renderer) + : RenderbufferImpl(state), mRenderer(renderer), mRenderTarget(nullptr), mImage(nullptr) +{} + +RenderbufferD3D::~RenderbufferD3D() +{ + SafeDelete(mRenderTarget); + mImage = nullptr; +} + +void RenderbufferD3D::onDestroy(const gl::Context *context) +{ + SafeDelete(mRenderTarget); +} + +angle::Result RenderbufferD3D::setStorage(const gl::Context *context, + GLenum internalformat, + GLsizei width, + GLsizei height) +{ + return setStorageMultisample(context, 0, internalformat, width, height, + gl::MultisamplingMode::Regular); +} + +angle::Result RenderbufferD3D::setStorageMultisample(const gl::Context *context, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + gl::MultisamplingMode mode) +{ + // TODO: Correctly differentiate between normal multisampling and render to texture. In the + // latter case, the renderbuffer must be automatically resolved when rendering is broken and + // operations performed on it (such as blit, copy etc) should use the resolved image. + // http://anglebug.com/3107. + + // If the renderbuffer parameters are queried, the calling function + // will expect one of the valid renderbuffer formats for use in + // glRenderbufferStorage, but we should create depth and stencil buffers + // as DEPTH24_STENCIL8 + GLenum creationFormat = internalformat; + if (internalformat == GL_DEPTH_COMPONENT16 || internalformat == GL_STENCIL_INDEX8) + { + creationFormat = GL_DEPTH24_STENCIL8_OES; + } + + // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create + // the specified storage. + // Because ES 3.0 already knows the exact number of supported samples, it would already have + // been validated and generated GL_INVALID_VALUE. + const gl::TextureCaps &formatCaps = mRenderer->getNativeTextureCaps().get(creationFormat); + ANGLE_CHECK_GL_ALLOC(GetImplAs(context), + static_cast(samples) <= formatCaps.getMaxSamples()); + + RenderTargetD3D *newRT = nullptr; + ANGLE_TRY( + mRenderer->createRenderTarget(context, width, height, creationFormat, samples, &newRT)); + + SafeDelete(mRenderTarget); + mImage = nullptr; + mRenderTarget = newRT; + + return angle::Result::Continue; +} + +angle::Result RenderbufferD3D::setStorageEGLImageTarget(const gl::Context *context, + egl::Image *image) +{ + mImage = GetImplAs(image); + SafeDelete(mRenderTarget); + + return angle::Result::Continue; +} + +angle::Result RenderbufferD3D::getRenderTarget(const gl::Context *context, + RenderTargetD3D **outRenderTarget) +{ + if (mImage) + { + return mImage->getRenderTarget(context, outRenderTarget); + } + else + { + *outRenderTarget = mRenderTarget; + return angle::Result::Continue; + } +} + +angle::Result RenderbufferD3D::getAttachmentRenderTarget(const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex, + GLsizei samples, + FramebufferAttachmentRenderTarget **rtOut) +{ + return getRenderTarget(context, reinterpret_cast(rtOut)); +} + +angle::Result RenderbufferD3D::initializeContents(const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex) +{ + RenderTargetD3D *renderTarget = nullptr; + ANGLE_TRY(getRenderTarget(context, &renderTarget)); + return mRenderer->initRenderTarget(context, renderTarget); +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderbufferD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderbufferD3D.h new file mode 100644 index 0000000000..7b48c48073 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderbufferD3D.h @@ -0,0 +1,63 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// RenderbufferD3d.h: Defines the RenderbufferD3D class which implements RenderbufferImpl. + +#ifndef LIBANGLE_RENDERER_D3D_RENDERBUFFERD3D_H_ +#define LIBANGLE_RENDERER_D3D_RENDERBUFFERD3D_H_ + +#include "angle_gl.h" + +#include "common/angleutils.h" +#include "libANGLE/renderer/RenderbufferImpl.h" + +namespace rx +{ +class EGLImageD3D; +class RendererD3D; +class RenderTargetD3D; +class SwapChainD3D; + +class RenderbufferD3D : public RenderbufferImpl +{ + public: + RenderbufferD3D(const gl::RenderbufferState &state, RendererD3D *renderer); + ~RenderbufferD3D() override; + + void onDestroy(const gl::Context *context) override; + + angle::Result setStorage(const gl::Context *context, + GLenum internalformat, + GLsizei width, + GLsizei height) override; + angle::Result setStorageMultisample(const gl::Context *context, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + gl::MultisamplingMode mode) override; + angle::Result setStorageEGLImageTarget(const gl::Context *context, egl::Image *image) override; + + angle::Result getRenderTarget(const gl::Context *context, RenderTargetD3D **outRenderTarget); + angle::Result getAttachmentRenderTarget(const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex, + GLsizei samples, + FramebufferAttachmentRenderTarget **rtOut) override; + + angle::Result initializeContents(const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex) override; + + private: + RendererD3D *mRenderer; + RenderTargetD3D *mRenderTarget; + EGLImageD3D *mImage; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_RENDERBUFFERD3D_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/RendererD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/RendererD3D.cpp new file mode 100644 index 0000000000..39e6e536dd --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/RendererD3D.cpp @@ -0,0 +1,247 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// RendererD3D.cpp: Implementation of the base D3D Renderer. + +#include "libANGLE/renderer/d3d/RendererD3D.h" + +#include "common/MemoryBuffer.h" +#include "common/debug.h" +#include "common/utilities.h" +#include "libANGLE/Context.h" +#include "libANGLE/Display.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/ImageIndex.h" +#include "libANGLE/ResourceManager.h" +#include "libANGLE/State.h" +#include "libANGLE/VertexArray.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/ContextImpl.h" +#include "libANGLE/renderer/TextureImpl.h" +#include "libANGLE/renderer/d3d/BufferD3D.h" +#include "libANGLE/renderer/d3d/DeviceD3D.h" +#include "libANGLE/renderer/d3d/DisplayD3D.h" +#include "libANGLE/renderer/d3d/IndexDataManager.h" +#include "libANGLE/renderer/d3d/ProgramD3D.h" +#include "libANGLE/renderer/d3d/SamplerD3D.h" +#include "libANGLE/renderer/d3d/TextureD3D.h" + +namespace rx +{ + +RendererD3D::RendererD3D(egl::Display *display) + : mDisplay(display), + mPresentPathFastEnabled(false), + mCapsInitialized(false), + mFeaturesInitialized(false), + mDisjoint(false), + mDeviceLost(false) +{} + +RendererD3D::~RendererD3D() {} + +bool RendererD3D::skipDraw(const gl::State &glState, gl::PrimitiveMode drawMode) +{ + if (drawMode == gl::PrimitiveMode::Points) + { + bool usesPointSize = GetImplAs(glState.getProgram())->usesPointSize(); + + // ProgramBinary assumes non-point rendering if gl_PointSize isn't written, + // which affects varying interpolation. Since the value of gl_PointSize is + // undefined when not written, just skip drawing to avoid unexpected results. + if (!usesPointSize && !glState.isTransformFeedbackActiveUnpaused()) + { + // Notify developers of risking undefined behavior. + WARN() << "Point rendering without writing to gl_PointSize."; + return true; + } + } + else if (gl::IsTriangleMode(drawMode)) + { + if (glState.getRasterizerState().cullFace && + glState.getRasterizerState().cullMode == gl::CullFaceMode::FrontAndBack) + { + return true; + } + } + + return false; +} + +gl::GraphicsResetStatus RendererD3D::getResetStatus() +{ + if (!mDeviceLost) + { + if (testDeviceLost()) + { + mDeviceLost = true; + notifyDeviceLost(); + return gl::GraphicsResetStatus::UnknownContextReset; + } + return gl::GraphicsResetStatus::NoError; + } + + if (testDeviceResettable()) + { + return gl::GraphicsResetStatus::NoError; + } + + return gl::GraphicsResetStatus::UnknownContextReset; +} + +void RendererD3D::notifyDeviceLost() +{ + mDisplay->notifyDeviceLost(); +} + +void RendererD3D::setGPUDisjoint() +{ + mDisjoint = true; +} + +GLint RendererD3D::getGPUDisjoint() +{ + bool disjoint = mDisjoint; + + // Disjoint flag is cleared when read + mDisjoint = false; + + return disjoint; +} + +GLint64 RendererD3D::getTimestamp() +{ + // D3D has no way to get an actual timestamp reliably so 0 is returned + return 0; +} + +void RendererD3D::ensureCapsInitialized() const +{ + if (!mCapsInitialized) + { + generateCaps(&mNativeCaps, &mNativeTextureCaps, &mNativeExtensions, &mNativeLimitations); + mCapsInitialized = true; + } +} + +const gl::Caps &RendererD3D::getNativeCaps() const +{ + ensureCapsInitialized(); + return mNativeCaps; +} + +const gl::TextureCapsMap &RendererD3D::getNativeTextureCaps() const +{ + ensureCapsInitialized(); + return mNativeTextureCaps; +} + +const gl::Extensions &RendererD3D::getNativeExtensions() const +{ + ensureCapsInitialized(); + return mNativeExtensions; +} + +const gl::Limitations &RendererD3D::getNativeLimitations() const +{ + ensureCapsInitialized(); + return mNativeLimitations; +} + +ShPixelLocalStorageType RendererD3D::getNativePixelLocalStorageType() const +{ + if (!getNativeExtensions().shaderPixelLocalStorageANGLE) + { + return ShPixelLocalStorageType::NotSupported; + } + // Read/write UAVs only support "r32*" images. + return ShPixelLocalStorageType::ImageStoreR32PackedFormats; +} + +Serial RendererD3D::generateSerial() +{ + return mSerialFactory.generate(); +} + +bool InstancedPointSpritesActive(ProgramD3D *programD3D, gl::PrimitiveMode mode) +{ + return programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation() && + mode == gl::PrimitiveMode::Points; +} + +angle::Result RendererD3D::initRenderTarget(const gl::Context *context, + RenderTargetD3D *renderTarget) +{ + return clearRenderTarget(context, renderTarget, gl::ColorF(0, 0, 0, 0), 1, 0); +} + +const angle::FeaturesD3D &RendererD3D::getFeatures() const +{ + if (!mFeaturesInitialized) + { + initializeFeatures(&mFeatures); + mFeaturesInitialized = true; + } + + return mFeatures; +} + +unsigned int GetBlendSampleMask(const gl::State &glState, int samples) +{ + unsigned int mask = 0; + if (glState.isSampleCoverageEnabled()) + { + GLfloat coverageValue = glState.getSampleCoverageValue(); + if (coverageValue != 0) + { + float threshold = 0.5f; + + for (int i = 0; i < samples; ++i) + { + mask <<= 1; + + if ((i + 1) * coverageValue >= threshold) + { + threshold += 1.0f; + mask |= 1; + } + } + } + + bool coverageInvert = glState.getSampleCoverageInvert(); + if (coverageInvert) + { + mask = ~mask; + } + } + else + { + mask = 0xFFFFFFFF; + } + + if (glState.isSampleMaskEnabled()) + { + mask &= glState.getSampleMaskWord(0); + } + + return mask; +} + +GLenum DefaultGLErrorCode(HRESULT hr) +{ + switch (hr) + { +#ifdef ANGLE_ENABLE_D3D9 + case D3DERR_OUTOFVIDEOMEMORY: +#endif + case E_OUTOFMEMORY: + return GL_OUT_OF_MEMORY; + default: + return GL_INVALID_OPERATION; + } +} +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/RendererD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/RendererD3D.h new file mode 100644 index 0000000000..3846e1eb2a --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/RendererD3D.h @@ -0,0 +1,489 @@ + +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// RendererD3D.h: Defines a back-end specific class for the DirectX renderer. + +#ifndef LIBANGLE_RENDERER_D3D_RENDERERD3D_H_ +#define LIBANGLE_RENDERER_D3D_RENDERERD3D_H_ + +#include + +#include "common/Color.h" +#include "common/MemoryBuffer.h" +#include "common/debug.h" +#include "libANGLE/Device.h" +#include "libANGLE/State.h" +#include "libANGLE/Version.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/ShaderD3D.h" +#include "libANGLE/renderer/d3d/VertexDataManager.h" +#include "libANGLE/renderer/d3d/formatutilsD3D.h" +#include "libANGLE/renderer/renderer_utils.h" +#include "libANGLE/renderer/serial_utils.h" +#include "platform/FeaturesD3D_autogen.h" + +namespace egl +{ +class ConfigSet; +} + +namespace gl +{ +class ErrorSet; +class FramebufferState; +class InfoLog; +class Texture; +struct LinkedVarying; +} // namespace gl + +namespace rx +{ +class ContextImpl; +struct D3DUniform; +struct D3DVarying; +class DeviceD3D; +class EGLImageD3D; +class FramebufferImpl; +class ImageD3D; +class IndexBuffer; +class NativeWindowD3D; +class ProgramD3D; +class RenderTargetD3D; +class ShaderExecutableD3D; +class SwapChainD3D; +class TextureStorage; +struct TranslatedIndexData; +class UniformStorageD3D; +class VertexBuffer; + +struct DeviceIdentifier +{ + UINT VendorId; + UINT DeviceId; + UINT SubSysId; + UINT Revision; + UINT FeatureLevel; +}; + +enum RendererClass +{ + RENDERER_D3D11, + RENDERER_D3D9 +}; + +struct BindFlags +{ + bool renderTarget = false; + bool unorderedAccess = false; + static BindFlags RenderTarget() + { + BindFlags flags; + flags.renderTarget = true; + return flags; + } + static BindFlags UnorderedAccess() + { + BindFlags flags; + flags.unorderedAccess = true; + return flags; + } +}; + +// A d3d::Context wraps error handling. +namespace d3d +{ +class Context : angle::NonCopyable +{ + public: + Context() {} + virtual ~Context() {} + + virtual void handleResult(HRESULT hr, + const char *message, + const char *file, + const char *function, + unsigned int line) = 0; +}; +} // namespace d3d + +// ANGLE_TRY for HRESULT errors. +#define ANGLE_TRY_HR(CONTEXT, EXPR, MESSAGE) \ + do \ + { \ + auto ANGLE_LOCAL_VAR = (EXPR); \ + if (ANGLE_UNLIKELY(FAILED(ANGLE_LOCAL_VAR))) \ + { \ + CONTEXT->handleResult(ANGLE_LOCAL_VAR, MESSAGE, __FILE__, ANGLE_FUNCTION, __LINE__); \ + return angle::Result::Stop; \ + } \ + } while (0) + +#define ANGLE_CHECK_HR(CONTEXT, EXPR, MESSAGE, ERROR) \ + do \ + { \ + if (ANGLE_UNLIKELY(!(EXPR))) \ + { \ + CONTEXT->handleResult(ERROR, MESSAGE, __FILE__, ANGLE_FUNCTION, __LINE__); \ + return angle::Result::Stop; \ + } \ + } while (0) + +#define ANGLE_HR_UNREACHABLE(context) \ + UNREACHABLE(); \ + ANGLE_CHECK_HR(context, false, "Unreachble code reached.", E_FAIL) + +// Check if the device is lost every 10 failures to get the query data +constexpr unsigned int kPollingD3DDeviceLostCheckFrequency = 10; + +// Useful for unit testing +class BufferFactoryD3D : angle::NonCopyable +{ + public: + BufferFactoryD3D() {} + virtual ~BufferFactoryD3D() {} + + virtual VertexBuffer *createVertexBuffer() = 0; + virtual IndexBuffer *createIndexBuffer() = 0; + + // TODO(jmadill): add VertexFormatCaps + virtual VertexConversionType getVertexConversionType(angle::FormatID vertexFormatID) const = 0; + virtual GLenum getVertexComponentType(angle::FormatID vertexFormatID) const = 0; + + // Warning: you should ensure binding really matches attrib.bindingIndex before using this + // function. + virtual angle::Result getVertexSpaceRequired(const gl::Context *context, + const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + size_t count, + GLsizei instances, + GLuint baseInstance, + unsigned int *bytesRequiredOut) const = 0; +}; + +using AttribIndexArray = gl::AttribArray; + +class RendererD3D : public BufferFactoryD3D +{ + public: + explicit RendererD3D(egl::Display *display); + ~RendererD3D() override; + + virtual egl::Error initialize() = 0; + + virtual egl::ConfigSet generateConfigs() = 0; + virtual void generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const = 0; + + virtual ContextImpl *createContext(const gl::State &state, gl::ErrorSet *errorSet) = 0; + + virtual std::string getRendererDescription() const = 0; + virtual std::string getVendorString() const = 0; + virtual std::string getVersionString(bool includeFullVersion) const = 0; + + virtual int getMinorShaderModel() const = 0; + virtual std::string getShaderModelSuffix() const = 0; + + // Direct3D Specific methods + virtual DeviceIdentifier getAdapterIdentifier() const = 0; + + virtual bool isValidNativeWindow(EGLNativeWindowType window) const = 0; + virtual NativeWindowD3D *createNativeWindow(EGLNativeWindowType window, + const egl::Config *config, + const egl::AttributeMap &attribs) const = 0; + + virtual SwapChainD3D *createSwapChain(NativeWindowD3D *nativeWindow, + HANDLE shareHandle, + IUnknown *d3dTexture, + GLenum backBufferFormat, + GLenum depthBufferFormat, + EGLint orientation, + EGLint samples) = 0; + virtual egl::Error getD3DTextureInfo(const egl::Config *configuration, + IUnknown *d3dTexture, + const egl::AttributeMap &attribs, + EGLint *width, + EGLint *height, + GLsizei *samples, + gl::Format *glFormat, + const angle::Format **angleFormat, + UINT *arraySlice) const = 0; + virtual egl::Error validateShareHandle(const egl::Config *config, + HANDLE shareHandle, + const egl::AttributeMap &attribs) const = 0; + + virtual int getMajorShaderModel() const = 0; + + virtual void setGlobalDebugAnnotator() = 0; + + const angle::FeaturesD3D &getFeatures() const; + + // Pixel operations + virtual angle::Result copyImage2D(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) = 0; + virtual angle::Result copyImageCube(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + gl::TextureTarget target, + GLint level) = 0; + virtual angle::Result copyImage3D(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) = 0; + virtual angle::Result copyImage2DArray(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) = 0; + + virtual angle::Result copyTexture(const gl::Context *context, + const gl::Texture *source, + GLint sourceLevel, + gl::TextureTarget srcTarget, + const gl::Box &sourceBox, + GLenum destFormat, + GLenum destType, + const gl::Offset &destOffset, + TextureStorage *storage, + gl::TextureTarget destTarget, + GLint destLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) = 0; + virtual angle::Result copyCompressedTexture(const gl::Context *context, + const gl::Texture *source, + GLint sourceLevel, + TextureStorage *storage, + GLint destLevel) = 0; + + // RenderTarget creation + virtual angle::Result createRenderTarget(const gl::Context *context, + int width, + int height, + GLenum format, + GLsizei samples, + RenderTargetD3D **outRT) = 0; + virtual angle::Result createRenderTargetCopy(const gl::Context *context, + RenderTargetD3D *source, + RenderTargetD3D **outRT) = 0; + + // Shader operations + virtual angle::Result loadExecutable(d3d::Context *context, + const uint8_t *function, + size_t length, + gl::ShaderType type, + const std::vector &streamOutVaryings, + bool separatedOutputBuffers, + ShaderExecutableD3D **outExecutable) = 0; + virtual angle::Result compileToExecutable(d3d::Context *context, + gl::InfoLog &infoLog, + const std::string &shaderHLSL, + gl::ShaderType type, + const std::vector &streamOutVaryings, + bool separatedOutputBuffers, + const CompilerWorkaroundsD3D &workarounds, + ShaderExecutableD3D **outExectuable) = 0; + virtual angle::Result ensureHLSLCompilerInitialized(d3d::Context *context) = 0; + + virtual UniformStorageD3D *createUniformStorage(size_t storageSize) = 0; + + // Image operations + virtual ImageD3D *createImage() = 0; + virtual ExternalImageSiblingImpl *createExternalImageSibling( + const gl::Context *context, + EGLenum target, + EGLClientBuffer buffer, + const egl::AttributeMap &attribs) = 0; + virtual angle::Result generateMipmap(const gl::Context *context, + ImageD3D *dest, + ImageD3D *source) = 0; + virtual angle::Result generateMipmapUsingD3D(const gl::Context *context, + TextureStorage *storage, + const gl::TextureState &textureState) = 0; + virtual angle::Result copyImage(const gl::Context *context, + ImageD3D *dest, + ImageD3D *source, + const gl::Box &sourceBox, + const gl::Offset &destOffset, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) = 0; + virtual TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain, + const std::string &label) = 0; + virtual TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage, + RenderTargetD3D *renderTargetD3D, + const std::string &label) = 0; + virtual TextureStorage *createTextureStorageBuffer( + const gl::OffsetBindingPointer &buffer, + GLenum internalFormat, + const std::string &label) = 0; + virtual TextureStorage *createTextureStorageExternal( + egl::Stream *stream, + const egl::Stream::GLTextureDescription &desc, + const std::string &label) = 0; + virtual TextureStorage *createTextureStorage2D(GLenum internalformat, + BindFlags bindFlags, + GLsizei width, + GLsizei height, + int levels, + const std::string &label, + bool hintLevelZeroOnly) = 0; + virtual TextureStorage *createTextureStorageCube(GLenum internalformat, + BindFlags bindFlags, + int size, + int levels, + bool hintLevelZeroOnly, + const std::string &label) = 0; + virtual TextureStorage *createTextureStorage3D(GLenum internalformat, + BindFlags bindFlags, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels, + const std::string &label) = 0; + virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, + BindFlags bindFlags, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels, + const std::string &label) = 0; + virtual TextureStorage *createTextureStorage2DMultisample(GLenum internalformat, + GLsizei width, + GLsizei height, + int levels, + int samples, + bool fixedSampleLocations, + const std::string &label) = 0; + virtual TextureStorage *createTextureStorage2DMultisampleArray(GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels, + int samples, + bool fixedSampleLocations, + const std::string &label) = 0; + + // Buffer-to-texture and Texture-to-buffer copies + virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const = 0; + virtual angle::Result fastCopyBufferToTexture(const gl::Context *context, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + unsigned int offset, + RenderTargetD3D *destRenderTarget, + GLenum destinationFormat, + GLenum sourcePixelsType, + const gl::Box &destArea) = 0; + + // Device lost + gl::GraphicsResetStatus getResetStatus(); + void notifyDeviceLost(); + virtual bool resetDevice() = 0; + virtual bool testDeviceLost() = 0; + virtual bool testDeviceResettable() = 0; + + virtual RendererClass getRendererClass() const = 0; + virtual void *getD3DDevice() = 0; + + void setGPUDisjoint(); + + GLint getGPUDisjoint(); + GLint64 getTimestamp(); + + virtual angle::Result clearRenderTarget(const gl::Context *context, + RenderTargetD3D *renderTarget, + const gl::ColorF &clearColorValue, + const float clearDepthValue, + const unsigned int clearStencilValue) = 0; + + virtual DeviceImpl *createEGLDevice() = 0; + + bool presentPathFastEnabled() const { return mPresentPathFastEnabled; } + + // Stream creation + virtual StreamProducerImpl *createStreamProducerD3DTexture( + egl::Stream::ConsumerType consumerType, + const egl::AttributeMap &attribs) = 0; + + const gl::Caps &getNativeCaps() const; + const gl::TextureCapsMap &getNativeTextureCaps() const; + const gl::Extensions &getNativeExtensions() const; + const gl::Limitations &getNativeLimitations() const; + ShPixelLocalStorageType getNativePixelLocalStorageType() const; + virtual void initializeFrontendFeatures(angle::FrontendFeatures *features) const = 0; + + // Necessary hack for default framebuffers in D3D. + virtual FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) = 0; + + virtual gl::Version getMaxSupportedESVersion() const = 0; + virtual gl::Version getMaxConformantESVersion() const = 0; + + angle::Result initRenderTarget(const gl::Context *context, RenderTargetD3D *renderTarget); + + virtual angle::Result getIncompleteTexture(const gl::Context *context, + gl::TextureType type, + gl::Texture **textureOut) = 0; + + Serial generateSerial(); + + virtual bool canSelectViewInVertexShader() const = 0; + + protected: + virtual bool getLUID(LUID *adapterLuid) const = 0; + virtual void generateCaps(gl::Caps *outCaps, + gl::TextureCapsMap *outTextureCaps, + gl::Extensions *outExtensions, + gl::Limitations *outLimitations) const = 0; + + bool skipDraw(const gl::State &glState, gl::PrimitiveMode drawMode); + + egl::Display *mDisplay; + + bool mPresentPathFastEnabled; + + private: + void ensureCapsInitialized() const; + + virtual void initializeFeatures(angle::FeaturesD3D *features) const = 0; + + mutable bool mCapsInitialized; + mutable gl::Caps mNativeCaps; + mutable gl::TextureCapsMap mNativeTextureCaps; + mutable gl::Extensions mNativeExtensions; + mutable gl::Limitations mNativeLimitations; + + mutable bool mFeaturesInitialized; + mutable angle::FeaturesD3D mFeatures; + + bool mDisjoint; + bool mDeviceLost; + + SerialFactory mSerialFactory; +}; + +unsigned int GetBlendSampleMask(const gl::State &glState, int samples); +bool InstancedPointSpritesActive(ProgramD3D *programD3D, gl::PrimitiveMode mode); +GLenum DefaultGLErrorCode(HRESULT hr); + +// Define stubs so we don't need to include D3D9/D3D11 headers directly. +RendererD3D *CreateRenderer11(egl::Display *display); +RendererD3D *CreateRenderer9(egl::Display *display); + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_RENDERERD3D_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/SamplerD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/SamplerD3D.h new file mode 100644 index 0000000000..ad4b15a4ab --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/SamplerD3D.h @@ -0,0 +1,33 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// SamplerD3D.h: Defines the rx::SamplerD3D class, an implementation of SamplerImpl. + +#ifndef LIBANGLE_RENDERER_D3D_SAMPLERD3D_H_ +#define LIBANGLE_RENDERER_D3D_SAMPLERD3D_H_ + +#include "libANGLE/renderer/SamplerImpl.h" + +namespace rx +{ + +class SamplerD3D : public SamplerImpl +{ + public: + SamplerD3D(const gl::SamplerState &state) : SamplerImpl(state) {} + ~SamplerD3D() override {} + + angle::Result syncState(const gl::Context *context, const bool dirtyBits) override; +}; + +inline angle::Result SamplerD3D::syncState(const gl::Context *context, const bool dirtyBits) +{ + return angle::Result::Continue; +} + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_SAMPLERD3D_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderD3D.cpp new file mode 100644 index 0000000000..ae8a9ebcfb --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderD3D.cpp @@ -0,0 +1,391 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ShaderD3D.cpp: Defines the rx::ShaderD3D class which implements rx::ShaderImpl. + +#include "libANGLE/renderer/d3d/ShaderD3D.h" + +#include "common/system_utils.h" +#include "common/utilities.h" +#include "libANGLE/Caps.h" +#include "libANGLE/Compiler.h" +#include "libANGLE/Context.h" +#include "libANGLE/Shader.h" +#include "libANGLE/features.h" +#include "libANGLE/renderer/ContextImpl.h" +#include "libANGLE/renderer/d3d/ProgramD3D.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" +#include "libANGLE/trace.h" + +namespace rx +{ + +class TranslateTaskD3D : public angle::Closure +{ + public: + TranslateTaskD3D(ShHandle handle, + const ShCompileOptions &options, + const std::string &source, + const std::string &sourcePath) + : mHandle(handle), + mOptions(options), + mSource(source), + mSourcePath(sourcePath), + mResult(false) + {} + + void operator()() override + { + ANGLE_TRACE_EVENT1("gpu.angle", "TranslateTask::run", "source", mSource); + std::vector srcStrings; + if (!mSourcePath.empty()) + { + srcStrings.push_back(mSourcePath.c_str()); + } + srcStrings.push_back(mSource.c_str()); + + mResult = sh::Compile(mHandle, &srcStrings[0], srcStrings.size(), mOptions); + } + + bool getResult() { return mResult; } + + private: + ShHandle mHandle; + ShCompileOptions mOptions; + std::string mSource; + std::string mSourcePath; + bool mResult; +}; + +using PostTranslateFunctor = + std::function; + +class WaitableCompileEventD3D final : public WaitableCompileEvent +{ + public: + WaitableCompileEventD3D(std::shared_ptr waitableEvent, + gl::ShCompilerInstance *compilerInstance, + PostTranslateFunctor &&postTranslateFunctor, + std::shared_ptr translateTask) + : WaitableCompileEvent(waitableEvent), + mCompilerInstance(compilerInstance), + mPostTranslateFunctor(std::move(postTranslateFunctor)), + mTranslateTask(translateTask) + {} + + bool getResult() override { return mTranslateTask->getResult(); } + + bool postTranslate(std::string *infoLog) override + { + return mPostTranslateFunctor(mCompilerInstance, infoLog); + } + + private: + gl::ShCompilerInstance *mCompilerInstance; + PostTranslateFunctor mPostTranslateFunctor; + std::shared_ptr mTranslateTask; +}; + +ShaderD3D::ShaderD3D(const gl::ShaderState &state, RendererD3D *renderer) + : ShaderImpl(state), mRenderer(renderer) +{ + uncompile(); +} + +ShaderD3D::~ShaderD3D() {} + +std::string ShaderD3D::getDebugInfo() const +{ + if (mDebugInfo.empty()) + { + return ""; + } + + return mDebugInfo + std::string("\n// ") + gl::GetShaderTypeString(mState.getShaderType()) + + " SHADER END\n"; +} + +// initialize/clean up previous state +void ShaderD3D::uncompile() +{ + // set by compileToHLSL + mCompilerOutputType = SH_ESSL_OUTPUT; + + mUsesMultipleRenderTargets = false; + mUsesFragColor = false; + mUsesFragData = false; + mUsesSecondaryColor = false; + mUsesFragCoord = false; + mUsesFrontFacing = false; + mUsesHelperInvocation = false; + mUsesPointSize = false; + mUsesPointCoord = false; + mUsesDepthRange = false; + mUsesFragDepth = false; + mHasANGLEMultiviewEnabled = false; + mUsesVertexID = false; + mUsesViewID = false; + mUsesDiscardRewriting = false; + mUsesNestedBreak = false; + mRequiresIEEEStrictCompiling = false; + + mDebugInfo.clear(); +} + +void ShaderD3D::generateWorkarounds(CompilerWorkaroundsD3D *workarounds) const +{ + if (mUsesDiscardRewriting) + { + // ANGLE issue 486: + // Work-around a D3D9 compiler bug that presents itself when using conditional discard, by + // disabling optimization + workarounds->skipOptimization = true; + } + else if (mUsesNestedBreak) + { + // ANGLE issue 603: + // Work-around a D3D9 compiler bug that presents itself when using break in a nested loop, + // by maximizing optimization We want to keep the use of + // ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION minimal to prevent hangs, so usesDiscard takes + // precedence + workarounds->useMaxOptimization = true; + } + + if (mRequiresIEEEStrictCompiling) + { + // IEEE Strictness for D3D compiler needs to be enabled for NaNs to work. + workarounds->enableIEEEStrictness = true; + } +} + +unsigned int ShaderD3D::getUniformRegister(const std::string &uniformName) const +{ + ASSERT(mUniformRegisterMap.count(uniformName) > 0); + return mUniformRegisterMap.find(uniformName)->second; +} + +unsigned int ShaderD3D::getUniformBlockRegister(const std::string &blockName) const +{ + ASSERT(mUniformBlockRegisterMap.count(blockName) > 0); + return mUniformBlockRegisterMap.find(blockName)->second; +} + +bool ShaderD3D::shouldUniformBlockUseStructuredBuffer(const std::string &blockName) const +{ + ASSERT(mUniformBlockUseStructuredBufferMap.count(blockName) > 0); + return mUniformBlockUseStructuredBufferMap.find(blockName)->second; +} + +unsigned int ShaderD3D::getShaderStorageBlockRegister(const std::string &blockName) const +{ + ASSERT(mShaderStorageBlockRegisterMap.count(blockName) > 0); + return mShaderStorageBlockRegisterMap.find(blockName)->second; +} + +ShShaderOutput ShaderD3D::getCompilerOutputType() const +{ + return mCompilerOutputType; +} + +bool ShaderD3D::useImage2DFunction(const std::string &functionName) const +{ + if (mUsedImage2DFunctionNames.empty()) + { + return false; + } + + return mUsedImage2DFunctionNames.find(functionName) != mUsedImage2DFunctionNames.end(); +} + +const std::set &ShaderD3D::getSlowCompilingUniformBlockSet() const +{ + return mSlowCompilingUniformBlockSet; +} + +const std::map &GetUniformRegisterMap( + const std::map *uniformRegisterMap) +{ + ASSERT(uniformRegisterMap); + return *uniformRegisterMap; +} + +const std::set &GetSlowCompilingUniformBlockSet( + const std::set *slowCompilingUniformBlockSet) +{ + ASSERT(slowCompilingUniformBlockSet); + return *slowCompilingUniformBlockSet; +} + +const std::set &GetUsedImage2DFunctionNames( + const std::set *usedImage2DFunctionNames) +{ + ASSERT(usedImage2DFunctionNames); + return *usedImage2DFunctionNames; +} + +std::shared_ptr ShaderD3D::compile(const gl::Context *context, + gl::ShCompilerInstance *compilerInstance, + ShCompileOptions *options) +{ + std::string sourcePath; + uncompile(); + + const angle::FeaturesD3D &features = mRenderer->getFeatures(); + const gl::Extensions &extensions = mRenderer->getNativeExtensions(); + + const std::string &source = mState.getSource(); + +#if !defined(ANGLE_ENABLE_WINDOWS_UWP) + if (gl::DebugAnnotationsActive(context)) + { + sourcePath = angle::CreateTemporaryFile().value(); + writeFile(sourcePath.c_str(), source.c_str(), source.length()); + options->lineDirectives = true; + options->sourcePath = true; + } +#endif + + if (features.expandIntegerPowExpressions.enabled) + { + options->expandSelectHLSLIntegerPowExpressions = true; + } + + if (features.getDimensionsIgnoresBaseLevel.enabled) + { + options->HLSLGetDimensionsIgnoresBaseLevel = true; + } + + if (features.preAddTexelFetchOffsets.enabled) + { + options->rewriteTexelFetchOffsetToTexelFetch = true; + } + if (features.rewriteUnaryMinusOperator.enabled) + { + options->rewriteIntegerUnaryMinusOperator = true; + } + if (features.emulateIsnanFloat.enabled) + { + options->emulateIsnanFloatFunction = true; + } + if (features.skipVSConstantRegisterZero.enabled && + mState.getShaderType() == gl::ShaderType::Vertex) + { + options->skipD3DConstantRegisterZero = true; + } + if (features.forceAtomicValueResolution.enabled) + { + options->forceAtomicValueResolution = true; + } + if (features.allowTranslateUniformBlockToStructuredBuffer.enabled) + { + options->allowTranslateUniformBlockToStructuredBuffer = true; + } + if (extensions.multiviewOVR || extensions.multiview2OVR) + { + options->initializeBuiltinsForInstancedMultiview = true; + } + if (extensions.shaderPixelLocalStorageANGLE) + { + options->pls.type = mRenderer->getNativePixelLocalStorageType(); + if (extensions.shaderPixelLocalStorageCoherentANGLE) + { + options->pls.fragmentSynchronizationType = + ShFragmentSynchronizationType::RasterizerOrderViews_D3D; + } + } + + auto postTranslateFunctor = [this](gl::ShCompilerInstance *compiler, std::string *infoLog) { + // TODO(jmadill): We shouldn't need to cache this. + mCompilerOutputType = compiler->getShaderOutputType(); + + const std::string &translatedSource = mState.getTranslatedSource(); + + mUsesMultipleRenderTargets = translatedSource.find("GL_USES_MRT") != std::string::npos; + mUsesFragColor = translatedSource.find("GL_USES_FRAG_COLOR") != std::string::npos; + mUsesFragData = translatedSource.find("GL_USES_FRAG_DATA") != std::string::npos; + mUsesSecondaryColor = translatedSource.find("GL_USES_SECONDARY_COLOR") != std::string::npos; + mUsesFragCoord = translatedSource.find("GL_USES_FRAG_COORD") != std::string::npos; + mUsesFrontFacing = translatedSource.find("GL_USES_FRONT_FACING") != std::string::npos; + mUsesHelperInvocation = + translatedSource.find("GL_USES_HELPER_INVOCATION") != std::string::npos; + mUsesPointSize = translatedSource.find("GL_USES_POINT_SIZE") != std::string::npos; + mUsesPointCoord = translatedSource.find("GL_USES_POINT_COORD") != std::string::npos; + mUsesDepthRange = translatedSource.find("GL_USES_DEPTH_RANGE") != std::string::npos; + mUsesFragDepth = translatedSource.find("GL_USES_FRAG_DEPTH") != std::string::npos; + mHasANGLEMultiviewEnabled = + translatedSource.find("GL_ANGLE_MULTIVIEW_ENABLED") != std::string::npos; + mUsesVertexID = translatedSource.find("GL_USES_VERTEX_ID") != std::string::npos; + mUsesViewID = translatedSource.find("GL_USES_VIEW_ID") != std::string::npos; + mUsesDiscardRewriting = + translatedSource.find("ANGLE_USES_DISCARD_REWRITING") != std::string::npos; + mUsesNestedBreak = translatedSource.find("ANGLE_USES_NESTED_BREAK") != std::string::npos; + mRequiresIEEEStrictCompiling = + translatedSource.find("ANGLE_REQUIRES_IEEE_STRICT_COMPILING") != std::string::npos; + + ShHandle compilerHandle = compiler->getHandle(); + + mUniformRegisterMap = GetUniformRegisterMap(sh::GetUniformRegisterMap(compilerHandle)); + mReadonlyImage2DRegisterIndex = sh::GetReadonlyImage2DRegisterIndex(compilerHandle); + mImage2DRegisterIndex = sh::GetImage2DRegisterIndex(compilerHandle); + mUsedImage2DFunctionNames = + GetUsedImage2DFunctionNames(sh::GetUsedImage2DFunctionNames(compilerHandle)); + + for (const sh::InterfaceBlock &interfaceBlock : mState.getUniformBlocks()) + { + if (interfaceBlock.active) + { + unsigned int index = static_cast(-1); + bool blockRegisterResult = + sh::GetUniformBlockRegister(compilerHandle, interfaceBlock.name, &index); + ASSERT(blockRegisterResult); + bool useStructuredBuffer = + sh::ShouldUniformBlockUseStructuredBuffer(compilerHandle, interfaceBlock.name); + + mUniformBlockRegisterMap[interfaceBlock.name] = index; + mUniformBlockUseStructuredBufferMap[interfaceBlock.name] = useStructuredBuffer; + } + } + + mSlowCompilingUniformBlockSet = + GetSlowCompilingUniformBlockSet(sh::GetSlowCompilingUniformBlockSet(compilerHandle)); + + for (const sh::InterfaceBlock &interfaceBlock : mState.getShaderStorageBlocks()) + { + if (interfaceBlock.active) + { + unsigned int index = static_cast(-1); + bool blockRegisterResult = + sh::GetShaderStorageBlockRegister(compilerHandle, interfaceBlock.name, &index); + ASSERT(blockRegisterResult); + + mShaderStorageBlockRegisterMap[interfaceBlock.name] = index; + } + } + + mDebugInfo += std::string("// ") + gl::GetShaderTypeString(mState.getShaderType()) + + " SHADER BEGIN\n"; + mDebugInfo += "\n// GLSL BEGIN\n\n" + mState.getSource() + "\n\n// GLSL END\n\n\n"; + mDebugInfo += + "// INITIAL HLSL BEGIN\n\n" + translatedSource + "\n// INITIAL HLSL END\n\n\n"; + // Successive steps will append more info + return true; + }; + + auto workerThreadPool = context->getWorkerThreadPool(); + auto translateTask = std::make_shared(compilerInstance->getHandle(), *options, + source, sourcePath); + + return std::make_shared( + angle::WorkerThreadPool::PostWorkerTask(workerThreadPool, translateTask), compilerInstance, + std::move(postTranslateFunctor), translateTask); +} + +bool ShaderD3D::hasUniform(const std::string &name) const +{ + return mUniformRegisterMap.find(name) != mUniformRegisterMap.end(); +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderD3D.h new file mode 100644 index 0000000000..d1c5622a27 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderD3D.h @@ -0,0 +1,126 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ShaderD3D.h: Defines the rx::ShaderD3D class which implements rx::ShaderImpl. + +#ifndef LIBANGLE_RENDERER_D3D_SHADERD3D_H_ +#define LIBANGLE_RENDERER_D3D_SHADERD3D_H_ + +#include "libANGLE/renderer/ShaderImpl.h" + +#include + +namespace angle +{ +struct FeaturesD3D; +} // namespace angle + +namespace gl +{ +struct Extensions; +} + +namespace rx +{ +class DynamicHLSL; +class RendererD3D; +struct D3DUniform; + +// Workarounds attached to each shader. Do not need to expose information about these workarounds so +// a simple bool struct suffices. +struct CompilerWorkaroundsD3D +{ + bool skipOptimization = false; + + bool useMaxOptimization = false; + + // IEEE strictness needs to be enabled for NANs to work. + bool enableIEEEStrictness = false; +}; + +class ShaderD3D : public ShaderImpl +{ + public: + ShaderD3D(const gl::ShaderState &state, RendererD3D *renderer); + ~ShaderD3D() override; + + std::shared_ptr compile(const gl::Context *context, + gl::ShCompilerInstance *compilerInstance, + ShCompileOptions *options) override; + + std::string getDebugInfo() const override; + + // D3D-specific methods + void uncompile(); + + bool hasUniform(const std::string &name) const; + + // Query regular uniforms with their name. Query sampler fields of structs with field selection + // using dot (.) operator. + unsigned int getUniformRegister(const std::string &uniformName) const; + + unsigned int getUniformBlockRegister(const std::string &blockName) const; + bool shouldUniformBlockUseStructuredBuffer(const std::string &blockName) const; + unsigned int getShaderStorageBlockRegister(const std::string &blockName) const; + unsigned int getReadonlyImage2DRegisterIndex() const { return mReadonlyImage2DRegisterIndex; } + unsigned int getImage2DRegisterIndex() const { return mImage2DRegisterIndex; } + bool useImage2DFunction(const std::string &functionName) const; + const std::set &getSlowCompilingUniformBlockSet() const; + void appendDebugInfo(const std::string &info) const { mDebugInfo += info; } + + void generateWorkarounds(CompilerWorkaroundsD3D *workarounds) const; + + bool usesMultipleRenderTargets() const { return mUsesMultipleRenderTargets; } + bool usesFragColor() const { return mUsesFragColor; } + bool usesFragData() const { return mUsesFragData; } + bool usesSecondaryColor() const { return mUsesSecondaryColor; } + bool usesFragCoord() const { return mUsesFragCoord; } + bool usesFrontFacing() const { return mUsesFrontFacing; } + bool usesHelperInvocation() const { return mUsesHelperInvocation; } + bool usesPointSize() const { return mUsesPointSize; } + bool usesPointCoord() const { return mUsesPointCoord; } + bool usesDepthRange() const { return mUsesDepthRange; } + bool usesFragDepth() const { return mUsesFragDepth; } + bool usesVertexID() const { return mUsesVertexID; } + bool usesViewID() const { return mUsesViewID; } + bool hasANGLEMultiviewEnabled() const { return mHasANGLEMultiviewEnabled; } + + ShShaderOutput getCompilerOutputType() const; + + private: + bool mUsesMultipleRenderTargets; + bool mUsesFragColor; + bool mUsesFragData; + bool mUsesSecondaryColor; + bool mUsesFragCoord; + bool mUsesFrontFacing; + bool mUsesHelperInvocation; + bool mUsesPointSize; + bool mUsesPointCoord; + bool mUsesDepthRange; + bool mUsesFragDepth; + bool mHasANGLEMultiviewEnabled; + bool mUsesVertexID; + bool mUsesViewID; + bool mUsesDiscardRewriting; + bool mUsesNestedBreak; + bool mRequiresIEEEStrictCompiling; + + RendererD3D *mRenderer; + ShShaderOutput mCompilerOutputType; + mutable std::string mDebugInfo; + std::map mUniformRegisterMap; + std::map mUniformBlockRegisterMap; + std::map mUniformBlockUseStructuredBufferMap; + std::set mSlowCompilingUniformBlockSet; + std::map mShaderStorageBlockRegisterMap; + unsigned int mReadonlyImage2DRegisterIndex; + unsigned int mImage2DRegisterIndex; + std::set mUsedImage2DFunctionNames; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_SHADERD3D_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderExecutableD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderExecutableD3D.cpp new file mode 100644 index 0000000000..eab3becc91 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderExecutableD3D.cpp @@ -0,0 +1,67 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ShaderExecutable.cpp: Implements a class to contain D3D shader executable +// implementation details. + +#include "libANGLE/renderer/d3d/ShaderExecutableD3D.h" + +#include "common/angleutils.h" + +namespace rx +{ + +ShaderExecutableD3D::ShaderExecutableD3D(const void *function, size_t length) + : mFunctionBuffer(length) +{ + memcpy(mFunctionBuffer.data(), function, length); +} + +ShaderExecutableD3D::~ShaderExecutableD3D() {} + +const uint8_t *ShaderExecutableD3D::getFunction() const +{ + return mFunctionBuffer.data(); +} + +size_t ShaderExecutableD3D::getLength() const +{ + return mFunctionBuffer.size(); +} + +const std::string &ShaderExecutableD3D::getDebugInfo() const +{ + return mDebugInfo; +} + +void ShaderExecutableD3D::appendDebugInfo(const std::string &info) +{ + mDebugInfo += info; +} + +UniformStorageD3D::UniformStorageD3D(size_t initialSize) : mUniformData() +{ + bool result = mUniformData.resize(initialSize); + ASSERT(result); + + // Uniform data is zero-initialized by default. + mUniformData.fill(0); +} + +UniformStorageD3D::~UniformStorageD3D() {} + +size_t UniformStorageD3D::size() const +{ + return mUniformData.size(); +} + +uint8_t *UniformStorageD3D::getDataPointer(unsigned int registerIndex, unsigned int registerElement) +{ + size_t offset = ((registerIndex * 4 + registerElement) * sizeof(float)); + return mUniformData.data() + offset; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderExecutableD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderExecutableD3D.h new file mode 100644 index 0000000000..673822b152 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderExecutableD3D.h @@ -0,0 +1,57 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ShaderExecutable.h: Defines a class to contain D3D shader executable +// implementation details. + +#ifndef LIBANGLE_RENDERER_D3D_SHADEREXECUTABLED3D_H_ +#define LIBANGLE_RENDERER_D3D_SHADEREXECUTABLED3D_H_ + +#include "common/MemoryBuffer.h" +#include "common/debug.h" + +#include +#include + +namespace rx +{ + +class ShaderExecutableD3D : angle::NonCopyable +{ + public: + ShaderExecutableD3D(const void *function, size_t length); + virtual ~ShaderExecutableD3D(); + + const uint8_t *getFunction() const; + + size_t getLength() const; + + const std::string &getDebugInfo() const; + + void appendDebugInfo(const std::string &info); + + private: + std::vector mFunctionBuffer; + std::string mDebugInfo; +}; + +class UniformStorageD3D : angle::NonCopyable +{ + public: + UniformStorageD3D(size_t initialSize); + virtual ~UniformStorageD3D(); + + size_t size() const; + + uint8_t *getDataPointer(unsigned int registerIndex, unsigned int registerElement); + + private: + angle::MemoryBuffer mUniformData; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_SHADEREXECUTABLED3D_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/SurfaceD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/SurfaceD3D.cpp new file mode 100644 index 0000000000..256808637f --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/SurfaceD3D.cpp @@ -0,0 +1,517 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// SurfaceD3D.cpp: D3D implementation of an EGL surface + +#include "libANGLE/renderer/d3d/SurfaceD3D.h" + +#include "libANGLE/Context.h" +#include "libANGLE/Display.h" +#include "libANGLE/Surface.h" +#include "libANGLE/renderer/Format.h" +#include "libANGLE/renderer/d3d/DisplayD3D.h" +#include "libANGLE/renderer/d3d/RenderTargetD3D.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" +#include "libANGLE/renderer/d3d/SwapChainD3D.h" + +#include +#include +#include + +namespace rx +{ + +SurfaceD3D::SurfaceD3D(const egl::SurfaceState &state, + RendererD3D *renderer, + egl::Display *display, + EGLNativeWindowType window, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const egl::AttributeMap &attribs) + : SurfaceImpl(state), + mRenderer(renderer), + mDisplay(display), + mFixedSize(window == nullptr || attribs.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE) == EGL_TRUE), + mFixedWidth(0), + mFixedHeight(0), + mOrientation(static_cast(attribs.get(EGL_SURFACE_ORIENTATION_ANGLE, 0))), + mRenderTargetFormat(state.config->renderTargetFormat), + mDepthStencilFormat(state.config->depthStencilFormat), + mColorFormat(nullptr), + mSwapChain(nullptr), + mSwapIntervalDirty(true), + mNativeWindow(renderer->createNativeWindow(window, state.config, attribs)), + mWidth(static_cast(attribs.get(EGL_WIDTH, 0))), + mHeight(static_cast(attribs.get(EGL_HEIGHT, 0))), + mSwapInterval(1), + mShareHandle(0), + mD3DTexture(nullptr), + mBuftype(buftype) +{ + if (window != nullptr && !mFixedSize) + { + mWidth = -1; + mHeight = -1; + } + + if (mFixedSize) + { + mFixedWidth = mWidth; + mFixedHeight = mHeight; + } + + switch (buftype) + { + case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE: + mShareHandle = static_cast(clientBuffer); + break; + + case EGL_D3D_TEXTURE_ANGLE: + mD3DTexture = static_cast(clientBuffer); + ASSERT(mD3DTexture != nullptr); + mD3DTexture->AddRef(); + break; + + default: + break; + } +} + +SurfaceD3D::~SurfaceD3D() +{ + releaseSwapChain(); + SafeDelete(mNativeWindow); + SafeRelease(mD3DTexture); +} + +void SurfaceD3D::releaseSwapChain() +{ + SafeDelete(mSwapChain); +} + +egl::Error SurfaceD3D::initialize(const egl::Display *display) +{ + if (mNativeWindow->getNativeWindow()) + { + if (!mNativeWindow->initialize()) + { + return egl::EglBadSurface(); + } + } + + if (mBuftype == EGL_D3D_TEXTURE_ANGLE) + { + ANGLE_TRY(mRenderer->getD3DTextureInfo(mState.config, mD3DTexture, mState.attributes, + &mFixedWidth, &mFixedHeight, nullptr, nullptr, + &mColorFormat, nullptr)); + if (mState.attributes.contains(EGL_GL_COLORSPACE)) + { + if (mColorFormat->id != angle::FormatID::R8G8B8A8_TYPELESS && + mColorFormat->id != angle::FormatID::B8G8R8A8_TYPELESS) + { + return egl::EglBadMatch() + << "EGL_GL_COLORSPACE may only be specified for TYPELESS textures"; + } + } + if (mColorFormat->id == angle::FormatID::R8G8B8A8_TYPELESS) + { + EGLAttrib colorspace = + mState.attributes.get(EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_LINEAR); + if (colorspace == EGL_GL_COLORSPACE_SRGB) + { + mColorFormat = &angle::Format::Get(angle::FormatID::R8G8B8A8_TYPELESS_SRGB); + } + } + if (mColorFormat->id == angle::FormatID::B8G8R8A8_TYPELESS) + { + EGLAttrib colorspace = + mState.attributes.get(EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_LINEAR); + if (colorspace == EGL_GL_COLORSPACE_SRGB) + { + mColorFormat = &angle::Format::Get(angle::FormatID::B8G8R8A8_TYPELESS_SRGB); + } + } + mRenderTargetFormat = mColorFormat->fboImplementationInternalFormat; + } + + ANGLE_TRY(resetSwapChain(display)); + return egl::NoError(); +} + +egl::Error SurfaceD3D::bindTexImage(const gl::Context *, gl::Texture *, EGLint) +{ + return egl::NoError(); +} + +egl::Error SurfaceD3D::releaseTexImage(const gl::Context *, EGLint) +{ + return egl::NoError(); +} + +egl::Error SurfaceD3D::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) +{ + if (!mState.directComposition) + { + return egl::EglBadSurface() + << "getSyncValues: surface requires Direct Composition to be enabled"; + } + + return mSwapChain->getSyncValues(ust, msc, sbc); +} + +egl::Error SurfaceD3D::getMscRate(EGLint *numerator, EGLint *denominator) +{ + UNIMPLEMENTED(); + return egl::EglBadAccess(); +} + +egl::Error SurfaceD3D::resetSwapChain(const egl::Display *display) +{ + ASSERT(!mSwapChain); + + int width; + int height; + + if (!mFixedSize) + { + RECT windowRect; + if (!mNativeWindow->getClientRect(&windowRect)) + { + ASSERT(false); + + return egl::EglBadSurface() << "Could not retrieve the window dimensions"; + } + + width = windowRect.right - windowRect.left; + height = windowRect.bottom - windowRect.top; + } + else + { + // non-window surface - size is determined at creation + width = mFixedWidth; + height = mFixedHeight; + } + + mSwapChain = + mRenderer->createSwapChain(mNativeWindow, mShareHandle, mD3DTexture, mRenderTargetFormat, + mDepthStencilFormat, mOrientation, mState.config->samples); + if (!mSwapChain) + { + return egl::EglBadAlloc(); + } + + // This is a bit risky to pass the proxy context here, but it can happen at almost any time. + DisplayD3D *displayD3D = GetImplAs(display); + egl::Error error = resetSwapChain(displayD3D, width, height); + if (error.isError()) + { + SafeDelete(mSwapChain); + return error; + } + + return egl::NoError(); +} + +egl::Error SurfaceD3D::resizeSwapChain(DisplayD3D *displayD3D, + int backbufferWidth, + int backbufferHeight) +{ + ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0); + ASSERT(mSwapChain); + + EGLint status = + mSwapChain->resize(displayD3D, std::max(1, backbufferWidth), std::max(1, backbufferHeight)); + + if (status == EGL_CONTEXT_LOST) + { + mDisplay->notifyDeviceLost(); + return egl::Error(status); + } + else if (status != EGL_SUCCESS) + { + return egl::Error(status); + } + + mWidth = backbufferWidth; + mHeight = backbufferHeight; + + return egl::NoError(); +} + +egl::Error SurfaceD3D::resetSwapChain(DisplayD3D *displayD3D, + int backbufferWidth, + int backbufferHeight) +{ + ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0); + ASSERT(mSwapChain); + + EGLint status = mSwapChain->reset(displayD3D, std::max(1, backbufferWidth), + std::max(1, backbufferHeight), mSwapInterval); + + if (status == EGL_CONTEXT_LOST) + { + mRenderer->notifyDeviceLost(); + return egl::Error(status); + } + else if (status != EGL_SUCCESS) + { + return egl::Error(status); + } + + mWidth = backbufferWidth; + mHeight = backbufferHeight; + mSwapIntervalDirty = false; + + return egl::NoError(); +} + +egl::Error SurfaceD3D::swapRect(DisplayD3D *displayD3D, + EGLint x, + EGLint y, + EGLint width, + EGLint height) +{ + if (!mSwapChain) + { + return egl::NoError(); + } + + if (x + width > mWidth) + { + width = mWidth - x; + } + + if (y + height > mHeight) + { + height = mHeight - y; + } + + if (width != 0 && height != 0) + { + EGLint status = mSwapChain->swapRect(displayD3D, x, y, width, height); + + if (status == EGL_CONTEXT_LOST) + { + mRenderer->notifyDeviceLost(); + return egl::Error(status); + } + else if (status != EGL_SUCCESS) + { + return egl::Error(status); + } + } + + ANGLE_TRY(checkForOutOfDateSwapChain(displayD3D)); + + return egl::NoError(); +} + +egl::Error SurfaceD3D::checkForOutOfDateSwapChain(DisplayD3D *displayD3D) +{ + RECT client; + int clientWidth = getWidth(); + int clientHeight = getHeight(); + bool sizeDirty = false; + if (!mFixedSize && !mNativeWindow->isIconic()) + { + // The window is automatically resized to 150x22 when it's minimized, but the swapchain + // shouldn't be resized because that's not a useful size to render to. + if (!mNativeWindow->getClientRect(&client)) + { + UNREACHABLE(); + return egl::NoError(); + } + + // Grow the buffer now, if the window has grown. We need to grow now to avoid losing + // information. + clientWidth = client.right - client.left; + clientHeight = client.bottom - client.top; + sizeDirty = clientWidth != getWidth() || clientHeight != getHeight(); + } + else if (mFixedSize) + { + clientWidth = mFixedWidth; + clientHeight = mFixedHeight; + sizeDirty = mFixedWidth != getWidth() || mFixedHeight != getHeight(); + } + + if (mSwapIntervalDirty) + { + ANGLE_TRY(resetSwapChain(displayD3D, clientWidth, clientHeight)); + } + else if (sizeDirty) + { + ANGLE_TRY(resizeSwapChain(displayD3D, clientWidth, clientHeight)); + } + + return egl::NoError(); +} + +egl::Error SurfaceD3D::swap(const gl::Context *context) +{ + DisplayD3D *displayD3D = GetImplAs(context->getDisplay()); + return swapRect(displayD3D, 0, 0, mWidth, mHeight); +} + +egl::Error SurfaceD3D::postSubBuffer(const gl::Context *context, + EGLint x, + EGLint y, + EGLint width, + EGLint height) +{ + DisplayD3D *displayD3D = GetImplAs(context->getDisplay()); + return swapRect(displayD3D, x, y, width, height); +} + +rx::SwapChainD3D *SurfaceD3D::getSwapChain() const +{ + return mSwapChain; +} + +void SurfaceD3D::setSwapInterval(EGLint interval) +{ + if (mSwapInterval == interval) + { + return; + } + + mSwapInterval = interval; + mSwapIntervalDirty = true; +} + +void SurfaceD3D::setFixedWidth(EGLint width) +{ + mFixedWidth = width; +} + +void SurfaceD3D::setFixedHeight(EGLint height) +{ + mFixedHeight = height; +} + +EGLint SurfaceD3D::getWidth() const +{ + return mWidth; +} + +EGLint SurfaceD3D::getHeight() const +{ + return mHeight; +} + +EGLint SurfaceD3D::isPostSubBufferSupported() const +{ + // post sub buffer is always possible on D3D surfaces + return EGL_TRUE; +} + +EGLint SurfaceD3D::getSwapBehavior() const +{ + return EGL_BUFFER_PRESERVED; +} + +egl::Error SurfaceD3D::querySurfacePointerANGLE(EGLint attribute, void **value) +{ + if (attribute == EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE) + { + *value = mSwapChain->getShareHandle(); + } + else if (attribute == EGL_DXGI_KEYED_MUTEX_ANGLE) + { + *value = mSwapChain->getKeyedMutex(); + } + else + UNREACHABLE(); + + return egl::NoError(); +} + +const angle::Format *SurfaceD3D::getD3DTextureColorFormat() const +{ + return mColorFormat; +} + +egl::Error SurfaceD3D::attachToFramebuffer(const gl::Context *context, gl::Framebuffer *framebuffer) +{ + return egl::NoError(); +} + +egl::Error SurfaceD3D::detachFromFramebuffer(const gl::Context *context, + gl::Framebuffer *framebuffer) +{ + return egl::NoError(); +} + +angle::Result SurfaceD3D::getAttachmentRenderTarget(const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex, + GLsizei samples, + FramebufferAttachmentRenderTarget **rtOut) +{ + if (binding == GL_BACK) + { + *rtOut = mSwapChain->getColorRenderTarget(); + } + else + { + *rtOut = mSwapChain->getDepthStencilRenderTarget(); + } + return angle::Result::Continue; +} + +angle::Result SurfaceD3D::initializeContents(const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex) +{ + switch (binding) + { + case GL_BACK: + ASSERT(mState.config->renderTargetFormat != GL_NONE); + ANGLE_TRY(mRenderer->initRenderTarget(context, mSwapChain->getColorRenderTarget())); + break; + + case GL_DEPTH: + case GL_STENCIL: + ASSERT(mState.config->depthStencilFormat != GL_NONE); + ANGLE_TRY( + mRenderer->initRenderTarget(context, mSwapChain->getDepthStencilRenderTarget())); + break; + + default: + UNREACHABLE(); + break; + } + return angle::Result::Continue; +} + +WindowSurfaceD3D::WindowSurfaceD3D(const egl::SurfaceState &state, + RendererD3D *renderer, + egl::Display *display, + EGLNativeWindowType window, + const egl::AttributeMap &attribs) + : SurfaceD3D(state, renderer, display, window, 0, static_cast(0), attribs) +{} + +WindowSurfaceD3D::~WindowSurfaceD3D() {} + +PbufferSurfaceD3D::PbufferSurfaceD3D(const egl::SurfaceState &state, + RendererD3D *renderer, + egl::Display *display, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const egl::AttributeMap &attribs) + : SurfaceD3D(state, + renderer, + display, + static_cast(0), + buftype, + clientBuffer, + attribs) +{} + +PbufferSurfaceD3D::~PbufferSurfaceD3D() {} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/SurfaceD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/SurfaceD3D.h new file mode 100644 index 0000000000..720943c8d1 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/SurfaceD3D.h @@ -0,0 +1,145 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// SurfaceD3D.h: D3D implementation of an EGL surface + +#ifndef LIBANGLE_RENDERER_D3D_SURFACED3D_H_ +#define LIBANGLE_RENDERER_D3D_SURFACED3D_H_ + +#include "libANGLE/renderer/SurfaceImpl.h" +#include "libANGLE/renderer/d3d/NativeWindowD3D.h" + +namespace egl +{ +class Surface; +} + +namespace rx +{ +class DisplayD3D; +class SwapChainD3D; +class RendererD3D; + +class SurfaceD3D : public SurfaceImpl +{ + public: + ~SurfaceD3D() override; + void releaseSwapChain(); + + egl::Error initialize(const egl::Display *display) override; + + egl::Error swap(const gl::Context *context) override; + egl::Error postSubBuffer(const gl::Context *context, + EGLint x, + EGLint y, + EGLint width, + EGLint height) override; + egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override; + egl::Error bindTexImage(const gl::Context *context, + gl::Texture *texture, + EGLint buffer) override; + egl::Error releaseTexImage(const gl::Context *context, EGLint buffer) override; + egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) override; + egl::Error getMscRate(EGLint *numerator, EGLint *denominator) override; + void setSwapInterval(EGLint interval) override; + void setFixedWidth(EGLint width) override; + void setFixedHeight(EGLint height) override; + + EGLint getWidth() const override; + EGLint getHeight() const override; + + EGLint isPostSubBufferSupported() const override; + EGLint getSwapBehavior() const override; + + // D3D implementations + SwapChainD3D *getSwapChain() const; + + egl::Error resetSwapChain(const egl::Display *display); + + egl::Error checkForOutOfDateSwapChain(DisplayD3D *displayD3D); + + angle::Result getAttachmentRenderTarget(const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex, + GLsizei samples, + FramebufferAttachmentRenderTarget **rtOut) override; + angle::Result initializeContents(const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex) override; + + const angle::Format *getD3DTextureColorFormat() const override; + + egl::Error attachToFramebuffer(const gl::Context *context, + gl::Framebuffer *framebuffer) override; + egl::Error detachFromFramebuffer(const gl::Context *context, + gl::Framebuffer *framebuffer) override; + + protected: + SurfaceD3D(const egl::SurfaceState &state, + RendererD3D *renderer, + egl::Display *display, + EGLNativeWindowType window, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const egl::AttributeMap &attribs); + + egl::Error swapRect(DisplayD3D *displayD3D, EGLint x, EGLint y, EGLint width, EGLint height); + egl::Error resetSwapChain(DisplayD3D *displayD3D, int backbufferWidth, int backbufferHeight); + egl::Error resizeSwapChain(DisplayD3D *displayD3D, int backbufferWidth, int backbufferHeight); + + RendererD3D *mRenderer; + egl::Display *mDisplay; + + bool mFixedSize; + GLint mFixedWidth; + GLint mFixedHeight; + GLint mOrientation; + + GLenum mRenderTargetFormat; + GLenum mDepthStencilFormat; + const angle::Format *mColorFormat; + + SwapChainD3D *mSwapChain; + bool mSwapIntervalDirty; + + NativeWindowD3D *mNativeWindow; // Handler for the Window that the surface is created for. + EGLint mWidth; + EGLint mHeight; + + EGLint mSwapInterval; + + HANDLE mShareHandle; + IUnknown *mD3DTexture; + + EGLenum mBuftype; +}; + +class WindowSurfaceD3D : public SurfaceD3D +{ + public: + WindowSurfaceD3D(const egl::SurfaceState &state, + RendererD3D *renderer, + egl::Display *display, + EGLNativeWindowType window, + const egl::AttributeMap &attribs); + ~WindowSurfaceD3D() override; +}; + +class PbufferSurfaceD3D : public SurfaceD3D +{ + public: + PbufferSurfaceD3D(const egl::SurfaceState &state, + RendererD3D *renderer, + egl::Display *display, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const egl::AttributeMap &attribs); + ~PbufferSurfaceD3D() override; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_SURFACED3D_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/SwapChainD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/SwapChainD3D.cpp new file mode 100644 index 0000000000..8891888a68 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/SwapChainD3D.cpp @@ -0,0 +1,34 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// SwapChainD3D.cpp: Defines a back-end specific class that hides the details of the +// implementation-specific swapchain. + +#include "libANGLE/renderer/d3d/SwapChainD3D.h" + +namespace rx +{ + +SwapChainD3D::SwapChainD3D(HANDLE shareHandle, + IUnknown *d3dTexture, + GLenum backBufferFormat, + GLenum depthBufferFormat) + : mOffscreenRenderTargetFormat(backBufferFormat), + mDepthBufferFormat(depthBufferFormat), + mShareHandle(shareHandle), + mD3DTexture(d3dTexture) +{ + if (mD3DTexture) + { + mD3DTexture->AddRef(); + } +} + +SwapChainD3D::~SwapChainD3D() +{ + SafeRelease(mD3DTexture); +} +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/SwapChainD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/SwapChainD3D.h new file mode 100644 index 0000000000..fcbab95c8d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/SwapChainD3D.h @@ -0,0 +1,83 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// SwapChainD3D.h: Defines a back-end specific class that hides the details of the +// implementation-specific swapchain. + +#ifndef LIBANGLE_RENDERER_D3D_SWAPCHAIND3D_H_ +#define LIBANGLE_RENDERER_D3D_SWAPCHAIND3D_H_ + +#include +#include +#include + +#include "common/angleutils.h" +#include "common/platform.h" +#include "libANGLE/Error.h" + +#if !defined(ANGLE_FORCE_VSYNC_OFF) +# define ANGLE_FORCE_VSYNC_OFF 0 +#endif + +namespace gl +{ +class Context; +} // namespace gl + +namespace egl +{ +class Display; +} // namespace egl + +namespace rx +{ +class DisplayD3D; +class RenderTargetD3D; + +class SwapChainD3D : angle::NonCopyable +{ + public: + SwapChainD3D(HANDLE shareHandle, + IUnknown *d3dTexture, + GLenum backBufferFormat, + GLenum depthBufferFormat); + virtual ~SwapChainD3D(); + + virtual EGLint resize(DisplayD3D *displayD3D, + EGLint backbufferWidth, + EGLint backbufferSize) = 0; + virtual EGLint reset(DisplayD3D *displayD3D, + EGLint backbufferWidth, + EGLint backbufferHeight, + EGLint swapInterval) = 0; + virtual EGLint swapRect(DisplayD3D *displayD3D, + EGLint x, + EGLint y, + EGLint width, + EGLint height) = 0; + virtual void recreate() = 0; + + virtual RenderTargetD3D *getColorRenderTarget() = 0; + virtual RenderTargetD3D *getDepthStencilRenderTarget() = 0; + + GLenum getRenderTargetInternalFormat() const { return mOffscreenRenderTargetFormat; } + GLenum getDepthBufferInternalFormat() const { return mDepthBufferFormat; } + + HANDLE getShareHandle() { return mShareHandle; } + virtual void *getKeyedMutex() = 0; + + virtual egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) = 0; + + protected: + const GLenum mOffscreenRenderTargetFormat; + const GLenum mDepthBufferFormat; + + HANDLE mShareHandle; + IUnknown *mD3DTexture; +}; + +} // namespace rx +#endif // LIBANGLE_RENDERER_D3D_SWAPCHAIND3D_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureD3D.cpp new file mode 100644 index 0000000000..fc22f000be --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureD3D.cpp @@ -0,0 +1,4640 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// TextureD3D.cpp: Implementations of the Texture interfaces shared betweeen the D3D backends. + +#include "libANGLE/renderer/d3d/TextureD3D.h" + +#include "common/mathutil.h" +#include "common/utilities.h" +#include "libANGLE/Buffer.h" +#include "libANGLE/Config.h" +#include "libANGLE/Context.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/Image.h" +#include "libANGLE/Surface.h" +#include "libANGLE/Texture.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/BufferImpl.h" +#include "libANGLE/renderer/d3d/BufferD3D.h" +#include "libANGLE/renderer/d3d/ContextD3D.h" +#include "libANGLE/renderer/d3d/EGLImageD3D.h" +#include "libANGLE/renderer/d3d/ImageD3D.h" +#include "libANGLE/renderer/d3d/RenderTargetD3D.h" +#include "libANGLE/renderer/d3d/SurfaceD3D.h" +#include "libANGLE/renderer/d3d/TextureStorage.h" + +namespace rx +{ + +namespace +{ + +angle::Result GetUnpackPointer(const gl::Context *context, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels, + ptrdiff_t layerOffset, + const uint8_t **pointerOut) +{ + if (unpackBuffer) + { + // Do a CPU readback here, if we have an unpack buffer bound and the fast GPU path is not + // supported + ptrdiff_t offset = reinterpret_cast(pixels); + + // TODO: this is the only place outside of renderer that asks for a buffers raw data. + // This functionality should be moved into renderer and the getData method of BufferImpl + // removed. + BufferD3D *bufferD3D = GetImplAs(unpackBuffer); + ASSERT(bufferD3D); + const uint8_t *bufferData = nullptr; + ANGLE_TRY(bufferD3D->getData(context, &bufferData)); + *pointerOut = bufferData + offset; + } + else + { + *pointerOut = pixels; + } + + // Offset the pointer for 2D array layer (if it's valid) + if (*pointerOut != nullptr) + { + *pointerOut += layerOffset; + } + + return angle::Result::Continue; +} + +bool IsRenderTargetUsage(GLenum usage) +{ + return (usage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE); +} +} // namespace + +TextureD3D::TextureD3D(const gl::TextureState &state, RendererD3D *renderer) + : TextureImpl(state), + mRenderer(renderer), + mDirtyImages(true), + mImmutable(false), + mTexStorage(nullptr), + mTexStorageObserverBinding(this, kTextureStorageObserverMessageIndex), + mBaseLevel(0) +{} + +TextureD3D::~TextureD3D() +{ + ASSERT(!mTexStorage); +} + +angle::Result TextureD3D::getNativeTexture(const gl::Context *context, TextureStorage **outStorage) +{ + // ensure the underlying texture is created + ANGLE_TRY(initializeStorage(context, BindFlags())); + + if (mTexStorage) + { + ANGLE_TRY(updateStorage(context)); + } + + ASSERT(outStorage); + + *outStorage = mTexStorage; + return angle::Result::Continue; +} + +angle::Result TextureD3D::getImageAndSyncFromStorage(const gl::Context *context, + const gl::ImageIndex &index, + ImageD3D **outImage) +{ + ImageD3D *image = getImage(index); + if (mTexStorage && mTexStorage->isRenderTarget()) + { + ANGLE_TRY(image->copyFromTexStorage(context, index, mTexStorage)); + mDirtyImages = true; + } + image->markClean(); + *outImage = image; + return angle::Result::Continue; +} + +GLint TextureD3D::getLevelZeroWidth() const +{ + ASSERT(gl::CountLeadingZeros(static_cast(getBaseLevelWidth())) > getBaseLevel()); + return getBaseLevelWidth() << mBaseLevel; +} + +GLint TextureD3D::getLevelZeroHeight() const +{ + ASSERT(gl::CountLeadingZeros(static_cast(getBaseLevelHeight())) > getBaseLevel()); + return getBaseLevelHeight() << mBaseLevel; +} + +GLint TextureD3D::getLevelZeroDepth() const +{ + return getBaseLevelDepth(); +} + +GLint TextureD3D::getBaseLevelWidth() const +{ + const ImageD3D *baseImage = getBaseLevelImage(); + return (baseImage ? baseImage->getWidth() : 0); +} + +GLint TextureD3D::getBaseLevelHeight() const +{ + const ImageD3D *baseImage = getBaseLevelImage(); + return (baseImage ? baseImage->getHeight() : 0); +} + +GLint TextureD3D::getBaseLevelDepth() const +{ + const ImageD3D *baseImage = getBaseLevelImage(); + return (baseImage ? baseImage->getDepth() : 0); +} + +// Note: "base level image" is loosely defined to be any image from the base level, +// where in the base of 2D array textures and cube maps there are several. Don't use +// the base level image for anything except querying texture format and size. +GLenum TextureD3D::getBaseLevelInternalFormat() const +{ + const ImageD3D *baseImage = getBaseLevelImage(); + return (baseImage ? baseImage->getInternalFormat() : GL_NONE); +} + +angle::Result TextureD3D::setStorage(const gl::Context *context, + gl::TextureType type, + size_t levels, + GLenum internalFormat, + const gl::Extents &size) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3D::setStorageMultisample(const gl::Context *context, + gl::TextureType type, + GLsizei samples, + GLint internalformat, + const gl::Extents &size, + bool fixedSampleLocations) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3D::setBuffer(const gl::Context *context, GLenum internalFormat) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3D::setStorageExternalMemory(const gl::Context *context, + gl::TextureType type, + size_t levels, + GLenum internalFormat, + const gl::Extents &size, + gl::MemoryObject *memoryObject, + GLuint64 offset, + GLbitfield createFlags, + GLbitfield usageFlags, + const void *imageCreateInfoPNext) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +bool TextureD3D::couldUseSetData() const +{ + if (!mRenderer->getFeatures().setDataFasterThanImageUpload.enabled) + { + return false; + } + + if (!mRenderer->getFeatures().setDataFasterThanImageUploadOn128bitFormats.enabled) + { + gl::InternalFormat internalFormat = + gl::GetSizedInternalFormatInfo(getBaseLevelInternalFormat()); + return internalFormat.pixelBytes < 16; + } + + return true; +} + +bool TextureD3D::shouldUseSetData(const ImageD3D *image) const +{ + if (!couldUseSetData()) + { + return false; + } + + if (image->isDirty()) + { + return false; + } + + gl::InternalFormat internalFormat = gl::GetSizedInternalFormatInfo(image->getInternalFormat()); + + // We can only handle full updates for depth-stencil textures, so to avoid complications + // disable them entirely. + if (internalFormat.depthBits > 0 || internalFormat.stencilBits > 0) + { + return false; + } + + // TODO(jmadill): Handle compressed internal formats + return (mTexStorage && !internalFormat.compressed); +} + +angle::Result TextureD3D::setImageImpl(const gl::Context *context, + const gl::ImageIndex &index, + GLenum type, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels, + ptrdiff_t layerOffset) +{ + ImageD3D *image = getImage(index); + ASSERT(image); + + // No-op + if (image->getWidth() == 0 || image->getHeight() == 0 || image->getDepth() == 0) + { + return angle::Result::Continue; + } + + // We no longer need the "GLenum format" parameter to TexImage to determine what data format + // "pixels" contains. From our image internal format we know how many channels to expect, and + // "type" gives the format of pixel's components. + const uint8_t *pixelData = nullptr; + ANGLE_TRY(GetUnpackPointer(context, unpack, unpackBuffer, pixels, layerOffset, &pixelData)); + + if (pixelData != nullptr) + { + if (shouldUseSetData(image)) + { + ANGLE_TRY( + mTexStorage->setData(context, index, image, nullptr, type, unpack, pixelData)); + } + else + { + gl::Box fullImageArea(0, 0, 0, image->getWidth(), image->getHeight(), + image->getDepth()); + ANGLE_TRY(image->loadData(context, fullImageArea, unpack, type, pixelData, + index.usesTex3D())); + } + + mDirtyImages = true; + } + + return angle::Result::Continue; +} + +angle::Result TextureD3D::subImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels, + ptrdiff_t layerOffset) +{ + // CPU readback & copy where direct GPU copy is not supported + const uint8_t *pixelData = nullptr; + ANGLE_TRY(GetUnpackPointer(context, unpack, unpackBuffer, pixels, layerOffset, &pixelData)); + + if (pixelData != nullptr) + { + ImageD3D *image = getImage(index); + ASSERT(image); + + if (shouldUseSetData(image)) + { + return mTexStorage->setData(context, index, image, &area, type, unpack, pixelData); + } + + ANGLE_TRY(image->loadData(context, area, unpack, type, pixelData, index.usesTex3D())); + ANGLE_TRY(commitRegion(context, index, area)); + mDirtyImages = true; + } + + return angle::Result::Continue; +} + +angle::Result TextureD3D::setCompressedImageImpl(const gl::Context *context, + const gl::ImageIndex &index, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels, + ptrdiff_t layerOffset) +{ + ImageD3D *image = getImage(index); + ASSERT(image); + + if (image->getWidth() == 0 || image->getHeight() == 0 || image->getDepth() == 0) + { + return angle::Result::Continue; + } + + // We no longer need the "GLenum format" parameter to TexImage to determine what data format + // "pixels" contains. From our image internal format we know how many channels to expect, and + // "type" gives the format of pixel's components. + const uint8_t *pixelData = nullptr; + gl::Buffer *unpackBuffer = context->getState().getTargetBuffer(gl::BufferBinding::PixelUnpack); + ANGLE_TRY(GetUnpackPointer(context, unpack, unpackBuffer, pixels, layerOffset, &pixelData)); + + if (pixelData != nullptr) + { + gl::Box fullImageArea(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth()); + ANGLE_TRY(image->loadCompressedData(context, fullImageArea, pixelData)); + + mDirtyImages = true; + } + + return angle::Result::Continue; +} + +angle::Result TextureD3D::subImageCompressed(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels, + ptrdiff_t layerOffset) +{ + const uint8_t *pixelData = nullptr; + gl::Buffer *unpackBuffer = context->getState().getTargetBuffer(gl::BufferBinding::PixelUnpack); + ANGLE_TRY(GetUnpackPointer(context, unpack, unpackBuffer, pixels, layerOffset, &pixelData)); + + if (pixelData != nullptr) + { + ImageD3D *image = getImage(index); + ASSERT(image); + + ANGLE_TRY(image->loadCompressedData(context, area, pixelData)); + + mDirtyImages = true; + } + + return angle::Result::Continue; +} + +bool TextureD3D::isFastUnpackable(const gl::Buffer *unpackBuffer, + const gl::PixelUnpackState &unpack, + GLenum sizedInternalFormat) +{ + return unpackBuffer != nullptr && unpack.skipRows == 0 && unpack.skipPixels == 0 && + unpack.imageHeight == 0 && unpack.skipImages == 0 && + mRenderer->supportsFastCopyBufferToTexture(sizedInternalFormat); +} + +angle::Result TextureD3D::fastUnpackPixels(const gl::Context *context, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels, + const gl::Box &destArea, + GLenum sizedInternalFormat, + GLenum type, + RenderTargetD3D *destRenderTarget) +{ + bool check = (unpack.skipRows != 0 || unpack.skipPixels != 0 || unpack.imageHeight != 0 || + unpack.skipImages != 0); + ANGLE_CHECK(GetImplAs(context), !check, + "Unimplemented pixel store parameters in fastUnpackPixels", GL_INVALID_OPERATION); + + // No-op + if (destArea.width <= 0 && destArea.height <= 0 && destArea.depth <= 0) + { + return angle::Result::Continue; + } + + // In order to perform the fast copy through the shader, we must have the right format, and be + // able to create a render target. + ASSERT(mRenderer->supportsFastCopyBufferToTexture(sizedInternalFormat)); + + uintptr_t offset = reinterpret_cast(pixels); + + ANGLE_TRY(mRenderer->fastCopyBufferToTexture( + context, unpack, unpackBuffer, static_cast(offset), destRenderTarget, + sizedInternalFormat, type, destArea)); + + return angle::Result::Continue; +} + +GLint TextureD3D::creationLevels(GLsizei width, GLsizei height, GLsizei depth) const +{ + if ((gl::isPow2(width) && gl::isPow2(height) && gl::isPow2(depth)) || + mRenderer->getNativeExtensions().textureNpotOES) + { + // Maximum number of levels + return gl::log2(std::max(std::max(width, height), depth)) + 1; + } + else + { + // OpenGL ES 2.0 without GL_OES_texture_npot does not permit NPOT mipmaps. + return 1; + } +} + +TextureStorage *TextureD3D::getStorage() +{ + ASSERT(mTexStorage); + return mTexStorage; +} + +ImageD3D *TextureD3D::getBaseLevelImage() const +{ + if (mBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + return nullptr; + } + return getImage(getImageIndex(mBaseLevel, 0)); +} + +angle::Result TextureD3D::setImageExternal(const gl::Context *context, + gl::TextureType type, + egl::Stream *stream, + const egl::Stream::GLTextureDescription &desc) +{ + // Only external images can accept external textures + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3D::generateMipmap(const gl::Context *context) +{ + const GLuint baseLevel = mState.getEffectiveBaseLevel(); + const GLuint maxLevel = mState.getMipmapMaxLevel(); + ASSERT(maxLevel > baseLevel); // Should be checked before calling this. + + if (mTexStorage && mRenderer->getFeatures().zeroMaxLodWorkaround.enabled) + { + // Switch to using the mipmapped texture. + TextureStorage *textureStorageEXT = nullptr; + ANGLE_TRY(getNativeTexture(context, &textureStorageEXT)); + ANGLE_TRY(textureStorageEXT->useLevelZeroWorkaroundTexture(context, false)); + } + + // Set up proper mipmap chain in our Image array. + ANGLE_TRY(initMipmapImages(context)); + + if (mTexStorage && mTexStorage->supportsNativeMipmapFunction()) + { + ANGLE_TRY(updateStorage(context)); + + // Generate the mipmap chain using the ad-hoc DirectX function. + ANGLE_TRY(mRenderer->generateMipmapUsingD3D(context, mTexStorage, mState)); + } + else + { + // Generate the mipmap chain, one level at a time. + ANGLE_TRY(generateMipmapUsingImages(context, maxLevel)); + } + + return angle::Result::Continue; +} + +angle::Result TextureD3D::generateMipmapUsingImages(const gl::Context *context, + const GLuint maxLevel) +{ + // We know that all layers have the same dimension, for the texture to be complete + GLint layerCount = static_cast(getLayerCount(mBaseLevel)); + + if (mTexStorage && !mTexStorage->isRenderTarget() && + canCreateRenderTargetForImage(getImageIndex(mBaseLevel, 0)) && + mRenderer->getRendererClass() == RENDERER_D3D11) + { + if (!mRenderer->getFeatures().setDataFasterThanImageUpload.enabled) + { + ANGLE_TRY(updateStorage(context)); + } + ANGLE_TRY(ensureRenderTarget(context)); + } + else if (couldUseSetData() && mTexStorage) + { + // When making mipmaps with the setData workaround enabled, the texture storage has + // the image data already. For non-render-target storage, we have to pull it out into + // an image layer. + if (!mTexStorage->isRenderTarget()) + { + // Copy from the storage mip 0 to Image mip 0 + for (GLint layer = 0; layer < layerCount; ++layer) + { + gl::ImageIndex srcIndex = getImageIndex(mBaseLevel, layer); + + ImageD3D *image = getImage(srcIndex); + ANGLE_TRY(image->copyFromTexStorage(context, srcIndex, mTexStorage)); + } + } + else + { + ANGLE_TRY(updateStorage(context)); + } + } + + // TODO: Decouple this from zeroMaxLodWorkaround. This is a 9_3 restriction, unrelated to + // zeroMaxLodWorkaround. The restriction is because Feature Level 9_3 can't create SRVs on + // individual levels of the texture. As a result, even if the storage is a rendertarget, we + // can't use the GPU to generate the mipmaps without further work. The D3D9 renderer works + // around this by copying each level of the texture into its own single-layer GPU texture (in + // Blit9::boxFilter). Feature Level 9_3 could do something similar, or it could continue to use + // CPU-side mipmap generation, or something else. + bool renderableStorage = (mTexStorage && mTexStorage->isRenderTarget() && + !(mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)); + if (renderableStorage) + { + ANGLE_TRY(updateStorage(context)); + } + + for (GLint layer = 0; layer < layerCount; ++layer) + { + for (GLuint mip = mBaseLevel + 1; mip <= maxLevel; ++mip) + { + ASSERT(getLayerCount(mip) == layerCount); + + gl::ImageIndex sourceIndex = getImageIndex(mip - 1, layer); + gl::ImageIndex destIndex = getImageIndex(mip, layer); + + if (renderableStorage) + { + // GPU-side mipmapping + ANGLE_TRY(mTexStorage->generateMipmap(context, sourceIndex, destIndex)); + } + else + { + // CPU-side mipmapping + ANGLE_TRY( + mRenderer->generateMipmap(context, getImage(destIndex), getImage(sourceIndex))); + } + } + } + + mDirtyImages = !renderableStorage; + + if (mTexStorage && mDirtyImages) + { + ANGLE_TRY(updateStorage(context)); + } + + return angle::Result::Continue; +} + +bool TextureD3D::isBaseImageZeroSize() const +{ + ImageD3D *baseImage = getBaseLevelImage(); + + if (!baseImage || baseImage->getWidth() <= 0 || baseImage->getHeight() <= 0) + { + return true; + } + + if (baseImage->getType() == gl::TextureType::_3D && baseImage->getDepth() <= 0) + { + return true; + } + + if (baseImage->getType() == gl::TextureType::_2DArray && getLayerCount(getBaseLevel()) <= 0) + { + return true; + } + + return false; +} + +angle::Result TextureD3D::ensureBindFlags(const gl::Context *context, BindFlags bindFlags) +{ + ANGLE_TRY(initializeStorage(context, bindFlags)); + + // initializeStorage can fail with NoError if the texture is not complete. This is not + // an error for incomplete sampling, but it is a big problem for rendering. + if (!mTexStorage) + { + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; + } + + if (!isBaseImageZeroSize()) + { + ASSERT(mTexStorage); + if ((bindFlags.renderTarget && !mTexStorage->isRenderTarget()) || + (bindFlags.unorderedAccess && !mTexStorage->isUnorderedAccess())) + { + TexStoragePointer newRenderTargetStorage; + ANGLE_TRY(createCompleteStorage(context, bindFlags, &newRenderTargetStorage)); + + ANGLE_TRY(mTexStorage->copyToStorage(context, newRenderTargetStorage.get())); + ANGLE_TRY(setCompleteTexStorage(context, newRenderTargetStorage.get())); + newRenderTargetStorage.release(); + // If this texture is used in compute shader, we should invalidate this texture so that + // the UAV/SRV is rebound again with this new texture storage in next dispatch call. + mTexStorage->invalidateTextures(); + } + } + + return angle::Result::Continue; +} + +angle::Result TextureD3D::ensureRenderTarget(const gl::Context *context) +{ + return ensureBindFlags(context, BindFlags::RenderTarget()); +} + +angle::Result TextureD3D::ensureUnorderedAccess(const gl::Context *context) +{ + return ensureBindFlags(context, BindFlags::UnorderedAccess()); +} + +bool TextureD3D::canCreateRenderTargetForImage(const gl::ImageIndex &index) const +{ + if (index.getType() == gl::TextureType::_2DMultisample || + index.getType() == gl::TextureType::_2DMultisampleArray) + { + ASSERT(index.getType() != gl::TextureType::_2DMultisampleArray || index.hasLayer()); + return true; + } + + ImageD3D *image = getImage(index); + ASSERT(image); + bool levelsComplete = (isImageComplete(index) && isImageComplete(getImageIndex(0, 0))); + return (image->isRenderableFormat() && levelsComplete); +} + +angle::Result TextureD3D::commitRegion(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box ®ion) +{ + if (mTexStorage) + { + ASSERT(isValidIndex(index)); + ImageD3D *image = getImage(index); + ANGLE_TRY(image->copyToStorage(context, mTexStorage, index, region)); + image->markClean(); + } + + return angle::Result::Continue; +} + +angle::Result TextureD3D::getAttachmentRenderTarget(const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex, + GLsizei samples, + FramebufferAttachmentRenderTarget **rtOut) +{ + RenderTargetD3D *rtD3D = nullptr; + ANGLE_TRY(getRenderTarget(context, imageIndex, samples, &rtD3D)); + *rtOut = static_cast(rtD3D); + return angle::Result::Continue; +} + +angle::Result TextureD3D::setBaseLevel(const gl::Context *context, GLuint baseLevel) +{ + const int oldStorageWidth = std::max(1, getLevelZeroWidth()); + const int oldStorageHeight = std::max(1, getLevelZeroHeight()); + const int oldStorageDepth = std::max(1, getLevelZeroDepth()); + const int oldStorageFormat = getBaseLevelInternalFormat(); + mBaseLevel = baseLevel; + + // When the base level changes, the texture storage might not be valid anymore, since it could + // have been created based on the dimensions of the previous specified level range. + const int newStorageWidth = std::max(1, getLevelZeroWidth()); + const int newStorageHeight = std::max(1, getLevelZeroHeight()); + const int newStorageDepth = std::max(1, getLevelZeroDepth()); + const int newStorageFormat = getBaseLevelInternalFormat(); + if (mTexStorage && + (newStorageWidth != oldStorageWidth || newStorageHeight != oldStorageHeight || + newStorageDepth != oldStorageDepth || newStorageFormat != oldStorageFormat)) + { + markAllImagesDirty(); + + // Iterate over all images, and backup the content if it's been used as a render target. The + // D3D11 backend can automatically restore images on storage destroy, but it only works for + // images that have been associated with the texture storage before, which is insufficient + // here. + if (mTexStorage->isRenderTarget()) + { + gl::ImageIndexIterator iterator = imageIterator(); + while (iterator.hasNext()) + { + const gl::ImageIndex index = iterator.next(); + const GLsizei samples = getRenderToTextureSamples(); + RenderTargetD3D *renderTarget = nullptr; + ANGLE_TRY(mTexStorage->findRenderTarget(context, index, samples, &renderTarget)); + if (renderTarget) + { + ANGLE_TRY(getImage(index)->copyFromTexStorage(context, index, mTexStorage)); + } + } + } + + ANGLE_TRY(releaseTexStorage(context, gl::TexLevelMask())); + } + + return angle::Result::Continue; +} + +angle::Result TextureD3D::onLabelUpdate(const gl::Context *context) +{ + if (mTexStorage) + { + mTexStorage->setLabel(mState.getLabel()); + } + return angle::Result::Continue; +} + +angle::Result TextureD3D::syncState(const gl::Context *context, + const gl::Texture::DirtyBits &dirtyBits, + gl::Command source) +{ + // This could be improved using dirty bits. + return angle::Result::Continue; +} + +angle::Result TextureD3D::releaseTexStorage(const gl::Context *context, + const gl::TexLevelMask ©StorageToImagesMask) +{ + if (!mTexStorage) + { + return angle::Result::Continue; + } + + if (mTexStorage->isRenderTarget()) + { + const GLenum storageFormat = getBaseLevelInternalFormat(); + const size_t storageLevels = mTexStorage->getLevelCount(); + + gl::ImageIndexIterator iterator = imageIterator(); + while (iterator.hasNext()) + { + const gl::ImageIndex index = iterator.next(); + ImageD3D *image = getImage(index); + const int storageWidth = std::max(1, getLevelZeroWidth() >> index.getLevelIndex()); + const int storageHeight = std::max(1, getLevelZeroHeight() >> index.getLevelIndex()); + if (image && isImageComplete(index) && image->getWidth() == storageWidth && + image->getHeight() == storageHeight && + image->getInternalFormat() == storageFormat && + index.getLevelIndex() < static_cast(storageLevels) && + copyStorageToImagesMask[index.getLevelIndex()]) + { + ANGLE_TRY(image->copyFromTexStorage(context, index, mTexStorage)); + } + } + } + + onStateChange(angle::SubjectMessage::StorageReleased); + + auto err = mTexStorage->onDestroy(context); + SafeDelete(mTexStorage); + return err; +} + +void TextureD3D::onDestroy(const gl::Context *context) +{ + (void)releaseTexStorage(context, gl::TexLevelMask()); +} + +angle::Result TextureD3D::initializeContents(const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex) +{ + ContextD3D *contextD3D = GetImplAs(context); + gl::ImageIndex index = imageIndex; + + // Special case for D3D11 3D textures. We can't create render targets for individual layers of a + // 3D texture, so force the clear to the entire mip. There shouldn't ever be a case where we + // would lose existing data. + if (index.getType() == gl::TextureType::_3D) + { + index = gl::ImageIndex::Make3D(index.getLevelIndex(), gl::ImageIndex::kEntireLevel); + } + else if (index.getType() == gl::TextureType::_2DArray && !index.hasLayer()) + { + std::array tempLayerCounts; + + GLint levelIndex = index.getLevelIndex(); + tempLayerCounts[levelIndex] = getLayerCount(levelIndex); + gl::ImageIndexIterator iterator = + gl::ImageIndexIterator::Make2DArray(levelIndex, levelIndex + 1, tempLayerCounts.data()); + while (iterator.hasNext()) + { + ANGLE_TRY(initializeContents(context, GL_NONE, iterator.next())); + } + return angle::Result::Continue; + } + else if (index.getType() == gl::TextureType::_2DMultisampleArray && !index.hasLayer()) + { + std::array tempLayerCounts; + + ASSERT(index.getLevelIndex() == 0); + tempLayerCounts[0] = getLayerCount(0); + gl::ImageIndexIterator iterator = + gl::ImageIndexIterator::Make2DMultisampleArray(tempLayerCounts.data()); + while (iterator.hasNext()) + { + ANGLE_TRY(initializeContents(context, GL_NONE, iterator.next())); + } + return angle::Result::Continue; + } + + // Force image clean. + ImageD3D *image = getImage(index); + if (image) + { + image->markClean(); + } + + // Fast path: can use a render target clear. + // We don't use the fast path with the zero max lod workaround because it would introduce a race + // between the rendertarget and the staging images. + const angle::FeaturesD3D &features = mRenderer->getFeatures(); + bool shouldUseClear = (image == nullptr); + if (canCreateRenderTargetForImage(index) && !features.zeroMaxLodWorkaround.enabled && + (shouldUseClear || features.allowClearForRobustResourceInit.enabled)) + { + ANGLE_TRY(ensureRenderTarget(context)); + ASSERT(mTexStorage); + RenderTargetD3D *renderTarget = nullptr; + ANGLE_TRY(mTexStorage->getRenderTarget(context, index, 0, &renderTarget)); + ANGLE_TRY(mRenderer->initRenderTarget(context, renderTarget)); + + // Force image clean again, the texture storage may have been re-created and the image used. + if (image) + { + image->markClean(); + } + + return angle::Result::Continue; + } + + ASSERT(image != nullptr); + + // Slow path: non-renderable texture or the texture levels aren't set up. + const auto &formatInfo = gl::GetSizedInternalFormatInfo(image->getInternalFormat()); + + GLuint imageBytes = 0; + ANGLE_CHECK_GL_MATH(contextD3D, formatInfo.computeRowPitch(formatInfo.type, image->getWidth(), + 1, 0, &imageBytes)); + imageBytes *= image->getHeight() * image->getDepth(); + + gl::PixelUnpackState zeroDataUnpackState; + zeroDataUnpackState.alignment = 1; + + angle::MemoryBuffer *zeroBuffer = nullptr; + ANGLE_CHECK_GL_ALLOC(contextD3D, context->getZeroFilledBuffer(imageBytes, &zeroBuffer)); + + if (shouldUseSetData(image)) + { + ANGLE_TRY(mTexStorage->setData(context, index, image, nullptr, formatInfo.type, + zeroDataUnpackState, zeroBuffer->data())); + } + else + { + gl::Box fullImageArea(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth()); + ANGLE_TRY(image->loadData(context, fullImageArea, zeroDataUnpackState, formatInfo.type, + zeroBuffer->data(), false)); + + // Force an update to the tex storage so we avoid problems with subImage and dirty regions. + if (mTexStorage) + { + ANGLE_TRY(commitRegion(context, index, fullImageArea)); + image->markClean(); + } + else + { + mDirtyImages = true; + } + } + return angle::Result::Continue; +} + +GLsizei TextureD3D::getRenderToTextureSamples() +{ + if (mTexStorage) + { + return mTexStorage->getRenderToTextureSamples(); + } + return 0; +} + +void TextureD3D::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) +{ + onStateChange(message); +} + +TextureD3D_2D::TextureD3D_2D(const gl::TextureState &state, RendererD3D *renderer) + : TextureD3D(state, renderer) +{ + mEGLImageTarget = false; + for (auto &image : mImageArray) + { + image.reset(renderer->createImage()); + } +} + +void TextureD3D_2D::onDestroy(const gl::Context *context) +{ + // Delete the Images before the TextureStorage. Images might be relying on the TextureStorage + // for some of their data. If TextureStorage is deleted before the Images, then their data will + // be wastefully copied back from the GPU before we delete the Images. + for (auto &image : mImageArray) + { + image.reset(); + } + return TextureD3D::onDestroy(context); +} + +TextureD3D_2D::~TextureD3D_2D() {} + +ImageD3D *TextureD3D_2D::getImage(int level, int layer) const +{ + ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + ASSERT(layer == 0); + return mImageArray[level].get(); +} + +ImageD3D *TextureD3D_2D::getImage(const gl::ImageIndex &index) const +{ + ASSERT(index.getLevelIndex() < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + ASSERT(!index.hasLayer()); + ASSERT(index.getType() == gl::TextureType::_2D || + index.getType() == gl::TextureType::VideoImage); + return mImageArray[index.getLevelIndex()].get(); +} + +GLsizei TextureD3D_2D::getLayerCount(int level) const +{ + ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + return 1; +} + +GLsizei TextureD3D_2D::getWidth(GLint level) const +{ + if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + return mImageArray[level]->getWidth(); + else + return 0; +} + +GLsizei TextureD3D_2D::getHeight(GLint level) const +{ + if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + return mImageArray[level]->getHeight(); + else + return 0; +} + +GLenum TextureD3D_2D::getInternalFormat(GLint level) const +{ + if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + return mImageArray[level]->getInternalFormat(); + else + return GL_NONE; +} + +bool TextureD3D_2D::isDepth(GLint level) const +{ + return gl::GetSizedInternalFormatInfo(getInternalFormat(level)).depthBits > 0; +} + +bool TextureD3D_2D::isSRGB(GLint level) const +{ + return gl::GetSizedInternalFormatInfo(getInternalFormat(level)).colorEncoding == GL_SRGB; +} + +angle::Result TextureD3D_2D::setImage(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + const gl::Extents &size, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels) +{ + ASSERT((index.getTarget() == gl::TextureTarget::_2D || + index.getTarget() == gl::TextureTarget::VideoImage) && + size.depth == 1); + + const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type); + + bool fastUnpacked = false; + + ANGLE_TRY(redefineImage(context, index.getLevelIndex(), internalFormatInfo.sizedInternalFormat, + size, false)); + + // Attempt a fast gpu copy of the pixel data to the surface + if (mTexStorage) + { + ANGLE_TRY(mTexStorage->releaseMultisampledTexStorageForLevel(index.getLevelIndex())); + } + if (isFastUnpackable(unpackBuffer, unpack, internalFormatInfo.sizedInternalFormat) && + isLevelComplete(index.getLevelIndex())) + { + // Will try to create RT storage if it does not exist + RenderTargetD3D *destRenderTarget = nullptr; + ANGLE_TRY(getRenderTarget(context, index, getRenderToTextureSamples(), &destRenderTarget)); + + gl::Box destArea(0, 0, 0, getWidth(index.getLevelIndex()), getHeight(index.getLevelIndex()), + 1); + + ANGLE_TRY(fastUnpackPixels(context, unpack, unpackBuffer, pixels, destArea, + internalFormatInfo.sizedInternalFormat, type, destRenderTarget)); + + // Ensure we don't overwrite our newly initialized data + mImageArray[index.getLevelIndex()]->markClean(); + + fastUnpacked = true; + } + + if (!fastUnpacked) + { + ANGLE_TRY(setImageImpl(context, index, type, unpack, unpackBuffer, pixels, 0)); + } + + return angle::Result::Continue; +} + +angle::Result TextureD3D_2D::setSubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels) +{ + ASSERT(index.getTarget() == gl::TextureTarget::_2D && area.depth == 1 && area.z == 0); + + GLenum mipFormat = getInternalFormat(index.getLevelIndex()); + if (mTexStorage) + { + ANGLE_TRY(mTexStorage->releaseMultisampledTexStorageForLevel(index.getLevelIndex())); + } + if (isFastUnpackable(unpackBuffer, unpack, mipFormat) && isLevelComplete(index.getLevelIndex())) + { + RenderTargetD3D *renderTarget = nullptr; + ANGLE_TRY(getRenderTarget(context, index, getRenderToTextureSamples(), &renderTarget)); + ASSERT(!mImageArray[index.getLevelIndex()]->isDirty()); + + return fastUnpackPixels(context, unpack, unpackBuffer, pixels, area, mipFormat, type, + renderTarget); + } + else + { + return TextureD3D::subImage(context, index, area, format, type, unpack, unpackBuffer, + pixels, 0); + } +} + +angle::Result TextureD3D_2D::setCompressedImage(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + const gl::Extents &size, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) +{ + ASSERT(index.getTarget() == gl::TextureTarget::_2D && size.depth == 1); + + // compressed formats don't have separate sized internal formats-- we can just use the + // compressed format directly + ANGLE_TRY(redefineImage(context, index.getLevelIndex(), internalFormat, size, false)); + + return setCompressedImageImpl(context, index, unpack, pixels, 0); +} + +angle::Result TextureD3D_2D::setCompressedSubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) +{ + ASSERT(index.getTarget() == gl::TextureTarget::_2D && area.depth == 1 && area.z == 0); + ANGLE_TRY(TextureD3D::subImageCompressed(context, index, area, format, unpack, pixels, 0)); + + return commitRegion(context, index, area); +} + +angle::Result TextureD3D_2D::copyImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Rectangle &sourceArea, + GLenum internalFormat, + gl::Framebuffer *source) +{ + ASSERT(index.getTarget() == gl::TextureTarget::_2D); + + const gl::InternalFormat &internalFormatInfo = + gl::GetInternalFormatInfo(internalFormat, GL_UNSIGNED_BYTE); + gl::Extents sourceExtents(sourceArea.width, sourceArea.height, 1); + ANGLE_TRY(redefineImage(context, index.getLevelIndex(), internalFormatInfo.sizedInternalFormat, + sourceExtents, false)); + + gl::Extents fbSize = source->getReadColorAttachment()->getSize(); + + // Does the read area extend beyond the framebuffer? + bool outside = sourceArea.x < 0 || sourceArea.y < 0 || + sourceArea.x + sourceArea.width > fbSize.width || + sourceArea.y + sourceArea.height > fbSize.height; + + // WebGL requires that pixels that would be outside the framebuffer are treated as zero values, + // so clear the mip level to 0 prior to making the copy if any pixel would be sampled outside. + // Same thing for robust resource init. + if (outside && (context->isWebGL() || context->isRobustResourceInitEnabled())) + { + ANGLE_TRY(initializeContents(context, GL_NONE, index)); + } + + gl::Rectangle clippedArea; + if (!ClipRectangle(sourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height), &clippedArea)) + { + // Empty source area, nothing to do. + return angle::Result::Continue; + } + + gl::Offset destOffset(clippedArea.x - sourceArea.x, clippedArea.y - sourceArea.y, 0); + + // If the zero max LOD workaround is active, then we can't sample from individual layers of the + // framebuffer in shaders, so we should use the non-rendering copy path. + if (!canCreateRenderTargetForImage(index) || + mRenderer->getFeatures().zeroMaxLodWorkaround.enabled) + { + ANGLE_TRY(mImageArray[index.getLevelIndex()]->copyFromFramebuffer(context, destOffset, + clippedArea, source)); + mDirtyImages = true; + } + else + { + ANGLE_TRY(ensureRenderTarget(context)); + + if (clippedArea.width != 0 && clippedArea.height != 0 && + isValidLevel(index.getLevelIndex())) + { + ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex())); + ANGLE_TRY(mRenderer->copyImage2D(context, source, clippedArea, internalFormat, + destOffset, mTexStorage, index.getLevelIndex())); + } + } + + return angle::Result::Continue; +} + +angle::Result TextureD3D_2D::copySubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + gl::Framebuffer *source) +{ + ASSERT(index.getTarget() == gl::TextureTarget::_2D && destOffset.z == 0); + + gl::Extents fbSize = source->getReadColorAttachment()->getSize(); + gl::Rectangle clippedArea; + if (!ClipRectangle(sourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height), &clippedArea)) + { + return angle::Result::Continue; + } + const gl::Offset clippedOffset(destOffset.x + clippedArea.x - sourceArea.x, + destOffset.y + clippedArea.y - sourceArea.y, 0); + + // can only make our texture storage to a render target if level 0 is defined (with a width & + // height) and the current level we're copying to is defined (with appropriate format, width & + // height) + + // If the zero max LOD workaround is active, then we can't sample from individual layers of the + // framebuffer in shaders, so we should use the non-rendering copy path. + if (!canCreateRenderTargetForImage(index) || + mRenderer->getFeatures().zeroMaxLodWorkaround.enabled) + { + ANGLE_TRY(mImageArray[index.getLevelIndex()]->copyFromFramebuffer(context, clippedOffset, + clippedArea, source)); + mDirtyImages = true; + onStateChange(angle::SubjectMessage::DirtyBitsFlagged); + } + else + { + ANGLE_TRY(ensureRenderTarget(context)); + + if (isValidLevel(index.getLevelIndex())) + { + ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex())); + ANGLE_TRY(mRenderer->copyImage2D(context, source, clippedArea, + gl::GetUnsizedFormat(getBaseLevelInternalFormat()), + clippedOffset, mTexStorage, index.getLevelIndex())); + } + } + + return angle::Result::Continue; +} + +angle::Result TextureD3D_2D::copyTexture(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + GLenum type, + GLint sourceLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) +{ + ASSERT(index.getTarget() == gl::TextureTarget::_2D); + + gl::TextureType sourceType = source->getType(); + + const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type); + gl::Extents size( + static_cast(source->getWidth(NonCubeTextureTypeToTarget(sourceType), sourceLevel)), + static_cast(source->getHeight(NonCubeTextureTypeToTarget(sourceType), sourceLevel)), + 1); + ANGLE_TRY(redefineImage(context, index.getLevelIndex(), internalFormatInfo.sizedInternalFormat, + size, false)); + + gl::Box sourceBox(0, 0, 0, size.width, size.height, 1); + gl::Offset destOffset(0, 0, 0); + + if (!isSRGB(index.getLevelIndex()) && canCreateRenderTargetForImage(index)) + { + ANGLE_TRY(ensureRenderTarget(context)); + ASSERT(isValidLevel(index.getLevelIndex())); + ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex())); + + ANGLE_TRY(mRenderer->copyTexture(context, source, sourceLevel, gl::TextureTarget::_2D, + sourceBox, internalFormatInfo.format, + internalFormatInfo.type, destOffset, mTexStorage, + index.getTarget(), index.getLevelIndex(), unpackFlipY, + unpackPremultiplyAlpha, unpackUnmultiplyAlpha)); + } + else + { + gl::ImageIndex sourceImageIndex = gl::ImageIndex::Make2D(sourceLevel); + TextureD3D *sourceD3D = GetImplAs(source); + ImageD3D *sourceImage = nullptr; + ANGLE_TRY(sourceD3D->getImageAndSyncFromStorage(context, sourceImageIndex, &sourceImage)); + + ImageD3D *destImage = nullptr; + ANGLE_TRY(getImageAndSyncFromStorage(context, index, &destImage)); + + ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, sourceBox, destOffset, + unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha)); + + mDirtyImages = true; + + gl::Box destRegion(destOffset, size); + ANGLE_TRY(commitRegion(context, index, destRegion)); + } + + return angle::Result::Continue; +} + +angle::Result TextureD3D_2D::copySubTexture(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Offset &destOffset, + GLint sourceLevel, + const gl::Box &sourceBox, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) +{ + ASSERT(index.getTarget() == gl::TextureTarget::_2D); + + if (!isSRGB(index.getLevelIndex()) && canCreateRenderTargetForImage(index)) + { + ANGLE_TRY(ensureRenderTarget(context)); + ASSERT(isValidLevel(index.getLevelIndex())); + ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex())); + + const gl::InternalFormat &internalFormatInfo = + gl::GetSizedInternalFormatInfo(getInternalFormat(index.getLevelIndex())); + ANGLE_TRY(mRenderer->copyTexture(context, source, sourceLevel, gl::TextureTarget::_2D, + sourceBox, internalFormatInfo.format, + internalFormatInfo.type, destOffset, mTexStorage, + index.getTarget(), index.getLevelIndex(), unpackFlipY, + unpackPremultiplyAlpha, unpackUnmultiplyAlpha)); + } + else + { + gl::ImageIndex sourceImageIndex = gl::ImageIndex::Make2D(sourceLevel); + TextureD3D *sourceD3D = GetImplAs(source); + ImageD3D *sourceImage = nullptr; + ANGLE_TRY(sourceD3D->getImageAndSyncFromStorage(context, sourceImageIndex, &sourceImage)); + + ImageD3D *destImage = nullptr; + ANGLE_TRY(getImageAndSyncFromStorage(context, index, &destImage)); + + ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, sourceBox, destOffset, + unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha)); + + mDirtyImages = true; + + gl::Box destRegion(destOffset.x, destOffset.y, 0, sourceBox.width, sourceBox.height, 1); + ANGLE_TRY(commitRegion(context, index, destRegion)); + } + + return angle::Result::Continue; +} + +angle::Result TextureD3D_2D::copyCompressedTexture(const gl::Context *context, + const gl::Texture *source) +{ + gl::TextureTarget sourceTarget = NonCubeTextureTypeToTarget(source->getType()); + GLint sourceLevel = 0; + + GLint destLevel = 0; + + GLenum sizedInternalFormat = + source->getFormat(sourceTarget, sourceLevel).info->sizedInternalFormat; + gl::Extents size(static_cast(source->getWidth(sourceTarget, sourceLevel)), + static_cast(source->getHeight(sourceTarget, sourceLevel)), 1); + ANGLE_TRY(redefineImage(context, destLevel, sizedInternalFormat, size, false)); + + ANGLE_TRY(initializeStorage(context, BindFlags())); + ASSERT(mTexStorage); + + ANGLE_TRY( + mRenderer->copyCompressedTexture(context, source, sourceLevel, mTexStorage, destLevel)); + + return angle::Result::Continue; +} + +angle::Result TextureD3D_2D::setStorage(const gl::Context *context, + gl::TextureType type, + size_t levels, + GLenum internalFormat, + const gl::Extents &size) +{ + ASSERT(type == gl::TextureType::_2D && size.depth == 1); + + for (size_t level = 0; level < levels; level++) + { + gl::Extents levelSize(std::max(1, size.width >> level), std::max(1, size.height >> level), + 1); + ANGLE_TRY(redefineImage(context, level, internalFormat, levelSize, true)); + } + + for (size_t level = levels; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) + { + ANGLE_TRY(redefineImage(context, level, GL_NONE, gl::Extents(0, 0, 1), true)); + } + + // TODO(geofflang): Verify storage creation had no errors + BindFlags flags; + flags.renderTarget = IsRenderTargetUsage(mState.getUsage()); + TexStoragePointer storage = { + mRenderer->createTextureStorage2D(internalFormat, flags, size.width, size.height, + static_cast(levels), mState.getLabel(), false), + context}; + + ANGLE_TRY(setCompleteTexStorage(context, storage.get())); + storage.release(); + + ANGLE_TRY(updateStorage(context)); + + mImmutable = true; + + return angle::Result::Continue; +} + +angle::Result TextureD3D_2D::bindTexImage(const gl::Context *context, egl::Surface *surface) +{ + GLenum internalformat = surface->getConfig()->renderTargetFormat; + + gl::Extents size(surface->getWidth(), surface->getHeight(), 1); + ANGLE_TRY(redefineImage(context, 0, internalformat, size, true)); + + ANGLE_TRY(releaseTexStorage(context, gl::TexLevelMask())); + + SurfaceD3D *surfaceD3D = GetImplAs(surface); + ASSERT(surfaceD3D); + + mTexStorage = mRenderer->createTextureStorage2D(surfaceD3D->getSwapChain(), mState.getLabel()); + mEGLImageTarget = false; + + mDirtyImages = false; + mImageArray[0]->markClean(); + + return angle::Result::Continue; +} + +angle::Result TextureD3D_2D::releaseTexImage(const gl::Context *context) +{ + if (mTexStorage) + { + ANGLE_TRY(releaseTexStorage(context, gl::TexLevelMask())); + } + + for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) + { + ANGLE_TRY(redefineImage(context, i, GL_NONE, gl::Extents(0, 0, 1), true)); + } + + return angle::Result::Continue; +} + +angle::Result TextureD3D_2D::setEGLImageTarget(const gl::Context *context, + gl::TextureType type, + egl::Image *image) +{ + EGLImageD3D *eglImaged3d = GetImplAs(image); + + // Set the properties of the base mip level from the EGL image + const auto &format = image->getFormat(); + gl::Extents size(static_cast(image->getWidth()), static_cast(image->getHeight()), 1); + ANGLE_TRY(redefineImage(context, 0, format.info->sizedInternalFormat, size, true)); + + // Clear all other images. + for (size_t level = 1; level < mImageArray.size(); level++) + { + ANGLE_TRY(redefineImage(context, level, GL_NONE, gl::Extents(0, 0, 1), true)); + } + + ANGLE_TRY(releaseTexStorage(context, gl::TexLevelMask())); + mImageArray[0]->markClean(); + + // Pass in the RenderTargetD3D here: createTextureStorage can't generate an error. + RenderTargetD3D *renderTargetD3D = nullptr; + ANGLE_TRY(eglImaged3d->getRenderTarget(context, &renderTargetD3D)); + + mTexStorage = + mRenderer->createTextureStorageEGLImage(eglImaged3d, renderTargetD3D, mState.getLabel()); + mEGLImageTarget = true; + + return angle::Result::Continue; +} + +angle::Result TextureD3D_2D::initMipmapImages(const gl::Context *context) +{ + const GLuint baseLevel = mState.getEffectiveBaseLevel(); + const GLuint maxLevel = mState.getMipmapMaxLevel(); + // Purge array levels baseLevel + 1 through q and reset them to represent the generated mipmap + // levels. + for (GLuint level = baseLevel + 1; level <= maxLevel; level++) + { + gl::Extents levelSize(std::max(getLevelZeroWidth() >> level, 1), + std::max(getLevelZeroHeight() >> level, 1), 1); + + ANGLE_TRY(redefineImage(context, level, getBaseLevelInternalFormat(), levelSize, false)); + } + + // We should be mip-complete now so generate the storage. + ANGLE_TRY(initializeStorage(context, BindFlags::RenderTarget())); + + return angle::Result::Continue; +} + +angle::Result TextureD3D_2D::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) +{ + ASSERT(!index.hasLayer()); + + // ensure the underlying texture is created + ANGLE_TRY(ensureRenderTarget(context)); + ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex())); + + return mTexStorage->getRenderTarget(context, index, samples, outRT); +} + +bool TextureD3D_2D::isValidLevel(int level) const +{ + return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : false); +} + +bool TextureD3D_2D::isLevelComplete(int level) const +{ + if (isImmutable()) + { + return true; + } + + GLsizei width = getLevelZeroWidth(); + GLsizei height = getLevelZeroHeight(); + + if (width <= 0 || height <= 0) + { + return false; + } + + // The base image level is complete if the width and height are positive + if (level == static_cast(getBaseLevel())) + { + return true; + } + + ASSERT(level >= 0 && level <= static_cast(mImageArray.size()) && + mImageArray[level] != nullptr); + ImageD3D *image = mImageArray[level].get(); + + if (image->getInternalFormat() != getBaseLevelInternalFormat()) + { + return false; + } + + if (image->getWidth() != std::max(1, width >> level)) + { + return false; + } + + if (image->getHeight() != std::max(1, height >> level)) + { + return false; + } + + return true; +} + +bool TextureD3D_2D::isImageComplete(const gl::ImageIndex &index) const +{ + return isLevelComplete(index.getLevelIndex()); +} + +// Constructs a native texture resource from the texture images +angle::Result TextureD3D_2D::initializeStorage(const gl::Context *context, BindFlags bindFlags) +{ + // Only initialize the first time this texture is used as a render target or shader resource + if (mTexStorage) + { + return angle::Result::Continue; + } + + // do not attempt to create storage for nonexistant data + if (!isLevelComplete(getBaseLevel())) + { + return angle::Result::Continue; + } + + bindFlags.renderTarget |= IsRenderTargetUsage(mState.getUsage()); + + TexStoragePointer storage; + ANGLE_TRY(createCompleteStorage(context, bindFlags, &storage)); + + ANGLE_TRY(setCompleteTexStorage(context, storage.get())); + storage.release(); + + ASSERT(mTexStorage); + + // flush image data to the storage + ANGLE_TRY(updateStorage(context)); + + return angle::Result::Continue; +} + +angle::Result TextureD3D_2D::createCompleteStorage(const gl::Context *context, + BindFlags bindFlags, + TexStoragePointer *outStorage) const +{ + GLsizei width = getLevelZeroWidth(); + GLsizei height = getLevelZeroHeight(); + GLenum internalFormat = getBaseLevelInternalFormat(); + + ASSERT(width > 0 && height > 0); + + // use existing storage level count, when previously specified by TexStorage*D + GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, 1)); + + bool hintLevelZeroOnly = false; + if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled) + { + // If any of the CPU images (levels >= 1) are dirty, then the textureStorage2D should use + // the mipped texture to begin with. Otherwise, it should use the level-zero-only texture. + hintLevelZeroOnly = true; + for (int level = 1; level < levels && hintLevelZeroOnly; level++) + { + hintLevelZeroOnly = !(mImageArray[level]->isDirty() && isLevelComplete(level)); + } + } + + // TODO(geofflang): Determine if the texture creation succeeded + *outStorage = {mRenderer->createTextureStorage2D(internalFormat, bindFlags, width, height, + levels, mState.getLabel(), hintLevelZeroOnly), + context}; + + return angle::Result::Continue; +} + +angle::Result TextureD3D_2D::setCompleteTexStorage(const gl::Context *context, + TextureStorage *newCompleteTexStorage) +{ + if (newCompleteTexStorage && newCompleteTexStorage->isManaged()) + { + for (int level = 0; level < newCompleteTexStorage->getLevelCount(); level++) + { + ANGLE_TRY( + mImageArray[level]->setManagedSurface2D(context, newCompleteTexStorage, level)); + } + } + + gl::TexLevelMask copyImageMask; + copyImageMask.set(); + + ANGLE_TRY(releaseTexStorage(context, copyImageMask)); + mTexStorage = newCompleteTexStorage; + mTexStorageObserverBinding.bind(mTexStorage); + + mDirtyImages = true; + + return angle::Result::Continue; +} + +angle::Result TextureD3D_2D::updateStorage(const gl::Context *context) +{ + if (!mDirtyImages) + { + return angle::Result::Continue; + } + + ASSERT(mTexStorage != nullptr); + GLint storageLevels = mTexStorage->getLevelCount(); + for (int level = 0; level < storageLevels; level++) + { + if (mImageArray[level]->isDirty() && isLevelComplete(level)) + { + ANGLE_TRY(updateStorageLevel(context, level)); + } + } + + mDirtyImages = false; + return angle::Result::Continue; +} + +angle::Result TextureD3D_2D::updateStorageLevel(const gl::Context *context, int level) +{ + ASSERT(level <= static_cast(mImageArray.size()) && mImageArray[level] != nullptr); + ASSERT(isLevelComplete(level)); + + if (mImageArray[level]->isDirty()) + { + gl::ImageIndex index = gl::ImageIndex::Make2D(level); + gl::Box region(0, 0, 0, getWidth(level), getHeight(level), 1); + ANGLE_TRY(commitRegion(context, index, region)); + } + + return angle::Result::Continue; +} + +angle::Result TextureD3D_2D::redefineImage(const gl::Context *context, + size_t level, + GLenum internalformat, + const gl::Extents &size, + bool forceRelease) +{ + ASSERT(size.depth == 1); + + // If there currently is a corresponding storage texture image, it has these parameters + const int storageWidth = std::max(1, getLevelZeroWidth() >> level); + const int storageHeight = std::max(1, getLevelZeroHeight() >> level); + const GLenum storageFormat = getBaseLevelInternalFormat(); + + if (mTexStorage) + { + const size_t storageLevels = mTexStorage->getLevelCount(); + + // If the storage was from an EGL image, copy it back into local images to preserve it + // while orphaning + if (level != 0 && mEGLImageTarget) + { + ANGLE_TRY(mImageArray[0]->copyFromTexStorage(context, gl::ImageIndex::Make2D(0), + mTexStorage)); + } + + if ((level >= storageLevels && storageLevels != 0) || size.width != storageWidth || + size.height != storageHeight || internalformat != storageFormat || + mEGLImageTarget) // Discard mismatched storage + { + gl::TexLevelMask copyImageMask; + copyImageMask.set(); + copyImageMask.set(level, false); + + ANGLE_TRY(releaseTexStorage(context, copyImageMask)); + markAllImagesDirty(); + } + } + + mImageArray[level]->redefine(gl::TextureType::_2D, internalformat, size, forceRelease); + mDirtyImages = mDirtyImages || mImageArray[level]->isDirty(); + + // Can't be an EGL image target after being redefined + mEGLImageTarget = false; + + return angle::Result::Continue; +} + +gl::ImageIndexIterator TextureD3D_2D::imageIterator() const +{ + return gl::ImageIndexIterator::Make2D(0, mTexStorage->getLevelCount()); +} + +gl::ImageIndex TextureD3D_2D::getImageIndex(GLint mip, GLint /*layer*/) const +{ + // "layer" does not apply to 2D Textures. + return gl::ImageIndex::Make2D(mip); +} + +bool TextureD3D_2D::isValidIndex(const gl::ImageIndex &index) const +{ + return (mTexStorage && index.getType() == gl::TextureType::_2D && index.getLevelIndex() >= 0 && + index.getLevelIndex() < mTexStorage->getLevelCount()); +} + +void TextureD3D_2D::markAllImagesDirty() +{ + for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) + { + mImageArray[i]->markDirty(); + } + mDirtyImages = true; +} + +TextureD3D_Cube::TextureD3D_Cube(const gl::TextureState &state, RendererD3D *renderer) + : TextureD3D(state, renderer) +{ + for (auto &face : mImageArray) + { + for (auto &image : face) + { + image.reset(renderer->createImage()); + } + } +} + +void TextureD3D_Cube::onDestroy(const gl::Context *context) +{ + // Delete the Images before the TextureStorage. Images might be relying on the TextureStorage + // for some of their data. If TextureStorage is deleted before the Images, then their data will + // be wastefully copied back from the GPU before we delete the Images. + for (auto &face : mImageArray) + { + for (auto &image : face) + { + image.reset(); + } + } + return TextureD3D::onDestroy(context); +} + +TextureD3D_Cube::~TextureD3D_Cube() {} + +ImageD3D *TextureD3D_Cube::getImage(int level, int layer) const +{ + ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + ASSERT(layer >= 0 && static_cast(layer) < gl::kCubeFaceCount); + return mImageArray[layer][level].get(); +} + +ImageD3D *TextureD3D_Cube::getImage(const gl::ImageIndex &index) const +{ + ASSERT(index.getLevelIndex() < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + ASSERT(gl::IsCubeMapFaceTarget(index.getTarget())); + return mImageArray[index.cubeMapFaceIndex()][index.getLevelIndex()].get(); +} + +GLsizei TextureD3D_Cube::getLayerCount(int level) const +{ + ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + return gl::kCubeFaceCount; +} + +GLenum TextureD3D_Cube::getInternalFormat(GLint level, GLint layer) const +{ + if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + return mImageArray[layer][level]->getInternalFormat(); + else + return GL_NONE; +} + +bool TextureD3D_Cube::isDepth(GLint level, GLint layer) const +{ + return gl::GetSizedInternalFormatInfo(getInternalFormat(level, layer)).depthBits > 0; +} + +bool TextureD3D_Cube::isSRGB(GLint level, GLint layer) const +{ + return gl::GetSizedInternalFormatInfo(getInternalFormat(level, layer)).colorEncoding == GL_SRGB; +} + +angle::Result TextureD3D_Cube::setEGLImageTarget(const gl::Context *context, + gl::TextureType type, + egl::Image *image) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3D_Cube::setImage(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + const gl::Extents &size, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels) +{ + ASSERT(size.depth == 1); + + const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type); + ANGLE_TRY(redefineImage(context, index.cubeMapFaceIndex(), index.getLevelIndex(), + internalFormatInfo.sizedInternalFormat, size, false)); + + return setImageImpl(context, index, type, unpack, unpackBuffer, pixels, 0); +} + +angle::Result TextureD3D_Cube::setSubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels) +{ + ASSERT(area.depth == 1 && area.z == 0); + return TextureD3D::subImage(context, index, area, format, type, unpack, unpackBuffer, pixels, + 0); +} + +angle::Result TextureD3D_Cube::setCompressedImage(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + const gl::Extents &size, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) +{ + ASSERT(size.depth == 1); + + // compressed formats don't have separate sized internal formats-- we can just use the + // compressed format directly + ANGLE_TRY(redefineImage(context, index.cubeMapFaceIndex(), index.getLevelIndex(), + internalFormat, size, false)); + + return setCompressedImageImpl(context, index, unpack, pixels, 0); +} + +angle::Result TextureD3D_Cube::setCompressedSubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) +{ + ASSERT(area.depth == 1 && area.z == 0); + + ANGLE_TRY(TextureD3D::subImageCompressed(context, index, area, format, unpack, pixels, 0)); + return commitRegion(context, index, area); +} + +angle::Result TextureD3D_Cube::copyImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Rectangle &sourceArea, + GLenum internalFormat, + gl::Framebuffer *source) +{ + GLint faceIndex = index.cubeMapFaceIndex(); + const gl::InternalFormat &internalFormatInfo = + gl::GetInternalFormatInfo(internalFormat, GL_UNSIGNED_BYTE); + + gl::Extents size(sourceArea.width, sourceArea.height, 1); + ANGLE_TRY(redefineImage(context, faceIndex, index.getLevelIndex(), + internalFormatInfo.sizedInternalFormat, size, false)); + + gl::Extents fbSize = source->getReadColorAttachment()->getSize(); + + // Does the read area extend beyond the framebuffer? + bool outside = sourceArea.x < 0 || sourceArea.y < 0 || + sourceArea.x + sourceArea.width > fbSize.width || + sourceArea.y + sourceArea.height > fbSize.height; + + // WebGL requires that pixels that would be outside the framebuffer are treated as zero values, + // so clear the mip level to 0 prior to making the copy if any pixel would be sampled outside. + // Same thing for robust resource init. + if (outside && (context->isWebGL() || context->isRobustResourceInitEnabled())) + { + ANGLE_TRY(initializeContents(context, GL_NONE, index)); + } + + gl::Rectangle clippedArea; + if (!ClipRectangle(sourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height), &clippedArea)) + { + // Empty source area, nothing to do. + return angle::Result::Continue; + } + + gl::Offset destOffset(clippedArea.x - sourceArea.x, clippedArea.y - sourceArea.y, 0); + + // If the zero max LOD workaround is active, then we can't sample from individual layers of the + // framebuffer in shaders, so we should use the non-rendering copy path. + if (!canCreateRenderTargetForImage(index) || + mRenderer->getFeatures().zeroMaxLodWorkaround.enabled) + { + ANGLE_TRY(mImageArray[faceIndex][index.getLevelIndex()]->copyFromFramebuffer( + context, destOffset, clippedArea, source)); + mDirtyImages = true; + onStateChange(angle::SubjectMessage::DirtyBitsFlagged); + } + else + { + ANGLE_TRY(ensureRenderTarget(context)); + + ASSERT(size.width == size.height); + + if (size.width > 0 && isValidFaceLevel(faceIndex, index.getLevelIndex())) + { + ANGLE_TRY(updateStorageFaceLevel(context, faceIndex, index.getLevelIndex())); + ANGLE_TRY(mRenderer->copyImageCube(context, source, clippedArea, internalFormat, + destOffset, mTexStorage, index.getTarget(), + index.getLevelIndex())); + } + } + + return angle::Result::Continue; +} + +angle::Result TextureD3D_Cube::copySubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + gl::Framebuffer *source) +{ + gl::Extents fbSize = source->getReadColorAttachment()->getSize(); + gl::Rectangle clippedArea; + if (!ClipRectangle(sourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height), &clippedArea)) + { + return angle::Result::Continue; + } + const gl::Offset clippedOffset(destOffset.x + clippedArea.x - sourceArea.x, + destOffset.y + clippedArea.y - sourceArea.y, 0); + + GLint faceIndex = index.cubeMapFaceIndex(); + + // If the zero max LOD workaround is active, then we can't sample from individual layers of the + // framebuffer in shaders, so we should use the non-rendering copy path. + if (!canCreateRenderTargetForImage(index) || + mRenderer->getFeatures().zeroMaxLodWorkaround.enabled) + { + ANGLE_TRY(mImageArray[faceIndex][index.getLevelIndex()]->copyFromFramebuffer( + context, clippedOffset, clippedArea, source)); + mDirtyImages = true; + onStateChange(angle::SubjectMessage::DirtyBitsFlagged); + } + else + { + ANGLE_TRY(ensureRenderTarget(context)); + if (isValidFaceLevel(faceIndex, index.getLevelIndex())) + { + ANGLE_TRY(updateStorageFaceLevel(context, faceIndex, index.getLevelIndex())); + ANGLE_TRY(mRenderer->copyImageCube( + context, source, clippedArea, gl::GetUnsizedFormat(getBaseLevelInternalFormat()), + clippedOffset, mTexStorage, index.getTarget(), index.getLevelIndex())); + } + } + + return angle::Result::Continue; +} + +angle::Result TextureD3D_Cube::copyTexture(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + GLenum type, + GLint sourceLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) +{ + ASSERT(gl::IsCubeMapFaceTarget(index.getTarget())); + + gl::TextureTarget sourceTarget = NonCubeTextureTypeToTarget(source->getType()); + + GLint faceIndex = index.cubeMapFaceIndex(); + + const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type); + gl::Extents size(static_cast(source->getWidth(sourceTarget, sourceLevel)), + static_cast(source->getHeight(sourceTarget, sourceLevel)), 1); + ANGLE_TRY(redefineImage(context, faceIndex, index.getLevelIndex(), + internalFormatInfo.sizedInternalFormat, size, false)); + + gl::Box sourceBox(0, 0, 0, size.width, size.height, 1); + gl::Offset destOffset(0, 0, 0); + + if (!isSRGB(index.getLevelIndex(), faceIndex) && canCreateRenderTargetForImage(index)) + { + + ANGLE_TRY(ensureRenderTarget(context)); + ASSERT(isValidFaceLevel(faceIndex, index.getLevelIndex())); + ANGLE_TRY(updateStorageFaceLevel(context, faceIndex, index.getLevelIndex())); + + ANGLE_TRY(mRenderer->copyTexture(context, source, sourceLevel, gl::TextureTarget::_2D, + sourceBox, internalFormatInfo.format, + internalFormatInfo.type, destOffset, mTexStorage, + index.getTarget(), index.getLevelIndex(), unpackFlipY, + unpackPremultiplyAlpha, unpackUnmultiplyAlpha)); + } + else + { + gl::ImageIndex sourceImageIndex = gl::ImageIndex::Make2D(sourceLevel); + TextureD3D *sourceD3D = GetImplAs(source); + ImageD3D *sourceImage = nullptr; + ANGLE_TRY(sourceD3D->getImageAndSyncFromStorage(context, sourceImageIndex, &sourceImage)); + + ImageD3D *destImage = nullptr; + ANGLE_TRY(getImageAndSyncFromStorage(context, index, &destImage)); + + ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, sourceBox, destOffset, + unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha)); + + mDirtyImages = true; + + gl::Box destRegion(destOffset, size); + ANGLE_TRY(commitRegion(context, index, destRegion)); + } + + return angle::Result::Continue; +} + +angle::Result TextureD3D_Cube::copySubTexture(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Offset &destOffset, + GLint sourceLevel, + const gl::Box &sourceBox, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) +{ + ASSERT(gl::IsCubeMapFaceTarget(index.getTarget())); + + GLint faceIndex = index.cubeMapFaceIndex(); + + if (!isSRGB(index.getLevelIndex(), faceIndex) && canCreateRenderTargetForImage(index)) + { + ANGLE_TRY(ensureRenderTarget(context)); + ASSERT(isValidFaceLevel(faceIndex, index.getLevelIndex())); + ANGLE_TRY(updateStorageFaceLevel(context, faceIndex, index.getLevelIndex())); + + const gl::InternalFormat &internalFormatInfo = + gl::GetSizedInternalFormatInfo(getInternalFormat(index.getLevelIndex(), faceIndex)); + ANGLE_TRY(mRenderer->copyTexture(context, source, sourceLevel, gl::TextureTarget::_2D, + sourceBox, internalFormatInfo.format, + internalFormatInfo.type, destOffset, mTexStorage, + index.getTarget(), index.getLevelIndex(), unpackFlipY, + unpackPremultiplyAlpha, unpackUnmultiplyAlpha)); + } + else + { + gl::ImageIndex sourceImageIndex = gl::ImageIndex::Make2D(sourceLevel); + TextureD3D *sourceD3D = GetImplAs(source); + ImageD3D *sourceImage = nullptr; + ANGLE_TRY(sourceD3D->getImageAndSyncFromStorage(context, sourceImageIndex, &sourceImage)); + + ImageD3D *destImage = nullptr; + ANGLE_TRY(getImageAndSyncFromStorage(context, index, &destImage)); + + ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, sourceBox, destOffset, + unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha)); + + mDirtyImages = true; + + gl::Box destRegion(destOffset.x, destOffset.y, 0, sourceBox.width, sourceBox.height, 1); + ANGLE_TRY(commitRegion(context, index, destRegion)); + } + + return angle::Result::Continue; +} + +angle::Result TextureD3D_Cube::setStorage(const gl::Context *context, + gl::TextureType type, + size_t levels, + GLenum internalFormat, + const gl::Extents &size) +{ + ASSERT(size.width == size.height); + ASSERT(size.depth == 1); + + for (size_t level = 0; level < levels; level++) + { + GLsizei mipSize = std::max(1, size.width >> level); + for (size_t faceIndex = 0; faceIndex < gl::kCubeFaceCount; faceIndex++) + { + mImageArray[faceIndex][level]->redefine(gl::TextureType::CubeMap, internalFormat, + gl::Extents(mipSize, mipSize, 1), true); + } + } + + for (size_t level = levels; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) + { + for (size_t faceIndex = 0; faceIndex < gl::kCubeFaceCount; faceIndex++) + { + mImageArray[faceIndex][level]->redefine(gl::TextureType::CubeMap, GL_NONE, + gl::Extents(0, 0, 0), true); + } + } + + // TODO(geofflang): Verify storage creation had no errors + BindFlags bindFlags; + bindFlags.renderTarget = IsRenderTargetUsage(mState.getUsage()); + + TexStoragePointer storage = { + mRenderer->createTextureStorageCube(internalFormat, bindFlags, size.width, + static_cast(levels), false, mState.getLabel()), + context}; + + ANGLE_TRY(setCompleteTexStorage(context, storage.get())); + storage.release(); + + ANGLE_TRY(updateStorage(context)); + + mImmutable = true; + + return angle::Result::Continue; +} + +// Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81. +bool TextureD3D_Cube::isCubeComplete() const +{ + int baseWidth = getBaseLevelWidth(); + int baseHeight = getBaseLevelHeight(); + GLenum baseFormat = getBaseLevelInternalFormat(); + + if (baseWidth <= 0 || baseWidth != baseHeight) + { + return false; + } + + for (size_t faceIndex = 1; faceIndex < gl::kCubeFaceCount; faceIndex++) + { + const ImageD3D &faceBaseImage = *mImageArray[faceIndex][getBaseLevel()]; + + if (faceBaseImage.getWidth() != baseWidth || faceBaseImage.getHeight() != baseHeight || + faceBaseImage.getInternalFormat() != baseFormat) + { + return false; + } + } + + return true; +} + +angle::Result TextureD3D_Cube::bindTexImage(const gl::Context *context, egl::Surface *surface) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3D_Cube::releaseTexImage(const gl::Context *context) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3D_Cube::initMipmapImages(const gl::Context *context) +{ + const GLuint baseLevel = mState.getEffectiveBaseLevel(); + const GLuint maxLevel = mState.getMipmapMaxLevel(); + // Purge array levels baseLevel + 1 through q and reset them to represent the generated mipmap + // levels. + for (int faceIndex = 0; faceIndex < static_cast(gl::kCubeFaceCount); faceIndex++) + { + for (GLuint level = baseLevel + 1; level <= maxLevel; level++) + { + int faceLevelSize = + (std::max(mImageArray[faceIndex][baseLevel]->getWidth() >> (level - baseLevel), 1)); + ANGLE_TRY(redefineImage(context, faceIndex, level, + mImageArray[faceIndex][baseLevel]->getInternalFormat(), + gl::Extents(faceLevelSize, faceLevelSize, 1), false)); + } + } + + // We should be mip-complete now so generate the storage. + ANGLE_TRY(initializeStorage(context, BindFlags::RenderTarget())); + + return angle::Result::Continue; +} + +angle::Result TextureD3D_Cube::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) +{ + ASSERT(gl::IsCubeMapFaceTarget(index.getTarget())); + + // ensure the underlying texture is created + ANGLE_TRY(ensureRenderTarget(context)); + ANGLE_TRY(updateStorageFaceLevel(context, index.cubeMapFaceIndex(), index.getLevelIndex())); + + return mTexStorage->getRenderTarget(context, index, samples, outRT); +} + +angle::Result TextureD3D_Cube::initializeStorage(const gl::Context *context, BindFlags bindFlags) +{ + // Only initialize the first time this texture is used as a render target or shader resource + if (mTexStorage) + { + return angle::Result::Continue; + } + + // do not attempt to create storage for nonexistant data + if (!isFaceLevelComplete(0, getBaseLevel())) + { + return angle::Result::Continue; + } + + bindFlags.renderTarget |= IsRenderTargetUsage(mState.getUsage()); + + TexStoragePointer storage; + ANGLE_TRY(createCompleteStorage(context, bindFlags, &storage)); + + ANGLE_TRY(setCompleteTexStorage(context, storage.get())); + storage.release(); + + ASSERT(mTexStorage); + + // flush image data to the storage + ANGLE_TRY(updateStorage(context)); + + return angle::Result::Continue; +} + +angle::Result TextureD3D_Cube::createCompleteStorage(const gl::Context *context, + BindFlags bindFlags, + TexStoragePointer *outStorage) const +{ + GLsizei size = getLevelZeroWidth(); + + ASSERT(size > 0); + + // use existing storage level count, when previously specified by TexStorage*D + GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(size, size, 1)); + + bool hintLevelZeroOnly = false; + if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled) + { + // If any of the CPU images (levels >= 1) are dirty, then the textureStorageEXT should use + // the mipped texture to begin with. Otherwise, it should use the level-zero-only texture. + hintLevelZeroOnly = true; + for (int faceIndex = 0; + faceIndex < static_cast(gl::kCubeFaceCount) && hintLevelZeroOnly; faceIndex++) + { + for (int level = 1; level < levels && hintLevelZeroOnly; level++) + { + hintLevelZeroOnly = !(mImageArray[faceIndex][level]->isDirty() && + isFaceLevelComplete(faceIndex, level)); + } + } + } + + // TODO (geofflang): detect if storage creation succeeded + *outStorage = { + mRenderer->createTextureStorageCube(getBaseLevelInternalFormat(), bindFlags, size, levels, + hintLevelZeroOnly, mState.getLabel()), + context}; + + return angle::Result::Continue; +} + +angle::Result TextureD3D_Cube::setCompleteTexStorage(const gl::Context *context, + TextureStorage *newCompleteTexStorage) +{ + if (newCompleteTexStorage && newCompleteTexStorage->isManaged()) + { + for (int faceIndex = 0; faceIndex < static_cast(gl::kCubeFaceCount); faceIndex++) + { + for (int level = 0; level < newCompleteTexStorage->getLevelCount(); level++) + { + ANGLE_TRY(mImageArray[faceIndex][level]->setManagedSurfaceCube( + context, newCompleteTexStorage, faceIndex, level)); + } + } + } + + gl::TexLevelMask copyImageMask; + copyImageMask.set(); + + ANGLE_TRY(releaseTexStorage(context, copyImageMask)); + mTexStorage = newCompleteTexStorage; + mTexStorageObserverBinding.bind(mTexStorage); + + mDirtyImages = true; + return angle::Result::Continue; +} + +angle::Result TextureD3D_Cube::updateStorage(const gl::Context *context) +{ + if (!mDirtyImages) + { + return angle::Result::Continue; + } + + ASSERT(mTexStorage != nullptr); + GLint storageLevels = mTexStorage->getLevelCount(); + for (int face = 0; face < static_cast(gl::kCubeFaceCount); face++) + { + for (int level = 0; level < storageLevels; level++) + { + if (mImageArray[face][level]->isDirty() && isFaceLevelComplete(face, level)) + { + ANGLE_TRY(updateStorageFaceLevel(context, face, level)); + } + } + } + + mDirtyImages = false; + return angle::Result::Continue; +} + +bool TextureD3D_Cube::isValidFaceLevel(int faceIndex, int level) const +{ + return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : 0); +} + +bool TextureD3D_Cube::isFaceLevelComplete(int faceIndex, int level) const +{ + if (getBaseLevel() >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + return false; + } + ASSERT(level >= 0 && static_cast(faceIndex) < gl::kCubeFaceCount && + level < static_cast(mImageArray[faceIndex].size()) && + mImageArray[faceIndex][level] != nullptr); + + if (isImmutable()) + { + return true; + } + + int levelZeroSize = getLevelZeroWidth(); + + if (levelZeroSize <= 0) + { + return false; + } + + // Check that non-zero levels are consistent with the base level. + const ImageD3D *faceLevelImage = mImageArray[faceIndex][level].get(); + + if (faceLevelImage->getInternalFormat() != getBaseLevelInternalFormat()) + { + return false; + } + + if (faceLevelImage->getWidth() != std::max(1, levelZeroSize >> level)) + { + return false; + } + + return true; +} + +bool TextureD3D_Cube::isImageComplete(const gl::ImageIndex &index) const +{ + return isFaceLevelComplete(index.cubeMapFaceIndex(), index.getLevelIndex()); +} + +angle::Result TextureD3D_Cube::updateStorageFaceLevel(const gl::Context *context, + int faceIndex, + int level) +{ + ASSERT(level >= 0 && static_cast(faceIndex) < gl::kCubeFaceCount && + level < static_cast(mImageArray[faceIndex].size()) && + mImageArray[faceIndex][level] != nullptr); + ImageD3D *image = mImageArray[faceIndex][level].get(); + + if (image->isDirty()) + { + gl::TextureTarget faceTarget = gl::CubeFaceIndexToTextureTarget(faceIndex); + gl::ImageIndex index = gl::ImageIndex::MakeCubeMapFace(faceTarget, level); + gl::Box region(0, 0, 0, image->getWidth(), image->getHeight(), 1); + ANGLE_TRY(commitRegion(context, index, region)); + } + + return angle::Result::Continue; +} + +angle::Result TextureD3D_Cube::redefineImage(const gl::Context *context, + int faceIndex, + GLint level, + GLenum internalformat, + const gl::Extents &size, + bool forceRelease) +{ + // If there currently is a corresponding storage texture image, it has these parameters + const int storageWidth = std::max(1, getLevelZeroWidth() >> level); + const int storageHeight = std::max(1, getLevelZeroHeight() >> level); + const GLenum storageFormat = getBaseLevelInternalFormat(); + + if (mTexStorage) + { + const int storageLevels = mTexStorage->getLevelCount(); + + if ((level >= storageLevels && storageLevels != 0) || size.width != storageWidth || + size.height != storageHeight || + internalformat != storageFormat) // Discard mismatched storage + { + markAllImagesDirty(); + + gl::TexLevelMask copyImageMask; + copyImageMask.set(); + copyImageMask.set(level, false); + + ANGLE_TRY(releaseTexStorage(context, copyImageMask)); + } + } + + mImageArray[faceIndex][level]->redefine(gl::TextureType::CubeMap, internalformat, size, + forceRelease); + mDirtyImages = mDirtyImages || mImageArray[faceIndex][level]->isDirty(); + + return angle::Result::Continue; +} + +gl::ImageIndexIterator TextureD3D_Cube::imageIterator() const +{ + return gl::ImageIndexIterator::MakeCube(0, mTexStorage->getLevelCount()); +} + +gl::ImageIndex TextureD3D_Cube::getImageIndex(GLint mip, GLint layer) const +{ + // The "layer" of the image index corresponds to the cube face + return gl::ImageIndex::MakeCubeMapFace(gl::CubeFaceIndexToTextureTarget(layer), mip); +} + +bool TextureD3D_Cube::isValidIndex(const gl::ImageIndex &index) const +{ + return (mTexStorage && index.getType() == gl::TextureType::CubeMap && + gl::IsCubeMapFaceTarget(index.getTarget()) && index.getLevelIndex() >= 0 && + index.getLevelIndex() < mTexStorage->getLevelCount()); +} + +void TextureD3D_Cube::markAllImagesDirty() +{ + for (int dirtyLevel = 0; dirtyLevel < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; dirtyLevel++) + { + for (size_t dirtyFace = 0; dirtyFace < gl::kCubeFaceCount; dirtyFace++) + { + mImageArray[dirtyFace][dirtyLevel]->markDirty(); + } + } + mDirtyImages = true; +} + +TextureD3D_3D::TextureD3D_3D(const gl::TextureState &state, RendererD3D *renderer) + : TextureD3D(state, renderer) +{ + for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i) + { + mImageArray[i].reset(renderer->createImage()); + } +} + +void TextureD3D_3D::onDestroy(const gl::Context *context) +{ + // Delete the Images before the TextureStorage. Images might be relying on the TextureStorage + // for some of their data. If TextureStorage is deleted before the Images, then their data will + // be wastefully copied back from the GPU before we delete the Images. + for (auto &image : mImageArray) + { + image.reset(); + } + return TextureD3D::onDestroy(context); +} + +TextureD3D_3D::~TextureD3D_3D() {} + +ImageD3D *TextureD3D_3D::getImage(int level, int layer) const +{ + ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + ASSERT(layer == 0); + return mImageArray[level].get(); +} + +ImageD3D *TextureD3D_3D::getImage(const gl::ImageIndex &index) const +{ + ASSERT(index.getLevelIndex() < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + ASSERT(!index.hasLayer()); + ASSERT(index.getType() == gl::TextureType::_3D); + return mImageArray[index.getLevelIndex()].get(); +} + +GLsizei TextureD3D_3D::getLayerCount(int level) const +{ + ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + return 1; +} + +GLsizei TextureD3D_3D::getWidth(GLint level) const +{ + if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + return mImageArray[level]->getWidth(); + else + return 0; +} + +GLsizei TextureD3D_3D::getHeight(GLint level) const +{ + if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + return mImageArray[level]->getHeight(); + else + return 0; +} + +GLsizei TextureD3D_3D::getDepth(GLint level) const +{ + if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + return mImageArray[level]->getDepth(); + else + return 0; +} + +GLenum TextureD3D_3D::getInternalFormat(GLint level) const +{ + if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + return mImageArray[level]->getInternalFormat(); + else + return GL_NONE; +} + +bool TextureD3D_3D::isDepth(GLint level) const +{ + return gl::GetSizedInternalFormatInfo(getInternalFormat(level)).depthBits > 0; +} + +bool TextureD3D_3D::isSRGB(GLint level) const +{ + return gl::GetSizedInternalFormatInfo(getInternalFormat(level)).colorEncoding == GL_SRGB; +} + +angle::Result TextureD3D_3D::setEGLImageTarget(const gl::Context *context, + gl::TextureType type, + egl::Image *image) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3D_3D::setImage(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + const gl::Extents &size, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels) +{ + ASSERT(index.getTarget() == gl::TextureTarget::_3D); + const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type); + + ANGLE_TRY(redefineImage(context, index.getLevelIndex(), internalFormatInfo.sizedInternalFormat, + size, false)); + + bool fastUnpacked = false; + + // Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer + if (isFastUnpackable(unpackBuffer, unpack, internalFormatInfo.sizedInternalFormat) && + !size.empty() && isLevelComplete(index.getLevelIndex())) + { + // Will try to create RT storage if it does not exist + RenderTargetD3D *destRenderTarget = nullptr; + ANGLE_TRY(getRenderTarget(context, index, getRenderToTextureSamples(), &destRenderTarget)); + + gl::Box destArea(0, 0, 0, getWidth(index.getLevelIndex()), getHeight(index.getLevelIndex()), + getDepth(index.getLevelIndex())); + + ANGLE_TRY(fastUnpackPixels(context, unpack, unpackBuffer, pixels, destArea, + internalFormatInfo.sizedInternalFormat, type, destRenderTarget)); + + // Ensure we don't overwrite our newly initialized data + mImageArray[index.getLevelIndex()]->markClean(); + + fastUnpacked = true; + } + + if (!fastUnpacked) + { + ANGLE_TRY(setImageImpl(context, index, type, unpack, unpackBuffer, pixels, 0)); + } + + return angle::Result::Continue; +} + +angle::Result TextureD3D_3D::setSubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels) +{ + ASSERT(index.getTarget() == gl::TextureTarget::_3D); + + // Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer + GLenum mipFormat = getInternalFormat(index.getLevelIndex()); + if (isFastUnpackable(unpackBuffer, unpack, mipFormat) && isLevelComplete(index.getLevelIndex())) + { + RenderTargetD3D *destRenderTarget = nullptr; + ANGLE_TRY(getRenderTarget(context, index, getRenderToTextureSamples(), &destRenderTarget)); + ASSERT(!mImageArray[index.getLevelIndex()]->isDirty()); + + return fastUnpackPixels(context, unpack, unpackBuffer, pixels, area, mipFormat, type, + destRenderTarget); + } + else + { + return TextureD3D::subImage(context, index, area, format, type, unpack, unpackBuffer, + pixels, 0); + } +} + +angle::Result TextureD3D_3D::setCompressedImage(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + const gl::Extents &size, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) +{ + ASSERT(index.getTarget() == gl::TextureTarget::_3D); + + // compressed formats don't have separate sized internal formats-- we can just use the + // compressed format directly + ANGLE_TRY(redefineImage(context, index.getLevelIndex(), internalFormat, size, false)); + + return setCompressedImageImpl(context, index, unpack, pixels, 0); +} + +angle::Result TextureD3D_3D::setCompressedSubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) +{ + ASSERT(index.getTarget() == gl::TextureTarget::_3D); + + ANGLE_TRY(TextureD3D::subImageCompressed(context, index, area, format, unpack, pixels, 0)); + return commitRegion(context, index, area); +} + +angle::Result TextureD3D_3D::copyImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Rectangle &sourceArea, + GLenum internalFormat, + gl::Framebuffer *source) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3D_3D::copySubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + gl::Framebuffer *source) +{ + ASSERT(index.getTarget() == gl::TextureTarget::_3D); + + gl::Extents fbSize = source->getReadColorAttachment()->getSize(); + gl::Rectangle clippedSourceArea; + if (!ClipRectangle(sourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height), + &clippedSourceArea)) + { + return angle::Result::Continue; + } + const gl::Offset clippedDestOffset(destOffset.x + clippedSourceArea.x - sourceArea.x, + destOffset.y + clippedSourceArea.y - sourceArea.y, + destOffset.z); + + // Currently, copying directly to the storage is not possible because it's not possible to + // create an SRV from a single layer of a 3D texture. Instead, make sure the image is up to + // date before the copy and then copy back to the storage afterwards if needed. + // TODO: Investigate 3D blits in D3D11. + + bool syncTexStorage = mTexStorage && isLevelComplete(index.getLevelIndex()); + if (syncTexStorage) + { + ANGLE_TRY( + mImageArray[index.getLevelIndex()]->copyFromTexStorage(context, index, mTexStorage)); + } + ANGLE_TRY(mImageArray[index.getLevelIndex()]->copyFromFramebuffer(context, clippedDestOffset, + clippedSourceArea, source)); + mDirtyImages = true; + onStateChange(angle::SubjectMessage::DirtyBitsFlagged); + + if (syncTexStorage) + { + ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex())); + } + + return angle::Result::Continue; +} + +angle::Result TextureD3D_3D::copyTexture(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + GLenum type, + GLint sourceLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) +{ + ASSERT(index.getTarget() == gl::TextureTarget::_3D); + + gl::TextureType sourceType = source->getType(); + + const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type); + gl::Extents size( + static_cast(source->getWidth(NonCubeTextureTypeToTarget(sourceType), sourceLevel)), + static_cast(source->getHeight(NonCubeTextureTypeToTarget(sourceType), sourceLevel)), + static_cast(source->getDepth(NonCubeTextureTypeToTarget(sourceType), sourceLevel))); + + ANGLE_TRY(redefineImage(context, index.getLevelIndex(), internalFormatInfo.sizedInternalFormat, + size, false)); + + gl::Box sourceBox(0, 0, 0, size.width, size.height, size.depth); + gl::Offset destOffset(0, 0, 0); + gl::ImageIndex destIndex = gl::ImageIndex::Make3D(static_cast(index.getLevelIndex())); + + if (!isSRGB(index.getLevelIndex()) && canCreateRenderTargetForImage(destIndex)) + { + ANGLE_TRY(ensureRenderTarget(context)); + ASSERT(isValidLevel(index.getLevelIndex())); + ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex())); + + ANGLE_TRY(mRenderer->copyTexture(context, source, sourceLevel, gl::TextureTarget::_3D, + sourceBox, internalFormatInfo.format, + internalFormatInfo.type, destOffset, mTexStorage, + index.getTarget(), index.getLevelIndex(), unpackFlipY, + unpackPremultiplyAlpha, unpackUnmultiplyAlpha)); + } + else + { + gl::ImageIndex sourceIndex = gl::ImageIndex::Make3D(sourceLevel); + ImageD3D *sourceImage = nullptr; + ImageD3D *destImage = nullptr; + TextureD3D *sourceD3D = GetImplAs(source); + + ANGLE_TRY(getImageAndSyncFromStorage(context, destIndex, &destImage)); + ANGLE_TRY(sourceD3D->getImageAndSyncFromStorage(context, sourceIndex, &sourceImage)); + + ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, sourceBox, destOffset, + unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha)); + + mDirtyImages = true; + + gl::Box destRegion(0, 0, 0, sourceBox.width, sourceBox.height, sourceBox.depth); + ANGLE_TRY(commitRegion(context, destIndex, destRegion)); + } + + return angle::Result::Continue; +} +angle::Result TextureD3D_3D::copySubTexture(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Offset &destOffset, + GLint sourceLevel, + const gl::Box &sourceBox, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) +{ + ASSERT(index.getTarget() == gl::TextureTarget::_3D); + + gl::ImageIndex destIndex = gl::ImageIndex::Make3D(static_cast(index.getLevelIndex())); + + if (!isSRGB(index.getLevelIndex()) && canCreateRenderTargetForImage(destIndex)) + { + ANGLE_TRY(ensureRenderTarget(context)); + ASSERT(isValidLevel(index.getLevelIndex())); + ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex())); + + const gl::InternalFormat &internalFormatInfo = + gl::GetSizedInternalFormatInfo(getInternalFormat(index.getLevelIndex())); + ANGLE_TRY(mRenderer->copyTexture(context, source, sourceLevel, gl::TextureTarget::_3D, + sourceBox, internalFormatInfo.format, + internalFormatInfo.type, destOffset, mTexStorage, + index.getTarget(), index.getLevelIndex(), unpackFlipY, + unpackPremultiplyAlpha, unpackUnmultiplyAlpha)); + } + else + { + gl::ImageIndex sourceImageIndex = gl::ImageIndex::Make3D(sourceLevel); + TextureD3D *sourceD3D = GetImplAs(source); + ImageD3D *sourceImage = nullptr; + ANGLE_TRY(sourceD3D->getImageAndSyncFromStorage(context, sourceImageIndex, &sourceImage)); + + ImageD3D *destImage = nullptr; + ANGLE_TRY(getImageAndSyncFromStorage(context, destIndex, &destImage)); + + ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, sourceBox, destOffset, + unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha)); + + mDirtyImages = true; + + gl::Box destRegion(destOffset.x, destOffset.y, destOffset.z, sourceBox.width, + sourceBox.height, sourceBox.depth); + ANGLE_TRY(commitRegion(context, destIndex, destRegion)); + } + + return angle::Result::Continue; +} + +angle::Result TextureD3D_3D::setStorage(const gl::Context *context, + gl::TextureType type, + size_t levels, + GLenum internalFormat, + const gl::Extents &size) +{ + ASSERT(type == gl::TextureType::_3D); + + for (size_t level = 0; level < levels; level++) + { + gl::Extents levelSize(std::max(1, size.width >> level), std::max(1, size.height >> level), + std::max(1, size.depth >> level)); + mImageArray[level]->redefine(gl::TextureType::_3D, internalFormat, levelSize, true); + } + + for (size_t level = levels; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) + { + mImageArray[level]->redefine(gl::TextureType::_3D, GL_NONE, gl::Extents(0, 0, 0), true); + } + + // TODO(geofflang): Verify storage creation had no errors + BindFlags bindFlags; + bindFlags.renderTarget = IsRenderTargetUsage(mState.getUsage()); + TexStoragePointer storage = { + mRenderer->createTextureStorage3D(internalFormat, bindFlags, size.width, size.height, + size.depth, static_cast(levels), mState.getLabel()), + context}; + + ANGLE_TRY(setCompleteTexStorage(context, storage.get())); + storage.release(); + + ANGLE_TRY(updateStorage(context)); + + mImmutable = true; + + return angle::Result::Continue; +} + +angle::Result TextureD3D_3D::bindTexImage(const gl::Context *context, egl::Surface *surface) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3D_3D::releaseTexImage(const gl::Context *context) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3D_3D::initMipmapImages(const gl::Context *context) +{ + const GLuint baseLevel = mState.getEffectiveBaseLevel(); + const GLuint maxLevel = mState.getMipmapMaxLevel(); + // Purge array levels baseLevel + 1 through q and reset them to represent the generated mipmap + // levels. + for (GLuint level = baseLevel + 1; level <= maxLevel; level++) + { + gl::Extents levelSize(std::max(getLevelZeroWidth() >> level, 1), + std::max(getLevelZeroHeight() >> level, 1), + std::max(getLevelZeroDepth() >> level, 1)); + ANGLE_TRY(redefineImage(context, level, getBaseLevelInternalFormat(), levelSize, false)); + } + + // We should be mip-complete now so generate the storage. + ANGLE_TRY(initializeStorage(context, BindFlags::RenderTarget())); + + return angle::Result::Continue; +} + +angle::Result TextureD3D_3D::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) +{ + // ensure the underlying texture is created + ANGLE_TRY(ensureRenderTarget(context)); + + if (index.hasLayer()) + { + ANGLE_TRY(updateStorage(context)); + } + else + { + ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex())); + } + + return mTexStorage->getRenderTarget(context, index, samples, outRT); +} + +angle::Result TextureD3D_3D::initializeStorage(const gl::Context *context, BindFlags bindFlags) +{ + // Only initialize the first time this texture is used as a render target or shader resource + if (mTexStorage) + { + return angle::Result::Continue; + } + + // do not attempt to create storage for nonexistant data + if (!isLevelComplete(getBaseLevel())) + { + return angle::Result::Continue; + } + + TexStoragePointer storage; + ANGLE_TRY(createCompleteStorage(context, bindFlags, &storage)); + + ANGLE_TRY(setCompleteTexStorage(context, storage.get())); + storage.release(); + + ASSERT(mTexStorage); + + // flush image data to the storage + ANGLE_TRY(updateStorage(context)); + + return angle::Result::Continue; +} + +angle::Result TextureD3D_3D::createCompleteStorage(const gl::Context *context, + BindFlags bindFlags, + TexStoragePointer *outStorage) const +{ + GLsizei width = getLevelZeroWidth(); + GLsizei height = getLevelZeroHeight(); + GLsizei depth = getLevelZeroDepth(); + GLenum internalFormat = getBaseLevelInternalFormat(); + + ASSERT(width > 0 && height > 0 && depth > 0); + + // use existing storage level count, when previously specified by TexStorage*D + GLint levels = + (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, depth)); + + // TODO: Verify creation of the storage succeeded + *outStorage = {mRenderer->createTextureStorage3D(internalFormat, bindFlags, width, height, + depth, levels, mState.getLabel()), + context}; + + return angle::Result::Continue; +} + +angle::Result TextureD3D_3D::setCompleteTexStorage(const gl::Context *context, + TextureStorage *newCompleteTexStorage) +{ + gl::TexLevelMask copyImageMask; + copyImageMask.set(); + + ANGLE_TRY(releaseTexStorage(context, copyImageMask)); + mTexStorage = newCompleteTexStorage; + mTexStorageObserverBinding.bind(mTexStorage); + mDirtyImages = true; + + // We do not support managed 3D storage, as that is D3D9/ES2-only + ASSERT(!mTexStorage->isManaged()); + + return angle::Result::Continue; +} + +angle::Result TextureD3D_3D::updateStorage(const gl::Context *context) +{ + if (!mDirtyImages) + { + return angle::Result::Continue; + } + + ASSERT(mTexStorage != nullptr); + GLint storageLevels = mTexStorage->getLevelCount(); + for (int level = 0; level < storageLevels; level++) + { + if (mImageArray[level]->isDirty() && isLevelComplete(level)) + { + ANGLE_TRY(updateStorageLevel(context, level)); + } + } + + mDirtyImages = false; + return angle::Result::Continue; +} + +bool TextureD3D_3D::isValidLevel(int level) const +{ + return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : 0); +} + +bool TextureD3D_3D::isLevelComplete(int level) const +{ + ASSERT(level >= 0 && level < static_cast(mImageArray.size()) && + mImageArray[level] != nullptr); + + if (isImmutable()) + { + return true; + } + + GLsizei width = getLevelZeroWidth(); + GLsizei height = getLevelZeroHeight(); + GLsizei depth = getLevelZeroDepth(); + + if (width <= 0 || height <= 0 || depth <= 0) + { + return false; + } + + if (level == static_cast(getBaseLevel())) + { + return true; + } + + ImageD3D *levelImage = mImageArray[level].get(); + + if (levelImage->getInternalFormat() != getBaseLevelInternalFormat()) + { + return false; + } + + if (levelImage->getWidth() != std::max(1, width >> level)) + { + return false; + } + + if (levelImage->getHeight() != std::max(1, height >> level)) + { + return false; + } + + if (levelImage->getDepth() != std::max(1, depth >> level)) + { + return false; + } + + return true; +} + +bool TextureD3D_3D::isImageComplete(const gl::ImageIndex &index) const +{ + return isLevelComplete(index.getLevelIndex()); +} + +angle::Result TextureD3D_3D::updateStorageLevel(const gl::Context *context, int level) +{ + ASSERT(level >= 0 && level < static_cast(mImageArray.size()) && + mImageArray[level] != nullptr); + ASSERT(isLevelComplete(level)); + + if (mImageArray[level]->isDirty()) + { + gl::ImageIndex index = gl::ImageIndex::Make3D(level); + gl::Box region(0, 0, 0, getWidth(level), getHeight(level), getDepth(level)); + ANGLE_TRY(commitRegion(context, index, region)); + } + + return angle::Result::Continue; +} + +angle::Result TextureD3D_3D::redefineImage(const gl::Context *context, + GLint level, + GLenum internalformat, + const gl::Extents &size, + bool forceRelease) +{ + // If there currently is a corresponding storage texture image, it has these parameters + const int storageWidth = std::max(1, getLevelZeroWidth() >> level); + const int storageHeight = std::max(1, getLevelZeroHeight() >> level); + const int storageDepth = std::max(1, getLevelZeroDepth() >> level); + const GLenum storageFormat = getBaseLevelInternalFormat(); + + if (mTexStorage) + { + const int storageLevels = mTexStorage->getLevelCount(); + + if ((level >= storageLevels && storageLevels != 0) || size.width != storageWidth || + size.height != storageHeight || size.depth != storageDepth || + internalformat != storageFormat) // Discard mismatched storage + { + markAllImagesDirty(); + + gl::TexLevelMask copyImageMask; + copyImageMask.set(); + copyImageMask.set(level, false); + + ANGLE_TRY(releaseTexStorage(context, copyImageMask)); + } + } + + mImageArray[level]->redefine(gl::TextureType::_3D, internalformat, size, forceRelease); + mDirtyImages = mDirtyImages || mImageArray[level]->isDirty(); + + return angle::Result::Continue; +} + +gl::ImageIndexIterator TextureD3D_3D::imageIterator() const +{ + return gl::ImageIndexIterator::Make3D(0, mTexStorage->getLevelCount(), + gl::ImageIndex::kEntireLevel, + gl::ImageIndex::kEntireLevel); +} + +gl::ImageIndex TextureD3D_3D::getImageIndex(GLint mip, GLint /*layer*/) const +{ + // The "layer" here does not apply to 3D images. We use one Image per mip. + return gl::ImageIndex::Make3D(mip); +} + +bool TextureD3D_3D::isValidIndex(const gl::ImageIndex &index) const +{ + return (mTexStorage && index.getType() == gl::TextureType::_3D && index.getLevelIndex() >= 0 && + index.getLevelIndex() < mTexStorage->getLevelCount()); +} + +void TextureD3D_3D::markAllImagesDirty() +{ + for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) + { + mImageArray[i]->markDirty(); + } + mDirtyImages = true; +} + +GLint TextureD3D_3D::getLevelZeroDepth() const +{ + ASSERT(gl::CountLeadingZeros(static_cast(getBaseLevelDepth())) > getBaseLevel()); + return getBaseLevelDepth() << getBaseLevel(); +} + +TextureD3D_2DArray::TextureD3D_2DArray(const gl::TextureState &state, RendererD3D *renderer) + : TextureD3D(state, renderer) +{ + for (int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++level) + { + mLayerCounts[level] = 0; + mImageArray[level] = nullptr; + } +} + +void TextureD3D_2DArray::onDestroy(const gl::Context *context) +{ + // Delete the Images before the TextureStorage. Images might be relying on the TextureStorage + // for some of their data. If TextureStorage is deleted before the Images, then their data will + // be wastefully copied back from the GPU before we delete the Images. + deleteImages(); + return TextureD3D::onDestroy(context); +} + +TextureD3D_2DArray::~TextureD3D_2DArray() {} + +ImageD3D *TextureD3D_2DArray::getImage(int level, int layer) const +{ + ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + ASSERT((layer == 0 && mLayerCounts[level] == 0) || layer < mLayerCounts[level]); + return (mImageArray[level] ? mImageArray[level][layer] : nullptr); +} + +ImageD3D *TextureD3D_2DArray::getImage(const gl::ImageIndex &index) const +{ + ASSERT(index.getLevelIndex() < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + ASSERT(index.hasLayer()); + ASSERT((index.getLayerIndex() == 0 && mLayerCounts[index.getLevelIndex()] == 0) || + index.getLayerIndex() < mLayerCounts[index.getLevelIndex()]); + ASSERT(index.getType() == gl::TextureType::_2DArray); + return (mImageArray[index.getLevelIndex()] + ? mImageArray[index.getLevelIndex()][index.getLayerIndex()] + : nullptr); +} + +GLsizei TextureD3D_2DArray::getLayerCount(int level) const +{ + ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + return mLayerCounts[level]; +} + +GLsizei TextureD3D_2DArray::getWidth(GLint level) const +{ + return (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0) + ? mImageArray[level][0]->getWidth() + : 0; +} + +GLsizei TextureD3D_2DArray::getHeight(GLint level) const +{ + return (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0) + ? mImageArray[level][0]->getHeight() + : 0; +} + +GLenum TextureD3D_2DArray::getInternalFormat(GLint level) const +{ + return (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0) + ? mImageArray[level][0]->getInternalFormat() + : GL_NONE; +} + +bool TextureD3D_2DArray::isDepth(GLint level) const +{ + return gl::GetSizedInternalFormatInfo(getInternalFormat(level)).depthBits > 0; +} + +bool TextureD3D_2DArray::isSRGB(GLint level) const +{ + return gl::GetSizedInternalFormatInfo(getInternalFormat(level)).colorEncoding == GL_SRGB; +} + +angle::Result TextureD3D_2DArray::setEGLImageTarget(const gl::Context *context, + gl::TextureType type, + egl::Image *image) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3D_2DArray::setImage(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + const gl::Extents &size, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels) +{ + ASSERT(index.getTarget() == gl::TextureTarget::_2DArray); + + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat, type); + + ANGLE_TRY( + redefineImage(context, index.getLevelIndex(), formatInfo.sizedInternalFormat, size, false)); + + ContextD3D *contextD3D = GetImplAs(context); + + GLuint inputDepthPitch = 0; + ANGLE_CHECK_GL_MATH(contextD3D, formatInfo.computeDepthPitch( + type, size.width, size.height, unpack.alignment, + unpack.rowLength, unpack.imageHeight, &inputDepthPitch)); + + for (int i = 0; i < size.depth; i++) + { + const ptrdiff_t layerOffset = (inputDepthPitch * i); + gl::ImageIndex layerIndex = gl::ImageIndex::Make2DArray(index.getLevelIndex(), i); + ANGLE_TRY( + setImageImpl(context, layerIndex, type, unpack, unpackBuffer, pixels, layerOffset)); + } + + return angle::Result::Continue; +} + +angle::Result TextureD3D_2DArray::setSubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels) +{ + ContextD3D *contextD3D = GetImplAs(context); + + ASSERT(index.getTarget() == gl::TextureTarget::_2DArray); + const gl::InternalFormat &formatInfo = + gl::GetInternalFormatInfo(getInternalFormat(index.getLevelIndex()), type); + GLuint inputDepthPitch = 0; + ANGLE_CHECK_GL_MATH(contextD3D, formatInfo.computeDepthPitch( + type, area.width, area.height, unpack.alignment, + unpack.rowLength, unpack.imageHeight, &inputDepthPitch)); + + for (int i = 0; i < area.depth; i++) + { + int layer = area.z + i; + const ptrdiff_t layerOffset = (inputDepthPitch * i); + + gl::Box layerArea(area.x, area.y, 0, area.width, area.height, 1); + + gl::ImageIndex layerIndex = gl::ImageIndex::Make2DArray(index.getLevelIndex(), layer); + ANGLE_TRY(TextureD3D::subImage(context, layerIndex, layerArea, format, type, unpack, + unpackBuffer, pixels, layerOffset)); + } + + return angle::Result::Continue; +} + +angle::Result TextureD3D_2DArray::setCompressedImage(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + const gl::Extents &size, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) +{ + ASSERT(index.getTarget() == gl::TextureTarget::_2DArray); + + ContextD3D *contextD3D = GetImplAs(context); + + // compressed formats don't have separate sized internal formats-- we can just use the + // compressed format directly + ANGLE_TRY(redefineImage(context, index.getLevelIndex(), internalFormat, size, false)); + + const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalFormat); + GLuint inputDepthPitch = 0; + ANGLE_CHECK_GL_MATH( + contextD3D, formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, size.width, size.height, 1, 0, 0, + &inputDepthPitch)); + + for (int i = 0; i < size.depth; i++) + { + const ptrdiff_t layerOffset = (inputDepthPitch * i); + + gl::ImageIndex layerIndex = gl::ImageIndex::Make2DArray(index.getLevelIndex(), i); + ANGLE_TRY(setCompressedImageImpl(context, layerIndex, unpack, pixels, layerOffset)); + } + + return angle::Result::Continue; +} + +angle::Result TextureD3D_2DArray::setCompressedSubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) +{ + ASSERT(index.getTarget() == gl::TextureTarget::_2DArray); + + ContextD3D *contextD3D = GetImplAs(context); + + const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(format); + GLuint inputDepthPitch = 0; + ANGLE_CHECK_GL_MATH( + contextD3D, formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, area.width, area.height, 1, 0, 0, + &inputDepthPitch)); + + for (int i = 0; i < area.depth; i++) + { + int layer = area.z + i; + const ptrdiff_t layerOffset = (inputDepthPitch * i); + + gl::Box layerArea(area.x, area.y, 0, area.width, area.height, 1); + + gl::ImageIndex layerIndex = gl::ImageIndex::Make2DArray(index.getLevelIndex(), layer); + ANGLE_TRY(TextureD3D::subImageCompressed(context, layerIndex, layerArea, format, unpack, + pixels, layerOffset)); + ANGLE_TRY(commitRegion(context, layerIndex, layerArea)); + } + + return angle::Result::Continue; +} + +angle::Result TextureD3D_2DArray::copyImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Rectangle &sourceArea, + GLenum internalFormat, + gl::Framebuffer *source) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3D_2DArray::copySubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + gl::Framebuffer *source) +{ + ASSERT(index.getTarget() == gl::TextureTarget::_2DArray); + + gl::Extents fbSize = source->getReadColorAttachment()->getSize(); + gl::Rectangle clippedSourceArea; + if (!ClipRectangle(sourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height), + &clippedSourceArea)) + { + return angle::Result::Continue; + } + const gl::Offset clippedDestOffset(destOffset.x + clippedSourceArea.x - sourceArea.x, + destOffset.y + clippedSourceArea.y - sourceArea.y, + destOffset.z); + + if (!canCreateRenderTargetForImage(index)) + { + gl::Offset destLayerOffset(clippedDestOffset.x, clippedDestOffset.y, 0); + ANGLE_TRY(mImageArray[index.getLevelIndex()][clippedDestOffset.z]->copyFromFramebuffer( + context, destLayerOffset, clippedSourceArea, source)); + mDirtyImages = true; + onStateChange(angle::SubjectMessage::DirtyBitsFlagged); + } + else + { + ANGLE_TRY(ensureRenderTarget(context)); + + if (isValidLevel(index.getLevelIndex())) + { + ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex())); + ANGLE_TRY( + mRenderer->copyImage2DArray(context, source, clippedSourceArea, + gl::GetUnsizedFormat(getInternalFormat(getBaseLevel())), + clippedDestOffset, mTexStorage, index.getLevelIndex())); + } + } + return angle::Result::Continue; +} + +angle::Result TextureD3D_2DArray::copyTexture(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + GLenum type, + GLint sourceLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) +{ + ASSERT(index.getTarget() == gl::TextureTarget::_2DArray); + + gl::TextureType sourceType = source->getType(); + + const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type); + gl::Extents size( + static_cast(source->getWidth(NonCubeTextureTypeToTarget(sourceType), sourceLevel)), + static_cast(source->getHeight(NonCubeTextureTypeToTarget(sourceType), sourceLevel)), + static_cast(source->getDepth(NonCubeTextureTypeToTarget(sourceType), sourceLevel))); + + ANGLE_TRY(redefineImage(context, index.getLevelIndex(), internalFormatInfo.sizedInternalFormat, + size, false)); + + gl::Box sourceBox(0, 0, 0, size.width, size.height, size.depth); + gl::Offset destOffset(0, 0, 0); + + gl::ImageIndex destIndex = + gl::ImageIndex::Make2DArrayRange(index.getLevelIndex(), 0, size.depth); + + if (!isSRGB(index.getLevelIndex()) && + canCreateRenderTargetForImage( + gl::ImageIndex::Make2DArrayRange(index.getLevelIndex(), 0, size.depth))) + { + ANGLE_TRY(ensureRenderTarget(context)); + ASSERT(isValidLevel(index.getLevelIndex())); + ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex())); + ANGLE_TRY(mRenderer->copyTexture(context, source, sourceLevel, gl::TextureTarget::_2DArray, + sourceBox, internalFormatInfo.format, + internalFormatInfo.type, destOffset, mTexStorage, + index.getTarget(), index.getLevelIndex(), unpackFlipY, + unpackPremultiplyAlpha, unpackUnmultiplyAlpha)); + } + else + { + for (int i = 0; i < size.depth; i++) + { + gl::ImageIndex currentSourceDepthIndex = gl::ImageIndex::Make2DArray(sourceLevel, i); + gl::ImageIndex currentDestDepthIndex = + gl::ImageIndex::Make2DArray(index.getLevelIndex(), i); + ImageD3D *sourceImage = nullptr; + ImageD3D *destImage = nullptr; + TextureD3D *sourceD3D = GetImplAs(source); + + ANGLE_TRY(getImageAndSyncFromStorage(context, currentDestDepthIndex, &destImage)); + ANGLE_TRY(sourceD3D->getImageAndSyncFromStorage(context, currentSourceDepthIndex, + &sourceImage)); + gl::Box imageBox(sourceBox.x, sourceBox.y, 0, sourceBox.width, sourceBox.height, 1); + ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, imageBox, destOffset, + unpackFlipY, unpackPremultiplyAlpha, + unpackUnmultiplyAlpha)); + } + + mDirtyImages = true; + + gl::Box destRegion(destOffset.x, destOffset.y, destOffset.z, sourceBox.width, + sourceBox.height, sourceBox.depth); + ANGLE_TRY(commitRegion(context, destIndex, destRegion)); + } + + return angle::Result::Continue; +} + +angle::Result TextureD3D_2DArray::copySubTexture(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Offset &destOffset, + GLint sourceLevel, + const gl::Box &sourceBox, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) +{ + ASSERT(index.getTarget() == gl::TextureTarget::_2DArray); + + gl::ImageIndex destIndex = gl::ImageIndex::Make2DArrayRange( + static_cast(index.getLevelIndex()), destOffset.z, sourceBox.depth - destOffset.z); + + if (!isSRGB(destIndex.getLevelIndex()) && canCreateRenderTargetForImage(destIndex)) + { + ANGLE_TRY(ensureRenderTarget(context)); + ASSERT(isValidLevel(destIndex.getLevelIndex())); + ANGLE_TRY(updateStorageLevel(context, destIndex.getLevelIndex())); + + const gl::InternalFormat &internalFormatInfo = + gl::GetSizedInternalFormatInfo(getInternalFormat(destIndex.getLevelIndex())); + ANGLE_TRY(mRenderer->copyTexture(context, source, sourceLevel, gl::TextureTarget::_2DArray, + sourceBox, internalFormatInfo.format, + internalFormatInfo.type, destOffset, mTexStorage, + index.getTarget(), index.getLevelIndex(), unpackFlipY, + unpackPremultiplyAlpha, unpackUnmultiplyAlpha)); + } + else + { + for (int i = 0; i < sourceBox.depth; i++) + { + gl::ImageIndex currentSourceIndex = + gl::ImageIndex::Make2DArray(sourceLevel, i + sourceBox.z); + gl::ImageIndex currentDestIndex = + gl::ImageIndex::Make2DArray(index.getLevelIndex(), i + destOffset.z); + + gl::Box currentLayerBox(sourceBox.x, sourceBox.y, 0, sourceBox.width, sourceBox.height, + 1); + + TextureD3D *sourceD3D = GetImplAs(source); + ImageD3D *sourceImage = nullptr; + ANGLE_TRY( + sourceD3D->getImageAndSyncFromStorage(context, currentSourceIndex, &sourceImage)); + + ImageD3D *destImage = nullptr; + ANGLE_TRY(getImageAndSyncFromStorage(context, currentDestIndex, &destImage)); + + ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, currentLayerBox, + destOffset, unpackFlipY, unpackPremultiplyAlpha, + unpackUnmultiplyAlpha)); + } + + mDirtyImages = true; + + gl::Box destRegion(destOffset.x, destOffset.y, destOffset.z, sourceBox.width, + sourceBox.height, sourceBox.depth); + ANGLE_TRY(commitRegion(context, destIndex, destRegion)); + } + + return angle::Result::Continue; +} + +angle::Result TextureD3D_2DArray::setStorage(const gl::Context *context, + gl::TextureType type, + size_t levels, + GLenum internalFormat, + const gl::Extents &size) +{ + ASSERT(type == gl::TextureType::_2DArray); + + deleteImages(); + + for (size_t level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) + { + gl::Extents levelLayerSize(std::max(1, size.width >> level), + std::max(1, size.height >> level), 1); + + mLayerCounts[level] = (level < levels ? size.depth : 0); + + if (mLayerCounts[level] > 0) + { + // Create new images for this level + mImageArray[level] = new ImageD3D *[mLayerCounts[level]]; + + for (int layer = 0; layer < mLayerCounts[level]; layer++) + { + mImageArray[level][layer] = mRenderer->createImage(); + mImageArray[level][layer]->redefine(gl::TextureType::_2DArray, internalFormat, + levelLayerSize, true); + } + } + } + + // TODO(geofflang): Verify storage creation had no errors + BindFlags bindFlags; + bindFlags.renderTarget = IsRenderTargetUsage(mState.getUsage()); + TexStoragePointer storage = {mRenderer->createTextureStorage2DArray( + internalFormat, bindFlags, size.width, size.height, size.depth, + static_cast(levels), mState.getLabel()), + context}; + + ANGLE_TRY(setCompleteTexStorage(context, storage.get())); + storage.release(); + + ANGLE_TRY(updateStorage(context)); + + mImmutable = true; + + return angle::Result::Continue; +} + +angle::Result TextureD3D_2DArray::bindTexImage(const gl::Context *context, egl::Surface *surface) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3D_2DArray::releaseTexImage(const gl::Context *context) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3D_2DArray::initMipmapImages(const gl::Context *context) +{ + const GLuint baseLevel = mState.getEffectiveBaseLevel(); + const GLuint maxLevel = mState.getMipmapMaxLevel(); + int baseWidth = getLevelZeroWidth(); + int baseHeight = getLevelZeroHeight(); + int baseDepth = getLayerCount(getBaseLevel()); + GLenum baseFormat = getBaseLevelInternalFormat(); + + // Purge array levels baseLevel + 1 through q and reset them to represent the generated mipmap + // levels. + for (GLuint level = baseLevel + 1u; level <= maxLevel; level++) + { + ASSERT((baseWidth >> level) > 0 || (baseHeight >> level) > 0); + gl::Extents levelLayerSize(std::max(baseWidth >> level, 1), + std::max(baseHeight >> level, 1), baseDepth); + ANGLE_TRY(redefineImage(context, level, baseFormat, levelLayerSize, false)); + } + + // We should be mip-complete now so generate the storage. + ANGLE_TRY(initializeStorage(context, BindFlags::RenderTarget())); + + return angle::Result::Continue; +} + +angle::Result TextureD3D_2DArray::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) +{ + // ensure the underlying texture is created + ANGLE_TRY(ensureRenderTarget(context)); + ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex())); + return mTexStorage->getRenderTarget(context, index, samples, outRT); +} + +angle::Result TextureD3D_2DArray::initializeStorage(const gl::Context *context, BindFlags bindFlags) +{ + // Only initialize the first time this texture is used as a render target or shader resource + if (mTexStorage) + { + return angle::Result::Continue; + } + + // do not attempt to create storage for nonexistant data + if (!isLevelComplete(getBaseLevel())) + { + return angle::Result::Continue; + } + + bindFlags.renderTarget |= IsRenderTargetUsage(mState.getUsage()); + + TexStoragePointer storage; + ANGLE_TRY(createCompleteStorage(context, bindFlags, &storage)); + + ANGLE_TRY(setCompleteTexStorage(context, storage.get())); + storage.release(); + + ASSERT(mTexStorage); + + // flush image data to the storage + ANGLE_TRY(updateStorage(context)); + + return angle::Result::Continue; +} + +angle::Result TextureD3D_2DArray::createCompleteStorage(const gl::Context *context, + BindFlags bindFlags, + TexStoragePointer *outStorage) const +{ + GLsizei width = getLevelZeroWidth(); + GLsizei height = getLevelZeroHeight(); + GLsizei depth = getLayerCount(getBaseLevel()); + GLenum internalFormat = getBaseLevelInternalFormat(); + + ASSERT(width > 0 && height > 0 && depth > 0); + + // use existing storage level count, when previously specified by TexStorage*D + GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, 1)); + + // TODO(geofflang): Verify storage creation succeeds + *outStorage = {mRenderer->createTextureStorage2DArray(internalFormat, bindFlags, width, height, + depth, levels, mState.getLabel()), + context}; + + return angle::Result::Continue; +} + +angle::Result TextureD3D_2DArray::setCompleteTexStorage(const gl::Context *context, + TextureStorage *newCompleteTexStorage) +{ + gl::TexLevelMask copyImageMask; + copyImageMask.set(); + + ANGLE_TRY(releaseTexStorage(context, copyImageMask)); + mTexStorage = newCompleteTexStorage; + mTexStorageObserverBinding.bind(mTexStorage); + mDirtyImages = true; + + // We do not support managed 2D array storage, as managed storage is ES2/D3D9 only + ASSERT(!mTexStorage->isManaged()); + + return angle::Result::Continue; +} + +angle::Result TextureD3D_2DArray::updateStorage(const gl::Context *context) +{ + if (!mDirtyImages) + { + return angle::Result::Continue; + } + + ASSERT(mTexStorage != nullptr); + GLint storageLevels = mTexStorage->getLevelCount(); + for (int level = 0; level < storageLevels; level++) + { + if (isLevelComplete(level)) + { + ANGLE_TRY(updateStorageLevel(context, level)); + } + } + + mDirtyImages = false; + return angle::Result::Continue; +} + +bool TextureD3D_2DArray::isValidLevel(int level) const +{ + return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : 0); +} + +bool TextureD3D_2DArray::isLevelComplete(int level) const +{ + ASSERT(level >= 0 && level < (int)ArraySize(mImageArray)); + + if (isImmutable()) + { + return true; + } + + GLsizei width = getLevelZeroWidth(); + GLsizei height = getLevelZeroHeight(); + + if (width <= 0 || height <= 0) + { + return false; + } + + // Layers check needs to happen after the above checks, otherwise out-of-range base level may be + // queried. + GLsizei layers = getLayerCount(getBaseLevel()); + + if (layers <= 0) + { + return false; + } + + if (level == static_cast(getBaseLevel())) + { + return true; + } + + if (getInternalFormat(level) != getInternalFormat(getBaseLevel())) + { + return false; + } + + if (getWidth(level) != std::max(1, width >> level)) + { + return false; + } + + if (getHeight(level) != std::max(1, height >> level)) + { + return false; + } + + if (getLayerCount(level) != layers) + { + return false; + } + + return true; +} + +bool TextureD3D_2DArray::isImageComplete(const gl::ImageIndex &index) const +{ + return isLevelComplete(index.getLevelIndex()); +} + +angle::Result TextureD3D_2DArray::updateStorageLevel(const gl::Context *context, int level) +{ + ASSERT(level >= 0 && level < static_cast(ArraySize(mLayerCounts))); + ASSERT(isLevelComplete(level)); + + for (int layer = 0; layer < mLayerCounts[level]; layer++) + { + ASSERT(mImageArray[level] != nullptr && mImageArray[level][layer] != nullptr); + if (mImageArray[level][layer]->isDirty()) + { + gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, layer); + gl::Box region(0, 0, 0, getWidth(level), getHeight(level), 1); + ANGLE_TRY(commitRegion(context, index, region)); + } + } + + return angle::Result::Continue; +} + +void TextureD3D_2DArray::deleteImages() +{ + for (int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++level) + { + for (int layer = 0; layer < mLayerCounts[level]; ++layer) + { + delete mImageArray[level][layer]; + } + delete[] mImageArray[level]; + mImageArray[level] = nullptr; + mLayerCounts[level] = 0; + } +} + +angle::Result TextureD3D_2DArray::redefineImage(const gl::Context *context, + GLint level, + GLenum internalformat, + const gl::Extents &size, + bool forceRelease) +{ + // If there currently is a corresponding storage texture image, it has these parameters + const int storageWidth = std::max(1, getLevelZeroWidth() >> level); + const int storageHeight = std::max(1, getLevelZeroHeight() >> level); + const GLuint baseLevel = getBaseLevel(); + const GLenum storageFormat = getBaseLevelInternalFormat(); + + int storageDepth = 0; + if (baseLevel < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + storageDepth = getLayerCount(baseLevel); + } + + // Only reallocate the layers if the size doesn't match + if (size.depth != mLayerCounts[level]) + { + for (int layer = 0; layer < mLayerCounts[level]; layer++) + { + SafeDelete(mImageArray[level][layer]); + } + SafeDeleteArray(mImageArray[level]); + mLayerCounts[level] = size.depth; + + if (size.depth > 0) + { + mImageArray[level] = new ImageD3D *[size.depth]; + for (int layer = 0; layer < mLayerCounts[level]; layer++) + { + mImageArray[level][layer] = mRenderer->createImage(); + } + } + } + + if (mTexStorage) + { + const int storageLevels = mTexStorage->getLevelCount(); + + if ((level >= storageLevels && storageLevels != 0) || size.width != storageWidth || + size.height != storageHeight || size.depth != storageDepth || + internalformat != storageFormat) // Discard mismatched storage + { + markAllImagesDirty(); + + gl::TexLevelMask copyImageMask; + copyImageMask.set(); + copyImageMask.set(level, false); + + ANGLE_TRY(releaseTexStorage(context, copyImageMask)); + } + } + + if (size.depth > 0) + { + for (int layer = 0; layer < mLayerCounts[level]; layer++) + { + mImageArray[level][layer]->redefine(gl::TextureType::_2DArray, internalformat, + gl::Extents(size.width, size.height, 1), + forceRelease); + mDirtyImages = mDirtyImages || mImageArray[level][layer]->isDirty(); + } + } + + return angle::Result::Continue; +} + +gl::ImageIndexIterator TextureD3D_2DArray::imageIterator() const +{ + return gl::ImageIndexIterator::Make2DArray(0, mTexStorage->getLevelCount(), mLayerCounts); +} + +gl::ImageIndex TextureD3D_2DArray::getImageIndex(GLint mip, GLint layer) const +{ + return gl::ImageIndex::Make2DArray(mip, layer); +} + +bool TextureD3D_2DArray::isValidIndex(const gl::ImageIndex &index) const +{ + // Check for having a storage and the right type of index + if (!mTexStorage || index.getType() != gl::TextureType::_2DArray) + { + return false; + } + + // Check the mip index + if (index.getLevelIndex() < 0 || index.getLevelIndex() >= mTexStorage->getLevelCount()) + { + return false; + } + + // Check the layer index + return (!index.hasLayer() || (index.getLayerIndex() >= 0 && + index.getLayerIndex() < mLayerCounts[index.getLevelIndex()])); +} + +void TextureD3D_2DArray::markAllImagesDirty() +{ + for (int dirtyLevel = 0; dirtyLevel < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; dirtyLevel++) + { + for (int dirtyLayer = 0; dirtyLayer < mLayerCounts[dirtyLevel]; dirtyLayer++) + { + mImageArray[dirtyLevel][dirtyLayer]->markDirty(); + } + } + mDirtyImages = true; +} + +TextureD3DImmutableBase::TextureD3DImmutableBase(const gl::TextureState &state, + RendererD3D *renderer) + : TextureD3D(state, renderer) +{} + +TextureD3DImmutableBase::~TextureD3DImmutableBase() {} + +ImageD3D *TextureD3DImmutableBase::getImage(const gl::ImageIndex &index) const +{ + return nullptr; +} + +angle::Result TextureD3DImmutableBase::setImage(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + const gl::Extents &size, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3DImmutableBase::setSubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3DImmutableBase::setCompressedImage(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + const gl::Extents &size, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3DImmutableBase::setCompressedSubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3DImmutableBase::copyImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Rectangle &sourceArea, + GLenum internalFormat, + gl::Framebuffer *source) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3DImmutableBase::copySubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + gl::Framebuffer *source) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3DImmutableBase::bindTexImage(const gl::Context *context, + egl::Surface *surface) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3DImmutableBase::releaseTexImage(const gl::Context *context) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +TextureD3D_External::TextureD3D_External(const gl::TextureState &state, RendererD3D *renderer) + : TextureD3DImmutableBase(state, renderer) +{} + +TextureD3D_External::~TextureD3D_External() {} + +GLsizei TextureD3D_External::getLayerCount(int level) const +{ + return 1; +} + +angle::Result TextureD3D_External::setImageExternal(const gl::Context *context, + gl::TextureType type, + egl::Stream *stream, + const egl::Stream::GLTextureDescription &desc) +{ + ASSERT(type == gl::TextureType::External); + + ANGLE_TRY(releaseTexStorage(context, gl::TexLevelMask())); + + // If the stream is null, the external image is unbound and we release the storage + if (stream != nullptr) + { + mTexStorage = mRenderer->createTextureStorageExternal(stream, desc, mState.getLabel()); + } + + return angle::Result::Continue; +} + +angle::Result TextureD3D_External::setEGLImageTarget(const gl::Context *context, + gl::TextureType type, + egl::Image *image) +{ + EGLImageD3D *eglImaged3d = GetImplAs(image); + + // Pass in the RenderTargetD3D here: createTextureStorage can't generate an error. + RenderTargetD3D *renderTargetD3D = nullptr; + ANGLE_TRY(eglImaged3d->getRenderTarget(context, &renderTargetD3D)); + + ANGLE_TRY(releaseTexStorage(context, gl::TexLevelMask())); + mTexStorage = + mRenderer->createTextureStorageEGLImage(eglImaged3d, renderTargetD3D, mState.getLabel()); + + return angle::Result::Continue; +} + +angle::Result TextureD3D_External::initMipmapImages(const gl::Context *context) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result TextureD3D_External::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) +{ + UNREACHABLE(); + return angle::Result::Stop; +} + +bool TextureD3D_External::isImageComplete(const gl::ImageIndex &index) const +{ + return (index.getLevelIndex() == 0) ? (mTexStorage != nullptr) : false; +} + +angle::Result TextureD3D_External::initializeStorage(const gl::Context *context, + BindFlags bindFlags) +{ + // Texture storage is created when an external image is bound + ASSERT(mTexStorage); + return angle::Result::Continue; +} + +angle::Result TextureD3D_External::createCompleteStorage(const gl::Context *context, + BindFlags bindFlags, + TexStoragePointer *outStorage) const +{ + UNREACHABLE(); + return angle::Result::Continue; +} + +angle::Result TextureD3D_External::setCompleteTexStorage(const gl::Context *context, + TextureStorage *newCompleteTexStorage) +{ + UNREACHABLE(); + return angle::Result::Continue; +} + +angle::Result TextureD3D_External::updateStorage(const gl::Context *context) +{ + // Texture storage does not need to be updated since it is already loaded with the latest + // external image + ASSERT(mTexStorage); + return angle::Result::Continue; +} + +gl::ImageIndexIterator TextureD3D_External::imageIterator() const +{ + return gl::ImageIndexIterator::Make2D(0, mTexStorage->getLevelCount()); +} + +gl::ImageIndex TextureD3D_External::getImageIndex(GLint mip, GLint /*layer*/) const +{ + // "layer" does not apply to 2D Textures. + return gl::ImageIndex::Make2D(mip); +} + +bool TextureD3D_External::isValidIndex(const gl::ImageIndex &index) const +{ + return (mTexStorage && index.getType() == gl::TextureType::External && + index.getLevelIndex() == 0); +} + +void TextureD3D_External::markAllImagesDirty() +{ + UNREACHABLE(); +} + +TextureD3D_2DMultisample::TextureD3D_2DMultisample(const gl::TextureState &state, + RendererD3D *renderer) + : TextureD3DImmutableBase(state, renderer) +{} + +TextureD3D_2DMultisample::~TextureD3D_2DMultisample() {} + +angle::Result TextureD3D_2DMultisample::setStorageMultisample(const gl::Context *context, + gl::TextureType type, + GLsizei samples, + GLint internalformat, + const gl::Extents &size, + bool fixedSampleLocations) +{ + ASSERT(type == gl::TextureType::_2DMultisample && size.depth == 1); + + // We allocate storage immediately instead of doing it lazily like other TextureD3D classes do. + // This requires less state in this class. + TexStoragePointer storage = {mRenderer->createTextureStorage2DMultisample( + internalformat, size.width, size.height, static_cast(0), + samples, fixedSampleLocations, mState.getLabel()), + context}; + + ANGLE_TRY(setCompleteTexStorage(context, storage.get())); + storage.release(); + + mImmutable = true; + + return angle::Result::Continue; +} + +angle::Result TextureD3D_2DMultisample::setEGLImageTarget(const gl::Context *context, + gl::TextureType type, + egl::Image *image) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3D_2DMultisample::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) +{ + ASSERT(!index.hasLayer()); + + // ensure the underlying texture is created + ANGLE_TRY(ensureRenderTarget(context)); + + return mTexStorage->getRenderTarget(context, index, samples, outRT); +} + +gl::ImageIndexIterator TextureD3D_2DMultisample::imageIterator() const +{ + return gl::ImageIndexIterator::Make2DMultisample(); +} + +gl::ImageIndex TextureD3D_2DMultisample::getImageIndex(GLint mip, GLint layer) const +{ + return gl::ImageIndex::Make2DMultisample(); +} + +bool TextureD3D_2DMultisample::isValidIndex(const gl::ImageIndex &index) const +{ + return (mTexStorage && index.getType() == gl::TextureType::_2DMultisample && + index.getLevelIndex() == 0); +} + +GLsizei TextureD3D_2DMultisample::getLayerCount(int level) const +{ + return 1; +} + +void TextureD3D_2DMultisample::markAllImagesDirty() {} + +angle::Result TextureD3D_2DMultisample::initializeStorage(const gl::Context *context, + BindFlags bindFlags) +{ + // initializeStorage should only be called in a situation where the texture already has storage + // associated with it (storage is created in setStorageMultisample). + ASSERT(mTexStorage); + return angle::Result::Continue; +} + +angle::Result TextureD3D_2DMultisample::createCompleteStorage(const gl::Context *context, + BindFlags bindFlags, + TexStoragePointer *outStorage) const +{ + UNREACHABLE(); + *outStorage = {mTexStorage, context}; + return angle::Result::Continue; +} + +angle::Result TextureD3D_2DMultisample::setCompleteTexStorage(const gl::Context *context, + TextureStorage *newCompleteTexStorage) +{ + // These textures are immutable, so this should only be ever called once. + ASSERT(!mTexStorage); + mTexStorage = newCompleteTexStorage; + mTexStorageObserverBinding.bind(mTexStorage); + return angle::Result::Continue; +} + +angle::Result TextureD3D_2DMultisample::updateStorage(const gl::Context *context) +{ + return angle::Result::Continue; +} + +angle::Result TextureD3D_2DMultisample::initMipmapImages(const gl::Context *context) +{ + UNREACHABLE(); + return angle::Result::Continue; +} + +bool TextureD3D_2DMultisample::isImageComplete(const gl::ImageIndex &index) const +{ + return true; +} + +TextureD3D_2DMultisampleArray::TextureD3D_2DMultisampleArray(const gl::TextureState &state, + RendererD3D *renderer) + : TextureD3DImmutableBase(state, renderer) +{} + +TextureD3D_2DMultisampleArray::~TextureD3D_2DMultisampleArray() {} + +angle::Result TextureD3D_2DMultisampleArray::setStorageMultisample(const gl::Context *context, + gl::TextureType type, + GLsizei samples, + GLint internalformat, + const gl::Extents &size, + bool fixedSampleLocations) +{ + ASSERT(type == gl::TextureType::_2DMultisampleArray); + + mLayerCount = size.depth; + + TexStoragePointer storage = { + mRenderer->createTextureStorage2DMultisampleArray(internalformat, size.width, size.height, + size.depth, static_cast(0), samples, + fixedSampleLocations, mState.getLabel()), + context}; + + ANGLE_TRY(setCompleteTexStorage(context, storage.get())); + storage.release(); + + mImmutable = true; + + return angle::Result::Continue; +} + +angle::Result TextureD3D_2DMultisampleArray::setEGLImageTarget(const gl::Context *context, + gl::TextureType type, + egl::Image *image) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3D_2DMultisampleArray::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) +{ + // ensure the underlying texture is created + ANGLE_TRY(ensureRenderTarget(context)); + + return mTexStorage->getRenderTarget(context, index, samples, outRT); +} + +gl::ImageIndexIterator TextureD3D_2DMultisampleArray::imageIterator() const +{ + return gl::ImageIndexIterator::Make2DMultisampleArray(&mLayerCount); +} + +gl::ImageIndex TextureD3D_2DMultisampleArray::getImageIndex(GLint mip, GLint layer) const +{ + return gl::ImageIndex::Make2DMultisampleArray(layer); +} + +bool TextureD3D_2DMultisampleArray::isValidIndex(const gl::ImageIndex &index) const +{ + return (mTexStorage && index.getType() == gl::TextureType::_2DMultisampleArray && + index.getLevelIndex() == 0); +} + +GLsizei TextureD3D_2DMultisampleArray::getLayerCount(int level) const +{ + return mLayerCount; +} + +void TextureD3D_2DMultisampleArray::markAllImagesDirty() {} + +angle::Result TextureD3D_2DMultisampleArray::initializeStorage(const gl::Context *context, + BindFlags bindFlags) +{ + // initializeStorage should only be called in a situation where the texture already has storage + // associated with it (storage is created in setStorageMultisample). + ASSERT(mTexStorage); + return angle::Result::Continue; +} + +angle::Result TextureD3D_2DMultisampleArray::createCompleteStorage( + const gl::Context *context, + BindFlags bindFlags, + TexStoragePointer *outStorage) const +{ + UNREACHABLE(); + *outStorage = {mTexStorage, context}; + return angle::Result::Continue; +} + +angle::Result TextureD3D_2DMultisampleArray::setCompleteTexStorage( + const gl::Context *context, + TextureStorage *newCompleteTexStorage) +{ + // These textures are immutable, so this should only be ever called once. + ASSERT(!mTexStorage); + mTexStorage = newCompleteTexStorage; + mTexStorageObserverBinding.bind(mTexStorage); + return angle::Result::Continue; +} + +angle::Result TextureD3D_2DMultisampleArray::updateStorage(const gl::Context *context) +{ + return angle::Result::Continue; +} + +angle::Result TextureD3D_2DMultisampleArray::initMipmapImages(const gl::Context *context) +{ + UNIMPLEMENTED(); + return angle::Result::Continue; +} + +bool TextureD3D_2DMultisampleArray::isImageComplete(const gl::ImageIndex &index) const +{ + return true; +} + +TextureD3D_Buffer::TextureD3D_Buffer(const gl::TextureState &state, RendererD3D *renderer) + : TextureD3D(state, renderer), mInternalFormat(GL_INVALID_ENUM) +{} + +TextureD3D_Buffer::~TextureD3D_Buffer() {} + +angle::Result TextureD3D_Buffer::setImage(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + const gl::Extents &size, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3D_Buffer::setSubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3D_Buffer::setCompressedImage(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + const gl::Extents &size, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3D_Buffer::setCompressedSubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3D_Buffer::copyImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Rectangle &sourceArea, + GLenum internalFormat, + gl::Framebuffer *source) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3D_Buffer::copySubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + gl::Framebuffer *source) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3D_Buffer::bindTexImage(const gl::Context *context, egl::Surface *surface) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3D_Buffer::releaseTexImage(const gl::Context *context) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +GLsizei TextureD3D_Buffer::getLayerCount(int level) const +{ + return 1; +} + +angle::Result TextureD3D_Buffer::initMipmapImages(const gl::Context *context) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +bool TextureD3D_Buffer::isImageComplete(const gl::ImageIndex &index) const +{ + return (index.getLevelIndex() == 0) ? (mTexStorage != nullptr) : false; +} + +angle::Result TextureD3D_Buffer::initializeStorage(const gl::Context *context, BindFlags bindFlags) +{ + ASSERT(mTexStorage); + return angle::Result::Continue; +} + +angle::Result TextureD3D_Buffer::createCompleteStorage(const gl::Context *context, + BindFlags bindFlags, + TexStoragePointer *outStorage) const +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3D_Buffer::setCompleteTexStorage(const gl::Context *context, + TextureStorage *newCompleteTexStorage) +{ + ANGLE_TRY(releaseTexStorage(context, gl::TexLevelMask())); + mTexStorage = newCompleteTexStorage; + mTexStorageObserverBinding.bind(mTexStorage); + + mDirtyImages = true; + + return angle::Result::Continue; +} + +angle::Result TextureD3D_Buffer::updateStorage(const gl::Context *context) +{ + ASSERT(mTexStorage); + return angle::Result::Continue; +} + +gl::ImageIndexIterator TextureD3D_Buffer::imageIterator() const +{ + return gl::ImageIndexIterator::MakeBuffer(); +} + +gl::ImageIndex TextureD3D_Buffer::getImageIndex(GLint mip, GLint layer) const +{ + return gl::ImageIndex::MakeBuffer(); +} + +bool TextureD3D_Buffer::isValidIndex(const gl::ImageIndex &index) const +{ + return (mTexStorage && index.getType() == gl::TextureType::Buffer && + index.getLevelIndex() == 0); +} + +void TextureD3D_Buffer::markAllImagesDirty() +{ + UNREACHABLE(); +} + +angle::Result TextureD3D_Buffer::setEGLImageTarget(const gl::Context *context, + gl::TextureType type, + egl::Image *image) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +angle::Result TextureD3D_Buffer::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Continue; +} + +ImageD3D *TextureD3D_Buffer::getImage(const gl::ImageIndex &index) const +{ + return nullptr; +} + +angle::Result TextureD3D_Buffer::setBuffer(const gl::Context *context, GLenum internalFormat) +{ + ASSERT(mState.getType() == gl::TextureType::Buffer); + TexStoragePointer storage; + storage.reset(mRenderer->createTextureStorageBuffer(mState.getBuffer(), internalFormat, + mState.getLabel())); + ANGLE_TRY(setCompleteTexStorage(context, storage.get())); + storage.release(); + mInternalFormat = internalFormat; + mImmutable = false; + return angle::Result::Continue; +} + +angle::Result TextureD3D_Buffer::syncState(const gl::Context *context, + const gl::Texture::DirtyBits &dirtyBits, + gl::Command source) +{ + ASSERT(mState.getType() == gl::TextureType::Buffer); + if (dirtyBits.test(gl::Texture::DirtyBitType::DIRTY_BIT_IMPLEMENTATION) && + mState.getBuffer().get() != nullptr) + { + // buffer data have been changed. Buffer data may out of sync + // give up the old TexStorage, create a new one. + // this may not efficient, since staging buffer may be patially updated. + ANGLE_TRY(setBuffer(context, mInternalFormat)); + } + return angle::Result::Continue; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureD3D.h new file mode 100644 index 0000000000..a87806b3e7 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureD3D.h @@ -0,0 +1,1050 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// TextureD3D.h: Implementations of the Texture interfaces shared betweeen the D3D backends. + +#ifndef LIBANGLE_RENDERER_D3D_TEXTURED3D_H_ +#define LIBANGLE_RENDERER_D3D_TEXTURED3D_H_ + +#include "common/Color.h" +#include "libANGLE/Constants.h" +#include "libANGLE/Stream.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/renderer/TextureImpl.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" +#include "libANGLE/renderer/d3d/TextureStorage.h" + +namespace gl +{ +class Framebuffer; +} + +namespace rx +{ +class EGLImageD3D; +class ImageD3D; +class RendererD3D; +class RenderTargetD3D; +class TextureStorage; + +class TextureD3D : public TextureImpl, public angle::ObserverInterface +{ + public: + TextureD3D(const gl::TextureState &data, RendererD3D *renderer); + ~TextureD3D() override; + + void onDestroy(const gl::Context *context) override; + + angle::Result getNativeTexture(const gl::Context *context, TextureStorage **outStorage); + + bool hasDirtyImages() const { return mDirtyImages; } + void resetDirty() { mDirtyImages = false; } + + virtual ImageD3D *getImage(const gl::ImageIndex &index) const = 0; + virtual GLsizei getLayerCount(int level) const = 0; + + angle::Result getImageAndSyncFromStorage(const gl::Context *context, + const gl::ImageIndex &index, + ImageD3D **outImage); + + GLint getBaseLevelWidth() const; + GLint getBaseLevelHeight() const; + GLenum getBaseLevelInternalFormat() const; + + angle::Result setStorage(const gl::Context *context, + gl::TextureType type, + size_t levels, + GLenum internalFormat, + const gl::Extents &size) override; + + angle::Result setStorageMultisample(const gl::Context *context, + gl::TextureType type, + GLsizei samples, + GLint internalformat, + const gl::Extents &size, + bool fixedSampleLocations) override; + + angle::Result setBuffer(const gl::Context *context, GLenum internalFormat) override; + + angle::Result setStorageExternalMemory(const gl::Context *context, + gl::TextureType type, + size_t levels, + GLenum internalFormat, + const gl::Extents &size, + gl::MemoryObject *memoryObject, + GLuint64 offset, + GLbitfield createFlags, + GLbitfield usageFlags, + const void *imageCreateInfoPNext) override; + + bool isImmutable() const { return mImmutable; } + + virtual angle::Result getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) = 0; + + // Returns an iterator over all "Images" for this particular Texture. + virtual gl::ImageIndexIterator imageIterator() const = 0; + + // Returns an ImageIndex for a particular "Image". 3D Textures do not have images for + // slices of their depth texures, so 3D textures ignore the layer parameter. + virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const = 0; + virtual bool isValidIndex(const gl::ImageIndex &index) const = 0; + + angle::Result setImageExternal(const gl::Context *context, + gl::TextureType type, + egl::Stream *stream, + const egl::Stream::GLTextureDescription &desc) override; + angle::Result generateMipmap(const gl::Context *context) override; + bool hasStorage() const { return mTexStorage != nullptr; } + TextureStorage *getStorage(); + ImageD3D *getBaseLevelImage() const; + + angle::Result getAttachmentRenderTarget(const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex, + GLsizei samples, + FramebufferAttachmentRenderTarget **rtOut) override; + + angle::Result setBaseLevel(const gl::Context *context, GLuint baseLevel) override; + + angle::Result syncState(const gl::Context *context, + const gl::Texture::DirtyBits &dirtyBits, + gl::Command source) override; + + angle::Result initializeContents(const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex) override; + + GLsizei getRenderToTextureSamples(); + + angle::Result ensureUnorderedAccess(const gl::Context *context); + angle::Result onLabelUpdate(const gl::Context *context) override; + + // ObserverInterface implementation. + void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; + + protected: + angle::Result setImageImpl(const gl::Context *context, + const gl::ImageIndex &index, + GLenum type, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels, + ptrdiff_t layerOffset); + angle::Result subImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels, + ptrdiff_t layerOffset); + angle::Result setCompressedImageImpl(const gl::Context *context, + const gl::ImageIndex &index, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels, + ptrdiff_t layerOffset); + angle::Result subImageCompressed(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels, + ptrdiff_t layerOffset); + bool isFastUnpackable(const gl::Buffer *unpackBuffer, + const gl::PixelUnpackState &unpack, + GLenum sizedInternalFormat); + angle::Result fastUnpackPixels(const gl::Context *context, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels, + const gl::Box &destArea, + GLenum sizedInternalFormat, + GLenum type, + RenderTargetD3D *destRenderTarget); + + GLint getLevelZeroWidth() const; + GLint getLevelZeroHeight() const; + virtual GLint getLevelZeroDepth() const; + + GLint creationLevels(GLsizei width, GLsizei height, GLsizei depth) const; + virtual angle::Result initMipmapImages(const gl::Context *context) = 0; + bool isBaseImageZeroSize() const; + virtual bool isImageComplete(const gl::ImageIndex &index) const = 0; + + bool canCreateRenderTargetForImage(const gl::ImageIndex &index) const; + angle::Result ensureBindFlags(const gl::Context *context, BindFlags bindFlags); + angle::Result ensureRenderTarget(const gl::Context *context); + + virtual angle::Result createCompleteStorage(const gl::Context *context, + BindFlags bindFlags, + TexStoragePointer *outTexStorage) const = 0; + virtual angle::Result setCompleteTexStorage(const gl::Context *context, + TextureStorage *newCompleteTexStorage) = 0; + angle::Result commitRegion(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box ®ion); + + angle::Result releaseTexStorage(const gl::Context *context, + const gl::TexLevelMask ©StorageToImagesMask); + + GLuint getBaseLevel() const { return mBaseLevel; } + + virtual void markAllImagesDirty() = 0; + + GLint getBaseLevelDepth() const; + + RendererD3D *mRenderer; + + bool mDirtyImages; + + bool mImmutable; + TextureStorage *mTexStorage; + angle::ObserverBinding mTexStorageObserverBinding; + + private: + virtual angle::Result initializeStorage(const gl::Context *context, BindFlags bindFlags) = 0; + + virtual angle::Result updateStorage(const gl::Context *context) = 0; + + bool couldUseSetData() const; + bool shouldUseSetData(const ImageD3D *image) const; + + angle::Result generateMipmapUsingImages(const gl::Context *context, const GLuint maxLevel); + + GLuint mBaseLevel; +}; + +class TextureD3D_2D : public TextureD3D +{ + public: + TextureD3D_2D(const gl::TextureState &data, RendererD3D *renderer); + ~TextureD3D_2D() override; + + void onDestroy(const gl::Context *context) override; + + ImageD3D *getImage(int level, int layer) const; + ImageD3D *getImage(const gl::ImageIndex &index) const override; + GLsizei getLayerCount(int level) const override; + + GLsizei getWidth(GLint level) const; + GLsizei getHeight(GLint level) const; + GLenum getInternalFormat(GLint level) const; + bool isDepth(GLint level) const; + bool isSRGB(GLint level) const; + + angle::Result setImage(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + const gl::Extents &size, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels) override; + angle::Result setSubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels) override; + + angle::Result setCompressedImage(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + const gl::Extents &size, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) override; + angle::Result setCompressedSubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) override; + + angle::Result copyImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Rectangle &sourceArea, + GLenum internalFormat, + gl::Framebuffer *source) override; + angle::Result copySubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + gl::Framebuffer *source) override; + + angle::Result copyTexture(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + GLenum type, + GLint sourceLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) override; + angle::Result copySubTexture(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Offset &destOffset, + GLint sourceLevel, + const gl::Box &sourceBox, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) override; + angle::Result copyCompressedTexture(const gl::Context *context, + const gl::Texture *source) override; + + angle::Result setStorage(const gl::Context *context, + gl::TextureType type, + size_t levels, + GLenum internalFormat, + const gl::Extents &size) override; + + angle::Result bindTexImage(const gl::Context *context, egl::Surface *surface) override; + angle::Result releaseTexImage(const gl::Context *context) override; + + angle::Result setEGLImageTarget(const gl::Context *context, + gl::TextureType type, + egl::Image *image) override; + + angle::Result getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) override; + + gl::ImageIndexIterator imageIterator() const override; + gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override; + bool isValidIndex(const gl::ImageIndex &index) const override; + + protected: + void markAllImagesDirty() override; + + private: + angle::Result initializeStorage(const gl::Context *context, BindFlags bindFlags) override; + angle::Result createCompleteStorage(const gl::Context *context, + BindFlags bindFlags, + TexStoragePointer *outTexStorage) const override; + angle::Result setCompleteTexStorage(const gl::Context *context, + TextureStorage *newCompleteTexStorage) override; + + angle::Result updateStorage(const gl::Context *context) override; + angle::Result initMipmapImages(const gl::Context *context) override; + + bool isValidLevel(int level) const; + bool isLevelComplete(int level) const; + bool isImageComplete(const gl::ImageIndex &index) const override; + + angle::Result updateStorageLevel(const gl::Context *context, int level); + + angle::Result redefineImage(const gl::Context *context, + size_t level, + GLenum internalformat, + const gl::Extents &size, + bool forceRelease); + + bool mEGLImageTarget; + gl::TexLevelArray> mImageArray; +}; + +class TextureD3D_Cube : public TextureD3D +{ + public: + TextureD3D_Cube(const gl::TextureState &data, RendererD3D *renderer); + ~TextureD3D_Cube() override; + + void onDestroy(const gl::Context *context) override; + + ImageD3D *getImage(int level, int layer) const; + ImageD3D *getImage(const gl::ImageIndex &index) const override; + GLsizei getLayerCount(int level) const override; + + GLenum getInternalFormat(GLint level, GLint layer) const; + bool isDepth(GLint level, GLint layer) const; + bool isSRGB(GLint level, GLint layer) const; + + angle::Result setImage(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + const gl::Extents &size, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels) override; + angle::Result setSubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels) override; + + angle::Result setCompressedImage(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + const gl::Extents &size, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) override; + angle::Result setCompressedSubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) override; + + angle::Result copyImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Rectangle &sourceArea, + GLenum internalFormat, + gl::Framebuffer *source) override; + angle::Result copySubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + gl::Framebuffer *source) override; + + angle::Result copyTexture(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + GLenum type, + GLint sourceLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) override; + angle::Result copySubTexture(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Offset &destOffset, + GLint sourceLevel, + const gl::Box &sourceBox, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) override; + + angle::Result setStorage(const gl::Context *context, + gl::TextureType type, + size_t levels, + GLenum internalFormat, + const gl::Extents &size) override; + + angle::Result bindTexImage(const gl::Context *context, egl::Surface *surface) override; + angle::Result releaseTexImage(const gl::Context *context) override; + + angle::Result setEGLImageTarget(const gl::Context *context, + gl::TextureType type, + egl::Image *image) override; + + angle::Result getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) override; + + gl::ImageIndexIterator imageIterator() const override; + gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override; + bool isValidIndex(const gl::ImageIndex &index) const override; + + protected: + void markAllImagesDirty() override; + + private: + angle::Result initializeStorage(const gl::Context *context, BindFlags bindFlags) override; + angle::Result createCompleteStorage(const gl::Context *context, + BindFlags bindFlags, + TexStoragePointer *outTexStorage) const override; + angle::Result setCompleteTexStorage(const gl::Context *context, + TextureStorage *newCompleteTexStorage) override; + + angle::Result updateStorage(const gl::Context *context) override; + angle::Result initMipmapImages(const gl::Context *context) override; + + bool isValidFaceLevel(int faceIndex, int level) const; + bool isFaceLevelComplete(int faceIndex, int level) const; + bool isCubeComplete() const; + bool isImageComplete(const gl::ImageIndex &index) const override; + angle::Result updateStorageFaceLevel(const gl::Context *context, int faceIndex, int level); + + angle::Result redefineImage(const gl::Context *context, + int faceIndex, + GLint level, + GLenum internalformat, + const gl::Extents &size, + bool forceRelease); + + std::array>, 6> mImageArray; +}; + +class TextureD3D_3D : public TextureD3D +{ + public: + TextureD3D_3D(const gl::TextureState &data, RendererD3D *renderer); + ~TextureD3D_3D() override; + + void onDestroy(const gl::Context *context) override; + + ImageD3D *getImage(int level, int layer) const; + ImageD3D *getImage(const gl::ImageIndex &index) const override; + GLsizei getLayerCount(int level) const override; + + GLsizei getWidth(GLint level) const; + GLsizei getHeight(GLint level) const; + GLsizei getDepth(GLint level) const; + GLenum getInternalFormat(GLint level) const; + bool isDepth(GLint level) const; + bool isSRGB(GLint level) const; + + angle::Result setImage(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + const gl::Extents &size, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels) override; + angle::Result setSubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels) override; + + angle::Result setCompressedImage(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + const gl::Extents &size, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) override; + angle::Result setCompressedSubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) override; + + angle::Result copyImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Rectangle &sourceArea, + GLenum internalFormat, + gl::Framebuffer *source) override; + angle::Result copySubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + gl::Framebuffer *source) override; + + angle::Result copyTexture(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + GLenum type, + GLint sourceLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) override; + angle::Result copySubTexture(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Offset &destOffset, + GLint sourceLevel, + const gl::Box &sourceBox, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) override; + + angle::Result setStorage(const gl::Context *context, + gl::TextureType type, + size_t levels, + GLenum internalFormat, + const gl::Extents &size) override; + + angle::Result bindTexImage(const gl::Context *context, egl::Surface *surface) override; + angle::Result releaseTexImage(const gl::Context *context) override; + + angle::Result setEGLImageTarget(const gl::Context *context, + gl::TextureType type, + egl::Image *image) override; + + angle::Result getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) override; + + gl::ImageIndexIterator imageIterator() const override; + gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override; + bool isValidIndex(const gl::ImageIndex &index) const override; + + protected: + void markAllImagesDirty() override; + GLint getLevelZeroDepth() const override; + + private: + angle::Result initializeStorage(const gl::Context *context, BindFlags bindFlags) override; + angle::Result createCompleteStorage(const gl::Context *context, + BindFlags bindFlags, + TexStoragePointer *outStorage) const override; + angle::Result setCompleteTexStorage(const gl::Context *context, + TextureStorage *newCompleteTexStorage) override; + + angle::Result updateStorage(const gl::Context *context) override; + angle::Result initMipmapImages(const gl::Context *context) override; + + bool isValidLevel(int level) const; + bool isLevelComplete(int level) const; + bool isImageComplete(const gl::ImageIndex &index) const override; + angle::Result updateStorageLevel(const gl::Context *context, int level); + + angle::Result redefineImage(const gl::Context *context, + GLint level, + GLenum internalformat, + const gl::Extents &size, + bool forceRelease); + + gl::TexLevelArray> mImageArray; +}; + +class TextureD3D_2DArray : public TextureD3D +{ + public: + TextureD3D_2DArray(const gl::TextureState &data, RendererD3D *renderer); + ~TextureD3D_2DArray() override; + + void onDestroy(const gl::Context *context) override; + + virtual ImageD3D *getImage(int level, int layer) const; + ImageD3D *getImage(const gl::ImageIndex &index) const override; + GLsizei getLayerCount(int level) const override; + + GLsizei getWidth(GLint level) const; + GLsizei getHeight(GLint level) const; + GLenum getInternalFormat(GLint level) const; + bool isDepth(GLint level) const; + + angle::Result setImage(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + const gl::Extents &size, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels) override; + angle::Result setSubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels) override; + + angle::Result setCompressedImage(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + const gl::Extents &size, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) override; + angle::Result setCompressedSubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) override; + + angle::Result copyImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Rectangle &sourceArea, + GLenum internalFormat, + gl::Framebuffer *source) override; + angle::Result copySubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + gl::Framebuffer *source) override; + + angle::Result copyTexture(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + GLenum type, + GLint sourceLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) override; + angle::Result copySubTexture(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Offset &destOffset, + GLint sourceLevel, + const gl::Box &sourceBox, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) override; + + angle::Result setStorage(const gl::Context *context, + gl::TextureType type, + size_t levels, + GLenum internalFormat, + const gl::Extents &size) override; + + angle::Result bindTexImage(const gl::Context *context, egl::Surface *surface) override; + angle::Result releaseTexImage(const gl::Context *context) override; + + angle::Result setEGLImageTarget(const gl::Context *context, + gl::TextureType type, + egl::Image *image) override; + + angle::Result getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) override; + + gl::ImageIndexIterator imageIterator() const override; + gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override; + bool isValidIndex(const gl::ImageIndex &index) const override; + + protected: + void markAllImagesDirty() override; + + private: + angle::Result initializeStorage(const gl::Context *context, BindFlags bindFlags) override; + angle::Result createCompleteStorage(const gl::Context *context, + BindFlags bindFlags, + TexStoragePointer *outStorage) const override; + angle::Result setCompleteTexStorage(const gl::Context *context, + TextureStorage *newCompleteTexStorage) override; + + angle::Result updateStorage(const gl::Context *context) override; + angle::Result initMipmapImages(const gl::Context *context) override; + + bool isValidLevel(int level) const; + bool isLevelComplete(int level) const; + bool isImageComplete(const gl::ImageIndex &index) const override; + bool isSRGB(GLint level) const; + angle::Result updateStorageLevel(const gl::Context *context, int level); + + void deleteImages(); + angle::Result redefineImage(const gl::Context *context, + GLint level, + GLenum internalformat, + const gl::Extents &size, + bool forceRelease); + + // Storing images as an array of single depth textures since D3D11 treats each array level of a + // Texture2D object as a separate subresource. Each layer would have to be looped over + // to update all the texture layers since they cannot all be updated at once and it makes the + // most sense for the Image class to not have to worry about layer subresource as well as mip + // subresources. + GLsizei mLayerCounts[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + ImageD3D **mImageArray[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; +}; + +// Base class for immutable textures. These don't support manipulation of individual texture images. +class TextureD3DImmutableBase : public TextureD3D +{ + public: + TextureD3DImmutableBase(const gl::TextureState &data, RendererD3D *renderer); + ~TextureD3DImmutableBase() override; + + ImageD3D *getImage(const gl::ImageIndex &index) const override; + angle::Result setImage(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + const gl::Extents &size, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels) override; + angle::Result setSubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels) override; + + angle::Result setCompressedImage(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + const gl::Extents &size, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) override; + angle::Result setCompressedSubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) override; + + angle::Result copyImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Rectangle &sourceArea, + GLenum internalFormat, + gl::Framebuffer *source) override; + angle::Result copySubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + gl::Framebuffer *source) override; + + angle::Result bindTexImage(const gl::Context *context, egl::Surface *surface) override; + angle::Result releaseTexImage(const gl::Context *context) override; +}; + +class TextureD3D_External : public TextureD3DImmutableBase +{ + public: + TextureD3D_External(const gl::TextureState &data, RendererD3D *renderer); + ~TextureD3D_External() override; + + GLsizei getLayerCount(int level) const override; + + angle::Result setImageExternal(const gl::Context *context, + gl::TextureType type, + egl::Stream *stream, + const egl::Stream::GLTextureDescription &desc) override; + + angle::Result setEGLImageTarget(const gl::Context *context, + gl::TextureType type, + egl::Image *image) override; + + angle::Result getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) override; + + gl::ImageIndexIterator imageIterator() const override; + gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override; + bool isValidIndex(const gl::ImageIndex &index) const override; + + protected: + void markAllImagesDirty() override; + + private: + angle::Result initializeStorage(const gl::Context *context, BindFlags bindFlags) override; + angle::Result createCompleteStorage(const gl::Context *context, + BindFlags bindFlags, + TexStoragePointer *outTexStorage) const override; + angle::Result setCompleteTexStorage(const gl::Context *context, + TextureStorage *newCompleteTexStorage) override; + + angle::Result updateStorage(const gl::Context *context) override; + angle::Result initMipmapImages(const gl::Context *context) override; + + bool isImageComplete(const gl::ImageIndex &index) const override; +}; + +class TextureD3D_2DMultisample : public TextureD3DImmutableBase +{ + public: + TextureD3D_2DMultisample(const gl::TextureState &data, RendererD3D *renderer); + ~TextureD3D_2DMultisample() override; + + angle::Result setStorageMultisample(const gl::Context *context, + gl::TextureType type, + GLsizei samples, + GLint internalformat, + const gl::Extents &size, + bool fixedSampleLocations) override; + + angle::Result setEGLImageTarget(const gl::Context *context, + gl::TextureType type, + egl::Image *image) override; + + angle::Result getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) override; + + gl::ImageIndexIterator imageIterator() const override; + gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override; + bool isValidIndex(const gl::ImageIndex &index) const override; + + GLsizei getLayerCount(int level) const override; + + protected: + void markAllImagesDirty() override; + + angle::Result setCompleteTexStorage(const gl::Context *context, + TextureStorage *newCompleteTexStorage) override; + + angle::Result updateStorage(const gl::Context *context) override; + + private: + angle::Result initializeStorage(const gl::Context *context, BindFlags bindFlags) override; + angle::Result createCompleteStorage(const gl::Context *context, + BindFlags bindFlags, + TexStoragePointer *outTexStorage) const override; + angle::Result initMipmapImages(const gl::Context *context) override; + + bool isImageComplete(const gl::ImageIndex &index) const override; +}; + +class TextureD3D_2DMultisampleArray : public TextureD3DImmutableBase +{ + public: + TextureD3D_2DMultisampleArray(const gl::TextureState &data, RendererD3D *renderer); + ~TextureD3D_2DMultisampleArray() override; + + angle::Result setStorageMultisample(const gl::Context *context, + gl::TextureType type, + GLsizei samples, + GLint internalformat, + const gl::Extents &size, + bool fixedSampleLocations) override; + + angle::Result setEGLImageTarget(const gl::Context *context, + gl::TextureType type, + egl::Image *image) override; + + angle::Result getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) override; + + gl::ImageIndexIterator imageIterator() const override; + gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override; + bool isValidIndex(const gl::ImageIndex &index) const override; + + GLsizei getLayerCount(int level) const override; + + protected: + void markAllImagesDirty() override; + + angle::Result setCompleteTexStorage(const gl::Context *context, + TextureStorage *newCompleteTexStorage) override; + + angle::Result updateStorage(const gl::Context *context) override; + + private: + angle::Result initializeStorage(const gl::Context *context, BindFlags bindFlags) override; + angle::Result createCompleteStorage(const gl::Context *context, + BindFlags bindFlags, + TexStoragePointer *outTexStorage) const override; + angle::Result initMipmapImages(const gl::Context *context) override; + + bool isImageComplete(const gl::ImageIndex &index) const override; + + GLsizei mLayerCount; +}; + +class TextureD3D_Buffer : public TextureD3D +{ + public: + TextureD3D_Buffer(const gl::TextureState &data, RendererD3D *renderer); + ~TextureD3D_Buffer() override; + + ImageD3D *getImage(const gl::ImageIndex &index) const override; + + angle::Result setBuffer(const gl::Context *context, GLenum internalFormat) override; + + angle::Result setImage(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + const gl::Extents &size, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels) override; + angle::Result setSubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels) override; + + angle::Result setCompressedImage(const gl::Context *context, + const gl::ImageIndex &index, + GLenum internalFormat, + const gl::Extents &size, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) override; + angle::Result setCompressedSubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) override; + + angle::Result copyImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Rectangle &sourceArea, + GLenum internalFormat, + gl::Framebuffer *source) override; + angle::Result copySubImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + gl::Framebuffer *source) override; + + angle::Result bindTexImage(const gl::Context *context, egl::Surface *surface) override; + angle::Result releaseTexImage(const gl::Context *context) override; + + angle::Result setEGLImageTarget(const gl::Context *context, + gl::TextureType type, + egl::Image *image) override; + + angle::Result getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) override; + + GLsizei getLayerCount(int level) const override; + + angle::Result syncState(const gl::Context *context, + const gl::Texture::DirtyBits &dirtyBits, + gl::Command source) override; + + gl::ImageIndexIterator imageIterator() const override; + gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override; + bool isValidIndex(const gl::ImageIndex &index) const override; + + protected: + void markAllImagesDirty() override; + + private: + angle::Result initializeStorage(const gl::Context *context, BindFlags bindFlags) override; + angle::Result createCompleteStorage(const gl::Context *context, + BindFlags bindFlags, + TexStoragePointer *outTexStorage) const override; + angle::Result setCompleteTexStorage(const gl::Context *context, + TextureStorage *newCompleteTexStorage) override; + + angle::Result updateStorage(const gl::Context *context) override; + angle::Result initMipmapImages(const gl::Context *context) override; + + bool isImageComplete(const gl::ImageIndex &index) const override; + + GLenum mInternalFormat; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_TEXTURED3D_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureStorage.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureStorage.h new file mode 100644 index 0000000000..fc073f8b5a --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureStorage.h @@ -0,0 +1,135 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// TextureStorage.h: Defines the abstract rx::TextureStorage class. + +#ifndef LIBANGLE_RENDERER_D3D_TEXTURESTORAGE_H_ +#define LIBANGLE_RENDERER_D3D_TEXTURESTORAGE_H_ + +#include "common/debug.h" +#include "libANGLE/angletypes.h" + +#include +#include + +namespace gl +{ +class Context; +class ImageIndex; +struct Box; +struct PixelUnpackState; +} // namespace gl + +namespace angle +{ +class Subject; +} // namespace angle + +namespace rx +{ +class SwapChainD3D; +class RenderTargetD3D; +class ImageD3D; + +// Dirty bit messages from TextureStorage +constexpr size_t kTextureStorageObserverMessageIndex = 0; + +class TextureStorage : public angle::Subject +{ + public: + TextureStorage(const std::string &label) : mKHRDebugLabel(label) {} + ~TextureStorage() override {} + + virtual angle::Result onDestroy(const gl::Context *context); + + virtual int getTopLevel() const = 0; + virtual bool isRenderTarget() const = 0; + virtual bool isUnorderedAccess() const = 0; + virtual bool isManaged() const = 0; + virtual bool supportsNativeMipmapFunction() const = 0; + virtual int getLevelCount() const = 0; + + virtual angle::Result findRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) const = 0; + virtual angle::Result getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) = 0; + virtual angle::Result generateMipmap(const gl::Context *context, + const gl::ImageIndex &sourceIndex, + const gl::ImageIndex &destIndex) = 0; + + virtual angle::Result copyToStorage(const gl::Context *context, + TextureStorage *destStorage) = 0; + virtual angle::Result setData(const gl::Context *context, + const gl::ImageIndex &index, + ImageD3D *image, + const gl::Box *destBox, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixelData) = 0; + + // This is a no-op for most implementations of TextureStorage. Some (e.g. TextureStorage11_2D) + // might override it. + virtual angle::Result useLevelZeroWorkaroundTexture(const gl::Context *context, + bool useLevelZeroTexture); + + virtual void invalidateTextures() {} + + // RenderToTexture methods + virtual angle::Result releaseMultisampledTexStorageForLevel(size_t level); + virtual angle::Result resolveTexture(const gl::Context *context); + virtual GLsizei getRenderToTextureSamples() const; + + // Called by outer object when label has changed via KHR_debug extension + void setLabel(const std::string &newLabel); + + protected: + virtual void onLabelUpdate() {} + + const angle::Subject *mSubject; + std::string mKHRDebugLabel; +}; + +inline angle::Result TextureStorage::onDestroy(const gl::Context *context) +{ + return angle::Result::Continue; +} + +inline angle::Result TextureStorage::useLevelZeroWorkaroundTexture(const gl::Context *context, + bool useLevelZeroTexture) +{ + return angle::Result::Continue; +} + +inline angle::Result TextureStorage::releaseMultisampledTexStorageForLevel(size_t level) +{ + return angle::Result::Continue; +} + +inline angle::Result TextureStorage::resolveTexture(const gl::Context *context) +{ + return angle::Result::Continue; +} + +inline GLsizei TextureStorage::getRenderToTextureSamples() const +{ + return 0; +} + +inline void TextureStorage::setLabel(const std::string &newLabel) +{ + mKHRDebugLabel = newLabel; + onLabelUpdate(); +} + +using TexStoragePointer = angle::UniqueObjectPointer; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_TEXTURESTORAGE_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexBuffer.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexBuffer.cpp new file mode 100644 index 0000000000..acb27adfcc --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexBuffer.cpp @@ -0,0 +1,308 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// VertexBuffer.cpp: Defines the abstract VertexBuffer class and VertexBufferInterface +// class with derivations, classes that perform graphics API agnostic vertex buffer operations. + +#include "libANGLE/renderer/d3d/VertexBuffer.h" + +#include "common/mathutil.h" +#include "libANGLE/Context.h" +#include "libANGLE/VertexAttribute.h" +#include "libANGLE/renderer/d3d/BufferD3D.h" +#include "libANGLE/renderer/d3d/ContextD3D.h" + +namespace rx +{ + +// VertexBuffer Implementation +unsigned int VertexBuffer::mNextSerial = 1; + +VertexBuffer::VertexBuffer() : mRefCount(1) +{ + updateSerial(); +} + +VertexBuffer::~VertexBuffer() {} + +void VertexBuffer::updateSerial() +{ + mSerial = mNextSerial++; +} + +unsigned int VertexBuffer::getSerial() const +{ + return mSerial; +} + +void VertexBuffer::addRef() +{ + mRefCount++; +} + +void VertexBuffer::release() +{ + ASSERT(mRefCount > 0); + mRefCount--; + + if (mRefCount == 0) + { + delete this; + } +} + +// VertexBufferInterface Implementation +VertexBufferInterface::VertexBufferInterface(BufferFactoryD3D *factory, bool dynamic) + : mFactory(factory), mVertexBuffer(factory->createVertexBuffer()), mDynamic(dynamic) +{} + +VertexBufferInterface::~VertexBufferInterface() +{ + if (mVertexBuffer) + { + mVertexBuffer->release(); + mVertexBuffer = nullptr; + } +} + +unsigned int VertexBufferInterface::getSerial() const +{ + ASSERT(mVertexBuffer); + return mVertexBuffer->getSerial(); +} + +unsigned int VertexBufferInterface::getBufferSize() const +{ + ASSERT(mVertexBuffer); + return mVertexBuffer->getBufferSize(); +} + +angle::Result VertexBufferInterface::setBufferSize(const gl::Context *context, unsigned int size) +{ + ASSERT(mVertexBuffer); + if (mVertexBuffer->getBufferSize() == 0) + { + return mVertexBuffer->initialize(context, size, mDynamic); + } + + return mVertexBuffer->setBufferSize(context, size); +} + +angle::Result VertexBufferInterface::getSpaceRequired(const gl::Context *context, + const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + size_t count, + GLsizei instances, + GLuint baseInstance, + unsigned int *spaceInBytesOut) const +{ + unsigned int spaceRequired = 0; + ANGLE_TRY(mFactory->getVertexSpaceRequired(context, attrib, binding, count, instances, + baseInstance, &spaceRequired)); + + // Align to 16-byte boundary + unsigned int alignedSpaceRequired = roundUpPow2(spaceRequired, 16u); + ANGLE_CHECK_GL_ALLOC(GetImplAs(context), alignedSpaceRequired >= spaceRequired); + + *spaceInBytesOut = alignedSpaceRequired; + return angle::Result::Continue; +} + +angle::Result VertexBufferInterface::discard(const gl::Context *context) +{ + ASSERT(mVertexBuffer); + return mVertexBuffer->discard(context); +} + +VertexBuffer *VertexBufferInterface::getVertexBuffer() const +{ + ASSERT(mVertexBuffer); + return mVertexBuffer; +} + +// StreamingVertexBufferInterface Implementation +StreamingVertexBufferInterface::StreamingVertexBufferInterface(BufferFactoryD3D *factory) + : VertexBufferInterface(factory, true), mWritePosition(0), mReservedSpace(0) +{} + +angle::Result StreamingVertexBufferInterface::initialize(const gl::Context *context, + std::size_t initialSize) +{ + return setBufferSize(context, static_cast(initialSize)); +} + +void StreamingVertexBufferInterface::reset() +{ + if (mVertexBuffer) + { + mVertexBuffer->release(); + mVertexBuffer = mFactory->createVertexBuffer(); + } +} + +StreamingVertexBufferInterface::~StreamingVertexBufferInterface() {} + +angle::Result StreamingVertexBufferInterface::reserveSpace(const gl::Context *context, + unsigned int size) +{ + unsigned int curBufferSize = getBufferSize(); + if (size > curBufferSize) + { + ANGLE_TRY(setBufferSize(context, std::max(size, 3 * curBufferSize / 2))); + mWritePosition = 0; + } + else if (mWritePosition + size > curBufferSize) + { + ANGLE_TRY(discard(context)); + mWritePosition = 0; + } + + mReservedSpace = size; + return angle::Result::Continue; +} + +angle::Result StreamingVertexBufferInterface::storeDynamicAttribute( + const gl::Context *context, + const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + gl::VertexAttribType currentValueType, + GLint start, + size_t count, + GLsizei instances, + GLuint baseInstance, + unsigned int *outStreamOffset, + const uint8_t *sourceData) +{ + unsigned int spaceRequired = 0; + ANGLE_TRY( + getSpaceRequired(context, attrib, binding, count, instances, baseInstance, &spaceRequired)); + + // Protect against integer overflow + angle::CheckedNumeric checkedPosition(mWritePosition); + checkedPosition += spaceRequired; + ANGLE_CHECK_GL_ALLOC(GetImplAs(context), checkedPosition.IsValid()); + + mReservedSpace = 0; + + size_t adjustedCount = count; + GLuint divisor = binding.getDivisor(); + + if (instances != 0 && divisor != 0) + { + // The attribute is an instanced attribute and it's an draw instance call + // Extra number of elements are copied at the beginning to make sure + // the driver is referencing the correct data with non-zero baseInstance + adjustedCount += UnsignedCeilDivide(baseInstance, divisor); + } + + ANGLE_TRY(mVertexBuffer->storeVertexAttributes(context, attrib, binding, currentValueType, + start, adjustedCount, instances, mWritePosition, + sourceData)); + + if (outStreamOffset) + { + *outStreamOffset = mWritePosition; + } + + mWritePosition += spaceRequired; + + return angle::Result::Continue; +} + +angle::Result StreamingVertexBufferInterface::reserveVertexSpace(const gl::Context *context, + const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + size_t count, + GLsizei instances, + GLuint baseInstance) +{ + unsigned int requiredSpace = 0; + ANGLE_TRY(mFactory->getVertexSpaceRequired(context, attrib, binding, count, instances, + baseInstance, &requiredSpace)); + + // Align to 16-byte boundary + auto alignedRequiredSpace = rx::CheckedRoundUp(requiredSpace, 16u); + alignedRequiredSpace += mReservedSpace; + + // Protect against integer overflow + ANGLE_CHECK_GL_ALLOC(GetImplAs(context), alignedRequiredSpace.IsValid()); + + ANGLE_TRY(reserveSpace(context, alignedRequiredSpace.ValueOrDie())); + + return angle::Result::Continue; +} + +// StaticVertexBufferInterface Implementation +StaticVertexBufferInterface::AttributeSignature::AttributeSignature() + : formatID(angle::FormatID::NONE), stride(0), offset(0) +{} + +bool StaticVertexBufferInterface::AttributeSignature::matchesAttribute( + const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding) const +{ + size_t attribStride = ComputeVertexAttributeStride(attrib, binding); + + if (formatID != attrib.format->id || static_cast(stride) != attribStride) + { + return false; + } + + size_t attribOffset = + (static_cast(ComputeVertexAttributeOffset(attrib, binding)) % attribStride); + return (offset == attribOffset); +} + +void StaticVertexBufferInterface::AttributeSignature::set(const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding) +{ + formatID = attrib.format->id; + offset = stride = static_cast(ComputeVertexAttributeStride(attrib, binding)); + offset = static_cast(ComputeVertexAttributeOffset(attrib, binding)) % + ComputeVertexAttributeStride(attrib, binding); +} + +StaticVertexBufferInterface::StaticVertexBufferInterface(BufferFactoryD3D *factory) + : VertexBufferInterface(factory, false) +{} + +StaticVertexBufferInterface::~StaticVertexBufferInterface() {} + +bool StaticVertexBufferInterface::matchesAttribute(const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding) const +{ + return mSignature.matchesAttribute(attrib, binding); +} + +void StaticVertexBufferInterface::setAttribute(const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding) +{ + return mSignature.set(attrib, binding); +} + +angle::Result StaticVertexBufferInterface::storeStaticAttribute(const gl::Context *context, + const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + GLint start, + GLsizei count, + GLsizei instances, + const uint8_t *sourceData) +{ + unsigned int spaceRequired = 0; + ANGLE_TRY(getSpaceRequired(context, attrib, binding, count, instances, 0, &spaceRequired)); + ANGLE_TRY(setBufferSize(context, spaceRequired)); + + ASSERT(attrib.enabled); + ANGLE_TRY(mVertexBuffer->storeVertexAttributes(context, attrib, binding, + gl::VertexAttribType::InvalidEnum, start, count, + instances, 0, sourceData)); + + mSignature.set(attrib, binding); + mVertexBuffer->hintUnmapResource(); + return angle::Result::Continue; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexBuffer.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexBuffer.h new file mode 100644 index 0000000000..45a16c6bf5 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexBuffer.h @@ -0,0 +1,189 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// VertexBuffer.h: Defines the abstract VertexBuffer class and VertexBufferInterface +// class with derivations, classes that perform graphics API agnostic vertex buffer operations. + +#ifndef LIBANGLE_RENDERER_D3D_VERTEXBUFFER_H_ +#define LIBANGLE_RENDERER_D3D_VERTEXBUFFER_H_ + +#include "common/PackedEnums.h" +#include "common/angleutils.h" +#include "libANGLE/Error.h" +#include "libANGLE/renderer/Format.h" + +#include + +#include +#include +#include + +namespace gl +{ +class Context; +struct VertexAttribute; +class VertexBinding; +struct VertexAttribCurrentValueData; +} // namespace gl + +namespace rx +{ +class BufferFactoryD3D; + +// Use a ref-counting scheme with self-deletion on release. We do this so that we can more +// easily manage the static buffer cache, without deleting currently bound buffers. +class VertexBuffer : angle::NonCopyable +{ + public: + VertexBuffer(); + + virtual angle::Result initialize(const gl::Context *context, + unsigned int size, + bool dynamicUsage) = 0; + + // Warning: you should ensure binding really matches attrib.bindingIndex before using this + // function. + virtual angle::Result storeVertexAttributes(const gl::Context *context, + const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + gl::VertexAttribType currentValueType, + GLint start, + size_t count, + GLsizei instances, + unsigned int offset, + const uint8_t *sourceData) = 0; + + virtual unsigned int getBufferSize() const = 0; + virtual angle::Result setBufferSize(const gl::Context *context, unsigned int size) = 0; + virtual angle::Result discard(const gl::Context *context) = 0; + + unsigned int getSerial() const; + + // This may be overridden (e.g. by VertexBuffer11) if necessary. + virtual void hintUnmapResource() {} + + // Reference counting. + void addRef(); + void release(); + + protected: + void updateSerial(); + virtual ~VertexBuffer(); + + private: + unsigned int mSerial; + static unsigned int mNextSerial; + unsigned int mRefCount; +}; + +class VertexBufferInterface : angle::NonCopyable +{ + public: + VertexBufferInterface(BufferFactoryD3D *factory, bool dynamic); + virtual ~VertexBufferInterface(); + + unsigned int getBufferSize() const; + bool empty() const { return getBufferSize() == 0; } + + unsigned int getSerial() const; + + VertexBuffer *getVertexBuffer() const; + + protected: + angle::Result discard(const gl::Context *context); + + angle::Result setBufferSize(const gl::Context *context, unsigned int size); + + angle::Result getSpaceRequired(const gl::Context *context, + const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + size_t count, + GLsizei instances, + GLuint baseInstance, + unsigned int *spaceInBytesOut) const; + BufferFactoryD3D *const mFactory; + VertexBuffer *mVertexBuffer; + bool mDynamic; +}; + +class StreamingVertexBufferInterface : public VertexBufferInterface +{ + public: + StreamingVertexBufferInterface(BufferFactoryD3D *factory); + ~StreamingVertexBufferInterface() override; + + angle::Result initialize(const gl::Context *context, std::size_t initialSize); + void reset(); + + angle::Result storeDynamicAttribute(const gl::Context *context, + const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + gl::VertexAttribType currentValueType, + GLint start, + size_t count, + GLsizei instances, + GLuint baseInstance, + unsigned int *outStreamOffset, + const uint8_t *sourceData); + + angle::Result reserveVertexSpace(const gl::Context *context, + const gl::VertexAttribute &attribute, + const gl::VertexBinding &binding, + size_t count, + GLsizei instances, + GLuint baseInstance); + + private: + angle::Result reserveSpace(const gl::Context *context, unsigned int size); + + unsigned int mWritePosition; + unsigned int mReservedSpace; +}; + +class StaticVertexBufferInterface : public VertexBufferInterface +{ + public: + explicit StaticVertexBufferInterface(BufferFactoryD3D *factory); + ~StaticVertexBufferInterface() override; + + // Warning: you should ensure binding really matches attrib.bindingIndex before using these + // functions. + angle::Result storeStaticAttribute(const gl::Context *context, + const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + GLint start, + GLsizei count, + GLsizei instances, + const uint8_t *sourceData); + + bool matchesAttribute(const gl::VertexAttribute &attribute, + const gl::VertexBinding &binding) const; + + void setAttribute(const gl::VertexAttribute &attribute, const gl::VertexBinding &binding); + + private: + class AttributeSignature final : angle::NonCopyable + { + public: + AttributeSignature(); + + bool matchesAttribute(const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding) const; + + void set(const gl::VertexAttribute &attrib, const gl::VertexBinding &binding); + + private: + angle::FormatID formatID; + GLuint stride; + size_t offset; + }; + + AttributeSignature mSignature; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_VERTEXBUFFER_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexDataManager.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexDataManager.cpp new file mode 100644 index 0000000000..6b989c9e80 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexDataManager.cpp @@ -0,0 +1,683 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// VertexDataManager.h: Defines the VertexDataManager, a class that +// runs the Buffer translation process. + +#include "libANGLE/renderer/d3d/VertexDataManager.h" + +#include "common/bitset_utils.h" +#include "libANGLE/Buffer.h" +#include "libANGLE/Context.h" +#include "libANGLE/Program.h" +#include "libANGLE/State.h" +#include "libANGLE/VertexArray.h" +#include "libANGLE/VertexAttribute.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/BufferD3D.h" +#include "libANGLE/renderer/d3d/ContextD3D.h" +#include "libANGLE/renderer/d3d/VertexBuffer.h" + +using namespace angle; + +namespace rx +{ +namespace +{ +enum +{ + INITIAL_STREAM_BUFFER_SIZE = 1024 * 1024 +}; +// This has to be at least 4k or else it fails on ATI cards. +enum +{ + CONSTANT_VERTEX_BUFFER_SIZE = 4096 +}; + +// Warning: ensure the binding matches attrib.bindingIndex before using these functions. +int64_t GetMaxAttributeByteOffsetForDraw(const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + int64_t elementCount) +{ + CheckedNumeric stride = ComputeVertexAttributeStride(attrib, binding); + CheckedNumeric offset = ComputeVertexAttributeOffset(attrib, binding); + CheckedNumeric size = ComputeVertexAttributeTypeSize(attrib); + + ASSERT(elementCount > 0); + + CheckedNumeric result = + stride * (CheckedNumeric(elementCount) - 1) + size + offset; + return result.ValueOrDefault(std::numeric_limits::max()); +} + +// Warning: ensure the binding matches attrib.bindingIndex before using these functions. +int ElementsInBuffer(const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + unsigned int size) +{ + angle::CheckedNumeric bufferSize(size); + angle::CheckedNumeric stride = ComputeVertexAttributeStride(attrib, binding); + angle::CheckedNumeric offset = ComputeVertexAttributeOffset(attrib, binding); + angle::CheckedNumeric elementSize = ComputeVertexAttributeTypeSize(attrib); + + auto elementsInBuffer = (bufferSize - (offset % stride) + (stride - elementSize)) / stride; + auto elementsInBufferInt = elementsInBuffer.Cast(); + + return elementsInBufferInt.ValueOrDefault(0); +} + +// Warning: you should ensure binding really matches attrib.bindingIndex before using this function. +bool DirectStoragePossible(const gl::Context *context, + const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding) +{ + // Current value attribs may not use direct storage. + if (!attrib.enabled) + { + return false; + } + + gl::Buffer *buffer = binding.getBuffer().get(); + if (!buffer) + { + return false; + } + + BufferD3D *bufferD3D = GetImplAs(buffer); + ASSERT(bufferD3D); + if (!bufferD3D->supportsDirectBinding()) + { + return false; + } + + // Alignment restrictions: In D3D, vertex data must be aligned to the format stride, or to a + // 4-byte boundary, whichever is smaller. (Undocumented, and experimentally confirmed) + size_t alignment = 4; + + // TODO(jmadill): add VertexFormatCaps + BufferFactoryD3D *factory = bufferD3D->getFactory(); + + angle::FormatID vertexFormatID = attrib.format->id; + + // CPU-converted vertex data must be converted (naturally). + if ((factory->getVertexConversionType(vertexFormatID) & VERTEX_CONVERT_CPU) != 0) + { + return false; + } + + if (attrib.format->vertexAttribType != gl::VertexAttribType::Float) + { + unsigned int elementSize = 0; + angle::Result error = + factory->getVertexSpaceRequired(context, attrib, binding, 1, 0, 0, &elementSize); + ASSERT(error == angle::Result::Continue); + alignment = std::min(elementSize, 4); + } + + GLintptr offset = ComputeVertexAttributeOffset(attrib, binding); + // Final alignment check - unaligned data must be converted. + return (static_cast(ComputeVertexAttributeStride(attrib, binding)) % alignment == 0) && + (static_cast(offset) % alignment == 0); +} +} // anonymous namespace + +TranslatedAttribute::TranslatedAttribute() + : active(false), + attribute(nullptr), + binding(nullptr), + currentValueType(gl::VertexAttribType::InvalidEnum), + baseOffset(0), + usesFirstVertexOffset(false), + stride(0), + vertexBuffer(), + storage(nullptr), + serial(0), + divisor(0) +{} + +TranslatedAttribute::TranslatedAttribute(const TranslatedAttribute &other) = default; + +angle::Result TranslatedAttribute::computeOffset(const gl::Context *context, + GLint startVertex, + unsigned int *offsetOut) const +{ + if (!usesFirstVertexOffset) + { + *offsetOut = baseOffset; + return angle::Result::Continue; + } + + CheckedNumeric offset(baseOffset); + CheckedNumeric checkedStride(stride); + + offset += checkedStride * static_cast(startVertex); + ANGLE_CHECK_GL_MATH(GetImplAs(context), offset.IsValid()); + *offsetOut = offset.ValueOrDie(); + return angle::Result::Continue; +} + +// Warning: you should ensure binding really matches attrib.bindingIndex before using this function. +VertexStorageType ClassifyAttributeStorage(const gl::Context *context, + const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding) +{ + // If attribute is disabled, we use the current value. + if (!attrib.enabled) + { + return VertexStorageType::CURRENT_VALUE; + } + + // If specified with immediate data, we must use dynamic storage. + gl::Buffer *buffer = binding.getBuffer().get(); + if (!buffer) + { + return VertexStorageType::DYNAMIC; + } + + // Check if the buffer supports direct storage. + if (DirectStoragePossible(context, attrib, binding)) + { + return VertexStorageType::DIRECT; + } + + // Otherwise the storage is static or dynamic. + BufferD3D *bufferD3D = GetImplAs(buffer); + ASSERT(bufferD3D); + switch (bufferD3D->getUsage()) + { + case D3DBufferUsage::DYNAMIC: + return VertexStorageType::DYNAMIC; + case D3DBufferUsage::STATIC: + return VertexStorageType::STATIC; + default: + UNREACHABLE(); + return VertexStorageType::UNKNOWN; + } +} + +VertexDataManager::CurrentValueState::CurrentValueState(BufferFactoryD3D *factory) + : buffer(new StreamingVertexBufferInterface(factory)), offset(0) +{ + data.Values.FloatValues[0] = std::numeric_limits::quiet_NaN(); + data.Values.FloatValues[1] = std::numeric_limits::quiet_NaN(); + data.Values.FloatValues[2] = std::numeric_limits::quiet_NaN(); + data.Values.FloatValues[3] = std::numeric_limits::quiet_NaN(); + data.Type = gl::VertexAttribType::Float; +} + +VertexDataManager::CurrentValueState::CurrentValueState(CurrentValueState &&other) +{ + std::swap(buffer, other.buffer); + std::swap(data, other.data); + std::swap(offset, other.offset); +} + +VertexDataManager::CurrentValueState::~CurrentValueState() {} + +VertexDataManager::VertexDataManager(BufferFactoryD3D *factory) + : mFactory(factory), mStreamingBuffer(factory) +{ + mCurrentValueCache.reserve(gl::MAX_VERTEX_ATTRIBS); + for (int currentValueIndex = 0; currentValueIndex < gl::MAX_VERTEX_ATTRIBS; ++currentValueIndex) + { + mCurrentValueCache.emplace_back(factory); + } +} + +VertexDataManager::~VertexDataManager() {} + +angle::Result VertexDataManager::initialize(const gl::Context *context) +{ + return mStreamingBuffer.initialize(context, INITIAL_STREAM_BUFFER_SIZE); +} + +void VertexDataManager::deinitialize() +{ + mStreamingBuffer.reset(); + mCurrentValueCache.clear(); +} + +angle::Result VertexDataManager::prepareVertexData( + const gl::Context *context, + GLint start, + GLsizei count, + std::vector *translatedAttribs, + GLsizei instances) +{ + const gl::State &state = context->getState(); + const gl::ProgramExecutable *executable = state.getProgramExecutable(); + const gl::VertexArray *vertexArray = state.getVertexArray(); + const auto &vertexAttributes = vertexArray->getVertexAttributes(); + const auto &vertexBindings = vertexArray->getVertexBindings(); + + mDynamicAttribsMaskCache.reset(); + + translatedAttribs->clear(); + + for (size_t attribIndex = 0; attribIndex < vertexAttributes.size(); ++attribIndex) + { + // Skip attrib locations the program doesn't use. + if (!executable->isAttribLocationActive(attribIndex)) + continue; + + const auto &attrib = vertexAttributes[attribIndex]; + const auto &binding = vertexBindings[attrib.bindingIndex]; + + // Resize automatically puts in empty attribs + translatedAttribs->resize(attribIndex + 1); + + TranslatedAttribute *translated = &(*translatedAttribs)[attribIndex]; + auto currentValueData = state.getVertexAttribCurrentValue(attribIndex); + + // Record the attribute now + translated->active = true; + translated->attribute = &attrib; + translated->binding = &binding; + translated->currentValueType = currentValueData.Type; + translated->divisor = binding.getDivisor(); + + switch (ClassifyAttributeStorage(context, attrib, binding)) + { + case VertexStorageType::STATIC: + { + // Store static attribute. + ANGLE_TRY(StoreStaticAttrib(context, translated)); + break; + } + case VertexStorageType::DYNAMIC: + // Dynamic attributes must be handled together. + mDynamicAttribsMaskCache.set(attribIndex); + break; + case VertexStorageType::DIRECT: + // Update translated data for direct attributes. + StoreDirectAttrib(context, translated); + break; + case VertexStorageType::CURRENT_VALUE: + { + ANGLE_TRY(storeCurrentValue(context, currentValueData, translated, attribIndex)); + break; + } + default: + UNREACHABLE(); + break; + } + } + + if (mDynamicAttribsMaskCache.none()) + { + return angle::Result::Continue; + } + + // prepareVertexData is only called by Renderer9 which don't support baseInstance + ANGLE_TRY(storeDynamicAttribs(context, translatedAttribs, mDynamicAttribsMaskCache, start, + count, instances, 0u)); + + PromoteDynamicAttribs(context, *translatedAttribs, mDynamicAttribsMaskCache, count); + + return angle::Result::Continue; +} + +// static +void VertexDataManager::StoreDirectAttrib(const gl::Context *context, + TranslatedAttribute *directAttrib) +{ + ASSERT(directAttrib->attribute && directAttrib->binding); + const auto &attrib = *directAttrib->attribute; + const auto &binding = *directAttrib->binding; + + gl::Buffer *buffer = binding.getBuffer().get(); + ASSERT(buffer); + BufferD3D *bufferD3D = GetImplAs(buffer); + + ASSERT(DirectStoragePossible(context, attrib, binding)); + directAttrib->vertexBuffer.set(nullptr); + directAttrib->storage = bufferD3D; + directAttrib->serial = bufferD3D->getSerial(); + directAttrib->stride = static_cast(ComputeVertexAttributeStride(attrib, binding)); + directAttrib->baseOffset = + static_cast(ComputeVertexAttributeOffset(attrib, binding)); + + // Instanced vertices do not apply the 'start' offset + directAttrib->usesFirstVertexOffset = (binding.getDivisor() == 0); +} + +// static +angle::Result VertexDataManager::StoreStaticAttrib(const gl::Context *context, + TranslatedAttribute *translated) +{ + ASSERT(translated->attribute && translated->binding); + const auto &attrib = *translated->attribute; + const auto &binding = *translated->binding; + + gl::Buffer *buffer = binding.getBuffer().get(); + ASSERT(buffer && attrib.enabled && !DirectStoragePossible(context, attrib, binding)); + BufferD3D *bufferD3D = GetImplAs(buffer); + + // Compute source data pointer + const uint8_t *sourceData = nullptr; + const int offset = static_cast(ComputeVertexAttributeOffset(attrib, binding)); + + ANGLE_TRY(bufferD3D->getData(context, &sourceData)); + + if (sourceData) + { + sourceData += offset; + } + + unsigned int streamOffset = 0; + + translated->storage = nullptr; + ANGLE_TRY(bufferD3D->getFactory()->getVertexSpaceRequired(context, attrib, binding, 1, 0, 0, + &translated->stride)); + + auto *staticBuffer = bufferD3D->getStaticVertexBuffer(attrib, binding); + ASSERT(staticBuffer); + + if (staticBuffer->empty()) + { + // Convert the entire buffer + int totalCount = + ElementsInBuffer(attrib, binding, static_cast(bufferD3D->getSize())); + int startIndex = offset / static_cast(ComputeVertexAttributeStride(attrib, binding)); + + if (totalCount > 0) + { + ANGLE_TRY(staticBuffer->storeStaticAttribute(context, attrib, binding, -startIndex, + totalCount, 0, sourceData)); + } + } + + unsigned int firstElementOffset = + (static_cast(offset) / + static_cast(ComputeVertexAttributeStride(attrib, binding))) * + translated->stride; + + VertexBuffer *vertexBuffer = staticBuffer->getVertexBuffer(); + + CheckedNumeric checkedOffset(streamOffset); + checkedOffset += firstElementOffset; + + ANGLE_CHECK_GL_MATH(GetImplAs(context), checkedOffset.IsValid()); + + translated->vertexBuffer.set(vertexBuffer); + translated->serial = vertexBuffer->getSerial(); + translated->baseOffset = streamOffset + firstElementOffset; + + // Instanced vertices do not apply the 'start' offset + translated->usesFirstVertexOffset = (binding.getDivisor() == 0); + + return angle::Result::Continue; +} + +angle::Result VertexDataManager::storeDynamicAttribs( + const gl::Context *context, + std::vector *translatedAttribs, + const gl::AttributesMask &dynamicAttribsMask, + GLint start, + size_t count, + GLsizei instances, + GLuint baseInstance) +{ + // Instantiating this class will ensure the streaming buffer is never left mapped. + class StreamingBufferUnmapper final : NonCopyable + { + public: + StreamingBufferUnmapper(StreamingVertexBufferInterface *streamingBuffer) + : mStreamingBuffer(streamingBuffer) + { + ASSERT(mStreamingBuffer); + } + ~StreamingBufferUnmapper() { mStreamingBuffer->getVertexBuffer()->hintUnmapResource(); } + + private: + StreamingVertexBufferInterface *mStreamingBuffer; + }; + + // Will trigger unmapping on return. + StreamingBufferUnmapper localUnmapper(&mStreamingBuffer); + + // Reserve the required space for the dynamic buffers. + for (auto attribIndex : dynamicAttribsMask) + { + const auto &dynamicAttrib = (*translatedAttribs)[attribIndex]; + ANGLE_TRY( + reserveSpaceForAttrib(context, dynamicAttrib, start, count, instances, baseInstance)); + } + + // Store dynamic attributes + for (auto attribIndex : dynamicAttribsMask) + { + auto *dynamicAttrib = &(*translatedAttribs)[attribIndex]; + ANGLE_TRY( + storeDynamicAttrib(context, dynamicAttrib, start, count, instances, baseInstance)); + } + + return angle::Result::Continue; +} + +void VertexDataManager::PromoteDynamicAttribs( + const gl::Context *context, + const std::vector &translatedAttribs, + const gl::AttributesMask &dynamicAttribsMask, + size_t count) +{ + for (auto attribIndex : dynamicAttribsMask) + { + const auto &dynamicAttrib = translatedAttribs[attribIndex]; + ASSERT(dynamicAttrib.attribute && dynamicAttrib.binding); + const auto &binding = *dynamicAttrib.binding; + + gl::Buffer *buffer = binding.getBuffer().get(); + if (buffer) + { + // Note: this multiplication can overflow. It should not be a security problem. + BufferD3D *bufferD3D = GetImplAs(buffer); + size_t typeSize = ComputeVertexAttributeTypeSize(*dynamicAttrib.attribute); + bufferD3D->promoteStaticUsage(context, count * typeSize); + } + } +} + +angle::Result VertexDataManager::reserveSpaceForAttrib(const gl::Context *context, + const TranslatedAttribute &translatedAttrib, + GLint start, + size_t count, + GLsizei instances, + GLuint baseInstance) +{ + ASSERT(translatedAttrib.attribute && translatedAttrib.binding); + const auto &attrib = *translatedAttrib.attribute; + const auto &binding = *translatedAttrib.binding; + + ASSERT(!DirectStoragePossible(context, attrib, binding)); + + gl::Buffer *buffer = binding.getBuffer().get(); + BufferD3D *bufferD3D = buffer ? GetImplAs(buffer) : nullptr; + ASSERT(!bufferD3D || bufferD3D->getStaticVertexBuffer(attrib, binding) == nullptr); + + size_t totalCount = gl::ComputeVertexBindingElementCount(binding.getDivisor(), count, + static_cast(instances)); + // TODO(jiajia.qin@intel.com): force the index buffer to clamp any out of range indices instead + // of invalid operation here. + if (bufferD3D) + { + // Vertices do not apply the 'start' offset when the divisor is non-zero even when doing + // a non-instanced draw call + GLint firstVertexIndex = binding.getDivisor() > 0 + ? UnsignedCeilDivide(baseInstance, binding.getDivisor()) + : start; + int64_t maxVertexCount = + static_cast(firstVertexIndex) + static_cast(totalCount); + + int64_t maxByte = GetMaxAttributeByteOffsetForDraw(attrib, binding, maxVertexCount); + + ASSERT(bufferD3D->getSize() <= static_cast(std::numeric_limits::max())); + ANGLE_CHECK(GetImplAs(context), + maxByte <= static_cast(bufferD3D->getSize()), + "Vertex buffer is not big enough for the draw call.", GL_INVALID_OPERATION); + } + return mStreamingBuffer.reserveVertexSpace(context, attrib, binding, totalCount, instances, + baseInstance); +} + +angle::Result VertexDataManager::storeDynamicAttrib(const gl::Context *context, + TranslatedAttribute *translated, + GLint start, + size_t count, + GLsizei instances, + GLuint baseInstance) +{ + ASSERT(translated->attribute && translated->binding); + const auto &attrib = *translated->attribute; + const auto &binding = *translated->binding; + + gl::Buffer *buffer = binding.getBuffer().get(); + ASSERT(buffer || attrib.pointer); + ASSERT(attrib.enabled); + + BufferD3D *storage = buffer ? GetImplAs(buffer) : nullptr; + + // Instanced vertices do not apply the 'start' offset + GLint firstVertexIndex = + (binding.getDivisor() > 0 ? UnsignedCeilDivide(baseInstance, binding.getDivisor()) : start); + + // Compute source data pointer + const uint8_t *sourceData = nullptr; + + if (buffer) + { + ANGLE_TRY(storage->getData(context, &sourceData)); + sourceData += static_cast(ComputeVertexAttributeOffset(attrib, binding)); + } + else + { + // Attributes using client memory ignore the VERTEX_ATTRIB_BINDING state. + // https://www.opengl.org/registry/specs/ARB/vertex_attrib_binding.txt + sourceData = static_cast(attrib.pointer); + } + + unsigned int streamOffset = 0; + + translated->storage = nullptr; + ANGLE_TRY( + mFactory->getVertexSpaceRequired(context, attrib, binding, 1, 0, 0, &translated->stride)); + + size_t totalCount = gl::ComputeVertexBindingElementCount(binding.getDivisor(), count, + static_cast(instances)); + + ANGLE_TRY(mStreamingBuffer.storeDynamicAttribute( + context, attrib, binding, translated->currentValueType, firstVertexIndex, + static_cast(totalCount), instances, baseInstance, &streamOffset, sourceData)); + + VertexBuffer *vertexBuffer = mStreamingBuffer.getVertexBuffer(); + + translated->vertexBuffer.set(vertexBuffer); + translated->serial = vertexBuffer->getSerial(); + translated->baseOffset = streamOffset; + translated->usesFirstVertexOffset = false; + + return angle::Result::Continue; +} + +angle::Result VertexDataManager::storeCurrentValue( + const gl::Context *context, + const gl::VertexAttribCurrentValueData ¤tValue, + TranslatedAttribute *translated, + size_t attribIndex) +{ + CurrentValueState *cachedState = &mCurrentValueCache[attribIndex]; + StreamingVertexBufferInterface &buffer = *cachedState->buffer; + + if (buffer.getBufferSize() == 0) + { + ANGLE_TRY(buffer.initialize(context, CONSTANT_VERTEX_BUFFER_SIZE)); + } + + if (cachedState->data != currentValue) + { + ASSERT(translated->attribute && translated->binding); + const auto &attrib = *translated->attribute; + const auto &binding = *translated->binding; + + ANGLE_TRY(buffer.reserveVertexSpace(context, attrib, binding, 1, 0, 0)); + + const uint8_t *sourceData = + reinterpret_cast(currentValue.Values.FloatValues); + unsigned int streamOffset; + ANGLE_TRY(buffer.storeDynamicAttribute(context, attrib, binding, currentValue.Type, 0, 1, 0, + 0, &streamOffset, sourceData)); + + buffer.getVertexBuffer()->hintUnmapResource(); + + cachedState->data = currentValue; + cachedState->offset = streamOffset; + } + + translated->vertexBuffer.set(buffer.getVertexBuffer()); + + translated->storage = nullptr; + translated->serial = buffer.getSerial(); + translated->divisor = 0; + translated->stride = 0; + translated->baseOffset = static_cast(cachedState->offset); + translated->usesFirstVertexOffset = false; + + return angle::Result::Continue; +} + +// VertexBufferBinding implementation +VertexBufferBinding::VertexBufferBinding() : mBoundVertexBuffer(nullptr) {} + +VertexBufferBinding::VertexBufferBinding(const VertexBufferBinding &other) + : mBoundVertexBuffer(other.mBoundVertexBuffer) +{ + if (mBoundVertexBuffer) + { + mBoundVertexBuffer->addRef(); + } +} + +VertexBufferBinding::~VertexBufferBinding() +{ + if (mBoundVertexBuffer) + { + mBoundVertexBuffer->release(); + } +} + +VertexBufferBinding &VertexBufferBinding::operator=(const VertexBufferBinding &other) +{ + mBoundVertexBuffer = other.mBoundVertexBuffer; + if (mBoundVertexBuffer) + { + mBoundVertexBuffer->addRef(); + } + return *this; +} + +void VertexBufferBinding::set(VertexBuffer *vertexBuffer) +{ + if (mBoundVertexBuffer == vertexBuffer) + return; + + if (mBoundVertexBuffer) + { + mBoundVertexBuffer->release(); + } + if (vertexBuffer) + { + vertexBuffer->addRef(); + } + + mBoundVertexBuffer = vertexBuffer; +} + +VertexBuffer *VertexBufferBinding::get() const +{ + return mBoundVertexBuffer; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexDataManager.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexDataManager.h new file mode 100644 index 0000000000..50400db027 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexDataManager.h @@ -0,0 +1,163 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// VertexDataManager.h: Defines the VertexDataManager, a class that +// runs the Buffer translation process. + +#ifndef LIBANGLE_RENDERER_D3D_VERTEXDATAMANAGER_H_ +#define LIBANGLE_RENDERER_D3D_VERTEXDATAMANAGER_H_ + +#include "common/angleutils.h" +#include "libANGLE/Constants.h" +#include "libANGLE/VertexAttribute.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/renderer/d3d/VertexBuffer.h" + +namespace gl +{ +class State; +struct VertexAttribute; +class VertexBinding; +struct VertexAttribCurrentValueData; +} // namespace gl + +namespace rx +{ +class BufferD3D; +class BufferFactoryD3D; +class StreamingVertexBufferInterface; +class VertexBuffer; + +class VertexBufferBinding final +{ + public: + VertexBufferBinding(); + VertexBufferBinding(const VertexBufferBinding &other); + ~VertexBufferBinding(); + + void set(VertexBuffer *vertexBuffer); + VertexBuffer *get() const; + VertexBufferBinding &operator=(const VertexBufferBinding &other); + + private: + VertexBuffer *mBoundVertexBuffer; +}; + +struct TranslatedAttribute +{ + TranslatedAttribute(); + TranslatedAttribute(const TranslatedAttribute &other); + + // Computes the correct offset from baseOffset, usesFirstVertexOffset, stride and startVertex. + // Can throw an error on integer overflow. + angle::Result computeOffset(const gl::Context *context, + GLint startVertex, + unsigned int *offsetOut) const; + + bool active; + + const gl::VertexAttribute *attribute; + const gl::VertexBinding *binding; + gl::VertexAttribType currentValueType; + unsigned int baseOffset; + bool usesFirstVertexOffset; + unsigned int stride; // 0 means not to advance the read pointer at all + + VertexBufferBinding vertexBuffer; + BufferD3D *storage; + unsigned int serial; + unsigned int divisor; +}; + +enum class VertexStorageType +{ + UNKNOWN, + STATIC, // Translate the vertex data once and re-use it. + DYNAMIC, // Translate the data every frame into a ring buffer. + DIRECT, // Bind a D3D buffer directly without any translation. + CURRENT_VALUE, // Use a single value for the attribute. +}; + +// Given a vertex attribute, return the type of storage it will use. +VertexStorageType ClassifyAttributeStorage(const gl::Context *context, + const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding); + +class VertexDataManager : angle::NonCopyable +{ + public: + VertexDataManager(BufferFactoryD3D *factory); + virtual ~VertexDataManager(); + + angle::Result initialize(const gl::Context *context); + void deinitialize(); + + angle::Result prepareVertexData(const gl::Context *context, + GLint start, + GLsizei count, + std::vector *translatedAttribs, + GLsizei instances); + + static void StoreDirectAttrib(const gl::Context *context, TranslatedAttribute *directAttrib); + + static angle::Result StoreStaticAttrib(const gl::Context *context, + TranslatedAttribute *translated); + + angle::Result storeDynamicAttribs(const gl::Context *context, + std::vector *translatedAttribs, + const gl::AttributesMask &dynamicAttribsMask, + GLint start, + size_t count, + GLsizei instances, + GLuint baseInstance); + + // Promote static usage of dynamic buffers. + static void PromoteDynamicAttribs(const gl::Context *context, + const std::vector &translatedAttribs, + const gl::AttributesMask &dynamicAttribsMask, + size_t count); + + angle::Result storeCurrentValue(const gl::Context *context, + const gl::VertexAttribCurrentValueData ¤tValue, + TranslatedAttribute *translated, + size_t attribIndex); + + private: + struct CurrentValueState final : angle::NonCopyable + { + CurrentValueState(BufferFactoryD3D *factory); + CurrentValueState(CurrentValueState &&other); + ~CurrentValueState(); + + std::unique_ptr buffer; + gl::VertexAttribCurrentValueData data; + size_t offset; + }; + + angle::Result reserveSpaceForAttrib(const gl::Context *context, + const TranslatedAttribute &translatedAttrib, + GLint start, + size_t count, + GLsizei instances, + GLuint baseInstance); + + angle::Result storeDynamicAttrib(const gl::Context *context, + TranslatedAttribute *translated, + GLint start, + size_t count, + GLsizei instances, + GLuint baseInstance); + + BufferFactoryD3D *const mFactory; + + StreamingVertexBufferInterface mStreamingBuffer; + std::vector mCurrentValueCache; + gl::AttributesMask mDynamicAttribsMaskCache; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_VERTEXDATAMANAGER_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp new file mode 100644 index 0000000000..b78ecc5dee --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp @@ -0,0 +1,1943 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Blit11.cpp: Texture copy utility class. + +#include "libANGLE/renderer/d3d/d3d11/Blit11.h" + +#include + +#include "common/utilities.h" +#include "libANGLE/Context.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/d3d11/Context11.h" +#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" +#include "libANGLE/trace.h" + +namespace rx +{ + +namespace +{ + +// Include inline shaders in the anonymous namespace to make sure no symbols are exported +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2d11ps.h" + +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11gs.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11vs.h" + +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepth11_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_vs.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvestencil11_ps.h" + +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2darrayps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2dps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef3dps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2darrayps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei3dps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2darrayps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2dps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui3dps.h" + +void StretchedBlitNearest_RowByRow(const gl::Box &sourceArea, + const gl::Box &destArea, + const gl::Rectangle &clippedDestArea, + const gl::Extents &sourceSize, + unsigned int sourceRowPitch, + unsigned int destRowPitch, + size_t pixelSize, + const uint8_t *sourceData, + uint8_t *destData) +{ + int srcHeightSubOne = (sourceArea.height - 1); + size_t copySize = pixelSize * clippedDestArea.width; + size_t srcOffset = sourceArea.x * pixelSize; + size_t destOffset = clippedDestArea.x * pixelSize; + + for (int y = clippedDestArea.y; y < clippedDestArea.y + clippedDestArea.height; y++) + { + // TODO: Fix divide by zero when height == 1. http://anglebug.com/6099 + float yPerc = static_cast(y - destArea.y) / (destArea.height - 1); + + // Interpolate using the original source rectangle to determine which row to sample from + // while clamping to the edges + unsigned int readRow = static_cast( + gl::clamp(sourceArea.y + floor(yPerc * srcHeightSubOne + 0.5f), 0, srcHeightSubOne)); + unsigned int writeRow = y; + + const uint8_t *sourceRow = sourceData + readRow * sourceRowPitch + srcOffset; + uint8_t *destRow = destData + writeRow * destRowPitch + destOffset; + memcpy(destRow, sourceRow, copySize); + } +} + +void StretchedBlitNearest_PixelByPixel(const gl::Box &sourceArea, + const gl::Box &destArea, + const gl::Rectangle &clippedDestArea, + const gl::Extents &sourceSize, + unsigned int sourceRowPitch, + unsigned int destRowPitch, + ptrdiff_t readOffset, + ptrdiff_t writeOffset, + size_t copySize, + size_t srcPixelStride, + size_t destPixelStride, + const uint8_t *sourceData, + uint8_t *destData) +{ + auto xMax = clippedDestArea.x + clippedDestArea.width; + auto yMax = clippedDestArea.y + clippedDestArea.height; + + for (int writeRow = clippedDestArea.y; writeRow < yMax; writeRow++) + { + // Interpolate using the original source rectangle to determine which row to sample from + // while clamping to the edges + float yPerc = static_cast(writeRow - destArea.y) / (destArea.height - 1); + float yRounded = floor(yPerc * (sourceArea.height - 1) + 0.5f); + unsigned int readRow = + static_cast(gl::clamp(sourceArea.y + yRounded, 0, sourceSize.height - 1)); + + for (int writeColumn = clippedDestArea.x; writeColumn < xMax; writeColumn++) + { + // Interpolate the original source rectangle to determine which column to sample + // from while clamping to the edges + float xPerc = static_cast(writeColumn - destArea.x) / (destArea.width - 1); + float xRounded = floor(xPerc * (sourceArea.width - 1) + 0.5f); + unsigned int readColumn = static_cast( + gl::clamp(sourceArea.x + xRounded, 0, sourceSize.width - 1)); + + const uint8_t *sourcePixel = + sourceData + readRow * sourceRowPitch + readColumn * srcPixelStride + readOffset; + + uint8_t *destPixel = + destData + writeRow * destRowPitch + writeColumn * destPixelStride + writeOffset; + + memcpy(destPixel, sourcePixel, copySize); + } + } +} + +void StretchedBlitNearest(const gl::Box &sourceArea, + const gl::Box &destArea, + const gl::Rectangle &clipRect, + const gl::Extents &sourceSize, + unsigned int sourceRowPitch, + unsigned int destRowPitch, + ptrdiff_t readOffset, + ptrdiff_t writeOffset, + size_t copySize, + size_t srcPixelStride, + size_t destPixelStride, + const uint8_t *sourceData, + uint8_t *destData) +{ + gl::Rectangle clippedDestArea(destArea.x, destArea.y, destArea.width, destArea.height); + if (!gl::ClipRectangle(clippedDestArea, clipRect, &clippedDestArea)) + { + return; + } + + // Determine if entire rows can be copied at once instead of each individual pixel. There + // must be no out of bounds lookups, whole rows copies, and no scale. + if (sourceArea.width == clippedDestArea.width && sourceArea.x >= 0 && + sourceArea.x + sourceArea.width <= sourceSize.width && copySize == srcPixelStride && + copySize == destPixelStride) + { + StretchedBlitNearest_RowByRow(sourceArea, destArea, clippedDestArea, sourceSize, + sourceRowPitch, destRowPitch, srcPixelStride, sourceData, + destData); + } + else + { + StretchedBlitNearest_PixelByPixel(sourceArea, destArea, clippedDestArea, sourceSize, + sourceRowPitch, destRowPitch, readOffset, writeOffset, + copySize, srcPixelStride, destPixelStride, sourceData, + destData); + } +} + +using DepthStencilLoader = void(const float *, uint8_t *); + +void LoadDepth16(const float *source, uint8_t *dest) +{ + uint32_t convertedDepth = gl::floatToNormalized<16, uint32_t>(source[0]); + memcpy(dest, &convertedDepth, 2u); +} + +void LoadDepth24(const float *source, uint8_t *dest) +{ + uint32_t convertedDepth = gl::floatToNormalized<24, uint32_t>(source[0]); + memcpy(dest, &convertedDepth, 3u); +} + +void LoadStencilHelper(const float *source, uint8_t *dest) +{ + uint32_t convertedStencil = gl::getShiftedData<8, 0>(static_cast(source[1])); + memcpy(dest, &convertedStencil, 1u); +} + +void LoadStencil8(const float *source, uint8_t *dest) +{ + // STENCIL_INDEX8 is implemented with D24S8, with the depth bits unused. Writes zero for safety. + float zero = 0.0f; + LoadDepth24(&zero, &dest[0]); + LoadStencilHelper(source, &dest[3]); +} + +void LoadDepth24Stencil8(const float *source, uint8_t *dest) +{ + LoadDepth24(source, &dest[0]); + LoadStencilHelper(source, &dest[3]); +} + +void LoadDepth32F(const float *source, uint8_t *dest) +{ + memcpy(dest, source, sizeof(float)); +} + +void LoadDepth32FStencil8(const float *source, uint8_t *dest) +{ + LoadDepth32F(source, &dest[0]); + LoadStencilHelper(source, &dest[4]); +} + +template +void CopyDepthStencil(const gl::Box &sourceArea, + const gl::Box &destArea, + const gl::Rectangle &clippedDestArea, + const gl::Extents &sourceSize, + unsigned int sourceRowPitch, + unsigned int destRowPitch, + ptrdiff_t readOffset, + ptrdiff_t writeOffset, + size_t copySize, + size_t srcPixelStride, + size_t destPixelStride, + const uint8_t *sourceData, + uint8_t *destData) +{ + // No stretching or subregions are supported, only full blits. + ASSERT(sourceArea == destArea); + ASSERT(sourceSize.width == sourceArea.width && sourceSize.height == sourceArea.height && + sourceSize.depth == 1); + ASSERT(clippedDestArea.width == sourceSize.width && + clippedDestArea.height == sourceSize.height); + ASSERT(readOffset == 0 && writeOffset == 0); + ASSERT(destArea.x == 0 && destArea.y == 0); + + for (int row = 0; row < destArea.height; ++row) + { + for (int column = 0; column < destArea.width; ++column) + { + ptrdiff_t offset = row * sourceRowPitch + column * srcPixelStride; + const float *sourcePixel = reinterpret_cast(sourceData + offset); + + uint8_t *destPixel = destData + row * destRowPitch + column * destPixelStride; + + loader(sourcePixel, destPixel); + } + } +} + +void Depth32FStencil8ToDepth32F(const float *source, float *dest) +{ + *dest = *source; +} + +void Depth24Stencil8ToDepth32F(const uint32_t *source, float *dest) +{ + uint32_t normDepth = source[0] & 0x00FFFFFF; + float floatDepth = gl::normalizedToFloat<24>(normDepth); + *dest = floatDepth; +} + +void BlitD24S8ToD32F(const gl::Box &sourceArea, + const gl::Box &destArea, + const gl::Rectangle &clippedDestArea, + const gl::Extents &sourceSize, + unsigned int sourceRowPitch, + unsigned int destRowPitch, + ptrdiff_t readOffset, + ptrdiff_t writeOffset, + size_t copySize, + size_t srcPixelStride, + size_t destPixelStride, + const uint8_t *sourceData, + uint8_t *destData) +{ + // No stretching or subregions are supported, only full blits. + ASSERT(sourceArea == destArea); + ASSERT(sourceSize.width == sourceArea.width && sourceSize.height == sourceArea.height && + sourceSize.depth == 1); + ASSERT(clippedDestArea.width == sourceSize.width && + clippedDestArea.height == sourceSize.height); + ASSERT(readOffset == 0 && writeOffset == 0); + ASSERT(destArea.x == 0 && destArea.y == 0); + + for (int row = 0; row < destArea.height; ++row) + { + for (int column = 0; column < destArea.width; ++column) + { + ptrdiff_t offset = row * sourceRowPitch + column * srcPixelStride; + const uint32_t *sourcePixel = reinterpret_cast(sourceData + offset); + + float *destPixel = + reinterpret_cast(destData + row * destRowPitch + column * destPixelStride); + + Depth24Stencil8ToDepth32F(sourcePixel, destPixel); + } + } +} + +void BlitD32FS8ToD32F(const gl::Box &sourceArea, + const gl::Box &destArea, + const gl::Rectangle &clippedDestArea, + const gl::Extents &sourceSize, + unsigned int sourceRowPitch, + unsigned int destRowPitch, + ptrdiff_t readOffset, + ptrdiff_t writeOffset, + size_t copySize, + size_t srcPixelStride, + size_t destPixelStride, + const uint8_t *sourceData, + uint8_t *destData) +{ + // No stretching or subregions are supported, only full blits. + ASSERT(sourceArea == destArea); + ASSERT(sourceSize.width == sourceArea.width && sourceSize.height == sourceArea.height && + sourceSize.depth == 1); + ASSERT(clippedDestArea.width == sourceSize.width && + clippedDestArea.height == sourceSize.height); + ASSERT(readOffset == 0 && writeOffset == 0); + ASSERT(destArea.x == 0 && destArea.y == 0); + + for (int row = 0; row < destArea.height; ++row) + { + for (int column = 0; column < destArea.width; ++column) + { + ptrdiff_t offset = row * sourceRowPitch + column * srcPixelStride; + const float *sourcePixel = reinterpret_cast(sourceData + offset); + float *destPixel = + reinterpret_cast(destData + row * destRowPitch + column * destPixelStride); + + Depth32FStencil8ToDepth32F(sourcePixel, destPixel); + } + } +} + +Blit11::BlitConvertFunction *GetCopyDepthStencilFunction(GLenum internalFormat) +{ + switch (internalFormat) + { + case GL_DEPTH_COMPONENT16: + return &CopyDepthStencil; + case GL_DEPTH_COMPONENT24: + return &CopyDepthStencil; + case GL_DEPTH_COMPONENT32F: + return &CopyDepthStencil; + case GL_STENCIL_INDEX8: + return &CopyDepthStencil; + case GL_DEPTH24_STENCIL8: + return &CopyDepthStencil; + case GL_DEPTH32F_STENCIL8: + return &CopyDepthStencil; + default: + UNREACHABLE(); + return nullptr; + } +} + +inline void GenerateVertexCoords(const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const gl::Box &destArea, + const gl::Extents &destSize, + float *x1, + float *y1, + float *x2, + float *y2, + float *u1, + float *v1, + float *u2, + float *v2) +{ + *x1 = (destArea.x / float(destSize.width)) * 2.0f - 1.0f; + *y1 = ((destSize.height - destArea.y - destArea.height) / float(destSize.height)) * 2.0f - 1.0f; + *x2 = ((destArea.x + destArea.width) / float(destSize.width)) * 2.0f - 1.0f; + *y2 = ((destSize.height - destArea.y) / float(destSize.height)) * 2.0f - 1.0f; + + *u1 = sourceArea.x / float(sourceSize.width); + *v1 = sourceArea.y / float(sourceSize.height); + *u2 = (sourceArea.x + sourceArea.width) / float(sourceSize.width); + *v2 = (sourceArea.y + sourceArea.height) / float(sourceSize.height); +} + +void Write2DVertices(const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const gl::Box &destArea, + const gl::Extents &destSize, + void *outVertices, + unsigned int *outStride, + unsigned int *outVertexCount, + D3D11_PRIMITIVE_TOPOLOGY *outTopology) +{ + float x1, y1, x2, y2, u1, v1, u2, v2; + GenerateVertexCoords(sourceArea, sourceSize, destArea, destSize, &x1, &y1, &x2, &y2, &u1, &v1, + &u2, &v2); + + d3d11::PositionTexCoordVertex *vertices = + static_cast(outVertices); + + d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, u1, v2); + d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v1); + d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v2); + d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v1); + + *outStride = sizeof(d3d11::PositionTexCoordVertex); + *outVertexCount = 4; + *outTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; +} + +void Write3DVertices(const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const gl::Box &destArea, + const gl::Extents &destSize, + void *outVertices, + unsigned int *outStride, + unsigned int *outVertexCount, + D3D11_PRIMITIVE_TOPOLOGY *outTopology) +{ + ASSERT(sourceSize.depth > 0 && destSize.depth > 0); + + float x1, y1, x2, y2, u1, v1, u2, v2; + GenerateVertexCoords(sourceArea, sourceSize, destArea, destSize, &x1, &y1, &x2, &y2, &u1, &v1, + &u2, &v2); + + d3d11::PositionLayerTexCoord3DVertex *vertices = + static_cast(outVertices); + + for (int i = 0; i < destSize.depth; i++) + { + float readDepth = (float)i / std::max(destSize.depth - 1, 1); + + d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 0], x1, y1, i, u1, v2, readDepth); + d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 1], x1, y2, i, u1, v1, readDepth); + d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 2], x2, y1, i, u2, v2, readDepth); + + d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 3], x1, y2, i, u1, v1, readDepth); + d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 4], x2, y2, i, u2, v1, readDepth); + d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 5], x2, y1, i, u2, v2, readDepth); + } + + *outStride = sizeof(d3d11::PositionLayerTexCoord3DVertex); + *outVertexCount = destSize.depth * 6; + *outTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; +} + +unsigned int GetSwizzleIndex(GLenum swizzle) +{ + unsigned int colorIndex = 0; + + switch (swizzle) + { + case GL_RED: + colorIndex = 0; + break; + case GL_GREEN: + colorIndex = 1; + break; + case GL_BLUE: + colorIndex = 2; + break; + case GL_ALPHA: + colorIndex = 3; + break; + case GL_ZERO: + colorIndex = 4; + break; + case GL_ONE: + colorIndex = 5; + break; + default: + UNREACHABLE(); + break; + } + + return colorIndex; +} + +D3D11_BLEND_DESC GetAlphaMaskBlendStateDesc() +{ + D3D11_BLEND_DESC desc; + memset(&desc, 0, sizeof(desc)); + desc.RenderTarget[0].BlendEnable = TRUE; + desc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; + desc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO; + desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ZERO; + desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; + desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_RED | + D3D11_COLOR_WRITE_ENABLE_GREEN | + D3D11_COLOR_WRITE_ENABLE_BLUE; + return desc; +} + +D3D11_INPUT_ELEMENT_DESC quad2DLayout[] = { + {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0}, +}; + +D3D11_INPUT_ELEMENT_DESC quad3DLayout[] = { + {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"LAYER", 0, DXGI_FORMAT_R32_UINT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}, +}; + +DXGI_FORMAT GetStencilSRVFormat(const d3d11::Format &formatSet) +{ + switch (formatSet.texFormat) + { + case DXGI_FORMAT_R32G8X24_TYPELESS: + return DXGI_FORMAT_X32_TYPELESS_G8X24_UINT; + case DXGI_FORMAT_R24G8_TYPELESS: + return DXGI_FORMAT_X24_TYPELESS_G8_UINT; + default: + UNREACHABLE(); + return DXGI_FORMAT_UNKNOWN; + } +} + +} // namespace + +#include "libANGLE/renderer/d3d/d3d11/Blit11Helper_autogen.inc" + +Blit11::Shader::Shader() = default; + +Blit11::Shader::Shader(Shader &&other) = default; + +Blit11::Shader::~Shader() = default; + +Blit11::Shader &Blit11::Shader::operator=(Blit11::Shader &&other) = default; + +Blit11::Blit11(Renderer11 *renderer) + : mRenderer(renderer), + mResourcesInitialized(false), + mVertexBuffer(), + mPointSampler(), + mLinearSampler(), + mScissorEnabledRasterizerState(), + mScissorDisabledRasterizerState(), + mDepthStencilState(), + mQuad2DIL(quad2DLayout, + ArraySize(quad2DLayout), + g_VS_Passthrough2D, + ArraySize(g_VS_Passthrough2D), + "Blit11 2D input layout"), + mQuad2DVS(g_VS_Passthrough2D, ArraySize(g_VS_Passthrough2D), "Blit11 2D vertex shader"), + mDepthPS(g_PS_PassthroughDepth2D, + ArraySize(g_PS_PassthroughDepth2D), + "Blit11 2D depth pixel shader"), + mQuad3DIL(quad3DLayout, + ArraySize(quad3DLayout), + g_VS_Passthrough3D, + ArraySize(g_VS_Passthrough3D), + "Blit11 3D input layout"), + mQuad3DVS(g_VS_Passthrough3D, ArraySize(g_VS_Passthrough3D), "Blit11 3D vertex shader"), + mQuad3DGS(g_GS_Passthrough3D, ArraySize(g_GS_Passthrough3D), "Blit11 3D geometry shader"), + mAlphaMaskBlendState(GetAlphaMaskBlendStateDesc(), "Blit11 Alpha Mask Blend"), + mSwizzleCB(), + mResolveDepthStencilVS(g_VS_ResolveDepthStencil, + ArraySize(g_VS_ResolveDepthStencil), + "Blit11::mResolveDepthStencilVS"), + mResolveDepthPS(g_PS_ResolveDepth, ArraySize(g_PS_ResolveDepth), "Blit11::mResolveDepthPS"), + mResolveDepthStencilPS(g_PS_ResolveDepthStencil, + ArraySize(g_PS_ResolveDepthStencil), + "Blit11::mResolveDepthStencilPS"), + mResolveStencilPS(g_PS_ResolveStencil, + ArraySize(g_PS_ResolveStencil), + "Blit11::mResolveStencilPS"), + mStencilSRV(), + mResolvedDepthStencilRTView() +{} + +Blit11::~Blit11() {} + +angle::Result Blit11::initResources(const gl::Context *context) +{ + if (mResourcesInitialized) + { + return angle::Result::Continue; + } + + ANGLE_TRACE_EVENT0("gpu.angle", "Blit11::initResources"); + + D3D11_BUFFER_DESC vbDesc; + vbDesc.ByteWidth = + static_cast(std::max(sizeof(d3d11::PositionLayerTexCoord3DVertex), + sizeof(d3d11::PositionTexCoordVertex)) * + 6 * mRenderer->getNativeCaps().max3DTextureSize); + vbDesc.Usage = D3D11_USAGE_DYNAMIC; + vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + vbDesc.MiscFlags = 0; + vbDesc.StructureByteStride = 0; + + Context11 *context11 = GetImplAs(context); + + ANGLE_TRY(mRenderer->allocateResource(context11, vbDesc, &mVertexBuffer)); + mVertexBuffer.setInternalName("Blit11VertexBuffer"); + + D3D11_SAMPLER_DESC pointSamplerDesc; + pointSamplerDesc.Filter = D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR; + pointSamplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; + pointSamplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; + pointSamplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; + pointSamplerDesc.MipLODBias = 0.0f; + pointSamplerDesc.MaxAnisotropy = 0; + pointSamplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; + pointSamplerDesc.BorderColor[0] = 0.0f; + pointSamplerDesc.BorderColor[1] = 0.0f; + pointSamplerDesc.BorderColor[2] = 0.0f; + pointSamplerDesc.BorderColor[3] = 0.0f; + pointSamplerDesc.MinLOD = 0.0f; + pointSamplerDesc.MaxLOD = FLT_MAX; + + ANGLE_TRY(mRenderer->allocateResource(context11, pointSamplerDesc, &mPointSampler)); + mPointSampler.setInternalName("Blit11PointSampler"); + + D3D11_SAMPLER_DESC linearSamplerDesc; + linearSamplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + linearSamplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; + linearSamplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; + linearSamplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; + linearSamplerDesc.MipLODBias = 0.0f; + linearSamplerDesc.MaxAnisotropy = 0; + linearSamplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; + linearSamplerDesc.BorderColor[0] = 0.0f; + linearSamplerDesc.BorderColor[1] = 0.0f; + linearSamplerDesc.BorderColor[2] = 0.0f; + linearSamplerDesc.BorderColor[3] = 0.0f; + linearSamplerDesc.MinLOD = 0.0f; + linearSamplerDesc.MaxLOD = FLT_MAX; + + ANGLE_TRY(mRenderer->allocateResource(context11, linearSamplerDesc, &mLinearSampler)); + mLinearSampler.setInternalName("Blit11LinearSampler"); + + // Use a rasterizer state that will not cull so that inverted quads will not be culled + D3D11_RASTERIZER_DESC rasterDesc; + rasterDesc.FillMode = D3D11_FILL_SOLID; + rasterDesc.CullMode = D3D11_CULL_NONE; + rasterDesc.FrontCounterClockwise = FALSE; + rasterDesc.DepthBias = 0; + rasterDesc.SlopeScaledDepthBias = 0.0f; + rasterDesc.DepthBiasClamp = 0.0f; + rasterDesc.DepthClipEnable = TRUE; + rasterDesc.MultisampleEnable = FALSE; + rasterDesc.AntialiasedLineEnable = FALSE; + + rasterDesc.ScissorEnable = TRUE; + ANGLE_TRY(mRenderer->allocateResource(context11, rasterDesc, &mScissorEnabledRasterizerState)); + mScissorEnabledRasterizerState.setInternalName("Blit11ScissoringRasterizerState"); + + rasterDesc.ScissorEnable = FALSE; + ANGLE_TRY(mRenderer->allocateResource(context11, rasterDesc, &mScissorDisabledRasterizerState)); + mScissorDisabledRasterizerState.setInternalName("Blit11NoScissoringRasterizerState"); + + D3D11_DEPTH_STENCIL_DESC depthStencilDesc; + depthStencilDesc.DepthEnable = TRUE; + depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; + depthStencilDesc.DepthFunc = D3D11_COMPARISON_ALWAYS; + depthStencilDesc.StencilEnable = FALSE; + depthStencilDesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; + depthStencilDesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; + depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + + ANGLE_TRY(mRenderer->allocateResource(context11, depthStencilDesc, &mDepthStencilState)); + mDepthStencilState.setInternalName("Blit11DepthStencilState"); + + D3D11_BUFFER_DESC swizzleBufferDesc; + swizzleBufferDesc.ByteWidth = sizeof(unsigned int) * 4; + swizzleBufferDesc.Usage = D3D11_USAGE_DYNAMIC; + swizzleBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + swizzleBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + swizzleBufferDesc.MiscFlags = 0; + swizzleBufferDesc.StructureByteStride = 0; + + ANGLE_TRY(mRenderer->allocateResource(context11, swizzleBufferDesc, &mSwizzleCB)); + mSwizzleCB.setInternalName("Blit11SwizzleConstantBuffer"); + + mResourcesInitialized = true; + + return angle::Result::Continue; +} + +// static +Blit11::SwizzleShaderType Blit11::GetSwizzleShaderType(GLenum type, + D3D11_SRV_DIMENSION dimensionality) +{ + switch (dimensionality) + { + case D3D11_SRV_DIMENSION_TEXTURE2D: + switch (type) + { + case GL_FLOAT: + return SWIZZLESHADER_2D_FLOAT; + case GL_UNSIGNED_INT: + return SWIZZLESHADER_2D_UINT; + case GL_INT: + return SWIZZLESHADER_2D_INT; + default: + UNREACHABLE(); + return SWIZZLESHADER_INVALID; + } + case D3D11_SRV_DIMENSION_TEXTURECUBE: + switch (type) + { + case GL_FLOAT: + return SWIZZLESHADER_CUBE_FLOAT; + case GL_UNSIGNED_INT: + return SWIZZLESHADER_CUBE_UINT; + case GL_INT: + return SWIZZLESHADER_CUBE_INT; + default: + UNREACHABLE(); + return SWIZZLESHADER_INVALID; + } + case D3D11_SRV_DIMENSION_TEXTURE3D: + switch (type) + { + case GL_FLOAT: + return SWIZZLESHADER_3D_FLOAT; + case GL_UNSIGNED_INT: + return SWIZZLESHADER_3D_UINT; + case GL_INT: + return SWIZZLESHADER_3D_INT; + default: + UNREACHABLE(); + return SWIZZLESHADER_INVALID; + } + case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: + switch (type) + { + case GL_FLOAT: + return SWIZZLESHADER_ARRAY_FLOAT; + case GL_UNSIGNED_INT: + return SWIZZLESHADER_ARRAY_UINT; + case GL_INT: + return SWIZZLESHADER_ARRAY_INT; + default: + UNREACHABLE(); + return SWIZZLESHADER_INVALID; + } + default: + UNREACHABLE(); + return SWIZZLESHADER_INVALID; + } +} + +angle::Result Blit11::getShaderSupport(const gl::Context *context, + const Shader &shader, + Blit11::ShaderSupport *supportOut) +{ + + Context11 *context11 = GetImplAs(context); + + switch (shader.dimension) + { + case SHADER_2D: + { + ANGLE_TRY(mQuad2DIL.resolve(context11, mRenderer)); + ANGLE_TRY(mQuad2DVS.resolve(context11, mRenderer)); + supportOut->inputLayout = &mQuad2DIL.getObj(); + supportOut->vertexShader = &mQuad2DVS.getObj(); + supportOut->geometryShader = nullptr; + supportOut->vertexWriteFunction = Write2DVertices; + break; + } + case SHADER_3D: + case SHADER_2DARRAY: + { + ANGLE_TRY(mQuad3DIL.resolve(context11, mRenderer)); + ANGLE_TRY(mQuad3DVS.resolve(context11, mRenderer)); + ANGLE_TRY(mQuad3DGS.resolve(context11, mRenderer)); + supportOut->inputLayout = &mQuad3DIL.getObj(); + supportOut->vertexShader = &mQuad3DVS.getObj(); + supportOut->geometryShader = &mQuad3DGS.getObj(); + supportOut->vertexWriteFunction = Write3DVertices; + break; + } + default: + UNREACHABLE(); + } + + return angle::Result::Continue; +} + +angle::Result Blit11::swizzleTexture(const gl::Context *context, + const d3d11::SharedSRV &source, + const d3d11::RenderTargetView &dest, + const gl::Extents &size, + const gl::SwizzleState &swizzleTarget) +{ + ANGLE_TRY(initResources(context)); + + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + D3D11_SHADER_RESOURCE_VIEW_DESC sourceSRVDesc; + source.get()->GetDesc(&sourceSRVDesc); + + GLenum componentType = d3d11::GetComponentType(sourceSRVDesc.Format); + if (componentType == GL_NONE) + { + // We're swizzling the depth component of a depth-stencil texture. + switch (sourceSRVDesc.Format) + { + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + componentType = GL_UNSIGNED_NORMALIZED; + break; + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + componentType = GL_FLOAT; + break; + default: + UNREACHABLE(); + break; + } + } + + GLenum shaderType = GL_NONE; + switch (componentType) + { + case GL_UNSIGNED_NORMALIZED: + case GL_SIGNED_NORMALIZED: + case GL_FLOAT: + shaderType = GL_FLOAT; + break; + case GL_INT: + shaderType = GL_INT; + break; + case GL_UNSIGNED_INT: + shaderType = GL_UNSIGNED_INT; + break; + default: + UNREACHABLE(); + break; + } + + const Shader *shader = nullptr; + ANGLE_TRY(getSwizzleShader(context, shaderType, sourceSRVDesc.ViewDimension, &shader)); + + // Set vertices + D3D11_MAPPED_SUBRESOURCE mappedResource; + ANGLE_TRY(mRenderer->mapResource(context, mVertexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, + &mappedResource)); + + ShaderSupport support; + ANGLE_TRY(getShaderSupport(context, *shader, &support)); + + UINT stride = 0; + UINT drawCount = 0; + D3D11_PRIMITIVE_TOPOLOGY topology; + + gl::Box area(0, 0, 0, size.width, size.height, size.depth); + support.vertexWriteFunction(area, size, area, size, mappedResource.pData, &stride, &drawCount, + &topology); + + deviceContext->Unmap(mVertexBuffer.get(), 0); + + // Set constant buffer + ANGLE_TRY(mRenderer->mapResource(context, mSwizzleCB.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, + &mappedResource)); + + unsigned int *swizzleIndices = static_cast(mappedResource.pData); + swizzleIndices[0] = GetSwizzleIndex(swizzleTarget.swizzleRed); + swizzleIndices[1] = GetSwizzleIndex(swizzleTarget.swizzleGreen); + swizzleIndices[2] = GetSwizzleIndex(swizzleTarget.swizzleBlue); + swizzleIndices[3] = GetSwizzleIndex(swizzleTarget.swizzleAlpha); + + deviceContext->Unmap(mSwizzleCB.get(), 0); + + StateManager11 *stateManager = mRenderer->getStateManager(); + + // Apply vertex buffer + stateManager->setSingleVertexBuffer(&mVertexBuffer, stride, 0); + + // Apply constant buffer + stateManager->setPixelConstantBuffer(0, &mSwizzleCB); + + // Apply state + stateManager->setSimpleBlendState(nullptr); + stateManager->setDepthStencilState(nullptr, 0xFFFFFFFF); + stateManager->setRasterizerState(&mScissorDisabledRasterizerState); + + // Apply shaders + stateManager->setInputLayout(support.inputLayout); + stateManager->setPrimitiveTopology(topology); + + stateManager->setDrawShaders(support.vertexShader, support.geometryShader, + &shader->pixelShader); + + // Apply render target + stateManager->setRenderTarget(dest.get(), nullptr); + + // Set the viewport + stateManager->setSimpleViewport(size); + + // Apply textures and sampler + stateManager->setSimplePixelTextureAndSampler(source, mPointSampler); + + // Draw the quad + deviceContext->Draw(drawCount, 0); + + return angle::Result::Continue; +} + +angle::Result Blit11::copyTexture(const gl::Context *context, + const d3d11::SharedSRV &source, + const gl::Box &sourceArea, + const gl::Extents &sourceSize, + GLenum sourceFormat, + const d3d11::RenderTargetView &dest, + const gl::Box &destArea, + const gl::Extents &destSize, + const gl::Rectangle *scissor, + GLenum destFormat, + GLenum destTypeForDownsampling, + GLenum filter, + bool maskOffAlpha, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) +{ + ANGLE_TRY(initResources(context)); + + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + // Determine if the source format is a signed integer format, the destFormat will already + // be GL_XXXX_INTEGER but it does not tell us if it is signed or unsigned. + D3D11_SHADER_RESOURCE_VIEW_DESC sourceSRVDesc; + source.get()->GetDesc(&sourceSRVDesc); + + GLenum componentType = d3d11::GetComponentType(sourceSRVDesc.Format); + + ASSERT(componentType != GL_NONE); + ASSERT(componentType != GL_SIGNED_NORMALIZED); + bool isSrcSigned = (componentType == GL_INT); + + D3D11_RENDER_TARGET_VIEW_DESC destRTVDesc; + dest.get()->GetDesc(&destRTVDesc); + + GLenum destComponentType = d3d11::GetComponentType(destRTVDesc.Format); + + ASSERT(componentType != GL_NONE); + bool isDestSigned = (destComponentType == GL_INT); + + ShaderDimension dimension = SHADER_INVALID; + + switch (sourceSRVDesc.ViewDimension) + { + case D3D11_SRV_DIMENSION_TEXTURE2D: + dimension = SHADER_2D; + break; + case D3D11_SRV_DIMENSION_TEXTURE3D: + dimension = SHADER_3D; + break; + case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: + dimension = SHADER_2DARRAY; + break; + default: + UNREACHABLE(); + } + + const Shader *shader = nullptr; + + ANGLE_TRY(getBlitShader(context, destFormat, sourceFormat, isSrcSigned, isDestSigned, + unpackPremultiplyAlpha, unpackUnmultiplyAlpha, destTypeForDownsampling, + dimension, &shader)); + + ShaderSupport support; + ANGLE_TRY(getShaderSupport(context, *shader, &support)); + + // Set vertices + D3D11_MAPPED_SUBRESOURCE mappedResource; + ANGLE_TRY(mRenderer->mapResource(context, mVertexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, + &mappedResource)); + + UINT stride = 0; + UINT drawCount = 0; + D3D11_PRIMITIVE_TOPOLOGY topology; + + support.vertexWriteFunction(sourceArea, sourceSize, destArea, destSize, mappedResource.pData, + &stride, &drawCount, &topology); + + deviceContext->Unmap(mVertexBuffer.get(), 0); + + StateManager11 *stateManager = mRenderer->getStateManager(); + + // Apply vertex buffer + stateManager->setSingleVertexBuffer(&mVertexBuffer, stride, 0); + + // Apply state + if (maskOffAlpha) + { + ANGLE_TRY(mAlphaMaskBlendState.resolve(GetImplAs(context), mRenderer)); + stateManager->setSimpleBlendState(&mAlphaMaskBlendState.getObj()); + } + else + { + stateManager->setSimpleBlendState(nullptr); + } + stateManager->setDepthStencilState(nullptr, 0xFFFFFFFF); + + if (scissor) + { + stateManager->setSimpleScissorRect(*scissor); + stateManager->setRasterizerState(&mScissorEnabledRasterizerState); + } + else + { + stateManager->setRasterizerState(&mScissorDisabledRasterizerState); + } + + // Apply shaders + stateManager->setInputLayout(support.inputLayout); + stateManager->setPrimitiveTopology(topology); + + stateManager->setDrawShaders(support.vertexShader, support.geometryShader, + &shader->pixelShader); + + // Apply render target + stateManager->setRenderTarget(dest.get(), nullptr); + + // Set the viewport + stateManager->setSimpleViewport(destSize); + + // Apply texture and sampler + switch (filter) + { + case GL_NEAREST: + stateManager->setSimplePixelTextureAndSampler(source, mPointSampler); + break; + case GL_LINEAR: + stateManager->setSimplePixelTextureAndSampler(source, mLinearSampler); + break; + + default: + UNREACHABLE(); + ANGLE_TRY_HR(GetImplAs(context), E_FAIL, + "Internal error, unknown blit filter mode."); + } + + // Draw the quad + deviceContext->Draw(drawCount, 0); + + return angle::Result::Continue; +} + +angle::Result Blit11::copyStencil(const gl::Context *context, + const TextureHelper11 &source, + unsigned int sourceSubresource, + const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const TextureHelper11 &dest, + unsigned int destSubresource, + const gl::Box &destArea, + const gl::Extents &destSize, + const gl::Rectangle *scissor) +{ + return copyDepthStencilImpl(context, source, sourceSubresource, sourceArea, sourceSize, dest, + destSubresource, destArea, destSize, scissor, true); +} + +angle::Result Blit11::copyDepth(const gl::Context *context, + const d3d11::SharedSRV &source, + const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const d3d11::DepthStencilView &dest, + const gl::Box &destArea, + const gl::Extents &destSize, + const gl::Rectangle *scissor) +{ + ANGLE_TRY(initResources(context)); + + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + // Set vertices + D3D11_MAPPED_SUBRESOURCE mappedResource; + ANGLE_TRY(mRenderer->mapResource(context, mVertexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, + &mappedResource)); + + UINT stride = 0; + UINT drawCount = 0; + D3D11_PRIMITIVE_TOPOLOGY topology; + + Write2DVertices(sourceArea, sourceSize, destArea, destSize, mappedResource.pData, &stride, + &drawCount, &topology); + + deviceContext->Unmap(mVertexBuffer.get(), 0); + + StateManager11 *stateManager = mRenderer->getStateManager(); + + // Apply vertex buffer + stateManager->setSingleVertexBuffer(&mVertexBuffer, stride, 0); + + // Apply state + stateManager->setSimpleBlendState(nullptr); + stateManager->setDepthStencilState(&mDepthStencilState, 0xFFFFFFFF); + + if (scissor) + { + stateManager->setSimpleScissorRect(*scissor); + stateManager->setRasterizerState(&mScissorEnabledRasterizerState); + } + else + { + stateManager->setRasterizerState(&mScissorDisabledRasterizerState); + } + + Context11 *context11 = GetImplAs(context); + + ANGLE_TRY(mQuad2DIL.resolve(context11, mRenderer)); + ANGLE_TRY(mQuad2DVS.resolve(context11, mRenderer)); + ANGLE_TRY(mDepthPS.resolve(context11, mRenderer)); + + // Apply shaders + stateManager->setInputLayout(&mQuad2DIL.getObj()); + stateManager->setPrimitiveTopology(topology); + + stateManager->setDrawShaders(&mQuad2DVS.getObj(), nullptr, &mDepthPS.getObj()); + + // Apply render target + stateManager->setRenderTarget(nullptr, dest.get()); + + // Set the viewport + stateManager->setSimpleViewport(destSize); + + // Apply texture and sampler + stateManager->setSimplePixelTextureAndSampler(source, mPointSampler); + + // Draw the quad + deviceContext->Draw(drawCount, 0); + + return angle::Result::Continue; +} + +angle::Result Blit11::copyDepthStencil(const gl::Context *context, + const TextureHelper11 &source, + unsigned int sourceSubresource, + const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const TextureHelper11 &dest, + unsigned int destSubresource, + const gl::Box &destArea, + const gl::Extents &destSize, + const gl::Rectangle *scissor) +{ + return copyDepthStencilImpl(context, source, sourceSubresource, sourceArea, sourceSize, dest, + destSubresource, destArea, destSize, scissor, false); +} + +angle::Result Blit11::copyDepthStencilImpl(const gl::Context *context, + const TextureHelper11 &source, + unsigned int sourceSubresource, + const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const TextureHelper11 &dest, + unsigned int destSubresource, + const gl::Box &destArea, + const gl::Extents &destSize, + const gl::Rectangle *scissor, + bool stencilOnly) +{ + auto srcDXGIFormat = source.getFormat(); + const auto &srcSizeInfo = d3d11::GetDXGIFormatSizeInfo(srcDXGIFormat); + unsigned int srcPixelSize = srcSizeInfo.pixelBytes; + unsigned int copyOffset = 0; + unsigned int copySize = srcPixelSize; + auto destDXGIFormat = dest.getFormat(); + const auto &destSizeInfo = d3d11::GetDXGIFormatSizeInfo(destDXGIFormat); + unsigned int destPixelSize = destSizeInfo.pixelBytes; + + ASSERT(srcDXGIFormat == destDXGIFormat || destDXGIFormat == DXGI_FORMAT_R32_TYPELESS); + + if (stencilOnly) + { + const auto &srcFormat = source.getFormatSet().format(); + + // Stencil channel should be right after the depth channel. Some views to depth/stencil + // resources have red channel for depth, in which case the depth channel bit width is in + // redBits. + ASSERT((srcFormat.redBits != 0) != (srcFormat.depthBits != 0)); + GLuint depthBits = srcFormat.redBits + srcFormat.depthBits; + // Known formats have either 24 or 32 bits of depth. + ASSERT(depthBits == 24 || depthBits == 32); + copyOffset = depthBits / 8; + + // Stencil is assumed to be 8-bit - currently this is true for all possible formats. + copySize = 1; + } + + if (srcDXGIFormat != destDXGIFormat) + { + if (srcDXGIFormat == DXGI_FORMAT_R24G8_TYPELESS) + { + ASSERT(sourceArea == destArea && sourceSize == destSize && scissor == nullptr); + return copyAndConvert(context, source, sourceSubresource, sourceArea, sourceSize, dest, + destSubresource, destArea, destSize, scissor, copyOffset, + copyOffset, copySize, srcPixelSize, destPixelSize, + BlitD24S8ToD32F); + } + ASSERT(srcDXGIFormat == DXGI_FORMAT_R32G8X24_TYPELESS); + return copyAndConvert(context, source, sourceSubresource, sourceArea, sourceSize, dest, + destSubresource, destArea, destSize, scissor, copyOffset, copyOffset, + copySize, srcPixelSize, destPixelSize, BlitD32FS8ToD32F); + } + + return copyAndConvert(context, source, sourceSubresource, sourceArea, sourceSize, dest, + destSubresource, destArea, destSize, scissor, copyOffset, copyOffset, + copySize, srcPixelSize, destPixelSize, StretchedBlitNearest); +} + +angle::Result Blit11::copyAndConvertImpl(const gl::Context *context, + const TextureHelper11 &source, + unsigned int sourceSubresource, + const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const TextureHelper11 &destStaging, + const gl::Box &destArea, + const gl::Extents &destSize, + const gl::Rectangle *scissor, + size_t readOffset, + size_t writeOffset, + size_t copySize, + size_t srcPixelStride, + size_t destPixelStride, + BlitConvertFunction *convertFunction) +{ + ANGLE_TRY(initResources(context)); + + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + TextureHelper11 sourceStaging; + ANGLE_TRY(mRenderer->createStagingTexture(context, ResourceType::Texture2D, + source.getFormatSet(), sourceSize, + StagingAccess::READ, &sourceStaging)); + + deviceContext->CopySubresourceRegion(sourceStaging.get(), 0, 0, 0, 0, source.get(), + sourceSubresource, nullptr); + + D3D11_MAPPED_SUBRESOURCE sourceMapping; + ANGLE_TRY( + mRenderer->mapResource(context, sourceStaging.get(), 0, D3D11_MAP_READ, 0, &sourceMapping)); + + D3D11_MAPPED_SUBRESOURCE destMapping; + angle::Result error = + mRenderer->mapResource(context, destStaging.get(), 0, D3D11_MAP_WRITE, 0, &destMapping); + if (error == angle::Result::Stop) + { + deviceContext->Unmap(sourceStaging.get(), 0); + return error; + } + + // Clip dest area to the destination size + gl::Rectangle clipRect = gl::Rectangle(0, 0, destSize.width, destSize.height); + + // Clip dest area to the scissor + if (scissor) + { + if (!gl::ClipRectangle(clipRect, *scissor, &clipRect)) + { + return angle::Result::Continue; + } + } + + convertFunction(sourceArea, destArea, clipRect, sourceSize, sourceMapping.RowPitch, + destMapping.RowPitch, readOffset, writeOffset, copySize, srcPixelStride, + destPixelStride, static_cast(sourceMapping.pData), + static_cast(destMapping.pData)); + + deviceContext->Unmap(sourceStaging.get(), 0); + deviceContext->Unmap(destStaging.get(), 0); + + return angle::Result::Continue; +} + +angle::Result Blit11::copyAndConvert(const gl::Context *context, + const TextureHelper11 &source, + unsigned int sourceSubresource, + const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const TextureHelper11 &dest, + unsigned int destSubresource, + const gl::Box &destArea, + const gl::Extents &destSize, + const gl::Rectangle *scissor, + size_t readOffset, + size_t writeOffset, + size_t copySize, + size_t srcPixelStride, + size_t destPixelStride, + BlitConvertFunction *convertFunction) +{ + ANGLE_TRY(initResources(context)); + + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + // HACK: Create the destination staging buffer as a read/write texture so + // ID3D11DevicContext::UpdateSubresource can be called + // using it's mapped data as a source + TextureHelper11 destStaging; + ANGLE_TRY(mRenderer->createStagingTexture(context, ResourceType::Texture2D, dest.getFormatSet(), + destSize, StagingAccess::READ_WRITE, &destStaging)); + + deviceContext->CopySubresourceRegion(destStaging.get(), 0, 0, 0, 0, dest.get(), destSubresource, + nullptr); + + ANGLE_TRY(copyAndConvertImpl(context, source, sourceSubresource, sourceArea, sourceSize, + destStaging, destArea, destSize, scissor, readOffset, writeOffset, + copySize, srcPixelStride, destPixelStride, convertFunction)); + + // Work around timeouts/TDRs in older NVIDIA drivers. + if (mRenderer->getFeatures().depthStencilBlitExtraCopy.enabled) + { + D3D11_MAPPED_SUBRESOURCE mapped; + ANGLE_TRY( + mRenderer->mapResource(context, destStaging.get(), 0, D3D11_MAP_READ, 0, &mapped)); + deviceContext->UpdateSubresource(dest.get(), destSubresource, nullptr, mapped.pData, + mapped.RowPitch, mapped.DepthPitch); + deviceContext->Unmap(destStaging.get(), 0); + } + else + { + deviceContext->CopySubresourceRegion(dest.get(), destSubresource, 0, 0, 0, + destStaging.get(), 0, nullptr); + } + + return angle::Result::Continue; +} + +angle::Result Blit11::addBlitShaderToMap(const gl::Context *context, + BlitShaderType blitShaderType, + ShaderDimension dimension, + const ShaderData &shaderData, + const char *name) +{ + ASSERT(mBlitShaderMap.find(blitShaderType) == mBlitShaderMap.end()); + + d3d11::PixelShader ps; + ANGLE_TRY(mRenderer->allocateResource(GetImplAs(context), shaderData, &ps)); + ps.setInternalName(name); + + Shader shader; + shader.dimension = dimension; + shader.pixelShader = std::move(ps); + + mBlitShaderMap[blitShaderType] = std::move(shader); + return angle::Result::Continue; +} + +angle::Result Blit11::addSwizzleShaderToMap(const gl::Context *context, + SwizzleShaderType swizzleShaderType, + ShaderDimension dimension, + const ShaderData &shaderData, + const char *name) +{ + ASSERT(mSwizzleShaderMap.find(swizzleShaderType) == mSwizzleShaderMap.end()); + + d3d11::PixelShader ps; + ANGLE_TRY(mRenderer->allocateResource(GetImplAs(context), shaderData, &ps)); + ps.setInternalName(name); + + Shader shader; + shader.dimension = dimension; + shader.pixelShader = std::move(ps); + + mSwizzleShaderMap[swizzleShaderType] = std::move(shader); + return angle::Result::Continue; +} + +void Blit11::clearShaderMap() +{ + mBlitShaderMap.clear(); + mSwizzleShaderMap.clear(); +} + +Blit11::BlitShaderOperation Blit11::getBlitShaderOperation(GLenum destinationFormat, + GLenum sourceFormat, + bool isSrcSigned, + bool isDestSigned, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + GLenum destTypeForDownsampling) +{ + bool floatToIntBlit = + !gl::IsIntegerFormat(sourceFormat) && gl::IsIntegerFormat(destinationFormat); + + if (isSrcSigned) + { + ASSERT(!unpackPremultiplyAlpha && !unpackUnmultiplyAlpha); + switch (destinationFormat) + { + case GL_RGBA_INTEGER: + return RGBAI; + case GL_RGB_INTEGER: + return RGBI; + case GL_RG_INTEGER: + return RGI; + case GL_RED_INTEGER: + return RI; + default: + UNREACHABLE(); + return OPERATION_INVALID; + } + } + else if (isDestSigned) + { + ASSERT(floatToIntBlit); + + switch (destinationFormat) + { + case GL_RGBA_INTEGER: + if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha) + { + return RGBAF_TOI; + } + return unpackPremultiplyAlpha ? RGBAF_TOI_PREMULTIPLY : RGBAF_TOI_UNMULTIPLY; + case GL_RGB_INTEGER: + case GL_RG_INTEGER: + case GL_RED_INTEGER: + if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha) + { + return RGBF_TOI; + } + return unpackPremultiplyAlpha ? RGBF_TOI_PREMULTIPLY : RGBF_TOI_UNMULTIPLY; + default: + UNREACHABLE(); + return OPERATION_INVALID; + } + } + else + { + // Check for the downsample formats first + switch (destTypeForDownsampling) + { + case GL_UNSIGNED_SHORT_4_4_4_4: + ASSERT(destinationFormat == GL_RGBA && !floatToIntBlit); + if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha) + { + return RGBAF_4444; + } + else if (unpackPremultiplyAlpha) + { + return RGBAF_4444_PREMULTIPLY; + } + else + { + return RGBAF_4444_UNMULTIPLY; + } + + case GL_UNSIGNED_SHORT_5_6_5: + ASSERT(destinationFormat == GL_RGB && !floatToIntBlit); + if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha) + { + return RGBF_565; + } + else + { + return unpackPremultiplyAlpha ? RGBF_565_PREMULTIPLY : RGBF_565_UNMULTIPLY; + } + case GL_UNSIGNED_SHORT_5_5_5_1: + if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha) + { + return RGBAF_5551; + } + else + { + return unpackPremultiplyAlpha ? RGBAF_5551_PREMULTIPLY : RGBAF_5551_UNMULTIPLY; + } + + default: + // By default, use the regular passthrough/multiply/unmultiply shaders. The above + // shaders are only needed for some emulated texture formats. + break; + } + + if (unpackPremultiplyAlpha != unpackUnmultiplyAlpha || floatToIntBlit) + { + switch (destinationFormat) + { + case GL_RGBA: + case GL_BGRA_EXT: + ASSERT(!floatToIntBlit); + return unpackPremultiplyAlpha ? RGBAF_PREMULTIPLY : RGBAF_UNMULTIPLY; + case GL_RGB: + case GL_RG: + case GL_RED: + if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha) + { + return RGBF_TOUI; + } + else + { + return unpackPremultiplyAlpha ? RGBF_PREMULTIPLY : RGBF_UNMULTIPLY; + } + case GL_RGBA_INTEGER: + if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha) + { + return RGBAF_TOUI; + } + else + { + return unpackPremultiplyAlpha ? RGBAF_TOUI_PREMULTIPLY + : RGBAF_TOUI_UNMULTIPLY; + } + case GL_RGB_INTEGER: + case GL_RG_INTEGER: + case GL_RED_INTEGER: + if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha) + { + return RGBF_TOUI; + } + else + { + return unpackPremultiplyAlpha ? RGBF_TOUI_PREMULTIPLY + : RGBF_TOUI_UNMULTIPLY; + } + case GL_LUMINANCE: + ASSERT(!floatToIntBlit); + return unpackPremultiplyAlpha ? LUMAF_PREMULTIPLY : LUMAF_UNMULTIPLY; + + case GL_LUMINANCE_ALPHA: + ASSERT(!floatToIntBlit); + return unpackPremultiplyAlpha ? LUMAALPHAF_PREMULTIPLY : LUMAALPHAF_UNMULTIPLY; + case GL_ALPHA: + return ALPHA; + default: + UNREACHABLE(); + return OPERATION_INVALID; + } + } + else + { + switch (destinationFormat) + { + case GL_RGBA: + return RGBAF; + case GL_RGBA_INTEGER: + return RGBAUI; + case GL_BGRA_EXT: + return BGRAF; + case GL_RGB: + return RGBF; + case GL_RGB_INTEGER: + return RGBUI; + case GL_RG: + return RGF; + case GL_RG_INTEGER: + return RGUI; + case GL_RED: + return RF; + case GL_RED_INTEGER: + return RUI; + case GL_ALPHA: + return ALPHA; + case GL_LUMINANCE: + return LUMA; + case GL_LUMINANCE_ALPHA: + return LUMAALPHA; + default: + UNREACHABLE(); + return OPERATION_INVALID; + } + } + } +} + +angle::Result Blit11::getBlitShader(const gl::Context *context, + GLenum destFormat, + GLenum sourceFormat, + bool isSrcSigned, + bool isDestSigned, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + GLenum destTypeForDownsampling, + ShaderDimension dimension, + const Shader **shader) +{ + BlitShaderOperation blitShaderOperation = OPERATION_INVALID; + + blitShaderOperation = getBlitShaderOperation(destFormat, sourceFormat, isSrcSigned, + isDestSigned, unpackPremultiplyAlpha, + unpackUnmultiplyAlpha, destTypeForDownsampling); + + BlitShaderType blitShaderType = BLITSHADER_INVALID; + + blitShaderType = getBlitShaderType(blitShaderOperation, dimension); + + ANGLE_CHECK_HR(GetImplAs(context), blitShaderType != BLITSHADER_INVALID, + "Internal blit shader type mismatch", E_FAIL); + + auto blitShaderIt = mBlitShaderMap.find(blitShaderType); + if (blitShaderIt != mBlitShaderMap.end()) + { + *shader = &blitShaderIt->second; + return angle::Result::Continue; + } + + ASSERT(dimension == SHADER_2D || mRenderer->isES3Capable()); + + ANGLE_TRY(mapBlitShader(context, blitShaderType)); + + blitShaderIt = mBlitShaderMap.find(blitShaderType); + ASSERT(blitShaderIt != mBlitShaderMap.end()); + *shader = &blitShaderIt->second; + return angle::Result::Continue; +} + +angle::Result Blit11::getSwizzleShader(const gl::Context *context, + GLenum type, + D3D11_SRV_DIMENSION viewDimension, + const Shader **shader) +{ + SwizzleShaderType swizzleShaderType = GetSwizzleShaderType(type, viewDimension); + + ANGLE_CHECK_HR(GetImplAs(context), swizzleShaderType != SWIZZLESHADER_INVALID, + "Swizzle shader type not found", E_FAIL); + + auto swizzleShaderIt = mSwizzleShaderMap.find(swizzleShaderType); + if (swizzleShaderIt != mSwizzleShaderMap.end()) + { + *shader = &swizzleShaderIt->second; + return angle::Result::Continue; + } + + // Swizzling shaders (OpenGL ES 3+) + ASSERT(mRenderer->isES3Capable()); + + switch (swizzleShaderType) + { + case SWIZZLESHADER_2D_FLOAT: + ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_2D, + ShaderData(g_PS_SwizzleF2D), + "Blit11 2D F swizzle pixel shader")); + break; + case SWIZZLESHADER_2D_UINT: + ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_2D, + ShaderData(g_PS_SwizzleUI2D), + "Blit11 2D UI swizzle pixel shader")); + break; + case SWIZZLESHADER_2D_INT: + ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_2D, + ShaderData(g_PS_SwizzleI2D), + "Blit11 2D I swizzle pixel shader")); + break; + case SWIZZLESHADER_CUBE_FLOAT: + ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D, + ShaderData(g_PS_SwizzleF2DArray), + "Blit11 2D Cube F swizzle pixel shader")); + break; + case SWIZZLESHADER_CUBE_UINT: + ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D, + ShaderData(g_PS_SwizzleUI2DArray), + "Blit11 2D Cube UI swizzle pixel shader")); + break; + case SWIZZLESHADER_CUBE_INT: + ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D, + ShaderData(g_PS_SwizzleI2DArray), + "Blit11 2D Cube I swizzle pixel shader")); + break; + case SWIZZLESHADER_3D_FLOAT: + ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D, + ShaderData(g_PS_SwizzleF3D), + "Blit11 3D F swizzle pixel shader")); + break; + case SWIZZLESHADER_3D_UINT: + ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D, + ShaderData(g_PS_SwizzleUI3D), + "Blit11 3D UI swizzle pixel shader")); + break; + case SWIZZLESHADER_3D_INT: + ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D, + ShaderData(g_PS_SwizzleI3D), + "Blit11 3D I swizzle pixel shader")); + break; + case SWIZZLESHADER_ARRAY_FLOAT: + ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D, + ShaderData(g_PS_SwizzleF2DArray), + "Blit11 2D Array F swizzle pixel shader")); + break; + case SWIZZLESHADER_ARRAY_UINT: + ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D, + ShaderData(g_PS_SwizzleUI2DArray), + "Blit11 2D Array UI swizzle pixel shader")); + break; + case SWIZZLESHADER_ARRAY_INT: + ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D, + ShaderData(g_PS_SwizzleI2DArray), + "Blit11 2D Array I swizzle pixel shader")); + break; + default: + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + } + + swizzleShaderIt = mSwizzleShaderMap.find(swizzleShaderType); + ASSERT(swizzleShaderIt != mSwizzleShaderMap.end()); + *shader = &swizzleShaderIt->second; + return angle::Result::Continue; +} + +angle::Result Blit11::resolveDepth(const gl::Context *context, + RenderTarget11 *depth, + TextureHelper11 *textureOut) +{ + ANGLE_TRY(initResources(context)); + + // Multisampled depth stencil SRVs are not available in feature level 10.0 + ASSERT(mRenderer->getRenderer11DeviceCaps().featureLevel > D3D_FEATURE_LEVEL_10_0); + + const auto &extents = depth->getExtents(); + auto *deviceContext = mRenderer->getDeviceContext(); + auto *stateManager = mRenderer->getStateManager(); + + ANGLE_TRY(initResolveDepthOnly(context, depth->getFormatSet(), extents)); + + Context11 *context11 = GetImplAs(context); + + ANGLE_TRY(mResolveDepthStencilVS.resolve(context11, mRenderer)); + ANGLE_TRY(mResolveDepthPS.resolve(context11, mRenderer)); + + // Apply the necessary state changes to the D3D11 immediate device context. + stateManager->setInputLayout(nullptr); + stateManager->setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + stateManager->setDrawShaders(&mResolveDepthStencilVS.getObj(), nullptr, + &mResolveDepthPS.getObj()); + stateManager->setRasterizerState(nullptr); + stateManager->setDepthStencilState(&mDepthStencilState, 0xFFFFFFFF); + stateManager->setRenderTargets(nullptr, 0, mResolvedDepthDSView.get()); + stateManager->setSimpleBlendState(nullptr); + stateManager->setSimpleViewport(extents); + + // Set the viewport + const d3d11::SharedSRV *srv; + ANGLE_TRY(depth->getShaderResourceView(context, &srv)); + + stateManager->setShaderResourceShared(gl::ShaderType::Fragment, 0, srv); + + // Trigger the blit on the GPU. + deviceContext->Draw(6, 0); + + *textureOut = mResolvedDepth; + return angle::Result::Continue; +} + +angle::Result Blit11::initResolveDepthOnly(const gl::Context *context, + const d3d11::Format &format, + const gl::Extents &extents) +{ + if (mResolvedDepth.valid() && extents == mResolvedDepth.getExtents() && + format.texFormat == mResolvedDepth.getFormat()) + { + return angle::Result::Continue; + } + + D3D11_TEXTURE2D_DESC textureDesc; + textureDesc.Width = extents.width; + textureDesc.Height = extents.height; + textureDesc.MipLevels = 1; + textureDesc.ArraySize = 1; + textureDesc.Format = format.texFormat; + textureDesc.SampleDesc.Count = 1; + textureDesc.SampleDesc.Quality = 0; + textureDesc.Usage = D3D11_USAGE_DEFAULT; + textureDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE; + textureDesc.CPUAccessFlags = 0; + textureDesc.MiscFlags = 0; + + Context11 *context11 = GetImplAs(context); + + ANGLE_TRY(mRenderer->allocateTexture(context11, textureDesc, format, &mResolvedDepth)); + mResolvedDepth.setInternalName("Blit11::mResolvedDepth"); + + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsvDesc.Flags = 0; + dsvDesc.Format = format.dsvFormat; + dsvDesc.Texture2D.MipSlice = 0; + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + + ANGLE_TRY(mRenderer->allocateResource(context11, dsvDesc, mResolvedDepth.get(), + &mResolvedDepthDSView)); + mResolvedDepthDSView.setInternalName("Blit11::mResolvedDepthDSView"); + + // Possibly D3D11 bug or undefined behaviour: Clear the DSV so that our first render + // works as expected. Otherwise the results of the first use seem to be incorrect. + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + deviceContext->ClearDepthStencilView(mResolvedDepthDSView.get(), D3D11_CLEAR_DEPTH, 1.0f, 0); + + return angle::Result::Continue; +} + +angle::Result Blit11::initResolveDepthStencil(const gl::Context *context, + const gl::Extents &extents) +{ + // Check if we need to recreate depth stencil view + if (mResolvedDepthStencil.valid() && extents == mResolvedDepthStencil.getExtents()) + { + ASSERT(mResolvedDepthStencil.getFormat() == DXGI_FORMAT_R32G32_FLOAT); + return angle::Result::Continue; + } + + if (mResolvedDepthStencil.valid()) + { + releaseResolveDepthStencilResources(); + } + + const auto &formatSet = d3d11::Format::Get(GL_RG32F, mRenderer->getRenderer11DeviceCaps()); + + D3D11_TEXTURE2D_DESC textureDesc; + textureDesc.Width = extents.width; + textureDesc.Height = extents.height; + textureDesc.MipLevels = 1; + textureDesc.ArraySize = 1; + textureDesc.Format = formatSet.texFormat; + textureDesc.SampleDesc.Count = 1; + textureDesc.SampleDesc.Quality = 0; + textureDesc.Usage = D3D11_USAGE_DEFAULT; + textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET; + textureDesc.CPUAccessFlags = 0; + textureDesc.MiscFlags = 0; + + Context11 *context11 = GetImplAs(context); + + ANGLE_TRY( + mRenderer->allocateTexture(context11, textureDesc, formatSet, &mResolvedDepthStencil)); + mResolvedDepthStencil.setInternalName("Blit11::mResolvedDepthStencil"); + + ANGLE_TRY(mRenderer->allocateResourceNoDesc(context11, mResolvedDepthStencil.get(), + &mResolvedDepthStencilRTView)); + mResolvedDepthStencilRTView.setInternalName("Blit11::mResolvedDepthStencilRTView"); + + return angle::Result::Continue; +} + +angle::Result Blit11::resolveStencil(const gl::Context *context, + RenderTarget11 *depthStencil, + bool alsoDepth, + TextureHelper11 *textureOut) +{ + ANGLE_TRY(initResources(context)); + + // Multisampled depth stencil SRVs are not available in feature level 10.0 + ASSERT(mRenderer->getRenderer11DeviceCaps().featureLevel > D3D_FEATURE_LEVEL_10_0); + + const auto &extents = depthStencil->getExtents(); + + ANGLE_TRY(initResolveDepthStencil(context, extents)); + + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + auto *stateManager = mRenderer->getStateManager(); + ID3D11Resource *stencilResource = depthStencil->getTexture().get(); + + // Check if we need to re-create the stencil SRV. + if (mStencilSRV.valid()) + { + ID3D11Resource *priorResource = nullptr; + mStencilSRV.get()->GetResource(&priorResource); + + if (stencilResource != priorResource) + { + mStencilSRV.reset(); + } + + SafeRelease(priorResource); + } + + Context11 *context11 = GetImplAs(context); + + if (!mStencilSRV.valid()) + { + D3D11_SHADER_RESOURCE_VIEW_DESC srViewDesc; + srViewDesc.Format = GetStencilSRVFormat(depthStencil->getFormatSet()); + srViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; + + ANGLE_TRY( + mRenderer->allocateResource(context11, srViewDesc, stencilResource, &mStencilSRV)); + mStencilSRV.setInternalName("Blit11::mStencilSRV"); + } + + // Notify the Renderer that all state should be invalidated. + ANGLE_TRY(mResolveDepthStencilVS.resolve(context11, mRenderer)); + + // Resolving the depth buffer works by sampling the depth in the shader using a SRV, then + // writing to the resolved depth buffer using SV_Depth. We can't use this method for stencil + // because SV_StencilRef isn't supported until HLSL 5.1/D3D11.3. + const d3d11::PixelShader *pixelShader = nullptr; + if (alsoDepth) + { + ANGLE_TRY(mResolveDepthStencilPS.resolve(context11, mRenderer)); + pixelShader = &mResolveDepthStencilPS.getObj(); + } + else + { + ANGLE_TRY(mResolveStencilPS.resolve(context11, mRenderer)); + pixelShader = &mResolveStencilPS.getObj(); + } + + // Apply the necessary state changes to the D3D11 immediate device context. + stateManager->setInputLayout(nullptr); + stateManager->setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + stateManager->setDrawShaders(&mResolveDepthStencilVS.getObj(), nullptr, pixelShader); + stateManager->setRasterizerState(nullptr); + stateManager->setDepthStencilState(nullptr, 0xFFFFFFFF); + stateManager->setRenderTarget(mResolvedDepthStencilRTView.get(), nullptr); + stateManager->setSimpleBlendState(nullptr); + + // Set the viewport + stateManager->setSimpleViewport(extents); + const d3d11::SharedSRV *srv; + ANGLE_TRY(depthStencil->getShaderResourceView(context, &srv)); + stateManager->setShaderResourceShared(gl::ShaderType::Fragment, 0, srv); + stateManager->setShaderResource(gl::ShaderType::Fragment, 1, &mStencilSRV); + + // Trigger the blit on the GPU. + deviceContext->Draw(6, 0); + + gl::Box copyBox(0, 0, 0, extents.width, extents.height, 1); + + ANGLE_TRY(mRenderer->createStagingTexture(context, ResourceType::Texture2D, + depthStencil->getFormatSet(), extents, + StagingAccess::READ_WRITE, textureOut)); + + const auto ©Function = GetCopyDepthStencilFunction(depthStencil->getInternalFormat()); + const auto &dsFormatSet = depthStencil->getFormatSet(); + const auto &dsDxgiInfo = d3d11::GetDXGIFormatSizeInfo(dsFormatSet.texFormat); + + ANGLE_TRY(copyAndConvertImpl(context, mResolvedDepthStencil, 0, copyBox, extents, *textureOut, + copyBox, extents, nullptr, 0, 0, 0, 8u, dsDxgiInfo.pixelBytes, + copyFunction)); + + return angle::Result::Continue; +} + +void Blit11::releaseResolveDepthStencilResources() +{ + mStencilSRV.reset(); + mResolvedDepthStencilRTView.reset(); +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Blit11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Blit11.h new file mode 100644 index 0000000000..cef491137d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Blit11.h @@ -0,0 +1,300 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Blit11.cpp: Texture copy utility class. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_BLIT11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_BLIT11_H_ + +#include "common/angleutils.h" +#include "libANGLE/Error.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" + +#include + +namespace rx +{ +class Renderer11; + +class Blit11 : angle::NonCopyable +{ + public: + explicit Blit11(Renderer11 *renderer); + ~Blit11(); + + angle::Result swizzleTexture(const gl::Context *context, + const d3d11::SharedSRV &source, + const d3d11::RenderTargetView &dest, + const gl::Extents &size, + const gl::SwizzleState &swizzleTarget); + + // Set destTypeForDownsampling to GL_NONE to skip downsampling + angle::Result copyTexture(const gl::Context *context, + const d3d11::SharedSRV &source, + const gl::Box &sourceArea, + const gl::Extents &sourceSize, + GLenum sourceFormat, + const d3d11::RenderTargetView &dest, + const gl::Box &destArea, + const gl::Extents &destSize, + const gl::Rectangle *scissor, + GLenum destFormat, + GLenum destTypeForDownsampling, + GLenum filter, + bool maskOffAlpha, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha); + + angle::Result copyStencil(const gl::Context *context, + const TextureHelper11 &source, + unsigned int sourceSubresource, + const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const TextureHelper11 &dest, + unsigned int destSubresource, + const gl::Box &destArea, + const gl::Extents &destSize, + const gl::Rectangle *scissor); + + angle::Result copyDepth(const gl::Context *context, + const d3d11::SharedSRV &source, + const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const d3d11::DepthStencilView &dest, + const gl::Box &destArea, + const gl::Extents &destSize, + const gl::Rectangle *scissor); + + angle::Result copyDepthStencil(const gl::Context *context, + const TextureHelper11 &source, + unsigned int sourceSubresource, + const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const TextureHelper11 &dest, + unsigned int destSubresource, + const gl::Box &destArea, + const gl::Extents &destSize, + const gl::Rectangle *scissor); + + angle::Result resolveDepth(const gl::Context *context, + RenderTarget11 *depth, + TextureHelper11 *textureOut); + + angle::Result resolveStencil(const gl::Context *context, + RenderTarget11 *depthStencil, + bool alsoDepth, + TextureHelper11 *textureOut); + + using BlitConvertFunction = void(const gl::Box &sourceArea, + const gl::Box &destArea, + const gl::Rectangle &clipRect, + const gl::Extents &sourceSize, + unsigned int sourceRowPitch, + unsigned int destRowPitch, + ptrdiff_t readOffset, + ptrdiff_t writeOffset, + size_t copySize, + size_t srcPixelStride, + size_t destPixelStride, + const uint8_t *sourceData, + uint8_t *destData); + + private: + enum BlitShaderOperation : unsigned int; + enum BlitShaderType : unsigned int; + enum SwizzleShaderType + { + SWIZZLESHADER_INVALID, + SWIZZLESHADER_2D_FLOAT, + SWIZZLESHADER_2D_UINT, + SWIZZLESHADER_2D_INT, + SWIZZLESHADER_CUBE_FLOAT, + SWIZZLESHADER_CUBE_UINT, + SWIZZLESHADER_CUBE_INT, + SWIZZLESHADER_3D_FLOAT, + SWIZZLESHADER_3D_UINT, + SWIZZLESHADER_3D_INT, + SWIZZLESHADER_ARRAY_FLOAT, + SWIZZLESHADER_ARRAY_UINT, + SWIZZLESHADER_ARRAY_INT, + }; + + typedef void (*WriteVertexFunction)(const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const gl::Box &destArea, + const gl::Extents &destSize, + void *outVertices, + unsigned int *outStride, + unsigned int *outVertexCount, + D3D11_PRIMITIVE_TOPOLOGY *outTopology); + + enum ShaderDimension + { + SHADER_INVALID, + SHADER_2D, + SHADER_3D, + SHADER_2DARRAY + }; + + struct Shader + { + Shader(); + Shader(Shader &&other); + ~Shader(); + Shader &operator=(Shader &&other); + + ShaderDimension dimension; + d3d11::PixelShader pixelShader; + }; + + struct ShaderSupport + { + const d3d11::InputLayout *inputLayout; + const d3d11::VertexShader *vertexShader; + const d3d11::GeometryShader *geometryShader; + WriteVertexFunction vertexWriteFunction; + }; + + angle::Result initResources(const gl::Context *context); + + angle::Result getShaderSupport(const gl::Context *context, + const Shader &shader, + ShaderSupport *supportOut); + + static BlitShaderOperation getBlitShaderOperation(GLenum destinationFormat, + GLenum sourceFormat, + bool isSrcSigned, + bool isDestSigned, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + GLenum destTypeForDownsampling); + + static BlitShaderType getBlitShaderType(BlitShaderOperation operation, + ShaderDimension dimension); + + static SwizzleShaderType GetSwizzleShaderType(GLenum type, D3D11_SRV_DIMENSION dimensionality); + + angle::Result copyDepthStencilImpl(const gl::Context *context, + const TextureHelper11 &source, + unsigned int sourceSubresource, + const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const TextureHelper11 &dest, + unsigned int destSubresource, + const gl::Box &destArea, + const gl::Extents &destSize, + const gl::Rectangle *scissor, + bool stencilOnly); + + angle::Result copyAndConvertImpl(const gl::Context *context, + const TextureHelper11 &source, + unsigned int sourceSubresource, + const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const TextureHelper11 &destStaging, + const gl::Box &destArea, + const gl::Extents &destSize, + const gl::Rectangle *scissor, + size_t readOffset, + size_t writeOffset, + size_t copySize, + size_t srcPixelStride, + size_t destPixelStride, + BlitConvertFunction *convertFunction); + + angle::Result copyAndConvert(const gl::Context *context, + const TextureHelper11 &source, + unsigned int sourceSubresource, + const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const TextureHelper11 &dest, + unsigned int destSubresource, + const gl::Box &destArea, + const gl::Extents &destSize, + const gl::Rectangle *scissor, + size_t readOffset, + size_t writeOffset, + size_t copySize, + size_t srcPixelStride, + size_t destPixelStride, + BlitConvertFunction *convertFunction); + + angle::Result mapBlitShader(const gl::Context *context, BlitShaderType blitShaderType); + angle::Result addBlitShaderToMap(const gl::Context *context, + BlitShaderType blitShaderType, + ShaderDimension dimension, + const ShaderData &shaderData, + const char *name); + + angle::Result getBlitShader(const gl::Context *context, + GLenum destFormat, + GLenum sourceFormat, + bool isSrcSigned, + bool isDestSigned, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + GLenum destTypeForDownsampling, + ShaderDimension dimension, + const Shader **shaderOut); + angle::Result getSwizzleShader(const gl::Context *context, + GLenum type, + D3D11_SRV_DIMENSION viewDimension, + const Shader **shaderOut); + + angle::Result addSwizzleShaderToMap(const gl::Context *context, + SwizzleShaderType swizzleShaderType, + ShaderDimension dimension, + const ShaderData &shaderData, + const char *name); + + void clearShaderMap(); + void releaseResolveDepthStencilResources(); + angle::Result initResolveDepthOnly(const gl::Context *context, + const d3d11::Format &format, + const gl::Extents &extents); + angle::Result initResolveDepthStencil(const gl::Context *context, const gl::Extents &extents); + + Renderer11 *mRenderer; + + std::map mBlitShaderMap; + std::map mSwizzleShaderMap; + + bool mResourcesInitialized; + d3d11::Buffer mVertexBuffer; + d3d11::SamplerState mPointSampler; + d3d11::SamplerState mLinearSampler; + d3d11::RasterizerState mScissorEnabledRasterizerState; + d3d11::RasterizerState mScissorDisabledRasterizerState; + d3d11::DepthStencilState mDepthStencilState; + + d3d11::LazyInputLayout mQuad2DIL; + d3d11::LazyShader mQuad2DVS; + d3d11::LazyShader mDepthPS; + + d3d11::LazyInputLayout mQuad3DIL; + d3d11::LazyShader mQuad3DVS; + d3d11::LazyShader mQuad3DGS; + + d3d11::LazyBlendState mAlphaMaskBlendState; + + d3d11::Buffer mSwizzleCB; + + d3d11::LazyShader mResolveDepthStencilVS; + d3d11::LazyShader mResolveDepthPS; + d3d11::LazyShader mResolveDepthStencilPS; + d3d11::LazyShader mResolveStencilPS; + d3d11::ShaderResourceView mStencilSRV; + TextureHelper11 mResolvedDepthStencil; + d3d11::RenderTargetView mResolvedDepthStencilRTView; + TextureHelper11 mResolvedDepth; + d3d11::DepthStencilView mResolvedDepthDSView; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_BLIT11_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Blit11Helper_autogen.inc b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Blit11Helper_autogen.inc new file mode 100644 index 0000000000..64d8106a18 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Blit11Helper_autogen.inc @@ -0,0 +1,1575 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_blit11helper.py. +// +// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Blit11Helper_autogen.inc: +// Defines and retrieves blitshaders for the D3D11 backend. + +namespace +{ +// Include inline shaders in the anonymous namespace to make sure no symbols are exported +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrougha2d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum2d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dui11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2di11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2dui11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2di11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2dui11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2di11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2dui11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2di11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_2d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_2d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_2d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_2d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_2d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_2d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_2d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_2d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_2d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_2d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_2d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_2d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_2d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_2d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d_4444_11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_4444_2d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_4444_2d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d_565_11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_565_2d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_565_2d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d_5551_11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_5551_2d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_5551_2d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum3d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3dui11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3di11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3dui11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3di11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3dui11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3di11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3dui11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3di11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_3d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_3d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_3d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_3d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_3d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_3d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_3d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_3d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_3d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_3d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgba_3d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgba_3d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgba_3d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgb_3d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgb_3d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgb_3d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_3d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_3d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_3d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_3d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d_4444_11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_4444_3d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_4444_3d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d_565_11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_565_3d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_565_3d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d_5551_11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_5551_3d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_5551_3d_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darray11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darray11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2darray11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2darray11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum2darray11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2darray11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darrayui11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darrayi11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darrayui11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darrayi11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2darrayui11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2darrayi11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2darrayui11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2darrayi11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_2darray_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_2darray_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_2darray_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_2darray_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_2darray_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_2darray_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_2darray_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_2darray_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_2darray_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_2darray_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgba_2darray_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgba_2darray_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgba_2darray_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgb_2darray_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgb_2darray_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgb_2darray_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_2darray_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_2darray_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_2darray_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_2darray_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darray_4444_11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_4444_2darray_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_4444_2darray_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darray_565_11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_565_2darray_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_565_2darray_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darray_5551_11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_5551_2darray_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_5551_2darray_ps.h" +} // namespace + +enum Blit11::BlitShaderOperation : unsigned int +{ + RGBAF, + BGRAF, + RGBF, + RGF, + RF, + ALPHA, + LUMA, + LUMAALPHA, + RGBAUI, + RGBAI, + RGBUI, + RGBI, + RGUI, + RGI, + RUI, + RI, + RGBAF_PREMULTIPLY, + RGBAF_UNMULTIPLY, + RGBF_PREMULTIPLY, + RGBF_UNMULTIPLY, + RGBAF_TOUI, + RGBAF_TOUI_PREMULTIPLY, + RGBAF_TOUI_UNMULTIPLY, + RGBF_TOUI, + RGBF_TOUI_PREMULTIPLY, + RGBF_TOUI_UNMULTIPLY, + RGBAF_TOI, + RGBAF_TOI_PREMULTIPLY, + RGBAF_TOI_UNMULTIPLY, + RGBF_TOI, + RGBF_TOI_PREMULTIPLY, + RGBF_TOI_UNMULTIPLY, + LUMAF_PREMULTIPLY, + LUMAF_UNMULTIPLY, + LUMAALPHAF_PREMULTIPLY, + LUMAALPHAF_UNMULTIPLY, + RGBAF_4444, + RGBAF_4444_PREMULTIPLY, + RGBAF_4444_UNMULTIPLY, + RGBF_565, + RGBF_565_PREMULTIPLY, + RGBF_565_UNMULTIPLY, + RGBAF_5551, + RGBAF_5551_PREMULTIPLY, + RGBAF_5551_UNMULTIPLY, + OPERATION_INVALID +}; + +enum Blit11::BlitShaderType : unsigned int +{ + BLITSHADER_2D_RGBAF, + BLITSHADER_2D_BGRAF, + BLITSHADER_2D_RGBF, + BLITSHADER_2D_RGF, + BLITSHADER_2D_RF, + BLITSHADER_2D_ALPHA, + BLITSHADER_2D_LUMA, + BLITSHADER_2D_LUMAALPHA, + BLITSHADER_2D_RGBAUI, + BLITSHADER_2D_RGBAI, + BLITSHADER_2D_RGBUI, + BLITSHADER_2D_RGBI, + BLITSHADER_2D_RGUI, + BLITSHADER_2D_RGI, + BLITSHADER_2D_RUI, + BLITSHADER_2D_RI, + BLITSHADER_2D_RGBAF_PREMULTIPLY, + BLITSHADER_2D_RGBAF_UNMULTIPLY, + BLITSHADER_2D_RGBF_PREMULTIPLY, + BLITSHADER_2D_RGBF_UNMULTIPLY, + BLITSHADER_2D_RGBAF_TOUI, + BLITSHADER_2D_RGBAF_TOUI_PREMULTIPLY, + BLITSHADER_2D_RGBAF_TOUI_UNMULTIPLY, + BLITSHADER_2D_RGBF_TOUI, + BLITSHADER_2D_RGBF_TOUI_PREMULTIPLY, + BLITSHADER_2D_RGBF_TOUI_UNMULTIPLY, + BLITSHADER_2D_LUMAF_PREMULTIPLY, + BLITSHADER_2D_LUMAF_UNMULTIPLY, + BLITSHADER_2D_LUMAALPHAF_PREMULTIPLY, + BLITSHADER_2D_LUMAALPHAF_UNMULTIPLY, + BLITSHADER_2D_RGBAF_4444, + BLITSHADER_2D_RGBAF_4444_PREMULTIPLY, + BLITSHADER_2D_RGBAF_4444_UNMULTIPLY, + BLITSHADER_2D_RGBF_565, + BLITSHADER_2D_RGBF_565_PREMULTIPLY, + BLITSHADER_2D_RGBF_565_UNMULTIPLY, + BLITSHADER_2D_RGBAF_5551, + BLITSHADER_2D_RGBAF_5551_PREMULTIPLY, + BLITSHADER_2D_RGBAF_5551_UNMULTIPLY, + BLITSHADER_3D_RGBAF, + BLITSHADER_3D_BGRAF, + BLITSHADER_3D_RGBF, + BLITSHADER_3D_RGF, + BLITSHADER_3D_RF, + BLITSHADER_3D_ALPHA, + BLITSHADER_3D_LUMA, + BLITSHADER_3D_LUMAALPHA, + BLITSHADER_3D_RGBAUI, + BLITSHADER_3D_RGBAI, + BLITSHADER_3D_RGBUI, + BLITSHADER_3D_RGBI, + BLITSHADER_3D_RGUI, + BLITSHADER_3D_RGI, + BLITSHADER_3D_RUI, + BLITSHADER_3D_RI, + BLITSHADER_3D_RGBAF_PREMULTIPLY, + BLITSHADER_3D_RGBAF_UNMULTIPLY, + BLITSHADER_3D_RGBF_PREMULTIPLY, + BLITSHADER_3D_RGBF_UNMULTIPLY, + BLITSHADER_3D_RGBAF_TOUI, + BLITSHADER_3D_RGBAF_TOUI_PREMULTIPLY, + BLITSHADER_3D_RGBAF_TOUI_UNMULTIPLY, + BLITSHADER_3D_RGBF_TOUI, + BLITSHADER_3D_RGBF_TOUI_PREMULTIPLY, + BLITSHADER_3D_RGBF_TOUI_UNMULTIPLY, + BLITSHADER_3D_RGBAF_TOI, + BLITSHADER_3D_RGBAF_TOI_PREMULTIPLY, + BLITSHADER_3D_RGBAF_TOI_UNMULTIPLY, + BLITSHADER_3D_RGBF_TOI, + BLITSHADER_3D_RGBF_TOI_PREMULTIPLY, + BLITSHADER_3D_RGBF_TOI_UNMULTIPLY, + BLITSHADER_3D_LUMAF_PREMULTIPLY, + BLITSHADER_3D_LUMAF_UNMULTIPLY, + BLITSHADER_3D_LUMAALPHAF_PREMULTIPLY, + BLITSHADER_3D_LUMAALPHAF_UNMULTIPLY, + BLITSHADER_3D_RGBAF_4444, + BLITSHADER_3D_RGBAF_4444_PREMULTIPLY, + BLITSHADER_3D_RGBAF_4444_UNMULTIPLY, + BLITSHADER_3D_RGBF_565, + BLITSHADER_3D_RGBF_565_PREMULTIPLY, + BLITSHADER_3D_RGBF_565_UNMULTIPLY, + BLITSHADER_3D_RGBAF_5551, + BLITSHADER_3D_RGBAF_5551_PREMULTIPLY, + BLITSHADER_3D_RGBAF_5551_UNMULTIPLY, + BLITSHADER_2DARRAY_RGBAF, + BLITSHADER_2DARRAY_BGRAF, + BLITSHADER_2DARRAY_RGBF, + BLITSHADER_2DARRAY_RGF, + BLITSHADER_2DARRAY_RF, + BLITSHADER_2DARRAY_ALPHA, + BLITSHADER_2DARRAY_LUMA, + BLITSHADER_2DARRAY_LUMAALPHA, + BLITSHADER_2DARRAY_RGBAUI, + BLITSHADER_2DARRAY_RGBAI, + BLITSHADER_2DARRAY_RGBUI, + BLITSHADER_2DARRAY_RGBI, + BLITSHADER_2DARRAY_RGUI, + BLITSHADER_2DARRAY_RGI, + BLITSHADER_2DARRAY_RUI, + BLITSHADER_2DARRAY_RI, + BLITSHADER_2DARRAY_RGBAF_PREMULTIPLY, + BLITSHADER_2DARRAY_RGBAF_UNMULTIPLY, + BLITSHADER_2DARRAY_RGBF_PREMULTIPLY, + BLITSHADER_2DARRAY_RGBF_UNMULTIPLY, + BLITSHADER_2DARRAY_RGBAF_TOUI, + BLITSHADER_2DARRAY_RGBAF_TOUI_PREMULTIPLY, + BLITSHADER_2DARRAY_RGBAF_TOUI_UNMULTIPLY, + BLITSHADER_2DARRAY_RGBF_TOUI, + BLITSHADER_2DARRAY_RGBF_TOUI_PREMULTIPLY, + BLITSHADER_2DARRAY_RGBF_TOUI_UNMULTIPLY, + BLITSHADER_2DARRAY_RGBAF_TOI, + BLITSHADER_2DARRAY_RGBAF_TOI_PREMULTIPLY, + BLITSHADER_2DARRAY_RGBAF_TOI_UNMULTIPLY, + BLITSHADER_2DARRAY_RGBF_TOI, + BLITSHADER_2DARRAY_RGBF_TOI_PREMULTIPLY, + BLITSHADER_2DARRAY_RGBF_TOI_UNMULTIPLY, + BLITSHADER_2DARRAY_LUMAF_PREMULTIPLY, + BLITSHADER_2DARRAY_LUMAF_UNMULTIPLY, + BLITSHADER_2DARRAY_LUMAALPHAF_PREMULTIPLY, + BLITSHADER_2DARRAY_LUMAALPHAF_UNMULTIPLY, + BLITSHADER_2DARRAY_RGBAF_4444, + BLITSHADER_2DARRAY_RGBAF_4444_PREMULTIPLY, + BLITSHADER_2DARRAY_RGBAF_4444_UNMULTIPLY, + BLITSHADER_2DARRAY_RGBF_565, + BLITSHADER_2DARRAY_RGBF_565_PREMULTIPLY, + BLITSHADER_2DARRAY_RGBF_565_UNMULTIPLY, + BLITSHADER_2DARRAY_RGBAF_5551, + BLITSHADER_2DARRAY_RGBAF_5551_PREMULTIPLY, + BLITSHADER_2DARRAY_RGBAF_5551_UNMULTIPLY, + BLITSHADER_INVALID +}; + +Blit11::BlitShaderType Blit11::getBlitShaderType(BlitShaderOperation operation, ShaderDimension dimension) +{ + switch(operation) + { + case RGBAF: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_RGBAF; + case SHADER_3D: + return BLITSHADER_3D_RGBAF; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGBAF; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case BGRAF: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_BGRAF; + case SHADER_3D: + return BLITSHADER_3D_BGRAF; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_BGRAF; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGBF: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_RGBF; + case SHADER_3D: + return BLITSHADER_3D_RGBF; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGBF; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGF: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_RGF; + case SHADER_3D: + return BLITSHADER_3D_RGF; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGF; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RF: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_RF; + case SHADER_3D: + return BLITSHADER_3D_RF; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RF; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case ALPHA: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_ALPHA; + case SHADER_3D: + return BLITSHADER_3D_ALPHA; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_ALPHA; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case LUMA: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_LUMA; + case SHADER_3D: + return BLITSHADER_3D_LUMA; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_LUMA; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case LUMAALPHA: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_LUMAALPHA; + case SHADER_3D: + return BLITSHADER_3D_LUMAALPHA; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_LUMAALPHA; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGBAUI: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_RGBAUI; + case SHADER_3D: + return BLITSHADER_3D_RGBAUI; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGBAUI; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGBAI: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_RGBAI; + case SHADER_3D: + return BLITSHADER_3D_RGBAI; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGBAI; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGBUI: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_RGBUI; + case SHADER_3D: + return BLITSHADER_3D_RGBUI; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGBUI; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGBI: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_RGBI; + case SHADER_3D: + return BLITSHADER_3D_RGBI; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGBI; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGUI: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_RGUI; + case SHADER_3D: + return BLITSHADER_3D_RGUI; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGUI; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGI: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_RGI; + case SHADER_3D: + return BLITSHADER_3D_RGI; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGI; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RUI: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_RUI; + case SHADER_3D: + return BLITSHADER_3D_RUI; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RUI; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RI: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_RI; + case SHADER_3D: + return BLITSHADER_3D_RI; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RI; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGBAF_PREMULTIPLY: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_RGBAF_PREMULTIPLY; + case SHADER_3D: + return BLITSHADER_3D_RGBAF_PREMULTIPLY; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGBAF_PREMULTIPLY; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGBAF_UNMULTIPLY: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_RGBAF_UNMULTIPLY; + case SHADER_3D: + return BLITSHADER_3D_RGBAF_UNMULTIPLY; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGBAF_UNMULTIPLY; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGBF_PREMULTIPLY: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_RGBF_PREMULTIPLY; + case SHADER_3D: + return BLITSHADER_3D_RGBF_PREMULTIPLY; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGBF_PREMULTIPLY; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGBF_UNMULTIPLY: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_RGBF_UNMULTIPLY; + case SHADER_3D: + return BLITSHADER_3D_RGBF_UNMULTIPLY; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGBF_UNMULTIPLY; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGBAF_TOUI: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_RGBAF_TOUI; + case SHADER_3D: + return BLITSHADER_3D_RGBAF_TOUI; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGBAF_TOUI; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGBAF_TOUI_PREMULTIPLY: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_RGBAF_TOUI_PREMULTIPLY; + case SHADER_3D: + return BLITSHADER_3D_RGBAF_TOUI_PREMULTIPLY; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGBAF_TOUI_PREMULTIPLY; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGBAF_TOUI_UNMULTIPLY: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_RGBAF_TOUI_UNMULTIPLY; + case SHADER_3D: + return BLITSHADER_3D_RGBAF_TOUI_UNMULTIPLY; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGBAF_TOUI_UNMULTIPLY; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGBF_TOUI: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_RGBF_TOUI; + case SHADER_3D: + return BLITSHADER_3D_RGBF_TOUI; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGBF_TOUI; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGBF_TOUI_PREMULTIPLY: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_RGBF_TOUI_PREMULTIPLY; + case SHADER_3D: + return BLITSHADER_3D_RGBF_TOUI_PREMULTIPLY; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGBF_TOUI_PREMULTIPLY; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGBF_TOUI_UNMULTIPLY: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_RGBF_TOUI_UNMULTIPLY; + case SHADER_3D: + return BLITSHADER_3D_RGBF_TOUI_UNMULTIPLY; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGBF_TOUI_UNMULTIPLY; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGBAF_TOI: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_INVALID; + case SHADER_3D: + return BLITSHADER_3D_RGBAF_TOI; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGBAF_TOI; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGBAF_TOI_PREMULTIPLY: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_INVALID; + case SHADER_3D: + return BLITSHADER_3D_RGBAF_TOI_PREMULTIPLY; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGBAF_TOI_PREMULTIPLY; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGBAF_TOI_UNMULTIPLY: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_INVALID; + case SHADER_3D: + return BLITSHADER_3D_RGBAF_TOI_UNMULTIPLY; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGBAF_TOI_UNMULTIPLY; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGBF_TOI: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_INVALID; + case SHADER_3D: + return BLITSHADER_3D_RGBF_TOI; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGBF_TOI; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGBF_TOI_PREMULTIPLY: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_INVALID; + case SHADER_3D: + return BLITSHADER_3D_RGBF_TOI_PREMULTIPLY; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGBF_TOI_PREMULTIPLY; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGBF_TOI_UNMULTIPLY: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_INVALID; + case SHADER_3D: + return BLITSHADER_3D_RGBF_TOI_UNMULTIPLY; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGBF_TOI_UNMULTIPLY; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case LUMAF_PREMULTIPLY: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_LUMAF_PREMULTIPLY; + case SHADER_3D: + return BLITSHADER_3D_LUMAF_PREMULTIPLY; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_LUMAF_PREMULTIPLY; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case LUMAF_UNMULTIPLY: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_LUMAF_UNMULTIPLY; + case SHADER_3D: + return BLITSHADER_3D_LUMAF_UNMULTIPLY; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_LUMAF_UNMULTIPLY; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case LUMAALPHAF_PREMULTIPLY: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_LUMAALPHAF_PREMULTIPLY; + case SHADER_3D: + return BLITSHADER_3D_LUMAALPHAF_PREMULTIPLY; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_LUMAALPHAF_PREMULTIPLY; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case LUMAALPHAF_UNMULTIPLY: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_LUMAALPHAF_UNMULTIPLY; + case SHADER_3D: + return BLITSHADER_3D_LUMAALPHAF_UNMULTIPLY; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_LUMAALPHAF_UNMULTIPLY; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGBAF_4444: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_RGBAF_4444; + case SHADER_3D: + return BLITSHADER_3D_RGBAF_4444; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGBAF_4444; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGBAF_4444_PREMULTIPLY: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_RGBAF_4444_PREMULTIPLY; + case SHADER_3D: + return BLITSHADER_3D_RGBAF_4444_PREMULTIPLY; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGBAF_4444_PREMULTIPLY; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGBAF_4444_UNMULTIPLY: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_RGBAF_4444_UNMULTIPLY; + case SHADER_3D: + return BLITSHADER_3D_RGBAF_4444_UNMULTIPLY; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGBAF_4444_UNMULTIPLY; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGBF_565: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_RGBF_565; + case SHADER_3D: + return BLITSHADER_3D_RGBF_565; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGBF_565; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGBF_565_PREMULTIPLY: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_RGBF_565_PREMULTIPLY; + case SHADER_3D: + return BLITSHADER_3D_RGBF_565_PREMULTIPLY; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGBF_565_PREMULTIPLY; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGBF_565_UNMULTIPLY: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_RGBF_565_UNMULTIPLY; + case SHADER_3D: + return BLITSHADER_3D_RGBF_565_UNMULTIPLY; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGBF_565_UNMULTIPLY; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGBAF_5551: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_RGBAF_5551; + case SHADER_3D: + return BLITSHADER_3D_RGBAF_5551; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGBAF_5551; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGBAF_5551_PREMULTIPLY: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_RGBAF_5551_PREMULTIPLY; + case SHADER_3D: + return BLITSHADER_3D_RGBAF_5551_PREMULTIPLY; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGBAF_5551_PREMULTIPLY; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + case RGBAF_5551_UNMULTIPLY: + switch (dimension) + { + case SHADER_2D: + return BLITSHADER_2D_RGBAF_5551_UNMULTIPLY; + case SHADER_3D: + return BLITSHADER_3D_RGBAF_5551_UNMULTIPLY; + case SHADER_2DARRAY: + return BLITSHADER_2DARRAY_RGBAF_5551_UNMULTIPLY; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } +} + +angle::Result Blit11::mapBlitShader(const gl::Context *context, + BlitShaderType blitShaderType) +{ + switch(blitShaderType) + { + case BLITSHADER_2D_RGBAF: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughRGBA2D), + "Blit11 2D PassthroughRGBA2D pixel shader")); + break; + case BLITSHADER_2D_BGRAF: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughRGBA2D), + "Blit11 2D PassthroughRGBA2D pixel shader")); + break; + case BLITSHADER_2D_RGBF: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughRGB2D), + "Blit11 2D PassthroughRGB2D pixel shader")); + break; + case BLITSHADER_2D_RGF: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughRG2D), + "Blit11 2D PassthroughRG2D pixel shader")); + break; + case BLITSHADER_2D_RF: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughR2D), + "Blit11 2D PassthroughR2D pixel shader")); + break; + case BLITSHADER_2D_ALPHA: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughA2D), + "Blit11 2D PassthroughA2D pixel shader")); + break; + case BLITSHADER_2D_LUMA: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughLum2D), + "Blit11 2D PassthroughLum2D pixel shader")); + break; + case BLITSHADER_2D_LUMAALPHA: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughLumAlpha2D), + "Blit11 2D PassthroughLumAlpha2D pixel shader")); + break; + case BLITSHADER_2D_RGBAUI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughRGBA2DUI), + "Blit11 2D PassthroughRGBA2DUI pixel shader")); + break; + case BLITSHADER_2D_RGBAI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughRGBA2DI), + "Blit11 2D PassthroughRGBA2DI pixel shader")); + break; + case BLITSHADER_2D_RGBUI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughRGB2DUI), + "Blit11 2D PassthroughRGB2DUI pixel shader")); + break; + case BLITSHADER_2D_RGBI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughRGB2DI), + "Blit11 2D PassthroughRGB2DI pixel shader")); + break; + case BLITSHADER_2D_RGUI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughRG2DUI), + "Blit11 2D PassthroughRG2DUI pixel shader")); + break; + case BLITSHADER_2D_RGI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughRG2DI), + "Blit11 2D PassthroughRG2DI pixel shader")); + break; + case BLITSHADER_2D_RUI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughR2DUI), + "Blit11 2D PassthroughR2DUI pixel shader")); + break; + case BLITSHADER_2D_RI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughR2DI), + "Blit11 2D PassthroughR2DI pixel shader")); + break; + case BLITSHADER_2D_RGBAF_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_FtoF_PM_RGBA_2D), + "Blit11 2D FtoF PM RGBA 2D pixel shader")); + break; + case BLITSHADER_2D_RGBAF_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_FtoF_UM_RGBA_2D), + "Blit11 2D FtoF UM RGBA 2D pixel shader")); + break; + case BLITSHADER_2D_RGBF_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_FtoF_PM_RGB_2D), + "Blit11 2D FtoF PM RGB 2D pixel shader")); + break; + case BLITSHADER_2D_RGBF_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_FtoF_UM_RGB_2D), + "Blit11 2D FtoF UM RGB 2D pixel shader")); + break; + case BLITSHADER_2D_RGBAF_TOUI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_FtoU_PT_RGBA_2D), + "Blit11 2D FtoU PT RGBA 2D pixel shader")); + break; + case BLITSHADER_2D_RGBAF_TOUI_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_FtoU_PM_RGBA_2D), + "Blit11 2D FtoU PM RGBA 2D pixel shader")); + break; + case BLITSHADER_2D_RGBAF_TOUI_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_FtoU_UM_RGBA_2D), + "Blit11 2D FtoU UM RGBA 2D pixel shader")); + break; + case BLITSHADER_2D_RGBF_TOUI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_FtoU_PT_RGB_2D), + "Blit11 2D FtoU PT RGB 2D pixel shader")); + break; + case BLITSHADER_2D_RGBF_TOUI_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_FtoU_PM_RGB_2D), + "Blit11 2D FtoU PM RGB 2D pixel shader")); + break; + case BLITSHADER_2D_RGBF_TOUI_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_FtoU_UM_RGB_2D), + "Blit11 2D FtoU UM RGB 2D pixel shader")); + break; + case BLITSHADER_2D_LUMAF_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_FtoF_PM_LUMA_2D), + "Blit11 2D FtoF PM LUMA 2D pixel shader")); + break; + case BLITSHADER_2D_LUMAF_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_FtoF_UM_LUMA_2D), + "Blit11 2D FtoF UM LUMA 2D pixel shader")); + break; + case BLITSHADER_2D_LUMAALPHAF_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_FtoF_PM_LUMAALPHA_2D), + "Blit11 2D FtoF PM LUMAALPHA 2D pixel shader")); + break; + case BLITSHADER_2D_LUMAALPHAF_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_FtoF_UM_LUMAALPHA_2D), + "Blit11 2D FtoF UM LUMAALPHA 2D pixel shader")); + break; + case BLITSHADER_2D_RGBAF_4444: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughRGBA2D_4444), + "Blit11 2D PassthroughRGBA2D 4444 pixel shader")); + break; + case BLITSHADER_2D_RGBAF_4444_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_FtoF_PM_RGBA_4444_2D), + "Blit11 2D FtoF PM RGBA 4444 2D pixel shader")); + break; + case BLITSHADER_2D_RGBAF_4444_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_FtoF_UM_RGBA_4444_2D), + "Blit11 2D FtoF UM RGBA 4444 2D pixel shader")); + break; + case BLITSHADER_2D_RGBF_565: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughRGB2D_565), + "Blit11 2D PassthroughRGB2D 565 pixel shader")); + break; + case BLITSHADER_2D_RGBF_565_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_FtoF_PM_RGB_565_2D), + "Blit11 2D FtoF PM RGB 565 2D pixel shader")); + break; + case BLITSHADER_2D_RGBF_565_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_FtoF_UM_RGB_565_2D), + "Blit11 2D FtoF UM RGB 565 2D pixel shader")); + break; + case BLITSHADER_2D_RGBAF_5551: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughRGBA2D_5551), + "Blit11 2D PassthroughRGBA2D 5551 pixel shader")); + break; + case BLITSHADER_2D_RGBAF_5551_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_FtoF_PM_RGBA_5551_2D), + "Blit11 2D FtoF PM RGBA 5551 2D pixel shader")); + break; + case BLITSHADER_2D_RGBAF_5551_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D, + ShaderData(g_PS_FtoF_UM_RGBA_5551_2D), + "Blit11 2D FtoF UM RGBA 5551 2D pixel shader")); + break; + case BLITSHADER_3D_RGBAF: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughRGBA3D), + "Blit11 3D PassthroughRGBA3D pixel shader")); + break; + case BLITSHADER_3D_BGRAF: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughRGBA3D), + "Blit11 3D PassthroughRGBA3D pixel shader")); + break; + case BLITSHADER_3D_RGBF: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughRGB3D), + "Blit11 3D PassthroughRGB3D pixel shader")); + break; + case BLITSHADER_3D_RGF: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughRG3D), + "Blit11 3D PassthroughRG3D pixel shader")); + break; + case BLITSHADER_3D_RF: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughR3D), + "Blit11 3D PassthroughR3D pixel shader")); + break; + case BLITSHADER_3D_ALPHA: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughRGBA3D), + "Blit11 3D PassthroughRGBA3D pixel shader")); + break; + case BLITSHADER_3D_LUMA: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughLum3D), + "Blit11 3D PassthroughLum3D pixel shader")); + break; + case BLITSHADER_3D_LUMAALPHA: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughLumAlpha3D), + "Blit11 3D PassthroughLumAlpha3D pixel shader")); + break; + case BLITSHADER_3D_RGBAUI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughRGBA3DUI), + "Blit11 3D PassthroughRGBA3DUI pixel shader")); + break; + case BLITSHADER_3D_RGBAI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughRGBA3DI), + "Blit11 3D PassthroughRGBA3DI pixel shader")); + break; + case BLITSHADER_3D_RGBUI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughRGB3DUI), + "Blit11 3D PassthroughRGB3DUI pixel shader")); + break; + case BLITSHADER_3D_RGBI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughRGB3DI), + "Blit11 3D PassthroughRGB3DI pixel shader")); + break; + case BLITSHADER_3D_RGUI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughRG3DUI), + "Blit11 3D PassthroughRG3DUI pixel shader")); + break; + case BLITSHADER_3D_RGI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughRG3DI), + "Blit11 3D PassthroughRG3DI pixel shader")); + break; + case BLITSHADER_3D_RUI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughR3DUI), + "Blit11 3D PassthroughR3DUI pixel shader")); + break; + case BLITSHADER_3D_RI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughR3DI), + "Blit11 3D PassthroughR3DI pixel shader")); + break; + case BLITSHADER_3D_RGBAF_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_FtoF_PM_RGBA_3D), + "Blit11 3D FtoF PM RGBA 3D pixel shader")); + break; + case BLITSHADER_3D_RGBAF_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_FtoF_UM_RGBA_3D), + "Blit11 3D FtoF UM RGBA 3D pixel shader")); + break; + case BLITSHADER_3D_RGBF_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_FtoF_PM_RGB_3D), + "Blit11 3D FtoF PM RGB 3D pixel shader")); + break; + case BLITSHADER_3D_RGBF_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_FtoF_UM_RGB_3D), + "Blit11 3D FtoF UM RGB 3D pixel shader")); + break; + case BLITSHADER_3D_RGBAF_TOUI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_FtoU_PT_RGBA_3D), + "Blit11 3D FtoU PT RGBA 3D pixel shader")); + break; + case BLITSHADER_3D_RGBAF_TOUI_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_FtoU_PM_RGBA_3D), + "Blit11 3D FtoU PM RGBA 3D pixel shader")); + break; + case BLITSHADER_3D_RGBAF_TOUI_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_FtoU_UM_RGBA_3D), + "Blit11 3D FtoU UM RGBA 3D pixel shader")); + break; + case BLITSHADER_3D_RGBF_TOUI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_FtoU_PT_RGB_3D), + "Blit11 3D FtoU PT RGB 3D pixel shader")); + break; + case BLITSHADER_3D_RGBF_TOUI_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_FtoU_PM_RGB_3D), + "Blit11 3D FtoU PM RGB 3D pixel shader")); + break; + case BLITSHADER_3D_RGBF_TOUI_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_FtoU_UM_RGB_3D), + "Blit11 3D FtoU UM RGB 3D pixel shader")); + break; + case BLITSHADER_3D_RGBAF_TOI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_FtoI_PT_RGBA_3D), + "Blit11 3D FtoI PT RGBA 3D pixel shader")); + break; + case BLITSHADER_3D_RGBAF_TOI_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_FtoI_PM_RGBA_3D), + "Blit11 3D FtoI PM RGBA 3D pixel shader")); + break; + case BLITSHADER_3D_RGBAF_TOI_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_FtoI_UM_RGBA_3D), + "Blit11 3D FtoI UM RGBA 3D pixel shader")); + break; + case BLITSHADER_3D_RGBF_TOI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_FtoI_PT_RGB_3D), + "Blit11 3D FtoI PT RGB 3D pixel shader")); + break; + case BLITSHADER_3D_RGBF_TOI_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_FtoI_PM_RGB_3D), + "Blit11 3D FtoI PM RGB 3D pixel shader")); + break; + case BLITSHADER_3D_RGBF_TOI_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_FtoI_UM_RGB_3D), + "Blit11 3D FtoI UM RGB 3D pixel shader")); + break; + case BLITSHADER_3D_LUMAF_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_FtoF_PM_LUMA_3D), + "Blit11 3D FtoF PM LUMA 3D pixel shader")); + break; + case BLITSHADER_3D_LUMAF_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_FtoF_UM_LUMA_3D), + "Blit11 3D FtoF UM LUMA 3D pixel shader")); + break; + case BLITSHADER_3D_LUMAALPHAF_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_FtoF_PM_LUMAALPHA_3D), + "Blit11 3D FtoF PM LUMAALPHA 3D pixel shader")); + break; + case BLITSHADER_3D_LUMAALPHAF_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_FtoF_UM_LUMAALPHA_3D), + "Blit11 3D FtoF UM LUMAALPHA 3D pixel shader")); + break; + case BLITSHADER_3D_RGBAF_4444: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughRGBA3D_4444), + "Blit11 3D PassthroughRGBA3D 4444 pixel shader")); + break; + case BLITSHADER_3D_RGBAF_4444_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_FtoF_PM_RGBA_4444_3D), + "Blit11 3D FtoF PM RGBA 4444 3D pixel shader")); + break; + case BLITSHADER_3D_RGBAF_4444_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_FtoF_UM_RGBA_4444_3D), + "Blit11 3D FtoF UM RGBA 4444 3D pixel shader")); + break; + case BLITSHADER_3D_RGBF_565: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughRGB3D_565), + "Blit11 3D PassthroughRGB3D 565 pixel shader")); + break; + case BLITSHADER_3D_RGBF_565_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_FtoF_PM_RGB_565_3D), + "Blit11 3D FtoF PM RGB 565 3D pixel shader")); + break; + case BLITSHADER_3D_RGBF_565_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_FtoF_UM_RGB_565_3D), + "Blit11 3D FtoF UM RGB 565 3D pixel shader")); + break; + case BLITSHADER_3D_RGBAF_5551: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughRGBA3D_5551), + "Blit11 3D PassthroughRGBA3D 5551 pixel shader")); + break; + case BLITSHADER_3D_RGBAF_5551_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_FtoF_PM_RGBA_5551_3D), + "Blit11 3D FtoF PM RGBA 5551 3D pixel shader")); + break; + case BLITSHADER_3D_RGBAF_5551_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D, + ShaderData(g_PS_FtoF_UM_RGBA_5551_3D), + "Blit11 3D FtoF UM RGBA 5551 3D pixel shader")); + break; + case BLITSHADER_2DARRAY_RGBAF: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_PassthroughRGBA2DArray), + "Blit11 2DArray PassthroughRGBA2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_BGRAF: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_PassthroughRGBA2DArray), + "Blit11 2DArray PassthroughRGBA2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_RGBF: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_PassthroughRGB2DArray), + "Blit11 2DArray PassthroughRGB2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_RGF: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_PassthroughRG2DArray), + "Blit11 2DArray PassthroughRG2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_RF: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_PassthroughR2DArray), + "Blit11 2DArray PassthroughR2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_ALPHA: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_PassthroughRGBA2DArray), + "Blit11 2DArray PassthroughRGBA2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_LUMA: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_PassthroughLum2DArray), + "Blit11 2DArray PassthroughLum2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_LUMAALPHA: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_PassthroughLumAlpha2DArray), + "Blit11 2DArray PassthroughLumAlpha2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_RGBAUI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_PassthroughRGBA2DArrayUI), + "Blit11 2DArray PassthroughRGBA2DArrayUI pixel shader")); + break; + case BLITSHADER_2DARRAY_RGBAI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_PassthroughRGBA2DArrayI), + "Blit11 2DArray PassthroughRGBA2DArrayI pixel shader")); + break; + case BLITSHADER_2DARRAY_RGBUI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_PassthroughRGB2DArrayUI), + "Blit11 2DArray PassthroughRGB2DArrayUI pixel shader")); + break; + case BLITSHADER_2DARRAY_RGBI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_PassthroughRGB2DArrayI), + "Blit11 2DArray PassthroughRGB2DArrayI pixel shader")); + break; + case BLITSHADER_2DARRAY_RGUI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_PassthroughRG2DArrayUI), + "Blit11 2DArray PassthroughRG2DArrayUI pixel shader")); + break; + case BLITSHADER_2DARRAY_RGI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_PassthroughRG2DArrayI), + "Blit11 2DArray PassthroughRG2DArrayI pixel shader")); + break; + case BLITSHADER_2DARRAY_RUI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_PassthroughR2DArrayUI), + "Blit11 2DArray PassthroughR2DArrayUI pixel shader")); + break; + case BLITSHADER_2DARRAY_RI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_PassthroughR2DArrayI), + "Blit11 2DArray PassthroughR2DArrayI pixel shader")); + break; + case BLITSHADER_2DARRAY_RGBAF_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_FtoF_PM_RGBA_2DArray), + "Blit11 2DArray FtoF PM RGBA 2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_RGBAF_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_FtoF_UM_RGBA_2DArray), + "Blit11 2DArray FtoF UM RGBA 2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_RGBF_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_FtoF_PM_RGB_2DArray), + "Blit11 2DArray FtoF PM RGB 2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_RGBF_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_FtoF_UM_RGB_2DArray), + "Blit11 2DArray FtoF UM RGB 2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_RGBAF_TOUI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_FtoU_PT_RGBA_2DArray), + "Blit11 2DArray FtoU PT RGBA 2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_RGBAF_TOUI_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_FtoU_PM_RGBA_2DArray), + "Blit11 2DArray FtoU PM RGBA 2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_RGBAF_TOUI_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_FtoU_UM_RGBA_2DArray), + "Blit11 2DArray FtoU UM RGBA 2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_RGBF_TOUI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_FtoU_PT_RGB_2DArray), + "Blit11 2DArray FtoU PT RGB 2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_RGBF_TOUI_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_FtoU_PM_RGB_2DArray), + "Blit11 2DArray FtoU PM RGB 2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_RGBF_TOUI_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_FtoU_UM_RGB_2DArray), + "Blit11 2DArray FtoU UM RGB 2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_RGBAF_TOI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_FtoI_PT_RGBA_2DArray), + "Blit11 2DArray FtoI PT RGBA 2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_RGBAF_TOI_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_FtoI_PM_RGBA_2DArray), + "Blit11 2DArray FtoI PM RGBA 2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_RGBAF_TOI_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_FtoI_UM_RGBA_2DArray), + "Blit11 2DArray FtoI UM RGBA 2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_RGBF_TOI: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_FtoI_PT_RGB_2DArray), + "Blit11 2DArray FtoI PT RGB 2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_RGBF_TOI_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_FtoI_PM_RGB_2DArray), + "Blit11 2DArray FtoI PM RGB 2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_RGBF_TOI_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_FtoI_UM_RGB_2DArray), + "Blit11 2DArray FtoI UM RGB 2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_LUMAF_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_FtoF_PM_LUMA_2DArray), + "Blit11 2DArray FtoF PM LUMA 2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_LUMAF_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_FtoF_UM_LUMA_2DArray), + "Blit11 2DArray FtoF UM LUMA 2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_LUMAALPHAF_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_FtoF_PM_LUMAALPHA_2DArray), + "Blit11 2DArray FtoF PM LUMAALPHA 2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_LUMAALPHAF_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_FtoF_UM_LUMAALPHA_2DArray), + "Blit11 2DArray FtoF UM LUMAALPHA 2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_RGBAF_4444: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_PassthroughRGBA2DArray_4444), + "Blit11 2DArray PassthroughRGBA2DArray 4444 pixel shader")); + break; + case BLITSHADER_2DARRAY_RGBAF_4444_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_FtoF_PM_RGBA_4444_2DArray), + "Blit11 2DArray FtoF PM RGBA 4444 2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_RGBAF_4444_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_FtoF_UM_RGBA_4444_2DArray), + "Blit11 2DArray FtoF UM RGBA 4444 2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_RGBF_565: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_PassthroughRGB2DArray_565), + "Blit11 2DArray PassthroughRGB2DArray 565 pixel shader")); + break; + case BLITSHADER_2DARRAY_RGBF_565_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_FtoF_PM_RGB_565_2DArray), + "Blit11 2DArray FtoF PM RGB 565 2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_RGBF_565_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_FtoF_UM_RGB_565_2DArray), + "Blit11 2DArray FtoF UM RGB 565 2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_RGBAF_5551: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_PassthroughRGBA2DArray_5551), + "Blit11 2DArray PassthroughRGBA2DArray 5551 pixel shader")); + break; + case BLITSHADER_2DARRAY_RGBAF_5551_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_FtoF_PM_RGBA_5551_2DArray), + "Blit11 2DArray FtoF PM RGBA 5551 2DArray pixel shader")); + break; + case BLITSHADER_2DARRAY_RGBAF_5551_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY, + ShaderData(g_PS_FtoF_UM_RGBA_5551_2DArray), + "Blit11 2DArray FtoF UM RGBA 5551 2DArray pixel shader")); + break; + default: + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + } + + return angle::Result::Continue; +} + diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp new file mode 100644 index 0000000000..8cc265f288 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp @@ -0,0 +1,1888 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Buffer11.cpp Defines the Buffer11 class. + +#include "libANGLE/renderer/d3d/d3d11/Buffer11.h" + +#include + +#include "common/MemoryBuffer.h" +#include "libANGLE/Context.h" +#include "libANGLE/renderer/d3d/IndexDataManager.h" +#include "libANGLE/renderer/d3d/VertexDataManager.h" +#include "libANGLE/renderer/d3d/d3d11/Context11.h" +#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" +#include "libANGLE/renderer/renderer_utils.h" + +namespace rx +{ + +namespace +{ + +template +GLuint ReadIndexValueFromIndices(const uint8_t *data, size_t index) +{ + return reinterpret_cast(data)[index]; +} +typedef GLuint (*ReadIndexValueFunction)(const uint8_t *data, size_t index); + +enum class CopyResult +{ + RECREATED, + NOT_RECREATED, +}; + +void CalculateConstantBufferParams(GLintptr offset, + GLsizeiptr size, + UINT *outFirstConstant, + UINT *outNumConstants) +{ + // The offset must be aligned to 256 bytes (should have been enforced by glBindBufferRange). + ASSERT(offset % 256 == 0); + + // firstConstant and numConstants are expressed in constants of 16-bytes. Furthermore they must + // be a multiple of 16 constants. + *outFirstConstant = static_cast(offset / 16); + + // The GL size is not required to be aligned to a 256 bytes boundary. + // Round the size up to a 256 bytes boundary then express the results in constants of 16-bytes. + *outNumConstants = static_cast(rx::roundUpPow2(size, static_cast(256)) / 16); + + // Since the size is rounded up, firstConstant + numConstants may be bigger than the actual size + // of the buffer. This behaviour is explictly allowed according to the documentation on + // ID3D11DeviceContext1::PSSetConstantBuffers1 + // https://msdn.microsoft.com/en-us/library/windows/desktop/hh404649%28v=vs.85%29.aspx +} + +} // anonymous namespace + +namespace gl_d3d11 +{ + +D3D11_MAP GetD3DMapTypeFromBits(BufferUsage usage, GLbitfield access) +{ + bool readBit = ((access & GL_MAP_READ_BIT) != 0); + bool writeBit = ((access & GL_MAP_WRITE_BIT) != 0); + + ASSERT(readBit || writeBit); + + // Note : we ignore the discard bit, because in D3D11, staging buffers + // don't accept the map-discard flag (discard only works for DYNAMIC usage) + + if (readBit && !writeBit) + { + return D3D11_MAP_READ; + } + else if (writeBit && !readBit) + { + // Special case for uniform storage - we only allow full buffer updates. + return usage == BUFFER_USAGE_UNIFORM || usage == BUFFER_USAGE_STRUCTURED + ? D3D11_MAP_WRITE_DISCARD + : D3D11_MAP_WRITE; + } + else if (writeBit && readBit) + { + return D3D11_MAP_READ_WRITE; + } + else + { + UNREACHABLE(); + return D3D11_MAP_READ; + } +} +} // namespace gl_d3d11 + +// Each instance of Buffer11::BufferStorage is specialized for a class of D3D binding points +// - vertex/transform feedback buffers +// - index buffers +// - pixel unpack buffers +// - uniform buffers +class Buffer11::BufferStorage : angle::NonCopyable +{ + public: + virtual ~BufferStorage() {} + + DataRevision getDataRevision() const { return mRevision; } + BufferUsage getUsage() const { return mUsage; } + size_t getSize() const { return mBufferSize; } + void setDataRevision(DataRevision rev) { mRevision = rev; } + + virtual bool isCPUAccessible(GLbitfield access) const = 0; + + virtual bool isGPUAccessible() const = 0; + + virtual angle::Result copyFromStorage(const gl::Context *context, + BufferStorage *source, + size_t sourceOffset, + size_t size, + size_t destOffset, + CopyResult *resultOut) = 0; + virtual angle::Result resize(const gl::Context *context, size_t size, bool preserveData) = 0; + + virtual angle::Result map(const gl::Context *context, + size_t offset, + size_t length, + GLbitfield access, + uint8_t **mapPointerOut) = 0; + virtual void unmap() = 0; + + angle::Result setData(const gl::Context *context, + const uint8_t *data, + size_t offset, + size_t size); + + void setStructureByteStride(unsigned int structureByteStride); + + protected: + BufferStorage(Renderer11 *renderer, BufferUsage usage); + + Renderer11 *mRenderer; + DataRevision mRevision; + const BufferUsage mUsage; + size_t mBufferSize; +}; + +// A native buffer storage represents an underlying D3D11 buffer for a particular +// type of storage. +class Buffer11::NativeStorage : public Buffer11::BufferStorage +{ + public: + NativeStorage(Renderer11 *renderer, BufferUsage usage, const angle::Subject *onStorageChanged); + ~NativeStorage() override; + + bool isCPUAccessible(GLbitfield access) const override; + + bool isGPUAccessible() const override { return true; } + + const d3d11::Buffer &getBuffer() const { return mBuffer; } + angle::Result copyFromStorage(const gl::Context *context, + BufferStorage *source, + size_t sourceOffset, + size_t size, + size_t destOffset, + CopyResult *resultOut) override; + angle::Result resize(const gl::Context *context, size_t size, bool preserveData) override; + + angle::Result map(const gl::Context *context, + size_t offset, + size_t length, + GLbitfield access, + uint8_t **mapPointerOut) override; + void unmap() override; + + angle::Result getSRVForFormat(const gl::Context *context, + DXGI_FORMAT srvFormat, + const d3d11::ShaderResourceView **srvOut); + angle::Result getRawUAV(const gl::Context *context, + unsigned int offset, + unsigned int size, + d3d11::UnorderedAccessView **uavOut); + + protected: + d3d11::Buffer mBuffer; + const angle::Subject *mOnStorageChanged; + + private: + static void FillBufferDesc(D3D11_BUFFER_DESC *bufferDesc, + Renderer11 *renderer, + BufferUsage usage, + unsigned int bufferSize); + void clearSRVs(); + void clearUAVs(); + + std::map mBufferResourceViews; + std::map, d3d11::UnorderedAccessView> mBufferRawUAVs; +}; + +class Buffer11::StructuredBufferStorage : public Buffer11::NativeStorage +{ + public: + StructuredBufferStorage(Renderer11 *renderer, + BufferUsage usage, + const angle::Subject *onStorageChanged); + ~StructuredBufferStorage() override; + angle::Result resizeStructuredBuffer(const gl::Context *context, + unsigned int size, + unsigned int structureByteStride); + angle::Result getStructuredBufferRangeSRV(const gl::Context *context, + unsigned int offset, + unsigned int size, + unsigned int structureByteStride, + const d3d11::ShaderResourceView **bufferOut); + + private: + d3d11::ShaderResourceView mStructuredBufferResourceView; +}; + +// A emulated indexed buffer storage represents an underlying D3D11 buffer for data +// that has been expanded to match the indices list used. This storage is only +// used for FL9_3 pointsprite rendering emulation. +class Buffer11::EmulatedIndexedStorage : public Buffer11::BufferStorage +{ + public: + EmulatedIndexedStorage(Renderer11 *renderer); + ~EmulatedIndexedStorage() override; + + bool isCPUAccessible(GLbitfield access) const override { return true; } + + bool isGPUAccessible() const override { return false; } + + angle::Result getBuffer(const gl::Context *context, + SourceIndexData *indexInfo, + const TranslatedAttribute &attribute, + GLint startVertex, + const d3d11::Buffer **bufferOut); + + angle::Result copyFromStorage(const gl::Context *context, + BufferStorage *source, + size_t sourceOffset, + size_t size, + size_t destOffset, + CopyResult *resultOut) override; + + angle::Result resize(const gl::Context *context, size_t size, bool preserveData) override; + + angle::Result map(const gl::Context *context, + size_t offset, + size_t length, + GLbitfield access, + uint8_t **mapPointerOut) override; + void unmap() override; + + private: + d3d11::Buffer mBuffer; // contains expanded data for use by D3D + angle::MemoryBuffer mMemoryBuffer; // original data (not expanded) + angle::MemoryBuffer mIndicesMemoryBuffer; // indices data +}; + +// Pack storage represents internal storage for pack buffers. We implement pack buffers +// as CPU memory, tied to a staging texture, for asynchronous texture readback. +class Buffer11::PackStorage : public Buffer11::BufferStorage +{ + public: + explicit PackStorage(Renderer11 *renderer); + ~PackStorage() override; + + bool isCPUAccessible(GLbitfield access) const override { return true; } + + bool isGPUAccessible() const override { return false; } + + angle::Result copyFromStorage(const gl::Context *context, + BufferStorage *source, + size_t sourceOffset, + size_t size, + size_t destOffset, + CopyResult *resultOut) override; + angle::Result resize(const gl::Context *context, size_t size, bool preserveData) override; + + angle::Result map(const gl::Context *context, + size_t offset, + size_t length, + GLbitfield access, + uint8_t **mapPointerOut) override; + void unmap() override; + + angle::Result packPixels(const gl::Context *context, + const gl::FramebufferAttachment &readAttachment, + const PackPixelsParams ¶ms); + + private: + angle::Result flushQueuedPackCommand(const gl::Context *context); + + TextureHelper11 mStagingTexture; + angle::MemoryBuffer mMemoryBuffer; + std::unique_ptr mQueuedPackCommand; + PackPixelsParams mPackParams; + bool mDataModified; +}; + +// System memory storage stores a CPU memory buffer with our buffer data. +// For dynamic data, it's much faster to update the CPU memory buffer than +// it is to update a D3D staging buffer and read it back later. +class Buffer11::SystemMemoryStorage : public Buffer11::BufferStorage +{ + public: + explicit SystemMemoryStorage(Renderer11 *renderer); + ~SystemMemoryStorage() override {} + + bool isCPUAccessible(GLbitfield access) const override { return true; } + + bool isGPUAccessible() const override { return false; } + + angle::Result copyFromStorage(const gl::Context *context, + BufferStorage *source, + size_t sourceOffset, + size_t size, + size_t destOffset, + CopyResult *resultOut) override; + angle::Result resize(const gl::Context *context, size_t size, bool preserveData) override; + + angle::Result map(const gl::Context *context, + size_t offset, + size_t length, + GLbitfield access, + uint8_t **mapPointerOut) override; + void unmap() override; + + angle::MemoryBuffer *getSystemCopy() { return &mSystemCopy; } + + protected: + angle::MemoryBuffer mSystemCopy; +}; + +Buffer11::Buffer11(const gl::BufferState &state, Renderer11 *renderer) + : BufferD3D(state, renderer), + mRenderer(renderer), + mSize(0), + mMappedStorage(nullptr), + mBufferStorages({}), + mLatestBufferStorage(nullptr), + mDeallocThresholds({}), + mIdleness({}), + mConstantBufferStorageAdditionalSize(0), + mMaxConstantBufferLruCount(0), + mStructuredBufferStorageAdditionalSize(0), + mMaxStructuredBufferLruCount(0) +{} + +Buffer11::~Buffer11() +{ + for (BufferStorage *&storage : mBufferStorages) + { + SafeDelete(storage); + } + + for (auto &p : mConstantBufferRangeStoragesCache) + { + SafeDelete(p.second.storage); + } + + for (auto &p : mStructuredBufferRangeStoragesCache) + { + SafeDelete(p.second.storage); + } + + mRenderer->onBufferDelete(this); +} + +angle::Result Buffer11::setData(const gl::Context *context, + gl::BufferBinding target, + const void *data, + size_t size, + gl::BufferUsage usage) +{ + updateD3DBufferUsage(context, usage); + return setSubData(context, target, data, size, 0); +} + +angle::Result Buffer11::getData(const gl::Context *context, const uint8_t **outData) +{ + if (mSize == 0) + { + // TODO(http://anglebug.com/2840): This ensures that we don't crash or assert in robust + // buffer access behavior mode if there are buffers without any data. However, technically + // it should still be possible to draw, with fetches from this buffer returning zero. + return angle::Result::Stop; + } + + SystemMemoryStorage *systemMemoryStorage = nullptr; + ANGLE_TRY(getBufferStorage(context, BUFFER_USAGE_SYSTEM_MEMORY, &systemMemoryStorage)); + + ASSERT(systemMemoryStorage->getSize() >= mSize); + + *outData = systemMemoryStorage->getSystemCopy()->data(); + return angle::Result::Continue; +} + +angle::Result Buffer11::setSubData(const gl::Context *context, + gl::BufferBinding target, + const void *data, + size_t size, + size_t offset) +{ + size_t requiredSize = size + offset; + + if (data && size > 0) + { + // Use system memory storage for dynamic buffers. + // Try using a constant storage for constant buffers + BufferStorage *writeBuffer = nullptr; + if (target == gl::BufferBinding::Uniform) + { + // If we are a very large uniform buffer, keep system memory storage around so that we + // aren't forced to read back from a constant buffer. We also check the workaround for + // Intel - this requires us to use system memory so we don't end up having to copy from + // a constant buffer to a staging buffer. + // TODO(jmadill): Use Context caps. + if (offset == 0 && size >= mSize && + size <= static_cast(mRenderer->getNativeCaps().maxUniformBlockSize) && + !mRenderer->getFeatures().useSystemMemoryForConstantBuffers.enabled) + { + BufferStorage *latestStorage = nullptr; + ANGLE_TRY(getLatestBufferStorage(context, &latestStorage)); + if (latestStorage && (latestStorage->getUsage() == BUFFER_USAGE_STRUCTURED)) + { + ANGLE_TRY(getBufferStorage(context, BUFFER_USAGE_STRUCTURED, &writeBuffer)); + } + else + { + ANGLE_TRY(getBufferStorage(context, BUFFER_USAGE_UNIFORM, &writeBuffer)); + } + } + else + { + ANGLE_TRY(getBufferStorage(context, BUFFER_USAGE_SYSTEM_MEMORY, &writeBuffer)); + } + } + else if (supportsDirectBinding()) + { + ANGLE_TRY(getStagingStorage(context, &writeBuffer)); + } + else + { + ANGLE_TRY(getBufferStorage(context, BUFFER_USAGE_SYSTEM_MEMORY, &writeBuffer)); + } + + ASSERT(writeBuffer); + + // Explicitly resize the staging buffer, preserving data if the new data will not + // completely fill the buffer + if (writeBuffer->getSize() < requiredSize) + { + bool preserveData = (offset > 0); + ANGLE_TRY(writeBuffer->resize(context, requiredSize, preserveData)); + } + + ANGLE_TRY(writeBuffer->setData(context, static_cast(data), offset, size)); + onStorageUpdate(writeBuffer); + } + + mSize = std::max(mSize, requiredSize); + invalidateStaticData(context); + + return angle::Result::Continue; +} + +angle::Result Buffer11::copySubData(const gl::Context *context, + BufferImpl *source, + GLintptr sourceOffset, + GLintptr destOffset, + GLsizeiptr size) +{ + Buffer11 *sourceBuffer = GetAs(source); + ASSERT(sourceBuffer != nullptr); + + BufferStorage *copyDest = nullptr; + ANGLE_TRY(getLatestBufferStorage(context, ©Dest)); + + if (!copyDest) + { + ANGLE_TRY(getStagingStorage(context, ©Dest)); + } + + BufferStorage *copySource = nullptr; + ANGLE_TRY(sourceBuffer->getLatestBufferStorage(context, ©Source)); + + if (!copySource) + { + ANGLE_TRY(sourceBuffer->getStagingStorage(context, ©Source)); + } + + ASSERT(copySource && copyDest); + + // A staging buffer is needed if there is no cpu-cpu or gpu-gpu copy path avaiable. + if (!copyDest->isGPUAccessible() && !copySource->isCPUAccessible(GL_MAP_READ_BIT)) + { + ANGLE_TRY(sourceBuffer->getStagingStorage(context, ©Source)); + } + else if (!copySource->isGPUAccessible() && !copyDest->isCPUAccessible(GL_MAP_WRITE_BIT)) + { + ANGLE_TRY(getStagingStorage(context, ©Dest)); + } + + // D3D11 does not allow overlapped copies until 11.1, and only if the + // device supports D3D11_FEATURE_DATA_D3D11_OPTIONS::CopyWithOverlap + // Get around this via a different source buffer + if (copySource == copyDest) + { + if (copySource->getUsage() == BUFFER_USAGE_STAGING) + { + ANGLE_TRY( + getBufferStorage(context, BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK, ©Source)); + } + else + { + ANGLE_TRY(getStagingStorage(context, ©Source)); + } + } + + CopyResult copyResult = CopyResult::NOT_RECREATED; + ANGLE_TRY(copyDest->copyFromStorage(context, copySource, sourceOffset, size, destOffset, + ©Result)); + onStorageUpdate(copyDest); + + mSize = std::max(mSize, destOffset + size); + invalidateStaticData(context); + + return angle::Result::Continue; +} + +angle::Result Buffer11::map(const gl::Context *context, GLenum access, void **mapPtr) +{ + // GL_OES_mapbuffer uses an enum instead of a bitfield for it's access, convert to a bitfield + // and call mapRange. + ASSERT(access == GL_WRITE_ONLY_OES); + return mapRange(context, 0, mSize, GL_MAP_WRITE_BIT, mapPtr); +} + +angle::Result Buffer11::mapRange(const gl::Context *context, + size_t offset, + size_t length, + GLbitfield access, + void **mapPtr) +{ + ASSERT(!mMappedStorage); + + BufferStorage *latestStorage = nullptr; + ANGLE_TRY(getLatestBufferStorage(context, &latestStorage)); + + if (latestStorage && (latestStorage->getUsage() == BUFFER_USAGE_PIXEL_PACK || + latestStorage->getUsage() == BUFFER_USAGE_STAGING)) + { + // Latest storage is mappable. + mMappedStorage = latestStorage; + } + else + { + // Fall back to using the staging buffer if the latest storage does not exist or is not + // CPU-accessible. + ANGLE_TRY(getStagingStorage(context, &mMappedStorage)); + } + + Context11 *context11 = GetImplAs(context); + ANGLE_CHECK_GL_ALLOC(context11, mMappedStorage); + + if ((access & GL_MAP_WRITE_BIT) > 0) + { + // Update the data revision immediately, since the data might be changed at any time + onStorageUpdate(mMappedStorage); + invalidateStaticData(context); + } + + uint8_t *mappedBuffer = nullptr; + ANGLE_TRY(mMappedStorage->map(context, offset, length, access, &mappedBuffer)); + ASSERT(mappedBuffer); + + *mapPtr = static_cast(mappedBuffer); + return angle::Result::Continue; +} + +angle::Result Buffer11::unmap(const gl::Context *context, GLboolean *result) +{ + ASSERT(mMappedStorage); + mMappedStorage->unmap(); + mMappedStorage = nullptr; + + // TODO: detect if we had corruption. if so, return false. + *result = GL_TRUE; + + return angle::Result::Continue; +} + +angle::Result Buffer11::markTransformFeedbackUsage(const gl::Context *context) +{ + ANGLE_TRY(markBufferUsage(context, BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK)); + return angle::Result::Continue; +} + +void Buffer11::updateDeallocThreshold(BufferUsage usage) +{ + // The following strategy was tuned on the Oort online benchmark (http://oortonline.gl/) + // as well as a custom microbenchmark (IndexConversionPerfTest.Run/index_range_d3d11) + + // First readback: 8 unmodified uses before we free buffer memory. + // After that, double the threshold each time until we reach the max. + if (mDeallocThresholds[usage] == 0) + { + mDeallocThresholds[usage] = 8; + } + else if (mDeallocThresholds[usage] < std::numeric_limits::max() / 2u) + { + mDeallocThresholds[usage] *= 2u; + } + else + { + mDeallocThresholds[usage] = std::numeric_limits::max(); + } +} + +// Free the storage if we decide it isn't being used very often. +angle::Result Buffer11::checkForDeallocation(const gl::Context *context, BufferUsage usage) +{ + mIdleness[usage]++; + + BufferStorage *&storage = mBufferStorages[usage]; + if (storage != nullptr && mIdleness[usage] > mDeallocThresholds[usage]) + { + BufferStorage *latestStorage = nullptr; + ANGLE_TRY(getLatestBufferStorage(context, &latestStorage)); + if (latestStorage != storage) + { + SafeDelete(storage); + } + } + + return angle::Result::Continue; +} + +// Keep system memory when we are using it for the canonical version of data. +bool Buffer11::canDeallocateSystemMemory() const +{ + // Must keep system memory on Intel. + if (mRenderer->getFeatures().useSystemMemoryForConstantBuffers.enabled) + { + return false; + } + + return (!mBufferStorages[BUFFER_USAGE_UNIFORM] || + mSize <= static_cast(mRenderer->getNativeCaps().maxUniformBlockSize)); +} + +void Buffer11::markBufferUsage(BufferUsage usage) +{ + mIdleness[usage] = 0; +} + +angle::Result Buffer11::markBufferUsage(const gl::Context *context, BufferUsage usage) +{ + BufferStorage *bufferStorage = nullptr; + ANGLE_TRY(getBufferStorage(context, usage, &bufferStorage)); + + if (bufferStorage) + { + onStorageUpdate(bufferStorage); + } + + invalidateStaticData(context); + return angle::Result::Continue; +} + +angle::Result Buffer11::garbageCollection(const gl::Context *context, BufferUsage currentUsage) +{ + if (currentUsage != BUFFER_USAGE_SYSTEM_MEMORY && canDeallocateSystemMemory()) + { + ANGLE_TRY(checkForDeallocation(context, BUFFER_USAGE_SYSTEM_MEMORY)); + } + + if (currentUsage != BUFFER_USAGE_STAGING) + { + ANGLE_TRY(checkForDeallocation(context, BUFFER_USAGE_STAGING)); + } + + return angle::Result::Continue; +} + +angle::Result Buffer11::getBuffer(const gl::Context *context, + BufferUsage usage, + ID3D11Buffer **bufferOut) +{ + NativeStorage *storage = nullptr; + ANGLE_TRY(getBufferStorage(context, usage, &storage)); + *bufferOut = storage->getBuffer().get(); + return angle::Result::Continue; +} + +angle::Result Buffer11::getEmulatedIndexedBuffer(const gl::Context *context, + SourceIndexData *indexInfo, + const TranslatedAttribute &attribute, + GLint startVertex, + ID3D11Buffer **bufferOut) +{ + ASSERT(indexInfo); + + EmulatedIndexedStorage *emulatedStorage = nullptr; + ANGLE_TRY(getBufferStorage(context, BUFFER_USAGE_EMULATED_INDEXED_VERTEX, &emulatedStorage)); + + const d3d11::Buffer *nativeBuffer = nullptr; + ANGLE_TRY( + emulatedStorage->getBuffer(context, indexInfo, attribute, startVertex, &nativeBuffer)); + *bufferOut = nativeBuffer->get(); + return angle::Result::Continue; +} + +angle::Result Buffer11::getConstantBufferRange(const gl::Context *context, + GLintptr offset, + GLsizeiptr size, + const d3d11::Buffer **bufferOut, + UINT *firstConstantOut, + UINT *numConstantsOut) +{ + NativeStorage *bufferStorage = nullptr; + if ((offset == 0 && + size < static_cast(mRenderer->getNativeCaps().maxUniformBlockSize)) || + mRenderer->getRenderer11DeviceCaps().supportsConstantBufferOffsets) + { + ANGLE_TRY(getBufferStorage(context, BUFFER_USAGE_UNIFORM, &bufferStorage)); + CalculateConstantBufferParams(offset, size, firstConstantOut, numConstantsOut); + } + else + { + ANGLE_TRY(getConstantBufferRangeStorage(context, offset, size, &bufferStorage)); + *firstConstantOut = 0; + *numConstantsOut = 0; + } + + *bufferOut = &bufferStorage->getBuffer(); + return angle::Result::Continue; +} + +angle::Result Buffer11::markRawBufferUsage(const gl::Context *context) +{ + ANGLE_TRY(markBufferUsage(context, BUFFER_USAGE_RAW_UAV)); + return angle::Result::Continue; +} + +angle::Result Buffer11::markTypedBufferUsage(const gl::Context *context) +{ + ANGLE_TRY(markBufferUsage(context, BUFFER_USAGE_TYPED_UAV)); + return angle::Result::Continue; +} + +angle::Result Buffer11::getRawUAVRange(const gl::Context *context, + GLintptr offset, + GLsizeiptr size, + d3d11::UnorderedAccessView **uavOut) +{ + NativeStorage *nativeStorage = nullptr; + ANGLE_TRY(getBufferStorage(context, BUFFER_USAGE_RAW_UAV, &nativeStorage)); + + return nativeStorage->getRawUAV(context, static_cast(offset), + static_cast(size), uavOut); +} + +angle::Result Buffer11::getSRV(const gl::Context *context, + DXGI_FORMAT srvFormat, + const d3d11::ShaderResourceView **srvOut) +{ + NativeStorage *nativeStorage = nullptr; + ANGLE_TRY(getBufferStorage(context, BUFFER_USAGE_PIXEL_UNPACK, &nativeStorage)); + return nativeStorage->getSRVForFormat(context, srvFormat, srvOut); +} + +angle::Result Buffer11::packPixels(const gl::Context *context, + const gl::FramebufferAttachment &readAttachment, + const PackPixelsParams ¶ms) +{ + PackStorage *packStorage = nullptr; + ANGLE_TRY(getBufferStorage(context, BUFFER_USAGE_PIXEL_PACK, &packStorage)); + + ASSERT(packStorage); + ANGLE_TRY(packStorage->packPixels(context, readAttachment, params)); + onStorageUpdate(packStorage); + + return angle::Result::Continue; +} + +size_t Buffer11::getTotalCPUBufferMemoryBytes() const +{ + size_t allocationSize = 0; + + BufferStorage *staging = mBufferStorages[BUFFER_USAGE_STAGING]; + allocationSize += staging ? staging->getSize() : 0; + + BufferStorage *sysMem = mBufferStorages[BUFFER_USAGE_SYSTEM_MEMORY]; + allocationSize += sysMem ? sysMem->getSize() : 0; + + return allocationSize; +} + +template +angle::Result Buffer11::getBufferStorage(const gl::Context *context, + BufferUsage usage, + StorageOutT **storageOut) +{ + ASSERT(0 <= usage && usage < BUFFER_USAGE_COUNT); + BufferStorage *&newStorage = mBufferStorages[usage]; + + if (!newStorage) + { + newStorage = allocateStorage(usage); + } + + markBufferUsage(usage); + + // resize buffer + if (newStorage->getSize() < mSize) + { + ANGLE_TRY(newStorage->resize(context, mSize, true)); + } + + ASSERT(newStorage); + + ANGLE_TRY(updateBufferStorage(context, newStorage, 0, mSize)); + ANGLE_TRY(garbageCollection(context, usage)); + + *storageOut = GetAs(newStorage); + return angle::Result::Continue; +} + +Buffer11::BufferStorage *Buffer11::allocateStorage(BufferUsage usage) +{ + updateDeallocThreshold(usage); + switch (usage) + { + case BUFFER_USAGE_PIXEL_PACK: + return new PackStorage(mRenderer); + case BUFFER_USAGE_SYSTEM_MEMORY: + return new SystemMemoryStorage(mRenderer); + case BUFFER_USAGE_EMULATED_INDEXED_VERTEX: + return new EmulatedIndexedStorage(mRenderer); + case BUFFER_USAGE_INDEX: + case BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK: + return new NativeStorage(mRenderer, usage, this); + case BUFFER_USAGE_STRUCTURED: + return new StructuredBufferStorage(mRenderer, usage, nullptr); + default: + return new NativeStorage(mRenderer, usage, nullptr); + } +} + +angle::Result Buffer11::getConstantBufferRangeStorage(const gl::Context *context, + GLintptr offset, + GLsizeiptr size, + Buffer11::NativeStorage **storageOut) +{ + BufferStorage *newStorage; + { + // Keep the cacheEntry in a limited scope because it may be invalidated later in the code if + // we need to reclaim some space. + BufferCacheEntry *cacheEntry = &mConstantBufferRangeStoragesCache[offset]; + + if (!cacheEntry->storage) + { + cacheEntry->storage = allocateStorage(BUFFER_USAGE_UNIFORM); + cacheEntry->lruCount = ++mMaxConstantBufferLruCount; + } + + cacheEntry->lruCount = ++mMaxConstantBufferLruCount; + newStorage = cacheEntry->storage; + } + + markBufferUsage(BUFFER_USAGE_UNIFORM); + + if (newStorage->getSize() < static_cast(size)) + { + size_t maximumAllowedAdditionalSize = 2 * getSize(); + + size_t sizeDelta = size - newStorage->getSize(); + + while (mConstantBufferStorageAdditionalSize + sizeDelta > maximumAllowedAdditionalSize) + { + auto iter = std::min_element( + std::begin(mConstantBufferRangeStoragesCache), + std::end(mConstantBufferRangeStoragesCache), + [](const BufferCache::value_type &a, const BufferCache::value_type &b) { + return a.second.lruCount < b.second.lruCount; + }); + + ASSERT(iter->second.storage != newStorage); + ASSERT(mConstantBufferStorageAdditionalSize >= iter->second.storage->getSize()); + + mConstantBufferStorageAdditionalSize -= iter->second.storage->getSize(); + SafeDelete(iter->second.storage); + mConstantBufferRangeStoragesCache.erase(iter); + } + + ANGLE_TRY(newStorage->resize(context, size, false)); + mConstantBufferStorageAdditionalSize += sizeDelta; + + // We don't copy the old data when resizing the constant buffer because the data may be + // out-of-date therefore we reset the data revision and let updateBufferStorage() handle the + // copy. + newStorage->setDataRevision(0); + } + + ANGLE_TRY(updateBufferStorage(context, newStorage, offset, size)); + ANGLE_TRY(garbageCollection(context, BUFFER_USAGE_UNIFORM)); + *storageOut = GetAs(newStorage); + return angle::Result::Continue; +} + +angle::Result Buffer11::getStructuredBufferRangeSRV(const gl::Context *context, + unsigned int offset, + unsigned int size, + unsigned int structureByteStride, + const d3d11::ShaderResourceView **srvOut) +{ + BufferStorage *newStorage; + + { + // Keep the cacheEntry in a limited scope because it may be invalidated later in the code if + // we need to reclaim some space. + StructuredBufferKey structuredBufferKey = StructuredBufferKey(offset, structureByteStride); + BufferCacheEntry *cacheEntry = &mStructuredBufferRangeStoragesCache[structuredBufferKey]; + + if (!cacheEntry->storage) + { + cacheEntry->storage = allocateStorage(BUFFER_USAGE_STRUCTURED); + cacheEntry->lruCount = ++mMaxStructuredBufferLruCount; + } + + cacheEntry->lruCount = ++mMaxStructuredBufferLruCount; + newStorage = cacheEntry->storage; + } + + StructuredBufferStorage *structuredBufferStorage = GetAs(newStorage); + + markBufferUsage(BUFFER_USAGE_STRUCTURED); + + if (newStorage->getSize() < static_cast(size)) + { + size_t maximumAllowedAdditionalSize = 2 * getSize(); + + size_t sizeDelta = static_cast(size) - newStorage->getSize(); + + while (mStructuredBufferStorageAdditionalSize + sizeDelta > maximumAllowedAdditionalSize) + { + auto iter = std::min_element(std::begin(mStructuredBufferRangeStoragesCache), + std::end(mStructuredBufferRangeStoragesCache), + [](const StructuredBufferCache::value_type &a, + const StructuredBufferCache::value_type &b) { + return a.second.lruCount < b.second.lruCount; + }); + + ASSERT(iter->second.storage != newStorage); + ASSERT(mStructuredBufferStorageAdditionalSize >= iter->second.storage->getSize()); + + mStructuredBufferStorageAdditionalSize -= iter->second.storage->getSize(); + SafeDelete(iter->second.storage); + mStructuredBufferRangeStoragesCache.erase(iter); + } + + ANGLE_TRY( + structuredBufferStorage->resizeStructuredBuffer(context, size, structureByteStride)); + mStructuredBufferStorageAdditionalSize += sizeDelta; + + // We don't copy the old data when resizing the structured buffer because the data may be + // out-of-date therefore we reset the data revision and let updateBufferStorage() handle the + // copy. + newStorage->setDataRevision(0); + } + + ANGLE_TRY(updateBufferStorage(context, newStorage, offset, static_cast(size))); + ANGLE_TRY(garbageCollection(context, BUFFER_USAGE_STRUCTURED)); + ANGLE_TRY(structuredBufferStorage->getStructuredBufferRangeSRV(context, offset, size, + structureByteStride, srvOut)); + return angle::Result::Continue; +} + +angle::Result Buffer11::updateBufferStorage(const gl::Context *context, + BufferStorage *storage, + size_t sourceOffset, + size_t storageSize) +{ + BufferStorage *latestBuffer = nullptr; + ANGLE_TRY(getLatestBufferStorage(context, &latestBuffer)); + + ASSERT(storage); + + if (!latestBuffer) + { + onStorageUpdate(storage); + return angle::Result::Continue; + } + + if (latestBuffer->getDataRevision() <= storage->getDataRevision()) + { + return angle::Result::Continue; + } + + if (latestBuffer->getSize() == 0 || storage->getSize() == 0) + { + return angle::Result::Continue; + } + + // Copy through a staging buffer if we're copying from or to a non-staging, mappable + // buffer storage. This is because we can't map a GPU buffer, and copy CPU + // data directly. If we're already using a staging buffer we're fine. + if (latestBuffer->getUsage() != BUFFER_USAGE_STAGING && + storage->getUsage() != BUFFER_USAGE_STAGING && + (!latestBuffer->isCPUAccessible(GL_MAP_READ_BIT) || + !storage->isCPUAccessible(GL_MAP_WRITE_BIT))) + { + NativeStorage *stagingBuffer = nullptr; + ANGLE_TRY(getStagingStorage(context, &stagingBuffer)); + + CopyResult copyResult = CopyResult::NOT_RECREATED; + ANGLE_TRY(stagingBuffer->copyFromStorage(context, latestBuffer, 0, latestBuffer->getSize(), + 0, ©Result)); + onCopyStorage(stagingBuffer, latestBuffer); + + latestBuffer = stagingBuffer; + } + + CopyResult copyResult = CopyResult::NOT_RECREATED; + ANGLE_TRY( + storage->copyFromStorage(context, latestBuffer, sourceOffset, storageSize, 0, ©Result)); + // If the D3D buffer has been recreated, we should update our serial. + if (copyResult == CopyResult::RECREATED) + { + updateSerial(); + } + onCopyStorage(storage, latestBuffer); + return angle::Result::Continue; +} + +angle::Result Buffer11::getLatestBufferStorage(const gl::Context *context, + Buffer11::BufferStorage **storageOut) const +{ + // resize buffer + if (mLatestBufferStorage && mLatestBufferStorage->getSize() < mSize) + { + ANGLE_TRY(mLatestBufferStorage->resize(context, mSize, true)); + } + + *storageOut = mLatestBufferStorage; + return angle::Result::Continue; +} + +template +angle::Result Buffer11::getStagingStorage(const gl::Context *context, StorageOutT **storageOut) +{ + return getBufferStorage(context, BUFFER_USAGE_STAGING, storageOut); +} + +size_t Buffer11::getSize() const +{ + return mSize; +} + +bool Buffer11::supportsDirectBinding() const +{ + // Do not support direct buffers for dynamic data. The streaming buffer + // offers better performance for data which changes every frame. + return (mUsage == D3DBufferUsage::STATIC); +} + +void Buffer11::initializeStaticData(const gl::Context *context) +{ + BufferD3D::initializeStaticData(context); + onStateChange(angle::SubjectMessage::SubjectChanged); +} + +void Buffer11::invalidateStaticData(const gl::Context *context) +{ + BufferD3D::invalidateStaticData(context); + onStateChange(angle::SubjectMessage::SubjectChanged); +} + +void Buffer11::onCopyStorage(BufferStorage *dest, BufferStorage *source) +{ + ASSERT(source && mLatestBufferStorage); + dest->setDataRevision(source->getDataRevision()); + + // Only update the latest buffer storage if our usage index is lower. See comment in header. + if (dest->getUsage() < mLatestBufferStorage->getUsage()) + { + mLatestBufferStorage = dest; + } +} + +void Buffer11::onStorageUpdate(BufferStorage *updatedStorage) +{ + updatedStorage->setDataRevision(updatedStorage->getDataRevision() + 1); + mLatestBufferStorage = updatedStorage; +} + +// Buffer11::BufferStorage implementation + +Buffer11::BufferStorage::BufferStorage(Renderer11 *renderer, BufferUsage usage) + : mRenderer(renderer), mRevision(0), mUsage(usage), mBufferSize(0) +{} + +angle::Result Buffer11::BufferStorage::setData(const gl::Context *context, + const uint8_t *data, + size_t offset, + size_t size) +{ + ASSERT(isCPUAccessible(GL_MAP_WRITE_BIT)); + + // Uniform storage can have a different internal size than the buffer size. Ensure we don't + // overflow. + size_t mapSize = std::min(size, mBufferSize - offset); + + uint8_t *writePointer = nullptr; + ANGLE_TRY(map(context, offset, mapSize, GL_MAP_WRITE_BIT, &writePointer)); + + memcpy(writePointer, data, mapSize); + + unmap(); + + return angle::Result::Continue; +} + +// Buffer11::NativeStorage implementation + +Buffer11::NativeStorage::NativeStorage(Renderer11 *renderer, + BufferUsage usage, + const angle::Subject *onStorageChanged) + : BufferStorage(renderer, usage), mBuffer(), mOnStorageChanged(onStorageChanged) +{} + +Buffer11::NativeStorage::~NativeStorage() +{ + clearSRVs(); + clearUAVs(); +} + +bool Buffer11::NativeStorage::isCPUAccessible(GLbitfield access) const +{ + if ((access & GL_MAP_READ_BIT) != 0) + { + // Read is more exclusive than write mappability. + return (mUsage == BUFFER_USAGE_STAGING); + } + ASSERT((access & GL_MAP_WRITE_BIT) != 0); + return (mUsage == BUFFER_USAGE_STAGING || mUsage == BUFFER_USAGE_UNIFORM || + mUsage == BUFFER_USAGE_STRUCTURED); +} + +// Returns true if it recreates the direct buffer +angle::Result Buffer11::NativeStorage::copyFromStorage(const gl::Context *context, + BufferStorage *source, + size_t sourceOffset, + size_t size, + size_t destOffset, + CopyResult *resultOut) +{ + size_t requiredSize = destOffset + size; + + // (Re)initialize D3D buffer if needed + bool preserveData = (destOffset > 0); + if (!mBuffer.valid() || mBufferSize < requiredSize) + { + ANGLE_TRY(resize(context, requiredSize, preserveData)); + *resultOut = CopyResult::RECREATED; + } + else + { + *resultOut = CopyResult::NOT_RECREATED; + } + + size_t clampedSize = size; + if (mUsage == BUFFER_USAGE_UNIFORM) + { + clampedSize = std::min(clampedSize, mBufferSize - destOffset); + } + + if (clampedSize == 0) + { + return angle::Result::Continue; + } + + if (source->getUsage() == BUFFER_USAGE_PIXEL_PACK || + source->getUsage() == BUFFER_USAGE_SYSTEM_MEMORY) + { + ASSERT(source->isCPUAccessible(GL_MAP_READ_BIT) && isCPUAccessible(GL_MAP_WRITE_BIT)); + + // Uniform buffers must be mapped with write/discard. + ASSERT(!(preserveData && mUsage == BUFFER_USAGE_UNIFORM)); + + uint8_t *sourcePointer = nullptr; + ANGLE_TRY(source->map(context, sourceOffset, clampedSize, GL_MAP_READ_BIT, &sourcePointer)); + + auto err = setData(context, sourcePointer, destOffset, clampedSize); + source->unmap(); + ANGLE_TRY(err); + } + else + { + D3D11_BOX srcBox; + srcBox.left = static_cast(sourceOffset); + srcBox.right = static_cast(sourceOffset + clampedSize); + srcBox.top = 0; + srcBox.bottom = 1; + srcBox.front = 0; + srcBox.back = 1; + + const d3d11::Buffer *sourceBuffer = &GetAs(source)->getBuffer(); + + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + deviceContext->CopySubresourceRegion(mBuffer.get(), 0, + static_cast(destOffset), 0, 0, + sourceBuffer->get(), 0, &srcBox); + } + + return angle::Result::Continue; +} + +angle::Result Buffer11::NativeStorage::resize(const gl::Context *context, + size_t size, + bool preserveData) +{ + if (size == 0) + { + mBuffer.reset(); + mBufferSize = 0; + return angle::Result::Continue; + } + + D3D11_BUFFER_DESC bufferDesc; + FillBufferDesc(&bufferDesc, mRenderer, mUsage, static_cast(size)); + + d3d11::Buffer newBuffer; + ANGLE_TRY( + mRenderer->allocateResource(SafeGetImplAs(context), bufferDesc, &newBuffer)); + newBuffer.setInternalName("Buffer11::NativeStorage"); + + if (mBuffer.valid() && preserveData) + { + // We don't call resize if the buffer is big enough already. + ASSERT(mBufferSize <= size); + + D3D11_BOX srcBox; + srcBox.left = 0; + srcBox.right = static_cast(mBufferSize); + srcBox.top = 0; + srcBox.bottom = 1; + srcBox.front = 0; + srcBox.back = 1; + + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + deviceContext->CopySubresourceRegion(newBuffer.get(), 0, 0, 0, 0, mBuffer.get(), 0, + &srcBox); + } + + // No longer need the old buffer + mBuffer = std::move(newBuffer); + + mBufferSize = bufferDesc.ByteWidth; + + // Free the SRVs. + clearSRVs(); + + // Free the UAVs. + clearUAVs(); + + // Notify that the storage has changed. + if (mOnStorageChanged) + { + mOnStorageChanged->onStateChange(angle::SubjectMessage::SubjectChanged); + } + + return angle::Result::Continue; +} + +// static +void Buffer11::NativeStorage::FillBufferDesc(D3D11_BUFFER_DESC *bufferDesc, + Renderer11 *renderer, + BufferUsage usage, + unsigned int bufferSize) +{ + bufferDesc->ByteWidth = bufferSize; + bufferDesc->MiscFlags = 0; + bufferDesc->StructureByteStride = 0; + + switch (usage) + { + case BUFFER_USAGE_STAGING: + bufferDesc->Usage = D3D11_USAGE_STAGING; + bufferDesc->BindFlags = 0; + bufferDesc->CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; + break; + + case BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK: + bufferDesc->Usage = D3D11_USAGE_DEFAULT; + bufferDesc->BindFlags = D3D11_BIND_VERTEX_BUFFER; + + if (renderer->isES3Capable()) + { + bufferDesc->BindFlags |= D3D11_BIND_STREAM_OUTPUT; + } + + bufferDesc->CPUAccessFlags = 0; + break; + + case BUFFER_USAGE_INDEX: + bufferDesc->Usage = D3D11_USAGE_DEFAULT; + bufferDesc->BindFlags = D3D11_BIND_INDEX_BUFFER; + bufferDesc->CPUAccessFlags = 0; + break; + + case BUFFER_USAGE_INDIRECT: + bufferDesc->MiscFlags = D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS; + bufferDesc->Usage = D3D11_USAGE_DEFAULT; + bufferDesc->BindFlags = 0; + bufferDesc->CPUAccessFlags = 0; + break; + + case BUFFER_USAGE_PIXEL_UNPACK: + bufferDesc->Usage = D3D11_USAGE_DEFAULT; + bufferDesc->BindFlags = D3D11_BIND_SHADER_RESOURCE; + bufferDesc->CPUAccessFlags = 0; + break; + + case BUFFER_USAGE_UNIFORM: + bufferDesc->Usage = D3D11_USAGE_DYNAMIC; + bufferDesc->BindFlags = D3D11_BIND_CONSTANT_BUFFER; + bufferDesc->CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + + // Constant buffers must be of a limited size, and aligned to 16 byte boundaries + // For our purposes we ignore any buffer data past the maximum constant buffer size + bufferDesc->ByteWidth = roundUpPow2(bufferDesc->ByteWidth, 16u); + + // Note: it seems that D3D11 allows larger buffers on some platforms, but not all. + // (Windows 10 seems to allow larger constant buffers, but not Windows 7) + if (!renderer->getRenderer11DeviceCaps().supportsConstantBufferOffsets) + { + bufferDesc->ByteWidth = std::min( + bufferDesc->ByteWidth, + static_cast(renderer->getNativeCaps().maxUniformBlockSize)); + } + break; + + case BUFFER_USAGE_RAW_UAV: + bufferDesc->MiscFlags = D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS; + bufferDesc->BindFlags = D3D11_BIND_UNORDERED_ACCESS; + bufferDesc->Usage = D3D11_USAGE_DEFAULT; + bufferDesc->CPUAccessFlags = 0; + break; + case BUFFER_USAGE_TYPED_UAV: + bufferDesc->BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE; + bufferDesc->Usage = D3D11_USAGE_DEFAULT; + bufferDesc->CPUAccessFlags = 0; + bufferDesc->MiscFlags = 0; + break; + + default: + UNREACHABLE(); + } +} + +angle::Result Buffer11::NativeStorage::map(const gl::Context *context, + size_t offset, + size_t length, + GLbitfield access, + uint8_t **mapPointerOut) +{ + ASSERT(isCPUAccessible(access)); + + D3D11_MAPPED_SUBRESOURCE mappedResource; + D3D11_MAP d3dMapType = gl_d3d11::GetD3DMapTypeFromBits(mUsage, access); + UINT d3dMapFlag = ((access & GL_MAP_UNSYNCHRONIZED_BIT) != 0 ? D3D11_MAP_FLAG_DO_NOT_WAIT : 0); + + ANGLE_TRY( + mRenderer->mapResource(context, mBuffer.get(), 0, d3dMapType, d3dMapFlag, &mappedResource)); + ASSERT(mappedResource.pData); + *mapPointerOut = static_cast(mappedResource.pData) + offset; + return angle::Result::Continue; +} + +void Buffer11::NativeStorage::unmap() +{ + ASSERT(isCPUAccessible(GL_MAP_WRITE_BIT) || isCPUAccessible(GL_MAP_READ_BIT)); + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + context->Unmap(mBuffer.get(), 0); +} + +angle::Result Buffer11::NativeStorage::getSRVForFormat(const gl::Context *context, + DXGI_FORMAT srvFormat, + const d3d11::ShaderResourceView **srvOut) +{ + auto bufferSRVIt = mBufferResourceViews.find(srvFormat); + + if (bufferSRVIt != mBufferResourceViews.end()) + { + *srvOut = &bufferSRVIt->second; + return angle::Result::Continue; + } + + const d3d11::DXGIFormatSize &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(srvFormat); + + D3D11_SHADER_RESOURCE_VIEW_DESC bufferSRVDesc; + bufferSRVDesc.Buffer.ElementOffset = 0; + bufferSRVDesc.Buffer.ElementWidth = static_cast(mBufferSize) / dxgiFormatInfo.pixelBytes; + bufferSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; + bufferSRVDesc.Format = srvFormat; + + ANGLE_TRY(mRenderer->allocateResource(GetImplAs(context), bufferSRVDesc, + mBuffer.get(), &mBufferResourceViews[srvFormat])); + + *srvOut = &mBufferResourceViews[srvFormat]; + return angle::Result::Continue; +} + +angle::Result Buffer11::NativeStorage::getRawUAV(const gl::Context *context, + unsigned int offset, + unsigned int size, + d3d11::UnorderedAccessView **uavOut) +{ + ASSERT(offset + size <= mBufferSize); + + auto bufferRawUAV = mBufferRawUAVs.find({offset, size}); + if (bufferRawUAV != mBufferRawUAVs.end()) + { + *uavOut = &bufferRawUAV->second; + return angle::Result::Continue; + } + + D3D11_UNORDERED_ACCESS_VIEW_DESC bufferUAVDesc; + + // DXGI_FORMAT_R32_TYPELESS uses 4 bytes per element + constexpr int kBytesToElement = 4; + bufferUAVDesc.Buffer.FirstElement = offset / kBytesToElement; + bufferUAVDesc.Buffer.NumElements = size / kBytesToElement; + bufferUAVDesc.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_RAW; + bufferUAVDesc.Format = DXGI_FORMAT_R32_TYPELESS; // Format must be DXGI_FORMAT_R32_TYPELESS, + // when creating Raw Unordered Access View + bufferUAVDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; + + ANGLE_TRY(mRenderer->allocateResource(GetImplAs(context), bufferUAVDesc, + mBuffer.get(), &mBufferRawUAVs[{offset, size}])); + *uavOut = &mBufferRawUAVs[{offset, size}]; + return angle::Result::Continue; +} + +void Buffer11::NativeStorage::clearSRVs() +{ + mBufferResourceViews.clear(); +} + +void Buffer11::NativeStorage::clearUAVs() +{ + mBufferRawUAVs.clear(); +} + +Buffer11::StructuredBufferStorage::StructuredBufferStorage(Renderer11 *renderer, + BufferUsage usage, + const angle::Subject *onStorageChanged) + : NativeStorage(renderer, usage, onStorageChanged), mStructuredBufferResourceView() +{} + +Buffer11::StructuredBufferStorage::~StructuredBufferStorage() +{ + mStructuredBufferResourceView.reset(); +} + +angle::Result Buffer11::StructuredBufferStorage::resizeStructuredBuffer( + const gl::Context *context, + unsigned int size, + unsigned int structureByteStride) +{ + if (size == 0) + { + mBuffer.reset(); + mBufferSize = 0; + return angle::Result::Continue; + } + + D3D11_BUFFER_DESC bufferDesc; + bufferDesc.ByteWidth = size; + bufferDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; + bufferDesc.StructureByteStride = structureByteStride; + bufferDesc.Usage = D3D11_USAGE_DYNAMIC; + bufferDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + + d3d11::Buffer newBuffer; + ANGLE_TRY( + mRenderer->allocateResource(SafeGetImplAs(context), bufferDesc, &newBuffer)); + newBuffer.setInternalName("Buffer11::StructuredBufferStorage"); + + // No longer need the old buffer + mBuffer = std::move(newBuffer); + + mBufferSize = static_cast(bufferDesc.ByteWidth); + + mStructuredBufferResourceView.reset(); + + // Notify that the storage has changed. + if (mOnStorageChanged) + { + mOnStorageChanged->onStateChange(angle::SubjectMessage::SubjectChanged); + } + + return angle::Result::Continue; +} + +angle::Result Buffer11::StructuredBufferStorage::getStructuredBufferRangeSRV( + const gl::Context *context, + unsigned int offset, + unsigned int size, + unsigned int structureByteStride, + const d3d11::ShaderResourceView **srvOut) +{ + if (mStructuredBufferResourceView.valid()) + { + *srvOut = &mStructuredBufferResourceView; + return angle::Result::Continue; + } + + D3D11_SHADER_RESOURCE_VIEW_DESC bufferSRVDesc = {}; + bufferSRVDesc.BufferEx.NumElements = structureByteStride == 0u ? 1 : size / structureByteStride; + bufferSRVDesc.BufferEx.FirstElement = 0; + bufferSRVDesc.BufferEx.Flags = 0; + bufferSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFEREX; + bufferSRVDesc.Format = DXGI_FORMAT_UNKNOWN; + + ANGLE_TRY(mRenderer->allocateResource(GetImplAs(context), bufferSRVDesc, + mBuffer.get(), &mStructuredBufferResourceView)); + + *srvOut = &mStructuredBufferResourceView; + return angle::Result::Continue; +} + +// Buffer11::EmulatedIndexStorage implementation +Buffer11::EmulatedIndexedStorage::EmulatedIndexedStorage(Renderer11 *renderer) + : BufferStorage(renderer, BUFFER_USAGE_EMULATED_INDEXED_VERTEX), mBuffer() +{} + +Buffer11::EmulatedIndexedStorage::~EmulatedIndexedStorage() {} + +angle::Result Buffer11::EmulatedIndexedStorage::getBuffer(const gl::Context *context, + SourceIndexData *indexInfo, + const TranslatedAttribute &attribute, + GLint startVertex, + const d3d11::Buffer **bufferOut) +{ + Context11 *context11 = GetImplAs(context); + + // If a change in the indices applied from the last draw call is detected, then the emulated + // indexed buffer needs to be invalidated. After invalidation, the change detected flag should + // be cleared to avoid unnecessary recreation of the buffer. + if (!mBuffer.valid() || indexInfo->srcIndicesChanged) + { + mBuffer.reset(); + + // Copy the source index data. This ensures that the lifetime of the indices pointer + // stays with this storage until the next time we invalidate. + size_t indicesDataSize = 0; + switch (indexInfo->srcIndexType) + { + case gl::DrawElementsType::UnsignedInt: + indicesDataSize = sizeof(GLuint) * indexInfo->srcCount; + break; + case gl::DrawElementsType::UnsignedShort: + indicesDataSize = sizeof(GLushort) * indexInfo->srcCount; + break; + case gl::DrawElementsType::UnsignedByte: + indicesDataSize = sizeof(GLubyte) * indexInfo->srcCount; + break; + default: + indicesDataSize = sizeof(GLushort) * indexInfo->srcCount; + break; + } + + ANGLE_CHECK_GL_ALLOC(context11, mIndicesMemoryBuffer.resize(indicesDataSize)); + + memcpy(mIndicesMemoryBuffer.data(), indexInfo->srcIndices, indicesDataSize); + + indexInfo->srcIndicesChanged = false; + } + + if (!mBuffer.valid()) + { + unsigned int offset = 0; + ANGLE_TRY(attribute.computeOffset(context, startVertex, &offset)); + + // Expand the memory storage upon request and cache the results. + unsigned int expandedDataSize = + static_cast((indexInfo->srcCount * attribute.stride) + offset); + angle::MemoryBuffer expandedData; + ANGLE_CHECK_GL_ALLOC(context11, expandedData.resize(expandedDataSize)); + + // Clear the contents of the allocated buffer + ZeroMemory(expandedData.data(), expandedDataSize); + + uint8_t *curr = expandedData.data(); + const uint8_t *ptr = static_cast(indexInfo->srcIndices); + + // Ensure that we start in the correct place for the emulated data copy operation to + // maintain offset behaviors. + curr += offset; + + ReadIndexValueFunction readIndexValue = ReadIndexValueFromIndices; + + switch (indexInfo->srcIndexType) + { + case gl::DrawElementsType::UnsignedInt: + readIndexValue = ReadIndexValueFromIndices; + break; + case gl::DrawElementsType::UnsignedShort: + readIndexValue = ReadIndexValueFromIndices; + break; + case gl::DrawElementsType::UnsignedByte: + readIndexValue = ReadIndexValueFromIndices; + break; + default: + UNREACHABLE(); + return angle::Result::Stop; + } + + // Iterate over the cached index data and copy entries indicated into the emulated buffer. + for (GLuint i = 0; i < indexInfo->srcCount; i++) + { + GLuint idx = readIndexValue(ptr, i); + memcpy(curr, mMemoryBuffer.data() + (attribute.stride * idx), attribute.stride); + curr += attribute.stride; + } + + // Finally, initialize the emulated indexed native storage object with the newly copied data + // and free the temporary buffers used. + D3D11_BUFFER_DESC bufferDesc; + bufferDesc.ByteWidth = expandedDataSize; + bufferDesc.MiscFlags = 0; + bufferDesc.StructureByteStride = 0; + bufferDesc.Usage = D3D11_USAGE_DEFAULT; + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufferDesc.CPUAccessFlags = 0; + + D3D11_SUBRESOURCE_DATA subResourceData = {expandedData.data(), 0, 0}; + + ANGLE_TRY(mRenderer->allocateResource(GetImplAs(context), bufferDesc, + &subResourceData, &mBuffer)); + mBuffer.setInternalName("Buffer11::EmulatedIndexedStorage"); + } + + *bufferOut = &mBuffer; + return angle::Result::Continue; +} + +angle::Result Buffer11::EmulatedIndexedStorage::copyFromStorage(const gl::Context *context, + BufferStorage *source, + size_t sourceOffset, + size_t size, + size_t destOffset, + CopyResult *resultOut) +{ + ASSERT(source->isCPUAccessible(GL_MAP_READ_BIT)); + uint8_t *sourceData = nullptr; + ANGLE_TRY(source->map(context, sourceOffset, size, GL_MAP_READ_BIT, &sourceData)); + ASSERT(destOffset + size <= mMemoryBuffer.size()); + memcpy(mMemoryBuffer.data() + destOffset, sourceData, size); + source->unmap(); + *resultOut = CopyResult::RECREATED; + return angle::Result::Continue; +} + +angle::Result Buffer11::EmulatedIndexedStorage::resize(const gl::Context *context, + size_t size, + bool preserveData) +{ + if (mMemoryBuffer.size() < size) + { + Context11 *context11 = GetImplAs(context); + ANGLE_CHECK_GL_ALLOC(context11, mMemoryBuffer.resize(size)); + mBufferSize = size; + } + + return angle::Result::Continue; +} + +angle::Result Buffer11::EmulatedIndexedStorage::map(const gl::Context *context, + size_t offset, + size_t length, + GLbitfield access, + uint8_t **mapPointerOut) +{ + ASSERT(!mMemoryBuffer.empty() && offset + length <= mMemoryBuffer.size()); + *mapPointerOut = mMemoryBuffer.data() + offset; + return angle::Result::Continue; +} + +void Buffer11::EmulatedIndexedStorage::unmap() +{ + // No-op +} + +// Buffer11::PackStorage implementation + +Buffer11::PackStorage::PackStorage(Renderer11 *renderer) + : BufferStorage(renderer, BUFFER_USAGE_PIXEL_PACK), mStagingTexture(), mDataModified(false) +{} + +Buffer11::PackStorage::~PackStorage() {} + +angle::Result Buffer11::PackStorage::copyFromStorage(const gl::Context *context, + BufferStorage *source, + size_t sourceOffset, + size_t size, + size_t destOffset, + CopyResult *resultOut) +{ + ANGLE_TRY(flushQueuedPackCommand(context)); + + // For all use cases of pack buffers, we must copy through a readable buffer. + ASSERT(source->isCPUAccessible(GL_MAP_READ_BIT)); + uint8_t *sourceData = nullptr; + ANGLE_TRY(source->map(context, sourceOffset, size, GL_MAP_READ_BIT, &sourceData)); + ASSERT(destOffset + size <= mMemoryBuffer.size()); + memcpy(mMemoryBuffer.data() + destOffset, sourceData, size); + source->unmap(); + *resultOut = CopyResult::NOT_RECREATED; + return angle::Result::Continue; +} + +angle::Result Buffer11::PackStorage::resize(const gl::Context *context, + size_t size, + bool preserveData) +{ + if (size != mBufferSize) + { + Context11 *context11 = GetImplAs(context); + ANGLE_CHECK_GL_ALLOC(context11, mMemoryBuffer.resize(size)); + mBufferSize = size; + } + + return angle::Result::Continue; +} + +angle::Result Buffer11::PackStorage::map(const gl::Context *context, + size_t offset, + size_t length, + GLbitfield access, + uint8_t **mapPointerOut) +{ + ASSERT(offset + length <= getSize()); + // TODO: fast path + // We might be able to optimize out one or more memcpy calls by detecting when + // and if D3D packs the staging texture memory identically to how we would fill + // the pack buffer according to the current pack state. + + ANGLE_TRY(flushQueuedPackCommand(context)); + + mDataModified = (mDataModified || (access & GL_MAP_WRITE_BIT) != 0); + + *mapPointerOut = mMemoryBuffer.data() + offset; + return angle::Result::Continue; +} + +void Buffer11::PackStorage::unmap() +{ + // No-op +} + +angle::Result Buffer11::PackStorage::packPixels(const gl::Context *context, + const gl::FramebufferAttachment &readAttachment, + const PackPixelsParams ¶ms) +{ + ANGLE_TRY(flushQueuedPackCommand(context)); + + RenderTarget11 *renderTarget = nullptr; + ANGLE_TRY(readAttachment.getRenderTarget(context, 0, &renderTarget)); + + const TextureHelper11 &srcTexture = renderTarget->getTexture(); + ASSERT(srcTexture.valid()); + unsigned int srcSubresource = renderTarget->getSubresourceIndex(); + + mQueuedPackCommand.reset(new PackPixelsParams(params)); + + gl::Extents srcTextureSize(params.area.width, params.area.height, 1); + if (!mStagingTexture.get() || mStagingTexture.getFormat() != srcTexture.getFormat() || + mStagingTexture.getExtents() != srcTextureSize) + { + ANGLE_TRY(mRenderer->createStagingTexture(context, srcTexture.getTextureType(), + srcTexture.getFormatSet(), srcTextureSize, + StagingAccess::READ, &mStagingTexture)); + } + + // ReadPixels from multisampled FBOs isn't supported in current GL + ASSERT(srcTexture.getSampleCount() <= 1); + + ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); + D3D11_BOX srcBox; + srcBox.left = params.area.x; + srcBox.right = params.area.x + params.area.width; + srcBox.top = params.area.y; + srcBox.bottom = params.area.y + params.area.height; + + // Select the correct layer from a 3D attachment + srcBox.front = 0; + if (mStagingTexture.is3D()) + { + srcBox.front = static_cast(readAttachment.layer()); + } + srcBox.back = srcBox.front + 1; + + // Asynchronous copy + immediateContext->CopySubresourceRegion(mStagingTexture.get(), 0, 0, 0, 0, srcTexture.get(), + srcSubresource, &srcBox); + + return angle::Result::Continue; +} + +angle::Result Buffer11::PackStorage::flushQueuedPackCommand(const gl::Context *context) +{ + ASSERT(mMemoryBuffer.size() > 0); + + if (mQueuedPackCommand) + { + ANGLE_TRY(mRenderer->packPixels(context, mStagingTexture, *mQueuedPackCommand, + mMemoryBuffer.data())); + mQueuedPackCommand.reset(nullptr); + } + + return angle::Result::Continue; +} + +// Buffer11::SystemMemoryStorage implementation + +Buffer11::SystemMemoryStorage::SystemMemoryStorage(Renderer11 *renderer) + : Buffer11::BufferStorage(renderer, BUFFER_USAGE_SYSTEM_MEMORY) +{} + +angle::Result Buffer11::SystemMemoryStorage::copyFromStorage(const gl::Context *context, + BufferStorage *source, + size_t sourceOffset, + size_t size, + size_t destOffset, + CopyResult *resultOut) +{ + ASSERT(source->isCPUAccessible(GL_MAP_READ_BIT)); + uint8_t *sourceData = nullptr; + ANGLE_TRY(source->map(context, sourceOffset, size, GL_MAP_READ_BIT, &sourceData)); + ASSERT(destOffset + size <= mSystemCopy.size()); + memcpy(mSystemCopy.data() + destOffset, sourceData, size); + source->unmap(); + *resultOut = CopyResult::RECREATED; + return angle::Result::Continue; +} + +angle::Result Buffer11::SystemMemoryStorage::resize(const gl::Context *context, + size_t size, + bool preserveData) +{ + if (mSystemCopy.size() < size) + { + Context11 *context11 = GetImplAs(context); + ANGLE_CHECK_GL_ALLOC(context11, mSystemCopy.resize(size)); + mBufferSize = size; + } + + return angle::Result::Continue; +} + +angle::Result Buffer11::SystemMemoryStorage::map(const gl::Context *context, + size_t offset, + size_t length, + GLbitfield access, + uint8_t **mapPointerOut) +{ + ASSERT(!mSystemCopy.empty() && offset + length <= mSystemCopy.size()); + *mapPointerOut = mSystemCopy.data() + offset; + return angle::Result::Continue; +} + +void Buffer11::SystemMemoryStorage::unmap() +{ + // No-op +} +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Buffer11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Buffer11.h new file mode 100644 index 0000000000..b24bd1a48b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Buffer11.h @@ -0,0 +1,234 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Buffer11.h: Defines the rx::Buffer11 class which implements rx::BufferImpl via rx::BufferD3D. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_BUFFER11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_BUFFER11_H_ + +#include +#include + +#include "libANGLE/angletypes.h" +#include "libANGLE/renderer/d3d/BufferD3D.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" + +namespace gl +{ +class FramebufferAttachment; +} + +namespace rx +{ +struct PackPixelsParams; +class Renderer11; +struct SourceIndexData; +struct TranslatedAttribute; + +// The order of this enum governs priority of 'getLatestBufferStorage'. +enum BufferUsage +{ + BUFFER_USAGE_SYSTEM_MEMORY, + BUFFER_USAGE_STAGING, + BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK, + BUFFER_USAGE_INDEX, + BUFFER_USAGE_INDIRECT, + BUFFER_USAGE_PIXEL_UNPACK, + BUFFER_USAGE_PIXEL_PACK, + BUFFER_USAGE_UNIFORM, + BUFFER_USAGE_STRUCTURED, + BUFFER_USAGE_EMULATED_INDEXED_VERTEX, + BUFFER_USAGE_RAW_UAV, + BUFFER_USAGE_TYPED_UAV, + + BUFFER_USAGE_COUNT, +}; + +typedef size_t DataRevision; + +class Buffer11 : public BufferD3D +{ + public: + Buffer11(const gl::BufferState &state, Renderer11 *renderer); + ~Buffer11() override; + + angle::Result getBuffer(const gl::Context *context, + BufferUsage usage, + ID3D11Buffer **bufferOut); + angle::Result getEmulatedIndexedBuffer(const gl::Context *context, + SourceIndexData *indexInfo, + const TranslatedAttribute &attribute, + GLint startVertex, + ID3D11Buffer **bufferOut); + angle::Result getConstantBufferRange(const gl::Context *context, + GLintptr offset, + GLsizeiptr size, + const d3d11::Buffer **bufferOut, + UINT *firstConstantOut, + UINT *numConstantsOut); + angle::Result getStructuredBufferRangeSRV(const gl::Context *context, + unsigned int offset, + unsigned int size, + unsigned int structureByteStride, + const d3d11::ShaderResourceView **srvOut); + angle::Result getSRV(const gl::Context *context, + DXGI_FORMAT srvFormat, + const d3d11::ShaderResourceView **srvOut); + angle::Result getRawUAVRange(const gl::Context *context, + GLintptr offset, + GLsizeiptr size, + d3d11::UnorderedAccessView **uavOut); + + angle::Result getTypedUAVRange(const gl::Context *context, + GLintptr offset, + GLsizeiptr size, + DXGI_FORMAT format, + d3d11::UnorderedAccessView **uavOut); + + angle::Result markRawBufferUsage(const gl::Context *context); + angle::Result markTypedBufferUsage(const gl::Context *context); + bool isMapped() const { return mMappedStorage != nullptr; } + angle::Result packPixels(const gl::Context *context, + const gl::FramebufferAttachment &readAttachment, + const PackPixelsParams ¶ms); + size_t getTotalCPUBufferMemoryBytes() const; + + // BufferD3D implementation + size_t getSize() const override; + bool supportsDirectBinding() const override; + angle::Result getData(const gl::Context *context, const uint8_t **outData) override; + void initializeStaticData(const gl::Context *context) override; + void invalidateStaticData(const gl::Context *context) override; + + // BufferImpl implementation + angle::Result setData(const gl::Context *context, + gl::BufferBinding target, + const void *data, + size_t size, + gl::BufferUsage usage) override; + angle::Result setSubData(const gl::Context *context, + gl::BufferBinding target, + const void *data, + size_t size, + size_t offset) override; + angle::Result copySubData(const gl::Context *context, + BufferImpl *source, + GLintptr sourceOffset, + GLintptr destOffset, + GLsizeiptr size) override; + angle::Result map(const gl::Context *context, GLenum access, void **mapPtr) override; + angle::Result mapRange(const gl::Context *context, + size_t offset, + size_t length, + GLbitfield access, + void **mapPtr) override; + angle::Result unmap(const gl::Context *context, GLboolean *result) override; + angle::Result markTransformFeedbackUsage(const gl::Context *context) override; + + private: + class BufferStorage; + class EmulatedIndexedStorage; + class NativeStorage; + class PackStorage; + class SystemMemoryStorage; + class StructuredBufferStorage; + + struct BufferCacheEntry + { + BufferCacheEntry() : storage(nullptr), lruCount(0) {} + + BufferStorage *storage; + unsigned int lruCount; + }; + + struct StructuredBufferKey + { + StructuredBufferKey(unsigned int offsetIn, unsigned int structureByteStrideIn) + : offset(offsetIn), structureByteStride(structureByteStrideIn) + {} + bool operator<(const StructuredBufferKey &rhs) const + { + return std::tie(offset, structureByteStride) < + std::tie(rhs.offset, rhs.structureByteStride); + } + unsigned int offset; + unsigned int structureByteStride; + }; + + void markBufferUsage(BufferUsage usage); + angle::Result markBufferUsage(const gl::Context *context, BufferUsage usage); + angle::Result garbageCollection(const gl::Context *context, BufferUsage currentUsage); + + angle::Result updateBufferStorage(const gl::Context *context, + BufferStorage *storage, + size_t sourceOffset, + size_t storageSize); + + angle::Result getNativeStorageForUAV(const gl::Context *context, + Buffer11::NativeStorage **storageOut); + + template + angle::Result getBufferStorage(const gl::Context *context, + BufferUsage usage, + StorageOutT **storageOut); + + template + angle::Result getStagingStorage(const gl::Context *context, StorageOutT **storageOut); + + angle::Result getLatestBufferStorage(const gl::Context *context, + BufferStorage **storageOut) const; + + angle::Result getConstantBufferRangeStorage(const gl::Context *context, + GLintptr offset, + GLsizeiptr size, + NativeStorage **storageOut); + + BufferStorage *allocateStorage(BufferUsage usage); + void updateDeallocThreshold(BufferUsage usage); + + // Free the storage if we decide it isn't being used very often. + angle::Result checkForDeallocation(const gl::Context *context, BufferUsage usage); + + // For some cases of uniform buffer storage, we can't deallocate system memory storage. + bool canDeallocateSystemMemory() const; + + // Updates data revisions and latest storage. + void onCopyStorage(BufferStorage *dest, BufferStorage *source); + void onStorageUpdate(BufferStorage *updatedStorage); + + Renderer11 *mRenderer; + size_t mSize; + + BufferStorage *mMappedStorage; + + // Buffer storages are sorted by usage. It's important that the latest buffer storage picks + // the lowest usage in the case where two storages are tied on data revision - this ensures + // we never do anything dangerous like map a uniform buffer over a staging or system memory + // copy. + std::array mBufferStorages; + BufferStorage *mLatestBufferStorage; + + // These two arrays are used to track when to free unused storage. + std::array mDeallocThresholds; + std::array mIdleness; + + // Cache of D3D11 constant buffer for specific ranges of buffer data. + // This is used to emulate UBO ranges on 11.0 devices. + // Constant buffers are indexed by there start offset. + typedef std::map BufferCache; + BufferCache mConstantBufferRangeStoragesCache; + size_t mConstantBufferStorageAdditionalSize; + unsigned int mMaxConstantBufferLruCount; + + typedef std::map StructuredBufferCache; + StructuredBufferCache mStructuredBufferRangeStoragesCache; + size_t mStructuredBufferStorageAdditionalSize; + unsigned int mMaxStructuredBufferLruCount; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_BUFFER11_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp new file mode 100644 index 0000000000..d85b18b840 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp @@ -0,0 +1,813 @@ + +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Clear11.cpp: Framebuffer clear utility class. + +#include "libANGLE/renderer/d3d/d3d11/Clear11.h" + +#include + +#include "libANGLE/Context.h" +#include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/FramebufferD3D.h" +#include "libANGLE/renderer/d3d/d3d11/Context11.h" +#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" +#include "libANGLE/trace.h" + +// Precompiled shaders +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11_fl9vs.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11multiviewgs.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11multiviewvs.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11vs.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/cleardepth11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11_fl9ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps1.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps2.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps3.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps4.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps5.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps6.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps7.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps8.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps1.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps2.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps3.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps4.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps5.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps6.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps7.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps8.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps1.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps2.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps3.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps4.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps5.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps6.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps7.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps8.h" + +namespace rx +{ + +namespace +{ +constexpr uint32_t g_ConstantBufferSize = sizeof(RtvDsvClearInfo); +constexpr uint32_t g_VertexSize = sizeof(d3d11::PositionVertex); + +// Updates color, depth and alpha components of cached CB if necessary. +// Returns true if any constants are updated, false otherwise. +template +bool UpdateDataCache(RtvDsvClearInfo *dataCache, + const gl::Color &color, + const float *zValue, + const uint32_t numRtvs, + const uint8_t writeMask) +{ + bool cacheDirty = false; + + if (numRtvs > 0) + { + const bool writeRGB = (writeMask & ~D3D11_COLOR_WRITE_ENABLE_ALPHA) != 0; + if (writeRGB && memcmp(&dataCache->r, &color.red, sizeof(T) * 3) != 0) + { + dataCache->r = color.red; + dataCache->g = color.green; + dataCache->b = color.blue; + cacheDirty = true; + } + + const bool writeAlpha = (writeMask & D3D11_COLOR_WRITE_ENABLE_ALPHA) != 0; + if (writeAlpha && (dataCache->a != color.alpha)) + { + dataCache->a = color.alpha; + cacheDirty = true; + } + } + + if (zValue) + { + const float clampedZValue = gl::clamp01(*zValue); + + if (clampedZValue != dataCache->z) + { + dataCache->z = clampedZValue; + cacheDirty = true; + } + } + + return cacheDirty; +} + +} // anonymous namespace + +#define CLEARPS(Index) \ + d3d11::LazyShader(g_PS_Clear##Index, ArraySize(g_PS_Clear##Index), \ + "Clear11 PS " ANGLE_STRINGIFY(Index)) + +Clear11::ShaderManager::ShaderManager() + : mIl9(), + mVs9(g_VS_Clear_FL9, ArraySize(g_VS_Clear_FL9), "Clear11 VS FL9"), + mPsFloat9(g_PS_ClearFloat_FL9, ArraySize(g_PS_ClearFloat_FL9), "Clear11 PS FloatFL9"), + mVs(g_VS_Clear, ArraySize(g_VS_Clear), "Clear11 VS"), + mVsMultiview(g_VS_Multiview_Clear, ArraySize(g_VS_Multiview_Clear), "Clear11 VS Multiview"), + mGsMultiview(g_GS_Multiview_Clear, ArraySize(g_GS_Multiview_Clear), "Clear11 GS Multiview"), + mPsDepth(g_PS_ClearDepth, ArraySize(g_PS_ClearDepth), "Clear11 PS Depth"), + mPsFloat{{CLEARPS(Float1), CLEARPS(Float2), CLEARPS(Float3), CLEARPS(Float4), CLEARPS(Float5), + CLEARPS(Float6), CLEARPS(Float7), CLEARPS(Float8)}}, + mPsUInt{{CLEARPS(Uint1), CLEARPS(Uint2), CLEARPS(Uint3), CLEARPS(Uint4), CLEARPS(Uint5), + CLEARPS(Uint6), CLEARPS(Uint7), CLEARPS(Uint8)}}, + mPsSInt{{CLEARPS(Sint1), CLEARPS(Sint2), CLEARPS(Sint3), CLEARPS(Sint4), CLEARPS(Sint5), + CLEARPS(Sint6), CLEARPS(Sint7), CLEARPS(Sint8)}} +{} + +#undef CLEARPS + +Clear11::ShaderManager::~ShaderManager() {} + +angle::Result Clear11::ShaderManager::getShadersAndLayout(const gl::Context *context, + Renderer11 *renderer, + const INT clearType, + const uint32_t numRTs, + const bool hasLayeredLayout, + const d3d11::InputLayout **il, + const d3d11::VertexShader **vs, + const d3d11::GeometryShader **gs, + const d3d11::PixelShader **ps) +{ + Context11 *context11 = GetImplAs(context); + + if (renderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3) + { + ASSERT(clearType == GL_FLOAT); + + ANGLE_TRY(mVs9.resolve(context11, renderer)); + ANGLE_TRY(mPsFloat9.resolve(context11, renderer)); + + if (!mIl9.valid()) + { + const D3D11_INPUT_ELEMENT_DESC ilDesc[] = { + {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}}; + + InputElementArray ilDescArray(ilDesc); + ShaderData vertexShader(g_VS_Clear_FL9); + + ANGLE_TRY(renderer->allocateResource(context11, ilDescArray, &vertexShader, &mIl9)); + } + + *vs = &mVs9.getObj(); + *gs = nullptr; + *il = &mIl9; + *ps = &mPsFloat9.getObj(); + return angle::Result::Continue; + } + + if (!hasLayeredLayout) + { + ANGLE_TRY(mVs.resolve(context11, renderer)); + *vs = &mVs.getObj(); + *gs = nullptr; + } + else + { + // For layered framebuffers we have to use the multi-view versions of the VS and GS. + ANGLE_TRY(mVsMultiview.resolve(context11, renderer)); + ANGLE_TRY(mGsMultiview.resolve(context11, renderer)); + *vs = &mVsMultiview.getObj(); + *gs = &mGsMultiview.getObj(); + } + + *il = nullptr; + + if (numRTs == 0) + { + ANGLE_TRY(mPsDepth.resolve(context11, renderer)); + *ps = &mPsDepth.getObj(); + return angle::Result::Continue; + } + + switch (clearType) + { + case GL_FLOAT: + ANGLE_TRY(mPsFloat[numRTs - 1].resolve(context11, renderer)); + *ps = &mPsFloat[numRTs - 1].getObj(); + break; + case GL_UNSIGNED_INT: + ANGLE_TRY(mPsUInt[numRTs - 1].resolve(context11, renderer)); + *ps = &mPsUInt[numRTs - 1].getObj(); + break; + case GL_INT: + ANGLE_TRY(mPsSInt[numRTs - 1].resolve(context11, renderer)); + *ps = &mPsSInt[numRTs - 1].getObj(); + break; + default: + UNREACHABLE(); + break; + } + + return angle::Result::Continue; +} + +Clear11::Clear11(Renderer11 *renderer) + : mRenderer(renderer), + mResourcesInitialized(false), + mScissorEnabledRasterizerState(), + mScissorDisabledRasterizerState(), + mShaderManager(), + mConstantBuffer(), + mVertexBuffer(), + mShaderData({}) +{} + +Clear11::~Clear11() {} + +angle::Result Clear11::ensureResourcesInitialized(const gl::Context *context) +{ + if (mResourcesInitialized) + { + return angle::Result::Continue; + } + + ANGLE_TRACE_EVENT0("gpu.angle", "Clear11::ensureResourcesInitialized"); + + static_assert((sizeof(RtvDsvClearInfo) == sizeof(RtvDsvClearInfo)), + "Size of rx::RtvDsvClearInfo is not equal to rx::RtvDsvClearInfo"); + + static_assert( + (sizeof(RtvDsvClearInfo) == sizeof(RtvDsvClearInfo)), + "Size of rx::RtvDsvClearInfo is not equal to rx::RtvDsvClearInfo"); + + static_assert((sizeof(RtvDsvClearInfo) % 16 == 0), + "The size of RtvDsvClearInfo should be a multiple of 16bytes."); + + // Create Rasterizer States + D3D11_RASTERIZER_DESC rsDesc; + rsDesc.FillMode = D3D11_FILL_SOLID; + rsDesc.CullMode = D3D11_CULL_NONE; + rsDesc.FrontCounterClockwise = FALSE; + rsDesc.DepthBias = 0; + rsDesc.DepthBiasClamp = 0.0f; + rsDesc.SlopeScaledDepthBias = 0.0f; + rsDesc.DepthClipEnable = TRUE; + rsDesc.ScissorEnable = FALSE; + rsDesc.MultisampleEnable = FALSE; + rsDesc.AntialiasedLineEnable = FALSE; + + Context11 *context11 = GetImplAs(context); + + ANGLE_TRY(mRenderer->allocateResource(context11, rsDesc, &mScissorDisabledRasterizerState)); + mScissorDisabledRasterizerState.setInternalName("Clear11RasterizerStateWithScissorDisabled"); + + rsDesc.ScissorEnable = TRUE; + ANGLE_TRY(mRenderer->allocateResource(context11, rsDesc, &mScissorEnabledRasterizerState)); + mScissorEnabledRasterizerState.setInternalName("Clear11RasterizerStateWithScissorEnabled"); + + // Initialize Depthstencil state with defaults + mDepthStencilStateKey.depthTest = false; + mDepthStencilStateKey.depthMask = false; + mDepthStencilStateKey.depthFunc = GL_ALWAYS; + mDepthStencilStateKey.stencilWritemask = static_cast(-1); + mDepthStencilStateKey.stencilBackWritemask = static_cast(-1); + mDepthStencilStateKey.stencilBackMask = 0; + mDepthStencilStateKey.stencilTest = false; + mDepthStencilStateKey.stencilMask = 0; + mDepthStencilStateKey.stencilFail = GL_REPLACE; + mDepthStencilStateKey.stencilPassDepthFail = GL_REPLACE; + mDepthStencilStateKey.stencilPassDepthPass = GL_REPLACE; + mDepthStencilStateKey.stencilFunc = GL_ALWAYS; + mDepthStencilStateKey.stencilBackFail = GL_REPLACE; + mDepthStencilStateKey.stencilBackPassDepthFail = GL_REPLACE; + mDepthStencilStateKey.stencilBackPassDepthPass = GL_REPLACE; + mDepthStencilStateKey.stencilBackFunc = GL_ALWAYS; + + // Initialize BlendStateKey with defaults + mBlendStateKey.blendStateExt = gl::BlendStateExt(mRenderer->getNativeCaps().maxDrawBuffers); + + mResourcesInitialized = true; + return angle::Result::Continue; +} + +bool Clear11::useVertexBuffer() const +{ + return (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3); +} + +angle::Result Clear11::ensureConstantBufferCreated(const gl::Context *context) +{ + if (mConstantBuffer.valid()) + { + return angle::Result::Continue; + } + + // Create constant buffer for color & depth data + + D3D11_BUFFER_DESC bufferDesc; + bufferDesc.ByteWidth = g_ConstantBufferSize; + bufferDesc.Usage = D3D11_USAGE_DYNAMIC; + bufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + bufferDesc.MiscFlags = 0; + bufferDesc.StructureByteStride = 0; + + D3D11_SUBRESOURCE_DATA initialData; + initialData.pSysMem = &mShaderData; + initialData.SysMemPitch = g_ConstantBufferSize; + initialData.SysMemSlicePitch = g_ConstantBufferSize; + + ANGLE_TRY(mRenderer->allocateResource(GetImplAs(context), bufferDesc, &initialData, + &mConstantBuffer)); + mConstantBuffer.setInternalName("Clear11ConstantBuffer"); + return angle::Result::Continue; +} + +angle::Result Clear11::ensureVertexBufferCreated(const gl::Context *context) +{ + ASSERT(useVertexBuffer()); + + if (mVertexBuffer.valid()) + { + return angle::Result::Continue; + } + + // Create vertex buffer with vertices for a quad covering the entire surface + + static_assert((sizeof(d3d11::PositionVertex) % 16) == 0, + "d3d11::PositionVertex should be a multiple of 16 bytes"); + const d3d11::PositionVertex vbData[6] = {{-1.0f, 1.0f, 0.0f, 1.0f}, {1.0f, -1.0f, 0.0f, 1.0f}, + {-1.0f, -1.0f, 0.0f, 1.0f}, {-1.0f, 1.0f, 0.0f, 1.0f}, + {1.0f, 1.0f, 0.0f, 1.0f}, {1.0f, -1.0f, 0.0f, 1.0f}}; + + const UINT vbSize = sizeof(vbData); + + D3D11_BUFFER_DESC bufferDesc; + bufferDesc.ByteWidth = vbSize; + bufferDesc.Usage = D3D11_USAGE_IMMUTABLE; + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufferDesc.CPUAccessFlags = 0; + bufferDesc.MiscFlags = 0; + bufferDesc.StructureByteStride = 0; + + D3D11_SUBRESOURCE_DATA initialData; + initialData.pSysMem = vbData; + initialData.SysMemPitch = vbSize; + initialData.SysMemSlicePitch = initialData.SysMemPitch; + + ANGLE_TRY(mRenderer->allocateResource(GetImplAs(context), bufferDesc, &initialData, + &mVertexBuffer)); + mVertexBuffer.setInternalName("Clear11VertexBuffer"); + return angle::Result::Continue; +} + +angle::Result Clear11::clearFramebuffer(const gl::Context *context, + const ClearParameters &clearParams, + const gl::FramebufferState &fboData) +{ + ANGLE_TRY(ensureResourcesInitialized(context)); + + // Iterate over the color buffers which require clearing and determine if they can be + // cleared with ID3D11DeviceContext::ClearRenderTargetView or ID3D11DeviceContext1::ClearView. + // This requires: + // 1) The render target is being cleared to a float value (will be cast to integer when clearing + // integer render targets as expected but does not work the other way around) + // 2) The format of the render target has no color channels that are currently masked out. + // Clear the easy-to-clear buffers on the spot and accumulate the ones that require special + // work. + // + // If these conditions are met, and: + // - No scissored clear is needed, then clear using ID3D11DeviceContext::ClearRenderTargetView. + // - A scissored clear is needed then clear using ID3D11DeviceContext1::ClearView if available. + // Otherwise perform a shader based clear. + // + // Also determine if the DSV can be cleared withID3D11DeviceContext::ClearDepthStencilView by + // checking if the stencil write mask covers the entire stencil. + // + // To clear the remaining buffers, a shader based clear is performed: + // - The appropriate ShaderManagers (VS & PS) for the clearType is set + // - A CB containing the clear color and Z values is bound + // - An IL and VB are bound (for FL93 and below) + // - ScissorRect/Raststate/Viewport set as required + // - Blendstate set containing appropriate colorMasks + // - DepthStencilState set with appropriate parameters for a z or stencil clear if required + // - Color and/or Z buffers to be cleared are bound + // - Primitive covering entire clear area is drawn + + gl::Extents framebufferSize; + + const auto *depthStencilAttachment = fboData.getDepthOrStencilAttachment(); + if (depthStencilAttachment != nullptr) + { + framebufferSize = depthStencilAttachment->getSize(); + } + else + { + const gl::FramebufferAttachment *colorAttachment = fboData.getFirstColorAttachment(); + ASSERT(colorAttachment); + framebufferSize = colorAttachment->getSize(); + } + + bool needScissoredClear = false; + D3D11_RECT scissorRect; + if (clearParams.scissorEnabled) + { + if (clearParams.scissor.x >= framebufferSize.width || + clearParams.scissor.y >= framebufferSize.height || clearParams.scissor.width == 0 || + clearParams.scissor.height == 0) + { + // The check assumes that the viewport offsets are not negative as according to the + // OVR_multiview2 spec. + // Scissor rect is outside the renderbuffer or is an empty rect. + return angle::Result::Continue; + } + + if (clearParams.scissor.x + clearParams.scissor.width <= 0 || + clearParams.scissor.y + clearParams.scissor.height <= 0) + { + // Scissor rect is outside the renderbuffer. + return angle::Result::Continue; + } + needScissoredClear = + clearParams.scissor.x > 0 || clearParams.scissor.y > 0 || + clearParams.scissor.x + clearParams.scissor.width < framebufferSize.width || + clearParams.scissor.y + clearParams.scissor.height < framebufferSize.height; + + if (needScissoredClear) + { + // Apply viewport offsets to compute the final scissor rectangles. + // Even in multiview all layers share the same viewport and scissor. + scissorRect.left = clearParams.scissor.x; + scissorRect.right = scissorRect.left + clearParams.scissor.width; + scissorRect.top = clearParams.scissor.y; + scissorRect.bottom = scissorRect.top + clearParams.scissor.height; + } + } + + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported(); + + std::array rtvs; + std::array rtvMasks = {}; + + uint32_t numRtvs = 0; + uint8_t commonColorMask = 0; + + const auto &colorAttachments = fboData.getColorAttachments(); + for (auto colorAttachmentIndex : fboData.getEnabledDrawBuffers()) + { + const uint8_t colorMask = gl::BlendStateExt::ColorMaskStorage::GetValueIndexed( + colorAttachmentIndex, clearParams.colorMask); + + commonColorMask |= colorMask; + + const gl::FramebufferAttachment &attachment = colorAttachments[colorAttachmentIndex]; + + if (!clearParams.clearColor[colorAttachmentIndex]) + { + continue; + } + + RenderTarget11 *renderTarget = nullptr; + ANGLE_TRY(attachment.getRenderTarget(context, attachment.getRenderToTextureSamples(), + &renderTarget)); + + const gl::InternalFormat &formatInfo = *attachment.getFormat().info; + + if (clearParams.colorType == GL_FLOAT && + !(formatInfo.componentType == GL_FLOAT || + formatInfo.componentType == GL_UNSIGNED_NORMALIZED || + formatInfo.componentType == GL_SIGNED_NORMALIZED)) + { + WARN() << "It is undefined behaviour to clear a render buffer which is not " + "normalized fixed point or floating-point to floating point values (color " + "attachment " + << colorAttachmentIndex << " has internal format " << attachment.getFormat() + << ")."; + } + + bool r, g, b, a; + gl::BlendStateExt::UnpackColorMask(colorMask, &r, &g, &b, &a); + if ((formatInfo.redBits == 0 || !r) && (formatInfo.greenBits == 0 || !g) && + (formatInfo.blueBits == 0 || !b) && (formatInfo.alphaBits == 0 || !a)) + { + // Every channel either does not exist in the render target or is masked out + continue; + } + + const auto &framebufferRTV = renderTarget->getRenderTargetView(); + ASSERT(framebufferRTV.valid()); + + bool canClearView = mRenderer->getRenderer11DeviceCaps().supportsClearView; + if (canClearView && + mRenderer->getFeatures().emulateClearViewAfterDualSourceBlending.enabled) + { + // Check the current state to see if we were using dual source blending + const auto isDualSource = [](const auto blend) { + switch (blend) + { + case D3D11_BLEND_SRC1_COLOR: + case D3D11_BLEND_INV_SRC1_COLOR: + case D3D11_BLEND_SRC1_ALPHA: + case D3D11_BLEND_INV_SRC1_ALPHA: + return true; + default: + return false; + } + }; + FLOAT blendFactor[4]; + UINT sampleMask; + ID3D11BlendState *blendState; + deviceContext->OMGetBlendState(&blendState, blendFactor, &sampleMask); + if (blendState) + { + D3D11_BLEND_DESC blendDesc; + blendState->GetDesc(&blendDesc); + // You can only use dual source blending on slot 0 so only check there + if (isDualSource(blendDesc.RenderTarget[0].SrcBlend) || + isDualSource(blendDesc.RenderTarget[0].DestBlend) || + isDualSource(blendDesc.RenderTarget[0].SrcBlendAlpha) || + isDualSource(blendDesc.RenderTarget[0].DestBlendAlpha)) + { + canClearView = false; + } + } + } + + if (needScissoredClear && mRenderer->getFeatures().scissoredClearArtifacts.enabled) + { + canClearView = false; + } + + if ((!canClearView && needScissoredClear) || clearParams.colorType != GL_FLOAT || + (formatInfo.redBits > 0 && !r) || (formatInfo.greenBits > 0 && !g) || + (formatInfo.blueBits > 0 && !b) || (formatInfo.alphaBits > 0 && !a)) + { + rtvs[numRtvs] = framebufferRTV.get(); + rtvMasks[numRtvs] = gl_d3d11::GetColorMask(formatInfo) & colorMask; + numRtvs++; + } + else + { + // ID3D11DeviceContext::ClearRenderTargetView or ID3D11DeviceContext1::ClearView is + // possible + + const auto &nativeFormat = renderTarget->getFormatSet().format(); + + // Check if the actual format has a channel that the internal format does not and + // set them to the default values + float clearValues[4] = { + ((formatInfo.redBits == 0 && nativeFormat.redBits > 0) ? 0.0f + : clearParams.colorF.red), + ((formatInfo.greenBits == 0 && nativeFormat.greenBits > 0) + ? 0.0f + : clearParams.colorF.green), + ((formatInfo.blueBits == 0 && nativeFormat.blueBits > 0) ? 0.0f + : clearParams.colorF.blue), + ((formatInfo.alphaBits == 0 && nativeFormat.alphaBits > 0) + ? 1.0f + : clearParams.colorF.alpha), + }; + + if (formatInfo.alphaBits == 1) + { + // Some drivers do not correctly handle calling Clear() on a format with 1-bit + // alpha. They can incorrectly round all non-zero values up to 1.0f. Note that + // WARP does not do this. We should handle the rounding for them instead. + clearValues[3] = (clearParams.colorF.alpha >= 0.5f) ? 1.0f : 0.0f; + } + + if (needScissoredClear) + { + // We shouldn't reach here if deviceContext1 is unavailable. + ASSERT(deviceContext1); + deviceContext1->ClearView(framebufferRTV.get(), clearValues, &scissorRect, 1); + if (mRenderer->getFeatures().callClearTwice.enabled) + { + deviceContext1->ClearView(framebufferRTV.get(), clearValues, &scissorRect, 1); + } + } + else + { + deviceContext->ClearRenderTargetView(framebufferRTV.get(), clearValues); + if (mRenderer->getFeatures().callClearTwice.enabled) + { + deviceContext->ClearRenderTargetView(framebufferRTV.get(), clearValues); + } + } + } + } + + ID3D11DepthStencilView *dsv = nullptr; + + if (clearParams.clearDepth || clearParams.clearStencil) + { + RenderTarget11 *depthStencilRenderTarget = nullptr; + + ASSERT(depthStencilAttachment != nullptr); + ANGLE_TRY(depthStencilAttachment->getRenderTarget( + context, depthStencilAttachment->getRenderToTextureSamples(), + &depthStencilRenderTarget)); + + dsv = depthStencilRenderTarget->getDepthStencilView().get(); + ASSERT(dsv != nullptr); + + const auto &nativeFormat = depthStencilRenderTarget->getFormatSet().format(); + const auto *stencilAttachment = fboData.getStencilAttachment(); + + uint32_t stencilUnmasked = + (stencilAttachment != nullptr) ? (1 << nativeFormat.stencilBits) - 1 : 0; + bool needMaskedStencilClear = + clearParams.clearStencil && + (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked; + + if (!needScissoredClear && !needMaskedStencilClear) + { + const UINT clearFlags = (clearParams.clearDepth ? D3D11_CLEAR_DEPTH : 0) | + (clearParams.clearStencil ? D3D11_CLEAR_STENCIL : 0); + const FLOAT depthClear = gl::clamp01(clearParams.depthValue); + const UINT8 stencilClear = clearParams.stencilValue & 0xFF; + + deviceContext->ClearDepthStencilView(dsv, clearFlags, depthClear, stencilClear); + + dsv = nullptr; + } + } + + if (numRtvs == 0 && dsv == nullptr) + { + return angle::Result::Continue; + } + + // Clear the remaining render targets and depth stencil in one pass by rendering a quad: + // + // IA/VS: Vertices containing position and color members are passed through to the next stage. + // The vertex position has XY coordinates equal to clip extents and a Z component equal to the + // Z clear value. The vertex color contains the clear color. + // + // Rasterizer: Viewport scales the VS output over the entire surface and depending on whether + // or not scissoring is enabled the appropriate scissor rect and rasterizerState with or without + // the scissor test enabled is set as well. + // + // DepthStencilTest: DepthTesting, DepthWrites, StencilMask and StencilWrites will be enabled or + // disabled or set depending on what the input depthStencil clear parameters are. Since the PS + // is not writing out depth or rejecting pixels, this should happen prior to the PS stage. + // + // PS: Will write out the color values passed through from the previous stage to all outputs. + // + // OM: BlendState will perform the required color masking and output to RTV(s). + + // + // ====================================================================================== + // + // Luckily, the gl spec (ES 3.0.2 pg 183) states that the results of clearing a render- + // buffer that is not normalized fixed point or floating point with floating point values + // are undefined so we can just write floats to them and D3D11 will bit cast them to + // integers. + // + // Also, we don't have to worry about attempting to clear a normalized fixed/floating point + // buffer with integer values because there is no gl API call which would allow it, + // glClearBuffer* calls only clear a single renderbuffer at a time which is verified to + // be a compatible clear type. + + ASSERT(numRtvs <= static_cast(mRenderer->getNativeCaps().maxDrawBuffers)); + + // Setup BlendStateKey parameters + mBlendStateKey.blendStateExt.setColorMask(false, false, false, false); + for (size_t i = 0; i < numRtvs; i++) + { + mBlendStateKey.blendStateExt.setColorMaskIndexed(i, rtvMasks[i]); + } + + mBlendStateKey.rtvMax = static_cast(numRtvs); + + // Get BlendState + const d3d11::BlendState *blendState = nullptr; + ANGLE_TRY(mRenderer->getBlendState(context, mBlendStateKey, &blendState)); + + const d3d11::DepthStencilState *dsState = nullptr; + const float *zValue = nullptr; + + if (dsv) + { + // Setup DepthStencilStateKey + mDepthStencilStateKey.depthTest = clearParams.clearDepth; + mDepthStencilStateKey.depthMask = clearParams.clearDepth; + mDepthStencilStateKey.stencilWritemask = clearParams.stencilWriteMask; + mDepthStencilStateKey.stencilTest = clearParams.clearStencil; + + // Get DepthStencilState + ANGLE_TRY(mRenderer->getDepthStencilState(context, mDepthStencilStateKey, &dsState)); + zValue = clearParams.clearDepth ? &clearParams.depthValue : nullptr; + } + + bool dirtyCb = false; + + // Compare the input color/z values against the CB cache and update it if necessary + switch (clearParams.colorType) + { + case GL_FLOAT: + dirtyCb = + UpdateDataCache(&mShaderData, clearParams.colorF, zValue, numRtvs, commonColorMask); + break; + case GL_UNSIGNED_INT: + dirtyCb = UpdateDataCache(reinterpret_cast *>(&mShaderData), + clearParams.colorUI, zValue, numRtvs, commonColorMask); + break; + case GL_INT: + dirtyCb = UpdateDataCache(reinterpret_cast *>(&mShaderData), + clearParams.colorI, zValue, numRtvs, commonColorMask); + break; + default: + UNREACHABLE(); + break; + } + + ANGLE_TRY(ensureConstantBufferCreated(context)); + + if (dirtyCb) + { + // Update the constant buffer with the updated cache contents + // TODO(Shahmeer): Consider using UpdateSubresource1 D3D11_COPY_DISCARD where possible. + D3D11_MAPPED_SUBRESOURCE mappedResource; + ANGLE_TRY(mRenderer->mapResource(context, mConstantBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, + 0, &mappedResource)); + + memcpy(mappedResource.pData, &mShaderData, g_ConstantBufferSize); + deviceContext->Unmap(mConstantBuffer.get(), 0); + } + + auto *stateManager = mRenderer->getStateManager(); + + // Set the viewport to be the same size as the framebuffer. + stateManager->setSimpleViewport(framebufferSize); + + // Apply state + stateManager->setSimpleBlendState(blendState); + + const UINT stencilValue = clearParams.stencilValue & 0xFF; + stateManager->setDepthStencilState(dsState, stencilValue); + + if (needScissoredClear) + { + stateManager->setRasterizerState(&mScissorEnabledRasterizerState); + } + else + { + stateManager->setRasterizerState(&mScissorDisabledRasterizerState); + } + + // Get Shaders + const d3d11::VertexShader *vs = nullptr; + const d3d11::GeometryShader *gs = nullptr; + const d3d11::InputLayout *il = nullptr; + const d3d11::PixelShader *ps = nullptr; + const bool hasLayeredLayout = (fboData.isMultiview()); + ANGLE_TRY(mShaderManager.getShadersAndLayout(context, mRenderer, clearParams.colorType, numRtvs, + hasLayeredLayout, &il, &vs, &gs, &ps)); + + // Apply Shaders + stateManager->setDrawShaders(vs, gs, ps); + stateManager->setPixelConstantBuffer(0, &mConstantBuffer); + + // Bind IL & VB if needed + stateManager->setIndexBuffer(nullptr, DXGI_FORMAT_UNKNOWN, 0); + stateManager->setInputLayout(il); + + if (useVertexBuffer()) + { + ANGLE_TRY(ensureVertexBufferCreated(context)); + stateManager->setSingleVertexBuffer(&mVertexBuffer, g_VertexSize, 0); + } + else + { + stateManager->setSingleVertexBuffer(nullptr, 0, 0); + } + + stateManager->setPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + + // Apply render targets + stateManager->setRenderTargets(&rtvs[0], numRtvs, dsv); + + if (needScissoredClear) + { + stateManager->setScissorRectD3D(scissorRect); + } + // Draw the fullscreen quad. + if (!hasLayeredLayout) + { + deviceContext->Draw(6, 0); + } + else + { + ASSERT(hasLayeredLayout); + deviceContext->DrawInstanced(6, static_cast(fboData.getNumViews()), 0, 0); + } + + return angle::Result::Continue; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Clear11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Clear11.h new file mode 100644 index 0000000000..2e2eca5e80 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Clear11.h @@ -0,0 +1,102 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Clear11.h: Framebuffer clear utility class. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_CLEAR11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_CLEAR11_H_ + +#include +#include + +#include "libANGLE/Error.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" + +namespace rx +{ +class Renderer11; +class RenderTarget11; +struct ClearParameters; + +template +struct RtvDsvClearInfo +{ + T r, g, b, a; + float z; + float c1padding[3]; +}; + +class Clear11 : angle::NonCopyable +{ + public: + explicit Clear11(Renderer11 *renderer); + ~Clear11(); + + // Clears the framebuffer with the supplied clear parameters, assumes that the framebuffer is + // currently applied. + angle::Result clearFramebuffer(const gl::Context *context, + const ClearParameters &clearParams, + const gl::FramebufferState &fboData); + + private: + class ShaderManager final : angle::NonCopyable + { + public: + ShaderManager(); + ~ShaderManager(); + angle::Result getShadersAndLayout(const gl::Context *context, + Renderer11 *renderer, + const INT clearType, + const uint32_t numRTs, + const bool hasLayeredLayout, + const d3d11::InputLayout **il, + const d3d11::VertexShader **vs, + const d3d11::GeometryShader **gs, + const d3d11::PixelShader **ps); + + private: + constexpr static size_t kNumShaders = D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; + + d3d11::InputLayout mIl9; + d3d11::LazyShader mVs9; + d3d11::LazyShader mPsFloat9; + d3d11::LazyShader mVs; + d3d11::LazyShader mVsMultiview; + d3d11::LazyShader mGsMultiview; + d3d11::LazyShader mPsDepth; + std::array, kNumShaders> mPsFloat; + std::array, kNumShaders> mPsUInt; + std::array, kNumShaders> mPsSInt; + }; + + bool useVertexBuffer() const; + angle::Result ensureConstantBufferCreated(const gl::Context *context); + angle::Result ensureVertexBufferCreated(const gl::Context *context); + angle::Result ensureResourcesInitialized(const gl::Context *context); + + Renderer11 *mRenderer; + bool mResourcesInitialized; + + // States + d3d11::RasterizerState mScissorEnabledRasterizerState; + d3d11::RasterizerState mScissorDisabledRasterizerState; + gl::DepthStencilState mDepthStencilStateKey; + d3d11::BlendStateKey mBlendStateKey; + + // Shaders and shader resources + ShaderManager mShaderManager; + d3d11::Buffer mConstantBuffer; + d3d11::Buffer mVertexBuffer; + + // Buffer data and draw parameters + RtvDsvClearInfo mShaderData; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_CLEAR11_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Context11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Context11.cpp new file mode 100644 index 0000000000..f3b13f678a --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Context11.cpp @@ -0,0 +1,1048 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Context11: +// D3D11-specific functionality associated with a GL Context. +// + +#include "libANGLE/renderer/d3d/d3d11/Context11.h" + +#include "common/entry_points_enum_autogen.h" +#include "common/string_utils.h" +#include "libANGLE/Context.h" +#include "libANGLE/Context.inl.h" +#include "libANGLE/MemoryProgramCache.h" +#include "libANGLE/renderer/OverlayImpl.h" +#include "libANGLE/renderer/d3d/CompilerD3D.h" +#include "libANGLE/renderer/d3d/RenderbufferD3D.h" +#include "libANGLE/renderer/d3d/SamplerD3D.h" +#include "libANGLE/renderer/d3d/ShaderD3D.h" +#include "libANGLE/renderer/d3d/TextureD3D.h" +#include "libANGLE/renderer/d3d/d3d11/Buffer11.h" +#include "libANGLE/renderer/d3d/d3d11/Fence11.h" +#include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h" +#include "libANGLE/renderer/d3d/d3d11/IndexBuffer11.h" +#include "libANGLE/renderer/d3d/d3d11/Program11.h" +#include "libANGLE/renderer/d3d/d3d11/ProgramPipeline11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/StateManager11.h" +#include "libANGLE/renderer/d3d/d3d11/TransformFeedback11.h" +#include "libANGLE/renderer/d3d/d3d11/VertexArray11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" + +namespace rx +{ + +namespace +{ +ANGLE_INLINE bool DrawCallHasDynamicAttribs(const gl::Context *context) +{ + VertexArray11 *vertexArray11 = GetImplAs(context->getState().getVertexArray()); + return vertexArray11->hasActiveDynamicAttrib(context); +} + +bool DrawCallHasStreamingVertexArrays(const gl::Context *context, gl::PrimitiveMode mode) +{ + // Direct drawing doesn't support dynamic attribute storage since it needs the first and count + // to translate when applyVertexBuffer. GL_LINE_LOOP and GL_TRIANGLE_FAN are not supported + // either since we need to simulate them in D3D. + if (DrawCallHasDynamicAttribs(context) || mode == gl::PrimitiveMode::LineLoop || + mode == gl::PrimitiveMode::TriangleFan) + { + return true; + } + + ProgramD3D *programD3D = GetImplAs(context->getState().getProgram()); + if (InstancedPointSpritesActive(programD3D, mode)) + { + return true; + } + + return false; +} + +bool DrawCallHasStreamingElementArray(const gl::Context *context, gl::DrawElementsType srcType) +{ + const gl::State &glState = context->getState(); + gl::Buffer *elementArrayBuffer = glState.getVertexArray()->getElementArrayBuffer(); + + bool primitiveRestartWorkaround = + UsePrimitiveRestartWorkaround(glState.isPrimitiveRestartEnabled(), srcType); + const gl::DrawElementsType dstType = + (srcType == gl::DrawElementsType::UnsignedInt || primitiveRestartWorkaround) + ? gl::DrawElementsType::UnsignedInt + : gl::DrawElementsType::UnsignedShort; + + // Not clear where the offset comes from here. + switch (ClassifyIndexStorage(glState, elementArrayBuffer, srcType, dstType, 0)) + { + case IndexStorageType::Dynamic: + return true; + case IndexStorageType::Direct: + return false; + case IndexStorageType::Static: + { + BufferD3D *bufferD3D = GetImplAs(elementArrayBuffer); + StaticIndexBufferInterface *staticBuffer = bufferD3D->getStaticIndexBuffer(); + return (staticBuffer->getBufferSize() == 0 || staticBuffer->getIndexType() != dstType); + } + default: + UNREACHABLE(); + return true; + } +} + +template +angle::Result ReadbackIndirectBuffer(const gl::Context *context, + const void *indirect, + const IndirectBufferT **bufferPtrOut) +{ + const gl::State &glState = context->getState(); + gl::Buffer *drawIndirectBuffer = glState.getTargetBuffer(gl::BufferBinding::DrawIndirect); + ASSERT(drawIndirectBuffer); + Buffer11 *storage = GetImplAs(drawIndirectBuffer); + uintptr_t offset = reinterpret_cast(indirect); + + const uint8_t *bufferData = nullptr; + ANGLE_TRY(storage->getData(context, &bufferData)); + ASSERT(bufferData); + + *bufferPtrOut = reinterpret_cast(bufferData + offset); + return angle::Result::Continue; +} +} // anonymous namespace + +Context11::Context11(const gl::State &state, gl::ErrorSet *errorSet, Renderer11 *renderer) + : ContextD3D(state, errorSet), mRenderer(renderer) +{} + +Context11::~Context11() {} + +angle::Result Context11::initialize() +{ + return angle::Result::Continue; +} + +void Context11::onDestroy(const gl::Context *context) +{ + mIncompleteTextures.onDestroy(context); +} + +CompilerImpl *Context11::createCompiler() +{ + if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3) + { + return new CompilerD3D(SH_HLSL_4_0_FL9_3_OUTPUT); + } + else + { + return new CompilerD3D(SH_HLSL_4_1_OUTPUT); + } +} + +ShaderImpl *Context11::createShader(const gl::ShaderState &data) +{ + return new ShaderD3D(data, mRenderer); +} + +ProgramImpl *Context11::createProgram(const gl::ProgramState &data) +{ + return new Program11(data, mRenderer); +} + +FramebufferImpl *Context11::createFramebuffer(const gl::FramebufferState &data) +{ + return new Framebuffer11(data, mRenderer); +} + +TextureImpl *Context11::createTexture(const gl::TextureState &state) +{ + switch (state.getType()) + { + case gl::TextureType::_2D: + // GL_TEXTURE_VIDEO_IMAGE_WEBGL maps to native 2D texture on Windows platform + case gl::TextureType::VideoImage: + return new TextureD3D_2D(state, mRenderer); + case gl::TextureType::CubeMap: + return new TextureD3D_Cube(state, mRenderer); + case gl::TextureType::_3D: + return new TextureD3D_3D(state, mRenderer); + case gl::TextureType::_2DArray: + return new TextureD3D_2DArray(state, mRenderer); + case gl::TextureType::External: + return new TextureD3D_External(state, mRenderer); + case gl::TextureType::_2DMultisample: + return new TextureD3D_2DMultisample(state, mRenderer); + case gl::TextureType::_2DMultisampleArray: + return new TextureD3D_2DMultisampleArray(state, mRenderer); + case gl::TextureType::Buffer: + return new TextureD3D_Buffer(state, mRenderer); + default: + UNREACHABLE(); + } + + return nullptr; +} + +RenderbufferImpl *Context11::createRenderbuffer(const gl::RenderbufferState &state) +{ + return new RenderbufferD3D(state, mRenderer); +} + +BufferImpl *Context11::createBuffer(const gl::BufferState &state) +{ + Buffer11 *buffer = new Buffer11(state, mRenderer); + mRenderer->onBufferCreate(buffer); + return buffer; +} + +VertexArrayImpl *Context11::createVertexArray(const gl::VertexArrayState &data) +{ + return new VertexArray11(data); +} + +QueryImpl *Context11::createQuery(gl::QueryType type) +{ + return new Query11(mRenderer, type); +} + +FenceNVImpl *Context11::createFenceNV() +{ + return new FenceNV11(mRenderer); +} + +SyncImpl *Context11::createSync() +{ + return new Sync11(mRenderer); +} + +TransformFeedbackImpl *Context11::createTransformFeedback(const gl::TransformFeedbackState &state) +{ + return new TransformFeedback11(state, mRenderer); +} + +SamplerImpl *Context11::createSampler(const gl::SamplerState &state) +{ + return new SamplerD3D(state); +} + +ProgramPipelineImpl *Context11::createProgramPipeline(const gl::ProgramPipelineState &data) +{ + return new ProgramPipeline11(data); +} + +MemoryObjectImpl *Context11::createMemoryObject() +{ + UNREACHABLE(); + return nullptr; +} + +SemaphoreImpl *Context11::createSemaphore() +{ + UNREACHABLE(); + return nullptr; +} + +OverlayImpl *Context11::createOverlay(const gl::OverlayState &state) +{ + // Not implemented. + return new OverlayImpl(state); +} + +angle::Result Context11::flush(const gl::Context *context) +{ + return mRenderer->flush(this); +} + +angle::Result Context11::finish(const gl::Context *context) +{ + return mRenderer->finish(this); +} + +angle::Result Context11::drawArrays(const gl::Context *context, + gl::PrimitiveMode mode, + GLint first, + GLsizei count) +{ + ASSERT(count > 0); + ANGLE_TRY(mRenderer->getStateManager()->updateState( + context, mode, first, count, gl::DrawElementsType::InvalidEnum, nullptr, 0, 0, 0, true)); + return mRenderer->drawArrays(context, mode, first, count, 0, 0, false); +} + +angle::Result Context11::drawArraysInstanced(const gl::Context *context, + gl::PrimitiveMode mode, + GLint first, + GLsizei count, + GLsizei instanceCount) +{ + ASSERT(count > 0); + ANGLE_TRY(mRenderer->getStateManager()->updateState(context, mode, first, count, + gl::DrawElementsType::InvalidEnum, nullptr, + instanceCount, 0, 0, true)); + return mRenderer->drawArrays(context, mode, first, count, instanceCount, 0, true); +} + +angle::Result Context11::drawArraysInstancedBaseInstance(const gl::Context *context, + gl::PrimitiveMode mode, + GLint first, + GLsizei count, + GLsizei instanceCount, + GLuint baseInstance) +{ + ASSERT(count > 0); + ANGLE_TRY(mRenderer->getStateManager()->updateState(context, mode, first, count, + gl::DrawElementsType::InvalidEnum, nullptr, + instanceCount, 0, baseInstance, true)); + return mRenderer->drawArrays(context, mode, first, count, instanceCount, baseInstance, true); +} + +ANGLE_INLINE angle::Result Context11::drawElementsImpl(const gl::Context *context, + gl::PrimitiveMode mode, + GLsizei indexCount, + gl::DrawElementsType indexType, + const void *indices, + GLsizei instanceCount, + GLint baseVertex, + GLuint baseInstance, + bool promoteDynamic, + bool isInstancedDraw) +{ + ASSERT(indexCount > 0); + + if (DrawCallHasDynamicAttribs(context)) + { + gl::IndexRange indexRange; + ANGLE_TRY(context->getState().getVertexArray()->getIndexRange( + context, indexType, indexCount, indices, &indexRange)); + GLint startVertex; + ANGLE_TRY(ComputeStartVertex(GetImplAs(context), indexRange, baseVertex, + &startVertex)); + ANGLE_TRY(mRenderer->getStateManager()->updateState( + context, mode, startVertex, indexCount, indexType, indices, instanceCount, baseVertex, + baseInstance, promoteDynamic)); + return mRenderer->drawElements(context, mode, startVertex, indexCount, indexType, indices, + instanceCount, baseVertex, baseInstance, isInstancedDraw); + } + else + { + ANGLE_TRY(mRenderer->getStateManager()->updateState(context, mode, 0, indexCount, indexType, + indices, instanceCount, baseVertex, + baseInstance, promoteDynamic)); + return mRenderer->drawElements(context, mode, 0, indexCount, indexType, indices, + instanceCount, baseVertex, baseInstance, isInstancedDraw); + } +} + +angle::Result Context11::drawElements(const gl::Context *context, + gl::PrimitiveMode mode, + GLsizei count, + gl::DrawElementsType type, + const void *indices) +{ + return drawElementsImpl(context, mode, count, type, indices, 0, 0, 0, true, false); +} + +angle::Result Context11::drawElementsBaseVertex(const gl::Context *context, + gl::PrimitiveMode mode, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + GLint baseVertex) +{ + return drawElementsImpl(context, mode, count, type, indices, 0, baseVertex, 0, true, false); +} + +angle::Result Context11::drawElementsInstanced(const gl::Context *context, + gl::PrimitiveMode mode, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + GLsizei instances) +{ + return drawElementsImpl(context, mode, count, type, indices, instances, 0, 0, true, true); +} + +angle::Result Context11::drawElementsInstancedBaseVertex(const gl::Context *context, + gl::PrimitiveMode mode, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + GLsizei instances, + GLint baseVertex) +{ + return drawElementsImpl(context, mode, count, type, indices, instances, baseVertex, 0, true, + true); +} + +angle::Result Context11::drawElementsInstancedBaseVertexBaseInstance(const gl::Context *context, + gl::PrimitiveMode mode, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + GLsizei instances, + GLint baseVertex, + GLuint baseInstance) +{ + return drawElementsImpl(context, mode, count, type, indices, instances, baseVertex, + baseInstance, true, true); +} + +angle::Result Context11::drawRangeElements(const gl::Context *context, + gl::PrimitiveMode mode, + GLuint start, + GLuint end, + GLsizei count, + gl::DrawElementsType type, + const void *indices) +{ + return drawElementsImpl(context, mode, count, type, indices, 0, 0, 0, true, false); +} + +angle::Result Context11::drawRangeElementsBaseVertex(const gl::Context *context, + gl::PrimitiveMode mode, + GLuint start, + GLuint end, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + GLint baseVertex) +{ + return drawElementsImpl(context, mode, count, type, indices, 0, baseVertex, 0, true, false); +} + +angle::Result Context11::drawArraysIndirect(const gl::Context *context, + gl::PrimitiveMode mode, + const void *indirect) +{ + if (DrawCallHasStreamingVertexArrays(context, mode)) + { + const gl::DrawArraysIndirectCommand *cmd = nullptr; + ANGLE_TRY(ReadbackIndirectBuffer(context, indirect, &cmd)); + + ANGLE_TRY(mRenderer->getStateManager()->updateState( + context, mode, cmd->first, cmd->count, gl::DrawElementsType::InvalidEnum, nullptr, + cmd->instanceCount, 0, 0, true)); + return mRenderer->drawArrays(context, mode, cmd->first, cmd->count, cmd->instanceCount, + cmd->baseInstance, true); + } + else + { + ANGLE_TRY(mRenderer->getStateManager()->updateState( + context, mode, 0, 0, gl::DrawElementsType::InvalidEnum, nullptr, 0, 0, 0, true)); + return mRenderer->drawArraysIndirect(context, indirect); + } +} + +angle::Result Context11::drawElementsIndirect(const gl::Context *context, + gl::PrimitiveMode mode, + gl::DrawElementsType type, + const void *indirect) +{ + if (DrawCallHasStreamingVertexArrays(context, mode) || + DrawCallHasStreamingElementArray(context, type)) + { + const gl::DrawElementsIndirectCommand *cmd = nullptr; + ANGLE_TRY(ReadbackIndirectBuffer(context, indirect, &cmd)); + + const GLuint typeBytes = gl::GetDrawElementsTypeSize(type); + const void *indices = + reinterpret_cast(static_cast(cmd->firstIndex * typeBytes)); + + // We must explicitly resolve the index range for the slow-path indirect drawElements to + // make sure we are using the correct 'baseVertex'. This parameter does not exist for the + // direct drawElements. + gl::IndexRange indexRange; + ANGLE_TRY(context->getState().getVertexArray()->getIndexRange(context, type, cmd->count, + indices, &indexRange)); + + GLint startVertex; + ANGLE_TRY(ComputeStartVertex(GetImplAs(context), indexRange, cmd->baseVertex, + &startVertex)); + + ANGLE_TRY(mRenderer->getStateManager()->updateState( + context, mode, startVertex, cmd->count, type, indices, cmd->primCount, cmd->baseVertex, + cmd->baseInstance, true)); + return mRenderer->drawElements(context, mode, static_cast(indexRange.start), + cmd->count, type, indices, cmd->primCount, 0, 0, true); + } + else + { + ANGLE_TRY(mRenderer->getStateManager()->updateState(context, mode, 0, 0, type, nullptr, 0, + 0, 0, true)); + return mRenderer->drawElementsIndirect(context, indirect); + } +} + +#define DRAW_ARRAYS__ \ + { \ + ANGLE_TRY(mRenderer->getStateManager()->updateState( \ + context, mode, firsts[drawID], counts[drawID], gl::DrawElementsType::InvalidEnum, \ + nullptr, 0, 0, 0, false)); \ + ANGLE_TRY( \ + mRenderer->drawArrays(context, mode, firsts[drawID], counts[drawID], 0, 0, false)); \ + } +#define DRAW_ARRAYS_INSTANCED_ \ + { \ + ANGLE_TRY(mRenderer->getStateManager()->updateState( \ + context, mode, firsts[drawID], counts[drawID], gl::DrawElementsType::InvalidEnum, \ + nullptr, instanceCounts[drawID], 0, 0, false)); \ + ANGLE_TRY(mRenderer->drawArrays(context, mode, firsts[drawID], counts[drawID], \ + instanceCounts[drawID], 0, true)); \ + } +#define DRAW_ARRAYS_INSTANCED_BASE_INSTANCE \ + { \ + ANGLE_TRY(mRenderer->getStateManager()->updateState( \ + context, mode, firsts[drawID], counts[drawID], gl::DrawElementsType::InvalidEnum, \ + nullptr, instanceCounts[drawID], 0, baseInstances[drawID], false)); \ + ANGLE_TRY(mRenderer->drawArrays(context, mode, firsts[drawID], counts[drawID], \ + instanceCounts[drawID], baseInstances[drawID], true)); \ + } +#define DRAW_ELEMENTS__ \ + { \ + ANGLE_TRY(drawElementsImpl(context, mode, counts[drawID], type, indices[drawID], 0, 0, 0, \ + false, false)); \ + } +#define DRAW_ELEMENTS_INSTANCED_ \ + { \ + ANGLE_TRY(drawElementsImpl(context, mode, counts[drawID], type, indices[drawID], \ + instanceCounts[drawID], 0, 0, false, true)); \ + } +#define DRAW_ELEMENTS_INSTANCED_BASE_VERTEX_BASE_INSTANCE \ + { \ + ANGLE_TRY(drawElementsImpl(context, mode, counts[drawID], type, indices[drawID], \ + instanceCounts[drawID], baseVertices[drawID], \ + baseInstances[drawID], false, true)); \ + } + +#define DRAW_CALL(drawType, instanced, bvbi) DRAW_##drawType##instanced##bvbi + +#define MULTI_DRAW_BLOCK(drawType, instanced, bvbi, hasDrawID, hasBaseVertex, hasBaseInstance) \ + for (GLsizei drawID = 0; drawID < drawcount; ++drawID) \ + { \ + if (ANGLE_NOOP_DRAW(instanced)) \ + { \ + continue; \ + } \ + ANGLE_SET_DRAW_ID_UNIFORM(hasDrawID)(drawID); \ + ANGLE_SET_BASE_VERTEX_UNIFORM(hasBaseVertex)(baseVertices[drawID]); \ + ANGLE_SET_BASE_INSTANCE_UNIFORM(hasBaseInstance)(baseInstances[drawID]); \ + ASSERT(counts[drawID] > 0); \ + DRAW_CALL(drawType, instanced, bvbi); \ + ANGLE_MARK_TRANSFORM_FEEDBACK_USAGE(instanced); \ + gl::MarkShaderStorageUsage(context); \ + } + +angle::Result Context11::multiDrawArrays(const gl::Context *context, + gl::PrimitiveMode mode, + const GLint *firsts, + const GLsizei *counts, + GLsizei drawcount) +{ + gl::Program *programObject = context->getState().getLinkedProgram(context); + const bool hasDrawID = programObject && programObject->hasDrawIDUniform(); + if (hasDrawID) + { + MULTI_DRAW_BLOCK(ARRAYS, _, _, 1, 0, 0) + } + else + { + MULTI_DRAW_BLOCK(ARRAYS, _, _, 0, 0, 0) + } + + return angle::Result::Continue; +} + +angle::Result Context11::multiDrawArraysInstanced(const gl::Context *context, + gl::PrimitiveMode mode, + const GLint *firsts, + const GLsizei *counts, + const GLsizei *instanceCounts, + GLsizei drawcount) +{ + gl::Program *programObject = context->getState().getLinkedProgram(context); + const bool hasDrawID = programObject && programObject->hasDrawIDUniform(); + if (hasDrawID) + { + MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _, 1, 0, 0) + } + else + { + MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _, 0, 0, 0) + } + + return angle::Result::Continue; +} + +angle::Result Context11::multiDrawArraysIndirect(const gl::Context *context, + gl::PrimitiveMode mode, + const void *indirect, + GLsizei drawcount, + GLsizei stride) +{ + return rx::MultiDrawArraysIndirectGeneral(this, context, mode, indirect, drawcount, stride); +} + +angle::Result Context11::multiDrawElements(const gl::Context *context, + gl::PrimitiveMode mode, + const GLsizei *counts, + gl::DrawElementsType type, + const GLvoid *const *indices, + GLsizei drawcount) +{ + gl::Program *programObject = context->getState().getLinkedProgram(context); + const bool hasDrawID = programObject && programObject->hasDrawIDUniform(); + if (hasDrawID) + { + MULTI_DRAW_BLOCK(ELEMENTS, _, _, 1, 0, 0) + } + else + { + MULTI_DRAW_BLOCK(ELEMENTS, _, _, 0, 0, 0) + } + + return angle::Result::Continue; +} + +angle::Result Context11::multiDrawElementsInstanced(const gl::Context *context, + gl::PrimitiveMode mode, + const GLsizei *counts, + gl::DrawElementsType type, + const GLvoid *const *indices, + const GLsizei *instanceCounts, + GLsizei drawcount) +{ + gl::Program *programObject = context->getState().getLinkedProgram(context); + const bool hasDrawID = programObject && programObject->hasDrawIDUniform(); + if (hasDrawID) + { + MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _, 1, 0, 0) + } + else + { + MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _, 0, 0, 0) + } + + return angle::Result::Continue; +} + +angle::Result Context11::multiDrawElementsIndirect(const gl::Context *context, + gl::PrimitiveMode mode, + gl::DrawElementsType type, + const void *indirect, + GLsizei drawcount, + GLsizei stride) +{ + return rx::MultiDrawElementsIndirectGeneral(this, context, mode, type, indirect, drawcount, + stride); +} + +angle::Result Context11::multiDrawArraysInstancedBaseInstance(const gl::Context *context, + gl::PrimitiveMode mode, + const GLint *firsts, + const GLsizei *counts, + const GLsizei *instanceCounts, + const GLuint *baseInstances, + GLsizei drawcount) +{ + gl::Program *programObject = context->getState().getLinkedProgram(context); + const bool hasDrawID = programObject && programObject->hasDrawIDUniform(); + const bool hasBaseInstance = programObject && programObject->hasBaseInstanceUniform(); + ResetBaseVertexBaseInstance resetUniforms(programObject, false, hasBaseInstance); + + if (hasDrawID && hasBaseInstance) + { + MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _BASE_INSTANCE, 1, 0, 1) + } + else if (hasDrawID) + { + MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _BASE_INSTANCE, 1, 0, 0) + } + else if (hasBaseInstance) + { + MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _BASE_INSTANCE, 0, 0, 1) + } + else + { + MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _BASE_INSTANCE, 0, 0, 0) + } + + return angle::Result::Continue; +} + +angle::Result Context11::multiDrawElementsInstancedBaseVertexBaseInstance( + const gl::Context *context, + gl::PrimitiveMode mode, + const GLsizei *counts, + gl::DrawElementsType type, + const GLvoid *const *indices, + const GLsizei *instanceCounts, + const GLint *baseVertices, + const GLuint *baseInstances, + GLsizei drawcount) +{ + gl::Program *programObject = context->getState().getLinkedProgram(context); + const bool hasDrawID = programObject && programObject->hasDrawIDUniform(); + const bool hasBaseVertex = programObject && programObject->hasBaseVertexUniform(); + const bool hasBaseInstance = programObject && programObject->hasBaseInstanceUniform(); + ResetBaseVertexBaseInstance resetUniforms(programObject, hasBaseVertex, hasBaseInstance); + + if (hasDrawID) + { + if (hasBaseVertex) + { + if (hasBaseInstance) + { + MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 1, 1, 1) + } + else + { + MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 1, 1, 0) + } + } + else + { + if (hasBaseInstance) + { + MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 1, 0, 1) + } + else + { + MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 1, 0, 0) + } + } + } + else + { + if (hasBaseVertex) + { + if (hasBaseInstance) + { + MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 0, 1, 1) + } + else + { + MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 0, 1, 0) + } + } + else + { + if (hasBaseInstance) + { + MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 0, 0, 1) + } + else + { + MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 0, 0, 0) + } + } + } + + return angle::Result::Continue; +} + +gl::GraphicsResetStatus Context11::getResetStatus() +{ + return mRenderer->getResetStatus(); +} + +angle::Result Context11::insertEventMarker(GLsizei length, const char *marker) +{ + mRenderer->getDebugAnnotatorContext()->setMarker(marker); + return angle::Result::Continue; +} + +angle::Result Context11::pushGroupMarker(GLsizei length, const char *marker) +{ + mRenderer->getDebugAnnotatorContext()->beginEvent(angle::EntryPoint::GLPushGroupMarkerEXT, + marker, marker); + mMarkerStack.push(std::string(marker)); + return angle::Result::Continue; +} + +angle::Result Context11::popGroupMarker() +{ + const char *marker = nullptr; + if (!mMarkerStack.empty()) + { + marker = mMarkerStack.top().c_str(); + mMarkerStack.pop(); + mRenderer->getDebugAnnotatorContext()->endEvent(marker, + angle::EntryPoint::GLPopGroupMarkerEXT); + } + return angle::Result::Continue; +} + +angle::Result Context11::pushDebugGroup(const gl::Context *context, + GLenum source, + GLuint id, + const std::string &message) +{ + // Fall through to the EXT_debug_marker functions + return pushGroupMarker(static_cast(message.size()), message.c_str()); +} + +angle::Result Context11::popDebugGroup(const gl::Context *context) +{ + // Fall through to the EXT_debug_marker functions + return popGroupMarker(); +} + +angle::Result Context11::syncState(const gl::Context *context, + const gl::State::DirtyBits &dirtyBits, + const gl::State::DirtyBits &bitMask, + gl::Command command) +{ + mRenderer->getStateManager()->syncState(context, dirtyBits, command); + return angle::Result::Continue; +} + +GLint Context11::getGPUDisjoint() +{ + return mRenderer->getGPUDisjoint(); +} + +GLint64 Context11::getTimestamp() +{ + return mRenderer->getTimestamp(); +} + +angle::Result Context11::onMakeCurrent(const gl::Context *context) +{ + // Immediately return if the device has been lost. + if (!mRenderer->getDevice()) + { + return angle::Result::Continue; + } + + return mRenderer->getStateManager()->onMakeCurrent(context); +} + +gl::Caps Context11::getNativeCaps() const +{ + gl::Caps caps = mRenderer->getNativeCaps(); + + // For pixel shaders, the render targets and unordered access views share the same resource + // slots, so the maximum number of fragment shader outputs depends on the current context + // version: + // - If current context is ES 3.0 and below, we use D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT(8) + // as the value of max draw buffers because UAVs are not used. + // - If current context is ES 3.1 and the feature level is 11_0, the RTVs and UAVs share 8 + // slots. As ES 3.1 requires at least 1 atomic counter buffer in compute shaders, the value + // of max combined shader output resources is limited to 7, thus only 7 RTV slots can be + // used simultaneously. + // - If current context is ES 3.1 and the feature level is 11_1, the RTVs and UAVs share 64 + // slots. Currently we allocate 60 slots for combined shader output resources, so we can use + // at most D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT(8) RTVs simultaneously. + if (mState.getClientVersion() >= gl::ES_3_1 && + mRenderer->getRenderer11DeviceCaps().featureLevel == D3D_FEATURE_LEVEL_11_0) + { + caps.maxDrawBuffers = caps.maxCombinedShaderOutputResources; + caps.maxColorAttachments = caps.maxCombinedShaderOutputResources; + } + + return caps; +} + +const gl::TextureCapsMap &Context11::getNativeTextureCaps() const +{ + return mRenderer->getNativeTextureCaps(); +} + +const gl::Extensions &Context11::getNativeExtensions() const +{ + return mRenderer->getNativeExtensions(); +} + +const gl::Limitations &Context11::getNativeLimitations() const +{ + return mRenderer->getNativeLimitations(); +} + +ShPixelLocalStorageType Context11::getNativePixelLocalStorageType() const +{ + return mRenderer->getNativePixelLocalStorageType(); +} + +angle::Result Context11::dispatchCompute(const gl::Context *context, + GLuint numGroupsX, + GLuint numGroupsY, + GLuint numGroupsZ) +{ + return mRenderer->dispatchCompute(context, numGroupsX, numGroupsY, numGroupsZ); +} + +angle::Result Context11::dispatchComputeIndirect(const gl::Context *context, GLintptr indirect) +{ + return mRenderer->dispatchComputeIndirect(context, indirect); +} + +angle::Result Context11::triggerDrawCallProgramRecompilation(const gl::Context *context, + gl::PrimitiveMode drawMode) +{ + const auto &glState = context->getState(); + const auto *va11 = GetImplAs(glState.getVertexArray()); + const auto *drawFBO = glState.getDrawFramebuffer(); + gl::Program *program = glState.getProgram(); + ProgramD3D *programD3D = GetImplAs(program); + + programD3D->updateCachedInputLayout(va11->getCurrentStateSerial(), glState); + programD3D->updateCachedOutputLayout(context, drawFBO); + + bool recompileVS = !programD3D->hasVertexExecutableForCachedInputLayout(); + bool recompileGS = !programD3D->hasGeometryExecutableForPrimitiveType(glState, drawMode); + bool recompilePS = !programD3D->hasPixelExecutableForCachedOutputLayout(); + + if (!recompileVS && !recompileGS && !recompilePS) + { + return angle::Result::Continue; + } + + // Load the compiler if necessary and recompile the programs. + ANGLE_TRY(mRenderer->ensureHLSLCompilerInitialized(this)); + + gl::InfoLog infoLog; + + if (recompileVS) + { + ShaderExecutableD3D *vertexExe = nullptr; + ANGLE_TRY(programD3D->getVertexExecutableForCachedInputLayout(this, &vertexExe, &infoLog)); + if (!programD3D->hasVertexExecutableForCachedInputLayout()) + { + ASSERT(infoLog.getLength() > 0); + ERR() << "Error compiling dynamic vertex executable: " << infoLog.str(); + ANGLE_TRY_HR(this, E_FAIL, "Error compiling dynamic vertex executable"); + } + } + + if (recompileGS) + { + ShaderExecutableD3D *geometryExe = nullptr; + ANGLE_TRY(programD3D->getGeometryExecutableForPrimitiveType(this, glState, drawMode, + &geometryExe, &infoLog)); + if (!programD3D->hasGeometryExecutableForPrimitiveType(glState, drawMode)) + { + ASSERT(infoLog.getLength() > 0); + ERR() << "Error compiling dynamic geometry executable: " << infoLog.str(); + ANGLE_TRY_HR(this, E_FAIL, "Error compiling dynamic geometry executable"); + } + } + + if (recompilePS) + { + ShaderExecutableD3D *pixelExe = nullptr; + ANGLE_TRY(programD3D->getPixelExecutableForCachedOutputLayout(this, &pixelExe, &infoLog)); + if (!programD3D->hasPixelExecutableForCachedOutputLayout()) + { + ASSERT(infoLog.getLength() > 0); + ERR() << "Error compiling dynamic pixel executable: " << infoLog.str(); + ANGLE_TRY_HR(this, E_FAIL, "Error compiling dynamic pixel executable"); + } + } + + // Refresh the program cache entry. + if (mMemoryProgramCache) + { + ANGLE_TRY(mMemoryProgramCache->updateProgram(context, program)); + } + + return angle::Result::Continue; +} + +angle::Result Context11::triggerDispatchCallProgramRecompilation(const gl::Context *context) +{ + const auto &glState = context->getState(); + gl::Program *program = glState.getProgram(); + ProgramD3D *programD3D = GetImplAs(program); + + programD3D->updateCachedComputeImage2DBindLayout(context); + + bool recompileCS = !programD3D->hasComputeExecutableForCachedImage2DBindLayout(); + + if (!recompileCS) + { + return angle::Result::Continue; + } + + // Load the compiler if necessary and recompile the programs. + ANGLE_TRY(mRenderer->ensureHLSLCompilerInitialized(this)); + + gl::InfoLog infoLog; + + ShaderExecutableD3D *computeExe = nullptr; + ANGLE_TRY( + programD3D->getComputeExecutableForImage2DBindLayout(context, this, &computeExe, &infoLog)); + if (!programD3D->hasComputeExecutableForCachedImage2DBindLayout()) + { + ASSERT(infoLog.getLength() > 0); + ERR() << "Dynamic recompilation error log: " << infoLog.str(); + ANGLE_TRY_HR(this, E_FAIL, "Error compiling dynamic compute executable"); + } + + // Refresh the program cache entry. + if (mMemoryProgramCache) + { + ANGLE_TRY(mMemoryProgramCache->updateProgram(context, program)); + } + + return angle::Result::Continue; +} + +angle::Result Context11::memoryBarrier(const gl::Context *context, GLbitfield barriers) +{ + return angle::Result::Continue; +} + +angle::Result Context11::memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers) +{ + return angle::Result::Continue; +} + +angle::Result Context11::getIncompleteTexture(const gl::Context *context, + gl::TextureType type, + gl::Texture **textureOut) +{ + return mIncompleteTextures.getIncompleteTexture(context, type, gl::SamplerFormat::Float, this, + textureOut); +} + +angle::Result Context11::initializeMultisampleTextureToBlack(const gl::Context *context, + gl::Texture *glTexture) +{ + ASSERT(glTexture->getType() == gl::TextureType::_2DMultisample); + TextureD3D *textureD3D = GetImplAs(glTexture); + gl::ImageIndex index = gl::ImageIndex::Make2DMultisample(); + RenderTargetD3D *renderTarget = nullptr; + GLsizei texSamples = textureD3D->getRenderToTextureSamples(); + ANGLE_TRY(textureD3D->getRenderTarget(context, index, texSamples, &renderTarget)); + return mRenderer->clearRenderTarget(context, renderTarget, gl::ColorF(0.0f, 0.0f, 0.0f, 1.0f), + 1.0f, 0); +} + +void Context11::handleResult(HRESULT hr, + const char *message, + const char *file, + const char *function, + unsigned int line) +{ + ASSERT(FAILED(hr)); + + GLenum glErrorCode = DefaultGLErrorCode(hr); + + std::stringstream errorStream; + errorStream << "Internal D3D11 error: " << gl::FmtHR(hr); + + if (d3d11::isDeviceLostError(hr)) + { + HRESULT removalReason = mRenderer->getDevice()->GetDeviceRemovedReason(); + errorStream << " (removal reason: " << gl::FmtHR(removalReason) << ")"; + mRenderer->notifyDeviceLost(); + } + + errorStream << ": " << message; + + mErrors->handleError(glErrorCode, errorStream.str().c_str(), file, function, line); +} +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Context11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Context11.h new file mode 100644 index 0000000000..5f84e410b5 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Context11.h @@ -0,0 +1,282 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Context11: +// D3D11-specific functionality associated with a GL Context. +// + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_CONTEXT11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_CONTEXT11_H_ + +#include +#include "libANGLE/renderer/ContextImpl.h" +#include "libANGLE/renderer/d3d/ContextD3D.h" + +namespace rx +{ +class Renderer11; + +class Context11 : public ContextD3D, public MultisampleTextureInitializer +{ + public: + Context11(const gl::State &state, gl::ErrorSet *errorSet, Renderer11 *renderer); + ~Context11() override; + + angle::Result initialize() override; + void onDestroy(const gl::Context *context) override; + + // Shader creation + CompilerImpl *createCompiler() override; + ShaderImpl *createShader(const gl::ShaderState &data) override; + ProgramImpl *createProgram(const gl::ProgramState &data) override; + + // Framebuffer creation + FramebufferImpl *createFramebuffer(const gl::FramebufferState &data) override; + + // Texture creation + TextureImpl *createTexture(const gl::TextureState &state) override; + + // Renderbuffer creation + RenderbufferImpl *createRenderbuffer(const gl::RenderbufferState &state) override; + + // Buffer creation + BufferImpl *createBuffer(const gl::BufferState &state) override; + + // Vertex Array creation + VertexArrayImpl *createVertexArray(const gl::VertexArrayState &data) override; + + // Query and Fence creation + QueryImpl *createQuery(gl::QueryType type) override; + FenceNVImpl *createFenceNV() override; + SyncImpl *createSync() override; + + // Transform Feedback creation + TransformFeedbackImpl *createTransformFeedback( + const gl::TransformFeedbackState &state) override; + + // Sampler object creation + SamplerImpl *createSampler(const gl::SamplerState &state) override; + + // Program Pipeline object creation + ProgramPipelineImpl *createProgramPipeline(const gl::ProgramPipelineState &data) override; + + // Memory object creation. + MemoryObjectImpl *createMemoryObject() override; + + // Semaphore creation. + SemaphoreImpl *createSemaphore() override; + + // Overlay creation. + OverlayImpl *createOverlay(const gl::OverlayState &state) override; + + // Flush and finish. + angle::Result flush(const gl::Context *context) override; + angle::Result finish(const gl::Context *context) override; + + // Drawing methods. + angle::Result drawArrays(const gl::Context *context, + gl::PrimitiveMode mode, + GLint first, + GLsizei count) override; + angle::Result drawArraysInstanced(const gl::Context *context, + gl::PrimitiveMode mode, + GLint first, + GLsizei count, + GLsizei instanceCount) override; + angle::Result drawArraysInstancedBaseInstance(const gl::Context *context, + gl::PrimitiveMode mode, + GLint first, + GLsizei count, + GLsizei instanceCount, + GLuint baseInstance) override; + + angle::Result drawElements(const gl::Context *context, + gl::PrimitiveMode mode, + GLsizei count, + gl::DrawElementsType type, + const void *indices) override; + angle::Result drawElementsBaseVertex(const gl::Context *context, + gl::PrimitiveMode mode, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + GLint baseVertex) override; + angle::Result drawElementsInstanced(const gl::Context *context, + gl::PrimitiveMode mode, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + GLsizei instances) override; + angle::Result drawElementsInstancedBaseVertex(const gl::Context *context, + gl::PrimitiveMode mode, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + GLsizei instances, + GLint baseVertex) override; + angle::Result drawElementsInstancedBaseVertexBaseInstance(const gl::Context *context, + gl::PrimitiveMode mode, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + GLsizei instances, + GLint baseVertex, + GLuint baseInstance) override; + angle::Result drawRangeElements(const gl::Context *context, + gl::PrimitiveMode mode, + GLuint start, + GLuint end, + GLsizei count, + gl::DrawElementsType type, + const void *indices) override; + angle::Result drawRangeElementsBaseVertex(const gl::Context *context, + gl::PrimitiveMode mode, + GLuint start, + GLuint end, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + GLint baseVertex) override; + angle::Result drawArraysIndirect(const gl::Context *context, + gl::PrimitiveMode mode, + const void *indirect) override; + angle::Result drawElementsIndirect(const gl::Context *context, + gl::PrimitiveMode mode, + gl::DrawElementsType type, + const void *indirect) override; + + angle::Result multiDrawArrays(const gl::Context *context, + gl::PrimitiveMode mode, + const GLint *firsts, + const GLsizei *counts, + GLsizei drawcount) override; + angle::Result multiDrawArraysInstanced(const gl::Context *context, + gl::PrimitiveMode mode, + const GLint *firsts, + const GLsizei *counts, + const GLsizei *instanceCounts, + GLsizei drawcount) override; + angle::Result multiDrawArraysIndirect(const gl::Context *context, + gl::PrimitiveMode mode, + const void *indirect, + GLsizei drawcount, + GLsizei stride) override; + angle::Result multiDrawElements(const gl::Context *context, + gl::PrimitiveMode mode, + const GLsizei *counts, + gl::DrawElementsType type, + const GLvoid *const *indices, + GLsizei drawcount) override; + angle::Result multiDrawElementsInstanced(const gl::Context *context, + gl::PrimitiveMode mode, + const GLsizei *counts, + gl::DrawElementsType type, + const GLvoid *const *indices, + const GLsizei *instanceCounts, + GLsizei drawcount) override; + angle::Result multiDrawElementsIndirect(const gl::Context *context, + gl::PrimitiveMode mode, + gl::DrawElementsType type, + const void *indirect, + GLsizei drawcount, + GLsizei stride) override; + angle::Result multiDrawArraysInstancedBaseInstance(const gl::Context *context, + gl::PrimitiveMode mode, + const GLint *firsts, + const GLsizei *counts, + const GLsizei *instanceCounts, + const GLuint *baseInstances, + GLsizei drawcount) override; + angle::Result multiDrawElementsInstancedBaseVertexBaseInstance(const gl::Context *context, + gl::PrimitiveMode mode, + const GLsizei *counts, + gl::DrawElementsType type, + const GLvoid *const *indices, + const GLsizei *instanceCounts, + const GLint *baseVertices, + const GLuint *baseInstances, + GLsizei drawcount) override; + + // Device loss + gl::GraphicsResetStatus getResetStatus() override; + + // EXT_debug_marker + angle::Result insertEventMarker(GLsizei length, const char *marker) override; + angle::Result pushGroupMarker(GLsizei length, const char *marker) override; + angle::Result popGroupMarker() override; + + // KHR_debug + angle::Result pushDebugGroup(const gl::Context *context, + GLenum source, + GLuint id, + const std::string &message) override; + angle::Result popDebugGroup(const gl::Context *context) override; + + // State sync with dirty bits. + angle::Result syncState(const gl::Context *context, + const gl::State::DirtyBits &dirtyBits, + const gl::State::DirtyBits &bitMask, + gl::Command command) override; + + // Disjoint timer queries + GLint getGPUDisjoint() override; + GLint64 getTimestamp() override; + + // Context switching + angle::Result onMakeCurrent(const gl::Context *context) override; + + // Caps queries + gl::Caps getNativeCaps() const override; + const gl::TextureCapsMap &getNativeTextureCaps() const override; + const gl::Extensions &getNativeExtensions() const override; + const gl::Limitations &getNativeLimitations() const override; + ShPixelLocalStorageType getNativePixelLocalStorageType() const override; + + Renderer11 *getRenderer() const { return mRenderer; } + + angle::Result dispatchCompute(const gl::Context *context, + GLuint numGroupsX, + GLuint numGroupsY, + GLuint numGroupsZ) override; + angle::Result dispatchComputeIndirect(const gl::Context *context, GLintptr indirect) override; + + angle::Result memoryBarrier(const gl::Context *context, GLbitfield barriers) override; + angle::Result memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers) override; + + angle::Result triggerDrawCallProgramRecompilation(const gl::Context *context, + gl::PrimitiveMode drawMode); + angle::Result triggerDispatchCallProgramRecompilation(const gl::Context *context); + angle::Result getIncompleteTexture(const gl::Context *context, + gl::TextureType type, + gl::Texture **textureOut); + + angle::Result initializeMultisampleTextureToBlack(const gl::Context *context, + gl::Texture *glTexture) override; + + void handleResult(HRESULT hr, + const char *message, + const char *file, + const char *function, + unsigned int line) override; + + private: + angle::Result drawElementsImpl(const gl::Context *context, + gl::PrimitiveMode mode, + GLsizei indexCount, + gl::DrawElementsType indexType, + const void *indices, + GLsizei instanceCount, + GLint baseVertex, + GLuint baseInstance, + bool promoteDynamic, + bool isInstancedDraw); + + Renderer11 *mRenderer; + IncompleteTextureSet mIncompleteTextures; + std::stack mMarkerStack; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_CONTEXT11_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp new file mode 100644 index 0000000000..2b947d8957 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp @@ -0,0 +1,148 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// DebugAnnotator11.cpp: D3D11 helpers for adding trace annotations. +// + +#include "libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h" + +#include "libANGLE/renderer/d3d/d3d11/Context11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" + +#include + +#include "common/system_utils.h" + +namespace rx +{ + +// DebugAnnotator11 implementation +DebugAnnotator11::DebugAnnotator11() {} + +DebugAnnotator11::~DebugAnnotator11() {} + +void DebugAnnotator11::beginEvent(gl::Context *context, + angle::EntryPoint entryPoint, + const char *eventName, + const char *eventMessage) +{ + angle::LoggingAnnotator::beginEvent(context, entryPoint, eventName, eventMessage); + if (!context) + { + return; + } + Renderer11 *renderer11 = GetImplAs(context)->getRenderer(); + renderer11->getDebugAnnotatorContext()->beginEvent(entryPoint, eventName, eventMessage); +} + +void DebugAnnotator11::endEvent(gl::Context *context, + const char *eventName, + angle::EntryPoint entryPoint) +{ + angle::LoggingAnnotator::endEvent(context, eventName, entryPoint); + if (!context) + { + return; + } + Renderer11 *renderer11 = GetImplAs(context)->getRenderer(); + renderer11->getDebugAnnotatorContext()->endEvent(eventName, entryPoint); +} + +void DebugAnnotator11::setMarker(gl::Context *context, const char *markerName) +{ + angle::LoggingAnnotator::setMarker(context, markerName); + if (!context) + { + return; + } + Renderer11 *renderer11 = GetImplAs(context)->getRenderer(); + renderer11->getDebugAnnotatorContext()->setMarker(markerName); +} + +bool DebugAnnotator11::getStatus(const gl::Context *context) +{ + if (!context) + { + return false; + } + Renderer11 *renderer11 = GetImplAs(context)->getRenderer(); + return renderer11->getDebugAnnotatorContext()->getStatus(); +} + +// DebugAnnotatorContext11 implemenetation +DebugAnnotatorContext11::DebugAnnotatorContext11() = default; + +DebugAnnotatorContext11::~DebugAnnotatorContext11() = default; + +void DebugAnnotatorContext11::beginEvent(angle::EntryPoint entryPoint, + const char *eventName, + const char *eventMessage) +{ + if (loggingEnabledForThisThread()) + { + std::mbstate_t state = std::mbstate_t(); + std::mbsrtowcs(mWCharMessage, &eventMessage, kMaxMessageLength, &state); + mUserDefinedAnnotation->BeginEvent(mWCharMessage); + } +} + +void DebugAnnotatorContext11::endEvent(const char *eventName, angle::EntryPoint entryPoint) +{ + if (loggingEnabledForThisThread()) + { + mUserDefinedAnnotation->EndEvent(); + } +} + +void DebugAnnotatorContext11::setMarker(const char *markerName) +{ + if (loggingEnabledForThisThread()) + { + std::mbstate_t state = std::mbstate_t(); + std::mbsrtowcs(mWCharMessage, &markerName, kMaxMessageLength, &state); + mUserDefinedAnnotation->SetMarker(mWCharMessage); + } +} + +bool DebugAnnotatorContext11::getStatus() const +{ + if (loggingEnabledForThisThread()) + { + return !!(mUserDefinedAnnotation->GetStatus()); + } + + return false; +} + +bool DebugAnnotatorContext11::loggingEnabledForThisThread() const +{ + return mUserDefinedAnnotation != nullptr && + angle::GetCurrentThreadUniqueId() == mAnnotationThread; +} + +void DebugAnnotatorContext11::initialize(ID3D11DeviceContext *context) +{ +#if !defined(ANGLE_ENABLE_WINDOWS_UWP) + // ID3DUserDefinedAnnotation.GetStatus only works on Windows10 or greater. + // Returning true unconditionally from DebugAnnotatorContext11::getStatus() means + // writing out all compiled shaders to temporary files even if debugging + // tools are not attached. See rx::ShaderD3D::prepareSourceAndReturnOptions. + // If you want debug annotations, you must use Windows 10. + if (IsWindows10OrGreater()) +#endif + { + mAnnotationThread = angle::GetCurrentThreadUniqueId(); + mUserDefinedAnnotation.Attach( + d3d11::DynamicCastComObject(context)); + } +} + +void DebugAnnotatorContext11::release() +{ + mUserDefinedAnnotation.Reset(); +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h new file mode 100644 index 0000000000..0356636762 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h @@ -0,0 +1,60 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// DebugAnnotator11.h: D3D11 helpers for adding trace annotations. +// + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_DEBUGANNOTATOR11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_DEBUGANNOTATOR11_H_ + +#include "libANGLE/LoggingAnnotator.h" + +namespace rx +{ + +// Note: To avoid any race conditions between threads, this class has no private data; +// DebugAnnotatorContext11 will be retrieved from Context11. +class DebugAnnotator11 : public angle::LoggingAnnotator +{ + public: + DebugAnnotator11(); + ~DebugAnnotator11() override; + void beginEvent(gl::Context *context, + angle::EntryPoint entryPoint, + const char *eventName, + const char *eventMessage) override; + void endEvent(gl::Context *context, + const char *eventName, + angle::EntryPoint entryPoint) override; + void setMarker(gl::Context *context, const char *markerName) override; + bool getStatus(const gl::Context *context) override; +}; + +class DebugAnnotatorContext11 +{ + public: + DebugAnnotatorContext11(); + ~DebugAnnotatorContext11(); + void initialize(ID3D11DeviceContext *context); + void release(); + void beginEvent(angle::EntryPoint entryPoint, const char *eventName, const char *eventMessage); + void endEvent(const char *eventName, angle::EntryPoint entryPoint); + void setMarker(const char *markerName); + bool getStatus() const; + + private: + bool loggingEnabledForThisThread() const; + + angle::ComPtr mUserDefinedAnnotation; + static constexpr size_t kMaxMessageLength = 256; + wchar_t mWCharMessage[kMaxMessageLength]; + + // Only log annotations from the thread used to initialize the debug annotator + uint64_t mAnnotationThread; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_DEBUGANNOTATOR11_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ExternalImageSiblingImpl11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ExternalImageSiblingImpl11.cpp new file mode 100644 index 0000000000..ff2fc8056c --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ExternalImageSiblingImpl11.cpp @@ -0,0 +1,209 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "libANGLE/renderer/d3d/d3d11/ExternalImageSiblingImpl11.h" + +#include "libANGLE/Context.h" +#include "libANGLE/Error.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/d3d11/Context11.h" +#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" + +namespace rx +{ +ExternalImageSiblingImpl11::ExternalImageSiblingImpl11(Renderer11 *renderer, + EGLClientBuffer buffer, + const egl::AttributeMap &attribs) + : mRenderer(renderer), mBuffer(buffer), mAttribs(attribs) +{} + +ExternalImageSiblingImpl11::~ExternalImageSiblingImpl11() {} + +egl::Error ExternalImageSiblingImpl11::initialize(const egl::Display *display) +{ + const angle::Format *angleFormat = nullptr; + ANGLE_TRY(mRenderer->getD3DTextureInfo(nullptr, static_cast(mBuffer), mAttribs, + &mWidth, &mHeight, &mSamples, &mFormat, &angleFormat, + &mArraySlice)); + ID3D11Texture2D *texture = + d3d11::DynamicCastComObject(static_cast(mBuffer)); + ASSERT(texture != nullptr); + // TextureHelper11 will release texture on destruction. + mTexture.set(texture, d3d11::Format::Get(angleFormat->glInternalFormat, + mRenderer->getRenderer11DeviceCaps())); + D3D11_TEXTURE2D_DESC textureDesc = {}; + mTexture.getDesc(&textureDesc); + + IDXGIResource *resource = d3d11::DynamicCastComObject(mTexture.get()); + ASSERT(resource != nullptr); + DXGI_USAGE resourceUsage = 0; + resource->GetUsage(&resourceUsage); + SafeRelease(resource); + + mIsRenderable = (textureDesc.BindFlags & D3D11_BIND_RENDER_TARGET) && + (resourceUsage & DXGI_USAGE_RENDER_TARGET_OUTPUT) && + !(resourceUsage & DXGI_USAGE_READ_ONLY); + + mIsTexturable = (textureDesc.BindFlags & D3D11_BIND_SHADER_RESOURCE) && + (resourceUsage & DXGI_USAGE_SHADER_INPUT); + + mIsTextureArray = (textureDesc.ArraySize > 1); + + return egl::NoError(); +} + +gl::Format ExternalImageSiblingImpl11::getFormat() const +{ + return mFormat; +} + +bool ExternalImageSiblingImpl11::isRenderable(const gl::Context *context) const +{ + return mIsRenderable; +} + +bool ExternalImageSiblingImpl11::isTexturable(const gl::Context *context) const +{ + return mIsTexturable; +} + +bool ExternalImageSiblingImpl11::isYUV() const +{ + return false; +} + +bool ExternalImageSiblingImpl11::hasProtectedContent() const +{ + return false; +} + +gl::Extents ExternalImageSiblingImpl11::getSize() const +{ + return gl::Extents(mWidth, mHeight, 1); +} + +size_t ExternalImageSiblingImpl11::getSamples() const +{ + return mSamples; +} + +angle::Result ExternalImageSiblingImpl11::getAttachmentRenderTarget( + const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex, + GLsizei samples, + FramebufferAttachmentRenderTarget **rtOut) +{ + ANGLE_TRY(createRenderTarget(context)); + *rtOut = mRenderTarget.get(); + return angle::Result::Continue; +} + +angle::Result ExternalImageSiblingImpl11::initializeContents(const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex) +{ + UNREACHABLE(); + return angle::Result::Stop; +} + +angle::Result ExternalImageSiblingImpl11::createRenderTarget(const gl::Context *context) +{ + if (mRenderTarget) + return angle::Result::Continue; + + Context11 *context11 = GetImplAs(context); + const d3d11::Format &formatInfo = mTexture.getFormatSet(); + + d3d11::RenderTargetView rtv; + if (mIsRenderable) + { + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = formatInfo.rtvFormat; + if (mIsTextureArray) + { + if (mSamples == 0) + { + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = 0; + rtvDesc.Texture2DArray.FirstArraySlice = mArraySlice; + rtvDesc.Texture2DArray.ArraySize = 1; + } + else + { + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY; + rtvDesc.Texture2DMSArray.FirstArraySlice = mArraySlice; + rtvDesc.Texture2DMSArray.ArraySize = 1; + } + } + else + { + if (mSamples == 0) + { + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + rtvDesc.Texture2D.MipSlice = 0; + } + else + { + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; + } + } + + ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, mTexture.get(), &rtv)); + rtv.setInternalName("getAttachmentRenderTarget.RTV"); + } + + d3d11::SharedSRV srv; + if (mIsTexturable) + { + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = formatInfo.srvFormat; + if (mIsTextureArray) + { + if (mSamples == 0) + { + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + srvDesc.Texture2DArray.MostDetailedMip = 0; + srvDesc.Texture2DArray.MipLevels = 1; + srvDesc.Texture2DArray.FirstArraySlice = mArraySlice; + srvDesc.Texture2DArray.ArraySize = 1; + } + else + { + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY; + srvDesc.Texture2DArray.FirstArraySlice = mArraySlice; + srvDesc.Texture2DArray.ArraySize = 1; + } + } + else + { + if (mSamples == 0) + { + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + srvDesc.Texture2D.MostDetailedMip = 0; + srvDesc.Texture2D.MipLevels = 1; + } + else + { + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; + } + } + + ANGLE_TRY(mRenderer->allocateResource(context11, srvDesc, mTexture.get(), &srv)); + srv.setInternalName("getAttachmentRenderTarget.SRV"); + } + d3d11::SharedSRV blitSrv = srv.makeCopy(); + + mRenderTarget = std::make_unique( + std::move(rtv), mTexture, std::move(srv), std::move(blitSrv), mFormat.info->internalFormat, + formatInfo, mWidth, mHeight, 1, mSamples); + return angle::Result::Continue; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ExternalImageSiblingImpl11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ExternalImageSiblingImpl11.h new file mode 100644 index 0000000000..3c57120ba2 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ExternalImageSiblingImpl11.h @@ -0,0 +1,70 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_EXTERNALIMAGESIBLINGIMPL11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_EXTERNALIMAGESIBLINGIMPL11_H_ + +#include "libANGLE/renderer/ImageImpl.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" + +namespace rx +{ + +class Renderer11; +class RenderTargetD3D; + +class ExternalImageSiblingImpl11 : public ExternalImageSiblingImpl +{ + public: + ExternalImageSiblingImpl11(Renderer11 *renderer, + EGLClientBuffer clientBuffer, + const egl::AttributeMap &attribs); + ~ExternalImageSiblingImpl11() override; + + // ExternalImageSiblingImpl interface + egl::Error initialize(const egl::Display *display) override; + gl::Format getFormat() const override; + bool isRenderable(const gl::Context *context) const override; + bool isTexturable(const gl::Context *context) const override; + bool isYUV() const override; + bool hasProtectedContent() const override; + gl::Extents getSize() const override; + size_t getSamples() const override; + + // FramebufferAttachmentObjectImpl interface + angle::Result getAttachmentRenderTarget(const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex, + GLsizei samples, + FramebufferAttachmentRenderTarget **rtOut) override; + angle::Result initializeContents(const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex) override; + + private: + angle::Result createRenderTarget(const gl::Context *context); + + Renderer11 *mRenderer; + EGLClientBuffer mBuffer; + egl::AttributeMap mAttribs; + + TextureHelper11 mTexture; + + gl::Format mFormat = gl::Format::Invalid(); + bool mIsRenderable = false; + bool mIsTexturable = false; + bool mIsTextureArray = false; + EGLint mWidth = 0; + EGLint mHeight = 0; + GLsizei mSamples = 0; + UINT mArraySlice = 0; + + std::unique_ptr mRenderTarget; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_EXTERNALIMAGESIBLINGIMPL11_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp new file mode 100644 index 0000000000..38a7331b00 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp @@ -0,0 +1,234 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Fence11.cpp: Defines the rx::FenceNV11 and rx::Sync11 classes which implement +// rx::FenceNVImpl and rx::SyncImpl. + +#include "libANGLE/renderer/d3d/d3d11/Fence11.h" + +#include "common/utilities.h" +#include "libANGLE/Context.h" +#include "libANGLE/renderer/d3d/d3d11/Context11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" + +namespace rx +{ + +// +// Template helpers for set and test operations. +// + +template +angle::Result FenceSetHelper(const gl::Context *context, FenceClass *fence) +{ + if (!fence->mQuery) + { + D3D11_QUERY_DESC queryDesc; + queryDesc.Query = D3D11_QUERY_EVENT; + queryDesc.MiscFlags = 0; + + Context11 *context11 = GetImplAs(context); + HRESULT result = fence->mRenderer->getDevice()->CreateQuery(&queryDesc, &fence->mQuery); + ANGLE_TRY_HR(context11, result, "Failed to create event query"); + } + + fence->mRenderer->getDeviceContext()->End(fence->mQuery); + return angle::Result::Continue; +} + +template +angle::Result FenceTestHelper(const gl::Context *context, + FenceClass *fence, + bool flushCommandBuffer, + GLboolean *outFinished) +{ + ASSERT(fence->mQuery); + + UINT getDataFlags = (flushCommandBuffer ? 0 : D3D11_ASYNC_GETDATA_DONOTFLUSH); + + Context11 *context11 = GetImplAs(context); + HRESULT result = + fence->mRenderer->getDeviceContext()->GetData(fence->mQuery, nullptr, 0, getDataFlags); + ANGLE_TRY_HR(context11, result, "Failed to get query data"); + + ASSERT(result == S_OK || result == S_FALSE); + *outFinished = ((result == S_OK) ? GL_TRUE : GL_FALSE); + return angle::Result::Continue; +} + +// +// FenceNV11 +// + +FenceNV11::FenceNV11(Renderer11 *renderer) : FenceNVImpl(), mRenderer(renderer), mQuery(nullptr) {} + +FenceNV11::~FenceNV11() +{ + SafeRelease(mQuery); +} + +angle::Result FenceNV11::set(const gl::Context *context, GLenum condition) +{ + return FenceSetHelper(context, this); +} + +angle::Result FenceNV11::test(const gl::Context *context, GLboolean *outFinished) +{ + return FenceTestHelper(context, this, true, outFinished); +} + +angle::Result FenceNV11::finish(const gl::Context *context) +{ + GLboolean finished = GL_FALSE; + + int loopCount = 0; + while (finished != GL_TRUE) + { + loopCount++; + ANGLE_TRY(FenceTestHelper(context, this, true, &finished)); + + bool checkDeviceLost = (loopCount % kPollingD3DDeviceLostCheckFrequency) == 0; + if (checkDeviceLost && mRenderer->testDeviceLost()) + { + ANGLE_TRY_HR(GetImplAs(context), DXGI_ERROR_DRIVER_INTERNAL_ERROR, + "Device was lost while querying result of an event query."); + } + + ScheduleYield(); + } + + return angle::Result::Continue; +} + +// +// Sync11 +// + +// Important note on accurate timers in Windows: +// +// QueryPerformanceCounter has a few major issues, including being 10x as expensive to call +// as timeGetTime on laptops and "jumping" during certain hardware events. +// +// See the comments at the top of the Chromium source file "chromium/src/base/time/time_win.cc" +// https://code.google.com/p/chromium/codesearch#chromium/src/base/time/time_win.cc +// +// We still opt to use QPC. In the present and moving forward, most newer systems will not suffer +// from buggy implementations. + +Sync11::Sync11(Renderer11 *renderer) : SyncImpl(), mRenderer(renderer), mQuery(nullptr) +{ + LARGE_INTEGER counterFreqency = {}; + BOOL success = QueryPerformanceFrequency(&counterFreqency); + ASSERT(success); + + mCounterFrequency = counterFreqency.QuadPart; +} + +Sync11::~Sync11() +{ + SafeRelease(mQuery); +} + +angle::Result Sync11::set(const gl::Context *context, GLenum condition, GLbitfield flags) +{ + ASSERT(condition == GL_SYNC_GPU_COMMANDS_COMPLETE && flags == 0); + return FenceSetHelper(context, this); +} + +angle::Result Sync11::clientWait(const gl::Context *context, + GLbitfield flags, + GLuint64 timeout, + GLenum *outResult) +{ + ASSERT(outResult); + + bool flushCommandBuffer = ((flags & GL_SYNC_FLUSH_COMMANDS_BIT) != 0); + + *outResult = GL_WAIT_FAILED; + + GLboolean result = GL_FALSE; + ANGLE_TRY(FenceTestHelper(context, this, flushCommandBuffer, &result)); + + if (result == GL_TRUE) + { + *outResult = GL_ALREADY_SIGNALED; + return angle::Result::Continue; + } + + if (timeout == 0) + { + *outResult = GL_TIMEOUT_EXPIRED; + return angle::Result::Continue; + } + + LARGE_INTEGER currentCounter = {}; + BOOL success = QueryPerformanceCounter(¤tCounter); + ASSERT(success); + + LONGLONG timeoutInSeconds = static_cast(timeout / 1000000000ull); + LONGLONG endCounter = currentCounter.QuadPart + mCounterFrequency * timeoutInSeconds; + + // Extremely unlikely, but if mCounterFrequency is large enough, endCounter can wrap + if (endCounter < currentCounter.QuadPart) + { + endCounter = MAXLONGLONG; + } + + int loopCount = 0; + while (currentCounter.QuadPart < endCounter && !result) + { + loopCount++; + ScheduleYield(); + success = QueryPerformanceCounter(¤tCounter); + ASSERT(success); + + *outResult = GL_WAIT_FAILED; + + ANGLE_TRY(FenceTestHelper(context, this, flushCommandBuffer, &result)); + + bool checkDeviceLost = (loopCount % kPollingD3DDeviceLostCheckFrequency) == 0; + if (checkDeviceLost && mRenderer->testDeviceLost()) + { + *outResult = GL_WAIT_FAILED; + ANGLE_TRY_HR(GetImplAs(context), DXGI_ERROR_DRIVER_INTERNAL_ERROR, + "Device was lost while querying result of an event query."); + } + } + + if (currentCounter.QuadPart >= endCounter) + { + *outResult = GL_TIMEOUT_EXPIRED; + } + else + { + *outResult = GL_CONDITION_SATISFIED; + } + + return angle::Result::Continue; +} + +angle::Result Sync11::serverWait(const gl::Context *context, GLbitfield flags, GLuint64 timeout) +{ + // Because our API is currently designed to be called from a single thread, we don't need to do + // extra work for a server-side fence. GPU commands issued after the fence is created will + // always be processed after the fence is signaled. + return angle::Result::Continue; +} + +angle::Result Sync11::getStatus(const gl::Context *context, GLint *outResult) +{ + GLboolean result = GL_FALSE; + + // The spec does not specify any way to report errors during the status test (e.g. device + // lost) so we report the fence is unblocked in case of error or signaled. + *outResult = GL_SIGNALED; + ANGLE_TRY(FenceTestHelper(context, this, false, &result)); + + *outResult = (result ? GL_SIGNALED : GL_UNSIGNALED); + return angle::Result::Continue; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Fence11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Fence11.h new file mode 100644 index 0000000000..e35ff6b71c --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Fence11.h @@ -0,0 +1,76 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Fence11.h: Defines the rx::FenceNV11 and rx::Sync11 classes which implement rx::FenceNVImpl +// and rx::SyncImpl. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_FENCE11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_FENCE11_H_ + +#include "libANGLE/renderer/FenceNVImpl.h" +#include "libANGLE/renderer/SyncImpl.h" + +namespace rx +{ +class Renderer11; + +class FenceNV11 : public FenceNVImpl +{ + public: + explicit FenceNV11(Renderer11 *renderer); + ~FenceNV11() override; + + void onDestroy(const gl::Context *context) override {} + angle::Result set(const gl::Context *context, GLenum condition) override; + angle::Result test(const gl::Context *context, GLboolean *outFinished) override; + angle::Result finish(const gl::Context *context) override; + + private: + template + friend angle::Result FenceSetHelper(const gl::Context *context, T *fence); + template + friend angle::Result FenceTestHelper(const gl::Context *context, + T *fence, + bool flushCommandBuffer, + GLboolean *outFinished); + + Renderer11 *mRenderer; + ID3D11Query *mQuery; +}; + +class Sync11 : public SyncImpl +{ + public: + explicit Sync11(Renderer11 *renderer); + ~Sync11() override; + + angle::Result set(const gl::Context *context, GLenum condition, GLbitfield flags) override; + angle::Result clientWait(const gl::Context *context, + GLbitfield flags, + GLuint64 timeout, + GLenum *outResult) override; + angle::Result serverWait(const gl::Context *context, + GLbitfield flags, + GLuint64 timeout) override; + angle::Result getStatus(const gl::Context *context, GLint *outResult) override; + + private: + template + friend angle::Result FenceSetHelper(const gl::Context *context, T *fence); + template + friend angle::Result FenceTestHelper(const gl::Context *context, + T *fence, + bool flushCommandBuffer, + GLboolean *outFinished); + + Renderer11 *mRenderer; + ID3D11Query *mQuery; + LONGLONG mCounterFrequency; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_FENCE11_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp new file mode 100644 index 0000000000..e6516ff521 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp @@ -0,0 +1,452 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Framebuffer11.cpp: Implements the Framebuffer11 class. + +#include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h" + +#include "common/bitset_utils.h" +#include "common/debug.h" +#include "libANGLE/Context.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/Texture.h" +#include "libANGLE/renderer/d3d/TextureD3D.h" +#include "libANGLE/renderer/d3d/d3d11/Buffer11.h" +#include "libANGLE/renderer/d3d/d3d11/Clear11.h" +#include "libANGLE/renderer/d3d/d3d11/Context11.h" +#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h" +#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" + +using namespace angle; + +namespace rx +{ + +namespace +{ +angle::Result MarkAttachmentsDirty(const gl::Context *context, + const gl::FramebufferAttachment *attachment) +{ + if (attachment->type() == GL_TEXTURE) + { + gl::Texture *texture = attachment->getTexture(); + + TextureD3D *textureD3D = GetImplAs(texture); + + TextureStorage *texStorage = nullptr; + ANGLE_TRY(textureD3D->getNativeTexture(context, &texStorage)); + + if (texStorage) + { + TextureStorage11 *texStorage11 = GetAs(texStorage); + ASSERT(texStorage11); + + texStorage11->markLevelDirty(attachment->mipLevel()); + } + } + + return angle::Result::Continue; +} + +UINT GetAttachmentLayer(const gl::FramebufferAttachment *attachment) +{ + if (attachment->type() == GL_TEXTURE && + attachment->getTexture()->getType() == gl::TextureType::_3D) + { + return attachment->layer(); + } + return 0; +} + +} // anonymous namespace + +Framebuffer11::Framebuffer11(const gl::FramebufferState &data, Renderer11 *renderer) + : FramebufferD3D(data, renderer), mRenderer(renderer) +{ + ASSERT(mRenderer != nullptr); +} + +Framebuffer11::~Framebuffer11() {} + +angle::Result Framebuffer11::markAttachmentsDirty(const gl::Context *context) const +{ + const auto &colorAttachments = mState.getColorAttachments(); + for (size_t drawBuffer : mState.getEnabledDrawBuffers()) + { + const gl::FramebufferAttachment &colorAttachment = colorAttachments[drawBuffer]; + ASSERT(colorAttachment.isAttached()); + ANGLE_TRY(MarkAttachmentsDirty(context, &colorAttachment)); + } + + const gl::FramebufferAttachment *dsAttachment = mState.getDepthOrStencilAttachment(); + if (dsAttachment) + { + ANGLE_TRY(MarkAttachmentsDirty(context, dsAttachment)); + } + + return angle::Result::Continue; +} + +angle::Result Framebuffer11::clearImpl(const gl::Context *context, + const ClearParameters &clearParams) +{ + Clear11 *clearer = mRenderer->getClearer(); + + const gl::FramebufferAttachment *colorAttachment = mState.getFirstColorAttachment(); + if (clearParams.scissorEnabled == true && colorAttachment != nullptr && + UsePresentPathFast(mRenderer, colorAttachment)) + { + // If the current framebuffer is using the default colorbuffer, and present path fast is + // active, and the scissor rect is enabled, then we should invert the scissor rect + // vertically + ClearParameters presentPathFastClearParams = clearParams; + gl::Extents framebufferSize = colorAttachment->getSize(); + presentPathFastClearParams.scissor.y = framebufferSize.height - + presentPathFastClearParams.scissor.y - + presentPathFastClearParams.scissor.height; + ANGLE_TRY(clearer->clearFramebuffer(context, presentPathFastClearParams, mState)); + } + else + { + ANGLE_TRY(clearer->clearFramebuffer(context, clearParams, mState)); + } + + ANGLE_TRY(markAttachmentsDirty(context)); + + return angle::Result::Continue; +} + +angle::Result Framebuffer11::invalidate(const gl::Context *context, + size_t count, + const GLenum *attachments) +{ + return invalidateBase(context, count, attachments, false); +} + +angle::Result Framebuffer11::discard(const gl::Context *context, + size_t count, + const GLenum *attachments) +{ + return invalidateBase(context, count, attachments, true); +} + +angle::Result Framebuffer11::invalidateBase(const gl::Context *context, + size_t count, + const GLenum *attachments, + bool useEXTBehavior) const +{ + ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported(); + + if (!deviceContext1) + { + // DiscardView() is only supported on ID3D11DeviceContext1 + return angle::Result::Continue; + } + + bool foundDepth = false; + bool foundStencil = false; + + for (size_t i = 0; i < count; ++i) + { + switch (attachments[i]) + { + // Handle depth and stencil attachments. Defer discarding until later. + case GL_DEPTH_STENCIL_ATTACHMENT: + foundDepth = true; + foundStencil = true; + break; + case GL_DEPTH_EXT: + case GL_DEPTH_ATTACHMENT: + foundDepth = true; + break; + case GL_STENCIL_EXT: + case GL_STENCIL_ATTACHMENT: + foundStencil = true; + break; + default: + { + // Handle color attachments + ASSERT((attachments[i] >= GL_COLOR_ATTACHMENT0 && + attachments[i] <= GL_COLOR_ATTACHMENT15) || + (attachments[i] == GL_COLOR)); + + size_t colorIndex = + (attachments[i] == GL_COLOR ? 0u : (attachments[i] - GL_COLOR_ATTACHMENT0)); + const gl::FramebufferAttachment *colorAttachment = + mState.getColorAttachment(colorIndex); + if (colorAttachment) + { + ANGLE_TRY(invalidateAttachment(context, colorAttachment)); + } + break; + } + } + } + + bool discardDepth = false; + bool discardStencil = false; + + // The D3D11 renderer uses the same view for depth and stencil buffers, so we must be careful. + if (useEXTBehavior) + { + // In the extension, if the app discards only one of the depth and stencil attachments, but + // those are backed by the same packed_depth_stencil buffer, then both images become + // undefined. + discardDepth = foundDepth; + + // Don't bother discarding the stencil buffer if the depth buffer will already do it + discardStencil = foundStencil && (!discardDepth || mState.getDepthAttachment() == nullptr); + } + else + { + // In ES 3.0.4, if a specified attachment has base internal format DEPTH_STENCIL but the + // attachments list does not include DEPTH_STENCIL_ATTACHMENT or both DEPTH_ATTACHMENT and + // STENCIL_ATTACHMENT, then only the specified portion of every pixel in the subregion of + // pixels of the DEPTH_STENCIL buffer may be invalidated, and the other portion must be + // preserved. + discardDepth = (foundDepth && foundStencil) || + (foundDepth && (mState.getStencilAttachment() == nullptr)); + discardStencil = (foundStencil && (mState.getDepthAttachment() == nullptr)); + } + + if (discardDepth && mState.getDepthAttachment()) + { + ANGLE_TRY(invalidateAttachment(context, mState.getDepthAttachment())); + } + + if (discardStencil && mState.getStencilAttachment()) + { + ANGLE_TRY(invalidateAttachment(context, mState.getStencilAttachment())); + } + + return angle::Result::Continue; +} + +angle::Result Framebuffer11::invalidateSub(const gl::Context *context, + size_t count, + const GLenum *attachments, + const gl::Rectangle &area) +{ + // A no-op implementation conforms to the spec, so don't call UNIMPLEMENTED() + return angle::Result::Continue; +} + +angle::Result Framebuffer11::invalidateAttachment(const gl::Context *context, + const gl::FramebufferAttachment *attachment) const +{ + ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported(); + ASSERT(deviceContext1); + ASSERT(attachment && attachment->isAttached()); + + RenderTarget11 *renderTarget = nullptr; + ANGLE_TRY(attachment->getRenderTarget(context, 0, &renderTarget)); + const auto &rtv = renderTarget->getRenderTargetView(); + + if (rtv.valid()) + { + deviceContext1->DiscardView(rtv.get()); + } + + return angle::Result::Continue; +} + +angle::Result Framebuffer11::readPixelsImpl(const gl::Context *context, + const gl::Rectangle &area, + GLenum format, + GLenum type, + size_t outputPitch, + const gl::PixelPackState &pack, + gl::Buffer *packBuffer, + uint8_t *pixels) +{ + const gl::FramebufferAttachment *readAttachment = mState.getReadPixelsAttachment(format); + ASSERT(readAttachment); + + if (packBuffer != nullptr) + { + Buffer11 *packBufferStorage = GetImplAs(packBuffer); + const angle::Format &angleFormat = GetFormatFromFormatType(format, type); + PackPixelsParams packParams(area, angleFormat, static_cast(outputPitch), + pack.reverseRowOrder, packBuffer, + reinterpret_cast(pixels)); + + return packBufferStorage->packPixels(context, *readAttachment, packParams); + } + + return mRenderer->readFromAttachment(context, *readAttachment, area, format, type, + static_cast(outputPitch), pack, pixels); +} + +angle::Result Framebuffer11::blitImpl(const gl::Context *context, + const gl::Rectangle &sourceArea, + const gl::Rectangle &destArea, + const gl::Rectangle *scissor, + bool blitRenderTarget, + bool blitDepth, + bool blitStencil, + GLenum filter, + const gl::Framebuffer *sourceFramebuffer) +{ + if (blitRenderTarget) + { + const gl::FramebufferAttachment *readBuffer = sourceFramebuffer->getReadColorAttachment(); + ASSERT(readBuffer); + + RenderTargetD3D *readRenderTarget = nullptr; + ANGLE_TRY(readBuffer->getRenderTarget(context, 0, &readRenderTarget)); + ASSERT(readRenderTarget); + + const auto &colorAttachments = mState.getColorAttachments(); + const auto &drawBufferStates = mState.getDrawBufferStates(); + UINT readLayer = GetAttachmentLayer(readBuffer); + + for (size_t colorAttachment = 0; colorAttachment < colorAttachments.size(); + colorAttachment++) + { + const gl::FramebufferAttachment &drawBuffer = colorAttachments[colorAttachment]; + + if (drawBuffer.isAttached() && drawBufferStates[colorAttachment] != GL_NONE) + { + RenderTargetD3D *drawRenderTarget = nullptr; + ANGLE_TRY(drawBuffer.getRenderTarget( + context, drawBuffer.getRenderToTextureSamples(), &drawRenderTarget)); + ASSERT(drawRenderTarget); + + const bool invertColorSource = UsePresentPathFast(mRenderer, readBuffer); + gl::Rectangle actualSourceArea = sourceArea; + if (invertColorSource) + { + RenderTarget11 *readRenderTarget11 = GetAs(readRenderTarget); + actualSourceArea.y = readRenderTarget11->getHeight() - sourceArea.y; + actualSourceArea.height = -sourceArea.height; + } + + const bool invertColorDest = UsePresentPathFast(mRenderer, &drawBuffer); + gl::Rectangle actualDestArea = destArea; + UINT drawLayer = GetAttachmentLayer(&drawBuffer); + + const auto &surfaceTextureOffset = mState.getSurfaceTextureOffset(); + actualDestArea.x = actualDestArea.x + surfaceTextureOffset.x; + actualDestArea.y = actualDestArea.y + surfaceTextureOffset.y; + + if (invertColorDest) + { + RenderTarget11 *drawRenderTarget11 = GetAs(drawRenderTarget); + actualDestArea.y = drawRenderTarget11->getHeight() - destArea.y; + actualDestArea.height = -destArea.height; + } + + ANGLE_TRY(mRenderer->blitRenderbufferRect(context, actualSourceArea, actualDestArea, + readLayer, drawLayer, readRenderTarget, + drawRenderTarget, filter, scissor, + blitRenderTarget, false, false)); + } + } + } + + if (blitDepth || blitStencil) + { + const gl::FramebufferAttachment *readBuffer = + sourceFramebuffer->getDepthOrStencilAttachment(); + ASSERT(readBuffer); + RenderTargetD3D *readRenderTarget = nullptr; + ANGLE_TRY(readBuffer->getRenderTarget(context, 0, &readRenderTarget)); + ASSERT(readRenderTarget); + + const bool invertSource = UsePresentPathFast(mRenderer, readBuffer); + gl::Rectangle actualSourceArea = sourceArea; + if (invertSource) + { + RenderTarget11 *readRenderTarget11 = GetAs(readRenderTarget); + actualSourceArea.y = readRenderTarget11->getHeight() - sourceArea.y; + actualSourceArea.height = -sourceArea.height; + } + + const gl::FramebufferAttachment *drawBuffer = mState.getDepthOrStencilAttachment(); + ASSERT(drawBuffer); + RenderTargetD3D *drawRenderTarget = nullptr; + ANGLE_TRY(drawBuffer->getRenderTarget(context, drawBuffer->getRenderToTextureSamples(), + &drawRenderTarget)); + ASSERT(drawRenderTarget); + + bool invertDest = UsePresentPathFast(mRenderer, drawBuffer); + gl::Rectangle actualDestArea = destArea; + if (invertDest) + { + RenderTarget11 *drawRenderTarget11 = GetAs(drawRenderTarget); + actualDestArea.y = drawRenderTarget11->getHeight() - destArea.y; + actualDestArea.height = -destArea.height; + } + + ANGLE_TRY(mRenderer->blitRenderbufferRect(context, actualSourceArea, actualDestArea, 0, 0, + readRenderTarget, drawRenderTarget, filter, + scissor, false, blitDepth, blitStencil)); + } + + ANGLE_TRY(markAttachmentsDirty(context)); + return angle::Result::Continue; +} + +const gl::InternalFormat &Framebuffer11::getImplementationColorReadFormat( + const gl::Context *context) const +{ + Context11 *context11 = GetImplAs(context); + const Renderer11DeviceCaps &caps = context11->getRenderer()->getRenderer11DeviceCaps(); + GLenum sizedFormat = mState.getReadAttachment()->getFormat().info->sizedInternalFormat; + const angle::Format &angleFormat = d3d11::Format::Get(sizedFormat, caps).format(); + return gl::GetSizedInternalFormatInfo(angleFormat.fboImplementationInternalFormat); +} + +angle::Result Framebuffer11::syncState(const gl::Context *context, + GLenum binding, + const gl::Framebuffer::DirtyBits &dirtyBits, + gl::Command command) +{ + ANGLE_TRY(mRenderTargetCache.update(context, mState, dirtyBits)); + ANGLE_TRY(FramebufferD3D::syncState(context, binding, dirtyBits, command)); + + // Call this last to allow the state manager to take advantage of the cached render targets. + mRenderer->getStateManager()->invalidateRenderTarget(); + + // Call this to syncViewport for framebuffer default parameters. + if (mState.getDefaultWidth() != 0 || mState.getDefaultHeight() != 0) + { + mRenderer->getStateManager()->invalidateViewport(context); + } + + return angle::Result::Continue; +} + +angle::Result Framebuffer11::getSamplePosition(const gl::Context *context, + size_t index, + GLfloat *xy) const +{ + const gl::FramebufferAttachment *attachment = mState.getFirstNonNullAttachment(); + ASSERT(attachment); + GLsizei sampleCount = attachment->getSamples(); + + rx::GetSamplePosition(sampleCount, index, xy); + return angle::Result::Continue; +} + +RenderTarget11 *Framebuffer11::getFirstRenderTarget() const +{ + for (auto *renderTarget : mRenderTargetCache.getColors()) + { + if (renderTarget) + { + return renderTarget; + } + } + + return mRenderTargetCache.getDepthStencil(); +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h new file mode 100644 index 0000000000..34cfdbd30e --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h @@ -0,0 +1,100 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Framebuffer11.h: Defines the Framebuffer11 class. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_FRAMBUFFER11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_FRAMBUFFER11_H_ + +#include "libANGLE/Observer.h" +#include "libANGLE/renderer/RenderTargetCache.h" +#include "libANGLE/renderer/d3d/FramebufferD3D.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" + +namespace rx +{ +class Renderer11; + +class Framebuffer11 : public FramebufferD3D +{ + public: + Framebuffer11(const gl::FramebufferState &data, Renderer11 *renderer); + ~Framebuffer11() override; + + angle::Result discard(const gl::Context *context, + size_t count, + const GLenum *attachments) override; + angle::Result invalidate(const gl::Context *context, + size_t count, + const GLenum *attachments) override; + angle::Result invalidateSub(const gl::Context *context, + size_t count, + const GLenum *attachments, + const gl::Rectangle &area) override; + + // Invalidate the cached swizzles of all bound texture attachments. + angle::Result markAttachmentsDirty(const gl::Context *context) const; + + angle::Result syncState(const gl::Context *context, + GLenum binding, + const gl::Framebuffer::DirtyBits &dirtyBits, + gl::Command command) override; + + const gl::AttachmentArray &getCachedColorRenderTargets() const + { + return mRenderTargetCache.getColors(); + } + const RenderTarget11 *getCachedDepthStencilRenderTarget() const + { + return mRenderTargetCache.getDepthStencil(); + } + + RenderTarget11 *getFirstRenderTarget() const; + + angle::Result getSamplePosition(const gl::Context *context, + size_t index, + GLfloat *xy) const override; + + const gl::InternalFormat &getImplementationColorReadFormat( + const gl::Context *context) const override; + + private: + angle::Result clearImpl(const gl::Context *context, + const ClearParameters &clearParams) override; + + angle::Result readPixelsImpl(const gl::Context *context, + const gl::Rectangle &area, + GLenum format, + GLenum type, + size_t outputPitch, + const gl::PixelPackState &pack, + gl::Buffer *packBuffer, + uint8_t *pixels) override; + + angle::Result blitImpl(const gl::Context *context, + const gl::Rectangle &sourceArea, + const gl::Rectangle &destArea, + const gl::Rectangle *scissor, + bool blitRenderTarget, + bool blitDepth, + bool blitStencil, + GLenum filter, + const gl::Framebuffer *sourceFramebuffer) override; + + angle::Result invalidateBase(const gl::Context *context, + size_t count, + const GLenum *attachments, + bool useEXTBehavior) const; + angle::Result invalidateAttachment(const gl::Context *context, + const gl::FramebufferAttachment *attachment) const; + + Renderer11 *const mRenderer; + RenderTargetCache mRenderTargetCache; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_FRAMBUFFER11_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Image11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Image11.cpp new file mode 100644 index 0000000000..2e6558b304 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Image11.cpp @@ -0,0 +1,676 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Image11.h: Implements the rx::Image11 class, which acts as the interface to +// the actual underlying resources of a Texture + +#include "libANGLE/renderer/d3d/d3d11/Image11.h" + +#include "common/utilities.h" +#include "libANGLE/Context.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/d3d11/Context11.h" +#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h" +#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" + +namespace rx +{ + +Image11::Image11(Renderer11 *renderer) + : mRenderer(renderer), + mDXGIFormat(DXGI_FORMAT_UNKNOWN), + mStagingTexture(), + mStagingSubresource(0), + mRecoverFromStorage(false), + mAssociatedStorage(nullptr), + mAssociatedImageIndex(), + mRecoveredFromStorageCount(0) +{} + +Image11::~Image11() +{ + disassociateStorage(); + releaseStagingTexture(); +} + +// static +angle::Result Image11::GenerateMipmap(const gl::Context *context, + Image11 *dest, + Image11 *src, + const Renderer11DeviceCaps &rendererCaps) +{ + ASSERT(src->getDXGIFormat() == dest->getDXGIFormat()); + ASSERT(src->getWidth() == 1 || src->getWidth() / 2 == dest->getWidth()); + ASSERT(src->getHeight() == 1 || src->getHeight() / 2 == dest->getHeight()); + + D3D11_MAPPED_SUBRESOURCE destMapped; + ANGLE_TRY(dest->map(context, D3D11_MAP_WRITE, &destMapped)); + d3d11::ScopedUnmapper destRAII(dest); + + D3D11_MAPPED_SUBRESOURCE srcMapped; + ANGLE_TRY(src->map(context, D3D11_MAP_READ, &srcMapped)); + d3d11::ScopedUnmapper srcRAII(src); + + const uint8_t *sourceData = static_cast(srcMapped.pData); + uint8_t *destData = static_cast(destMapped.pData); + + auto mipGenerationFunction = + d3d11::Format::Get(src->getInternalFormat(), rendererCaps).format().mipGenerationFunction; + mipGenerationFunction(src->getWidth(), src->getHeight(), src->getDepth(), sourceData, + srcMapped.RowPitch, srcMapped.DepthPitch, destData, destMapped.RowPitch, + destMapped.DepthPitch); + + dest->markDirty(); + + return angle::Result::Continue; +} + +// static +angle::Result Image11::CopyImage(const gl::Context *context, + Image11 *dest, + Image11 *source, + const gl::Box &sourceBox, + const gl::Offset &destOffset, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const Renderer11DeviceCaps &rendererCaps) +{ + D3D11_MAPPED_SUBRESOURCE destMapped; + ANGLE_TRY(dest->map(context, D3D11_MAP_WRITE, &destMapped)); + d3d11::ScopedUnmapper destRAII(dest); + + D3D11_MAPPED_SUBRESOURCE srcMapped; + ANGLE_TRY(source->map(context, D3D11_MAP_READ, &srcMapped)); + d3d11::ScopedUnmapper sourceRAII(source); + + const auto &sourceFormat = + d3d11::Format::Get(source->getInternalFormat(), rendererCaps).format(); + GLuint sourcePixelBytes = + gl::GetSizedInternalFormatInfo(sourceFormat.fboImplementationInternalFormat).pixelBytes; + + GLenum destUnsizedFormat = gl::GetUnsizedFormat(dest->getInternalFormat()); + const auto &destFormat = d3d11::Format::Get(dest->getInternalFormat(), rendererCaps).format(); + const auto &destFormatInfo = + gl::GetSizedInternalFormatInfo(destFormat.fboImplementationInternalFormat); + GLuint destPixelBytes = destFormatInfo.pixelBytes; + + const uint8_t *sourceData = static_cast(srcMapped.pData) + + sourceBox.x * sourcePixelBytes + sourceBox.y * srcMapped.RowPitch + + sourceBox.z * srcMapped.DepthPitch; + uint8_t *destData = static_cast(destMapped.pData) + destOffset.x * destPixelBytes + + destOffset.y * destMapped.RowPitch + destOffset.z * destMapped.DepthPitch; + + CopyImageCHROMIUM(sourceData, srcMapped.RowPitch, sourcePixelBytes, srcMapped.DepthPitch, + sourceFormat.pixelReadFunction, destData, destMapped.RowPitch, destPixelBytes, + destMapped.DepthPitch, destFormat.pixelWriteFunction, destUnsizedFormat, + destFormatInfo.componentType, sourceBox.width, sourceBox.height, + sourceBox.depth, unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha); + + dest->markDirty(); + + return angle::Result::Continue; +} + +bool Image11::isDirty() const +{ + // If mDirty is true AND mStagingTexture doesn't exist AND mStagingTexture doesn't need to be + // recovered from TextureStorage AND the texture doesn't require init data (i.e. a blank new + // texture will suffice) AND robust resource initialization is not enabled then isDirty should + // still return false. + if (mDirty && !mStagingTexture.valid() && !mRecoverFromStorage) + { + const Renderer11DeviceCaps &deviceCaps = mRenderer->getRenderer11DeviceCaps(); + const auto &formatInfo = d3d11::Format::Get(mInternalFormat, deviceCaps); + if (formatInfo.dataInitializerFunction == nullptr) + { + return false; + } + } + + return mDirty; +} + +angle::Result Image11::copyToStorage(const gl::Context *context, + TextureStorage *storage, + const gl::ImageIndex &index, + const gl::Box ®ion) +{ + TextureStorage11 *storage11 = GetAs(storage); + + // If an app's behavior results in an Image11 copying its data to/from to a TextureStorage + // multiple times, then we should just keep the staging texture around to prevent the copying + // from impacting perf. We allow the Image11 to copy its data to/from TextureStorage once. This + // accounts for an app making a late call to glGenerateMipmap. + bool attemptToReleaseStagingTexture = (mRecoveredFromStorageCount < 2); + + if (attemptToReleaseStagingTexture) + { + // If another image is relying on this Storage for its data, then we must let it recover its + // data before we overwrite it. + ANGLE_TRY(storage11->releaseAssociatedImage(context, index, this)); + } + + const TextureHelper11 *stagingTexture = nullptr; + unsigned int stagingSubresourceIndex = 0; + ANGLE_TRY(getStagingTexture(context, &stagingTexture, &stagingSubresourceIndex)); + ANGLE_TRY(storage11->updateSubresourceLevel(context, *stagingTexture, stagingSubresourceIndex, + index, region)); + + // Once the image data has been copied into the Storage, we can release it locally. + if (attemptToReleaseStagingTexture) + { + storage11->associateImage(this, index); + releaseStagingTexture(); + mRecoverFromStorage = true; + mAssociatedStorage = storage11; + mAssociatedImageIndex = index; + } + + return angle::Result::Continue; +} + +void Image11::verifyAssociatedStorageValid(TextureStorage11 *textureStorageEXT) const +{ + ASSERT(mAssociatedStorage == textureStorageEXT); +} + +angle::Result Image11::recoverFromAssociatedStorage(const gl::Context *context) +{ + if (mRecoverFromStorage) + { + ANGLE_TRY(createStagingTexture(context)); + + mAssociatedStorage->verifyAssociatedImageValid(mAssociatedImageIndex, this); + + // CopySubResource from the Storage to the Staging texture + gl::Box region(0, 0, 0, mWidth, mHeight, mDepth); + ANGLE_TRY(mAssociatedStorage->copySubresourceLevel( + context, mStagingTexture, mStagingSubresource, mAssociatedImageIndex, region)); + mRecoveredFromStorageCount += 1; + + // Reset all the recovery parameters, even if the texture storage association is broken. + disassociateStorage(); + + markDirty(); + } + + return angle::Result::Continue; +} + +void Image11::disassociateStorage() +{ + if (mRecoverFromStorage) + { + // Make the texturestorage release the Image11 too + mAssociatedStorage->disassociateImage(mAssociatedImageIndex, this); + + mRecoverFromStorage = false; + mAssociatedStorage = nullptr; + mAssociatedImageIndex = gl::ImageIndex(); + } +} + +bool Image11::redefine(gl::TextureType type, + GLenum internalformat, + const gl::Extents &size, + bool forceRelease) +{ + if (mWidth != size.width || mHeight != size.height || mDepth != size.depth || + mInternalFormat != internalformat || forceRelease) + { + // End the association with the TextureStorage, since that data will be out of date. + // Also reset mRecoveredFromStorageCount since this Image is getting completely redefined. + disassociateStorage(); + mRecoveredFromStorageCount = 0; + + mWidth = size.width; + mHeight = size.height; + mDepth = size.depth; + mInternalFormat = internalformat; + mType = type; + + // compute the d3d format that will be used + const d3d11::Format &formatInfo = + d3d11::Format::Get(internalformat, mRenderer->getRenderer11DeviceCaps()); + mDXGIFormat = formatInfo.texFormat; + mRenderable = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN); + + releaseStagingTexture(); + mDirty = (formatInfo.dataInitializerFunction != nullptr); + + return true; + } + + return false; +} + +DXGI_FORMAT Image11::getDXGIFormat() const +{ + // this should only happen if the image hasn't been redefined first + // which would be a bug by the caller + ASSERT(mDXGIFormat != DXGI_FORMAT_UNKNOWN); + + return mDXGIFormat; +} + +// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as +// format/type at input +// into the target pixel rectangle. +angle::Result Image11::loadData(const gl::Context *context, + const gl::Box &area, + const gl::PixelUnpackState &unpack, + GLenum type, + const void *input, + bool applySkipImages) +{ + Context11 *context11 = GetImplAs(context); + + const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(mInternalFormat); + GLuint inputRowPitch = 0; + ANGLE_CHECK_GL_MATH(context11, formatInfo.computeRowPitch(type, area.width, unpack.alignment, + unpack.rowLength, &inputRowPitch)); + GLuint inputDepthPitch = 0; + ANGLE_CHECK_GL_MATH(context11, formatInfo.computeDepthPitch(area.height, unpack.imageHeight, + inputRowPitch, &inputDepthPitch)); + GLuint inputSkipBytes = 0; + ANGLE_CHECK_GL_MATH(context11, + formatInfo.computeSkipBytes(type, inputRowPitch, inputDepthPitch, unpack, + applySkipImages, &inputSkipBytes)); + + const d3d11::DXGIFormatSize &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(mDXGIFormat); + GLuint outputPixelSize = dxgiFormatInfo.pixelBytes; + + const d3d11::Format &d3dFormatInfo = + d3d11::Format::Get(mInternalFormat, mRenderer->getRenderer11DeviceCaps()); + LoadImageFunction loadFunction = d3dFormatInfo.getLoadFunctions()(type).loadFunction; + + D3D11_MAPPED_SUBRESOURCE mappedImage; + ANGLE_TRY(map(context, D3D11_MAP_WRITE, &mappedImage)); + + uint8_t *offsetMappedData = (static_cast(mappedImage.pData) + + (area.y * mappedImage.RowPitch + area.x * outputPixelSize + + area.z * mappedImage.DepthPitch)); + loadFunction(area.width, area.height, area.depth, + static_cast(input) + inputSkipBytes, inputRowPitch, + inputDepthPitch, offsetMappedData, mappedImage.RowPitch, mappedImage.DepthPitch); + + unmap(); + + return angle::Result::Continue; +} + +angle::Result Image11::loadCompressedData(const gl::Context *context, + const gl::Box &area, + const void *input) +{ + Context11 *context11 = GetImplAs(context); + + const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(mInternalFormat); + GLuint inputRowPitch = 0; + ANGLE_CHECK_GL_MATH( + context11, formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, area.width, 1, 0, &inputRowPitch)); + GLuint inputDepthPitch = 0; + ANGLE_CHECK_GL_MATH( + context11, formatInfo.computeDepthPitch(area.height, 0, inputRowPitch, &inputDepthPitch)); + + const d3d11::DXGIFormatSize &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(mDXGIFormat); + GLuint outputPixelSize = dxgiFormatInfo.pixelBytes; + GLuint outputBlockWidth = dxgiFormatInfo.blockWidth; + GLuint outputBlockHeight = dxgiFormatInfo.blockHeight; + + ASSERT(area.x % outputBlockWidth == 0); + ASSERT(area.y % outputBlockHeight == 0); + + const d3d11::Format &d3dFormatInfo = + d3d11::Format::Get(mInternalFormat, mRenderer->getRenderer11DeviceCaps()); + LoadImageFunction loadFunction = + d3dFormatInfo.getLoadFunctions()(GL_UNSIGNED_BYTE).loadFunction; + + D3D11_MAPPED_SUBRESOURCE mappedImage; + ANGLE_TRY(map(context, D3D11_MAP_WRITE, &mappedImage)); + + uint8_t *offsetMappedData = + static_cast(mappedImage.pData) + + ((area.y / outputBlockHeight) * mappedImage.RowPitch + + (area.x / outputBlockWidth) * outputPixelSize + area.z * mappedImage.DepthPitch); + + loadFunction(area.width, area.height, area.depth, static_cast(input), + inputRowPitch, inputDepthPitch, offsetMappedData, mappedImage.RowPitch, + mappedImage.DepthPitch); + + unmap(); + + return angle::Result::Continue; +} + +angle::Result Image11::copyFromTexStorage(const gl::Context *context, + const gl::ImageIndex &imageIndex, + TextureStorage *source) +{ + TextureStorage11 *storage11 = GetAs(source); + + const TextureHelper11 *textureHelper = nullptr; + ANGLE_TRY(storage11->getResource(context, &textureHelper)); + + UINT subresourceIndex = 0; + ANGLE_TRY(storage11->getSubresourceIndex(context, imageIndex, &subresourceIndex)); + + gl::Box sourceBox(0, 0, 0, mWidth, mHeight, mDepth); + return copyWithoutConversion(context, gl::Offset(), sourceBox, *textureHelper, + subresourceIndex); +} + +angle::Result Image11::copyFromFramebuffer(const gl::Context *context, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + const gl::Framebuffer *sourceFBO) +{ + const gl::FramebufferAttachment *srcAttachment = sourceFBO->getReadColorAttachment(); + ASSERT(srcAttachment); + + GLenum sourceInternalFormat = srcAttachment->getFormat().info->sizedInternalFormat; + const auto &d3d11Format = + d3d11::Format::Get(sourceInternalFormat, mRenderer->getRenderer11DeviceCaps()); + + if (d3d11Format.texFormat == mDXGIFormat && sourceInternalFormat == mInternalFormat) + { + RenderTarget11 *rt11 = nullptr; + ANGLE_TRY(srcAttachment->getRenderTarget(context, 0, &rt11)); + ASSERT(rt11->getTexture().get()); + + TextureHelper11 textureHelper = rt11->getTexture(); + unsigned int sourceSubResource = rt11->getSubresourceIndex(); + + gl::Box sourceBox(sourceArea.x, sourceArea.y, 0, sourceArea.width, sourceArea.height, 1); + return copyWithoutConversion(context, destOffset, sourceBox, textureHelper, + sourceSubResource); + } + + // This format requires conversion, so we must copy the texture to staging and manually convert + // via readPixels + D3D11_MAPPED_SUBRESOURCE mappedImage; + ANGLE_TRY(map(context, D3D11_MAP_WRITE, &mappedImage)); + + // determine the offset coordinate into the destination buffer + const auto &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(mDXGIFormat); + GLsizei rowOffset = dxgiFormatInfo.pixelBytes * destOffset.x; + + uint8_t *dataOffset = static_cast(mappedImage.pData) + + mappedImage.RowPitch * destOffset.y + rowOffset + + destOffset.z * mappedImage.DepthPitch; + + const gl::InternalFormat &destFormatInfo = gl::GetSizedInternalFormatInfo(mInternalFormat); + const auto &destD3D11Format = + d3d11::Format::Get(mInternalFormat, mRenderer->getRenderer11DeviceCaps()); + + auto loadFunction = destD3D11Format.getLoadFunctions()(destFormatInfo.type); + angle::Result result = angle::Result::Continue; + if (loadFunction.requiresConversion) + { + size_t bufferSize = destFormatInfo.pixelBytes * sourceArea.width * sourceArea.height; + angle::MemoryBuffer *memoryBuffer = nullptr; + result = mRenderer->getScratchMemoryBuffer(GetImplAs(context), bufferSize, + &memoryBuffer); + + if (result == angle::Result::Continue) + { + GLuint memoryBufferRowPitch = destFormatInfo.pixelBytes * sourceArea.width; + + result = mRenderer->readFromAttachment( + context, *srcAttachment, sourceArea, destFormatInfo.format, destFormatInfo.type, + memoryBufferRowPitch, gl::PixelPackState(), memoryBuffer->data()); + + loadFunction.loadFunction(sourceArea.width, sourceArea.height, 1, memoryBuffer->data(), + memoryBufferRowPitch, 0, dataOffset, mappedImage.RowPitch, + mappedImage.DepthPitch); + } + } + else + { + result = mRenderer->readFromAttachment( + context, *srcAttachment, sourceArea, destFormatInfo.format, destFormatInfo.type, + mappedImage.RowPitch, gl::PixelPackState(), dataOffset); + } + + unmap(); + mDirty = true; + + return result; +} + +angle::Result Image11::copyWithoutConversion(const gl::Context *context, + const gl::Offset &destOffset, + const gl::Box &sourceArea, + const TextureHelper11 &textureHelper, + UINT sourceSubResource) +{ + // No conversion needed-- use copyback fastpath + const TextureHelper11 *stagingTexture = nullptr; + unsigned int stagingSubresourceIndex = 0; + ANGLE_TRY(getStagingTexture(context, &stagingTexture, &stagingSubresourceIndex)); + + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + const gl::Extents &extents = textureHelper.getExtents(); + + D3D11_BOX srcBox; + srcBox.left = sourceArea.x; + srcBox.right = sourceArea.x + sourceArea.width; + srcBox.top = sourceArea.y; + srcBox.bottom = sourceArea.y + sourceArea.height; + srcBox.front = sourceArea.z; + srcBox.back = sourceArea.z + sourceArea.depth; + + if (textureHelper.is2D() && textureHelper.getSampleCount() > 1) + { + D3D11_TEXTURE2D_DESC resolveDesc; + resolveDesc.Width = extents.width; + resolveDesc.Height = extents.height; + resolveDesc.MipLevels = 1; + resolveDesc.ArraySize = 1; + resolveDesc.Format = textureHelper.getFormat(); + resolveDesc.SampleDesc.Count = 1; + resolveDesc.SampleDesc.Quality = 0; + resolveDesc.Usage = D3D11_USAGE_DEFAULT; + resolveDesc.BindFlags = 0; + resolveDesc.CPUAccessFlags = 0; + resolveDesc.MiscFlags = 0; + + d3d11::Texture2D resolveTex; + ANGLE_TRY( + mRenderer->allocateResource(GetImplAs(context), resolveDesc, &resolveTex)); + + deviceContext->ResolveSubresource(resolveTex.get(), 0, textureHelper.get(), + sourceSubResource, textureHelper.getFormat()); + + deviceContext->CopySubresourceRegion(stagingTexture->get(), stagingSubresourceIndex, + destOffset.x, destOffset.y, destOffset.z, + resolveTex.get(), 0, &srcBox); + } + else + { + deviceContext->CopySubresourceRegion(stagingTexture->get(), stagingSubresourceIndex, + destOffset.x, destOffset.y, destOffset.z, + textureHelper.get(), sourceSubResource, &srcBox); + } + + mDirty = true; + return angle::Result::Continue; +} + +angle::Result Image11::getStagingTexture(const gl::Context *context, + const TextureHelper11 **outStagingTexture, + unsigned int *outSubresourceIndex) +{ + ANGLE_TRY(createStagingTexture(context)); + + *outStagingTexture = &mStagingTexture; + *outSubresourceIndex = mStagingSubresource; + return angle::Result::Continue; +} + +void Image11::releaseStagingTexture() +{ + mStagingTexture.reset(); + mStagingTextureSubresourceVerifier.reset(); +} + +angle::Result Image11::createStagingTexture(const gl::Context *context) +{ + if (mStagingTexture.valid()) + { + return angle::Result::Continue; + } + + ASSERT(mWidth > 0 && mHeight > 0 && mDepth > 0); + + const DXGI_FORMAT dxgiFormat = getDXGIFormat(); + const auto &formatInfo = + d3d11::Format::Get(mInternalFormat, mRenderer->getRenderer11DeviceCaps()); + + int lodOffset = 1; + GLsizei width = mWidth; + GLsizei height = mHeight; + + // adjust size if needed for compressed textures + d3d11::MakeValidSize(false, dxgiFormat, &width, &height, &lodOffset); + + Context11 *context11 = GetImplAs(context); + + switch (mType) + { + case gl::TextureType::_3D: + { + D3D11_TEXTURE3D_DESC desc; + desc.Width = width; + desc.Height = height; + desc.Depth = mDepth; + desc.MipLevels = lodOffset + 1; + desc.Format = dxgiFormat; + desc.Usage = D3D11_USAGE_STAGING; + desc.BindFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; + desc.MiscFlags = 0; + + if (formatInfo.dataInitializerFunction != nullptr) + { + gl::TexLevelArray initialData; + ANGLE_TRY(d3d11::GenerateInitialTextureData( + context, mInternalFormat, mRenderer->getRenderer11DeviceCaps(), width, height, + mDepth, lodOffset + 1, &initialData)); + + ANGLE_TRY(mRenderer->allocateTexture(context11, desc, formatInfo, + initialData.data(), &mStagingTexture)); + } + else + { + ANGLE_TRY( + mRenderer->allocateTexture(context11, desc, formatInfo, &mStagingTexture)); + } + + mStagingTexture.setInternalName("Image11::StagingTexture3D"); + mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1); + mStagingTextureSubresourceVerifier.setDesc(desc); + } + break; + + case gl::TextureType::_2D: + case gl::TextureType::_2DArray: + case gl::TextureType::CubeMap: + { + D3D11_TEXTURE2D_DESC desc; + desc.Width = width; + desc.Height = height; + desc.MipLevels = lodOffset + 1; + desc.ArraySize = 1; + desc.Format = dxgiFormat; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_STAGING; + desc.BindFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; + desc.MiscFlags = 0; + + if (formatInfo.dataInitializerFunction != nullptr) + { + gl::TexLevelArray initialData; + ANGLE_TRY(d3d11::GenerateInitialTextureData( + context, mInternalFormat, mRenderer->getRenderer11DeviceCaps(), width, height, + 1, lodOffset + 1, &initialData)); + + ANGLE_TRY(mRenderer->allocateTexture(context11, desc, formatInfo, + initialData.data(), &mStagingTexture)); + } + else + { + ANGLE_TRY( + mRenderer->allocateTexture(context11, desc, formatInfo, &mStagingTexture)); + } + + mStagingTexture.setInternalName("Image11::StagingTexture2D"); + mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1); + mStagingTextureSubresourceVerifier.setDesc(desc); + } + break; + + default: + UNREACHABLE(); + } + + mDirty = false; + return angle::Result::Continue; +} + +angle::Result Image11::map(const gl::Context *context, + D3D11_MAP mapType, + D3D11_MAPPED_SUBRESOURCE *map) +{ + // We must recover from the TextureStorage if necessary, even for D3D11_MAP_WRITE. + ANGLE_TRY(recoverFromAssociatedStorage(context)); + + const TextureHelper11 *stagingTexture = nullptr; + unsigned int subresourceIndex = 0; + ANGLE_TRY(getStagingTexture(context, &stagingTexture, &subresourceIndex)); + + ASSERT(stagingTexture && stagingTexture->valid()); + + ANGLE_TRY( + mRenderer->mapResource(context, stagingTexture->get(), subresourceIndex, mapType, 0, map)); + + if (!mStagingTextureSubresourceVerifier.wrap(mapType, map)) + { + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + deviceContext->Unmap(mStagingTexture.get(), mStagingSubresource); + Context11 *context11 = GetImplAs(context); + context11->handleError(GL_OUT_OF_MEMORY, + "Failed to allocate staging texture mapping verifier buffer.", + __FILE__, ANGLE_FUNCTION, __LINE__); + return angle::Result::Stop; + } + + mDirty = true; + + return angle::Result::Continue; +} + +void Image11::unmap() +{ + if (mStagingTexture.valid()) + { + mStagingTextureSubresourceVerifier.unwrap(); + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + deviceContext->Unmap(mStagingTexture.get(), mStagingSubresource); + } +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Image11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Image11.h new file mode 100644 index 0000000000..661365240c --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Image11.h @@ -0,0 +1,128 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Image11.h: Defines the rx::Image11 class, which acts as the interface to +// the actual underlying resources of a Texture + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_IMAGE11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_IMAGE11_H_ + +#include "common/debug.h" +#include "libANGLE/ImageIndex.h" +#include "libANGLE/renderer/d3d/ImageD3D.h" +#include "libANGLE/renderer/d3d/d3d11/MappedSubresourceVerifier11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" + +namespace gl +{ +class Framebuffer; +} + +namespace d3d11 +{ +template +class ScopedUnmapper; +} // namespace d3d11 + +namespace rx +{ +class Renderer11; +class TextureHelper11; +class TextureStorage11; +struct Renderer11DeviceCaps; + +class Image11 : public ImageD3D +{ + public: + Image11(Renderer11 *renderer); + ~Image11() override; + + static angle::Result GenerateMipmap(const gl::Context *context, + Image11 *dest, + Image11 *src, + const Renderer11DeviceCaps &rendererCaps); + static angle::Result CopyImage(const gl::Context *context, + Image11 *dest, + Image11 *source, + const gl::Box &sourceBox, + const gl::Offset &destOffset, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const Renderer11DeviceCaps &rendererCaps); + + bool isDirty() const override; + + angle::Result copyToStorage(const gl::Context *context, + TextureStorage *storage, + const gl::ImageIndex &index, + const gl::Box ®ion) override; + + bool redefine(gl::TextureType type, + GLenum internalformat, + const gl::Extents &size, + bool forceRelease) override; + + DXGI_FORMAT getDXGIFormat() const; + + angle::Result loadData(const gl::Context *context, + const gl::Box &area, + const gl::PixelUnpackState &unpack, + GLenum type, + const void *input, + bool applySkipImages) override; + angle::Result loadCompressedData(const gl::Context *context, + const gl::Box &area, + const void *input) override; + + angle::Result copyFromTexStorage(const gl::Context *context, + const gl::ImageIndex &imageIndex, + TextureStorage *source) override; + angle::Result copyFromFramebuffer(const gl::Context *context, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + const gl::Framebuffer *source) override; + + angle::Result recoverFromAssociatedStorage(const gl::Context *context); + void verifyAssociatedStorageValid(TextureStorage11 *textureStorageEXT) const; + void disassociateStorage(); + + angle::Result getStagingTexture(const gl::Context *context, + const TextureHelper11 **outStagingTexture, + unsigned int *outSubresourceIndex); + + protected: + template + friend class d3d11::ScopedUnmapper; + angle::Result map(const gl::Context *context, D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map); + void unmap(); + + private: + angle::Result copyWithoutConversion(const gl::Context *context, + const gl::Offset &destOffset, + const gl::Box &sourceArea, + const TextureHelper11 &textureHelper, + UINT sourceSubResource); + + angle::Result createStagingTexture(const gl::Context *context); + void releaseStagingTexture(); + + Renderer11 *mRenderer; + + DXGI_FORMAT mDXGIFormat; + TextureHelper11 mStagingTexture; + unsigned int mStagingSubresource; + MappedSubresourceVerifier11 mStagingTextureSubresourceVerifier; + + bool mRecoverFromStorage; + TextureStorage11 *mAssociatedStorage; + gl::ImageIndex mAssociatedImageIndex; + unsigned int mRecoveredFromStorageCount; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_IMAGE11_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.cpp new file mode 100644 index 0000000000..7630b341fa --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.cpp @@ -0,0 +1,160 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// IndexBuffer11.cpp: Defines the D3D11 IndexBuffer implementation. + +#include "libANGLE/renderer/d3d/d3d11/IndexBuffer11.h" + +#include "libANGLE/Context.h" +#include "libANGLE/renderer/d3d/d3d11/Context11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" + +namespace rx +{ + +IndexBuffer11::IndexBuffer11(Renderer11 *const renderer) + : mRenderer(renderer), + mBuffer(), + mBufferSize(0), + mIndexType(gl::DrawElementsType::InvalidEnum), + mDynamicUsage(false) +{} + +IndexBuffer11::~IndexBuffer11() {} + +angle::Result IndexBuffer11::initialize(const gl::Context *context, + unsigned int bufferSize, + gl::DrawElementsType indexType, + bool dynamic) +{ + mBuffer.reset(); + + updateSerial(); + + if (bufferSize > 0) + { + D3D11_BUFFER_DESC bufferDesc; + bufferDesc.ByteWidth = bufferSize; + bufferDesc.Usage = D3D11_USAGE_DYNAMIC; + bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; + bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + bufferDesc.MiscFlags = 0; + bufferDesc.StructureByteStride = 0; + + ANGLE_TRY(mRenderer->allocateResource(GetImplAs(context), bufferDesc, &mBuffer)); + + if (dynamic) + { + mBuffer.setInternalName("IndexBuffer11(dynamic)"); + } + else + { + mBuffer.setInternalName("IndexBuffer11(static)"); + } + } + + mBufferSize = bufferSize; + mIndexType = indexType; + mDynamicUsage = dynamic; + + return angle::Result::Continue; +} + +angle::Result IndexBuffer11::mapBuffer(const gl::Context *context, + unsigned int offset, + unsigned int size, + void **outMappedMemory) +{ + Context11 *context11 = GetImplAs(context); + ANGLE_CHECK_HR(context11, mBuffer.valid(), "Internal index buffer is not initialized.", + E_OUTOFMEMORY); + + // Check for integer overflows and out-out-bounds map requests + bool outOfBounds = (offset + size < offset || offset + size > mBufferSize); + ANGLE_CHECK_HR(context11, !outOfBounds, "Index buffer map range is not inside the buffer.", + E_OUTOFMEMORY); + + D3D11_MAPPED_SUBRESOURCE mappedResource; + ANGLE_TRY(mRenderer->mapResource(context, mBuffer.get(), 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, + &mappedResource)); + + *outMappedMemory = static_cast(mappedResource.pData) + offset; + return angle::Result::Continue; +} + +angle::Result IndexBuffer11::unmapBuffer(const gl::Context *context) +{ + Context11 *context11 = GetImplAs(context); + ANGLE_CHECK_HR(context11, mBuffer.valid(), "Internal index buffer is not initialized.", + E_OUTOFMEMORY); + + ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); + dxContext->Unmap(mBuffer.get(), 0); + return angle::Result::Continue; +} + +gl::DrawElementsType IndexBuffer11::getIndexType() const +{ + return mIndexType; +} + +unsigned int IndexBuffer11::getBufferSize() const +{ + return mBufferSize; +} + +angle::Result IndexBuffer11::setSize(const gl::Context *context, + unsigned int bufferSize, + gl::DrawElementsType indexType) +{ + if (bufferSize > mBufferSize || indexType != mIndexType) + { + return initialize(context, bufferSize, indexType, mDynamicUsage); + } + + return angle::Result::Continue; +} + +angle::Result IndexBuffer11::discard(const gl::Context *context) +{ + Context11 *context11 = GetImplAs(context); + ANGLE_CHECK_HR(context11, mBuffer.valid(), "Internal index buffer is not initialized.", + E_OUTOFMEMORY); + + ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); + + D3D11_MAPPED_SUBRESOURCE mappedResource; + ANGLE_TRY(mRenderer->mapResource(context, mBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, + &mappedResource)); + + dxContext->Unmap(mBuffer.get(), 0); + + return angle::Result::Continue; +} + +DXGI_FORMAT IndexBuffer11::getIndexFormat() const +{ + switch (mIndexType) + { + case gl::DrawElementsType::UnsignedByte: + return DXGI_FORMAT_R16_UINT; + case gl::DrawElementsType::UnsignedShort: + return DXGI_FORMAT_R16_UINT; + case gl::DrawElementsType::UnsignedInt: + return DXGI_FORMAT_R32_UINT; + default: + UNREACHABLE(); + return DXGI_FORMAT_UNKNOWN; + } +} + +const d3d11::Buffer &IndexBuffer11::getBuffer() const +{ + return mBuffer; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.h new file mode 100644 index 0000000000..53c736cf7a --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.h @@ -0,0 +1,58 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// IndexBuffer11.h: Defines the D3D11 IndexBuffer implementation. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_INDEXBUFFER11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_INDEXBUFFER11_H_ + +#include "libANGLE/renderer/d3d/IndexBuffer.h" +#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h" + +namespace rx +{ +class Renderer11; + +class IndexBuffer11 : public IndexBuffer +{ + public: + explicit IndexBuffer11(Renderer11 *const renderer); + ~IndexBuffer11() override; + + angle::Result initialize(const gl::Context *context, + unsigned int bufferSize, + gl::DrawElementsType indexType, + bool dynamic) override; + + angle::Result mapBuffer(const gl::Context *context, + unsigned int offset, + unsigned int size, + void **outMappedMemory) override; + angle::Result unmapBuffer(const gl::Context *context) override; + + gl::DrawElementsType getIndexType() const override; + unsigned int getBufferSize() const override; + angle::Result setSize(const gl::Context *context, + unsigned int bufferSize, + gl::DrawElementsType indexType) override; + + angle::Result discard(const gl::Context *context) override; + + DXGI_FORMAT getIndexFormat() const; + const d3d11::Buffer &getBuffer() const; + + private: + Renderer11 *const mRenderer; + + d3d11::Buffer mBuffer; + unsigned int mBufferSize; + gl::DrawElementsType mIndexType; + bool mDynamicUsage; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_INDEXBUFFER11_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp new file mode 100644 index 0000000000..b5e12499b2 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp @@ -0,0 +1,313 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// InputLayoutCache.cpp: Defines InputLayoutCache, a class that builds and caches +// D3D11 input layouts. + +#include "libANGLE/renderer/d3d/d3d11/InputLayoutCache.h" + +#include "common/bitset_utils.h" +#include "common/utilities.h" +#include "libANGLE/Context.h" +#include "libANGLE/Program.h" +#include "libANGLE/VertexArray.h" +#include "libANGLE/VertexAttribute.h" +#include "libANGLE/renderer/d3d/IndexDataManager.h" +#include "libANGLE/renderer/d3d/ProgramD3D.h" +#include "libANGLE/renderer/d3d/VertexDataManager.h" +#include "libANGLE/renderer/d3d/d3d11/Context11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h" +#include "libANGLE/renderer/d3d/d3d11/VertexArray11.h" +#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" + +namespace rx +{ + +namespace +{ + +GLenum GetGLSLAttributeType(const std::vector &shaderAttributes, size_t index) +{ + // Count matrices differently + for (const sh::ShaderVariable &attrib : shaderAttributes) + { + if (attrib.location == -1) + { + continue; + } + + GLenum transposedType = gl::TransposeMatrixType(attrib.type); + int rows = gl::VariableRowCount(transposedType); + int intIndex = static_cast(index); + + if (intIndex >= attrib.location && intIndex < attrib.location + rows) + { + return transposedType; + } + } + + UNREACHABLE(); + return GL_NONE; +} + +struct PackedAttribute +{ + uint8_t attribType; + uint8_t semanticIndex; + uint8_t vertexFormatType; + uint8_t unusedPadding; + uint32_t divisor; +}; + +} // anonymous namespace + +PackedAttributeLayout::PackedAttributeLayout() : numAttributes(0), flags(0), attributeData({}) {} + +PackedAttributeLayout::PackedAttributeLayout(const PackedAttributeLayout &other) = default; + +void PackedAttributeLayout::addAttributeData(GLenum glType, + UINT semanticIndex, + angle::FormatID vertexFormatID, + unsigned int divisor) +{ + gl::AttributeType attribType = gl::GetAttributeType(glType); + + PackedAttribute packedAttrib; + packedAttrib.attribType = static_cast(attribType); + packedAttrib.semanticIndex = static_cast(semanticIndex); + packedAttrib.vertexFormatType = static_cast(vertexFormatID); + packedAttrib.unusedPadding = 0u; + packedAttrib.divisor = static_cast(divisor); + + ASSERT(static_cast(packedAttrib.attribType) == attribType); + ASSERT(static_cast(packedAttrib.semanticIndex) == semanticIndex); + ASSERT(static_cast(packedAttrib.vertexFormatType) == vertexFormatID); + ASSERT(static_cast(packedAttrib.divisor) == divisor); + + static_assert(sizeof(uint64_t) == sizeof(PackedAttribute), + "PackedAttributes must be 64-bits exactly."); + + attributeData[numAttributes++] = gl::bitCast(packedAttrib); +} + +bool PackedAttributeLayout::operator==(const PackedAttributeLayout &other) const +{ + return (numAttributes == other.numAttributes) && (flags == other.flags) && + (attributeData == other.attributeData); +} + +InputLayoutCache::InputLayoutCache() : mLayoutCache(kDefaultCacheSize * 2) {} + +InputLayoutCache::~InputLayoutCache() {} + +void InputLayoutCache::clear() +{ + mLayoutCache.Clear(); +} + +angle::Result InputLayoutCache::getInputLayout( + Context11 *context11, + const gl::State &state, + const std::vector ¤tAttributes, + const AttribIndexArray &sortedSemanticIndices, + gl::PrimitiveMode mode, + GLsizei vertexCount, + GLsizei instances, + const d3d11::InputLayout **inputLayoutOut) +{ + gl::Program *program = state.getProgram(); + const auto &shaderAttributes = program->getAttributes(); + PackedAttributeLayout layout; + + ProgramD3D *programD3D = GetImplAs(program); + bool programUsesInstancedPointSprites = + programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation(); + bool instancedPointSpritesActive = + programUsesInstancedPointSprites && (mode == gl::PrimitiveMode::Points); + + if (programUsesInstancedPointSprites) + { + layout.flags |= PackedAttributeLayout::FLAG_USES_INSTANCED_SPRITES; + } + + if (instancedPointSpritesActive) + { + layout.flags |= PackedAttributeLayout::FLAG_INSTANCED_SPRITES_ACTIVE; + } + + if (instances > 0) + { + layout.flags |= PackedAttributeLayout::FLAG_INSTANCED_RENDERING_ACTIVE; + } + + const auto &attribs = state.getVertexArray()->getVertexAttributes(); + const auto &bindings = state.getVertexArray()->getVertexBindings(); + const auto &locationToSemantic = programD3D->getAttribLocationToD3DSemantics(); + int divisorMultiplier = program->usesMultiview() ? program->getNumViews() : 1; + + for (size_t attribIndex : state.getProgramExecutable()->getActiveAttribLocationsMask()) + { + // Record the type of the associated vertex shader vector in our key + // This will prevent mismatched vertex shaders from using the same input layout + GLenum glslElementType = GetGLSLAttributeType(shaderAttributes, attribIndex); + + const auto &attrib = attribs[attribIndex]; + const auto &binding = bindings[attrib.bindingIndex]; + int d3dSemantic = locationToSemantic[attribIndex]; + + const auto ¤tValue = + state.getVertexAttribCurrentValue(static_cast(attribIndex)); + angle::FormatID vertexFormatID = gl::GetVertexFormatID(attrib, currentValue.Type); + + layout.addAttributeData(glslElementType, d3dSemantic, vertexFormatID, + binding.getDivisor() * divisorMultiplier); + } + + if (layout.numAttributes > 0 || layout.flags != 0) + { + auto it = mLayoutCache.Get(layout); + if (it != mLayoutCache.end()) + { + *inputLayoutOut = &it->second; + } + else + { + angle::TrimCache(mLayoutCache.max_size() / 2, kGCLimit, "input layout", &mLayoutCache); + + d3d11::InputLayout newInputLayout; + ANGLE_TRY(createInputLayout(context11, sortedSemanticIndices, currentAttributes, mode, + vertexCount, instances, &newInputLayout)); + + auto insertIt = mLayoutCache.Put(layout, std::move(newInputLayout)); + *inputLayoutOut = &insertIt->second; + } + } + + return angle::Result::Continue; +} + +angle::Result InputLayoutCache::createInputLayout( + Context11 *context11, + const AttribIndexArray &sortedSemanticIndices, + const std::vector ¤tAttributes, + gl::PrimitiveMode mode, + GLsizei vertexCount, + GLsizei instances, + d3d11::InputLayout *inputLayoutOut) +{ + Renderer11 *renderer = context11->getRenderer(); + ProgramD3D *programD3D = renderer->getStateManager()->getProgramD3D(); + D3D_FEATURE_LEVEL featureLevel = renderer->getRenderer11DeviceCaps().featureLevel; + + bool programUsesInstancedPointSprites = + programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation(); + + unsigned int inputElementCount = 0; + gl::AttribArray inputElements; + + for (size_t attribIndex = 0; attribIndex < currentAttributes.size(); ++attribIndex) + { + const auto &attrib = *currentAttributes[attribIndex]; + const int sortedIndex = sortedSemanticIndices[attribIndex]; + + D3D11_INPUT_CLASSIFICATION inputClass = + attrib.divisor > 0 ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA; + + angle::FormatID vertexFormatID = + gl::GetVertexFormatID(*attrib.attribute, attrib.currentValueType); + const auto &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormatID, featureLevel); + + auto *inputElement = &inputElements[inputElementCount]; + + inputElement->SemanticName = "TEXCOORD"; + inputElement->SemanticIndex = sortedIndex; + inputElement->Format = vertexFormatInfo.nativeFormat; + inputElement->InputSlot = static_cast(attribIndex); + inputElement->AlignedByteOffset = 0; + inputElement->InputSlotClass = inputClass; + inputElement->InstanceDataStepRate = attrib.divisor; + + inputElementCount++; + } + + // Instanced PointSprite emulation requires additional entries in the + // inputlayout to support the vertices that make up the pointsprite quad. + // We do this even if mode != GL_POINTS, since the shader signature has these inputs, and the + // input layout must match the shader + if (programUsesInstancedPointSprites) + { + // On 9_3, we must ensure that slot 0 contains non-instanced data. + // If slot 0 currently contains instanced data then we swap it with a non-instanced element. + // Note that instancing is only available on 9_3 via ANGLE_instanced_arrays, since 9_3 + // doesn't support OpenGL ES 3.0. + // As per the spec for ANGLE_instanced_arrays, not all attributes can be instanced + // simultaneously, so a non-instanced element must exist. + + UINT numIndicesPerInstance = 0; + if (instances > 0) + { + // This requires that the index range is resolved. + // Note: Vertex indexes can be arbitrarily large. + numIndicesPerInstance = gl::clampCast(vertexCount); + } + + for (size_t elementIndex = 0; elementIndex < inputElementCount; ++elementIndex) + { + // If rendering points and instanced pointsprite emulation is being used, the + // inputClass is required to be configured as per instance data + if (mode == gl::PrimitiveMode::Points) + { + inputElements[elementIndex].InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA; + inputElements[elementIndex].InstanceDataStepRate = 1; + if (numIndicesPerInstance > 0 && currentAttributes[elementIndex]->divisor > 0) + { + inputElements[elementIndex].InstanceDataStepRate = numIndicesPerInstance; + } + } + inputElements[elementIndex].InputSlot++; + } + + inputElements[inputElementCount].SemanticName = "SPRITEPOSITION"; + inputElements[inputElementCount].SemanticIndex = 0; + inputElements[inputElementCount].Format = DXGI_FORMAT_R32G32B32_FLOAT; + inputElements[inputElementCount].InputSlot = 0; + inputElements[inputElementCount].AlignedByteOffset = 0; + inputElements[inputElementCount].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; + inputElements[inputElementCount].InstanceDataStepRate = 0; + inputElementCount++; + + inputElements[inputElementCount].SemanticName = "SPRITETEXCOORD"; + inputElements[inputElementCount].SemanticIndex = 0; + inputElements[inputElementCount].Format = DXGI_FORMAT_R32G32_FLOAT; + inputElements[inputElementCount].InputSlot = 0; + inputElements[inputElementCount].AlignedByteOffset = sizeof(float) * 3; + inputElements[inputElementCount].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; + inputElements[inputElementCount].InstanceDataStepRate = 0; + inputElementCount++; + } + + ShaderExecutableD3D *shader = nullptr; + ANGLE_TRY(programD3D->getVertexExecutableForCachedInputLayout(context11, &shader, nullptr)); + + ShaderExecutableD3D *shader11 = GetAs(shader); + + InputElementArray inputElementArray(inputElements.data(), inputElementCount); + ShaderData vertexShaderData(shader11->getFunction(), shader11->getLength()); + + ANGLE_TRY(renderer->allocateResource(context11, inputElementArray, &vertexShaderData, + inputLayoutOut)); + return angle::Result::Continue; +} + +void InputLayoutCache::setCacheSize(size_t newCacheSize) +{ + // Forces a reset of the cache. + LayoutCache newCache(newCacheSize); + mLayoutCache.Swap(newCache); +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h new file mode 100644 index 0000000000..35d1b60607 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h @@ -0,0 +1,123 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// InputLayoutCache.h: Defines InputLayoutCache, a class that builds and caches +// D3D11 input layouts. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_INPUTLAYOUTCACHE_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_INPUTLAYOUTCACHE_H_ + +#include + +#include + +#include +#include + +#include "common/angleutils.h" +#include "libANGLE/Constants.h" +#include "libANGLE/Error.h" +#include "libANGLE/SizedMRUCache.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" +#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h" + +namespace rx +{ +struct PackedAttributeLayout +{ + PackedAttributeLayout(); + PackedAttributeLayout(const PackedAttributeLayout &other); + + void addAttributeData(GLenum glType, + UINT semanticIndex, + angle::FormatID vertexFormatID, + unsigned int divisor); + + bool operator==(const PackedAttributeLayout &other) const; + + enum Flags + { + FLAG_USES_INSTANCED_SPRITES = 0x1, + FLAG_INSTANCED_SPRITES_ACTIVE = 0x2, + FLAG_INSTANCED_RENDERING_ACTIVE = 0x4, + }; + + uint32_t numAttributes; + uint32_t flags; + gl::AttribArray attributeData; +}; +} // namespace rx + +namespace std +{ +template <> +struct hash +{ + size_t operator()(const rx::PackedAttributeLayout &value) const + { + return angle::ComputeGenericHash(value); + } +}; +} // namespace std + +namespace gl +{ +class Program; +} // namespace gl + +namespace rx +{ +class Context11; +struct TranslatedAttribute; +struct TranslatedIndexData; +struct SourceIndexData; +class ProgramD3D; +class Renderer11; + +class InputLayoutCache : angle::NonCopyable +{ + public: + InputLayoutCache(); + ~InputLayoutCache(); + + void clear(); + + // Useful for testing + void setCacheSize(size_t newCacheSize); + + angle::Result getInputLayout(Context11 *context, + const gl::State &state, + const std::vector ¤tAttributes, + const AttribIndexArray &sortedSemanticIndices, + gl::PrimitiveMode mode, + GLsizei vertexCount, + GLsizei instances, + const d3d11::InputLayout **inputLayoutOut); + + private: + angle::Result createInputLayout( + Context11 *context11, + const AttribIndexArray &sortedSemanticIndices, + const std::vector ¤tAttributes, + gl::PrimitiveMode mode, + GLsizei vertexCount, + GLsizei instances, + d3d11::InputLayout *inputLayoutOut); + + // Starting cache size. + static constexpr size_t kDefaultCacheSize = 1024; + + // The cache tries to clean up this many states at once. + static constexpr size_t kGCLimit = 128; + + using LayoutCache = angle::base::HashingMRUCache; + LayoutCache mLayoutCache; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_INPUTLAYOUTCACHE_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/MappedSubresourceVerifier11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/MappedSubresourceVerifier11.cpp new file mode 100644 index 0000000000..d0f6906f1e --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/MappedSubresourceVerifier11.cpp @@ -0,0 +1,119 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// MappedSubresourceVerifier11.cpp: Implements the +// rx::MappedSubresourceVerifier11 class, a simple wrapper to D3D11 Texture2D +// mapped memory so that ASAN and MSAN can catch memory errors done with a +// pointer to the mapped texture memory. + +#include "libANGLE/renderer/d3d/d3d11/MappedSubresourceVerifier11.h" + +#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" + +namespace rx +{ + +#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || defined(ANGLE_ENABLE_ASSERTS) + +namespace +{ + +# if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) +constexpr bool kUseWrap = true; +# else +constexpr bool kUseWrap = false; +# endif + +size_t getPitchCount(const D3D11_TEXTURE2D_DESC &desc) +{ + const d3d11::DXGIFormatSize &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(desc.Format); + ASSERT(desc.Height % dxgiFormatInfo.blockHeight == 0); + return desc.Height / dxgiFormatInfo.blockHeight; +} + +} // namespace + +MappedSubresourceVerifier11::MappedSubresourceVerifier11() = default; + +MappedSubresourceVerifier11::~MappedSubresourceVerifier11() +{ + ASSERT(!mOrigData); + ASSERT(!mWrapData.size()); +} + +void MappedSubresourceVerifier11::setDesc(const D3D11_TEXTURE2D_DESC &desc) +{ + ASSERT(desc.CPUAccessFlags & (D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE)); + ASSERT(desc.Width); + ASSERT(desc.Height); + ASSERT(!mOrigData); + ASSERT(!mWrapData.size()); + ASSERT(!mPitchType); + ASSERT(!mPitchCount); + mPitchType = &D3D11_MAPPED_SUBRESOURCE::RowPitch; + mPitchCount = getPitchCount(desc); +} + +void MappedSubresourceVerifier11::setDesc(const D3D11_TEXTURE3D_DESC &desc) +{ + ASSERT(desc.CPUAccessFlags & (D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE)); + ASSERT(desc.Width); + ASSERT(desc.Height); + ASSERT(desc.Depth); + ASSERT(!mOrigData); + ASSERT(!mWrapData.size()); + ASSERT(!mPitchType); + ASSERT(!mPitchCount); + mPitchType = &D3D11_MAPPED_SUBRESOURCE::DepthPitch; + mPitchCount = desc.Depth; +} + +void MappedSubresourceVerifier11::reset() +{ + ASSERT(!mOrigData); + ASSERT(!mWrapData.size()); + mPitchType = nullptr; + mPitchCount = 0; +} + +bool MappedSubresourceVerifier11::wrap(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map) +{ + ASSERT(map && map->pData); + ASSERT(mapType == D3D11_MAP_READ || mapType == D3D11_MAP_WRITE || + mapType == D3D11_MAP_READ_WRITE); + ASSERT(mPitchCount); + + if (kUseWrap) + { + if (!mWrapData.resize(mPitchCount * map->*mPitchType)) + return false; + } + + mOrigData = reinterpret_cast(map->pData); + + if (kUseWrap) + { + std::copy(mOrigData, mOrigData + mWrapData.size(), mWrapData.data()); + map->pData = mWrapData.data(); + } + return true; +} + +void MappedSubresourceVerifier11::unwrap() +{ + ASSERT(mPitchCount); + ASSERT(mOrigData); + if (kUseWrap) + { + std::copy(mWrapData.data(), mWrapData.data() + mWrapData.size(), mOrigData); + mWrapData = angle::MemoryBuffer(); + } + mOrigData = nullptr; +} + +#endif + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/MappedSubresourceVerifier11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/MappedSubresourceVerifier11.h new file mode 100644 index 0000000000..f0fc70eb85 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/MappedSubresourceVerifier11.h @@ -0,0 +1,63 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// MappedSubresourceVerifier11.h: Defines the rx::MappedSubresourceVerifier11 +// class, a simple wrapper to D3D11 Texture2D mapped memory so that ASAN +// MSAN can catch memory errors done with a pointer to the mapped texture +// memory. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_MAPPED_SUBRESOURCE_VERIFIER11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_MAPPED_SUBRESOURCE_VERIFIER11_H_ + +#include "common/MemoryBuffer.h" +#include "common/angleutils.h" + +namespace rx +{ + +class MappedSubresourceVerifier11 final : angle::NonCopyable +{ + public: + MappedSubresourceVerifier11(); + ~MappedSubresourceVerifier11(); + + void setDesc(const D3D11_TEXTURE2D_DESC &desc); + void setDesc(const D3D11_TEXTURE3D_DESC &desc); + void reset(); + + bool wrap(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map); + void unwrap(); + + private: +#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || defined(ANGLE_ENABLE_ASSERTS) + UINT D3D11_MAPPED_SUBRESOURCE::*mPitchType = nullptr; + size_t mPitchCount = 0; + angle::MemoryBuffer mWrapData; + uint8_t *mOrigData = nullptr; +#endif +}; + +#if !(defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || defined(ANGLE_ENABLE_ASSERTS)) + +inline MappedSubresourceVerifier11::MappedSubresourceVerifier11() = default; +inline MappedSubresourceVerifier11::~MappedSubresourceVerifier11() = default; + +inline void MappedSubresourceVerifier11::setDesc(const D3D11_TEXTURE2D_DESC &desc) {} +inline void MappedSubresourceVerifier11::setDesc(const D3D11_TEXTURE3D_DESC &desc) {} +inline void MappedSubresourceVerifier11::reset() {} + +inline bool MappedSubresourceVerifier11::wrap(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map) +{ + return true; +} + +inline void MappedSubresourceVerifier11::unwrap() {} + +#endif + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_MAPPED_SUBRESOURCE_VERIFIER11_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/NativeWindow11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/NativeWindow11.h new file mode 100644 index 0000000000..e11b19cace --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/NativeWindow11.h @@ -0,0 +1,38 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// NativeWindow11.h: Defines NativeWindow11, a class for managing and performing operations on an +// EGLNativeWindowType for the D3D11 renderer. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_NATIVEWINDOW11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_NATIVEWINDOW11_H_ + +#include "common/debug.h" +#include "common/platform.h" + +#include "libANGLE/Config.h" +#include "libANGLE/renderer/d3d/NativeWindowD3D.h" + +namespace rx +{ + +class NativeWindow11 : public NativeWindowD3D +{ + public: + NativeWindow11(EGLNativeWindowType window) : NativeWindowD3D(window) {} + + virtual HRESULT createSwapChain(ID3D11Device *device, + IDXGIFactory *factory, + DXGI_FORMAT format, + UINT width, + UINT height, + UINT samples, + IDXGISwapChain **swapChain) = 0; + virtual void commitChange() = 0; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_NATIVEWINDOW11_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp new file mode 100644 index 0000000000..9649a91dd3 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp @@ -0,0 +1,271 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// PixelTransfer11.cpp: +// Implementation for buffer-to-texture and texture-to-buffer copies. +// Used to implement pixel transfers from unpack and to pack buffers. +// + +#include "libANGLE/renderer/d3d/d3d11/PixelTransfer11.h" + +#include "libANGLE/Buffer.h" +#include "libANGLE/Context.h" +#include "libANGLE/Texture.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/d3d11/Buffer11.h" +#include "libANGLE/renderer/d3d/d3d11/Context11.h" +#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h" +#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" +#include "libANGLE/renderer/serial_utils.h" + +// Precompiled shaders +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_gs.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4f.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4i.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_vs.h" + +namespace rx +{ + +PixelTransfer11::PixelTransfer11(Renderer11 *renderer) + : mRenderer(renderer), + mResourcesLoaded(false), + mBufferToTextureVS(), + mBufferToTextureGS(), + mParamsConstantBuffer(), + mCopyRasterizerState(), + mCopyDepthStencilState() +{} + +PixelTransfer11::~PixelTransfer11() {} + +angle::Result PixelTransfer11::loadResources(const gl::Context *context) +{ + if (mResourcesLoaded) + { + return angle::Result::Continue; + } + + D3D11_RASTERIZER_DESC rasterDesc; + rasterDesc.FillMode = D3D11_FILL_SOLID; + rasterDesc.CullMode = D3D11_CULL_NONE; + rasterDesc.FrontCounterClockwise = FALSE; + rasterDesc.DepthBias = 0; + rasterDesc.SlopeScaledDepthBias = 0.0f; + rasterDesc.DepthBiasClamp = 0.0f; + rasterDesc.DepthClipEnable = TRUE; + rasterDesc.ScissorEnable = FALSE; + rasterDesc.MultisampleEnable = FALSE; + rasterDesc.AntialiasedLineEnable = FALSE; + + Context11 *context11 = GetImplAs(context); + + ANGLE_TRY(mRenderer->allocateResource(context11, rasterDesc, &mCopyRasterizerState)); + + D3D11_DEPTH_STENCIL_DESC depthStencilDesc; + depthStencilDesc.DepthEnable = true; + depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; + depthStencilDesc.DepthFunc = D3D11_COMPARISON_ALWAYS; + depthStencilDesc.StencilEnable = FALSE; + depthStencilDesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; + depthStencilDesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; + depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + + ANGLE_TRY(mRenderer->allocateResource(context11, depthStencilDesc, &mCopyDepthStencilState)); + + D3D11_BUFFER_DESC constantBufferDesc = {}; + constantBufferDesc.ByteWidth = roundUpPow2(sizeof(CopyShaderParams), 32u); + constantBufferDesc.Usage = D3D11_USAGE_DYNAMIC; + constantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + constantBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + constantBufferDesc.MiscFlags = 0; + constantBufferDesc.StructureByteStride = 0; + + ANGLE_TRY(mRenderer->allocateResource(context11, constantBufferDesc, &mParamsConstantBuffer)); + mParamsConstantBuffer.setInternalName("PixelTransfer11ConstantBuffer"); + + // init shaders + ANGLE_TRY(mRenderer->allocateResource(context11, ShaderData(g_VS_BufferToTexture), + &mBufferToTextureVS)); + mBufferToTextureVS.setInternalName("BufferToTextureVS"); + + ANGLE_TRY(mRenderer->allocateResource(context11, ShaderData(g_GS_BufferToTexture), + &mBufferToTextureGS)); + mBufferToTextureGS.setInternalName("BufferToTextureGS"); + + ANGLE_TRY(buildShaderMap(context)); + + StructZero(&mParamsData); + + mResourcesLoaded = true; + + return angle::Result::Continue; +} + +void PixelTransfer11::setBufferToTextureCopyParams(const gl::Box &destArea, + const gl::Extents &destSize, + GLenum internalFormat, + const gl::PixelUnpackState &unpack, + unsigned int offset, + CopyShaderParams *parametersOut) +{ + StructZero(parametersOut); + + float texelCenterX = 0.5f / static_cast(destSize.width); + float texelCenterY = 0.5f / static_cast(destSize.height); + + unsigned int bytesPerPixel = gl::GetSizedInternalFormatInfo(internalFormat).pixelBytes; + unsigned int alignmentBytes = static_cast(unpack.alignment); + unsigned int alignmentPixels = + (alignmentBytes <= bytesPerPixel ? 1 : alignmentBytes / bytesPerPixel); + + parametersOut->FirstPixelOffset = offset / bytesPerPixel; + parametersOut->PixelsPerRow = + static_cast((unpack.rowLength > 0) ? unpack.rowLength : destArea.width); + parametersOut->RowStride = roundUp(parametersOut->PixelsPerRow, alignmentPixels); + parametersOut->RowsPerSlice = static_cast(destArea.height); + parametersOut->PositionOffset[0] = + texelCenterX + (destArea.x / float(destSize.width)) * 2.0f - 1.0f; + parametersOut->PositionOffset[1] = + texelCenterY + ((destSize.height - destArea.y - 1) / float(destSize.height)) * 2.0f - 1.0f; + parametersOut->PositionScale[0] = 2.0f / static_cast(destSize.width); + parametersOut->PositionScale[1] = -2.0f / static_cast(destSize.height); + parametersOut->FirstSlice = destArea.z; +} + +angle::Result PixelTransfer11::copyBufferToTexture(const gl::Context *context, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + unsigned int offset, + RenderTargetD3D *destRenderTarget, + GLenum destinationFormat, + GLenum sourcePixelsType, + const gl::Box &destArea) +{ + ASSERT(unpackBuffer); + + ANGLE_TRY(loadResources(context)); + + gl::Extents destSize = destRenderTarget->getExtents(); + + ASSERT(destArea.x >= 0 && destArea.x + destArea.width <= destSize.width && destArea.y >= 0 && + destArea.y + destArea.height <= destSize.height && destArea.z >= 0 && + destArea.z + destArea.depth <= destSize.depth); + + ASSERT(mRenderer->supportsFastCopyBufferToTexture(destinationFormat)); + + const d3d11::PixelShader *pixelShader = findBufferToTexturePS(destinationFormat); + ASSERT(pixelShader); + + // The SRV must be in the proper read format, which may be different from the destination format + // EG: for half float data, we can load full precision floats with implicit conversion + GLenum unsizedFormat = gl::GetUnsizedFormat(destinationFormat); + const gl::InternalFormat &sourceglFormatInfo = + gl::GetInternalFormatInfo(unsizedFormat, sourcePixelsType); + + const d3d11::Format &sourceFormatInfo = d3d11::Format::Get( + sourceglFormatInfo.sizedInternalFormat, mRenderer->getRenderer11DeviceCaps()); + DXGI_FORMAT srvFormat = sourceFormatInfo.srvFormat; + ASSERT(srvFormat != DXGI_FORMAT_UNKNOWN); + Buffer11 *bufferStorage11 = GetAs(unpackBuffer->getImplementation()); + const d3d11::ShaderResourceView *bufferSRV = nullptr; + ANGLE_TRY(bufferStorage11->getSRV(context, srvFormat, &bufferSRV)); + ASSERT(bufferSRV != nullptr); + + const d3d11::RenderTargetView &textureRTV = + GetAs(destRenderTarget)->getRenderTargetView(); + ASSERT(textureRTV.valid()); + + CopyShaderParams shaderParams; + setBufferToTextureCopyParams(destArea, destSize, sourceglFormatInfo.sizedInternalFormat, unpack, + offset, &shaderParams); + + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + // Are we doing a 2D or 3D copy? + const auto *geometryShader = ((destSize.depth > 1) ? &mBufferToTextureGS : nullptr); + StateManager11 *stateManager = mRenderer->getStateManager(); + + stateManager->setDrawShaders(&mBufferToTextureVS, geometryShader, pixelShader); + stateManager->setShaderResource(gl::ShaderType::Fragment, 0, bufferSRV); + stateManager->setInputLayout(nullptr); + stateManager->setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); + + stateManager->setSingleVertexBuffer(nullptr, 0, 0); + stateManager->setSimpleBlendState(nullptr); + stateManager->setDepthStencilState(&mCopyDepthStencilState, 0xFFFFFFFF); + stateManager->setRasterizerState(&mCopyRasterizerState); + + stateManager->setRenderTarget(textureRTV.get(), nullptr); + + if (!StructEquals(mParamsData, shaderParams)) + { + d3d11::SetBufferData(deviceContext, mParamsConstantBuffer.get(), shaderParams); + mParamsData = shaderParams; + } + + stateManager->setVertexConstantBuffer(0, &mParamsConstantBuffer); + + // Set the viewport + stateManager->setSimpleViewport(destSize); + + UINT numPixels = (shaderParams.PixelsPerRow * destArea.height * destArea.depth); + deviceContext->Draw(numPixels, 0); + + return angle::Result::Continue; +} + +angle::Result PixelTransfer11::buildShaderMap(const gl::Context *context) +{ + d3d11::PixelShader bufferToTextureFloat; + d3d11::PixelShader bufferToTextureInt; + d3d11::PixelShader bufferToTextureUint; + + Context11 *context11 = GetImplAs(context); + + ANGLE_TRY(mRenderer->allocateResource(context11, ShaderData(g_PS_BufferToTexture_4F), + &bufferToTextureFloat)); + ANGLE_TRY(mRenderer->allocateResource(context11, ShaderData(g_PS_BufferToTexture_4I), + &bufferToTextureInt)); + ANGLE_TRY(mRenderer->allocateResource(context11, ShaderData(g_PS_BufferToTexture_4UI), + &bufferToTextureUint)); + + bufferToTextureFloat.setInternalName("BufferToTextureRGBA.ps"); + bufferToTextureInt.setInternalName("BufferToTextureRGBA-I.ps"); + bufferToTextureUint.setInternalName("BufferToTextureRGBA-UI.ps"); + + mBufferToTexturePSMap[GL_FLOAT] = std::move(bufferToTextureFloat); + mBufferToTexturePSMap[GL_INT] = std::move(bufferToTextureInt); + mBufferToTexturePSMap[GL_UNSIGNED_INT] = std::move(bufferToTextureUint); + + return angle::Result::Continue; +} + +const d3d11::PixelShader *PixelTransfer11::findBufferToTexturePS(GLenum internalFormat) const +{ + GLenum componentType = gl::GetSizedInternalFormatInfo(internalFormat).componentType; + if (componentType == GL_SIGNED_NORMALIZED || componentType == GL_UNSIGNED_NORMALIZED) + { + componentType = GL_FLOAT; + } + + auto shaderMapIt = mBufferToTexturePSMap.find(componentType); + return (shaderMapIt == mBufferToTexturePSMap.end() ? nullptr : &shaderMapIt->second); +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.h new file mode 100644 index 0000000000..bdb11b90ff --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.h @@ -0,0 +1,96 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// PixelTransfer11.h: +// Buffer-to-Texture and Texture-to-Buffer data transfers. +// Used to implement pixel unpack and pixel pack buffers in ES3. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_PIXELTRANSFER11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_PIXELTRANSFER11_H_ + +#include + +#include + +#include "common/platform.h" +#include "libANGLE/Error.h" +#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h" + +namespace gl +{ +class Buffer; +class Context; +struct Box; +struct Extents; +struct PixelUnpackState; +} // namespace gl + +namespace rx +{ +class Renderer11; +class RenderTargetD3D; + +class PixelTransfer11 +{ + public: + explicit PixelTransfer11(Renderer11 *renderer); + ~PixelTransfer11(); + + // unpack: the source buffer is stored in the unpack state, and buffer strides + // offset: the start of the data within the unpack buffer + // destRenderTarget: individual slice/layer of a target texture + // destinationFormat/sourcePixelsType: determines shaders + shader parameters + // destArea: the sub-section of destRenderTarget to copy to + angle::Result copyBufferToTexture(const gl::Context *context, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + unsigned int offset, + RenderTargetD3D *destRenderTarget, + GLenum destinationFormat, + GLenum sourcePixelsType, + const gl::Box &destArea); + + private: + struct CopyShaderParams + { + unsigned int FirstPixelOffset; + unsigned int PixelsPerRow; + unsigned int RowStride; + unsigned int RowsPerSlice; + float PositionOffset[2]; + float PositionScale[2]; + int TexLocationOffset[2]; + int TexLocationScale[2]; + unsigned int FirstSlice; + }; + + static void setBufferToTextureCopyParams(const gl::Box &destArea, + const gl::Extents &destSize, + GLenum internalFormat, + const gl::PixelUnpackState &unpack, + unsigned int offset, + CopyShaderParams *parametersOut); + + angle::Result loadResources(const gl::Context *context); + angle::Result buildShaderMap(const gl::Context *context); + const d3d11::PixelShader *findBufferToTexturePS(GLenum internalFormat) const; + + Renderer11 *mRenderer; + + bool mResourcesLoaded; + std::map mBufferToTexturePSMap; + d3d11::VertexShader mBufferToTextureVS; + d3d11::GeometryShader mBufferToTextureGS; + d3d11::Buffer mParamsConstantBuffer; + CopyShaderParams mParamsData; + + d3d11::RasterizerState mCopyRasterizerState; + d3d11::DepthStencilState mCopyDepthStencilState; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_PIXELTRANSFER11_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Program11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Program11.cpp new file mode 100644 index 0000000000..510065ccd6 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Program11.cpp @@ -0,0 +1,34 @@ +// +// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Program11: D3D11 implementation of an OpenGL Program. + +#include "libANGLE/renderer/d3d/d3d11/Program11.h" + +#include "libANGLE/Context.h" +#include "libANGLE/renderer/d3d/d3d11/Context11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/StateManager11.h" + +namespace rx +{ +Program11::Program11(const gl::ProgramState &programState, Renderer11 *renderer) + : ProgramD3D(programState, renderer) +{} + +Program11::~Program11() = default; + +angle::Result Program11::syncState(const gl::Context *context, + const gl::Program::DirtyBits &dirtyBits) +{ + Renderer11 *renderer11 = GetImplAs(context)->getRenderer(); + StateManager11 *stateManager = renderer11->getStateManager(); + + // This single flag should be replace by individual dirtyness. + stateManager->invalidateProgramUniformBuffers(); + + return angle::Result::Continue; +} +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Program11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Program11.h new file mode 100644 index 0000000000..2bd6bc3710 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Program11.h @@ -0,0 +1,28 @@ +// +// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Program11: D3D11 implementation of an OpenGL Program. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_PROGRAM11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_PROGRAM11_H_ + +#include "libANGLE/renderer/d3d/ProgramD3D.h" + +namespace rx +{ +class Renderer11; + +class Program11 : public ProgramD3D +{ + public: + Program11(const gl::ProgramState &programState, Renderer11 *renderer11); + ~Program11() override; + + angle::Result syncState(const gl::Context *context, + const gl::Program::DirtyBits &dirtyBits) override; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_PROGRAM11_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ProgramPipeline11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ProgramPipeline11.cpp new file mode 100644 index 0000000000..2790809dde --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ProgramPipeline11.cpp @@ -0,0 +1,21 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ProgramPipelineNULL.cpp: +// Implements the class methods for ProgramPipeline11. +// + +#include "libANGLE/renderer/d3d/d3d11/ProgramPipeline11.h" + +namespace rx +{ + +ProgramPipeline11::ProgramPipeline11(const gl::ProgramPipelineState &state) + : ProgramPipelineImpl(state) +{} + +ProgramPipeline11::~ProgramPipeline11() {} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ProgramPipeline11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ProgramPipeline11.h new file mode 100644 index 0000000000..cf838eec05 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ProgramPipeline11.h @@ -0,0 +1,27 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ProgramPipeline11.h: +// Defines the class interface for ProgramPipeline11, implementing ProgramPipelineImpl. +// + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_PROGRAMPIPELINE11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_PROGRAMPIPELINE11_H_ + +#include "libANGLE/renderer/ProgramPipelineImpl.h" + +namespace rx +{ + +class ProgramPipeline11 : public ProgramPipelineImpl +{ + public: + ProgramPipeline11(const gl::ProgramPipelineState &state); + ~ProgramPipeline11() override; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_PROGRAMPIPELINE11_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Query11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Query11.cpp new file mode 100644 index 0000000000..f2368e9f8f --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Query11.cpp @@ -0,0 +1,357 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Query11.cpp: Defines the rx::Query11 class which implements rx::QueryImpl. + +#include "libANGLE/renderer/d3d/d3d11/Query11.h" + +#include + +#include "common/utilities.h" +#include "libANGLE/Context.h" +#include "libANGLE/renderer/d3d/d3d11/Context11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" + +namespace +{ + +GLuint64 MergeQueryResults(gl::QueryType type, GLuint64 currentResult, GLuint64 newResult) +{ + switch (type) + { + case gl::QueryType::AnySamples: + case gl::QueryType::AnySamplesConservative: + return (currentResult == GL_TRUE || newResult == GL_TRUE) ? GL_TRUE : GL_FALSE; + + case gl::QueryType::TransformFeedbackPrimitivesWritten: + return currentResult + newResult; + + case gl::QueryType::TimeElapsed: + return currentResult + newResult; + + case gl::QueryType::Timestamp: + return newResult; + + case gl::QueryType::CommandsCompleted: + return newResult; + + default: + UNREACHABLE(); + return 0; + } +} + +} // anonymous namespace + +namespace rx +{ + +Query11::QueryState::QueryState() + : getDataAttemptCount(0), query(), beginTimestamp(), endTimestamp(), finished(false) +{} + +Query11::QueryState::~QueryState() {} + +Query11::Query11(Renderer11 *renderer, gl::QueryType type) + : QueryImpl(type), mResult(0), mResultSum(0), mRenderer(renderer) +{ + mActiveQuery = std::unique_ptr(new QueryState()); +} + +Query11::~Query11() +{ + mRenderer->getStateManager()->onDeleteQueryObject(this); +} + +angle::Result Query11::begin(const gl::Context *context) +{ + mResultSum = 0; + mRenderer->getStateManager()->onBeginQuery(this); + return resume(GetImplAs(context)); +} + +angle::Result Query11::end(const gl::Context *context) +{ + return pause(GetImplAs(context)); +} + +angle::Result Query11::queryCounter(const gl::Context *context) +{ + // This doesn't do anything for D3D11 as we don't support timestamps + ASSERT(getType() == gl::QueryType::Timestamp); + mResultSum = 0; + mPendingQueries.push_back(std::unique_ptr(new QueryState())); + return angle::Result::Continue; +} + +template +angle::Result Query11::getResultBase(Context11 *context11, T *params) +{ + ASSERT(!mActiveQuery->query.valid()); + ANGLE_TRY(flush(context11, true)); + ASSERT(mPendingQueries.empty()); + *params = static_cast(mResultSum); + + return angle::Result::Continue; +} + +angle::Result Query11::getResult(const gl::Context *context, GLint *params) +{ + return getResultBase(GetImplAs(context), params); +} + +angle::Result Query11::getResult(const gl::Context *context, GLuint *params) +{ + return getResultBase(GetImplAs(context), params); +} + +angle::Result Query11::getResult(const gl::Context *context, GLint64 *params) +{ + return getResultBase(GetImplAs(context), params); +} + +angle::Result Query11::getResult(const gl::Context *context, GLuint64 *params) +{ + return getResultBase(GetImplAs(context), params); +} + +angle::Result Query11::isResultAvailable(const gl::Context *context, bool *available) +{ + ANGLE_TRY(flush(GetImplAs(context), false)); + + *available = mPendingQueries.empty(); + return angle::Result::Continue; +} + +angle::Result Query11::pause(Context11 *context11) +{ + if (mActiveQuery->query.valid()) + { + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + gl::QueryType type = getType(); + + // If we are doing time elapsed query the end timestamp + if (type == gl::QueryType::TimeElapsed) + { + context->End(mActiveQuery->endTimestamp.get()); + } + + context->End(mActiveQuery->query.get()); + + mPendingQueries.push_back(std::move(mActiveQuery)); + mActiveQuery = std::unique_ptr(new QueryState()); + } + + return flush(context11, false); +} + +angle::Result Query11::resume(Context11 *context11) +{ + if (!mActiveQuery->query.valid()) + { + ANGLE_TRY(flush(context11, false)); + + gl::QueryType type = getType(); + D3D11_QUERY d3dQueryType = gl_d3d11::ConvertQueryType(type); + + D3D11_QUERY_DESC queryDesc; + queryDesc.Query = d3dQueryType; + queryDesc.MiscFlags = 0; + + ANGLE_TRY(mRenderer->allocateResource(context11, queryDesc, &mActiveQuery->query)); + + // If we are doing time elapsed we also need a query to actually query the timestamp + if (type == gl::QueryType::TimeElapsed) + { + D3D11_QUERY_DESC desc; + desc.Query = D3D11_QUERY_TIMESTAMP; + desc.MiscFlags = 0; + + ANGLE_TRY(mRenderer->allocateResource(context11, desc, &mActiveQuery->beginTimestamp)); + ANGLE_TRY(mRenderer->allocateResource(context11, desc, &mActiveQuery->endTimestamp)); + } + + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + + if (d3dQueryType != D3D11_QUERY_EVENT) + { + context->Begin(mActiveQuery->query.get()); + } + + // If we are doing time elapsed, query the begin timestamp + if (type == gl::QueryType::TimeElapsed) + { + context->End(mActiveQuery->beginTimestamp.get()); + } + } + + return angle::Result::Continue; +} + +angle::Result Query11::flush(Context11 *context11, bool force) +{ + while (!mPendingQueries.empty()) + { + QueryState *query = mPendingQueries.front().get(); + + do + { + ANGLE_TRY(testQuery(context11, query)); + if (!query->finished && !force) + { + return angle::Result::Continue; + } + } while (!query->finished); + + mResultSum = MergeQueryResults(getType(), mResultSum, mResult); + mPendingQueries.pop_front(); + } + + return angle::Result::Continue; +} + +angle::Result Query11::testQuery(Context11 *context11, QueryState *queryState) +{ + if (!queryState->finished) + { + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + switch (getType()) + { + case gl::QueryType::AnySamples: + case gl::QueryType::AnySamplesConservative: + { + ASSERT(queryState->query.valid()); + UINT64 numPixels = 0; + HRESULT result = + context->GetData(queryState->query.get(), &numPixels, sizeof(numPixels), 0); + ANGLE_TRY_HR(context11, result, "Failed to get the data of an internal query"); + + if (result == S_OK) + { + queryState->finished = true; + mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE; + } + } + break; + + case gl::QueryType::TransformFeedbackPrimitivesWritten: + { + ASSERT(queryState->query.valid()); + D3D11_QUERY_DATA_SO_STATISTICS soStats = {}; + HRESULT result = + context->GetData(queryState->query.get(), &soStats, sizeof(soStats), 0); + ANGLE_TRY_HR(context11, result, "Failed to get the data of an internal query"); + + if (result == S_OK) + { + queryState->finished = true; + mResult = static_cast(soStats.NumPrimitivesWritten); + } + } + break; + + case gl::QueryType::TimeElapsed: + { + ASSERT(queryState->query.valid()); + ASSERT(queryState->beginTimestamp.valid()); + ASSERT(queryState->endTimestamp.valid()); + D3D11_QUERY_DATA_TIMESTAMP_DISJOINT timeStats = {}; + HRESULT result = + context->GetData(queryState->query.get(), &timeStats, sizeof(timeStats), 0); + ANGLE_TRY_HR(context11, result, "Failed to get the data of an internal query"); + + if (result == S_OK) + { + UINT64 beginTime = 0; + HRESULT beginRes = context->GetData(queryState->beginTimestamp.get(), + &beginTime, sizeof(UINT64), 0); + ANGLE_TRY_HR(context11, beginRes, + "Failed to get the data of an internal query"); + + UINT64 endTime = 0; + HRESULT endRes = context->GetData(queryState->endTimestamp.get(), &endTime, + sizeof(UINT64), 0); + ANGLE_TRY_HR(context11, endRes, "Failed to get the data of an internal query"); + + if (beginRes == S_OK && endRes == S_OK) + { + queryState->finished = true; + if (timeStats.Disjoint) + { + mRenderer->setGPUDisjoint(); + } + static_assert(sizeof(UINT64) == sizeof(unsigned long long), + "D3D UINT64 isn't 64 bits"); + + angle::CheckedNumeric checkedTime(endTime); + checkedTime -= beginTime; + checkedTime *= 1000000000ull; + checkedTime /= timeStats.Frequency; + if (checkedTime.IsValid()) + { + mResult = checkedTime.ValueOrDie(); + } + else + { + mResult = std::numeric_limits::max() / timeStats.Frequency; + // If an overflow does somehow occur, there is no way the elapsed time + // is accurate, so we generate a disjoint event + mRenderer->setGPUDisjoint(); + } + } + } + } + break; + + case gl::QueryType::Timestamp: + { + // D3D11 doesn't support GL timestamp queries as D3D timestamps are not guaranteed + // to have any sort of continuity outside of a disjoint timestamp query block, which + // GL depends on + ASSERT(!queryState->query.valid()); + mResult = 0; + queryState->finished = true; + } + break; + + case gl::QueryType::CommandsCompleted: + { + ASSERT(queryState->query.valid()); + BOOL completed = 0; + HRESULT result = + context->GetData(queryState->query.get(), &completed, sizeof(completed), 0); + ANGLE_TRY_HR(context11, result, "Failed to get the data of an internal query"); + + if (result == S_OK) + { + queryState->finished = true; + ASSERT(completed == TRUE); + mResult = (completed == TRUE) ? GL_TRUE : GL_FALSE; + } + } + break; + + default: + UNREACHABLE(); + break; + } + + queryState->getDataAttemptCount++; + bool checkDeviceLost = + (queryState->getDataAttemptCount % kPollingD3DDeviceLostCheckFrequency) == 0; + if (!queryState->finished && checkDeviceLost && mRenderer->testDeviceLost()) + { + mRenderer->notifyDeviceLost(); + ANGLE_TRY_HR(context11, E_OUTOFMEMORY, + "Failed to test get query result, device is lost."); + } + } + + return angle::Result::Continue; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Query11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Query11.h new file mode 100644 index 0000000000..96ac59d742 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Query11.h @@ -0,0 +1,71 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Query11.h: Defines the rx::Query11 class which implements rx::QueryImpl. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_QUERY11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_QUERY11_H_ + +#include + +#include "libANGLE/renderer/QueryImpl.h" +#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h" + +namespace rx +{ +class Context11; +class Renderer11; + +class Query11 : public QueryImpl +{ + public: + Query11(Renderer11 *renderer, gl::QueryType type); + ~Query11() override; + + angle::Result begin(const gl::Context *context) override; + angle::Result end(const gl::Context *context) override; + angle::Result queryCounter(const gl::Context *context) override; + angle::Result getResult(const gl::Context *context, GLint *params) override; + angle::Result getResult(const gl::Context *context, GLuint *params) override; + angle::Result getResult(const gl::Context *context, GLint64 *params) override; + angle::Result getResult(const gl::Context *context, GLuint64 *params) override; + angle::Result isResultAvailable(const gl::Context *context, bool *available) override; + + angle::Result pause(Context11 *context11); + angle::Result resume(Context11 *context11); + + private: + struct QueryState final : private angle::NonCopyable + { + QueryState(); + ~QueryState(); + + unsigned int getDataAttemptCount; + + d3d11::Query query; + d3d11::Query beginTimestamp; + d3d11::Query endTimestamp; + bool finished; + }; + + angle::Result flush(Context11 *context11, bool force); + angle::Result testQuery(Context11 *context11, QueryState *queryState); + + template + angle::Result getResultBase(Context11 *context11, T *params); + + GLuint64 mResult; + GLuint64 mResultSum; + + Renderer11 *mRenderer; + + std::unique_ptr mActiveQuery; + std::deque> mPendingQueries; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_QUERY11_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp new file mode 100644 index 0000000000..964ac8c287 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp @@ -0,0 +1,323 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// RenderStateCache.cpp: Defines rx::RenderStateCache, a cache of Direct3D render +// state objects. + +#include "libANGLE/renderer/d3d/d3d11/RenderStateCache.h" + +#include + +#include "common/Color.h" +#include "common/debug.h" +#include "libANGLE/Context.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/renderer/d3d/d3d11/Context11.h" +#include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" + +namespace rx +{ +using namespace gl_d3d11; + +RenderStateCache::RenderStateCache() + : mBlendStateCache(kMaxStates), + mRasterizerStateCache(kMaxStates), + mDepthStencilStateCache(kMaxStates), + mSamplerStateCache(kMaxStates) +{} + +RenderStateCache::~RenderStateCache() {} + +void RenderStateCache::clear() +{ + mBlendStateCache.Clear(); + mRasterizerStateCache.Clear(); + mDepthStencilStateCache.Clear(); + mSamplerStateCache.Clear(); +} + +// static +d3d11::BlendStateKey RenderStateCache::GetBlendStateKey(const gl::Context *context, + Framebuffer11 *framebuffer11, + const gl::BlendStateExt &blendStateExt, + bool sampleAlphaToCoverage) +{ + d3d11::BlendStateKey key; + // All fields of the BlendStateExt inside the key should be initialized for the caching to + // work correctly. Due to mrt_perf_workaround, the actual indices of active draw buffers may be + // different, so both arrays should be tracked. + key.blendStateExt = gl::BlendStateExt(blendStateExt.getDrawBufferCount()); + const gl::AttachmentList &colorbuffers = framebuffer11->getColorAttachmentsForRender(context); + const gl::DrawBufferMask colorAttachmentsForRenderMask = + framebuffer11->getLastColorAttachmentsForRenderMask(); + + ASSERT(blendStateExt.getDrawBufferCount() <= colorAttachmentsForRenderMask.size()); + ASSERT(colorbuffers.size() == colorAttachmentsForRenderMask.count()); + + size_t keyBlendIndex = 0; + + // With blending disabled, factors and equations are ignored when building + // D3D11_RENDER_TARGET_BLEND_DESC, so we can reduce the amount of unique keys by + // enforcing default values. + for (size_t sourceIndex : colorAttachmentsForRenderMask) + { + ASSERT(keyBlendIndex < colorbuffers.size()); + const gl::FramebufferAttachment *attachment = colorbuffers[keyBlendIndex]; + + // Do not set blend state for null attachments that may be present when + // mrt_perf_workaround is disabled. + if (attachment == nullptr) + { + keyBlendIndex++; + continue; + } + + const uint8_t colorMask = blendStateExt.getColorMaskIndexed(sourceIndex); + + const gl::InternalFormat &internalFormat = *attachment->getFormat().info; + + key.blendStateExt.setColorMaskIndexed(keyBlendIndex, + gl_d3d11::GetColorMask(internalFormat) & colorMask); + key.rtvMax = static_cast(keyBlendIndex) + 1; + + // Some D3D11 drivers produce unexpected results when blending is enabled for integer + // attachments. Per OpenGL ES spec, it must be ignored anyway. When blending is disabled, + // the state remains default to reduce the number of unique keys. + if (blendStateExt.getEnabledMask().test(sourceIndex) && !internalFormat.isInt()) + { + key.blendStateExt.setEnabledIndexed(keyBlendIndex, true); + key.blendStateExt.setEquationsIndexed(keyBlendIndex, sourceIndex, blendStateExt); + key.blendStateExt.setFactorsIndexed(keyBlendIndex, sourceIndex, blendStateExt); + } + keyBlendIndex++; + } + + key.sampleAlphaToCoverage = sampleAlphaToCoverage ? 1 : 0; + return key; +} + +angle::Result RenderStateCache::getBlendState(const gl::Context *context, + Renderer11 *renderer, + const d3d11::BlendStateKey &key, + const d3d11::BlendState **outBlendState) +{ + auto keyIter = mBlendStateCache.Get(key); + if (keyIter != mBlendStateCache.end()) + { + *outBlendState = &keyIter->second; + return angle::Result::Continue; + } + + TrimCache(kMaxStates, kGCLimit, "blend state", &mBlendStateCache); + + // Create a new blend state and insert it into the cache + D3D11_BLEND_DESC blendDesc = {}; // avoid undefined fields + const gl::BlendStateExt &blendStateExt = key.blendStateExt; + + blendDesc.AlphaToCoverageEnable = key.sampleAlphaToCoverage != 0 ? TRUE : FALSE; + blendDesc.IndependentBlendEnable = key.rtvMax > 1 ? TRUE : FALSE; + + // D3D11 API always accepts an array of blend states. Its validity depends on the hardware + // feature level. Given that we do not expose GL entrypoints that set per-buffer blend states on + // systems lower than FL10_1, this array will be always valid. + + for (size_t i = 0; i < blendStateExt.getDrawBufferCount(); i++) + { + D3D11_RENDER_TARGET_BLEND_DESC &rtDesc = blendDesc.RenderTarget[i]; + + if (blendStateExt.getEnabledMask().test(i)) + { + rtDesc.BlendEnable = true; + rtDesc.SrcBlend = + gl_d3d11::ConvertBlendFunc(blendStateExt.getSrcColorIndexed(i), false); + rtDesc.DestBlend = + gl_d3d11::ConvertBlendFunc(blendStateExt.getDstColorIndexed(i), false); + rtDesc.BlendOp = gl_d3d11::ConvertBlendOp(blendStateExt.getEquationColorIndexed(i)); + rtDesc.SrcBlendAlpha = + gl_d3d11::ConvertBlendFunc(blendStateExt.getSrcAlphaIndexed(i), true); + rtDesc.DestBlendAlpha = + gl_d3d11::ConvertBlendFunc(blendStateExt.getDstAlphaIndexed(i), true); + rtDesc.BlendOpAlpha = + gl_d3d11::ConvertBlendOp(blendStateExt.getEquationAlphaIndexed(i)); + } + + // blendStateExt.colorMask follows the same packing scheme as + // D3D11_RENDER_TARGET_BLEND_DESC.RenderTargetWriteMask + rtDesc.RenderTargetWriteMask = blendStateExt.getColorMaskIndexed(i); + } + + d3d11::BlendState d3dBlendState; + ANGLE_TRY(renderer->allocateResource(GetImplAs(context), blendDesc, &d3dBlendState)); + const auto &iter = mBlendStateCache.Put(key, std::move(d3dBlendState)); + + *outBlendState = &iter->second; + + return angle::Result::Continue; +} + +angle::Result RenderStateCache::getRasterizerState(const gl::Context *context, + Renderer11 *renderer, + const gl::RasterizerState &rasterState, + bool scissorEnabled, + ID3D11RasterizerState **outRasterizerState) +{ + d3d11::RasterizerStateKey key; + key.rasterizerState = rasterState; + key.scissorEnabled = scissorEnabled ? 1 : 0; + + auto keyIter = mRasterizerStateCache.Get(key); + if (keyIter != mRasterizerStateCache.end()) + { + *outRasterizerState = keyIter->second.get(); + return angle::Result::Continue; + } + + TrimCache(kMaxStates, kGCLimit, "rasterizer state", &mRasterizerStateCache); + + D3D11_CULL_MODE cullMode = + gl_d3d11::ConvertCullMode(rasterState.cullFace, rasterState.cullMode); + + // Disable culling if drawing points + if (rasterState.pointDrawMode) + { + cullMode = D3D11_CULL_NONE; + } + + D3D11_RASTERIZER_DESC rasterDesc; + rasterDesc.FillMode = D3D11_FILL_SOLID; + rasterDesc.CullMode = cullMode; + rasterDesc.FrontCounterClockwise = (rasterState.frontFace == GL_CCW) ? FALSE : TRUE; + rasterDesc.DepthBiasClamp = 0.0f; // MSDN documentation of DepthBiasClamp implies a value of + // zero will preform no clamping, must be tested though. + rasterDesc.DepthClipEnable = TRUE; + rasterDesc.ScissorEnable = scissorEnabled ? TRUE : FALSE; + rasterDesc.MultisampleEnable = rasterState.multiSample; + rasterDesc.AntialiasedLineEnable = FALSE; + + if (rasterState.polygonOffsetFill) + { + rasterDesc.SlopeScaledDepthBias = rasterState.polygonOffsetFactor; + rasterDesc.DepthBias = (INT)rasterState.polygonOffsetUnits; + } + else + { + rasterDesc.SlopeScaledDepthBias = 0.0f; + rasterDesc.DepthBias = 0; + } + + d3d11::RasterizerState dx11RasterizerState; + ANGLE_TRY(renderer->allocateResource(GetImplAs(context), rasterDesc, + &dx11RasterizerState)); + *outRasterizerState = dx11RasterizerState.get(); + mRasterizerStateCache.Put(key, std::move(dx11RasterizerState)); + + return angle::Result::Continue; +} + +angle::Result RenderStateCache::getDepthStencilState(const gl::Context *context, + Renderer11 *renderer, + const gl::DepthStencilState &glState, + const d3d11::DepthStencilState **outDSState) +{ + auto keyIter = mDepthStencilStateCache.Get(glState); + if (keyIter != mDepthStencilStateCache.end()) + { + *outDSState = &keyIter->second; + return angle::Result::Continue; + } + + TrimCache(kMaxStates, kGCLimit, "depth stencil state", &mDepthStencilStateCache); + + D3D11_DEPTH_STENCIL_DESC dsDesc = {}; + dsDesc.DepthEnable = glState.depthTest ? TRUE : FALSE; + dsDesc.DepthWriteMask = ConvertDepthMask(glState.depthMask); + dsDesc.DepthFunc = ConvertComparison(glState.depthFunc); + dsDesc.StencilEnable = glState.stencilTest ? TRUE : FALSE; + dsDesc.StencilReadMask = ConvertStencilMask(glState.stencilMask); + dsDesc.StencilWriteMask = ConvertStencilMask(glState.stencilWritemask); + dsDesc.FrontFace.StencilFailOp = ConvertStencilOp(glState.stencilFail); + dsDesc.FrontFace.StencilDepthFailOp = ConvertStencilOp(glState.stencilPassDepthFail); + dsDesc.FrontFace.StencilPassOp = ConvertStencilOp(glState.stencilPassDepthPass); + dsDesc.FrontFace.StencilFunc = ConvertComparison(glState.stencilFunc); + dsDesc.BackFace.StencilFailOp = ConvertStencilOp(glState.stencilBackFail); + dsDesc.BackFace.StencilDepthFailOp = ConvertStencilOp(glState.stencilBackPassDepthFail); + dsDesc.BackFace.StencilPassOp = ConvertStencilOp(glState.stencilBackPassDepthPass); + dsDesc.BackFace.StencilFunc = ConvertComparison(glState.stencilBackFunc); + + d3d11::DepthStencilState dx11DepthStencilState; + ANGLE_TRY( + renderer->allocateResource(GetImplAs(context), dsDesc, &dx11DepthStencilState)); + const auto &iter = mDepthStencilStateCache.Put(glState, std::move(dx11DepthStencilState)); + + *outDSState = &iter->second; + + return angle::Result::Continue; +} + +angle::Result RenderStateCache::getSamplerState(const gl::Context *context, + Renderer11 *renderer, + const gl::SamplerState &samplerState, + ID3D11SamplerState **outSamplerState) +{ + auto keyIter = mSamplerStateCache.Get(samplerState); + if (keyIter != mSamplerStateCache.end()) + { + *outSamplerState = keyIter->second.get(); + return angle::Result::Continue; + } + + TrimCache(kMaxStates, kGCLimit, "sampler state", &mSamplerStateCache); + + const auto &featureLevel = renderer->getRenderer11DeviceCaps().featureLevel; + + D3D11_SAMPLER_DESC samplerDesc; + samplerDesc.Filter = + gl_d3d11::ConvertFilter(samplerState.getMinFilter(), samplerState.getMagFilter(), + samplerState.getMaxAnisotropy(), samplerState.getCompareMode()); + samplerDesc.AddressU = gl_d3d11::ConvertTextureWrap(samplerState.getWrapS()); + samplerDesc.AddressV = gl_d3d11::ConvertTextureWrap(samplerState.getWrapT()); + samplerDesc.AddressW = gl_d3d11::ConvertTextureWrap(samplerState.getWrapR()); + samplerDesc.MipLODBias = 0; + samplerDesc.MaxAnisotropy = + gl_d3d11::ConvertMaxAnisotropy(samplerState.getMaxAnisotropy(), featureLevel); + samplerDesc.ComparisonFunc = gl_d3d11::ConvertComparison(samplerState.getCompareFunc()); + angle::ColorF borderColor; + if (samplerState.getBorderColor().type == angle::ColorGeneric::Type::Float) + { + borderColor = samplerState.getBorderColor().colorF; + } + samplerDesc.BorderColor[0] = borderColor.red; + samplerDesc.BorderColor[1] = borderColor.green; + samplerDesc.BorderColor[2] = borderColor.blue; + samplerDesc.BorderColor[3] = borderColor.alpha; + samplerDesc.MinLOD = samplerState.getMinLod(); + samplerDesc.MaxLOD = samplerState.getMaxLod(); + + if (featureLevel <= D3D_FEATURE_LEVEL_9_3) + { + // Check that maxLOD is nearly FLT_MAX (1000.0f is the default), since 9_3 doesn't support + // anything other than FLT_MAX. Note that Feature Level 9_* only supports GL ES 2.0, so the + // consumer of ANGLE can't modify the Max LOD themselves. + ASSERT(samplerState.getMaxLod() >= 999.9f); + + // Now just set MaxLOD to FLT_MAX. Other parts of the renderer (e.g. the non-zero max LOD + // workaround) should take account of this. + samplerDesc.MaxLOD = FLT_MAX; + } + + d3d11::SamplerState dx11SamplerState; + ANGLE_TRY( + renderer->allocateResource(GetImplAs(context), samplerDesc, &dx11SamplerState)); + *outSamplerState = dx11SamplerState.get(); + mSamplerStateCache.Put(samplerState, std::move(dx11SamplerState)); + + return angle::Result::Continue; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.h new file mode 100644 index 0000000000..bd853fe86e --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.h @@ -0,0 +1,124 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// RenderStateCache.h: Defines rx::RenderStateCache, a cache of Direct3D render +// state objects. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_RENDERSTATECACHE_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_RENDERSTATECACHE_H_ + +#include "common/angleutils.h" +#include "libANGLE/Error.h" +#include "libANGLE/SizedMRUCache.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" + +#include + +namespace std +{ +template <> +struct hash +{ + size_t operator()(const rx::d3d11::BlendStateKey &key) const + { + return angle::ComputeGenericHash(key); + } +}; + +template <> +struct hash +{ + size_t operator()(const rx::d3d11::RasterizerStateKey &key) const + { + return angle::ComputeGenericHash(key); + } +}; + +template <> +struct hash +{ + size_t operator()(const gl::DepthStencilState &key) const + { + return angle::ComputeGenericHash(key); + } +}; + +template <> +struct hash +{ + size_t operator()(const gl::SamplerState &key) const { return angle::ComputeGenericHash(key); } +}; +} // namespace std + +namespace rx +{ +class Framebuffer11; +class Renderer11; + +class RenderStateCache : angle::NonCopyable +{ + public: + RenderStateCache(); + virtual ~RenderStateCache(); + + void clear(); + + static d3d11::BlendStateKey GetBlendStateKey(const gl::Context *context, + Framebuffer11 *framebuffer11, + const gl::BlendStateExt &blendStateExt, + bool sampleAlphaToCoverage); + angle::Result getBlendState(const gl::Context *context, + Renderer11 *renderer, + const d3d11::BlendStateKey &key, + const d3d11::BlendState **outBlendState); + angle::Result getRasterizerState(const gl::Context *context, + Renderer11 *renderer, + const gl::RasterizerState &rasterState, + bool scissorEnabled, + ID3D11RasterizerState **outRasterizerState); + angle::Result getDepthStencilState(const gl::Context *context, + Renderer11 *renderer, + const gl::DepthStencilState &dsState, + const d3d11::DepthStencilState **outDSState); + angle::Result getSamplerState(const gl::Context *context, + Renderer11 *renderer, + const gl::SamplerState &samplerState, + ID3D11SamplerState **outSamplerState); + + private: + // MSDN's documentation of ID3D11Device::CreateBlendState, ID3D11Device::CreateRasterizerState, + // ID3D11Device::CreateDepthStencilState and ID3D11Device::CreateSamplerState claims the maximum + // number of unique states of each type an application can create is 4096 + // TODO(ShahmeerEsmail): Revisit the cache sizes to make sure they are appropriate for most + // scenarios. + static constexpr unsigned int kMaxStates = 4096; + + // The cache tries to clean up this many states at once. + static constexpr unsigned int kGCLimit = 128; + + // Blend state cache + using BlendStateMap = angle::base::HashingMRUCache; + BlendStateMap mBlendStateCache; + + // Rasterizer state cache + using RasterizerStateMap = + angle::base::HashingMRUCache; + RasterizerStateMap mRasterizerStateCache; + + // Depth stencil state cache + using DepthStencilStateMap = + angle::base::HashingMRUCache; + DepthStencilStateMap mDepthStencilStateCache; + + // Sample state cache + using SamplerStateMap = angle::base::HashingMRUCache; + SamplerStateMap mSamplerStateCache; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_RENDERSTATECACHE_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp new file mode 100644 index 0000000000..2f550b5a77 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp @@ -0,0 +1,403 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// RenderTarget11.cpp: Implements a DX11-specific wrapper for ID3D11View pointers +// retained by Renderbuffers. + +#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" + +#include "libANGLE/Context.h" +#include "libANGLE/renderer/d3d/d3d11/Context11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/SwapChain11.h" +#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" + +namespace rx +{ + +namespace +{ +bool GetTextureProperties(ID3D11Resource *resource, unsigned int *mipLevels, unsigned int *samples) +{ + ID3D11Texture1D *texture1D = d3d11::DynamicCastComObject(resource); + if (texture1D) + { + D3D11_TEXTURE1D_DESC texDesc; + texture1D->GetDesc(&texDesc); + SafeRelease(texture1D); + + *mipLevels = texDesc.MipLevels; + *samples = 0; + + return true; + } + + ID3D11Texture2D *texture2D = d3d11::DynamicCastComObject(resource); + if (texture2D) + { + D3D11_TEXTURE2D_DESC texDesc; + texture2D->GetDesc(&texDesc); + SafeRelease(texture2D); + + *mipLevels = texDesc.MipLevels; + *samples = texDesc.SampleDesc.Count > 1 ? texDesc.SampleDesc.Count : 0; + + return true; + } + + ID3D11Texture3D *texture3D = d3d11::DynamicCastComObject(resource); + if (texture3D) + { + D3D11_TEXTURE3D_DESC texDesc; + texture3D->GetDesc(&texDesc); + SafeRelease(texture3D); + + *mipLevels = texDesc.MipLevels; + *samples = 0; + + return true; + } + + return false; +} + +unsigned int GetRTVSubresourceIndex(ID3D11Resource *resource, ID3D11RenderTargetView *view) +{ + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + view->GetDesc(&rtvDesc); + + unsigned int mipSlice = 0; + unsigned int arraySlice = 0; + + switch (rtvDesc.ViewDimension) + { + case D3D11_RTV_DIMENSION_TEXTURE1D: + mipSlice = rtvDesc.Texture1D.MipSlice; + arraySlice = 0; + break; + + case D3D11_RTV_DIMENSION_TEXTURE1DARRAY: + mipSlice = rtvDesc.Texture1DArray.MipSlice; + arraySlice = rtvDesc.Texture1DArray.FirstArraySlice; + break; + + case D3D11_RTV_DIMENSION_TEXTURE2D: + mipSlice = rtvDesc.Texture2D.MipSlice; + arraySlice = 0; + break; + + case D3D11_RTV_DIMENSION_TEXTURE2DARRAY: + mipSlice = rtvDesc.Texture2DArray.MipSlice; + arraySlice = rtvDesc.Texture2DArray.FirstArraySlice; + break; + + case D3D11_RTV_DIMENSION_TEXTURE2DMS: + mipSlice = 0; + arraySlice = 0; + break; + + case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY: + mipSlice = 0; + arraySlice = rtvDesc.Texture2DMSArray.FirstArraySlice; + break; + + case D3D11_RTV_DIMENSION_TEXTURE3D: + mipSlice = rtvDesc.Texture3D.MipSlice; + arraySlice = 0; + break; + + case D3D11_RTV_DIMENSION_UNKNOWN: + case D3D11_RTV_DIMENSION_BUFFER: + UNIMPLEMENTED(); + break; + + default: + UNREACHABLE(); + break; + } + + unsigned int mipLevels, samples; + GetTextureProperties(resource, &mipLevels, &samples); + + return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels); +} + +unsigned int GetDSVSubresourceIndex(ID3D11Resource *resource, ID3D11DepthStencilView *view) +{ + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + view->GetDesc(&dsvDesc); + + unsigned int mipSlice = 0; + unsigned int arraySlice = 0; + + switch (dsvDesc.ViewDimension) + { + case D3D11_DSV_DIMENSION_TEXTURE1D: + mipSlice = dsvDesc.Texture1D.MipSlice; + arraySlice = 0; + break; + + case D3D11_DSV_DIMENSION_TEXTURE1DARRAY: + mipSlice = dsvDesc.Texture1DArray.MipSlice; + arraySlice = dsvDesc.Texture1DArray.FirstArraySlice; + break; + + case D3D11_DSV_DIMENSION_TEXTURE2D: + mipSlice = dsvDesc.Texture2D.MipSlice; + arraySlice = 0; + break; + + case D3D11_DSV_DIMENSION_TEXTURE2DARRAY: + mipSlice = dsvDesc.Texture2DArray.MipSlice; + arraySlice = dsvDesc.Texture2DArray.FirstArraySlice; + break; + + case D3D11_DSV_DIMENSION_TEXTURE2DMS: + mipSlice = 0; + arraySlice = 0; + break; + + case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY: + mipSlice = 0; + arraySlice = dsvDesc.Texture2DMSArray.FirstArraySlice; + break; + + case D3D11_DSV_DIMENSION_UNKNOWN: + UNIMPLEMENTED(); + break; + + default: + UNREACHABLE(); + break; + } + + unsigned int mipLevels, samples; + GetTextureProperties(resource, &mipLevels, &samples); + + return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels); +} + +GLenum GetSurfaceRTFormat(bool depth, SwapChain11 *swapChain) +{ + return (depth ? swapChain->getDepthBufferInternalFormat() + : swapChain->getRenderTargetInternalFormat()); +} + +const d3d11::Format &GetSurfaceFormatSet(bool depth, SwapChain11 *swapChain, Renderer11 *renderer) +{ + return d3d11::Format::Get(GetSurfaceRTFormat(depth, swapChain), + renderer->getRenderer11DeviceCaps()); +} + +} // anonymous namespace + +RenderTarget11::RenderTarget11(const d3d11::Format &formatSet) : mFormatSet(formatSet) {} + +RenderTarget11::~RenderTarget11() {} + +TextureRenderTarget11::TextureRenderTarget11(d3d11::RenderTargetView &&rtv, + const TextureHelper11 &resource, + const d3d11::SharedSRV &srv, + const d3d11::SharedSRV &blitSRV, + GLenum internalFormat, + const d3d11::Format &formatSet, + GLsizei width, + GLsizei height, + GLsizei depth, + GLsizei samples) + : RenderTarget11(formatSet), + mWidth(width), + mHeight(height), + mDepth(depth), + mInternalFormat(internalFormat), + mSamples(samples), + mSubresourceIndex(0), + mTexture(resource), + mRenderTarget(std::move(rtv)), + mDepthStencil(), + mShaderResource(srv.makeCopy()), + mBlitShaderResource(blitSRV.makeCopy()) +{ + if (mRenderTarget.valid() && mTexture.valid()) + { + mSubresourceIndex = GetRTVSubresourceIndex(mTexture.get(), mRenderTarget.get()); + } + ASSERT(mFormatSet.formatID != angle::FormatID::NONE || mWidth == 0 || mHeight == 0); +} + +TextureRenderTarget11::TextureRenderTarget11(d3d11::DepthStencilView &&dsv, + const TextureHelper11 &resource, + const d3d11::SharedSRV &srv, + GLenum internalFormat, + const d3d11::Format &formatSet, + GLsizei width, + GLsizei height, + GLsizei depth, + GLsizei samples) + : RenderTarget11(formatSet), + mWidth(width), + mHeight(height), + mDepth(depth), + mInternalFormat(internalFormat), + mSamples(samples), + mSubresourceIndex(0), + mTexture(resource), + mRenderTarget(), + mDepthStencil(std::move(dsv)), + mShaderResource(srv.makeCopy()), + mBlitShaderResource() +{ + if (mDepthStencil.valid() && mTexture.valid()) + { + mSubresourceIndex = GetDSVSubresourceIndex(mTexture.get(), mDepthStencil.get()); + } + ASSERT(mFormatSet.formatID != angle::FormatID::NONE || mWidth == 0 || mHeight == 0); +} + +TextureRenderTarget11::~TextureRenderTarget11() {} + +const TextureHelper11 &TextureRenderTarget11::getTexture() const +{ + return mTexture; +} + +const d3d11::RenderTargetView &TextureRenderTarget11::getRenderTargetView() const +{ + return mRenderTarget; +} + +const d3d11::DepthStencilView &TextureRenderTarget11::getDepthStencilView() const +{ + return mDepthStencil; +} + +angle::Result TextureRenderTarget11::getShaderResourceView(const gl::Context *context, + const d3d11::SharedSRV **outSRV) +{ + *outSRV = &mShaderResource; + return angle::Result::Continue; +} + +angle::Result TextureRenderTarget11::getBlitShaderResourceView(const gl::Context *context, + const d3d11::SharedSRV **outSRV) +{ + *outSRV = &mBlitShaderResource; + return angle::Result::Continue; +} + +GLsizei TextureRenderTarget11::getWidth() const +{ + return mWidth; +} + +GLsizei TextureRenderTarget11::getHeight() const +{ + return mHeight; +} + +GLsizei TextureRenderTarget11::getDepth() const +{ + return mDepth; +} + +GLenum TextureRenderTarget11::getInternalFormat() const +{ + return mInternalFormat; +} + +GLsizei TextureRenderTarget11::getSamples() const +{ + return mSamples; +} + +unsigned int TextureRenderTarget11::getSubresourceIndex() const +{ + return mSubresourceIndex; +} + +SurfaceRenderTarget11::SurfaceRenderTarget11(SwapChain11 *swapChain, + Renderer11 *renderer, + bool depth) + : RenderTarget11(GetSurfaceFormatSet(depth, swapChain, renderer)), + mSwapChain(swapChain), + mDepth(depth) +{ + ASSERT(mSwapChain); +} + +SurfaceRenderTarget11::~SurfaceRenderTarget11() {} + +GLsizei SurfaceRenderTarget11::getWidth() const +{ + return mSwapChain->getWidth(); +} + +GLsizei SurfaceRenderTarget11::getHeight() const +{ + return mSwapChain->getHeight(); +} + +GLsizei SurfaceRenderTarget11::getDepth() const +{ + return 1; +} + +GLenum SurfaceRenderTarget11::getInternalFormat() const +{ + return GetSurfaceRTFormat(mDepth, mSwapChain); +} + +GLsizei SurfaceRenderTarget11::getSamples() const +{ + return mSwapChain->getSamples(); +} + +const TextureHelper11 &SurfaceRenderTarget11::getTexture() const +{ + return (mDepth ? mSwapChain->getDepthStencilTexture() : mSwapChain->getOffscreenTexture()); +} + +const d3d11::RenderTargetView &SurfaceRenderTarget11::getRenderTargetView() const +{ + ASSERT(!mDepth); + return mSwapChain->getRenderTarget(); +} + +const d3d11::DepthStencilView &SurfaceRenderTarget11::getDepthStencilView() const +{ + ASSERT(mDepth); + return mSwapChain->getDepthStencil(); +} + +angle::Result SurfaceRenderTarget11::getShaderResourceView(const gl::Context *context, + const d3d11::SharedSRV **outSRV) +{ + if (mDepth) + { + *outSRV = &mSwapChain->getDepthStencilShaderResource(); + } + else + { + ANGLE_TRY(mSwapChain->getRenderTargetShaderResource(GetImplAs(context), outSRV)); + } + return angle::Result::Continue; +} + +angle::Result SurfaceRenderTarget11::getBlitShaderResourceView(const gl::Context *context, + const d3d11::SharedSRV **outSRV) +{ + // The SurfaceRenderTargetView format should always be such that the normal SRV works for blits. + return getShaderResourceView(context, outSRV); +} + +unsigned int SurfaceRenderTarget11::getSubresourceIndex() const +{ + return 0; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h new file mode 100644 index 0000000000..8467831e3b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h @@ -0,0 +1,133 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// RenderTarget11.h: Defines a DX11-specific wrapper for ID3D11View pointers +// retained by Renderbuffers. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_RENDERTARGET11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_RENDERTARGET11_H_ + +#include "libANGLE/renderer/d3d/RenderTargetD3D.h" +#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" + +namespace rx +{ +class SwapChain11; +class Renderer11; + +class RenderTarget11 : public RenderTargetD3D +{ + public: + RenderTarget11(const d3d11::Format &formatSet); + ~RenderTarget11() override; + + virtual const TextureHelper11 &getTexture() const = 0; + virtual const d3d11::RenderTargetView &getRenderTargetView() const = 0; + virtual const d3d11::DepthStencilView &getDepthStencilView() const = 0; + virtual angle::Result getShaderResourceView(const gl::Context *context, + const d3d11::SharedSRV **outSRV) = 0; + virtual angle::Result getBlitShaderResourceView(const gl::Context *context, + const d3d11::SharedSRV **outSRV) = 0; + + virtual unsigned int getSubresourceIndex() const = 0; + + const d3d11::Format &getFormatSet() const { return mFormatSet; } + + protected: + const d3d11::Format &mFormatSet; +}; + +class TextureRenderTarget11 : public RenderTarget11 +{ + public: + // TextureRenderTarget11 takes ownership of any D3D11 resources it is given and will AddRef them + TextureRenderTarget11(d3d11::RenderTargetView &&rtv, + const TextureHelper11 &resource, + const d3d11::SharedSRV &srv, + const d3d11::SharedSRV &blitSRV, + GLenum internalFormat, + const d3d11::Format &formatSet, + GLsizei width, + GLsizei height, + GLsizei depth, + GLsizei samples); + TextureRenderTarget11(d3d11::DepthStencilView &&dsv, + const TextureHelper11 &resource, + const d3d11::SharedSRV &srv, + GLenum internalFormat, + const d3d11::Format &formatSet, + GLsizei width, + GLsizei height, + GLsizei depth, + GLsizei samples); + ~TextureRenderTarget11() override; + + GLsizei getWidth() const override; + GLsizei getHeight() const override; + GLsizei getDepth() const override; + GLenum getInternalFormat() const override; + GLsizei getSamples() const override; + + const TextureHelper11 &getTexture() const override; + const d3d11::RenderTargetView &getRenderTargetView() const override; + const d3d11::DepthStencilView &getDepthStencilView() const override; + angle::Result getShaderResourceView(const gl::Context *context, + const d3d11::SharedSRV **outSRV) override; + angle::Result getBlitShaderResourceView(const gl::Context *context, + const d3d11::SharedSRV **outSRV) override; + + unsigned int getSubresourceIndex() const override; + + private: + GLsizei mWidth; + GLsizei mHeight; + GLsizei mDepth; + GLenum mInternalFormat; + GLsizei mSamples; + + unsigned int mSubresourceIndex; + TextureHelper11 mTexture; + d3d11::RenderTargetView mRenderTarget; + d3d11::DepthStencilView mDepthStencil; + d3d11::SharedSRV mShaderResource; + + // Shader resource view to use with internal blit shaders. Not set for depth/stencil render + // targets. + d3d11::SharedSRV mBlitShaderResource; +}; + +class SurfaceRenderTarget11 : public RenderTarget11 +{ + public: + SurfaceRenderTarget11(SwapChain11 *swapChain, Renderer11 *renderer, bool depth); + ~SurfaceRenderTarget11() override; + + GLsizei getWidth() const override; + GLsizei getHeight() const override; + GLsizei getDepth() const override; + GLenum getInternalFormat() const override; + GLsizei getSamples() const override; + + const TextureHelper11 &getTexture() const override; + const d3d11::RenderTargetView &getRenderTargetView() const override; + const d3d11::DepthStencilView &getDepthStencilView() const override; + angle::Result getShaderResourceView(const gl::Context *context, + const d3d11::SharedSRV **outSRV) override; + angle::Result getBlitShaderResourceView(const gl::Context *context, + const d3d11::SharedSRV **outSRV) override; + + unsigned int getSubresourceIndex() const override; + + private: + SwapChain11 *mSwapChain; + bool mDepth; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_RENDERTARGET11_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp new file mode 100644 index 0000000000..fdd264e92b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp @@ -0,0 +1,4454 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Renderer11.cpp: Implements a back-end specific class for the D3D11 renderer. + +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" + +#include +#include +#include + +#include "anglebase/no_destructor.h" +#include "common/tls.h" +#include "common/utilities.h" +#include "libANGLE/Buffer.h" +#include "libANGLE/Context.h" +#include "libANGLE/Display.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/Program.h" +#include "libANGLE/State.h" +#include "libANGLE/Surface.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/histogram_macros.h" +#include "libANGLE/renderer/d3d/CompilerD3D.h" +#include "libANGLE/renderer/d3d/DeviceD3D.h" +#include "libANGLE/renderer/d3d/DisplayD3D.h" +#include "libANGLE/renderer/d3d/FramebufferD3D.h" +#include "libANGLE/renderer/d3d/IndexDataManager.h" +#include "libANGLE/renderer/d3d/RenderbufferD3D.h" +#include "libANGLE/renderer/d3d/ShaderD3D.h" +#include "libANGLE/renderer/d3d/SurfaceD3D.h" +#include "libANGLE/renderer/d3d/TextureD3D.h" +#include "libANGLE/renderer/d3d/VertexDataManager.h" +#include "libANGLE/renderer/d3d/d3d11/Blit11.h" +#include "libANGLE/renderer/d3d/d3d11/Buffer11.h" +#include "libANGLE/renderer/d3d/d3d11/Clear11.h" +#include "libANGLE/renderer/d3d/d3d11/Context11.h" +#include "libANGLE/renderer/d3d/d3d11/ExternalImageSiblingImpl11.h" +#include "libANGLE/renderer/d3d/d3d11/Fence11.h" +#include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h" +#include "libANGLE/renderer/d3d/d3d11/Image11.h" +#include "libANGLE/renderer/d3d/d3d11/IndexBuffer11.h" +#include "libANGLE/renderer/d3d/d3d11/PixelTransfer11.h" +#include "libANGLE/renderer/d3d/d3d11/Program11.h" +#include "libANGLE/renderer/d3d/d3d11/Query11.h" +#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" +#include "libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h" +#include "libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.h" +#include "libANGLE/renderer/d3d/d3d11/SwapChain11.h" +#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h" +#include "libANGLE/renderer/d3d/d3d11/TransformFeedback11.h" +#include "libANGLE/renderer/d3d/d3d11/Trim11.h" +#include "libANGLE/renderer/d3d/d3d11/VertexArray11.h" +#include "libANGLE/renderer/d3d/d3d11/VertexBuffer11.h" +#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" +#include "libANGLE/renderer/d3d/driver_utils_d3d.h" +#include "libANGLE/renderer/driver_utils.h" +#include "libANGLE/renderer/dxgi_support_table.h" +#include "libANGLE/renderer/renderer_utils.h" +#include "libANGLE/trace.h" + +#ifdef ANGLE_ENABLE_WINDOWS_UWP +# include "libANGLE/renderer/d3d/d3d11/winrt/NativeWindow11WinRT.h" +#else +# include "libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.h" +#endif + +#ifdef ANGLE_ENABLE_D3D11_COMPOSITOR_NATIVE_WINDOW +# include "libANGLE/renderer/d3d/d3d11/converged/CompositorNativeWindow11.h" +#endif + +// Enable ANGLE_SKIP_DXGI_1_2_CHECK if there is not a possibility of using cross-process +// HWNDs or the Windows 7 Platform Update (KB2670838) is expected to be installed. +#ifndef ANGLE_SKIP_DXGI_1_2_CHECK +# define ANGLE_SKIP_DXGI_1_2_CHECK 0 +#endif + +namespace rx +{ + +namespace +{ + +enum +{ + MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 = 16 +}; + +enum ANGLEFeatureLevel +{ + ANGLE_FEATURE_LEVEL_INVALID, + ANGLE_FEATURE_LEVEL_9_3, + ANGLE_FEATURE_LEVEL_10_0, + ANGLE_FEATURE_LEVEL_10_1, + ANGLE_FEATURE_LEVEL_11_0, + ANGLE_FEATURE_LEVEL_11_1, + NUM_ANGLE_FEATURE_LEVELS +}; + +ANGLEFeatureLevel GetANGLEFeatureLevel(D3D_FEATURE_LEVEL d3dFeatureLevel) +{ + switch (d3dFeatureLevel) + { + case D3D_FEATURE_LEVEL_9_3: + return ANGLE_FEATURE_LEVEL_9_3; + case D3D_FEATURE_LEVEL_10_0: + return ANGLE_FEATURE_LEVEL_10_0; + case D3D_FEATURE_LEVEL_10_1: + return ANGLE_FEATURE_LEVEL_10_1; + case D3D_FEATURE_LEVEL_11_0: + return ANGLE_FEATURE_LEVEL_11_0; + case D3D_FEATURE_LEVEL_11_1: + return ANGLE_FEATURE_LEVEL_11_1; + default: + return ANGLE_FEATURE_LEVEL_INVALID; + } +} + +void SetLineLoopIndices(GLuint *dest, size_t count) +{ + for (size_t i = 0; i < count; i++) + { + dest[i] = static_cast(i); + } + dest[count] = 0; +} + +template +void CopyLineLoopIndices(const void *indices, GLuint *dest, size_t count) +{ + const T *srcPtr = static_cast(indices); + for (size_t i = 0; i < count; ++i) + { + dest[i] = static_cast(srcPtr[i]); + } + dest[count] = static_cast(srcPtr[0]); +} + +void SetTriangleFanIndices(GLuint *destPtr, size_t numTris) +{ + for (size_t i = 0; i < numTris; i++) + { + destPtr[i * 3 + 0] = 0; + destPtr[i * 3 + 1] = static_cast(i) + 1; + destPtr[i * 3 + 2] = static_cast(i) + 2; + } +} + +void GetLineLoopIndices(const void *indices, + gl::DrawElementsType indexType, + GLuint count, + bool usePrimitiveRestartFixedIndex, + std::vector *bufferOut) +{ + if (indexType != gl::DrawElementsType::InvalidEnum && usePrimitiveRestartFixedIndex) + { + size_t indexCount = GetLineLoopWithRestartIndexCount(indexType, count, + static_cast(indices)); + bufferOut->resize(indexCount); + switch (indexType) + { + case gl::DrawElementsType::UnsignedByte: + CopyLineLoopIndicesWithRestart( + count, static_cast(indices), + reinterpret_cast(bufferOut->data())); + break; + case gl::DrawElementsType::UnsignedShort: + CopyLineLoopIndicesWithRestart( + count, static_cast(indices), + reinterpret_cast(bufferOut->data())); + break; + case gl::DrawElementsType::UnsignedInt: + CopyLineLoopIndicesWithRestart( + count, static_cast(indices), + reinterpret_cast(bufferOut->data())); + break; + default: + UNREACHABLE(); + break; + } + return; + } + + // For non-primitive-restart draws, the index count is static. + bufferOut->resize(static_cast(count) + 1); + + switch (indexType) + { + // Non-indexed draw + case gl::DrawElementsType::InvalidEnum: + SetLineLoopIndices(&(*bufferOut)[0], count); + break; + case gl::DrawElementsType::UnsignedByte: + CopyLineLoopIndices(indices, &(*bufferOut)[0], count); + break; + case gl::DrawElementsType::UnsignedShort: + CopyLineLoopIndices(indices, &(*bufferOut)[0], count); + break; + case gl::DrawElementsType::UnsignedInt: + CopyLineLoopIndices(indices, &(*bufferOut)[0], count); + break; + default: + UNREACHABLE(); + break; + } +} + +template +void CopyTriangleFanIndices(const void *indices, GLuint *destPtr, size_t numTris) +{ + const T *srcPtr = static_cast(indices); + + for (size_t i = 0; i < numTris; i++) + { + destPtr[i * 3 + 0] = static_cast(srcPtr[0]); + destPtr[i * 3 + 1] = static_cast(srcPtr[i + 1]); + destPtr[i * 3 + 2] = static_cast(srcPtr[i + 2]); + } +} + +template +void CopyTriangleFanIndicesWithRestart(const void *indices, + GLuint indexCount, + gl::DrawElementsType indexType, + std::vector *bufferOut) +{ + GLuint restartIndex = gl::GetPrimitiveRestartIndex(indexType); + GLuint d3dRestartIndex = gl::GetPrimitiveRestartIndex(gl::DrawElementsType::UnsignedInt); + const T *srcPtr = static_cast(indices); + Optional vertexA; + Optional vertexB; + + bufferOut->clear(); + + for (size_t indexIdx = 0; indexIdx < indexCount; ++indexIdx) + { + GLuint value = static_cast(srcPtr[indexIdx]); + + if (value == restartIndex) + { + bufferOut->push_back(d3dRestartIndex); + vertexA.reset(); + vertexB.reset(); + } + else + { + if (!vertexA.valid()) + { + vertexA = value; + } + else if (!vertexB.valid()) + { + vertexB = value; + } + else + { + bufferOut->push_back(vertexA.value()); + bufferOut->push_back(vertexB.value()); + bufferOut->push_back(value); + vertexB = value; + } + } + } +} + +void GetTriFanIndices(const void *indices, + gl::DrawElementsType indexType, + GLuint count, + bool usePrimitiveRestartFixedIndex, + std::vector *bufferOut) +{ + if (indexType != gl::DrawElementsType::InvalidEnum && usePrimitiveRestartFixedIndex) + { + switch (indexType) + { + case gl::DrawElementsType::UnsignedByte: + CopyTriangleFanIndicesWithRestart(indices, count, indexType, bufferOut); + break; + case gl::DrawElementsType::UnsignedShort: + CopyTriangleFanIndicesWithRestart(indices, count, indexType, bufferOut); + break; + case gl::DrawElementsType::UnsignedInt: + CopyTriangleFanIndicesWithRestart(indices, count, indexType, bufferOut); + break; + default: + UNREACHABLE(); + break; + } + return; + } + + // For non-primitive-restart draws, the index count is static. + GLuint numTris = count - 2; + bufferOut->resize(numTris * 3); + + switch (indexType) + { + // Non-indexed draw + case gl::DrawElementsType::InvalidEnum: + SetTriangleFanIndices(&(*bufferOut)[0], numTris); + break; + case gl::DrawElementsType::UnsignedByte: + CopyTriangleFanIndices(indices, &(*bufferOut)[0], numTris); + break; + case gl::DrawElementsType::UnsignedShort: + CopyTriangleFanIndices(indices, &(*bufferOut)[0], numTris); + break; + case gl::DrawElementsType::UnsignedInt: + CopyTriangleFanIndices(indices, &(*bufferOut)[0], numTris); + break; + default: + UNREACHABLE(); + break; + } +} + +bool IsArrayRTV(ID3D11RenderTargetView *rtv) +{ + D3D11_RENDER_TARGET_VIEW_DESC desc; + rtv->GetDesc(&desc); + if (desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE1DARRAY && + desc.Texture1DArray.ArraySize > 1) + return true; + if (desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE2DARRAY && + desc.Texture2DArray.ArraySize > 1) + return true; + if (desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY && + desc.Texture2DMSArray.ArraySize > 1) + return true; + return false; +} + +GLsizei GetAdjustedInstanceCount(const ProgramD3D *program, GLsizei instanceCount) +{ + if (!program->getState().usesMultiview()) + { + return instanceCount; + } + if (instanceCount == 0) + { + return program->getState().getNumViews(); + } + return program->getState().getNumViews() * instanceCount; +} + +const uint32_t ScratchMemoryBufferLifetime = 1000; + +void PopulateFormatDeviceCaps(ID3D11Device *device, + DXGI_FORMAT format, + UINT *outSupport, + UINT *outMaxSamples) +{ + if (FAILED(device->CheckFormatSupport(format, outSupport))) + { + *outSupport = 0; + } + + *outMaxSamples = 0; + for (UINT sampleCount = 2; sampleCount <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; sampleCount *= 2) + { + UINT qualityCount = 0; + if (FAILED(device->CheckMultisampleQualityLevels(format, sampleCount, &qualityCount)) || + qualityCount == 0) + { + break; + } + + *outMaxSamples = sampleCount; + } +} + +angle::Result GetTextureD3DResourceFromStorageOrImage(const gl::Context *context, + TextureD3D *texture, + const gl::ImageIndex &index, + const TextureHelper11 **outResource, + UINT *outSubresource) +{ + // If the storage exists, use it. Otherwise, copy directly from the images to avoid + // allocating a new storage. + if (texture->hasStorage()) + { + TextureStorage *storage = nullptr; + ANGLE_TRY(texture->getNativeTexture(context, &storage)); + + TextureStorage11 *storage11 = GetAs(storage); + ANGLE_TRY(storage11->getResource(context, outResource)); + ANGLE_TRY(storage11->getSubresourceIndex(context, index, outSubresource)); + } + else + { + ImageD3D *image = texture->getImage(index); + Image11 *image11 = GetAs(image); + ANGLE_TRY(image11->getStagingTexture(context, outResource, outSubresource)); + } + + return angle::Result::Continue; +} + +} // anonymous namespace + +Renderer11DeviceCaps::Renderer11DeviceCaps() = default; + +Renderer11::Renderer11(egl::Display *display) + : RendererD3D(display), + mCreateDebugDevice(false), + mStateCache(), + mStateManager(this), + mLastHistogramUpdateTime( + ANGLEPlatformCurrent()->monotonicallyIncreasingTime(ANGLEPlatformCurrent())), + mDebug(nullptr), + mScratchMemoryBuffer(ScratchMemoryBufferLifetime) +{ + mLineLoopIB = nullptr; + mTriangleFanIB = nullptr; + + mBlit = nullptr; + mPixelTransfer = nullptr; + + mClear = nullptr; + + mTrim = nullptr; + + mRenderer11DeviceCaps.supportsClearView = false; + mRenderer11DeviceCaps.supportsConstantBufferOffsets = false; + mRenderer11DeviceCaps.supportsVpRtIndexWriteFromVertexShader = false; + mRenderer11DeviceCaps.supportsDXGI1_2 = false; + mRenderer11DeviceCaps.allowES3OnFL10_0 = false; + mRenderer11DeviceCaps.supportsTypedUAVLoadAdditionalFormats = false; + mRenderer11DeviceCaps.supportsRasterizerOrderViews = false; + mRenderer11DeviceCaps.B5G6R5support = 0; + mRenderer11DeviceCaps.B4G4R4A4support = 0; + mRenderer11DeviceCaps.B5G5R5A1support = 0; + + mD3d11Module = nullptr; + mD3d12Module = nullptr; + mDxgiModule = nullptr; + mDCompModule = nullptr; + mCreatedWithDeviceEXT = false; + + mDevice = nullptr; + mDevice1 = nullptr; + mDeviceContext = nullptr; + mDeviceContext1 = nullptr; + mDeviceContext3 = nullptr; + mDxgiAdapter = nullptr; + mDxgiFactory = nullptr; + + ZeroMemory(&mAdapterDescription, sizeof(mAdapterDescription)); + + const auto &attributes = mDisplay->getAttributeMap(); + + if (mDisplay->getPlatform() == EGL_PLATFORM_ANGLE_ANGLE) + { + EGLint requestedMajorVersion = static_cast( + attributes.get(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, EGL_DONT_CARE)); + EGLint requestedMinorVersion = static_cast( + attributes.get(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, EGL_DONT_CARE)); + + if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 11) + { + if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 1) + { + // This could potentially lead to failed context creation if done on a system + // without the platform update which installs DXGI 1.2. Currently, for Chrome users + // D3D11 contexts are only created if the platform update is available, so this + // should not cause any issues. + mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_11_1); + } + if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 0) + { + mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_11_0); + } + } + + if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 10) + { + if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 1) + { + mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_10_1); + } + if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 0) + { + mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_10_0); + } + } + + if (requestedMajorVersion == 9 && requestedMinorVersion == 3) + { + mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_3); + } + + EGLint requestedDeviceType = static_cast(attributes.get( + EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE)); + switch (requestedDeviceType) + { + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE: + mRequestedDriverType = D3D_DRIVER_TYPE_HARDWARE; + break; + + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE: + mRequestedDriverType = D3D_DRIVER_TYPE_WARP; + break; + + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE: + mRequestedDriverType = D3D_DRIVER_TYPE_REFERENCE; + break; + + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE: + mRequestedDriverType = D3D_DRIVER_TYPE_NULL; + break; + + default: + UNREACHABLE(); + } + + mCreateDebugDevice = ShouldUseDebugLayers(attributes); + } + else if (mDisplay->getPlatform() == EGL_PLATFORM_DEVICE_EXT) + { + ASSERT(mDisplay->getDevice() != nullptr); + mCreatedWithDeviceEXT = true; + + // Also set EGL_PLATFORM_ANGLE_ANGLE variables, in case they're used elsewhere in ANGLE + // mAvailableFeatureLevels defaults to empty + mRequestedDriverType = D3D_DRIVER_TYPE_UNKNOWN; + } + + const EGLenum presentPath = static_cast(attributes.get( + EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE, EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE)); + mPresentPathFastEnabled = (presentPath == EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE); +} + +Renderer11::~Renderer11() +{ + release(); +} + +#ifndef __d3d11_1_h__ +# define D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET ((D3D11_MESSAGE_ID)3146081) +#endif + +egl::Error Renderer11::initialize() +{ + HRESULT result = S_OK; + + ANGLE_TRY(initializeD3DDevice()); + +#if !defined(ANGLE_ENABLE_WINDOWS_UWP) +# if !ANGLE_SKIP_DXGI_1_2_CHECK + { + ANGLE_TRACE_EVENT0("gpu.angle", "Renderer11::initialize (DXGICheck)"); + // In order to create a swap chain for an HWND owned by another process, DXGI 1.2 is + // required. + // The easiest way to check is to query for a IDXGIDevice2. + bool requireDXGI1_2 = false; + HWND hwnd = WindowFromDC(mDisplay->getNativeDisplayId()); + if (hwnd) + { + DWORD currentProcessId = GetCurrentProcessId(); + DWORD wndProcessId; + GetWindowThreadProcessId(hwnd, &wndProcessId); + requireDXGI1_2 = (currentProcessId != wndProcessId); + } + else + { + requireDXGI1_2 = true; + } + + if (requireDXGI1_2) + { + IDXGIDevice2 *dxgiDevice2 = nullptr; + result = mDevice->QueryInterface(__uuidof(IDXGIDevice2), (void **)&dxgiDevice2); + if (FAILED(result)) + { + return egl::EglNotInitialized(D3D11_INIT_INCOMPATIBLE_DXGI) + << "DXGI 1.2 required to present to HWNDs owned by another process."; + } + SafeRelease(dxgiDevice2); + } + } +# endif +#endif + + { + ANGLE_TRACE_EVENT0("gpu.angle", "Renderer11::initialize (ComQueries)"); + // Cast the DeviceContext to a DeviceContext1 and DeviceContext3. + // This could fail on Windows 7 without the Platform Update. + // Don't error in this case- just don't use mDeviceContext1 or mDeviceContext3. + mDeviceContext1 = d3d11::DynamicCastComObject(mDeviceContext); + mDeviceContext3 = d3d11::DynamicCastComObject(mDeviceContext); + + IDXGIDevice *dxgiDevice = nullptr; + result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void **)&dxgiDevice); + + if (FAILED(result)) + { + return egl::EglNotInitialized(D3D11_INIT_OTHER_ERROR) << "Could not query DXGI device."; + } + + result = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void **)&mDxgiAdapter); + + if (FAILED(result)) + { + return egl::EglNotInitialized(D3D11_INIT_OTHER_ERROR) + << "Could not retrieve DXGI adapter"; + } + + SafeRelease(dxgiDevice); + + IDXGIAdapter2 *dxgiAdapter2 = d3d11::DynamicCastComObject(mDxgiAdapter); + + // On D3D_FEATURE_LEVEL_9_*, IDXGIAdapter::GetDesc returns "Software Adapter" for the + // description string. + // If DXGI1.2 is available then IDXGIAdapter2::GetDesc2 can be used to get the actual + // hardware values. + if (mRenderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3 && dxgiAdapter2 != nullptr) + { + DXGI_ADAPTER_DESC2 adapterDesc2 = {}; + result = dxgiAdapter2->GetDesc2(&adapterDesc2); + if (SUCCEEDED(result)) + { + // Copy the contents of the DXGI_ADAPTER_DESC2 into mAdapterDescription (a + // DXGI_ADAPTER_DESC). + memcpy(mAdapterDescription.Description, adapterDesc2.Description, + sizeof(mAdapterDescription.Description)); + mAdapterDescription.VendorId = adapterDesc2.VendorId; + mAdapterDescription.DeviceId = adapterDesc2.DeviceId; + mAdapterDescription.SubSysId = adapterDesc2.SubSysId; + mAdapterDescription.Revision = adapterDesc2.Revision; + mAdapterDescription.DedicatedVideoMemory = adapterDesc2.DedicatedVideoMemory; + mAdapterDescription.DedicatedSystemMemory = adapterDesc2.DedicatedSystemMemory; + mAdapterDescription.SharedSystemMemory = adapterDesc2.SharedSystemMemory; + mAdapterDescription.AdapterLuid = adapterDesc2.AdapterLuid; + } + } + else + { + result = mDxgiAdapter->GetDesc(&mAdapterDescription); + } + + SafeRelease(dxgiAdapter2); + + if (FAILED(result)) + { + return egl::EglNotInitialized(D3D11_INIT_OTHER_ERROR) + << "Could not read DXGI adaptor description."; + } + + memset(mDescription, 0, sizeof(mDescription)); + wcstombs(mDescription, mAdapterDescription.Description, sizeof(mDescription) - 1); + + result = mDxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void **)&mDxgiFactory); + + if (!mDxgiFactory || FAILED(result)) + { + return egl::EglNotInitialized(D3D11_INIT_OTHER_ERROR) + << "Could not create DXGI factory."; + } + } + + // Disable some spurious D3D11 debug warnings to prevent them from flooding the output log + if (mCreateDebugDevice) + { + ANGLE_TRACE_EVENT0("gpu.angle", "Renderer11::initialize (HideWarnings)"); + ID3D11InfoQueue *infoQueue; + result = mDevice->QueryInterface(__uuidof(ID3D11InfoQueue), (void **)&infoQueue); + + if (SUCCEEDED(result)) + { + D3D11_MESSAGE_ID hideMessages[] = { + D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET, + + // Robust access behaviour makes out of bounds messages safe + D3D11_MESSAGE_ID_DEVICE_DRAW_VERTEX_BUFFER_TOO_SMALL, + }; + + D3D11_INFO_QUEUE_FILTER filter = {}; + filter.DenyList.NumIDs = static_cast(ArraySize(hideMessages)); + filter.DenyList.pIDList = hideMessages; + + infoQueue->AddStorageFilterEntries(&filter); + SafeRelease(infoQueue); + } + } + +#if !defined(NDEBUG) + mDebug = d3d11::DynamicCastComObject(mDevice); +#endif + + ANGLE_TRY(initializeDevice()); + + return egl::NoError(); +} + +HRESULT Renderer11::callD3D11CreateDevice(PFN_D3D11_CREATE_DEVICE createDevice, bool debug) +{ + angle::ComPtr adapter; + + const egl::AttributeMap &attributes = mDisplay->getAttributeMap(); + // Check EGL_ANGLE_platform_angle_d3d_luid + long high = static_cast(attributes.get(EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE, 0)); + unsigned long low = + static_cast(attributes.get(EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE, 0)); + // Check EGL_ANGLE_platform_angle_device_id + if (high == 0 && low == 0) + { + high = static_cast(attributes.get(EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE, 0)); + low = static_cast(attributes.get(EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE, 0)); + } + if (high != 0 || low != 0) + { + angle::ComPtr factory; + if (SUCCEEDED(CreateDXGIFactory1(IID_PPV_ARGS(&factory)))) + { + angle::ComPtr temp; + for (UINT i = 0; SUCCEEDED(factory->EnumAdapters(i, &temp)); i++) + { + DXGI_ADAPTER_DESC desc; + if (SUCCEEDED(temp->GetDesc(&desc))) + { + // EGL_ANGLE_platform_angle_d3d_luid + if (desc.AdapterLuid.HighPart == high && desc.AdapterLuid.LowPart == low) + { + adapter = temp; + break; + } + + // EGL_ANGLE_platform_angle_device_id + // NOTE: If there are multiple GPUs with the same PCI + // vendor and device IDs, this will arbitrarily choose one + // of them. To select a specific GPU, use the LUID instead. + if ((high == 0 || desc.VendorId == static_cast(high)) && + (low == 0 || desc.DeviceId == static_cast(low))) + { + adapter = temp; + break; + } + } + } + } + } + + // If adapter is not nullptr, the driver type must be D3D_DRIVER_TYPE_UNKNOWN or + // D3D11CreateDevice will return E_INVALIDARG. + return createDevice( + adapter.Get(), adapter ? D3D_DRIVER_TYPE_UNKNOWN : mRequestedDriverType, nullptr, + debug ? D3D11_CREATE_DEVICE_DEBUG : 0, mAvailableFeatureLevels.data(), + static_cast(mAvailableFeatureLevels.size()), D3D11_SDK_VERSION, &mDevice, + &(mRenderer11DeviceCaps.featureLevel), &mDeviceContext); +} + +HRESULT Renderer11::callD3D11On12CreateDevice(PFN_D3D12_CREATE_DEVICE createDevice12, + PFN_D3D11ON12_CREATE_DEVICE createDevice11on12, + bool debug) +{ + angle::ComPtr factory; + HRESULT result = CreateDXGIFactory1(IID_PPV_ARGS(&factory)); + if (FAILED(result)) + { + return result; + } + + if (mRequestedDriverType == D3D_DRIVER_TYPE_WARP) + { + angle::ComPtr warpAdapter; + result = factory->EnumWarpAdapter(IID_PPV_ARGS(&warpAdapter)); + if (SUCCEEDED(result)) + { + result = createDevice12(warpAdapter.Get(), mAvailableFeatureLevels[0], + IID_PPV_ARGS(&mDevice12)); + } + } + else + { + // Passing nullptr into pAdapter chooses the default adapter which will be the hardware + // adapter if it exists. + result = createDevice12(nullptr, mAvailableFeatureLevels[0], IID_PPV_ARGS(&mDevice12)); + } + + if (SUCCEEDED(result)) + { + D3D12_COMMAND_QUEUE_DESC queueDesc = {}; + queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; + queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; + result = mDevice12->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&mCommandQueue)); + } + + if (SUCCEEDED(result)) + { + result = createDevice11on12( + mDevice12.Get(), debug ? D3D11_CREATE_DEVICE_DEBUG : 0, mAvailableFeatureLevels.data(), + static_cast(mAvailableFeatureLevels.size()), + reinterpret_cast(mCommandQueue.GetAddressOf()), 1 /* NumQueues */, + 0 /* NodeMask */, &mDevice, &mDeviceContext, &(mRenderer11DeviceCaps.featureLevel)); + } + + return result; +} + +egl::Error Renderer11::initializeD3DDevice() +{ + HRESULT result = S_OK; + bool createD3D11on12Device = false; + + if (!mCreatedWithDeviceEXT) + { +#if !defined(ANGLE_ENABLE_WINDOWS_UWP) + PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = nullptr; + PFN_D3D12_CREATE_DEVICE D3D12CreateDevice = nullptr; + PFN_D3D11ON12_CREATE_DEVICE D3D11On12CreateDevice = nullptr; + { + ANGLE_TRACE_EVENT0("gpu.angle", "Renderer11::initialize (Load DLLs)"); + mDxgiModule = LoadLibrary(TEXT("dxgi.dll")); + mD3d11Module = LoadLibrary(TEXT("d3d11.dll")); + mDCompModule = LoadLibrary(TEXT("dcomp.dll")); + + // create the D3D11 device + ASSERT(mDevice == nullptr); + + const egl::AttributeMap &attributes = mDisplay->getAttributeMap(); + createD3D11on12Device = + attributes.get(EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE, EGL_FALSE) == EGL_TRUE; + + if (createD3D11on12Device) + { + mD3d12Module = LoadLibrary(TEXT("d3d12.dll")); + if (mD3d12Module == nullptr) + { + return egl::EglNotInitialized(D3D11_INIT_MISSING_DEP) + << "Could not load D3D12 library."; + } + + D3D12CreateDevice = reinterpret_cast( + GetProcAddress(mD3d12Module, "D3D12CreateDevice")); + if (D3D12CreateDevice == nullptr) + { + return egl::EglNotInitialized(D3D11_INIT_MISSING_DEP) + << "Could not retrieve D3D12CreateDevice address."; + } + + D3D11On12CreateDevice = reinterpret_cast( + GetProcAddress(mD3d11Module, "D3D11On12CreateDevice")); + if (D3D11On12CreateDevice == nullptr) + { + return egl::EglNotInitialized(D3D11_INIT_MISSING_DEP) + << "Could not retrieve D3D11On12CreateDevice address."; + } + } + else + { + if (mD3d11Module == nullptr || mDxgiModule == nullptr) + { + return egl::EglNotInitialized(D3D11_INIT_MISSING_DEP) + << "Could not load D3D11 or DXGI library."; + } + + D3D11CreateDevice = reinterpret_cast( + GetProcAddress(mD3d11Module, "D3D11CreateDevice")); + + if (D3D11CreateDevice == nullptr) + { + return egl::EglNotInitialized(D3D11_INIT_MISSING_DEP) + << "Could not retrieve D3D11CreateDevice address."; + } + } + } +#endif + + if (mCreateDebugDevice) + { + ANGLE_TRACE_EVENT0("gpu.angle", "D3D11CreateDevice (Debug)"); + if (createD3D11on12Device) + { + result = callD3D11On12CreateDevice(D3D12CreateDevice, D3D11On12CreateDevice, true); + } + else + { + result = callD3D11CreateDevice(D3D11CreateDevice, true); + } + + if (result == E_INVALIDARG && mAvailableFeatureLevels.size() > 1u && + mAvailableFeatureLevels[0] == D3D_FEATURE_LEVEL_11_1) + { + // On older Windows platforms, D3D11.1 is not supported which returns E_INVALIDARG. + // Try again without passing D3D_FEATURE_LEVEL_11_1 in case we have other feature + // levels to fall back on. + mAvailableFeatureLevels.erase(mAvailableFeatureLevels.begin()); + if (createD3D11on12Device) + { + result = + callD3D11On12CreateDevice(D3D12CreateDevice, D3D11On12CreateDevice, true); + } + else + { + result = callD3D11CreateDevice(D3D11CreateDevice, true); + } + } + + if (!mDevice || FAILED(result)) + { + WARN() << "Failed creating Debug D3D11 device - falling back to release runtime."; + } + } + + if (!mDevice || FAILED(result)) + { + ANGLE_TRACE_EVENT0("gpu.angle", "D3D11CreateDevice"); + if (createD3D11on12Device) + { + result = callD3D11On12CreateDevice(D3D12CreateDevice, D3D11On12CreateDevice, false); + } + else + { + result = callD3D11CreateDevice(D3D11CreateDevice, false); + } + + if (result == E_INVALIDARG && mAvailableFeatureLevels.size() > 1u && + mAvailableFeatureLevels[0] == D3D_FEATURE_LEVEL_11_1) + { + // On older Windows platforms, D3D11.1 is not supported which returns E_INVALIDARG. + // Try again without passing D3D_FEATURE_LEVEL_11_1 in case we have other feature + // levels to fall back on. + mAvailableFeatureLevels.erase(mAvailableFeatureLevels.begin()); + if (createD3D11on12Device) + { + result = + callD3D11On12CreateDevice(D3D12CreateDevice, D3D11On12CreateDevice, false); + } + else + { + result = callD3D11CreateDevice(D3D11CreateDevice, false); + } + } + + // Cleanup done by destructor + if (!mDevice || FAILED(result)) + { + ANGLE_HISTOGRAM_SPARSE_SLOWLY("GPU.ANGLE.D3D11CreateDeviceError", + static_cast(result)); + return egl::EglNotInitialized(D3D11_INIT_CREATEDEVICE_ERROR) + << "Could not create D3D11 device."; + } + } + } + else + { + DeviceD3D *deviceD3D = GetImplAs(mDisplay->getDevice()); + ASSERT(deviceD3D != nullptr); + + // We should use the inputted D3D11 device instead + void *device = nullptr; + ANGLE_TRY(deviceD3D->getAttribute(mDisplay, EGL_D3D11_DEVICE_ANGLE, &device)); + + ID3D11Device *d3dDevice = static_cast(device); + if (FAILED(d3dDevice->GetDeviceRemovedReason())) + { + return egl::EglNotInitialized() << "Inputted D3D11 device has been lost."; + } + + if (d3dDevice->GetFeatureLevel() < D3D_FEATURE_LEVEL_9_3) + { + return egl::EglNotInitialized() + << "Inputted D3D11 device must be Feature Level 9_3 or greater."; + } + + // The Renderer11 adds a ref to the inputted D3D11 device, like D3D11CreateDevice does. + mDevice = d3dDevice; + mDevice->AddRef(); + mDevice->GetImmediateContext(&mDeviceContext); + mRenderer11DeviceCaps.featureLevel = mDevice->GetFeatureLevel(); + } + + mResourceManager11.setAllocationsInitialized(mCreateDebugDevice); + + d3d11::SetDebugName(mDeviceContext, "DeviceContext", nullptr); + + mAnnotatorContext.initialize(mDeviceContext); + + mDevice->QueryInterface(__uuidof(ID3D11Device1), reinterpret_cast(&mDevice1)); + + return egl::NoError(); +} + +void Renderer11::setGlobalDebugAnnotator() +{ + static angle::base::NoDestructor gMutex; + static angle::base::NoDestructor gGlobalAnnotator; + + std::lock_guard lg(*gMutex); + gl::InitializeDebugAnnotations(gGlobalAnnotator.get()); +} + +// do any one-time device initialization +// NOTE: this is also needed after a device lost/reset +// to reset the scene status and ensure the default states are reset. +egl::Error Renderer11::initializeDevice() +{ + ANGLE_TRACE_EVENT0("gpu.angle", "Renderer11::initializeDevice"); + + populateRenderer11DeviceCaps(); + + mStateCache.clear(); + + ASSERT(!mBlit); + mBlit = new Blit11(this); + + ASSERT(!mClear); + mClear = new Clear11(this); + + const auto &attributes = mDisplay->getAttributeMap(); + // If automatic trim is enabled, DXGIDevice3::Trim( ) is called for the application + // automatically when an application is suspended by the OS. This feature is currently + // only supported for Windows Store applications. + EGLint enableAutoTrim = static_cast( + attributes.get(EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_FALSE)); + + if (enableAutoTrim == EGL_TRUE) + { + ASSERT(!mTrim); + mTrim = new Trim11(this); + } + + ASSERT(!mPixelTransfer); + mPixelTransfer = new PixelTransfer11(this); + + // Gather stats on DXGI and D3D feature level + ANGLE_HISTOGRAM_BOOLEAN("GPU.ANGLE.SupportsDXGI1_2", mRenderer11DeviceCaps.supportsDXGI1_2); + + ANGLEFeatureLevel angleFeatureLevel = GetANGLEFeatureLevel(mRenderer11DeviceCaps.featureLevel); + + // We don't actually request a 11_1 device, because of complications with the platform + // update. Instead we check if the mDeviceContext1 pointer cast succeeded. + // Note: we should support D3D11_0 always, but we aren't guaranteed to be at FL11_0 + // because the app can specify a lower version (such as 9_3) on Display creation. + if (mDeviceContext1 != nullptr) + { + angleFeatureLevel = ANGLE_FEATURE_LEVEL_11_1; + } + + ANGLE_HISTOGRAM_ENUMERATION("GPU.ANGLE.D3D11FeatureLevel", angleFeatureLevel, + NUM_ANGLE_FEATURE_LEVELS); + + return egl::NoError(); +} + +void Renderer11::populateRenderer11DeviceCaps() +{ + HRESULT hr = S_OK; + + LARGE_INTEGER version; + hr = mDxgiAdapter->CheckInterfaceSupport(__uuidof(IDXGIDevice), &version); + if (FAILED(hr)) + { + mRenderer11DeviceCaps.driverVersion.reset(); + ERR() << "Error querying driver version from DXGI Adapter."; + } + else + { + mRenderer11DeviceCaps.driverVersion = version; + } + + if (mDeviceContext1) + { + D3D11_FEATURE_DATA_D3D11_OPTIONS d3d11Options; + HRESULT result = mDevice->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &d3d11Options, + sizeof(D3D11_FEATURE_DATA_D3D11_OPTIONS)); + if (SUCCEEDED(result)) + { + mRenderer11DeviceCaps.supportsClearView = (d3d11Options.ClearView != FALSE); + mRenderer11DeviceCaps.supportsConstantBufferOffsets = + (d3d11Options.ConstantBufferOffsetting != FALSE); + } + } + + if (mDeviceContext3) + { + D3D11_FEATURE_DATA_D3D11_OPTIONS3 d3d11Options3; + HRESULT result = mDevice->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS3, &d3d11Options3, + sizeof(D3D11_FEATURE_DATA_D3D11_OPTIONS3)); + if (SUCCEEDED(result)) + { + mRenderer11DeviceCaps.supportsVpRtIndexWriteFromVertexShader = + (d3d11Options3.VPAndRTArrayIndexFromAnyShaderFeedingRasterizer == TRUE); + } + D3D11_FEATURE_DATA_D3D11_OPTIONS2 d3d11Options2; + result = mDevice->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS2, &d3d11Options2, + sizeof(D3D11_FEATURE_DATA_D3D11_OPTIONS2)); + if (SUCCEEDED(result)) + { + mRenderer11DeviceCaps.supportsTypedUAVLoadAdditionalFormats = + d3d11Options2.TypedUAVLoadAdditionalFormats; + if (!getFeatures().disableRasterizerOrderViews.enabled) + { + mRenderer11DeviceCaps.supportsRasterizerOrderViews = d3d11Options2.ROVsSupported; + } + } + } + + mRenderer11DeviceCaps.supportsMultisampledDepthStencilSRVs = + mRenderer11DeviceCaps.featureLevel > D3D_FEATURE_LEVEL_10_0; + + if (getFeatures().disableB5G6R5Support.enabled) + { + mRenderer11DeviceCaps.B5G6R5support = 0; + mRenderer11DeviceCaps.B5G6R5maxSamples = 0; + } + else + { + PopulateFormatDeviceCaps(mDevice, DXGI_FORMAT_B5G6R5_UNORM, + &mRenderer11DeviceCaps.B5G6R5support, + &mRenderer11DeviceCaps.B5G6R5maxSamples); + } + + if (getFeatures().allowES3OnFL100.enabled) + { + mRenderer11DeviceCaps.allowES3OnFL10_0 = true; + } + + PopulateFormatDeviceCaps(mDevice, DXGI_FORMAT_B4G4R4A4_UNORM, + &mRenderer11DeviceCaps.B4G4R4A4support, + &mRenderer11DeviceCaps.B4G4R4A4maxSamples); + PopulateFormatDeviceCaps(mDevice, DXGI_FORMAT_B5G5R5A1_UNORM, + &mRenderer11DeviceCaps.B5G5R5A1support, + &mRenderer11DeviceCaps.B5G5R5A1maxSamples); + + IDXGIAdapter2 *dxgiAdapter2 = d3d11::DynamicCastComObject(mDxgiAdapter); + mRenderer11DeviceCaps.supportsDXGI1_2 = (dxgiAdapter2 != nullptr); + SafeRelease(dxgiAdapter2); +} + +gl::SupportedSampleSet Renderer11::generateSampleSetForEGLConfig( + const gl::TextureCaps &colorBufferFormatCaps, + const gl::TextureCaps &depthStencilBufferFormatCaps) const +{ + gl::SupportedSampleSet sampleCounts; + + // Generate a new set from the set intersection of sample counts between the color and depth + // format caps. + std::set_intersection(colorBufferFormatCaps.sampleCounts.begin(), + colorBufferFormatCaps.sampleCounts.end(), + depthStencilBufferFormatCaps.sampleCounts.begin(), + depthStencilBufferFormatCaps.sampleCounts.end(), + std::inserter(sampleCounts, sampleCounts.begin())); + + // Format of GL_NONE results in no supported sample counts. + // Add back the color sample counts to the supported sample set. + if (depthStencilBufferFormatCaps.sampleCounts.empty()) + { + sampleCounts = colorBufferFormatCaps.sampleCounts; + } + else if (colorBufferFormatCaps.sampleCounts.empty()) + { + // Likewise, add back the depth sample counts to the supported sample set. + sampleCounts = depthStencilBufferFormatCaps.sampleCounts; + } + + // Always support 0 samples + sampleCounts.insert(0); + + return sampleCounts; +} + +egl::ConfigSet Renderer11::generateConfigs() +{ + std::vector colorBufferFormats; + + // 32-bit supported formats + colorBufferFormats.push_back(GL_BGRA8_EXT); + colorBufferFormats.push_back(GL_RGBA8_OES); + + // 24-bit supported formats + colorBufferFormats.push_back(GL_RGB8_OES); + + if (mRenderer11DeviceCaps.featureLevel >= D3D_FEATURE_LEVEL_10_0) + { + // Additional high bit depth formats added in D3D 10.0 + // https://msdn.microsoft.com/en-us/library/windows/desktop/bb173064.aspx + colorBufferFormats.push_back(GL_RGBA16F); + colorBufferFormats.push_back(GL_RGB10_A2); + } + + if (!mPresentPathFastEnabled) + { + // 16-bit supported formats + // These aren't valid D3D11 swapchain formats, so don't expose them as configs + // if present path fast is active + colorBufferFormats.push_back(GL_RGBA4); + colorBufferFormats.push_back(GL_RGB5_A1); + colorBufferFormats.push_back(GL_RGB565); + } + + static const GLenum depthStencilBufferFormats[] = { + GL_NONE, GL_DEPTH24_STENCIL8_OES, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT16, + GL_STENCIL_INDEX8, + }; + + const gl::Caps &rendererCaps = getNativeCaps(); + const gl::TextureCapsMap &rendererTextureCaps = getNativeTextureCaps(); + + const EGLint optimalSurfaceOrientation = + mPresentPathFastEnabled ? 0 : EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE; + + egl::ConfigSet configs; + for (GLenum colorBufferInternalFormat : colorBufferFormats) + { + const gl::TextureCaps &colorBufferFormatCaps = + rendererTextureCaps.get(colorBufferInternalFormat); + if (!colorBufferFormatCaps.renderbuffer) + { + ASSERT(!colorBufferFormatCaps.textureAttachment); + continue; + } + + for (GLenum depthStencilBufferInternalFormat : depthStencilBufferFormats) + { + const gl::TextureCaps &depthStencilBufferFormatCaps = + rendererTextureCaps.get(depthStencilBufferInternalFormat); + if (!depthStencilBufferFormatCaps.renderbuffer && + depthStencilBufferInternalFormat != GL_NONE) + { + ASSERT(!depthStencilBufferFormatCaps.textureAttachment); + continue; + } + + const gl::InternalFormat &colorBufferFormatInfo = + gl::GetSizedInternalFormatInfo(colorBufferInternalFormat); + const gl::InternalFormat &depthStencilBufferFormatInfo = + gl::GetSizedInternalFormatInfo(depthStencilBufferInternalFormat); + const gl::Version &maxVersion = getMaxSupportedESVersion(); + + const gl::SupportedSampleSet sampleCounts = + generateSampleSetForEGLConfig(colorBufferFormatCaps, depthStencilBufferFormatCaps); + + for (GLuint sampleCount : sampleCounts) + { + egl::Config config; + config.renderTargetFormat = colorBufferInternalFormat; + config.depthStencilFormat = depthStencilBufferInternalFormat; + config.bufferSize = colorBufferFormatInfo.pixelBytes * 8; + config.redSize = colorBufferFormatInfo.redBits; + config.greenSize = colorBufferFormatInfo.greenBits; + config.blueSize = colorBufferFormatInfo.blueBits; + config.luminanceSize = colorBufferFormatInfo.luminanceBits; + config.alphaSize = colorBufferFormatInfo.alphaBits; + config.alphaMaskSize = 0; + config.bindToTextureRGB = + ((colorBufferFormatInfo.format == GL_RGB) && (sampleCount <= 1)); + config.bindToTextureRGBA = (((colorBufferFormatInfo.format == GL_RGBA) || + (colorBufferFormatInfo.format == GL_BGRA_EXT)) && + (sampleCount <= 1)); + config.colorBufferType = EGL_RGB_BUFFER; + config.configCaveat = EGL_NONE; + config.configID = static_cast(configs.size() + 1); + + // PresentPathFast may not be conformant + config.conformant = 0; + if (!mPresentPathFastEnabled) + { + // Can only support a conformant ES2 with feature level greater than 10.0. + if (mRenderer11DeviceCaps.featureLevel >= D3D_FEATURE_LEVEL_10_0) + { + config.conformant |= EGL_OPENGL_ES2_BIT; + } + + // We can only support conformant ES3 on FL 10.1+ + if (maxVersion.major >= 3) + { + config.conformant |= EGL_OPENGL_ES3_BIT_KHR; + } + } + + config.depthSize = depthStencilBufferFormatInfo.depthBits; + config.level = 0; + config.matchNativePixmap = EGL_NONE; + config.maxPBufferWidth = rendererCaps.max2DTextureSize; + config.maxPBufferHeight = rendererCaps.max2DTextureSize; + config.maxPBufferPixels = + rendererCaps.max2DTextureSize * rendererCaps.max2DTextureSize; + config.maxSwapInterval = 4; + config.minSwapInterval = 0; + config.nativeRenderable = EGL_FALSE; + config.nativeVisualID = 0; + config.nativeVisualType = EGL_NONE; + + // Can't support ES3 at all without feature level 10.1 + config.renderableType = EGL_OPENGL_ES2_BIT; + if (maxVersion.major >= 3) + { + config.renderableType |= EGL_OPENGL_ES3_BIT_KHR; + } + + config.sampleBuffers = (sampleCount == 0) ? 0 : 1; + config.samples = sampleCount; + config.stencilSize = depthStencilBufferFormatInfo.stencilBits; + config.surfaceType = + EGL_PBUFFER_BIT | EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT; + config.transparentType = EGL_NONE; + config.transparentRedValue = 0; + config.transparentGreenValue = 0; + config.transparentBlueValue = 0; + config.optimalOrientation = optimalSurfaceOrientation; + config.colorComponentType = gl_egl::GLComponentTypeToEGLColorComponentType( + colorBufferFormatInfo.componentType); + + configs.add(config); + } + } + } + + ASSERT(configs.size() > 0); + return configs; +} + +void Renderer11::generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const +{ + outExtensions->createContextRobustness = true; + + if (getShareHandleSupport()) + { + outExtensions->d3dShareHandleClientBuffer = true; + outExtensions->surfaceD3DTexture2DShareHandle = true; + } + outExtensions->d3dTextureClientBuffer = true; + outExtensions->imageD3D11Texture = true; + + outExtensions->keyedMutex = true; + outExtensions->querySurfacePointer = true; + outExtensions->windowFixedSize = true; + + // If present path fast is active then the surface orientation extension isn't supported + outExtensions->surfaceOrientation = !mPresentPathFastEnabled; + + // D3D11 does not support present with dirty rectangles until DXGI 1.2. + outExtensions->postSubBuffer = mRenderer11DeviceCaps.supportsDXGI1_2; + + outExtensions->image = true; + outExtensions->imageBase = true; + outExtensions->glTexture2DImage = true; + outExtensions->glTextureCubemapImage = true; + outExtensions->glRenderbufferImage = true; + + outExtensions->stream = true; + outExtensions->streamConsumerGLTexture = true; + outExtensions->streamConsumerGLTextureYUV = true; + outExtensions->streamProducerD3DTexture = true; + + outExtensions->noConfigContext = true; + outExtensions->directComposition = !!mDCompModule; + + // Contexts are virtualized so textures and semaphores can be shared globally + outExtensions->displayTextureShareGroup = true; + outExtensions->displaySemaphoreShareGroup = true; + + // syncControlCHROMIUM requires direct composition. + outExtensions->syncControlCHROMIUM = outExtensions->directComposition; + + // D3D11 can be used without a swap chain + outExtensions->surfacelessContext = true; + + // All D3D feature levels support robust resource init + outExtensions->robustResourceInitializationANGLE = true; + +#ifdef ANGLE_ENABLE_D3D11_COMPOSITOR_NATIVE_WINDOW + // Compositor Native Window capabilies require WinVer >= 1803 + if (CompositorNativeWindow11::IsSupportedWinRelease()) + { + outExtensions->windowsUIComposition = true; + } +#endif +} + +angle::Result Renderer11::flush(Context11 *context11) +{ + mDeviceContext->Flush(); + return angle::Result::Continue; +} + +angle::Result Renderer11::finish(Context11 *context11) +{ + if (!mSyncQuery.valid()) + { + D3D11_QUERY_DESC queryDesc; + queryDesc.Query = D3D11_QUERY_EVENT; + queryDesc.MiscFlags = 0; + + ANGLE_TRY(allocateResource(context11, queryDesc, &mSyncQuery)); + } + + mDeviceContext->End(mSyncQuery.get()); + + HRESULT result = S_OK; + unsigned int attempt = 0; + do + { + unsigned int flushFrequency = 100; + UINT flags = (attempt % flushFrequency == 0) ? 0 : D3D11_ASYNC_GETDATA_DONOTFLUSH; + attempt++; + + result = mDeviceContext->GetData(mSyncQuery.get(), nullptr, 0, flags); + ANGLE_TRY_HR(context11, result, "Failed to get event query data"); + + if (result == S_FALSE) + { + // Keep polling, but allow other threads to do something useful first + ScheduleYield(); + } + + // Attempt is incremented before checking if we should test for device loss so that device + // loss is not checked on the first iteration + bool checkDeviceLost = (attempt % kPollingD3DDeviceLostCheckFrequency) == 0; + if (checkDeviceLost && testDeviceLost()) + { + mDisplay->notifyDeviceLost(); + ANGLE_CHECK(context11, false, "Device was lost while waiting for sync.", + GL_OUT_OF_MEMORY); + } + } while (result == S_FALSE); + + return angle::Result::Continue; +} + +bool Renderer11::isValidNativeWindow(EGLNativeWindowType window) const +{ +#if defined(ANGLE_ENABLE_WINDOWS_UWP) + if (NativeWindow11WinRT::IsValidNativeWindow(window)) + { + return true; + } +#else + if (NativeWindow11Win32::IsValidNativeWindow(window)) + { + return true; + } +#endif + +#ifdef ANGLE_ENABLE_D3D11_COMPOSITOR_NATIVE_WINDOW + static_assert(sizeof(ABI::Windows::UI::Composition::SpriteVisual *) == sizeof(HWND), + "Pointer size must match Window Handle size"); + if (CompositorNativeWindow11::IsValidNativeWindow(window)) + { + return true; + } +#endif + + return false; +} + +NativeWindowD3D *Renderer11::createNativeWindow(EGLNativeWindowType window, + const egl::Config *config, + const egl::AttributeMap &attribs) const +{ +#if defined(ANGLE_ENABLE_WINDOWS_UWP) + if (window == nullptr || NativeWindow11WinRT::IsValidNativeWindow(window)) + { + return new NativeWindow11WinRT(window, config->alphaSize > 0); + } +#else + if (window == nullptr || NativeWindow11Win32::IsValidNativeWindow(window)) + { + return new NativeWindow11Win32( + window, config->alphaSize > 0, + attribs.get(EGL_DIRECT_COMPOSITION_ANGLE, EGL_FALSE) == EGL_TRUE); + } +#endif + +#ifdef ANGLE_ENABLE_D3D11_COMPOSITOR_NATIVE_WINDOW + if (CompositorNativeWindow11::IsValidNativeWindow(window)) + { + return new CompositorNativeWindow11(window, config->alphaSize > 0); + } +#endif + + UNREACHABLE(); + return nullptr; +} + +egl::Error Renderer11::getD3DTextureInfo(const egl::Config *configuration, + IUnknown *texture, + const egl::AttributeMap &attribs, + EGLint *width, + EGLint *height, + GLsizei *samples, + gl::Format *glFormat, + const angle::Format **angleFormat, + UINT *arraySlice) const +{ + angle::ComPtr d3dTexture = + d3d11::DynamicCastComObjectToComPtr(texture); + if (d3dTexture == nullptr) + { + return egl::EglBadParameter() << "client buffer is not a ID3D11Texture2D"; + } + + angle::ComPtr textureDevice; + d3dTexture->GetDevice(&textureDevice); + if (textureDevice.Get() != mDevice) + { + return egl::EglBadParameter() << "Texture's device does not match."; + } + + D3D11_TEXTURE2D_DESC desc = {}; + d3dTexture->GetDesc(&desc); + + EGLint imageWidth = static_cast(desc.Width); + EGLint imageHeight = static_cast(desc.Height); + + GLsizei sampleCount = static_cast(desc.SampleDesc.Count); + if (configuration && (configuration->samples != sampleCount)) + { + // Both the texture and EGL config sample count may not be the same when multi-sampling + // is disabled. The EGL sample count can be 0 but a D3D texture is always 1. Therefore, + // we must only check for a invalid match when the EGL config is non-zero or the texture is + // not one. + if (configuration->samples != 0 || sampleCount != 1) + { + return egl::EglBadParameter() << "Texture's sample count does not match."; + } + } + + const angle::Format *textureAngleFormat = nullptr; + GLenum sizedInternalFormat = GL_NONE; + + // From table egl.restrictions in EGL_ANGLE_d3d_texture_client_buffer. + if (desc.Format == DXGI_FORMAT_NV12 || desc.Format == DXGI_FORMAT_P010 || + desc.Format == DXGI_FORMAT_P016) + { + if (!attribs.contains(EGL_D3D11_TEXTURE_PLANE_ANGLE)) + { + return egl::EglBadParameter() + << "EGL_D3D11_TEXTURE_PLANE_ANGLE must be specified for YUV textures."; + } + + EGLint plane = attribs.getAsInt(EGL_D3D11_TEXTURE_PLANE_ANGLE); + + // P010 and P016 have the same memory layout, SRV/RTV format, etc. + const bool isNV12 = (desc.Format == DXGI_FORMAT_NV12); + if (plane == 0) + { + textureAngleFormat = isNV12 ? &angle::Format::Get(angle::FormatID::R8_UNORM) + : &angle::Format::Get(angle::FormatID::R16_UNORM); + } + else if (plane == 1) + { + textureAngleFormat = isNV12 ? &angle::Format::Get(angle::FormatID::R8G8_UNORM) + : &angle::Format::Get(angle::FormatID::R16G16_UNORM); + imageWidth /= 2; + imageHeight /= 2; + } + else + { + return egl::EglBadParameter() << "Invalid client buffer texture plane: " << plane; + } + + ASSERT(textureAngleFormat); + sizedInternalFormat = textureAngleFormat->glInternalFormat; + } + else + { + switch (desc.Format) + { + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_B8G8R8A8_UNORM: + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + case DXGI_FORMAT_R16G16B16A16_FLOAT: + case DXGI_FORMAT_R32G32B32A32_FLOAT: + case DXGI_FORMAT_R10G10B10A2_UNORM: + case DXGI_FORMAT_R8_UNORM: + case DXGI_FORMAT_R8G8_UNORM: + case DXGI_FORMAT_R16_UNORM: + case DXGI_FORMAT_R16G16_UNORM: + break; + + default: + return egl::EglBadParameter() + << "Invalid client buffer texture format: " << desc.Format; + } + + textureAngleFormat = &d3d11_angle::GetFormat(desc.Format); + ASSERT(textureAngleFormat); + + sizedInternalFormat = textureAngleFormat->glInternalFormat; + + if (attribs.contains(EGL_TEXTURE_INTERNAL_FORMAT_ANGLE)) + { + const GLenum internalFormat = + static_cast(attribs.get(EGL_TEXTURE_INTERNAL_FORMAT_ANGLE)); + switch (internalFormat) + { + case GL_RGBA: + case GL_BGRA_EXT: + case GL_RGB: + case GL_RED_EXT: + case GL_RG_EXT: + case GL_RGB10_A2_EXT: + case GL_R16_EXT: + case GL_RG16_EXT: + break; + default: + return egl::EglBadParameter() + << "Invalid client buffer texture internal format: " << std::hex + << internalFormat; + } + + const GLenum type = gl::GetSizedInternalFormatInfo(sizedInternalFormat).type; + + const auto format = gl::Format(internalFormat, type); + if (!format.valid()) + { + return egl::EglBadParameter() + << "Invalid client buffer texture internal format: " << std::hex + << internalFormat; + } + + sizedInternalFormat = format.info->sizedInternalFormat; + } + } + + UINT textureArraySlice = + static_cast(attribs.getAsInt(EGL_D3D11_TEXTURE_ARRAY_SLICE_ANGLE, 0)); + if (textureArraySlice >= desc.ArraySize) + { + return egl::EglBadParameter() + << "Invalid client buffer texture array slice: " << textureArraySlice; + } + + if (width) + { + *width = imageWidth; + } + if (height) + { + *height = imageHeight; + } + + if (samples) + { + // EGL samples 0 corresponds to D3D11 sample count 1. + *samples = sampleCount != 1 ? sampleCount : 0; + } + + if (glFormat) + { + *glFormat = gl::Format(sizedInternalFormat); + } + + if (angleFormat) + { + *angleFormat = textureAngleFormat; + } + + if (arraySlice) + { + *arraySlice = textureArraySlice; + } + + return egl::NoError(); +} + +egl::Error Renderer11::validateShareHandle(const egl::Config *config, + HANDLE shareHandle, + const egl::AttributeMap &attribs) const +{ + if (shareHandle == nullptr) + { + return egl::EglBadParameter() << "NULL share handle."; + } + + ID3D11Resource *tempResource11 = nullptr; + HRESULT result = mDevice->OpenSharedResource(shareHandle, __uuidof(ID3D11Resource), + (void **)&tempResource11); + if (FAILED(result) && mDevice1) + { + result = mDevice1->OpenSharedResource1(shareHandle, __uuidof(ID3D11Resource), + (void **)&tempResource11); + } + + if (FAILED(result)) + { + return egl::EglBadParameter() << "Failed to open share handle, " << gl::FmtHR(result); + } + + ID3D11Texture2D *texture2D = d3d11::DynamicCastComObject(tempResource11); + SafeRelease(tempResource11); + + if (texture2D == nullptr) + { + return egl::EglBadParameter() + << "Failed to query ID3D11Texture2D object from share handle."; + } + + D3D11_TEXTURE2D_DESC desc = {}; + texture2D->GetDesc(&desc); + SafeRelease(texture2D); + + EGLint width = attribs.getAsInt(EGL_WIDTH, 0); + EGLint height = attribs.getAsInt(EGL_HEIGHT, 0); + ASSERT(width != 0 && height != 0); + + const d3d11::Format &backbufferFormatInfo = + d3d11::Format::Get(config->renderTargetFormat, getRenderer11DeviceCaps()); + + if (desc.Width != static_cast(width) || desc.Height != static_cast(height) || + desc.Format != backbufferFormatInfo.texFormat || desc.MipLevels != 1 || desc.ArraySize != 1) + { + return egl::EglBadParameter() << "Invalid texture parameters in share handle texture."; + } + + return egl::NoError(); +} + +SwapChainD3D *Renderer11::createSwapChain(NativeWindowD3D *nativeWindow, + HANDLE shareHandle, + IUnknown *d3dTexture, + GLenum backBufferFormat, + GLenum depthBufferFormat, + EGLint orientation, + EGLint samples) +{ + return new SwapChain11(this, GetAs(nativeWindow), shareHandle, d3dTexture, + backBufferFormat, depthBufferFormat, orientation, samples); +} + +void *Renderer11::getD3DDevice() +{ + return mDevice; +} + +angle::Result Renderer11::drawWithGeometryShaderAndTransformFeedback(Context11 *context11, + gl::PrimitiveMode mode, + UINT instanceCount, + UINT vertexCount) +{ + const gl::State &glState = context11->getState(); + ProgramD3D *programD3D = mStateManager.getProgramD3D(); + + // Since we use a geometry if-and-only-if we rewrite vertex streams, transform feedback + // won't get the correct output. To work around this, draw with *only* the stream out + // first (no pixel shader) to feed the stream out buffers and then draw again with the + // geometry shader + pixel shader to rasterize the primitives. + mStateManager.setPixelShader(nullptr); + + if (instanceCount > 0) + { + mDeviceContext->DrawInstanced(vertexCount, instanceCount, 0, 0); + } + else + { + mDeviceContext->Draw(vertexCount, 0); + } + + rx::ShaderExecutableD3D *pixelExe = nullptr; + ANGLE_TRY(programD3D->getPixelExecutableForCachedOutputLayout(context11, &pixelExe, nullptr)); + + // Skip the draw call if rasterizer discard is enabled (or no fragment shader). + if (!pixelExe || glState.getRasterizerState().rasterizerDiscard) + { + return angle::Result::Continue; + } + + mStateManager.setPixelShader(&GetAs(pixelExe)->getPixelShader()); + + // Retrieve the geometry shader. + rx::ShaderExecutableD3D *geometryExe = nullptr; + ANGLE_TRY(programD3D->getGeometryExecutableForPrimitiveType(context11, glState, mode, + &geometryExe, nullptr)); + + mStateManager.setGeometryShader(&GetAs(geometryExe)->getGeometryShader()); + + if (instanceCount > 0) + { + mDeviceContext->DrawInstanced(vertexCount, instanceCount, 0, 0); + } + else + { + mDeviceContext->Draw(vertexCount, 0); + } + + return angle::Result::Continue; +} + +angle::Result Renderer11::drawArrays(const gl::Context *context, + gl::PrimitiveMode mode, + GLint firstVertex, + GLsizei vertexCount, + GLsizei instanceCount, + GLuint baseInstance, + bool isInstancedDraw) +{ + if (mStateManager.getCullEverything()) + { + return angle::Result::Continue; + } + + ANGLE_TRY(markRawBufferUsage(context)); + + ProgramD3D *programD3D = mStateManager.getProgramD3D(); + GLsizei adjustedInstanceCount = GetAdjustedInstanceCount(programD3D, instanceCount); + + // Note: vertex indexes can be arbitrarily large. + UINT clampedVertexCount = gl::GetClampedVertexCount(vertexCount); + + const auto &glState = context->getState(); + if (glState.getCurrentTransformFeedback() && glState.isTransformFeedbackActiveUnpaused()) + { + ANGLE_TRY(markTransformFeedbackUsage(context)); + + if (programD3D->usesGeometryShader(glState, mode)) + { + return drawWithGeometryShaderAndTransformFeedback( + GetImplAs(context), mode, adjustedInstanceCount, clampedVertexCount); + } + } + + switch (mode) + { + case gl::PrimitiveMode::LineLoop: + return drawLineLoop(context, clampedVertexCount, gl::DrawElementsType::InvalidEnum, + nullptr, 0, adjustedInstanceCount); + case gl::PrimitiveMode::TriangleFan: + return drawTriangleFan(context, clampedVertexCount, gl::DrawElementsType::InvalidEnum, + nullptr, 0, adjustedInstanceCount); + case gl::PrimitiveMode::Points: + if (getFeatures().useInstancedPointSpriteEmulation.enabled) + { + // This code should not be reachable by multi-view programs. + ASSERT(programD3D->getState().usesMultiview() == false); + + // If the shader is writing to gl_PointSize, then pointsprites are being rendered. + // Emulating instanced point sprites for FL9_3 requires the topology to be + // D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST and DrawIndexedInstanced is called instead. + if (adjustedInstanceCount == 0) + { + mDeviceContext->DrawIndexedInstanced(6, clampedVertexCount, 0, 0, baseInstance); + return angle::Result::Continue; + } + + // If pointsprite emulation is used with glDrawArraysInstanced then we need to take + // a less efficent code path. Instanced rendering of emulated pointsprites requires + // a loop to draw each batch of points. An offset into the instanced data buffer is + // calculated and applied on each iteration to ensure all instances are rendered + // correctly. Each instance being rendered requires the inputlayout cache to reapply + // buffers and offsets. + for (GLsizei i = 0; i < instanceCount; i++) + { + ANGLE_TRY(mStateManager.updateVertexOffsetsForPointSpritesEmulation( + context, firstVertex, i)); + mDeviceContext->DrawIndexedInstanced(6, clampedVertexCount, 0, 0, baseInstance); + } + + // This required by updateVertexOffsets... above but is outside of the loop for + // speed. + mStateManager.invalidateVertexBuffer(); + return angle::Result::Continue; + } + break; + default: + break; + } + + // "Normal" draw case. + if (!isInstancedDraw && adjustedInstanceCount == 0) + { + mDeviceContext->Draw(clampedVertexCount, 0); + } + else + { + mDeviceContext->DrawInstanced(clampedVertexCount, adjustedInstanceCount, 0, baseInstance); + } + return angle::Result::Continue; +} + +angle::Result Renderer11::drawElements(const gl::Context *context, + gl::PrimitiveMode mode, + GLint startVertex, + GLsizei indexCount, + gl::DrawElementsType indexType, + const void *indices, + GLsizei instanceCount, + GLint baseVertex, + GLuint baseInstance, + bool isInstancedDraw) +{ + if (mStateManager.getCullEverything()) + { + return angle::Result::Continue; + } + + ANGLE_TRY(markRawBufferUsage(context)); + + // Transform feedback is not allowed for DrawElements, this error should have been caught at the + // API validation layer. + const gl::State &glState = context->getState(); + ASSERT(!glState.isTransformFeedbackActiveUnpaused()); + + // If this draw call is coming from an indirect call, offset by the indirect call's base vertex. + GLint baseVertexAdjusted = baseVertex - startVertex; + + const ProgramD3D *programD3D = mStateManager.getProgramD3D(); + GLsizei adjustedInstanceCount = GetAdjustedInstanceCount(programD3D, instanceCount); + + if (mode == gl::PrimitiveMode::LineLoop) + { + return drawLineLoop(context, indexCount, indexType, indices, baseVertexAdjusted, + adjustedInstanceCount); + } + + if (mode == gl::PrimitiveMode::TriangleFan) + { + return drawTriangleFan(context, indexCount, indexType, indices, baseVertexAdjusted, + adjustedInstanceCount); + } + + if (mode != gl::PrimitiveMode::Points || !programD3D->usesInstancedPointSpriteEmulation()) + { + if (!isInstancedDraw && adjustedInstanceCount == 0) + { + mDeviceContext->DrawIndexed(indexCount, 0, baseVertexAdjusted); + } + else + { + mDeviceContext->DrawIndexedInstanced(indexCount, adjustedInstanceCount, 0, + baseVertexAdjusted, baseInstance); + } + return angle::Result::Continue; + } + + // This code should not be reachable by multi-view programs. + ASSERT(programD3D->getState().usesMultiview() == false); + + // If the shader is writing to gl_PointSize, then pointsprites are being rendered. + // Emulating instanced point sprites for FL9_3 requires the topology to be + // D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST and DrawIndexedInstanced is called instead. + // + // The count parameter passed to drawElements represents the total number of instances to be + // rendered. Each instance is referenced by the bound index buffer from the the caller. + // + // Indexed pointsprite emulation replicates data for duplicate entries found in the index + // buffer. This is not an efficent rendering mechanism and is only used on downlevel renderers + // that do not support geometry shaders. + if (instanceCount == 0) + { + mDeviceContext->DrawIndexedInstanced(6, indexCount, 0, baseVertexAdjusted, baseInstance); + return angle::Result::Continue; + } + + // If pointsprite emulation is used with glDrawElementsInstanced then we need to take a less + // efficent code path. Instanced rendering of emulated pointsprites requires a loop to draw each + // batch of points. An offset into the instanced data buffer is calculated and applied on each + // iteration to ensure all instances are rendered correctly. + gl::IndexRange indexRange; + ANGLE_TRY(glState.getVertexArray()->getIndexRange(context, indexType, indexCount, indices, + &indexRange)); + + UINT clampedVertexCount = gl::clampCast(indexRange.vertexCount()); + + // Each instance being rendered requires the inputlayout cache to reapply buffers and offsets. + for (GLsizei i = 0; i < instanceCount; i++) + { + ANGLE_TRY( + mStateManager.updateVertexOffsetsForPointSpritesEmulation(context, startVertex, i)); + mDeviceContext->DrawIndexedInstanced(6, clampedVertexCount, 0, baseVertexAdjusted, + baseInstance); + } + mStateManager.invalidateVertexBuffer(); + return angle::Result::Continue; +} + +angle::Result Renderer11::drawArraysIndirect(const gl::Context *context, const void *indirect) +{ + if (mStateManager.getCullEverything()) + { + return angle::Result::Continue; + } + + ANGLE_TRY(markRawBufferUsage(context)); + + const gl::State &glState = context->getState(); + ASSERT(!glState.isTransformFeedbackActiveUnpaused()); + + gl::Buffer *drawIndirectBuffer = glState.getTargetBuffer(gl::BufferBinding::DrawIndirect); + ASSERT(drawIndirectBuffer); + Buffer11 *storage = GetImplAs(drawIndirectBuffer); + + uintptr_t offset = reinterpret_cast(indirect); + + ID3D11Buffer *buffer = nullptr; + ANGLE_TRY(storage->getBuffer(context, BUFFER_USAGE_INDIRECT, &buffer)); + mDeviceContext->DrawInstancedIndirect(buffer, static_cast(offset)); + return angle::Result::Continue; +} + +angle::Result Renderer11::drawElementsIndirect(const gl::Context *context, const void *indirect) +{ + if (mStateManager.getCullEverything()) + { + return angle::Result::Continue; + } + + ANGLE_TRY(markRawBufferUsage(context)); + + const gl::State &glState = context->getState(); + ASSERT(!glState.isTransformFeedbackActiveUnpaused()); + + gl::Buffer *drawIndirectBuffer = glState.getTargetBuffer(gl::BufferBinding::DrawIndirect); + ASSERT(drawIndirectBuffer); + Buffer11 *storage = GetImplAs(drawIndirectBuffer); + uintptr_t offset = reinterpret_cast(indirect); + + ID3D11Buffer *buffer = nullptr; + ANGLE_TRY(storage->getBuffer(context, BUFFER_USAGE_INDIRECT, &buffer)); + mDeviceContext->DrawIndexedInstancedIndirect(buffer, static_cast(offset)); + return angle::Result::Continue; +} + +angle::Result Renderer11::drawLineLoop(const gl::Context *context, + GLuint count, + gl::DrawElementsType type, + const void *indexPointer, + int baseVertex, + int instances) +{ + const gl::State &glState = context->getState(); + gl::VertexArray *vao = glState.getVertexArray(); + gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer(); + + const void *indices = indexPointer; + + // Get the raw indices for an indexed draw + if (type != gl::DrawElementsType::InvalidEnum && elementArrayBuffer) + { + BufferD3D *storage = GetImplAs(elementArrayBuffer); + intptr_t offset = reinterpret_cast(indices); + + const uint8_t *bufferData = nullptr; + ANGLE_TRY(storage->getData(context, &bufferData)); + + indices = bufferData + offset; + } + + if (!mLineLoopIB) + { + mLineLoopIB = new StreamingIndexBufferInterface(this); + ANGLE_TRY(mLineLoopIB->reserveBufferSpace(context, INITIAL_INDEX_BUFFER_SIZE, + gl::DrawElementsType::UnsignedInt)); + } + + // Checked by Renderer11::applyPrimitiveType + bool indexCheck = static_cast(count) + 1 > + (std::numeric_limits::max() / sizeof(unsigned int)); + ANGLE_CHECK(GetImplAs(context), !indexCheck, + "Failed to create a 32-bit looping index buffer for " + "GL_LINE_LOOP, too many indices required.", + GL_OUT_OF_MEMORY); + + GetLineLoopIndices(indices, type, static_cast(count), + glState.isPrimitiveRestartEnabled(), &mScratchIndexDataBuffer); + + unsigned int spaceNeeded = + static_cast(sizeof(GLuint) * mScratchIndexDataBuffer.size()); + ANGLE_TRY( + mLineLoopIB->reserveBufferSpace(context, spaceNeeded, gl::DrawElementsType::UnsignedInt)); + + void *mappedMemory = nullptr; + unsigned int offset; + ANGLE_TRY(mLineLoopIB->mapBuffer(context, spaceNeeded, &mappedMemory, &offset)); + + // Copy over the converted index data. + memcpy(mappedMemory, &mScratchIndexDataBuffer[0], + sizeof(GLuint) * mScratchIndexDataBuffer.size()); + + ANGLE_TRY(mLineLoopIB->unmapBuffer(context)); + + IndexBuffer11 *indexBuffer = GetAs(mLineLoopIB->getIndexBuffer()); + const d3d11::Buffer &d3dIndexBuffer = indexBuffer->getBuffer(); + DXGI_FORMAT indexFormat = indexBuffer->getIndexFormat(); + + mStateManager.setIndexBuffer(d3dIndexBuffer.get(), indexFormat, offset); + + UINT indexCount = static_cast(mScratchIndexDataBuffer.size()); + + if (instances > 0) + { + mDeviceContext->DrawIndexedInstanced(indexCount, instances, 0, baseVertex, 0); + } + else + { + mDeviceContext->DrawIndexed(indexCount, 0, baseVertex); + } + + return angle::Result::Continue; +} + +angle::Result Renderer11::drawTriangleFan(const gl::Context *context, + GLuint count, + gl::DrawElementsType type, + const void *indices, + int baseVertex, + int instances) +{ + const gl::State &glState = context->getState(); + gl::VertexArray *vao = glState.getVertexArray(); + gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer(); + + const void *indexPointer = indices; + + // Get the raw indices for an indexed draw + if (type != gl::DrawElementsType::InvalidEnum && elementArrayBuffer) + { + BufferD3D *storage = GetImplAs(elementArrayBuffer); + intptr_t offset = reinterpret_cast(indices); + + const uint8_t *bufferData = nullptr; + ANGLE_TRY(storage->getData(context, &bufferData)); + + indexPointer = bufferData + offset; + } + + if (!mTriangleFanIB) + { + mTriangleFanIB = new StreamingIndexBufferInterface(this); + ANGLE_TRY(mTriangleFanIB->reserveBufferSpace(context, INITIAL_INDEX_BUFFER_SIZE, + gl::DrawElementsType::UnsignedInt)); + } + + // Checked by Renderer11::applyPrimitiveType + ASSERT(count >= 3); + + const GLuint numTris = count - 2; + + bool indexCheck = + (numTris > std::numeric_limits::max() / (sizeof(unsigned int) * 3)); + ANGLE_CHECK(GetImplAs(context), !indexCheck, + "Failed to create a scratch index buffer for GL_TRIANGLE_FAN, " + "too many indices required.", + GL_OUT_OF_MEMORY); + + GetTriFanIndices(indexPointer, type, count, glState.isPrimitiveRestartEnabled(), + &mScratchIndexDataBuffer); + + const unsigned int spaceNeeded = + static_cast(mScratchIndexDataBuffer.size() * sizeof(unsigned int)); + ANGLE_TRY(mTriangleFanIB->reserveBufferSpace(context, spaceNeeded, + gl::DrawElementsType::UnsignedInt)); + + void *mappedMemory = nullptr; + unsigned int offset; + ANGLE_TRY(mTriangleFanIB->mapBuffer(context, spaceNeeded, &mappedMemory, &offset)); + + memcpy(mappedMemory, &mScratchIndexDataBuffer[0], spaceNeeded); + + ANGLE_TRY(mTriangleFanIB->unmapBuffer(context)); + + IndexBuffer11 *indexBuffer = GetAs(mTriangleFanIB->getIndexBuffer()); + const d3d11::Buffer &d3dIndexBuffer = indexBuffer->getBuffer(); + DXGI_FORMAT indexFormat = indexBuffer->getIndexFormat(); + + mStateManager.setIndexBuffer(d3dIndexBuffer.get(), indexFormat, offset); + + UINT indexCount = static_cast(mScratchIndexDataBuffer.size()); + + if (instances > 0) + { + mDeviceContext->DrawIndexedInstanced(indexCount, instances, 0, baseVertex, 0); + } + else + { + mDeviceContext->DrawIndexed(indexCount, 0, baseVertex); + } + + return angle::Result::Continue; +} + +void Renderer11::releaseDeviceResources() +{ + mStateManager.deinitialize(); + mStateCache.clear(); + + SafeDelete(mLineLoopIB); + SafeDelete(mTriangleFanIB); + SafeDelete(mBlit); + SafeDelete(mClear); + SafeDelete(mTrim); + SafeDelete(mPixelTransfer); + + mSyncQuery.reset(); + + mCachedResolveTexture.reset(); +} + +// set notify to true to broadcast a message to all contexts of the device loss +bool Renderer11::testDeviceLost() +{ + if (!mDevice) + { + return true; + } + + // GetRemovedReason is used to test if the device is removed + HRESULT result = mDevice->GetDeviceRemovedReason(); + bool isLost = FAILED(result); + + if (isLost) + { + ERR() << "The D3D11 device was removed, " << gl::FmtHR(result); + } + + return isLost; +} + +bool Renderer11::testDeviceResettable() +{ + // determine if the device is resettable by creating a mock device + PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = + (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice"); + + if (D3D11CreateDevice == nullptr) + { + return false; + } + + ID3D11Device *mockDevice; + D3D_FEATURE_LEVEL mockFeatureLevel; + ID3D11DeviceContext *mockContext; + UINT flags = (mCreateDebugDevice ? D3D11_CREATE_DEVICE_DEBUG : 0); + + ASSERT(mRequestedDriverType != D3D_DRIVER_TYPE_UNKNOWN); + HRESULT result = D3D11CreateDevice( + nullptr, mRequestedDriverType, nullptr, flags, mAvailableFeatureLevels.data(), + static_cast(mAvailableFeatureLevels.size()), D3D11_SDK_VERSION, &mockDevice, + &mockFeatureLevel, &mockContext); + + if (!mDevice || FAILED(result)) + { + return false; + } + + SafeRelease(mockContext); + SafeRelease(mockDevice); + + return true; +} + +void Renderer11::release() +{ + mScratchMemoryBuffer.clear(); + + mAnnotatorContext.release(); + gl::UninitializeDebugAnnotations(); + + releaseDeviceResources(); + + SafeRelease(mDxgiFactory); + SafeRelease(mDxgiAdapter); + + SafeRelease(mDeviceContext3); + SafeRelease(mDeviceContext1); + + if (mDeviceContext) + { + mDeviceContext->ClearState(); + mDeviceContext->Flush(); + SafeRelease(mDeviceContext); + } + + SafeRelease(mDevice); + SafeRelease(mDevice1); + SafeRelease(mDebug); + + if (mD3d11Module) + { + FreeLibrary(mD3d11Module); + mD3d11Module = nullptr; + } + + if (mDxgiModule) + { + FreeLibrary(mDxgiModule); + mDxgiModule = nullptr; + } + + if (mDCompModule) + { + FreeLibrary(mDCompModule); + mDCompModule = nullptr; + } + + mDevice12.Reset(); + mCommandQueue.Reset(); + + if (mD3d12Module) + { + FreeLibrary(mD3d12Module); + mD3d12Module = nullptr; + } + + mCompiler.release(); + + mSupportsShareHandles.reset(); +} + +bool Renderer11::resetDevice() +{ + // recreate everything + release(); + egl::Error result = initialize(); + + if (result.isError()) + { + ERR() << "Could not reinitialize D3D11 device: " << result; + return false; + } + + return true; +} + +std::string Renderer11::getRendererDescription() const +{ + std::ostringstream rendererString; + + rendererString << mDescription; + rendererString << " Direct3D11"; + + rendererString << " vs_" << getMajorShaderModel() << "_" << getMinorShaderModel() + << getShaderModelSuffix(); + rendererString << " ps_" << getMajorShaderModel() << "_" << getMinorShaderModel() + << getShaderModelSuffix(); + + return rendererString.str(); +} + +DeviceIdentifier Renderer11::getAdapterIdentifier() const +{ + // Don't use the AdapterLuid here, since that doesn't persist across reboot. + DeviceIdentifier deviceIdentifier = {}; + deviceIdentifier.VendorId = mAdapterDescription.VendorId; + deviceIdentifier.DeviceId = mAdapterDescription.DeviceId; + deviceIdentifier.SubSysId = mAdapterDescription.SubSysId; + deviceIdentifier.Revision = mAdapterDescription.Revision; + deviceIdentifier.FeatureLevel = static_cast(mRenderer11DeviceCaps.featureLevel); + + return deviceIdentifier; +} + +unsigned int Renderer11::getReservedVertexUniformVectors() const +{ + // Driver uniforms are stored in a separate constant buffer + return d3d11_gl::GetReservedVertexUniformVectors(mRenderer11DeviceCaps.featureLevel); +} + +unsigned int Renderer11::getReservedFragmentUniformVectors() const +{ + // Driver uniforms are stored in a separate constant buffer + return d3d11_gl::GetReservedFragmentUniformVectors(mRenderer11DeviceCaps.featureLevel); +} + +gl::ShaderMap Renderer11::getReservedShaderUniformBuffers() const +{ + gl::ShaderMap shaderReservedUniformBuffers = {}; + + // we reserve one buffer for the application uniforms, and one for driver uniforms + shaderReservedUniformBuffers[gl::ShaderType::Vertex] = 2; + shaderReservedUniformBuffers[gl::ShaderType::Fragment] = 2; + + return shaderReservedUniformBuffers; +} + +d3d11::ANGLED3D11DeviceType Renderer11::getDeviceType() const +{ + if (mCreatedWithDeviceEXT) + { + return d3d11::GetDeviceType(mDevice); + } + + if ((mRequestedDriverType == D3D_DRIVER_TYPE_SOFTWARE) || + (mRequestedDriverType == D3D_DRIVER_TYPE_REFERENCE) || + (mRequestedDriverType == D3D_DRIVER_TYPE_NULL)) + { + return d3d11::ANGLE_D3D11_DEVICE_TYPE_SOFTWARE_REF_OR_NULL; + } + + if (mRequestedDriverType == D3D_DRIVER_TYPE_WARP) + { + return d3d11::ANGLE_D3D11_DEVICE_TYPE_WARP; + } + + return d3d11::ANGLE_D3D11_DEVICE_TYPE_HARDWARE; +} + +bool Renderer11::getShareHandleSupport() const +{ + if (mSupportsShareHandles.valid()) + { + return mSupportsShareHandles.value(); + } + + // We only currently support share handles with BGRA surfaces, because + // chrome needs BGRA. Once chrome fixes this, we should always support them. + if (!getNativeExtensions().textureFormatBGRA8888EXT) + { + mSupportsShareHandles = false; + return false; + } + + // PIX doesn't seem to support using share handles, so disable them. + if (mAnnotatorContext.getStatus()) + { + mSupportsShareHandles = false; + return false; + } + + // Also disable share handles on Feature Level 9_3, since it doesn't support share handles on + // RGBA8 textures/swapchains. + if (mRenderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3) + { + mSupportsShareHandles = false; + return false; + } + + // Find out which type of D3D11 device the Renderer11 is using + d3d11::ANGLED3D11DeviceType deviceType = getDeviceType(); + if (deviceType == d3d11::ANGLE_D3D11_DEVICE_TYPE_UNKNOWN) + { + mSupportsShareHandles = false; + return false; + } + + if (deviceType == d3d11::ANGLE_D3D11_DEVICE_TYPE_SOFTWARE_REF_OR_NULL) + { + // Software/Reference/NULL devices don't support share handles + mSupportsShareHandles = false; + return false; + } + + if (deviceType == d3d11::ANGLE_D3D11_DEVICE_TYPE_WARP) + { +#if !defined(ANGLE_ENABLE_WINDOWS_UWP) + if (!IsWindows8OrGreater()) + { + // WARP on Windows 7 doesn't support shared handles + mSupportsShareHandles = false; + return false; + } +#endif // !defined(ANGLE_ENABLE_WINDOWS_UWP) + + // WARP on Windows 8.0+ supports shared handles when shared with another WARP device + // TODO: allow applications to query for HARDWARE or WARP-specific share handles, + // to prevent them trying to use a WARP share handle with an a HW device (or + // vice-versa) + // e.g. by creating EGL_D3D11_[HARDWARE/WARP]_DEVICE_SHARE_HANDLE_ANGLE + mSupportsShareHandles = true; + return true; + } + + ASSERT(mCreatedWithDeviceEXT || mRequestedDriverType == D3D_DRIVER_TYPE_HARDWARE); + mSupportsShareHandles = true; + return true; +} + +int Renderer11::getMajorShaderModel() const +{ + switch (mRenderer11DeviceCaps.featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_SHADER_MAJOR_VERSION; // 5 + case D3D_FEATURE_LEVEL_10_1: + return D3D10_1_SHADER_MAJOR_VERSION; // 4 + case D3D_FEATURE_LEVEL_10_0: + return D3D10_SHADER_MAJOR_VERSION; // 4 + case D3D_FEATURE_LEVEL_9_3: + return D3D10_SHADER_MAJOR_VERSION; // 4 + default: + UNREACHABLE(); + return 0; + } +} + +int Renderer11::getMinorShaderModel() const +{ + switch (mRenderer11DeviceCaps.featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_SHADER_MINOR_VERSION; // 0 + case D3D_FEATURE_LEVEL_10_1: + return D3D10_1_SHADER_MINOR_VERSION; // 1 + case D3D_FEATURE_LEVEL_10_0: + return D3D10_SHADER_MINOR_VERSION; // 0 + case D3D_FEATURE_LEVEL_9_3: + return D3D10_SHADER_MINOR_VERSION; // 0 + default: + UNREACHABLE(); + return 0; + } +} + +std::string Renderer11::getShaderModelSuffix() const +{ + switch (mRenderer11DeviceCaps.featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return ""; + case D3D_FEATURE_LEVEL_10_1: + return ""; + case D3D_FEATURE_LEVEL_10_0: + return ""; + case D3D_FEATURE_LEVEL_9_3: + return "_level_9_3"; + default: + UNREACHABLE(); + return ""; + } +} + +angle::Result Renderer11::copyImageInternal(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + RenderTargetD3D *destRenderTarget) +{ + const gl::FramebufferAttachment *colorAttachment = framebuffer->getReadColorAttachment(); + ASSERT(colorAttachment); + + RenderTarget11 *sourceRenderTarget = nullptr; + ANGLE_TRY(colorAttachment->getRenderTarget(context, 0, &sourceRenderTarget)); + ASSERT(sourceRenderTarget); + + const d3d11::RenderTargetView &dest = + GetAs(destRenderTarget)->getRenderTargetView(); + ASSERT(dest.valid()); + + gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1); + gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1); + + const bool invertSource = UsePresentPathFast(this, colorAttachment); + if (invertSource) + { + sourceArea.y = sourceSize.height - sourceRect.y; + sourceArea.height = -sourceArea.height; + } + + gl::Box destArea(destOffset.x, destOffset.y, 0, sourceRect.width, sourceRect.height, 1); + gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1); + + // Use nearest filtering because source and destination are the same size for the direct copy. + // Convert to the unsized format before calling copyTexture. + GLenum sourceFormat = colorAttachment->getFormat().info->format; + if (sourceRenderTarget->getTexture().is2D() && sourceRenderTarget->isMultisampled()) + { + TextureHelper11 tex; + ANGLE_TRY(resolveMultisampledTexture(context, sourceRenderTarget, + colorAttachment->getDepthSize() > 0, + colorAttachment->getStencilSize() > 0, &tex)); + + D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc; + viewDesc.Format = sourceRenderTarget->getFormatSet().srvFormat; + viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + viewDesc.Texture2D.MipLevels = 1; + viewDesc.Texture2D.MostDetailedMip = 0; + + d3d11::SharedSRV readSRV; + ANGLE_TRY(allocateResource(GetImplAs(context), viewDesc, tex.get(), &readSRV)); + ASSERT(readSRV.valid()); + + ANGLE_TRY(mBlit->copyTexture(context, readSRV, sourceArea, sourceSize, sourceFormat, dest, + destArea, destSize, nullptr, gl::GetUnsizedFormat(destFormat), + GL_NONE, GL_NEAREST, false, false, false)); + + return angle::Result::Continue; + } + + ASSERT(!sourceRenderTarget->isMultisampled()); + + const d3d11::SharedSRV *source; + ANGLE_TRY(sourceRenderTarget->getBlitShaderResourceView(context, &source)); + ASSERT(source->valid()); + + ANGLE_TRY(mBlit->copyTexture(context, *source, sourceArea, sourceSize, sourceFormat, dest, + destArea, destSize, nullptr, gl::GetUnsizedFormat(destFormat), + GL_NONE, GL_NEAREST, false, false, false)); + + return angle::Result::Continue; +} + +angle::Result Renderer11::copyImage2D(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) +{ + TextureStorage11_2D *storage11 = GetAs(storage); + ASSERT(storage11); + + gl::ImageIndex index = gl::ImageIndex::Make2D(level); + RenderTargetD3D *destRenderTarget = nullptr; + ANGLE_TRY(storage11->getRenderTarget(context, index, storage11->getRenderToTextureSamples(), + &destRenderTarget)); + ASSERT(destRenderTarget); + + ANGLE_TRY(copyImageInternal(context, framebuffer, sourceRect, destFormat, destOffset, + destRenderTarget)); + + storage11->markLevelDirty(level); + + return angle::Result::Continue; +} + +angle::Result Renderer11::copyImageCube(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + gl::TextureTarget target, + GLint level) +{ + TextureStorage11_Cube *storage11 = GetAs(storage); + ASSERT(storage11); + + gl::ImageIndex index = gl::ImageIndex::MakeCubeMapFace(target, level); + RenderTargetD3D *destRenderTarget = nullptr; + ANGLE_TRY(storage11->getRenderTarget(context, index, storage11->getRenderToTextureSamples(), + &destRenderTarget)); + ASSERT(destRenderTarget); + + ANGLE_TRY(copyImageInternal(context, framebuffer, sourceRect, destFormat, destOffset, + destRenderTarget)); + + storage11->markLevelDirty(level); + + return angle::Result::Continue; +} + +angle::Result Renderer11::copyImage3D(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) +{ + TextureStorage11_3D *storage11 = GetAs(storage); + ASSERT(storage11); + + gl::ImageIndex index = gl::ImageIndex::Make3D(level, destOffset.z); + RenderTargetD3D *destRenderTarget = nullptr; + ANGLE_TRY(storage11->getRenderTarget(context, index, storage11->getRenderToTextureSamples(), + &destRenderTarget)); + ASSERT(destRenderTarget); + + ANGLE_TRY(copyImageInternal(context, framebuffer, sourceRect, destFormat, destOffset, + destRenderTarget)); + + storage11->markLevelDirty(level); + + return angle::Result::Continue; +} + +angle::Result Renderer11::copyImage2DArray(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) +{ + TextureStorage11_2DArray *storage11 = GetAs(storage); + ASSERT(storage11); + + gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, destOffset.z); + RenderTargetD3D *destRenderTarget = nullptr; + ANGLE_TRY(storage11->getRenderTarget(context, index, storage11->getRenderToTextureSamples(), + &destRenderTarget)); + ASSERT(destRenderTarget); + + ANGLE_TRY(copyImageInternal(context, framebuffer, sourceRect, destFormat, destOffset, + destRenderTarget)); + storage11->markLevelDirty(level); + + return angle::Result::Continue; +} + +angle::Result Renderer11::copyTexture(const gl::Context *context, + const gl::Texture *source, + GLint sourceLevel, + gl::TextureTarget srcTarget, + const gl::Box &sourceBox, + GLenum destFormat, + GLenum destType, + const gl::Offset &destOffset, + TextureStorage *storage, + gl::TextureTarget destTarget, + GLint destLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) +{ + + TextureD3D *sourceD3D = GetImplAs(source); + const gl::ImageDesc &sourceImageDesc = source->getTextureState().getImageDesc( + NonCubeTextureTypeToTarget(source->getType()), sourceLevel); + + TextureStorage11 *destStorage11 = GetAs(storage); + ASSERT(destStorage11); + + // Check for fast path where a CopySubresourceRegion can be used. + if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha && !unpackFlipY && + sourceImageDesc.format.info->sizedInternalFormat == + destStorage11->getFormatSet().internalFormat) + { + const TextureHelper11 *destResource = nullptr; + ANGLE_TRY(destStorage11->getResource(context, &destResource)); + + if (srcTarget == gl::TextureTarget::_2D || srcTarget == gl::TextureTarget::_3D) + { + gl::ImageIndex sourceIndex = gl::ImageIndex::MakeFromTarget(srcTarget, sourceLevel, 1); + const TextureHelper11 *sourceResource = nullptr; + UINT sourceSubresource = 0; + ANGLE_TRY(GetTextureD3DResourceFromStorageOrImage(context, sourceD3D, sourceIndex, + &sourceResource, &sourceSubresource)); + + gl::ImageIndex destIndex = gl::ImageIndex::MakeFromTarget(destTarget, destLevel, 1); + + UINT destSubresource = 0; + ANGLE_TRY(destStorage11->getSubresourceIndex(context, destIndex, &destSubresource)); + + D3D11_BOX d3dBox{static_cast(sourceBox.x), + static_cast(sourceBox.y), + static_cast(sourceBox.z), + static_cast(sourceBox.x + sourceBox.width), + static_cast(sourceBox.y + sourceBox.height), + static_cast(sourceBox.z + sourceBox.depth)}; + + mDeviceContext->CopySubresourceRegion( + destResource->get(), destSubresource, destOffset.x, destOffset.y, destOffset.z, + sourceResource->get(), sourceSubresource, &d3dBox); + } + else if (srcTarget == gl::TextureTarget::_2DArray) + { + D3D11_BOX d3dBox{static_cast(sourceBox.x), + static_cast(sourceBox.y), + 0, + static_cast(sourceBox.x + sourceBox.width), + static_cast(sourceBox.y + sourceBox.height), + 1u}; + + for (int i = 0; i < sourceBox.depth; i++) + { + gl::ImageIndex sourceIndex = + gl::ImageIndex::Make2DArray(sourceLevel, i + sourceBox.z); + const TextureHelper11 *sourceResource = nullptr; + UINT sourceSubresource = 0; + ANGLE_TRY(GetTextureD3DResourceFromStorageOrImage( + context, sourceD3D, sourceIndex, &sourceResource, &sourceSubresource)); + + gl::ImageIndex dIndex = gl::ImageIndex::Make2DArray(destLevel, i + destOffset.z); + UINT destSubresource = 0; + ANGLE_TRY(destStorage11->getSubresourceIndex(context, dIndex, &destSubresource)); + + mDeviceContext->CopySubresourceRegion( + destResource->get(), destSubresource, destOffset.x, destOffset.y, 0, + sourceResource->get(), sourceSubresource, &d3dBox); + } + } + else + { + UNREACHABLE(); + } + } + else + { + TextureStorage *sourceStorage = nullptr; + ANGLE_TRY(sourceD3D->getNativeTexture(context, &sourceStorage)); + + TextureStorage11 *sourceStorage11 = GetAs(sourceStorage); + ASSERT(sourceStorage11); + + const d3d11::SharedSRV *sourceSRV = nullptr; + ANGLE_TRY(sourceStorage11->getSRVLevels(context, sourceLevel, sourceLevel, &sourceSRV)); + + gl::ImageIndex destIndex; + if (destTarget == gl::TextureTarget::_2D || destTarget == gl::TextureTarget::_3D || + gl::IsCubeMapFaceTarget(destTarget)) + { + destIndex = gl::ImageIndex::MakeFromTarget(destTarget, destLevel, 1); + } + else if (destTarget == gl::TextureTarget::_2DArray) + { + destIndex = gl::ImageIndex::Make2DArrayRange(destLevel, 0, sourceImageDesc.size.depth); + } + else + { + UNREACHABLE(); + } + + RenderTargetD3D *destRenderTargetD3D = nullptr; + ANGLE_TRY(destStorage11->getRenderTarget( + context, destIndex, destStorage11->getRenderToTextureSamples(), &destRenderTargetD3D)); + + RenderTarget11 *destRenderTarget11 = GetAs(destRenderTargetD3D); + + const d3d11::RenderTargetView &destRTV = destRenderTarget11->getRenderTargetView(); + ASSERT(destRTV.valid()); + + gl::Box sourceArea(sourceBox.x, sourceBox.y, sourceBox.z, sourceBox.width, sourceBox.height, + sourceBox.depth); + + if (unpackFlipY) + { + sourceArea.y += sourceArea.height; + sourceArea.height = -sourceArea.height; + } + + gl::Box destArea(destOffset.x, destOffset.y, destOffset.z, sourceBox.width, + sourceBox.height, sourceBox.depth); + + gl::Extents destSize(destRenderTarget11->getWidth(), destRenderTarget11->getHeight(), + sourceBox.depth); + + // Use nearest filtering because source and destination are the same size for the direct + // copy + GLenum sourceFormat = source->getFormat(srcTarget, sourceLevel).info->format; + ANGLE_TRY(mBlit->copyTexture(context, *sourceSRV, sourceArea, sourceImageDesc.size, + sourceFormat, destRTV, destArea, destSize, nullptr, destFormat, + destType, GL_NEAREST, false, unpackPremultiplyAlpha, + unpackUnmultiplyAlpha)); + } + + destStorage11->markLevelDirty(destLevel); + + return angle::Result::Continue; +} + +angle::Result Renderer11::copyCompressedTexture(const gl::Context *context, + const gl::Texture *source, + GLint sourceLevel, + TextureStorage *storage, + GLint destLevel) +{ + TextureStorage11_2D *destStorage11 = GetAs(storage); + ASSERT(destStorage11); + + const TextureHelper11 *destResource = nullptr; + ANGLE_TRY(destStorage11->getResource(context, &destResource)); + + gl::ImageIndex destIndex = gl::ImageIndex::Make2D(destLevel); + UINT destSubresource = 0; + ANGLE_TRY(destStorage11->getSubresourceIndex(context, destIndex, &destSubresource)); + + TextureD3D *sourceD3D = GetImplAs(source); + ASSERT(sourceD3D); + + TextureStorage *sourceStorage = nullptr; + ANGLE_TRY(sourceD3D->getNativeTexture(context, &sourceStorage)); + + TextureStorage11_2D *sourceStorage11 = GetAs(sourceStorage); + ASSERT(sourceStorage11); + + const TextureHelper11 *sourceResource = nullptr; + ANGLE_TRY(sourceStorage11->getResource(context, &sourceResource)); + + gl::ImageIndex sourceIndex = gl::ImageIndex::Make2D(sourceLevel); + UINT sourceSubresource = 0; + ANGLE_TRY(sourceStorage11->getSubresourceIndex(context, sourceIndex, &sourceSubresource)); + + mDeviceContext->CopySubresourceRegion(destResource->get(), destSubresource, 0, 0, 0, + sourceResource->get(), sourceSubresource, nullptr); + + return angle::Result::Continue; +} + +angle::Result Renderer11::createRenderTarget(const gl::Context *context, + int width, + int height, + GLenum format, + GLsizei samples, + RenderTargetD3D **outRT) +{ + const d3d11::Format &formatInfo = d3d11::Format::Get(format, mRenderer11DeviceCaps); + + const gl::TextureCaps &textureCaps = getNativeTextureCaps().get(format); + GLuint supportedSamples = textureCaps.getNearestSamples(samples); + + Context11 *context11 = GetImplAs(context); + + if (width > 0 && height > 0) + { + // Create texture resource + D3D11_TEXTURE2D_DESC desc; + desc.Width = width; + desc.Height = height; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = formatInfo.texFormat; + desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples; + desc.SampleDesc.Quality = getSampleDescQuality(supportedSamples); + desc.Usage = D3D11_USAGE_DEFAULT; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + // If a rendertarget or depthstencil format exists for this texture format, + // we'll flag it to allow binding that way. Shader resource views are a little + // more complicated. + bool bindRTV = false, bindDSV = false, bindSRV = false; + bindRTV = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN); + bindDSV = (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN); + bindSRV = (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN); + + bool isMultisampledDepthStencil = bindDSV && desc.SampleDesc.Count > 1; + if (isMultisampledDepthStencil && + !mRenderer11DeviceCaps.supportsMultisampledDepthStencilSRVs) + { + bindSRV = false; + } + + desc.BindFlags = (bindRTV ? D3D11_BIND_RENDER_TARGET : 0) | + (bindDSV ? D3D11_BIND_DEPTH_STENCIL : 0) | + (bindSRV ? D3D11_BIND_SHADER_RESOURCE : 0); + + // The format must be either an RTV or a DSV + ASSERT(bindRTV != bindDSV); + + TextureHelper11 texture; + ANGLE_TRY(allocateTexture(context11, desc, formatInfo, &texture)); + texture.setInternalName("createRenderTarget.Texture"); + + d3d11::SharedSRV srv; + d3d11::SharedSRV blitSRV; + if (bindSRV) + { + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = formatInfo.srvFormat; + srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D + : D3D11_SRV_DIMENSION_TEXTURE2DMS; + srvDesc.Texture2D.MostDetailedMip = 0; + srvDesc.Texture2D.MipLevels = 1; + + ANGLE_TRY(allocateResource(context11, srvDesc, texture.get(), &srv)); + srv.setInternalName("createRenderTarget.SRV"); + + if (formatInfo.blitSRVFormat != formatInfo.srvFormat) + { + D3D11_SHADER_RESOURCE_VIEW_DESC blitSRVDesc; + blitSRVDesc.Format = formatInfo.blitSRVFormat; + blitSRVDesc.ViewDimension = (supportedSamples == 0) + ? D3D11_SRV_DIMENSION_TEXTURE2D + : D3D11_SRV_DIMENSION_TEXTURE2DMS; + blitSRVDesc.Texture2D.MostDetailedMip = 0; + blitSRVDesc.Texture2D.MipLevels = 1; + + ANGLE_TRY(allocateResource(context11, blitSRVDesc, texture.get(), &blitSRV)); + blitSRV.setInternalName("createRenderTarget.BlitSRV"); + } + else + { + blitSRV = srv.makeCopy(); + } + } + + if (bindDSV) + { + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsvDesc.Format = formatInfo.dsvFormat; + dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D + : D3D11_DSV_DIMENSION_TEXTURE2DMS; + dsvDesc.Texture2D.MipSlice = 0; + dsvDesc.Flags = 0; + + d3d11::DepthStencilView dsv; + ANGLE_TRY(allocateResource(context11, dsvDesc, texture.get(), &dsv)); + dsv.setInternalName("createRenderTarget.DSV"); + + *outRT = new TextureRenderTarget11(std::move(dsv), texture, srv, format, formatInfo, + width, height, 1, supportedSamples); + } + else if (bindRTV) + { + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = formatInfo.rtvFormat; + rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D + : D3D11_RTV_DIMENSION_TEXTURE2DMS; + rtvDesc.Texture2D.MipSlice = 0; + + d3d11::RenderTargetView rtv; + ANGLE_TRY(allocateResource(context11, rtvDesc, texture.get(), &rtv)); + rtv.setInternalName("createRenderTarget.RTV"); + + if (formatInfo.dataInitializerFunction != nullptr) + { + const float clearValues[4] = {0.0f, 0.0f, 0.0f, 1.0f}; + mDeviceContext->ClearRenderTargetView(rtv.get(), clearValues); + } + + *outRT = new TextureRenderTarget11(std::move(rtv), texture, srv, blitSRV, format, + formatInfo, width, height, 1, supportedSamples); + } + else + { + UNREACHABLE(); + } + } + else + { + *outRT = new TextureRenderTarget11(d3d11::RenderTargetView(), TextureHelper11(), + d3d11::SharedSRV(), d3d11::SharedSRV(), format, + d3d11::Format::Get(GL_NONE, mRenderer11DeviceCaps), + width, height, 1, supportedSamples); + } + + return angle::Result::Continue; +} + +angle::Result Renderer11::createRenderTargetCopy(const gl::Context *context, + RenderTargetD3D *source, + RenderTargetD3D **outRT) +{ + ASSERT(source != nullptr); + + RenderTargetD3D *newRT = nullptr; + ANGLE_TRY(createRenderTarget(context, source->getWidth(), source->getHeight(), + source->getInternalFormat(), source->getSamples(), &newRT)); + + RenderTarget11 *source11 = GetAs(source); + RenderTarget11 *dest11 = GetAs(newRT); + + mDeviceContext->CopySubresourceRegion(dest11->getTexture().get(), dest11->getSubresourceIndex(), + 0, 0, 0, source11->getTexture().get(), + source11->getSubresourceIndex(), nullptr); + *outRT = newRT; + return angle::Result::Continue; +} + +angle::Result Renderer11::loadExecutable(d3d::Context *context, + const uint8_t *function, + size_t length, + gl::ShaderType type, + const std::vector &streamOutVaryings, + bool separatedOutputBuffers, + ShaderExecutableD3D **outExecutable) +{ + ShaderData shaderData(function, length); + + switch (type) + { + case gl::ShaderType::Vertex: + { + d3d11::VertexShader vertexShader; + d3d11::GeometryShader streamOutShader; + ANGLE_TRY(allocateResource(context, shaderData, &vertexShader)); + + if (!streamOutVaryings.empty()) + { + std::vector soDeclaration; + soDeclaration.reserve(streamOutVaryings.size()); + + for (const auto &streamOutVarying : streamOutVaryings) + { + D3D11_SO_DECLARATION_ENTRY entry = {}; + entry.Stream = 0; + entry.SemanticName = streamOutVarying.semanticName.c_str(); + entry.SemanticIndex = streamOutVarying.semanticIndex; + entry.StartComponent = 0; + entry.ComponentCount = static_cast(streamOutVarying.componentCount); + entry.OutputSlot = static_cast( + (separatedOutputBuffers ? streamOutVarying.outputSlot : 0)); + soDeclaration.push_back(entry); + } + + ANGLE_TRY(allocateResource(context, shaderData, &soDeclaration, &streamOutShader)); + } + + *outExecutable = new ShaderExecutable11(function, length, std::move(vertexShader), + std::move(streamOutShader)); + } + break; + case gl::ShaderType::Fragment: + { + d3d11::PixelShader pixelShader; + ANGLE_TRY(allocateResource(context, shaderData, &pixelShader)); + *outExecutable = new ShaderExecutable11(function, length, std::move(pixelShader)); + } + break; + case gl::ShaderType::Geometry: + { + d3d11::GeometryShader geometryShader; + ANGLE_TRY(allocateResource(context, shaderData, &geometryShader)); + *outExecutable = new ShaderExecutable11(function, length, std::move(geometryShader)); + } + break; + case gl::ShaderType::Compute: + { + d3d11::ComputeShader computeShader; + ANGLE_TRY(allocateResource(context, shaderData, &computeShader)); + *outExecutable = new ShaderExecutable11(function, length, std::move(computeShader)); + } + break; + default: + ANGLE_HR_UNREACHABLE(context); + } + + return angle::Result::Continue; +} + +angle::Result Renderer11::compileToExecutable(d3d::Context *context, + gl::InfoLog &infoLog, + const std::string &shaderHLSL, + gl::ShaderType type, + const std::vector &streamOutVaryings, + bool separatedOutputBuffers, + const CompilerWorkaroundsD3D &workarounds, + ShaderExecutableD3D **outExectuable) +{ + std::stringstream profileStream; + + switch (type) + { + case gl::ShaderType::Vertex: + profileStream << "vs"; + break; + case gl::ShaderType::Fragment: + profileStream << "ps"; + break; + case gl::ShaderType::Geometry: + profileStream << "gs"; + break; + case gl::ShaderType::Compute: + profileStream << "cs"; + break; + default: + ANGLE_HR_UNREACHABLE(context); + } + + profileStream << "_" << getMajorShaderModel() << "_" << getMinorShaderModel() + << getShaderModelSuffix(); + std::string profile = profileStream.str(); + + UINT flags = D3DCOMPILE_OPTIMIZATION_LEVEL2; + +#if defined(ANGLE_ENABLE_DEBUG_TRACE) +# ifndef NDEBUG + flags = D3DCOMPILE_SKIP_OPTIMIZATION; +# endif // NDEBUG + flags |= D3DCOMPILE_DEBUG; +#endif // defined(ANGLE_ENABLE_DEBUG_TRACE) + + if (workarounds.enableIEEEStrictness) + flags |= D3DCOMPILE_IEEE_STRICTNESS; + + // Sometimes D3DCompile will fail with the default compilation flags for complicated shaders + // when it would otherwise pass with alternative options. + // Try the default flags first and if compilation fails, try some alternatives. + std::vector configs; + configs.push_back(CompileConfig(flags, "default")); + configs.push_back(CompileConfig(flags | D3DCOMPILE_SKIP_VALIDATION, "skip validation")); + configs.push_back(CompileConfig(flags | D3DCOMPILE_SKIP_OPTIMIZATION, "skip optimization")); + + if (getMajorShaderModel() == 4 && getShaderModelSuffix() != "") + { + // Some shaders might cause a "blob content mismatch between level9 and d3d10 shader". + // e.g. dEQP-GLES2.functional.shaders.struct.local.loop_nested_struct_array_*. + // Using the [unroll] directive works around this, as does this D3DCompile flag. + configs.push_back( + CompileConfig(flags | D3DCOMPILE_AVOID_FLOW_CONTROL, "avoid flow control")); + } + + D3D_SHADER_MACRO loopMacros[] = {{"ANGLE_ENABLE_LOOP_FLATTEN", "1"}, {0, 0}}; + + // TODO(jmadill): Use ComPtr? + ID3DBlob *binary = nullptr; + std::string debugInfo; + ANGLE_TRY(mCompiler.compileToBinary(context, infoLog, shaderHLSL, profile, configs, loopMacros, + &binary, &debugInfo)); + + // It's possible that binary is NULL if the compiler failed in all configurations. Set the + // executable to NULL and return GL_NO_ERROR to signify that there was a link error but the + // internal state is still OK. + if (!binary) + { + *outExectuable = nullptr; + return angle::Result::Continue; + } + + angle::Result error = loadExecutable( + context, static_cast(binary->GetBufferPointer()), binary->GetBufferSize(), + type, streamOutVaryings, separatedOutputBuffers, outExectuable); + + SafeRelease(binary); + if (error == angle::Result::Stop) + { + return error; + } + + if (!debugInfo.empty()) + { + (*outExectuable)->appendDebugInfo(debugInfo); + } + + return angle::Result::Continue; +} + +angle::Result Renderer11::ensureHLSLCompilerInitialized(d3d::Context *context) +{ + return mCompiler.ensureInitialized(context); +} + +UniformStorageD3D *Renderer11::createUniformStorage(size_t storageSize) +{ + return new UniformStorage11(storageSize); +} + +VertexBuffer *Renderer11::createVertexBuffer() +{ + return new VertexBuffer11(this); +} + +IndexBuffer *Renderer11::createIndexBuffer() +{ + return new IndexBuffer11(this); +} + +StreamProducerImpl *Renderer11::createStreamProducerD3DTexture( + egl::Stream::ConsumerType consumerType, + const egl::AttributeMap &attribs) +{ + return new StreamProducerD3DTexture(this); +} + +bool Renderer11::supportsFastCopyBufferToTexture(GLenum internalFormat) const +{ + ASSERT(getNativeExtensions().pixelBufferObjectNV); + + const gl::InternalFormat &internalFormatInfo = gl::GetSizedInternalFormatInfo(internalFormat); + const d3d11::Format &d3d11FormatInfo = + d3d11::Format::Get(internalFormat, mRenderer11DeviceCaps); + + // sRGB formats do not work with D3D11 buffer SRVs + if (internalFormatInfo.colorEncoding == GL_SRGB) + { + return false; + } + + // We cannot support direct copies to non-color-renderable formats + if (d3d11FormatInfo.rtvFormat == DXGI_FORMAT_UNKNOWN) + { + return false; + } + + // We skip all 3-channel formats since sometimes format support is missing + if (internalFormatInfo.componentCount == 3) + { + return false; + } + + // We don't support formats which we can't represent without conversion + if (d3d11FormatInfo.format().glInternalFormat != internalFormat) + { + return false; + } + + // Buffer SRV creation for this format was not working on Windows 10. + if (d3d11FormatInfo.texFormat == DXGI_FORMAT_B5G5R5A1_UNORM) + { + return false; + } + + // This format is not supported as a buffer SRV. + if (d3d11FormatInfo.texFormat == DXGI_FORMAT_A8_UNORM) + { + return false; + } + + return true; +} + +angle::Result Renderer11::fastCopyBufferToTexture(const gl::Context *context, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + unsigned int offset, + RenderTargetD3D *destRenderTarget, + GLenum destinationFormat, + GLenum sourcePixelsType, + const gl::Box &destArea) +{ + ASSERT(supportsFastCopyBufferToTexture(destinationFormat)); + return mPixelTransfer->copyBufferToTexture(context, unpack, unpackBuffer, offset, + destRenderTarget, destinationFormat, + sourcePixelsType, destArea); +} + +ImageD3D *Renderer11::createImage() +{ + return new Image11(this); +} + +ExternalImageSiblingImpl *Renderer11::createExternalImageSibling(const gl::Context *context, + EGLenum target, + EGLClientBuffer buffer, + const egl::AttributeMap &attribs) +{ + switch (target) + { + case EGL_D3D11_TEXTURE_ANGLE: + return new ExternalImageSiblingImpl11(this, buffer, attribs); + + default: + UNREACHABLE(); + return nullptr; + } +} + +angle::Result Renderer11::generateMipmap(const gl::Context *context, ImageD3D *dest, ImageD3D *src) +{ + Image11 *dest11 = GetAs(dest); + Image11 *src11 = GetAs(src); + return Image11::GenerateMipmap(context, dest11, src11, mRenderer11DeviceCaps); +} + +angle::Result Renderer11::generateMipmapUsingD3D(const gl::Context *context, + TextureStorage *storage, + const gl::TextureState &textureState) +{ + TextureStorage11 *storage11 = GetAs(storage); + + ASSERT(storage11->isRenderTarget()); + ASSERT(storage11->supportsNativeMipmapFunction()); + + const d3d11::SharedSRV *srv = nullptr; + ANGLE_TRY(storage11->getSRVLevels(context, textureState.getEffectiveBaseLevel(), + textureState.getEffectiveMaxLevel(), &srv)); + + mDeviceContext->GenerateMips(srv->get()); + + return angle::Result::Continue; +} + +angle::Result Renderer11::copyImage(const gl::Context *context, + ImageD3D *dest, + ImageD3D *source, + const gl::Box &sourceBox, + const gl::Offset &destOffset, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) +{ + Image11 *dest11 = GetAs(dest); + Image11 *src11 = GetAs(source); + return Image11::CopyImage(context, dest11, src11, sourceBox, destOffset, unpackFlipY, + unpackPremultiplyAlpha, unpackUnmultiplyAlpha, mRenderer11DeviceCaps); +} + +TextureStorage *Renderer11::createTextureStorage2D(SwapChainD3D *swapChain, + const std::string &label) +{ + SwapChain11 *swapChain11 = GetAs(swapChain); + return new TextureStorage11_2D(this, swapChain11, label); +} + +TextureStorage *Renderer11::createTextureStorageEGLImage(EGLImageD3D *eglImage, + RenderTargetD3D *renderTargetD3D, + const std::string &label) +{ + return new TextureStorage11_EGLImage(this, eglImage, GetAs(renderTargetD3D), + label); +} + +TextureStorage *Renderer11::createTextureStorageExternal( + egl::Stream *stream, + const egl::Stream::GLTextureDescription &desc, + const std::string &label) +{ + return new TextureStorage11_External(this, stream, desc, label); +} + +TextureStorage *Renderer11::createTextureStorage2D(GLenum internalformat, + BindFlags bindFlags, + GLsizei width, + GLsizei height, + int levels, + const std::string &label, + bool hintLevelZeroOnly) +{ + return new TextureStorage11_2D(this, internalformat, bindFlags, width, height, levels, label, + hintLevelZeroOnly); +} + +TextureStorage *Renderer11::createTextureStorageCube(GLenum internalformat, + BindFlags bindFlags, + int size, + int levels, + bool hintLevelZeroOnly, + const std::string &label) +{ + return new TextureStorage11_Cube(this, internalformat, bindFlags, size, levels, + hintLevelZeroOnly, label); +} + +TextureStorage *Renderer11::createTextureStorage3D(GLenum internalformat, + BindFlags bindFlags, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels, + const std::string &label) +{ + return new TextureStorage11_3D(this, internalformat, bindFlags, width, height, depth, levels, + label); +} + +TextureStorage *Renderer11::createTextureStorage2DArray(GLenum internalformat, + BindFlags bindFlags, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels, + const std::string &label) +{ + return new TextureStorage11_2DArray(this, internalformat, bindFlags, width, height, depth, + levels, label); +} + +TextureStorage *Renderer11::createTextureStorage2DMultisample(GLenum internalformat, + GLsizei width, + GLsizei height, + int levels, + int samples, + bool fixedSampleLocations, + const std::string &label) +{ + return new TextureStorage11_2DMultisample(this, internalformat, width, height, levels, samples, + fixedSampleLocations, label); +} + +TextureStorage *Renderer11::createTextureStorageBuffer( + const gl::OffsetBindingPointer &buffer, + GLenum internalFormat, + const std::string &label) +{ + return new TextureStorage11_Buffer(this, buffer, internalFormat, label); +} + +TextureStorage *Renderer11::createTextureStorage2DMultisampleArray(GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels, + int samples, + bool fixedSampleLocations, + const std::string &label) +{ + return new TextureStorage11_2DMultisampleArray(this, internalformat, width, height, depth, + levels, samples, fixedSampleLocations, label); +} + +angle::Result Renderer11::readFromAttachment(const gl::Context *context, + const gl::FramebufferAttachment &srcAttachment, + const gl::Rectangle &sourceArea, + GLenum format, + GLenum type, + GLuint outputPitch, + const gl::PixelPackState &pack, + uint8_t *pixelsOut) +{ + ASSERT(sourceArea.width >= 0); + ASSERT(sourceArea.height >= 0); + + const bool invertTexture = UsePresentPathFast(this, &srcAttachment); + + RenderTarget11 *rt11 = nullptr; + ANGLE_TRY(srcAttachment.getRenderTarget(context, 0, &rt11)); + ASSERT(rt11->getTexture().valid()); + + const TextureHelper11 &textureHelper = rt11->getTexture(); + unsigned int sourceSubResource = rt11->getSubresourceIndex(); + + const gl::Extents &texSize = textureHelper.getExtents(); + + gl::Rectangle actualArea = sourceArea; + bool reverseRowOrder = pack.reverseRowOrder; + if (invertTexture) + { + actualArea.y = texSize.height - actualArea.y - actualArea.height; + reverseRowOrder = !reverseRowOrder; + } + + // Clamp read region to the defined texture boundaries, preventing out of bounds reads + // and reads of uninitialized data. + gl::Rectangle safeArea; + safeArea.x = gl::clamp(actualArea.x, 0, texSize.width); + safeArea.y = gl::clamp(actualArea.y, 0, texSize.height); + safeArea.width = + gl::clamp(actualArea.width + std::min(actualArea.x, 0), 0, texSize.width - safeArea.x); + safeArea.height = + gl::clamp(actualArea.height + std::min(actualArea.y, 0), 0, texSize.height - safeArea.y); + + ASSERT(safeArea.x >= 0 && safeArea.y >= 0); + ASSERT(safeArea.x + safeArea.width <= texSize.width); + ASSERT(safeArea.y + safeArea.height <= texSize.height); + + if (safeArea.width == 0 || safeArea.height == 0) + { + // no work to do + return angle::Result::Continue; + } + + gl::Extents safeSize(safeArea.width, safeArea.height, 1); + TextureHelper11 stagingHelper; + ANGLE_TRY(createStagingTexture(context, textureHelper.getTextureType(), + textureHelper.getFormatSet(), safeSize, StagingAccess::READ, + &stagingHelper)); + stagingHelper.setInternalName("readFromAttachment::stagingHelper"); + + TextureHelper11 resolvedTextureHelper; + + // "srcTexture" usually points to the source texture. + // For 2D multisampled textures, it points to the multisampled resolve texture. + const TextureHelper11 *srcTexture = &textureHelper; + + if (textureHelper.is2D() && textureHelper.getSampleCount() > 1) + { + D3D11_TEXTURE2D_DESC resolveDesc; + resolveDesc.Width = static_cast(texSize.width); + resolveDesc.Height = static_cast(texSize.height); + resolveDesc.MipLevels = 1; + resolveDesc.ArraySize = 1; + resolveDesc.Format = textureHelper.getFormat(); + resolveDesc.SampleDesc.Count = 1; + resolveDesc.SampleDesc.Quality = 0; + resolveDesc.Usage = D3D11_USAGE_DEFAULT; + resolveDesc.BindFlags = 0; + resolveDesc.CPUAccessFlags = 0; + resolveDesc.MiscFlags = 0; + + ANGLE_TRY(allocateTexture(GetImplAs(context), resolveDesc, + textureHelper.getFormatSet(), &resolvedTextureHelper)); + resolvedTextureHelper.setInternalName("readFromAttachment::resolvedTextureHelper"); + + mDeviceContext->ResolveSubresource(resolvedTextureHelper.get(), 0, textureHelper.get(), + sourceSubResource, textureHelper.getFormat()); + + sourceSubResource = 0; + srcTexture = &resolvedTextureHelper; + } + + D3D11_BOX srcBox; + srcBox.left = static_cast(safeArea.x); + srcBox.right = static_cast(safeArea.x + safeArea.width); + srcBox.top = static_cast(safeArea.y); + srcBox.bottom = static_cast(safeArea.y + safeArea.height); + + // Select the correct layer from a 3D attachment + srcBox.front = 0; + if (textureHelper.is3D()) + { + srcBox.front = static_cast(srcAttachment.layer()); + } + srcBox.back = srcBox.front + 1; + + mDeviceContext->CopySubresourceRegion(stagingHelper.get(), 0, 0, 0, 0, srcTexture->get(), + sourceSubResource, &srcBox); + + const angle::Format &angleFormat = GetFormatFromFormatType(format, type); + gl::Buffer *packBuffer = context->getState().getTargetBuffer(gl::BufferBinding::PixelPack); + + PackPixelsParams packParams(safeArea, angleFormat, outputPitch, reverseRowOrder, packBuffer, 0); + return packPixels(context, stagingHelper, packParams, pixelsOut); +} + +angle::Result Renderer11::packPixels(const gl::Context *context, + const TextureHelper11 &textureHelper, + const PackPixelsParams ¶ms, + uint8_t *pixelsOut) +{ + ID3D11Resource *readResource = textureHelper.get(); + + D3D11_MAPPED_SUBRESOURCE mapping; + ANGLE_TRY(mapResource(context, readResource, 0, D3D11_MAP_READ, 0, &mapping)); + + uint8_t *source = static_cast(mapping.pData); + int inputPitch = static_cast(mapping.RowPitch); + + const auto &formatInfo = textureHelper.getFormatSet(); + ASSERT(formatInfo.format().glInternalFormat != GL_NONE); + + PackPixels(params, formatInfo.format(), inputPitch, source, pixelsOut); + + mDeviceContext->Unmap(readResource, 0); + + return angle::Result::Continue; +} + +angle::Result Renderer11::blitRenderbufferRect(const gl::Context *context, + const gl::Rectangle &readRectIn, + const gl::Rectangle &drawRectIn, + UINT readLayer, + UINT drawLayer, + RenderTargetD3D *readRenderTarget, + RenderTargetD3D *drawRenderTarget, + GLenum filter, + const gl::Rectangle *scissor, + bool colorBlit, + bool depthBlit, + bool stencilBlit) +{ + // Since blitRenderbufferRect is called for each render buffer that needs to be blitted, + // it should never be the case that both color and depth/stencil need to be blitted at + // at the same time. + ASSERT(colorBlit != (depthBlit || stencilBlit)); + + RenderTarget11 *drawRenderTarget11 = GetAs(drawRenderTarget); + ASSERT(drawRenderTarget11); + + const TextureHelper11 &drawTexture = drawRenderTarget11->getTexture(); + unsigned int drawSubresource = drawRenderTarget11->getSubresourceIndex(); + + RenderTarget11 *readRenderTarget11 = GetAs(readRenderTarget); + ASSERT(readRenderTarget11); + + const gl::Extents readSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1); + const gl::Extents drawSize(drawRenderTarget->getWidth(), drawRenderTarget->getHeight(), 1); + + // From the spec: + // "The actual region taken from the read framebuffer is limited to the intersection of the + // source buffers being transferred, which may include the color buffer selected by the read + // buffer, the depth buffer, and / or the stencil buffer depending on mask." + // This means negative x and y are out of bounds, and not to be read from. We handle this here + // by internally scaling the read and draw rectangles. + + // Remove reversal from readRect to simplify further operations. + gl::Rectangle readRect = readRectIn; + gl::Rectangle drawRect = drawRectIn; + if (readRect.isReversedX()) + { + readRect.x = readRect.x + readRect.width; + readRect.width = -readRect.width; + drawRect.x = drawRect.x + drawRect.width; + drawRect.width = -drawRect.width; + } + if (readRect.isReversedY()) + { + readRect.y = readRect.y + readRect.height; + readRect.height = -readRect.height; + drawRect.y = drawRect.y + drawRect.height; + drawRect.height = -drawRect.height; + } + + gl::Rectangle readBounds(0, 0, readSize.width, readSize.height); + gl::Rectangle inBoundsReadRect; + if (!gl::ClipRectangle(readRect, readBounds, &inBoundsReadRect)) + { + return angle::Result::Continue; + } + + { + // Calculate the drawRect that corresponds to inBoundsReadRect. + auto readToDrawX = [&drawRect, &readRect](int readOffset) { + double readToDrawScale = + static_cast(drawRect.width) / static_cast(readRect.width); + return static_cast( + round(static_cast(readOffset - readRect.x) * readToDrawScale) + drawRect.x); + }; + auto readToDrawY = [&drawRect, &readRect](int readOffset) { + double readToDrawScale = + static_cast(drawRect.height) / static_cast(readRect.height); + return static_cast( + round(static_cast(readOffset - readRect.y) * readToDrawScale) + drawRect.y); + }; + + gl::Rectangle drawRectMatchingInBoundsReadRect; + drawRectMatchingInBoundsReadRect.x = readToDrawX(inBoundsReadRect.x); + drawRectMatchingInBoundsReadRect.y = readToDrawY(inBoundsReadRect.y); + drawRectMatchingInBoundsReadRect.width = + readToDrawX(inBoundsReadRect.x1()) - drawRectMatchingInBoundsReadRect.x; + drawRectMatchingInBoundsReadRect.height = + readToDrawY(inBoundsReadRect.y1()) - drawRectMatchingInBoundsReadRect.y; + drawRect = drawRectMatchingInBoundsReadRect; + readRect = inBoundsReadRect; + } + + bool scissorNeeded = false; + if (scissor) + { + gl::Rectangle scissoredDrawRect; + if (!gl::ClipRectangle(drawRect, *scissor, &scissoredDrawRect)) + { + return angle::Result::Continue; + } + scissorNeeded = scissoredDrawRect != drawRect; + } + + const auto &destFormatInfo = + gl::GetSizedInternalFormatInfo(drawRenderTarget->getInternalFormat()); + const auto &srcFormatInfo = + gl::GetSizedInternalFormatInfo(readRenderTarget->getInternalFormat()); + const auto &formatSet = drawRenderTarget11->getFormatSet(); + const auto &nativeFormat = formatSet.format(); + + // Some blits require masking off emulated texture channels. eg: from RGBA8 to RGB8, we + // emulate RGB8 with RGBA8, so we need to mask off the alpha channel when we copy. + + gl::Color colorMask; + colorMask.red = + (srcFormatInfo.redBits > 0) && (destFormatInfo.redBits == 0) && (nativeFormat.redBits > 0); + colorMask.green = (srcFormatInfo.greenBits > 0) && (destFormatInfo.greenBits == 0) && + (nativeFormat.greenBits > 0); + colorMask.blue = (srcFormatInfo.blueBits > 0) && (destFormatInfo.blueBits == 0) && + (nativeFormat.blueBits > 0); + colorMask.alpha = (srcFormatInfo.alphaBits > 0) && (destFormatInfo.alphaBits == 0) && + (nativeFormat.alphaBits > 0); + + // We only currently support masking off the alpha channel. + bool colorMaskingNeeded = colorMask.alpha; + ASSERT(!colorMask.red && !colorMask.green && !colorMask.blue); + + bool wholeBufferCopy = !scissorNeeded && !colorMaskingNeeded && readRect.x == 0 && + readRect.width == readSize.width && readRect.y == 0 && + readRect.height == readSize.height && drawRect.x == 0 && + drawRect.width == drawSize.width && drawRect.y == 0 && + drawRect.height == drawSize.height; + + bool stretchRequired = readRect.width != drawRect.width || readRect.height != drawRect.height; + + ASSERT(!readRect.isReversedX() && !readRect.isReversedY()); + bool reversalRequired = drawRect.isReversedX() || drawRect.isReversedY(); + + bool outOfBounds = readRect.x < 0 || readRect.x + readRect.width > readSize.width || + readRect.y < 0 || readRect.y + readRect.height > readSize.height || + drawRect.x < 0 || drawRect.x + drawRect.width > drawSize.width || + drawRect.y < 0 || drawRect.y + drawRect.height > drawSize.height; + + bool partialDSBlit = + (nativeFormat.depthBits > 0 && depthBlit) != (nativeFormat.stencilBits > 0 && stencilBlit); + + const bool canCopySubresource = + drawRenderTarget->getSamples() == readRenderTarget->getSamples() && + readRenderTarget11->getFormatSet().formatID == + drawRenderTarget11->getFormatSet().formatID && + !stretchRequired && !outOfBounds && !reversalRequired && !partialDSBlit && + !colorMaskingNeeded && (!(depthBlit || stencilBlit) || wholeBufferCopy); + + TextureHelper11 readTexture; + unsigned int readSubresource = 0; + d3d11::SharedSRV readSRV; + + if (readRenderTarget->isMultisampled()) + { + ANGLE_TRY(resolveMultisampledTexture(context, readRenderTarget11, depthBlit, stencilBlit, + &readTexture)); + + if (!stencilBlit && !canCopySubresource) + { + const auto &readFormatSet = readTexture.getFormatSet(); + + D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc; + viewDesc.Format = readFormatSet.srvFormat; + viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + viewDesc.Texture2D.MipLevels = 1; + viewDesc.Texture2D.MostDetailedMip = 0; + + ANGLE_TRY(allocateResource(GetImplAs(context), viewDesc, readTexture.get(), + &readSRV)); + } + } + else + { + ASSERT(readRenderTarget11); + readTexture = readRenderTarget11->getTexture(); + readSubresource = readRenderTarget11->getSubresourceIndex(); + if (!canCopySubresource) + { + const d3d11::SharedSRV *blitSRV; + ANGLE_TRY(readRenderTarget11->getBlitShaderResourceView(context, &blitSRV)); + readSRV = blitSRV->makeCopy(); + if (!readSRV.valid()) + { + ASSERT(depthBlit || stencilBlit); + const d3d11::SharedSRV *srv; + ANGLE_TRY(readRenderTarget11->getShaderResourceView(context, &srv)); + readSRV = srv->makeCopy(); + } + ASSERT(readSRV.valid()); + } + } + + if (canCopySubresource) + { + UINT dstX = drawRect.x; + UINT dstY = drawRect.y; + UINT dstZ = drawLayer; + + D3D11_BOX readBox; + readBox.left = readRect.x; + readBox.right = readRect.x + readRect.width; + readBox.top = readRect.y; + readBox.bottom = readRect.y + readRect.height; + readBox.front = readLayer; + readBox.back = readLayer + 1; + + if (scissorNeeded) + { + // drawRect is guaranteed to have positive width and height because stretchRequired is + // false. + ASSERT(drawRect.width >= 0 || drawRect.height >= 0); + + if (drawRect.x < scissor->x) + { + dstX = scissor->x; + readBox.left += (scissor->x - drawRect.x); + } + if (drawRect.y < scissor->y) + { + dstY = scissor->y; + readBox.top += (scissor->y - drawRect.y); + } + if (drawRect.x + drawRect.width > scissor->x + scissor->width) + { + readBox.right -= ((drawRect.x + drawRect.width) - (scissor->x + scissor->width)); + } + if (drawRect.y + drawRect.height > scissor->y + scissor->height) + { + readBox.bottom -= ((drawRect.y + drawRect.height) - (scissor->y + scissor->height)); + } + } + + // D3D11 needs depth-stencil CopySubresourceRegions to have a NULL pSrcBox + // We also require complete framebuffer copies for depth-stencil blit. + D3D11_BOX *pSrcBox = wholeBufferCopy && readLayer == 0 ? nullptr : &readBox; + + mDeviceContext->CopySubresourceRegion(drawTexture.get(), drawSubresource, dstX, dstY, dstZ, + readTexture.get(), readSubresource, pSrcBox); + } + else + { + gl::Box readArea(readRect.x, readRect.y, 0, readRect.width, readRect.height, 1); + gl::Box drawArea(drawRect.x, drawRect.y, 0, drawRect.width, drawRect.height, 1); + + if (depthBlit && stencilBlit) + { + ANGLE_TRY(mBlit->copyDepthStencil(context, readTexture, readSubresource, readArea, + readSize, drawTexture, drawSubresource, drawArea, + drawSize, scissor)); + } + else if (depthBlit) + { + const d3d11::DepthStencilView &drawDSV = drawRenderTarget11->getDepthStencilView(); + ASSERT(readSRV.valid()); + ANGLE_TRY(mBlit->copyDepth(context, readSRV, readArea, readSize, drawDSV, drawArea, + drawSize, scissor)); + } + else if (stencilBlit) + { + ANGLE_TRY(mBlit->copyStencil(context, readTexture, readSubresource, readArea, readSize, + drawTexture, drawSubresource, drawArea, drawSize, + scissor)); + } + else + { + const d3d11::RenderTargetView &drawRTV = drawRenderTarget11->getRenderTargetView(); + + // We don't currently support masking off any other channel than alpha + bool maskOffAlpha = colorMaskingNeeded && colorMask.alpha; + ASSERT(readSRV.valid()); + ANGLE_TRY(mBlit->copyTexture(context, readSRV, readArea, readSize, srcFormatInfo.format, + drawRTV, drawArea, drawSize, scissor, + destFormatInfo.format, GL_NONE, filter, maskOffAlpha, + false, false)); + } + } + + return angle::Result::Continue; +} + +bool Renderer11::isES3Capable() const +{ + return (d3d11_gl::GetMaximumClientVersion(mRenderer11DeviceCaps).major > 2); +} + +RendererClass Renderer11::getRendererClass() const +{ + return RENDERER_D3D11; +} + +void Renderer11::onSwap() +{ + // Send histogram updates every half hour + const double kHistogramUpdateInterval = 30 * 60; + + auto *platform = ANGLEPlatformCurrent(); + const double currentTime = platform->monotonicallyIncreasingTime(platform); + const double timeSinceLastUpdate = currentTime - mLastHistogramUpdateTime; + + if (timeSinceLastUpdate > kHistogramUpdateInterval) + { + updateHistograms(); + mLastHistogramUpdateTime = currentTime; + } +} + +void Renderer11::updateHistograms() +{ + // Update the buffer CPU memory histogram + { + size_t sizeSum = 0; + for (const Buffer11 *buffer : mAliveBuffers) + { + sizeSum += buffer->getTotalCPUBufferMemoryBytes(); + } + const int kOneMegaByte = 1024 * 1024; + ANGLE_HISTOGRAM_MEMORY_MB("GPU.ANGLE.Buffer11CPUMemoryMB", + static_cast(sizeSum) / kOneMegaByte); + } +} + +void Renderer11::onBufferCreate(const Buffer11 *created) +{ + mAliveBuffers.insert(created); +} + +void Renderer11::onBufferDelete(const Buffer11 *deleted) +{ + mAliveBuffers.erase(deleted); +} + +angle::Result Renderer11::resolveMultisampledTexture(const gl::Context *context, + RenderTarget11 *renderTarget, + bool depth, + bool stencil, + TextureHelper11 *textureOut) +{ + if (depth && !stencil) + { + return mBlit->resolveDepth(context, renderTarget, textureOut); + } + + if (stencil) + { + return mBlit->resolveStencil(context, renderTarget, depth, textureOut); + } + + const auto &formatSet = renderTarget->getFormatSet(); + + ASSERT(renderTarget->isMultisampled()); + const d3d11::SharedSRV *sourceSRV; + ANGLE_TRY(renderTarget->getShaderResourceView(context, &sourceSRV)); + D3D11_SHADER_RESOURCE_VIEW_DESC sourceSRVDesc; + sourceSRV->get()->GetDesc(&sourceSRVDesc); + ASSERT(sourceSRVDesc.ViewDimension == D3D_SRV_DIMENSION_TEXTURE2DMS || + sourceSRVDesc.ViewDimension == D3D_SRV_DIMENSION_TEXTURE2DMSARRAY); + + if (!mCachedResolveTexture.valid() || + mCachedResolveTexture.getExtents().width != renderTarget->getWidth() || + mCachedResolveTexture.getExtents().height != renderTarget->getHeight() || + mCachedResolveTexture.getFormat() != formatSet.texFormat) + { + D3D11_TEXTURE2D_DESC resolveDesc; + resolveDesc.Width = renderTarget->getWidth(); + resolveDesc.Height = renderTarget->getHeight(); + resolveDesc.MipLevels = 1; + resolveDesc.ArraySize = 1; + resolveDesc.Format = formatSet.texFormat; + resolveDesc.SampleDesc.Count = 1; + resolveDesc.SampleDesc.Quality = 0; + resolveDesc.Usage = D3D11_USAGE_DEFAULT; + resolveDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + resolveDesc.CPUAccessFlags = 0; + resolveDesc.MiscFlags = 0; + + ANGLE_TRY(allocateTexture(GetImplAs(context), resolveDesc, formatSet, + &mCachedResolveTexture)); + } + + mDeviceContext->ResolveSubresource(mCachedResolveTexture.get(), 0, + renderTarget->getTexture().get(), + renderTarget->getSubresourceIndex(), formatSet.texFormat); + *textureOut = mCachedResolveTexture; + return angle::Result::Continue; +} + +bool Renderer11::getLUID(LUID *adapterLuid) const +{ + adapterLuid->HighPart = 0; + adapterLuid->LowPart = 0; + + if (!mDxgiAdapter) + { + return false; + } + + DXGI_ADAPTER_DESC adapterDesc; + if (FAILED(mDxgiAdapter->GetDesc(&adapterDesc))) + { + return false; + } + + *adapterLuid = adapterDesc.AdapterLuid; + return true; +} + +VertexConversionType Renderer11::getVertexConversionType(angle::FormatID vertexFormatID) const +{ + return d3d11::GetVertexFormatInfo(vertexFormatID, mRenderer11DeviceCaps.featureLevel) + .conversionType; +} + +GLenum Renderer11::getVertexComponentType(angle::FormatID vertexFormatID) const +{ + const auto &format = + d3d11::GetVertexFormatInfo(vertexFormatID, mRenderer11DeviceCaps.featureLevel); + return d3d11::GetComponentType(format.nativeFormat); +} + +angle::Result Renderer11::getVertexSpaceRequired(const gl::Context *context, + const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + size_t count, + GLsizei instances, + GLuint baseInstance, + unsigned int *bytesRequiredOut) const +{ + if (!attrib.enabled) + { + *bytesRequiredOut = 16u; + return angle::Result::Continue; + } + + unsigned int elementCount = 0; + const unsigned int divisor = binding.getDivisor(); + if (instances == 0 || divisor == 0) + { + // This could be a clipped cast. + elementCount = gl::clampCast(count); + } + else + { + // Round up to divisor, if possible + elementCount = + UnsignedCeilDivide(static_cast(instances + baseInstance), divisor); + } + + ASSERT(elementCount > 0); + + const D3D_FEATURE_LEVEL featureLevel = mRenderer11DeviceCaps.featureLevel; + const d3d11::VertexFormat &vertexFormatInfo = + d3d11::GetVertexFormatInfo(attrib.format->id, featureLevel); + const d3d11::DXGIFormatSize &dxgiFormatInfo = + d3d11::GetDXGIFormatSizeInfo(vertexFormatInfo.nativeFormat); + unsigned int elementSize = dxgiFormatInfo.pixelBytes; + bool check = (elementSize > std::numeric_limits::max() / elementCount); + ANGLE_CHECK(GetImplAs(context), !check, + "New vertex buffer size would result in an overflow.", GL_OUT_OF_MEMORY); + + *bytesRequiredOut = elementSize * elementCount; + return angle::Result::Continue; +} + +void Renderer11::generateCaps(gl::Caps *outCaps, + gl::TextureCapsMap *outTextureCaps, + gl::Extensions *outExtensions, + gl::Limitations *outLimitations) const +{ + d3d11_gl::GenerateCaps(mDevice, mDeviceContext, mRenderer11DeviceCaps, getFeatures(), + mDescription, outCaps, outTextureCaps, outExtensions, outLimitations); +} + +void Renderer11::initializeFeatures(angle::FeaturesD3D *features) const +{ + if (!mDisplay->getState().featuresAllDisabled) + { + d3d11::InitializeFeatures(mRenderer11DeviceCaps, mAdapterDescription, features); + } + ApplyFeatureOverrides(features, mDisplay->getState()); +} + +void Renderer11::initializeFrontendFeatures(angle::FrontendFeatures *features) const +{ + if (!mDisplay->getState().featuresAllDisabled) + { + d3d11::InitializeFrontendFeatures(mAdapterDescription, features); + } + ApplyFeatureOverrides(features, mDisplay->getState()); +} + +DeviceImpl *Renderer11::createEGLDevice() +{ + return new DeviceD3D(EGL_D3D11_DEVICE_ANGLE, mDevice); +} + +ContextImpl *Renderer11::createContext(const gl::State &state, gl::ErrorSet *errorSet) +{ + return new Context11(state, errorSet, this); +} + +FramebufferImpl *Renderer11::createDefaultFramebuffer(const gl::FramebufferState &state) +{ + return new Framebuffer11(state, this); +} + +angle::Result Renderer11::getScratchMemoryBuffer(Context11 *context11, + size_t requestedSize, + angle::MemoryBuffer **bufferOut) +{ + ANGLE_CHECK_GL_ALLOC(context11, mScratchMemoryBuffer.get(requestedSize, bufferOut)); + return angle::Result::Continue; +} + +gl::Version Renderer11::getMaxSupportedESVersion() const +{ + return d3d11_gl::GetMaximumClientVersion(mRenderer11DeviceCaps); +} + +gl::Version Renderer11::getMaxConformantESVersion() const +{ + // 3.1 support is in progress. + return std::min(getMaxSupportedESVersion(), gl::Version(3, 0)); +} + +DebugAnnotatorContext11 *Renderer11::getDebugAnnotatorContext() +{ + return &mAnnotatorContext; +} + +angle::Result Renderer11::dispatchCompute(const gl::Context *context, + GLuint numGroupsX, + GLuint numGroupsY, + GLuint numGroupsZ) +{ + const gl::State &glState = context->getState(); + const gl::Program *program = glState.getProgram(); + if (program->getActiveShaderStorageBlockCount() > 0 || + program->getActiveAtomicCounterBufferCount() > 0) + { + ANGLE_TRY(markRawBufferUsage(context)); + } + ANGLE_TRY(markTypedBufferUsage(context)); + ANGLE_TRY(mStateManager.updateStateForCompute(context, numGroupsX, numGroupsY, numGroupsZ)); + mDeviceContext->Dispatch(numGroupsX, numGroupsY, numGroupsZ); + + return angle::Result::Continue; +} +angle::Result Renderer11::dispatchComputeIndirect(const gl::Context *context, GLintptr indirect) +{ + const auto &glState = context->getState(); + const gl::Program *program = glState.getProgram(); + if (program->getActiveShaderStorageBlockCount() > 0 || + program->getActiveAtomicCounterBufferCount() > 0) + { + ANGLE_TRY(markRawBufferUsage(context)); + } + + auto *dispatchIndirectBuffer = glState.getTargetBuffer(gl::BufferBinding::DispatchIndirect); + ASSERT(dispatchIndirectBuffer); + + Buffer11 *storage = GetImplAs(dispatchIndirectBuffer); + const uint8_t *bufferData = nullptr; + // TODO(jie.a.chen@intel.com): num_groups_x,y,z have to be written into the driver constant + // buffer for the built-in variable gl_NumWorkGroups. There is an opportunity for optimization + // to use GPU->GPU copy instead. + // http://anglebug.com/2807 + ANGLE_TRY(storage->getData(context, &bufferData)); + const GLuint *groups = reinterpret_cast(bufferData + indirect); + ANGLE_TRY(mStateManager.updateStateForCompute(context, groups[0], groups[1], groups[2])); + + ID3D11Buffer *buffer = nullptr; + ANGLE_TRY(storage->getBuffer(context, BUFFER_USAGE_INDIRECT, &buffer)); + + mDeviceContext->DispatchIndirect(buffer, static_cast(indirect)); + return angle::Result::Continue; +} + +angle::Result Renderer11::createStagingTexture(const gl::Context *context, + ResourceType textureType, + const d3d11::Format &formatSet, + const gl::Extents &size, + StagingAccess readAndWriteAccess, + TextureHelper11 *textureOut) +{ + Context11 *context11 = GetImplAs(context); + + if (textureType == ResourceType::Texture2D) + { + D3D11_TEXTURE2D_DESC stagingDesc; + stagingDesc.Width = size.width; + stagingDesc.Height = size.height; + stagingDesc.MipLevels = 1; + stagingDesc.ArraySize = 1; + stagingDesc.Format = formatSet.texFormat; + stagingDesc.SampleDesc.Count = 1; + stagingDesc.SampleDesc.Quality = 0; + stagingDesc.Usage = D3D11_USAGE_STAGING; + stagingDesc.BindFlags = 0; + stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + stagingDesc.MiscFlags = 0; + + if (readAndWriteAccess == StagingAccess::READ_WRITE) + { + stagingDesc.CPUAccessFlags |= D3D11_CPU_ACCESS_WRITE; + } + + ANGLE_TRY(allocateTexture(context11, stagingDesc, formatSet, textureOut)); + return angle::Result::Continue; + } + ASSERT(textureType == ResourceType::Texture3D); + + D3D11_TEXTURE3D_DESC stagingDesc; + stagingDesc.Width = size.width; + stagingDesc.Height = size.height; + stagingDesc.Depth = 1; + stagingDesc.MipLevels = 1; + stagingDesc.Format = formatSet.texFormat; + stagingDesc.Usage = D3D11_USAGE_STAGING; + stagingDesc.BindFlags = 0; + stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + stagingDesc.MiscFlags = 0; + + ANGLE_TRY(allocateTexture(context11, stagingDesc, formatSet, textureOut)); + return angle::Result::Continue; +} + +angle::Result Renderer11::allocateTexture(d3d::Context *context, + const D3D11_TEXTURE2D_DESC &desc, + const d3d11::Format &format, + const D3D11_SUBRESOURCE_DATA *initData, + TextureHelper11 *textureOut) +{ + d3d11::Texture2D texture; + ANGLE_TRY(mResourceManager11.allocate(context, this, &desc, initData, &texture)); + textureOut->init(std::move(texture), desc, format); + return angle::Result::Continue; +} + +angle::Result Renderer11::allocateTexture(d3d::Context *context, + const D3D11_TEXTURE3D_DESC &desc, + const d3d11::Format &format, + const D3D11_SUBRESOURCE_DATA *initData, + TextureHelper11 *textureOut) +{ + d3d11::Texture3D texture; + ANGLE_TRY(mResourceManager11.allocate(context, this, &desc, initData, &texture)); + textureOut->init(std::move(texture), desc, format); + return angle::Result::Continue; +} + +angle::Result Renderer11::getBlendState(const gl::Context *context, + const d3d11::BlendStateKey &key, + const d3d11::BlendState **outBlendState) +{ + return mStateCache.getBlendState(context, this, key, outBlendState); +} + +angle::Result Renderer11::getRasterizerState(const gl::Context *context, + const gl::RasterizerState &rasterState, + bool scissorEnabled, + ID3D11RasterizerState **outRasterizerState) +{ + return mStateCache.getRasterizerState(context, this, rasterState, scissorEnabled, + outRasterizerState); +} + +angle::Result Renderer11::getDepthStencilState(const gl::Context *context, + const gl::DepthStencilState &dsState, + const d3d11::DepthStencilState **outDSState) +{ + return mStateCache.getDepthStencilState(context, this, dsState, outDSState); +} + +angle::Result Renderer11::getSamplerState(const gl::Context *context, + const gl::SamplerState &samplerState, + ID3D11SamplerState **outSamplerState) +{ + return mStateCache.getSamplerState(context, this, samplerState, outSamplerState); +} + +UINT Renderer11::getSampleDescQuality(GLuint supportedSamples) const +{ + // Per the documentation on + // https://docs.microsoft.com/en-us/windows/win32/api/d3d11/ne-d3d11-d3d11_standard_multisample_quality_levels + // applications can only request the standard multisample pattern on + // feature levels 10_1 and above. + if (supportedSamples > 0 && mDevice->GetFeatureLevel() >= D3D_FEATURE_LEVEL_10_1) + { + return D3D11_STANDARD_MULTISAMPLE_PATTERN; + } + return 0; +} + +angle::Result Renderer11::clearRenderTarget(const gl::Context *context, + RenderTargetD3D *renderTarget, + const gl::ColorF &clearColorValue, + const float clearDepthValue, + const unsigned int clearStencilValue) +{ + RenderTarget11 *rt11 = GetAs(renderTarget); + + if (rt11->getFormatSet().dsvFormat != DXGI_FORMAT_UNKNOWN) + { + ASSERT(rt11->getDepthStencilView().valid()); + + const auto &format = rt11->getFormatSet(); + const UINT clearFlags = (format.format().depthBits > 0 ? D3D11_CLEAR_DEPTH : 0) | + (format.format().stencilBits ? D3D11_CLEAR_STENCIL : 0); + mDeviceContext->ClearDepthStencilView(rt11->getDepthStencilView().get(), clearFlags, + clearDepthValue, + static_cast(clearStencilValue)); + return angle::Result::Continue; + } + + ASSERT(rt11->getRenderTargetView().valid()); + ID3D11RenderTargetView *rtv = rt11->getRenderTargetView().get(); + + // There are complications with some types of RTV and FL 9_3 with ClearRenderTargetView. + // See https://msdn.microsoft.com/en-us/library/windows/desktop/ff476388(v=vs.85).aspx + ASSERT(mRenderer11DeviceCaps.featureLevel > D3D_FEATURE_LEVEL_9_3 || !IsArrayRTV(rtv)); + + const auto &d3d11Format = rt11->getFormatSet(); + const auto &glFormat = gl::GetSizedInternalFormatInfo(renderTarget->getInternalFormat()); + + gl::ColorF safeClearColor = clearColorValue; + + if (d3d11Format.format().alphaBits > 0 && glFormat.alphaBits == 0) + { + safeClearColor.alpha = 1.0f; + } + + mDeviceContext->ClearRenderTargetView(rtv, &safeClearColor.red); + return angle::Result::Continue; +} + +bool Renderer11::canSelectViewInVertexShader() const +{ + return !getFeatures().selectViewInGeometryShader.enabled && + getRenderer11DeviceCaps().supportsVpRtIndexWriteFromVertexShader; +} + +angle::Result Renderer11::mapResource(const gl::Context *context, + ID3D11Resource *resource, + UINT subResource, + D3D11_MAP mapType, + UINT mapFlags, + D3D11_MAPPED_SUBRESOURCE *mappedResource) +{ + HRESULT hr = mDeviceContext->Map(resource, subResource, mapType, mapFlags, mappedResource); + ANGLE_TRY_HR(GetImplAs(context), hr, "Failed to map D3D11 resource."); + return angle::Result::Continue; +} + +angle::Result Renderer11::markTypedBufferUsage(const gl::Context *context) +{ + const gl::State &glState = context->getState(); + ProgramD3D *programD3D = GetImplAs(glState.getProgram()); + gl::RangeUI imageRange = programD3D->getUsedImageRange(gl::ShaderType::Compute, false); + for (unsigned int imageIndex = imageRange.low(); imageIndex < imageRange.high(); imageIndex++) + { + GLint imageUnitIndex = programD3D->getImageMapping(gl::ShaderType::Compute, imageIndex, + false, context->getCaps()); + ASSERT(imageUnitIndex != -1); + const gl::ImageUnit &imageUnit = glState.getImageUnit(imageUnitIndex); + if (imageUnit.texture.get()->getType() == gl::TextureType::Buffer) + { + Buffer11 *buffer11 = GetImplAs(imageUnit.texture.get()->getBuffer().get()); + ANGLE_TRY(buffer11->markTypedBufferUsage(context)); + } + } + return angle::Result::Continue; +} + +angle::Result Renderer11::markRawBufferUsage(const gl::Context *context) +{ + const gl::State &glState = context->getState(); + const gl::Program *program = glState.getProgram(); + for (size_t blockIndex = 0; blockIndex < program->getActiveShaderStorageBlockCount(); + blockIndex++) + { + GLuint binding = program->getShaderStorageBlockBinding(static_cast(blockIndex)); + const auto &shaderStorageBuffer = glState.getIndexedShaderStorageBuffer(binding); + if (shaderStorageBuffer.get() != nullptr) + { + Buffer11 *bufferStorage = GetImplAs(shaderStorageBuffer.get()); + ANGLE_TRY(bufferStorage->markRawBufferUsage(context)); + } + } + + for (const auto &atomicCounterBuffer : program->getState().getAtomicCounterBuffers()) + { + GLuint binding = atomicCounterBuffer.binding; + const auto &buffer = glState.getIndexedAtomicCounterBuffer(binding); + + if (buffer.get() != nullptr) + { + Buffer11 *bufferStorage = GetImplAs(buffer.get()); + ANGLE_TRY(bufferStorage->markRawBufferUsage(context)); + } + } + return angle::Result::Continue; +} + +angle::Result Renderer11::markTransformFeedbackUsage(const gl::Context *context) +{ + const gl::State &glState = context->getState(); + const gl::TransformFeedback *transformFeedback = glState.getCurrentTransformFeedback(); + for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++) + { + const gl::OffsetBindingPointer &binding = + transformFeedback->getIndexedBuffer(i); + if (binding.get() != nullptr) + { + BufferD3D *bufferD3D = GetImplAs(binding.get()); + ANGLE_TRY(bufferD3D->markTransformFeedbackUsage(context)); + } + } + + return angle::Result::Continue; +} + +angle::Result Renderer11::getIncompleteTexture(const gl::Context *context, + gl::TextureType type, + gl::Texture **textureOut) +{ + return GetImplAs(context)->getIncompleteTexture(context, type, textureOut); +} + +std::string Renderer11::getVendorString() const +{ + return GetVendorString(mAdapterDescription.VendorId); +} + +std::string Renderer11::getVersionString(bool includeFullVersion) const +{ + std::ostringstream versionString; + versionString << "D3D11"; + if (includeFullVersion && mRenderer11DeviceCaps.driverVersion.valid()) + { + versionString << "-" << GetDriverVersionString(mRenderer11DeviceCaps.driverVersion.value()); + } + return versionString.str(); +} + +RendererD3D *CreateRenderer11(egl::Display *display) +{ + return new Renderer11(display); +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Renderer11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Renderer11.h new file mode 100644 index 0000000000..6d4cb214af --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Renderer11.h @@ -0,0 +1,632 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Renderer11.h: Defines a back-end specific class for the D3D11 renderer. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_H_ + +#include "common/angleutils.h" +#include "common/mathutil.h" +#include "libANGLE/AttributeMap.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/renderer/d3d/HLSLCompiler.h" +#include "libANGLE/renderer/d3d/ProgramD3D.h" +#include "libANGLE/renderer/d3d/RenderTargetD3D.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" +#include "libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h" +#include "libANGLE/renderer/d3d/d3d11/RenderStateCache.h" +#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h" +#include "libANGLE/renderer/d3d/d3d11/StateManager11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" + +namespace gl +{ +class FramebufferAttachment; +class ImageIndex; +} // namespace gl + +namespace rx +{ +class Blit11; +class Buffer11; +class Clear11; +class Context11; +class IndexDataManager; +struct PackPixelsParams; +class PixelTransfer11; +class RenderTarget11; +class StreamingIndexBufferInterface; +class Trim11; +class VertexDataManager; + +struct Renderer11DeviceCaps +{ + Renderer11DeviceCaps(); + + D3D_FEATURE_LEVEL featureLevel; + bool supportsDXGI1_2; // Support for DXGI 1.2 + bool supportsClearView; // Support for ID3D11DeviceContext1::ClearView + bool supportsConstantBufferOffsets; // Support for Constant buffer offset + bool supportsVpRtIndexWriteFromVertexShader; // VP/RT can be selected in the Vertex Shader + // stage. + bool supportsMultisampledDepthStencilSRVs; // D3D feature level 10.0 no longer allows creation + // of textures with both the bind SRV and DSV flags + // when multisampled. Textures will need to be + // resolved before reading. crbug.com/656989 + bool supportsTypedUAVLoadAdditionalFormats; // + bool supportsRasterizerOrderViews; + bool allowES3OnFL10_0; + UINT B5G6R5support; // Bitfield of D3D11_FORMAT_SUPPORT values for DXGI_FORMAT_B5G6R5_UNORM + UINT B5G6R5maxSamples; // Maximum number of samples supported by DXGI_FORMAT_B5G6R5_UNORM + UINT B4G4R4A4support; // Bitfield of D3D11_FORMAT_SUPPORT values for DXGI_FORMAT_B4G4R4A4_UNORM + UINT B4G4R4A4maxSamples; // Maximum number of samples supported by DXGI_FORMAT_B4G4R4A4_UNORM + UINT B5G5R5A1support; // Bitfield of D3D11_FORMAT_SUPPORT values for DXGI_FORMAT_B5G5R5A1_UNORM + UINT B5G5R5A1maxSamples; // Maximum number of samples supported by DXGI_FORMAT_B5G5R5A1_UNORM + Optional driverVersion; // Four-part driver version number. +}; + +enum +{ + MAX_VERTEX_UNIFORM_VECTORS_D3D11 = 1024, + MAX_FRAGMENT_UNIFORM_VECTORS_D3D11 = 1024 +}; + +class Renderer11 : public RendererD3D +{ + public: + explicit Renderer11(egl::Display *display); + ~Renderer11() override; + + egl::Error initialize() override; + bool resetDevice() override; + + egl::ConfigSet generateConfigs() override; + void generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const override; + + ContextImpl *createContext(const gl::State &state, gl::ErrorSet *errorSet) override; + + angle::Result flush(Context11 *context11); + angle::Result finish(Context11 *context11); + + bool isValidNativeWindow(EGLNativeWindowType window) const override; + NativeWindowD3D *createNativeWindow(EGLNativeWindowType window, + const egl::Config *config, + const egl::AttributeMap &attribs) const override; + + SwapChainD3D *createSwapChain(NativeWindowD3D *nativeWindow, + HANDLE shareHandle, + IUnknown *d3dTexture, + GLenum backBufferFormat, + GLenum depthBufferFormat, + EGLint orientation, + EGLint samples) override; + egl::Error getD3DTextureInfo(const egl::Config *configuration, + IUnknown *d3dTexture, + const egl::AttributeMap &attribs, + EGLint *width, + EGLint *height, + GLsizei *samples, + gl::Format *glFormat, + const angle::Format **angleFormat, + UINT *arraySlice) const override; + egl::Error validateShareHandle(const egl::Config *config, + HANDLE shareHandle, + const egl::AttributeMap &attribs) const override; + + // lost device + bool testDeviceLost() override; + bool testDeviceResettable() override; + + DeviceIdentifier getAdapterIdentifier() const override; + + unsigned int getReservedVertexUniformVectors() const; + unsigned int getReservedFragmentUniformVectors() const; + gl::ShaderMap getReservedShaderUniformBuffers() const; + + bool getShareHandleSupport() const; + + int getMajorShaderModel() const override; + int getMinorShaderModel() const override; + std::string getShaderModelSuffix() const override; + + // Pixel operations + angle::Result copyImage2D(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) override; + angle::Result copyImageCube(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + gl::TextureTarget target, + GLint level) override; + angle::Result copyImage3D(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) override; + angle::Result copyImage2DArray(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) override; + + angle::Result copyTexture(const gl::Context *context, + const gl::Texture *source, + GLint sourceLevel, + gl::TextureTarget srcTarget, + const gl::Box &sourceBox, + GLenum destFormat, + GLenum destType, + const gl::Offset &destOffset, + TextureStorage *storage, + gl::TextureTarget destTarget, + GLint destLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) override; + angle::Result copyCompressedTexture(const gl::Context *context, + const gl::Texture *source, + GLint sourceLevel, + TextureStorage *storage, + GLint destLevel) override; + + // RenderTarget creation + angle::Result createRenderTarget(const gl::Context *context, + int width, + int height, + GLenum format, + GLsizei samples, + RenderTargetD3D **outRT) override; + angle::Result createRenderTargetCopy(const gl::Context *context, + RenderTargetD3D *source, + RenderTargetD3D **outRT) override; + + // Shader operations + angle::Result loadExecutable(d3d::Context *context, + const uint8_t *function, + size_t length, + gl::ShaderType type, + const std::vector &streamOutVaryings, + bool separatedOutputBuffers, + ShaderExecutableD3D **outExecutable) override; + angle::Result compileToExecutable(d3d::Context *context, + gl::InfoLog &infoLog, + const std::string &shaderHLSL, + gl::ShaderType type, + const std::vector &streamOutVaryings, + bool separatedOutputBuffers, + const CompilerWorkaroundsD3D &workarounds, + ShaderExecutableD3D **outExectuable) override; + angle::Result ensureHLSLCompilerInitialized(d3d::Context *context) override; + + UniformStorageD3D *createUniformStorage(size_t storageSize) override; + + // Image operations + ImageD3D *createImage() override; + ExternalImageSiblingImpl *createExternalImageSibling(const gl::Context *context, + EGLenum target, + EGLClientBuffer buffer, + const egl::AttributeMap &attribs) override; + angle::Result generateMipmap(const gl::Context *context, + ImageD3D *dest, + ImageD3D *source) override; + angle::Result generateMipmapUsingD3D(const gl::Context *context, + TextureStorage *storage, + const gl::TextureState &textureState) override; + angle::Result copyImage(const gl::Context *context, + ImageD3D *dest, + ImageD3D *source, + const gl::Box &sourceBox, + const gl::Offset &destOffset, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) override; + + TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain, + const std::string &label) override; + TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage, + RenderTargetD3D *renderTargetD3D, + const std::string &label) override; + TextureStorage *createTextureStorageExternal(egl::Stream *stream, + const egl::Stream::GLTextureDescription &desc, + const std::string &label) override; + TextureStorage *createTextureStorage2D(GLenum internalformat, + BindFlags bindFlags, + GLsizei width, + GLsizei height, + int levels, + const std::string &label, + bool hintLevelZeroOnly) override; + TextureStorage *createTextureStorageCube(GLenum internalformat, + BindFlags bindFlags, + int size, + int levels, + bool hintLevelZeroOnly, + const std::string &label) override; + TextureStorage *createTextureStorage3D(GLenum internalformat, + BindFlags bindFlags, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels, + const std::string &label) override; + TextureStorage *createTextureStorage2DArray(GLenum internalformat, + BindFlags bindFlags, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels, + const std::string &label) override; + TextureStorage *createTextureStorage2DMultisample(GLenum internalformat, + GLsizei width, + GLsizei height, + int levels, + int samples, + bool fixedSampleLocations, + const std::string &label) override; + + TextureStorage *createTextureStorageBuffer(const gl::OffsetBindingPointer &buffer, + GLenum internalFormat, + const std::string &label) override; + TextureStorage *createTextureStorage2DMultisampleArray(GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels, + int samples, + bool fixedSampleLocations, + const std::string &label) override; + + VertexBuffer *createVertexBuffer() override; + IndexBuffer *createIndexBuffer() override; + + // Stream Creation + StreamProducerImpl *createStreamProducerD3DTexture(egl::Stream::ConsumerType consumerType, + const egl::AttributeMap &attribs) override; + + // D3D11-renderer specific methods + ID3D11Device *getDevice() { return mDevice; } + ID3D11Device1 *getDevice1() { return mDevice1; } + void *getD3DDevice() override; + ID3D11DeviceContext *getDeviceContext() { return mDeviceContext; } + ID3D11DeviceContext1 *getDeviceContext1IfSupported() { return mDeviceContext1; } + IDXGIFactory *getDxgiFactory() { return mDxgiFactory; } + + angle::Result getBlendState(const gl::Context *context, + const d3d11::BlendStateKey &key, + const d3d11::BlendState **outBlendState); + angle::Result getRasterizerState(const gl::Context *context, + const gl::RasterizerState &rasterState, + bool scissorEnabled, + ID3D11RasterizerState **outRasterizerState); + angle::Result getDepthStencilState(const gl::Context *context, + const gl::DepthStencilState &dsState, + const d3d11::DepthStencilState **outDSState); + angle::Result getSamplerState(const gl::Context *context, + const gl::SamplerState &samplerState, + ID3D11SamplerState **outSamplerState); + UINT getSampleDescQuality(GLuint supportedSamples) const; + + Blit11 *getBlitter() { return mBlit; } + Clear11 *getClearer() { return mClear; } + DebugAnnotatorContext11 *getDebugAnnotatorContext(); + + // Buffer-to-texture and Texture-to-buffer copies + bool supportsFastCopyBufferToTexture(GLenum internalFormat) const override; + angle::Result fastCopyBufferToTexture(const gl::Context *context, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + unsigned int offset, + RenderTargetD3D *destRenderTarget, + GLenum destinationFormat, + GLenum sourcePixelsType, + const gl::Box &destArea) override; + + angle::Result packPixels(const gl::Context *context, + const TextureHelper11 &textureHelper, + const PackPixelsParams ¶ms, + uint8_t *pixelsOut); + + bool getLUID(LUID *adapterLuid) const override; + VertexConversionType getVertexConversionType(angle::FormatID vertexFormatID) const override; + GLenum getVertexComponentType(angle::FormatID vertexFormatID) const override; + + // Warning: you should ensure binding really matches attrib.bindingIndex before using this + // function. + angle::Result getVertexSpaceRequired(const gl::Context *context, + const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + size_t count, + GLsizei instances, + GLuint baseInstance, + unsigned int *bytesRequiredOut) const override; + + angle::Result readFromAttachment(const gl::Context *context, + const gl::FramebufferAttachment &srcAttachment, + const gl::Rectangle &sourceArea, + GLenum format, + GLenum type, + GLuint outputPitch, + const gl::PixelPackState &pack, + uint8_t *pixels); + + angle::Result blitRenderbufferRect(const gl::Context *context, + const gl::Rectangle &readRect, + const gl::Rectangle &drawRect, + UINT readLayer, + UINT drawLayer, + RenderTargetD3D *readRenderTarget, + RenderTargetD3D *drawRenderTarget, + GLenum filter, + const gl::Rectangle *scissor, + bool colorBlit, + bool depthBlit, + bool stencilBlit); + + bool isES3Capable() const; + const Renderer11DeviceCaps &getRenderer11DeviceCaps() const { return mRenderer11DeviceCaps; } + + RendererClass getRendererClass() const override; + StateManager11 *getStateManager() { return &mStateManager; } + + void onSwap(); + void onBufferCreate(const Buffer11 *created); + void onBufferDelete(const Buffer11 *deleted); + + DeviceImpl *createEGLDevice() override; + + angle::Result drawArrays(const gl::Context *context, + gl::PrimitiveMode mode, + GLint firstVertex, + GLsizei vertexCount, + GLsizei instanceCount, + GLuint baseInstance, + bool isInstancedDraw); + angle::Result drawElements(const gl::Context *context, + gl::PrimitiveMode mode, + GLint startVertex, + GLsizei indexCount, + gl::DrawElementsType indexType, + const void *indices, + GLsizei instanceCount, + GLint baseVertex, + GLuint baseInstance, + bool isInstancedDraw); + angle::Result drawArraysIndirect(const gl::Context *context, const void *indirect); + angle::Result drawElementsIndirect(const gl::Context *context, const void *indirect); + + // Necessary hack for default framebuffers in D3D. + FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) override; + + angle::Result getScratchMemoryBuffer(Context11 *context11, + size_t requestedSize, + angle::MemoryBuffer **bufferOut); + + gl::Version getMaxSupportedESVersion() const override; + gl::Version getMaxConformantESVersion() const override; + + angle::Result dispatchCompute(const gl::Context *context, + GLuint numGroupsX, + GLuint numGroupsY, + GLuint numGroupsZ); + angle::Result dispatchComputeIndirect(const gl::Context *context, GLintptr indirect); + + angle::Result createStagingTexture(const gl::Context *context, + ResourceType textureType, + const d3d11::Format &formatSet, + const gl::Extents &size, + StagingAccess readAndWriteAccess, + TextureHelper11 *textureOut); + + template + angle::Result allocateResource(d3d::Context *context, const DescT &desc, ResourceT *resourceOut) + { + return mResourceManager11.allocate(context, this, &desc, nullptr, resourceOut); + } + + template + angle::Result allocateResource(d3d::Context *context, + const DescT &desc, + InitDataT *initData, + ResourceT *resourceOut) + { + return mResourceManager11.allocate(context, this, &desc, initData, resourceOut); + } + + template + angle::Result allocateResourceNoDesc(d3d::Context *context, + InitDataT *initData, + ResourceT *resourceOut) + { + return mResourceManager11.allocate(context, this, nullptr, initData, resourceOut); + } + + template + angle::Result allocateTexture(d3d::Context *context, + const DescT &desc, + const d3d11::Format &format, + TextureHelper11 *textureOut) + { + return allocateTexture(context, desc, format, nullptr, textureOut); + } + + angle::Result allocateTexture(d3d::Context *context, + const D3D11_TEXTURE2D_DESC &desc, + const d3d11::Format &format, + const D3D11_SUBRESOURCE_DATA *initData, + TextureHelper11 *textureOut); + + angle::Result allocateTexture(d3d::Context *context, + const D3D11_TEXTURE3D_DESC &desc, + const d3d11::Format &format, + const D3D11_SUBRESOURCE_DATA *initData, + TextureHelper11 *textureOut); + + angle::Result clearRenderTarget(const gl::Context *context, + RenderTargetD3D *renderTarget, + const gl::ColorF &clearColorValue, + const float clearDepthValue, + const unsigned int clearStencilValue) override; + + bool canSelectViewInVertexShader() const override; + + angle::Result mapResource(const gl::Context *context, + ID3D11Resource *resource, + UINT subResource, + D3D11_MAP mapType, + UINT mapFlags, + D3D11_MAPPED_SUBRESOURCE *mappedResource); + + angle::Result getIncompleteTexture(const gl::Context *context, + gl::TextureType type, + gl::Texture **textureOut) override; + + void setGlobalDebugAnnotator() override; + + std::string getRendererDescription() const override; + std::string getVendorString() const override; + std::string getVersionString(bool includeFullVersion) const override; + + private: + void generateCaps(gl::Caps *outCaps, + gl::TextureCapsMap *outTextureCaps, + gl::Extensions *outExtensions, + gl::Limitations *outLimitations) const override; + + void initializeFeatures(angle::FeaturesD3D *features) const override; + + void initializeFrontendFeatures(angle::FrontendFeatures *features) const override; + + angle::Result drawLineLoop(const gl::Context *context, + GLuint count, + gl::DrawElementsType type, + const void *indices, + int baseVertex, + int instances); + angle::Result drawTriangleFan(const gl::Context *context, + GLuint count, + gl::DrawElementsType type, + const void *indices, + int baseVertex, + int instances); + + angle::Result resolveMultisampledTexture(const gl::Context *context, + RenderTarget11 *renderTarget, + bool depth, + bool stencil, + TextureHelper11 *textureOut); + + void populateRenderer11DeviceCaps(); + + void updateHistograms(); + + angle::Result copyImageInternal(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + RenderTargetD3D *destRenderTarget); + + gl::SupportedSampleSet generateSampleSetForEGLConfig( + const gl::TextureCaps &colorBufferFormatCaps, + const gl::TextureCaps &depthStencilBufferFormatCaps) const; + + HRESULT callD3D11CreateDevice(PFN_D3D11_CREATE_DEVICE createDevice, bool debug); + HRESULT callD3D11On12CreateDevice(PFN_D3D12_CREATE_DEVICE createDevice12, + PFN_D3D11ON12_CREATE_DEVICE createDevice11on12, + bool debug); + egl::Error initializeD3DDevice(); + egl::Error initializeDevice(); + void releaseDeviceResources(); + void release(); + + d3d11::ANGLED3D11DeviceType getDeviceType() const; + + // Make sure that the raw buffer is the latest buffer. + angle::Result markRawBufferUsage(const gl::Context *context); + angle::Result markTypedBufferUsage(const gl::Context *context); + angle::Result markTransformFeedbackUsage(const gl::Context *context); + angle::Result drawWithGeometryShaderAndTransformFeedback(Context11 *context11, + gl::PrimitiveMode mode, + UINT instanceCount, + UINT vertexCount); + + HMODULE mD3d11Module; + HMODULE mD3d12Module; + HMODULE mDxgiModule; + HMODULE mDCompModule; + std::vector mAvailableFeatureLevels; + D3D_DRIVER_TYPE mRequestedDriverType; + bool mCreateDebugDevice; + bool mCreatedWithDeviceEXT; + + HLSLCompiler mCompiler; + + RenderStateCache mStateCache; + + StateManager11 mStateManager; + + StreamingIndexBufferInterface *mLineLoopIB; + StreamingIndexBufferInterface *mTriangleFanIB; + + // Texture copy resources + Blit11 *mBlit; + PixelTransfer11 *mPixelTransfer; + + // Masked clear resources + Clear11 *mClear; + + // Perform trim for D3D resources + Trim11 *mTrim; + + // Sync query + d3d11::Query mSyncQuery; + + // Created objects state tracking + std::set mAliveBuffers; + + double mLastHistogramUpdateTime; + + angle::ComPtr mDevice12; + angle::ComPtr mCommandQueue; + + ID3D11Device *mDevice; + ID3D11Device1 *mDevice1; + Renderer11DeviceCaps mRenderer11DeviceCaps; + ID3D11DeviceContext *mDeviceContext; + ID3D11DeviceContext1 *mDeviceContext1; + ID3D11DeviceContext3 *mDeviceContext3; + IDXGIAdapter *mDxgiAdapter; + DXGI_ADAPTER_DESC mAdapterDescription; + char mDescription[128]; + IDXGIFactory *mDxgiFactory; + ID3D11Debug *mDebug; + + std::vector mScratchIndexDataBuffer; + + angle::ScratchBuffer mScratchMemoryBuffer; + + DebugAnnotatorContext11 mAnnotatorContext; + + mutable Optional mSupportsShareHandles; + ResourceManager11 mResourceManager11; + + TextureHelper11 mCachedResolveTexture; +}; + +} // namespace rx +#endif // LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.cpp new file mode 100644 index 0000000000..ebf2db497f --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.cpp @@ -0,0 +1,560 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ResourceManager11: +// Centralized point of allocation for all D3D11 Resources. + +#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h" + +#include "common/debug.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" + +namespace rx +{ + +namespace +{ + +constexpr uint8_t kDebugInitTextureDataValue = 0x48; +constexpr FLOAT kDebugColorInitClearValue[4] = {0.3f, 0.5f, 0.7f, 0.5f}; +constexpr FLOAT kDebugDepthInitValue = 0.2f; +constexpr UINT8 kDebugStencilInitValue = 3; + +// A hard limit on buffer size. This works around a problem in the NVIDIA drivers where buffer sizes +// close to MAX_UINT would give undefined results. The limit of MAX_UINT/2 should be generous enough +// for almost any demanding application. +constexpr UINT kMaximumBufferSizeHardLimit = std::numeric_limits::max() >> 1; + +uint64_t ComputeMippedMemoryUsage(unsigned int width, + unsigned int height, + unsigned int depth, + uint64_t pixelSize, + unsigned int mipLevels) +{ + uint64_t sizeSum = 0; + + for (unsigned int level = 0; level < mipLevels; ++level) + { + unsigned int mipWidth = std::max(width >> level, 1u); + unsigned int mipHeight = std::max(height >> level, 1u); + unsigned int mipDepth = std::max(depth >> level, 1u); + sizeSum += static_cast(mipWidth * mipHeight * mipDepth) * pixelSize; + } + + return sizeSum; +} + +uint64_t ComputeMemoryUsage(const D3D11_TEXTURE2D_DESC *desc) +{ + ASSERT(desc); + uint64_t pixelBytes = + static_cast(d3d11::GetDXGIFormatSizeInfo(desc->Format).pixelBytes); + return ComputeMippedMemoryUsage(desc->Width, desc->Height, 1, pixelBytes, desc->MipLevels); +} + +uint64_t ComputeMemoryUsage(const D3D11_TEXTURE3D_DESC *desc) +{ + ASSERT(desc); + uint64_t pixelBytes = + static_cast(d3d11::GetDXGIFormatSizeInfo(desc->Format).pixelBytes); + return ComputeMippedMemoryUsage(desc->Width, desc->Height, desc->Depth, pixelBytes, + desc->MipLevels); +} + +uint64_t ComputeMemoryUsage(const D3D11_BUFFER_DESC *desc) +{ + ASSERT(desc); + return static_cast(desc->ByteWidth); +} + +template +uint64_t ComputeMemoryUsage(const T *desc) +{ + return 0; +} + +template +uint64_t ComputeGenericMemoryUsage(ID3D11DeviceChild *genericResource) +{ + auto *typedResource = static_cast *>(genericResource); + GetDescType desc; + typedResource->GetDesc(&desc); + return ComputeMemoryUsage(&desc); +} + +uint64_t ComputeGenericMemoryUsage(ResourceType resourceType, ID3D11DeviceChild *resource) +{ + switch (resourceType) + { + case ResourceType::Texture2D: + return ComputeGenericMemoryUsage(resource); + case ResourceType::Texture3D: + return ComputeGenericMemoryUsage(resource); + case ResourceType::Buffer: + return ComputeGenericMemoryUsage(resource); + + default: + return 0; + } +} + +HRESULT CreateResource(ID3D11Device *device, + const D3D11_BLEND_DESC *desc, + void * /*initData*/, + ID3D11BlendState **blendState) +{ + return device->CreateBlendState(desc, blendState); +} + +HRESULT CreateResource(ID3D11Device *device, + const D3D11_BUFFER_DESC *desc, + const D3D11_SUBRESOURCE_DATA *initData, + ID3D11Buffer **buffer) +{ + // Force buffers to be limited to a fixed max size. + if (desc->ByteWidth > kMaximumBufferSizeHardLimit) + { + return E_OUTOFMEMORY; + } + + return device->CreateBuffer(desc, initData, buffer); +} + +HRESULT CreateResource(ID3D11Device *device, + const ShaderData *desc, + void * /*initData*/, + ID3D11ComputeShader **resourceOut) +{ + return device->CreateComputeShader(desc->get(), desc->size(), nullptr, resourceOut); +} + +HRESULT CreateResource(ID3D11Device *device, + const D3D11_DEPTH_STENCIL_DESC *desc, + void * /*initData*/, + ID3D11DepthStencilState **resourceOut) +{ + return device->CreateDepthStencilState(desc, resourceOut); +} + +HRESULT CreateResource(ID3D11Device *device, + const D3D11_DEPTH_STENCIL_VIEW_DESC *desc, + ID3D11Resource *resource, + ID3D11DepthStencilView **resourceOut) +{ + return device->CreateDepthStencilView(resource, desc, resourceOut); +} + +HRESULT CreateResource(ID3D11Device *device, + const ShaderData *desc, + const std::vector *initData, + ID3D11GeometryShader **resourceOut) +{ + if (initData) + { + return device->CreateGeometryShaderWithStreamOutput( + desc->get(), desc->size(), initData->data(), static_cast(initData->size()), + nullptr, 0, 0, nullptr, resourceOut); + } + else + { + return device->CreateGeometryShader(desc->get(), desc->size(), nullptr, resourceOut); + } +} + +HRESULT CreateResource(ID3D11Device *device, + const InputElementArray *desc, + const ShaderData *initData, + ID3D11InputLayout **resourceOut) +{ + return device->CreateInputLayout(desc->get(), static_cast(desc->size()), initData->get(), + initData->size(), resourceOut); +} + +HRESULT CreateResource(ID3D11Device *device, + const ShaderData *desc, + void * /*initData*/, + ID3D11PixelShader **resourceOut) +{ + return device->CreatePixelShader(desc->get(), desc->size(), nullptr, resourceOut); +} + +HRESULT CreateResource(ID3D11Device *device, + const D3D11_QUERY_DESC *desc, + void * /*initData*/, + ID3D11Query **resourceOut) +{ + return device->CreateQuery(desc, resourceOut); +} + +HRESULT CreateResource(ID3D11Device *device, + const D3D11_RASTERIZER_DESC *desc, + void * /*initData*/, + ID3D11RasterizerState **rasterizerState) +{ + return device->CreateRasterizerState(desc, rasterizerState); +} + +HRESULT CreateResource(ID3D11Device *device, + const D3D11_RENDER_TARGET_VIEW_DESC *desc, + ID3D11Resource *resource, + ID3D11RenderTargetView **renderTargetView) +{ + return device->CreateRenderTargetView(resource, desc, renderTargetView); +} + +HRESULT CreateResource(ID3D11Device *device, + const D3D11_SAMPLER_DESC *desc, + void * /*initData*/, + ID3D11SamplerState **resourceOut) +{ + return device->CreateSamplerState(desc, resourceOut); +} + +HRESULT CreateResource(ID3D11Device *device, + const D3D11_SHADER_RESOURCE_VIEW_DESC *desc, + ID3D11Resource *resource, + ID3D11ShaderResourceView **resourceOut) +{ + return device->CreateShaderResourceView(resource, desc, resourceOut); +} + +HRESULT CreateResource(ID3D11Device *device, + const D3D11_UNORDERED_ACCESS_VIEW_DESC *desc, + ID3D11Resource *resource, + ID3D11UnorderedAccessView **resourceOut) +{ + return device->CreateUnorderedAccessView(resource, desc, resourceOut); +} + +HRESULT CreateResource(ID3D11Device *device, + const D3D11_TEXTURE2D_DESC *desc, + const D3D11_SUBRESOURCE_DATA *initData, + ID3D11Texture2D **texture) +{ + return device->CreateTexture2D(desc, initData, texture); +} + +HRESULT CreateResource(ID3D11Device *device, + const D3D11_TEXTURE3D_DESC *desc, + const D3D11_SUBRESOURCE_DATA *initData, + ID3D11Texture3D **texture) +{ + return device->CreateTexture3D(desc, initData, texture); +} + +HRESULT CreateResource(ID3D11Device *device, + const ShaderData *desc, + void * /*initData*/, + ID3D11VertexShader **resourceOut) +{ + return device->CreateVertexShader(desc->get(), desc->size(), nullptr, resourceOut); +} + +DXGI_FORMAT GetTypedDepthStencilFormat(DXGI_FORMAT dxgiFormat) +{ + switch (dxgiFormat) + { + case DXGI_FORMAT_R16_TYPELESS: + return DXGI_FORMAT_D16_UNORM; + case DXGI_FORMAT_R24G8_TYPELESS: + return DXGI_FORMAT_D24_UNORM_S8_UINT; + case DXGI_FORMAT_R32_TYPELESS: + return DXGI_FORMAT_D32_FLOAT; + case DXGI_FORMAT_R32G8X24_TYPELESS: + return DXGI_FORMAT_D32_FLOAT_S8X24_UINT; + default: + return dxgiFormat; + } +} + +template +angle::Result ClearResource(d3d::Context *context, + Renderer11 *renderer, + const DescT *desc, + ResourceT *texture) +{ + // No-op. + return angle::Result::Continue; +} + +template <> +angle::Result ClearResource(d3d::Context *context, + Renderer11 *renderer, + const D3D11_TEXTURE2D_DESC *desc, + ID3D11Texture2D *texture) +{ + ID3D11DeviceContext *deviceContext = renderer->getDeviceContext(); + + if ((desc->BindFlags & D3D11_BIND_DEPTH_STENCIL) != 0) + { + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsvDesc.Flags = 0; + dsvDesc.Format = GetTypedDepthStencilFormat(desc->Format); + + const auto &format = d3d11_angle::GetFormat(dsvDesc.Format); + UINT clearFlags = (format.depthBits > 0 ? D3D11_CLEAR_DEPTH : 0) | + (format.stencilBits > 0 ? D3D11_CLEAR_STENCIL : 0); + + // Must process each mip level individually. + for (UINT mipLevel = 0; mipLevel < desc->MipLevels; ++mipLevel) + { + if (desc->SampleDesc.Count == 0) + { + dsvDesc.Texture2D.MipSlice = mipLevel; + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + } + else + { + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS; + } + + d3d11::DepthStencilView dsv; + ANGLE_TRY(renderer->allocateResource(context, dsvDesc, texture, &dsv)); + + deviceContext->ClearDepthStencilView(dsv.get(), clearFlags, kDebugDepthInitValue, + kDebugStencilInitValue); + } + } + else + { + ASSERT((desc->BindFlags & D3D11_BIND_RENDER_TARGET) != 0); + d3d11::RenderTargetView rtv; + ANGLE_TRY(renderer->allocateResourceNoDesc(context, texture, &rtv)); + + deviceContext->ClearRenderTargetView(rtv.get(), kDebugColorInitClearValue); + } + + return angle::Result::Continue; +} + +template <> +angle::Result ClearResource(d3d::Context *context, + Renderer11 *renderer, + const D3D11_TEXTURE3D_DESC *desc, + ID3D11Texture3D *texture) +{ + ID3D11DeviceContext *deviceContext = renderer->getDeviceContext(); + + ASSERT((desc->BindFlags & D3D11_BIND_DEPTH_STENCIL) == 0); + ASSERT((desc->BindFlags & D3D11_BIND_RENDER_TARGET) != 0); + + d3d11::RenderTargetView rtv; + ANGLE_TRY(renderer->allocateResourceNoDesc(context, texture, &rtv)); + + deviceContext->ClearRenderTargetView(rtv.get(), kDebugColorInitClearValue); + return angle::Result::Continue; +} + +#define ANGLE_RESOURCE_STRINGIFY_OP(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \ + "Error allocating " #RESTYPE, + +constexpr std::array kResourceTypeErrors = { + {ANGLE_RESOURCE_TYPE_OP(Stringify, ANGLE_RESOURCE_STRINGIFY_OP)}}; +static_assert(kResourceTypeErrors[NumResourceTypes - 1] != nullptr, + "All members must be initialized."); + +} // anonymous namespace + +// ResourceManager11 Implementation. +ResourceManager11::ResourceManager11() : mInitializeAllocations(false) +{ + for (auto &count : mAllocatedResourceCounts) + { + count = 0; + } + for (auto &memorySize : mAllocatedResourceDeviceMemory) + { + memorySize = 0; + } +} + +ResourceManager11::~ResourceManager11() +{ + for (size_t count : mAllocatedResourceCounts) + { + ASSERT(count == 0); + } + + for (uint64_t memorySize : mAllocatedResourceDeviceMemory) + { + ASSERT(memorySize == 0); + } +} + +template +angle::Result ResourceManager11::allocate(d3d::Context *context, + Renderer11 *renderer, + const GetDescFromD3D11 *desc, + GetInitDataFromD3D11 *initData, + Resource11 *resourceOut) +{ + ID3D11Device *device = renderer->getDevice(); + T *resource = nullptr; + + GetInitDataFromD3D11 *shadowInitData = initData; + if (!shadowInitData && mInitializeAllocations) + { + shadowInitData = createInitDataIfNeeded(desc); + } + + HRESULT hr = CreateResource(device, desc, shadowInitData, &resource); + ANGLE_TRY_HR(context, hr, kResourceTypeErrors[ResourceTypeIndex()]); + + if (!shadowInitData && mInitializeAllocations) + { + ANGLE_TRY(ClearResource(context, renderer, desc, resource)); + } + + ASSERT(resource); + incrResource(GetResourceTypeFromD3D11(), ComputeMemoryUsage(desc)); + *resourceOut = std::move(Resource11(resource, this)); + return angle::Result::Continue; +} + +void ResourceManager11::incrResource(ResourceType resourceType, uint64_t memorySize) +{ + size_t typeIndex = ResourceTypeIndex(resourceType); + + mAllocatedResourceCounts[typeIndex]++; + mAllocatedResourceDeviceMemory[typeIndex] += memorySize; + + // This checks for integer overflow. + ASSERT(mAllocatedResourceCounts[typeIndex] > 0); + ASSERT(mAllocatedResourceDeviceMemory[typeIndex] >= memorySize); +} + +void ResourceManager11::decrResource(ResourceType resourceType, uint64_t memorySize) +{ + size_t typeIndex = ResourceTypeIndex(resourceType); + + ASSERT(mAllocatedResourceCounts[typeIndex] > 0); + mAllocatedResourceCounts[typeIndex]--; + ASSERT(mAllocatedResourceDeviceMemory[typeIndex] >= memorySize); + mAllocatedResourceDeviceMemory[typeIndex] -= memorySize; +} + +void ResourceManager11::onReleaseGeneric(ResourceType resourceType, ID3D11DeviceChild *resource) +{ + ASSERT(resource); + decrResource(resourceType, ComputeGenericMemoryUsage(resourceType, resource)); +} + +template <> +const D3D11_SUBRESOURCE_DATA *ResourceManager11::createInitDataIfNeeded( + const D3D11_TEXTURE2D_DESC *desc) +{ + ASSERT(desc); + + if ((desc->BindFlags & (D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_RENDER_TARGET)) != 0) + { + // This will be done using ClearView methods. + return nullptr; + } + + size_t requiredSize = static_cast(ComputeMemoryUsage(desc)); + if (mZeroMemory.size() < requiredSize) + { + if (!mZeroMemory.resize(requiredSize)) + { + ERR() << "Failed to allocate D3D texture initialization data."; + return nullptr; + } + mZeroMemory.fill(kDebugInitTextureDataValue); + } + + const auto &formatSizeInfo = d3d11::GetDXGIFormatSizeInfo(desc->Format); + + UINT subresourceCount = desc->MipLevels * desc->ArraySize; + if (mShadowInitData.size() < subresourceCount) + { + mShadowInitData.resize(subresourceCount); + } + + for (UINT mipLevel = 0; mipLevel < desc->MipLevels; ++mipLevel) + { + for (UINT arrayIndex = 0; arrayIndex < desc->ArraySize; ++arrayIndex) + { + UINT subresourceIndex = D3D11CalcSubresource(mipLevel, arrayIndex, desc->MipLevels); + D3D11_SUBRESOURCE_DATA *data = &mShadowInitData[subresourceIndex]; + + UINT levelWidth = std::max(desc->Width >> mipLevel, 1u); + UINT levelHeight = std::max(desc->Height >> mipLevel, 1u); + + data->SysMemPitch = levelWidth * formatSizeInfo.pixelBytes; + data->SysMemSlicePitch = data->SysMemPitch * levelHeight; + data->pSysMem = mZeroMemory.data(); + } + } + + return mShadowInitData.data(); +} + +template <> +const D3D11_SUBRESOURCE_DATA *ResourceManager11::createInitDataIfNeeded( + const D3D11_TEXTURE3D_DESC *desc) +{ + ASSERT(desc); + + if ((desc->BindFlags & D3D11_BIND_RENDER_TARGET) != 0) + { + // This will be done using ClearView methods. + return nullptr; + } + + size_t requiredSize = static_cast(ComputeMemoryUsage(desc)); + if (mZeroMemory.size() < requiredSize) + { + if (!mZeroMemory.resize(requiredSize)) + { + ERR() << "Failed to allocate D3D texture initialization data."; + return nullptr; + } + mZeroMemory.fill(kDebugInitTextureDataValue); + } + + const auto &formatSizeInfo = d3d11::GetDXGIFormatSizeInfo(desc->Format); + + UINT subresourceCount = desc->MipLevels; + if (mShadowInitData.size() < subresourceCount) + { + mShadowInitData.resize(subresourceCount); + } + + for (UINT mipLevel = 0; mipLevel < desc->MipLevels; ++mipLevel) + { + UINT subresourceIndex = D3D11CalcSubresource(mipLevel, 0, desc->MipLevels); + D3D11_SUBRESOURCE_DATA *data = &mShadowInitData[subresourceIndex]; + + UINT levelWidth = std::max(desc->Width >> mipLevel, 1u); + UINT levelHeight = std::max(desc->Height >> mipLevel, 1u); + + data->SysMemPitch = levelWidth * formatSizeInfo.pixelBytes; + data->SysMemSlicePitch = data->SysMemPitch * levelHeight; + data->pSysMem = mZeroMemory.data(); + } + + return mShadowInitData.data(); +} + +template +GetInitDataFromD3D11 *ResourceManager11::createInitDataIfNeeded(const GetDescFromD3D11 *desc) +{ + // No-op. + return nullptr; +} + +void ResourceManager11::setAllocationsInitialized(bool initialize) +{ + mInitializeAllocations = initialize; +} + +#define ANGLE_INSTANTIATE_OP(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \ + \ + template angle::Result ResourceManager11::allocate( \ + d3d::Context *, Renderer11 *, const DESCTYPE *, INITDATATYPE *, Resource11 *); + +ANGLE_RESOURCE_TYPE_OP(Instantitate, ANGLE_INSTANTIATE_OP) +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.h new file mode 100644 index 0000000000..b013ab8358 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.h @@ -0,0 +1,411 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ResourceManager11: +// Centralized point of allocation for all D3D11 Resources. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_RESOURCEFACTORY11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_RESOURCEFACTORY11_H_ + +#include +#include +#include + +#include "common/MemoryBuffer.h" +#include "common/angleutils.h" +#include "common/debug.h" +#include "libANGLE/Error.h" +#include "libANGLE/renderer/serial_utils.h" + +namespace rx +{ +// These two methods are declared here to prevent circular includes. +namespace d3d11 +{ +HRESULT SetDebugName(ID3D11DeviceChild *resource, + const char *internalName, + const std::string *khrDebugName); + +template +HRESULT SetDebugName(angle::ComPtr &resource, + const char *internalName, + const std::string *khrDebugName) +{ + return SetDebugName(resource.Get(), internalName, khrDebugName); +} +} // namespace d3d11 + +namespace d3d +{ +class Context; +} // namespace d3d + +class Renderer11; +class ResourceManager11; +template +class SharedResource11; +class TextureHelper11; + +using InputElementArray = WrappedArray; +using ShaderData = WrappedArray; + +// Format: ResourceType, D3D11 type, DESC type, init data type. +#define ANGLE_RESOURCE_TYPE_OP(NAME, OP) \ + OP(NAME, BlendState, ID3D11BlendState, D3D11_BLEND_DESC, void) \ + OP(NAME, Buffer, ID3D11Buffer, D3D11_BUFFER_DESC, const D3D11_SUBRESOURCE_DATA) \ + OP(NAME, ComputeShader, ID3D11ComputeShader, ShaderData, void) \ + OP(NAME, DepthStencilState, ID3D11DepthStencilState, D3D11_DEPTH_STENCIL_DESC, void) \ + OP(NAME, DepthStencilView, ID3D11DepthStencilView, D3D11_DEPTH_STENCIL_VIEW_DESC, \ + ID3D11Resource) \ + OP(NAME, GeometryShader, ID3D11GeometryShader, ShaderData, \ + const std::vector) \ + OP(NAME, InputLayout, ID3D11InputLayout, InputElementArray, const ShaderData) \ + OP(NAME, PixelShader, ID3D11PixelShader, ShaderData, void) \ + OP(NAME, Query, ID3D11Query, D3D11_QUERY_DESC, void) \ + OP(NAME, RasterizerState, ID3D11RasterizerState, D3D11_RASTERIZER_DESC, void) \ + OP(NAME, RenderTargetView, ID3D11RenderTargetView, D3D11_RENDER_TARGET_VIEW_DESC, \ + ID3D11Resource) \ + OP(NAME, SamplerState, ID3D11SamplerState, D3D11_SAMPLER_DESC, void) \ + OP(NAME, ShaderResourceView, ID3D11ShaderResourceView, D3D11_SHADER_RESOURCE_VIEW_DESC, \ + ID3D11Resource) \ + OP(NAME, UnorderedAccessView, ID3D11UnorderedAccessView, D3D11_UNORDERED_ACCESS_VIEW_DESC, \ + ID3D11Resource) \ + OP(NAME, Texture2D, ID3D11Texture2D, D3D11_TEXTURE2D_DESC, const D3D11_SUBRESOURCE_DATA) \ + OP(NAME, Texture3D, ID3D11Texture3D, D3D11_TEXTURE3D_DESC, const D3D11_SUBRESOURCE_DATA) \ + OP(NAME, VertexShader, ID3D11VertexShader, ShaderData, void) + +#define ANGLE_RESOURCE_TYPE_LIST(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) RESTYPE, + +enum class ResourceType +{ + ANGLE_RESOURCE_TYPE_OP(List, ANGLE_RESOURCE_TYPE_LIST) Last +}; + +#undef ANGLE_RESOURCE_TYPE_LIST + +constexpr size_t ResourceTypeIndex(ResourceType resourceType) +{ + return static_cast(resourceType); +} + +constexpr size_t NumResourceTypes = ResourceTypeIndex(ResourceType::Last); + +#define ANGLE_RESOURCE_TYPE_TO_D3D11(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \ + \ + template <> \ + struct NAME \ + { \ + using Value = D3D11TYPE; \ + }; + +#define ANGLE_RESOURCE_TYPE_TO_DESC(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \ + \ + template <> \ + struct NAME \ + { \ + using Value = DESCTYPE; \ + }; + +#define ANGLE_RESOURCE_TYPE_TO_INIT_DATA(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \ + \ + template <> \ + struct NAME \ + { \ + using Value = INITDATATYPE; \ + }; + +#define ANGLE_RESOURCE_TYPE_TO_TYPE(NAME, OP) \ + template \ + struct NAME; \ + ANGLE_RESOURCE_TYPE_OP(NAME, OP) \ + \ + template \ + struct NAME \ + {}; \ + \ + template \ + using Get##NAME = typename NAME::Value; + +ANGLE_RESOURCE_TYPE_TO_TYPE(D3D11Type, ANGLE_RESOURCE_TYPE_TO_D3D11) +ANGLE_RESOURCE_TYPE_TO_TYPE(DescType, ANGLE_RESOURCE_TYPE_TO_DESC) +ANGLE_RESOURCE_TYPE_TO_TYPE(InitDataType, ANGLE_RESOURCE_TYPE_TO_INIT_DATA) + +#undef ANGLE_RESOURCE_TYPE_TO_D3D11 +#undef ANGLE_RESOURCE_TYPE_TO_DESC +#undef ANGLE_RESOURCE_TYPE_TO_INIT_DATA +#undef ANGLE_RESOURCE_TYPE_TO_TYPE + +#define ANGLE_TYPE_TO_RESOURCE_TYPE(NAME, OP) \ + template \ + struct NAME; \ + ANGLE_RESOURCE_TYPE_OP(NAME, OP) \ + \ + template \ + struct NAME \ + {}; \ + \ + template \ + constexpr ResourceType Get##NAME() \ + { \ + return NAME::Value; \ + } + +#define ANGLE_D3D11_TO_RESOURCE_TYPE(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \ + \ + template <> \ + struct NAME \ + { \ + static constexpr ResourceType Value = ResourceType::RESTYPE; \ + }; + +ANGLE_TYPE_TO_RESOURCE_TYPE(ResourceTypeFromD3D11, ANGLE_D3D11_TO_RESOURCE_TYPE) + +#undef ANGLE_D3D11_TO_RESOURCE_TYPE +#undef ANGLE_TYPE_TO_RESOURCE_TYPE + +template +using GetDescFromD3D11 = GetDescType::Value>; + +template +using GetInitDataFromD3D11 = GetInitDataType::Value>; + +template +constexpr size_t ResourceTypeIndex() +{ + return static_cast(GetResourceTypeFromD3D11()); +} + +template +struct TypedData +{ + TypedData() {} + ~TypedData(); + + T *object = nullptr; + ResourceManager11 *manager = nullptr; +}; + +// Smart pointer type. Wraps the resource and a factory for safe deletion. +template class Pointer, typename DataT> +class Resource11Base : angle::NonCopyable +{ + public: + T *get() const { return mData->object; } + T *const *getPointer() const { return &mData->object; } + + void setInternalName(const char *name) + { + mInternalDebugName = name; + UpdateDebugNameWithD3D(); + } + + void setKHRDebugLabel(const std::string *label) + { + mKhrDebugName = label; + UpdateDebugNameWithD3D(); + } + + void setLabels(const char *name, const std::string *label) + { + mInternalDebugName = name; + mKhrDebugName = label; + UpdateDebugNameWithD3D(); + } + + void set(T *object) + { + ASSERT(!valid()); + mData->object = object; + } + + bool valid() const { return (mData->object != nullptr); } + + void reset() + { + if (valid()) + mData.reset(new DataT()); + } + + ResourceSerial getSerial() const + { + return ResourceSerial(reinterpret_cast(mData->object)); + } + + protected: + friend class TextureHelper11; + + Resource11Base() : mData(new DataT()) {} + + Resource11Base(Resource11Base &&movedObj) : mData(new DataT()) + { + std::swap(mData, movedObj.mData); + } + + virtual ~Resource11Base() { mData.reset(); } + + Resource11Base &operator=(Resource11Base &&movedObj) + { + std::swap(mData, movedObj.mData); + return *this; + } + + Pointer mData; + + private: + void UpdateDebugNameWithD3D() + { + d3d11::SetDebugName(mData->object, mInternalDebugName, mKhrDebugName); + } + + const std::string *mKhrDebugName = nullptr; + const char *mInternalDebugName = nullptr; +}; + +template +using UniquePtr = typename std::unique_ptr>; + +template +class Resource11 : public Resource11Base> +{ + public: + Resource11() {} + Resource11(Resource11 &&other) + : Resource11Base>(std::move(other)) + {} + Resource11 &operator=(Resource11 &&other) + { + std::swap(this->mData, other.mData); + return *this; + } + + private: + template + friend class SharedResource11; + friend class ResourceManager11; + + Resource11(ResourceT *object, ResourceManager11 *manager) + { + this->mData->object = object; + this->mData->manager = manager; + } +}; + +template +class SharedResource11 : public Resource11Base> +{ + public: + SharedResource11() {} + SharedResource11(SharedResource11 &&movedObj) + : Resource11Base>(std::move(movedObj)) + {} + + SharedResource11 &operator=(SharedResource11 &&other) + { + std::swap(this->mData, other.mData); + return *this; + } + + SharedResource11 makeCopy() const + { + SharedResource11 copy; + copy.mData = this->mData; + return std::move(copy); + } + + private: + friend class ResourceManager11; + SharedResource11(Resource11 &&obj) : Resource11Base>() + { + std::swap(this->mData->manager, obj.mData->manager); + + // Can't use std::swap because of ID3D11Resource. + auto temp = this->mData->object; + this->mData->object = obj.mData->object; + obj.mData->object = static_cast(temp); + } +}; + +class ResourceManager11 final : angle::NonCopyable +{ + public: + ResourceManager11(); + ~ResourceManager11(); + + template + angle::Result allocate(d3d::Context *context, + Renderer11 *renderer, + const GetDescFromD3D11 *desc, + GetInitDataFromD3D11 *initData, + Resource11 *resourceOut); + + template + angle::Result allocate(d3d::Context *context, + Renderer11 *renderer, + const GetDescFromD3D11 *desc, + GetInitDataFromD3D11 *initData, + SharedResource11 *sharedRes) + { + Resource11 res; + ANGLE_TRY(allocate(context, renderer, desc, initData, &res)); + *sharedRes = std::move(res); + return angle::Result::Continue; + } + + template + void onRelease(T *resource) + { + onReleaseGeneric(GetResourceTypeFromD3D11(), resource); + } + + void onReleaseGeneric(ResourceType resourceType, ID3D11DeviceChild *resource); + + void setAllocationsInitialized(bool initialize); + + private: + void incrResource(ResourceType resourceType, uint64_t memorySize); + void decrResource(ResourceType resourceType, uint64_t memorySize); + + template + GetInitDataFromD3D11 *createInitDataIfNeeded(const GetDescFromD3D11 *desc); + + bool mInitializeAllocations; + + std::array mAllocatedResourceCounts; + std::array mAllocatedResourceDeviceMemory; + angle::MemoryBuffer mZeroMemory; + + std::vector mShadowInitData; +}; + +template +TypedData::~TypedData() +{ + if (object) + { + // We can have a nullptr factory when holding passed-in resources. + if (manager) + { + manager->onRelease(object); + } + object->Release(); + } +} + +#define ANGLE_RESOURCE_TYPE_CLASS(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \ + using RESTYPE = Resource11; + +namespace d3d11 +{ +ANGLE_RESOURCE_TYPE_OP(ClassList, ANGLE_RESOURCE_TYPE_CLASS) + +using SharedSRV = SharedResource11; +using SharedUAV = SharedResource11; +} // namespace d3d11 + +#undef ANGLE_RESOURCE_TYPE_CLASS + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_RESOURCEFACTORY11_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.cpp new file mode 100644 index 0000000000..a30ca417c1 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.cpp @@ -0,0 +1,116 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ShaderExecutable11.cpp: Implements a D3D11-specific class to contain shader +// executable implementation details. + +#include "libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h" + +#include "libANGLE/Context.h" +#include "libANGLE/renderer/d3d/d3d11/Context11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" + +namespace rx +{ + +ShaderExecutable11::ShaderExecutable11(const void *function, + size_t length, + d3d11::PixelShader &&executable) + : ShaderExecutableD3D(function, length), + mPixelExecutable(std::move(executable)), + mVertexExecutable(), + mGeometryExecutable(), + mStreamOutExecutable(), + mComputeExecutable() +{} + +ShaderExecutable11::ShaderExecutable11(const void *function, + size_t length, + d3d11::VertexShader &&executable, + d3d11::GeometryShader &&streamOut) + : ShaderExecutableD3D(function, length), + mPixelExecutable(), + mVertexExecutable(std::move(executable)), + mGeometryExecutable(), + mStreamOutExecutable(std::move(streamOut)), + mComputeExecutable() +{} + +ShaderExecutable11::ShaderExecutable11(const void *function, + size_t length, + d3d11::GeometryShader &&executable) + : ShaderExecutableD3D(function, length), + mPixelExecutable(), + mVertexExecutable(), + mGeometryExecutable(std::move(executable)), + mStreamOutExecutable(), + mComputeExecutable() +{} + +ShaderExecutable11::ShaderExecutable11(const void *function, + size_t length, + d3d11::ComputeShader &&executable) + : ShaderExecutableD3D(function, length), + mPixelExecutable(), + mVertexExecutable(), + mGeometryExecutable(), + mStreamOutExecutable(), + mComputeExecutable(std::move(executable)) +{} + +ShaderExecutable11::~ShaderExecutable11() {} + +const d3d11::VertexShader &ShaderExecutable11::getVertexShader() const +{ + return mVertexExecutable; +} + +const d3d11::PixelShader &ShaderExecutable11::getPixelShader() const +{ + return mPixelExecutable; +} + +const d3d11::GeometryShader &ShaderExecutable11::getGeometryShader() const +{ + return mGeometryExecutable; +} + +const d3d11::GeometryShader &ShaderExecutable11::getStreamOutShader() const +{ + return mStreamOutExecutable; +} + +const d3d11::ComputeShader &ShaderExecutable11::getComputeShader() const +{ + return mComputeExecutable; +} + +UniformStorage11::UniformStorage11(size_t initialSize) + : UniformStorageD3D(initialSize), mConstantBuffer() +{} + +UniformStorage11::~UniformStorage11() {} + +angle::Result UniformStorage11::getConstantBuffer(const gl::Context *context, + Renderer11 *renderer, + const d3d11::Buffer **bufferOut) +{ + if (size() > 0 && !mConstantBuffer.valid()) + { + D3D11_BUFFER_DESC desc = {}; + desc.ByteWidth = static_cast(size()); + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + + ANGLE_TRY( + renderer->allocateResource(GetImplAs(context), desc, &mConstantBuffer)); + } + + *bufferOut = &mConstantBuffer; + return angle::Result::Continue; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h new file mode 100644 index 0000000000..75c71b3238 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h @@ -0,0 +1,69 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ShaderExecutable11.h: Defines a D3D11-specific class to contain shader +// executable implementation details. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_SHADEREXECUTABLE11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_SHADEREXECUTABLE11_H_ + +#include "libANGLE/renderer/d3d/ShaderExecutableD3D.h" +#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h" + +namespace gl +{ +class Context; +} // namespace gl + +namespace rx +{ +class Renderer11; +class UniformStorage11; + +class ShaderExecutable11 : public ShaderExecutableD3D +{ + public: + ShaderExecutable11(const void *function, size_t length, d3d11::PixelShader &&executable); + ShaderExecutable11(const void *function, + size_t length, + d3d11::VertexShader &&executable, + d3d11::GeometryShader &&streamOut); + ShaderExecutable11(const void *function, size_t length, d3d11::GeometryShader &&executable); + ShaderExecutable11(const void *function, size_t length, d3d11::ComputeShader &&executable); + + ~ShaderExecutable11() override; + + const d3d11::PixelShader &getPixelShader() const; + const d3d11::VertexShader &getVertexShader() const; + const d3d11::GeometryShader &getGeometryShader() const; + const d3d11::GeometryShader &getStreamOutShader() const; + const d3d11::ComputeShader &getComputeShader() const; + + private: + d3d11::PixelShader mPixelExecutable; + d3d11::VertexShader mVertexExecutable; + d3d11::GeometryShader mGeometryExecutable; + d3d11::GeometryShader mStreamOutExecutable; + d3d11::ComputeShader mComputeExecutable; +}; + +class UniformStorage11 : public UniformStorageD3D +{ + public: + UniformStorage11(size_t initialSize); + ~UniformStorage11() override; + + angle::Result getConstantBuffer(const gl::Context *context, + Renderer11 *renderer, + const d3d11::Buffer **bufferOut); + + private: + d3d11::Buffer mConstantBuffer; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_SHADEREXECUTABLE11_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp new file mode 100644 index 0000000000..194c89d1c7 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp @@ -0,0 +1,4004 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// StateManager11.cpp: Defines a class for caching D3D11 state + +#include "libANGLE/renderer/d3d/d3d11/StateManager11.h" + +#include "common/angleutils.h" +#include "common/bitset_utils.h" +#include "common/mathutil.h" +#include "common/utilities.h" +#include "libANGLE/Context.h" +#include "libANGLE/Query.h" +#include "libANGLE/Surface.h" +#include "libANGLE/VertexArray.h" +#include "libANGLE/renderer/d3d/DisplayD3D.h" +#include "libANGLE/renderer/d3d/TextureD3D.h" +#include "libANGLE/renderer/d3d/d3d11/Buffer11.h" +#include "libANGLE/renderer/d3d/d3d11/Context11.h" +#include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h" +#include "libANGLE/renderer/d3d/d3d11/IndexBuffer11.h" +#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h" +#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h" +#include "libANGLE/renderer/d3d/d3d11/TransformFeedback11.h" +#include "libANGLE/renderer/d3d/d3d11/VertexArray11.h" +#include "libANGLE/renderer/d3d/d3d11/VertexBuffer11.h" + +namespace rx +{ + +namespace +{ +bool ImageIndexConflictsWithSRV(const gl::ImageIndex &index, D3D11_SHADER_RESOURCE_VIEW_DESC desc) +{ + unsigned mipLevel = index.getLevelIndex(); + gl::TextureType textureType = index.getType(); + + switch (desc.ViewDimension) + { + case D3D11_SRV_DIMENSION_TEXTURE2D: + { + bool allLevels = (desc.Texture2D.MipLevels == std::numeric_limits::max()); + unsigned int maxSrvMip = desc.Texture2D.MipLevels + desc.Texture2D.MostDetailedMip; + maxSrvMip = allLevels ? INT_MAX : maxSrvMip; + + unsigned mipMin = index.getLevelIndex(); + unsigned mipMax = INT_MAX; + + return textureType == gl::TextureType::_2D && + gl::RangeUI(mipMin, mipMax) + .intersects(gl::RangeUI(desc.Texture2D.MostDetailedMip, maxSrvMip)); + } + + case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: + { + GLint layerIndex = index.getLayerIndex(); + + bool allLevels = (desc.Texture2DArray.MipLevels == std::numeric_limits::max()); + unsigned int maxSrvMip = + desc.Texture2DArray.MipLevels + desc.Texture2DArray.MostDetailedMip; + maxSrvMip = allLevels ? INT_MAX : maxSrvMip; + + unsigned maxSlice = desc.Texture2DArray.FirstArraySlice + desc.Texture2DArray.ArraySize; + + // Cube maps can be mapped to Texture2DArray SRVs + return (textureType == gl::TextureType::_2DArray || + textureType == gl::TextureType::CubeMap) && + desc.Texture2DArray.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip && + desc.Texture2DArray.FirstArraySlice <= static_cast(layerIndex) && + static_cast(layerIndex) < maxSlice; + } + + case D3D11_SRV_DIMENSION_TEXTURECUBE: + { + bool allLevels = (desc.TextureCube.MipLevels == std::numeric_limits::max()); + unsigned int maxSrvMip = desc.TextureCube.MipLevels + desc.TextureCube.MostDetailedMip; + maxSrvMip = allLevels ? INT_MAX : maxSrvMip; + + return textureType == gl::TextureType::CubeMap && + desc.TextureCube.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip; + } + + case D3D11_SRV_DIMENSION_TEXTURE3D: + { + bool allLevels = (desc.Texture3D.MipLevels == std::numeric_limits::max()); + unsigned int maxSrvMip = desc.Texture3D.MipLevels + desc.Texture3D.MostDetailedMip; + maxSrvMip = allLevels ? INT_MAX : maxSrvMip; + + return textureType == gl::TextureType::_3D && + desc.Texture3D.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip; + } + default: + // We only handle the cases corresponding to valid image indexes + UNIMPLEMENTED(); + } + + return false; +} + +bool ImageIndexConflictsWithUAV(const gl::ImageIndex &index, D3D11_UNORDERED_ACCESS_VIEW_DESC desc) +{ + unsigned mipLevel = index.getLevelIndex(); + gl::TextureType textureType = index.getType(); + + switch (desc.ViewDimension) + { + case D3D11_UAV_DIMENSION_TEXTURE2D: + { + return textureType == gl::TextureType::_2D && mipLevel == desc.Texture2D.MipSlice; + } + + case D3D11_UAV_DIMENSION_TEXTURE2DARRAY: + { + GLint layerIndex = index.getLayerIndex(); + unsigned mipSlice = desc.Texture2DArray.MipSlice; + unsigned firstArraySlice = desc.Texture2DArray.FirstArraySlice; + unsigned lastArraySlice = firstArraySlice + desc.Texture2DArray.ArraySize; + + return (textureType == gl::TextureType::_2DArray || + textureType == gl::TextureType::CubeMap) && + (mipLevel == mipSlice && gl::RangeUI(firstArraySlice, lastArraySlice) + .contains(static_cast(layerIndex))); + } + + case D3D11_UAV_DIMENSION_TEXTURE3D: + { + GLint layerIndex = index.getLayerIndex(); + unsigned mipSlice = desc.Texture3D.MipSlice; + unsigned firstWSlice = desc.Texture3D.FirstWSlice; + unsigned lastWSlice = firstWSlice + desc.Texture3D.WSize; + + return textureType == gl::TextureType::_3D && + (mipLevel == mipSlice && + gl::RangeUI(firstWSlice, lastWSlice).contains(static_cast(layerIndex))); + } + default: + return false; + } +} + +// Does *not* increment the resource ref count!! +ID3D11Resource *GetViewResource(ID3D11View *view) +{ + ID3D11Resource *resource = nullptr; + ASSERT(view); + view->GetResource(&resource); + resource->Release(); + return resource; +} + +int GetWrapBits(GLenum wrap) +{ + switch (wrap) + { + case GL_CLAMP_TO_EDGE: + return 0x0; + case GL_REPEAT: + return 0x1; + case GL_MIRRORED_REPEAT: + return 0x2; + case GL_CLAMP_TO_BORDER: + return 0x3; + default: + UNREACHABLE(); + return 0; + } +} + +Optional FindFirstNonInstanced( + const std::vector ¤tAttributes) +{ + for (size_t index = 0; index < currentAttributes.size(); ++index) + { + if (currentAttributes[index]->divisor == 0) + { + return Optional(index); + } + } + + return Optional::Invalid(); +} + +void SortAttributesByLayout(const ProgramD3D &programD3D, + const std::vector &vertexArrayAttribs, + const std::vector ¤tValueAttribs, + AttribIndexArray *sortedD3DSemanticsOut, + std::vector *sortedAttributesOut) +{ + sortedAttributesOut->clear(); + + const AttribIndexArray &locationToSemantic = programD3D.getAttribLocationToD3DSemantics(); + const gl::ProgramExecutable &executable = programD3D.getState().getExecutable(); + + for (auto locationIndex : executable.getActiveAttribLocationsMask()) + { + int d3dSemantic = locationToSemantic[locationIndex]; + if (sortedAttributesOut->size() <= static_cast(d3dSemantic)) + { + sortedAttributesOut->resize(d3dSemantic + 1); + } + + (*sortedD3DSemanticsOut)[d3dSemantic] = d3dSemantic; + + const auto *arrayAttrib = &vertexArrayAttribs[locationIndex]; + if (arrayAttrib->attribute && arrayAttrib->attribute->enabled) + { + (*sortedAttributesOut)[d3dSemantic] = arrayAttrib; + } + else + { + ASSERT(currentValueAttribs[locationIndex].attribute); + (*sortedAttributesOut)[d3dSemantic] = ¤tValueAttribs[locationIndex]; + } + } +} + +void UpdateUniformBuffer(ID3D11DeviceContext *deviceContext, + UniformStorage11 *storage, + const d3d11::Buffer *buffer) +{ + deviceContext->UpdateSubresource(buffer->get(), 0, nullptr, storage->getDataPointer(0, 0), 0, + 0); +} + +size_t GetReservedBufferCount(bool usesPointSpriteEmulation) +{ + return usesPointSpriteEmulation ? 1 : 0; +} + +bool CullsEverything(const gl::State &glState) +{ + return (glState.getRasterizerState().cullFace && + glState.getRasterizerState().cullMode == gl::CullFaceMode::FrontAndBack); +} +} // anonymous namespace + +// StateManager11::ViewCache Implementation. +template +StateManager11::ViewCache::ViewCache() : mHighestUsedView(0) +{} + +template +StateManager11::ViewCache::~ViewCache() +{} + +template +void StateManager11::ViewCache::update(size_t resourceIndex, ViewType *view) +{ + ASSERT(resourceIndex < mCurrentViews.size()); + ViewRecord *record = &mCurrentViews[resourceIndex]; + + record->view = reinterpret_cast(view); + if (view) + { + record->resource = reinterpret_cast(GetViewResource(view)); + view->GetDesc(&record->desc); + mHighestUsedView = std::max(resourceIndex + 1, mHighestUsedView); + } + else + { + record->resource = 0; + + if (resourceIndex + 1 == mHighestUsedView) + { + do + { + --mHighestUsedView; + } while (mHighestUsedView > 0 && mCurrentViews[mHighestUsedView].view == 0); + } + } +} + +template +void StateManager11::ViewCache::clear() +{ + if (mCurrentViews.empty()) + { + return; + } + + memset(&mCurrentViews[0], 0, sizeof(ViewRecord) * mCurrentViews.size()); + mHighestUsedView = 0; +} + +StateManager11::SRVCache *StateManager11::getSRVCache(gl::ShaderType shaderType) +{ + ASSERT(shaderType != gl::ShaderType::InvalidEnum); + return &mCurShaderSRVs[shaderType]; +} + +// ShaderConstants11 implementation +ShaderConstants11::ShaderConstants11() : mNumActiveShaderSamplers({}) +{ + mShaderConstantsDirty.set(); +} + +ShaderConstants11::~ShaderConstants11() {} + +void ShaderConstants11::init(const gl::Caps &caps) +{ + for (gl::ShaderType shaderType : gl::AllShaderTypes()) + { + mShaderSamplerMetadata[shaderType].resize(caps.maxShaderTextureImageUnits[shaderType]); + mShaderReadonlyImageMetadata[shaderType].resize(caps.maxShaderImageUniforms[shaderType]); + mShaderImageMetadata[shaderType].resize(caps.maxShaderImageUniforms[shaderType]); + } +} + +size_t ShaderConstants11::GetShaderConstantsStructSize(gl::ShaderType shaderType) +{ + switch (shaderType) + { + case gl::ShaderType::Vertex: + return sizeof(Vertex); + case gl::ShaderType::Fragment: + return sizeof(Pixel); + case gl::ShaderType::Compute: + return sizeof(Compute); + + // TODO(jiawei.shao@intel.com): return geometry shader constant struct size + case gl::ShaderType::Geometry: + return 0u; + + default: + UNREACHABLE(); + return 0u; + } +} + +size_t ShaderConstants11::getRequiredBufferSize(gl::ShaderType shaderType) const +{ + ASSERT(shaderType != gl::ShaderType::InvalidEnum); + return GetShaderConstantsStructSize(shaderType) + + mShaderSamplerMetadata[shaderType].size() * sizeof(SamplerMetadata) + + mShaderImageMetadata[shaderType].size() * sizeof(ImageMetadata) + + mShaderReadonlyImageMetadata[shaderType].size() * sizeof(ImageMetadata); +} + +void ShaderConstants11::markDirty() +{ + mShaderConstantsDirty.set(); + mNumActiveShaderSamplers.fill(0); +} + +bool ShaderConstants11::updateSamplerMetadata(SamplerMetadata *data, + const gl::Texture &texture, + const gl::SamplerState &samplerState) +{ + bool dirty = false; + unsigned int baseLevel = texture.getTextureState().getEffectiveBaseLevel(); + gl::TextureTarget target = (texture.getType() == gl::TextureType::CubeMap) + ? gl::kCubeMapTextureTargetMin + : gl::NonCubeTextureTypeToTarget(texture.getType()); + GLenum sizedFormat = texture.getFormat(target, baseLevel).info->sizedInternalFormat; + if (data->baseLevel != static_cast(baseLevel)) + { + data->baseLevel = static_cast(baseLevel); + dirty = true; + } + + // Some metadata is needed only for integer textures. We avoid updating the constant buffer + // unnecessarily by changing the data only in case the texture is an integer texture and + // the values have changed. + bool needIntegerTextureMetadata = false; + // internalFormatBits == 0 means a 32-bit texture in the case of integer textures. + int internalFormatBits = 0; + switch (sizedFormat) + { + case GL_RGBA32I: + case GL_RGBA32UI: + case GL_RGB32I: + case GL_RGB32UI: + case GL_RG32I: + case GL_RG32UI: + case GL_R32I: + case GL_R32UI: + needIntegerTextureMetadata = true; + break; + case GL_RGBA16I: + case GL_RGBA16UI: + case GL_RGB16I: + case GL_RGB16UI: + case GL_RG16I: + case GL_RG16UI: + case GL_R16I: + case GL_R16UI: + needIntegerTextureMetadata = true; + internalFormatBits = 16; + break; + case GL_RGBA8I: + case GL_RGBA8UI: + case GL_RGB8I: + case GL_RGB8UI: + case GL_RG8I: + case GL_RG8UI: + case GL_R8I: + case GL_R8UI: + needIntegerTextureMetadata = true; + internalFormatBits = 8; + break; + case GL_RGB10_A2UI: + needIntegerTextureMetadata = true; + internalFormatBits = 10; + break; + default: + break; + } + if (needIntegerTextureMetadata) + { + if (data->internalFormatBits != internalFormatBits) + { + data->internalFormatBits = internalFormatBits; + dirty = true; + } + // Pack the wrap values into one integer so we can fit all the metadata in two 4-integer + // vectors. + GLenum wrapS = samplerState.getWrapS(); + GLenum wrapT = samplerState.getWrapT(); + GLenum wrapR = samplerState.getWrapR(); + int wrapModes = GetWrapBits(wrapS) | (GetWrapBits(wrapT) << 2) | (GetWrapBits(wrapR) << 4); + if (data->wrapModes != wrapModes) + { + data->wrapModes = wrapModes; + dirty = true; + } + + const angle::ColorGeneric &borderColor(samplerState.getBorderColor()); + constexpr int kBlack[4] = {}; + const void *const intBorderColor = (borderColor.type == angle::ColorGeneric::Type::Float) + ? kBlack + : borderColor.colorI.data(); + ASSERT(static_cast(borderColor.colorI.data()) == + static_cast(borderColor.colorUI.data())); + if (memcmp(data->intBorderColor, intBorderColor, sizeof(data->intBorderColor)) != 0) + { + memcpy(data->intBorderColor, intBorderColor, sizeof(data->intBorderColor)); + dirty = true; + } + } + + return dirty; +} + +bool ShaderConstants11::updateImageMetadata(ImageMetadata *data, const gl::ImageUnit &imageUnit) +{ + bool dirty = false; + + if (data->layer != static_cast(imageUnit.layer)) + { + data->layer = static_cast(imageUnit.layer); + dirty = true; + } + + if (data->level != static_cast(imageUnit.level)) + { + data->level = static_cast(imageUnit.level); + dirty = true; + } + + return dirty; +} + +void ShaderConstants11::setComputeWorkGroups(GLuint numGroupsX, + GLuint numGroupsY, + GLuint numGroupsZ) +{ + mCompute.numWorkGroups[0] = numGroupsX; + mCompute.numWorkGroups[1] = numGroupsY; + mCompute.numWorkGroups[2] = numGroupsZ; + mShaderConstantsDirty.set(gl::ShaderType::Compute); +} + +void ShaderConstants11::setMultiviewWriteToViewportIndex(GLfloat index) +{ + mVertex.multiviewWriteToViewportIndex = index; + mPixel.multiviewWriteToViewportIndex = index; + mShaderConstantsDirty.set(gl::ShaderType::Vertex); + mShaderConstantsDirty.set(gl::ShaderType::Fragment); +} + +void ShaderConstants11::onViewportChange(const gl::Rectangle &glViewport, + const D3D11_VIEWPORT &dxViewport, + const gl::Offset &glFragCoordOffset, + bool is9_3, + bool presentPathFast) +{ + mShaderConstantsDirty.set(gl::ShaderType::Vertex); + mShaderConstantsDirty.set(gl::ShaderType::Fragment); + + // On Feature Level 9_*, we must emulate large and/or negative viewports in the shaders + // using viewAdjust (like the D3D9 renderer). + if (is9_3) + { + mVertex.viewAdjust[0] = static_cast((glViewport.width - dxViewport.Width) + + 2 * (glViewport.x - dxViewport.TopLeftX)) / + dxViewport.Width; + mVertex.viewAdjust[1] = static_cast((glViewport.height - dxViewport.Height) + + 2 * (glViewport.y - dxViewport.TopLeftY)) / + dxViewport.Height; + mVertex.viewAdjust[2] = static_cast(glViewport.width) / dxViewport.Width; + mVertex.viewAdjust[3] = static_cast(glViewport.height) / dxViewport.Height; + } + + mPixel.viewCoords[0] = glViewport.width * 0.5f; + mPixel.viewCoords[1] = glViewport.height * 0.5f; + mPixel.viewCoords[2] = glViewport.x + (glViewport.width * 0.5f); + mPixel.viewCoords[3] = glViewport.y + (glViewport.height * 0.5f); + + // Instanced pointsprite emulation requires ViewCoords to be defined in the + // the vertex shader. + mVertex.viewCoords[0] = mPixel.viewCoords[0]; + mVertex.viewCoords[1] = mPixel.viewCoords[1]; + mVertex.viewCoords[2] = mPixel.viewCoords[2]; + mVertex.viewCoords[3] = mPixel.viewCoords[3]; + + const float zNear = dxViewport.MinDepth; + const float zFar = dxViewport.MaxDepth; + + mPixel.depthFront[0] = (zFar - zNear) * 0.5f; + mPixel.depthFront[1] = (zNear + zFar) * 0.5f; + + mVertex.depthRange[0] = zNear; + mVertex.depthRange[1] = zFar; + mVertex.depthRange[2] = zFar - zNear; + + mPixel.depthRange[0] = zNear; + mPixel.depthRange[1] = zFar; + mPixel.depthRange[2] = zFar - zNear; + + mPixel.viewScale[0] = 1.0f; + mPixel.viewScale[1] = presentPathFast ? 1.0f : -1.0f; + // Updates to the multiviewWriteToViewportIndex member are to be handled whenever the draw + // framebuffer's layout is changed. + + mVertex.viewScale[0] = mPixel.viewScale[0]; + mVertex.viewScale[1] = mPixel.viewScale[1]; + + mPixel.fragCoordOffset[0] = static_cast(glFragCoordOffset.x); + mPixel.fragCoordOffset[1] = static_cast(glFragCoordOffset.y); +} + +// Update the ShaderConstants with a new first vertex and return whether the update dirties them. +ANGLE_INLINE bool ShaderConstants11::onFirstVertexChange(GLint firstVertex) +{ + // firstVertex should already include baseVertex, if any. + uint32_t newFirstVertex = static_cast(firstVertex); + + bool firstVertexDirty = (mVertex.firstVertex != newFirstVertex); + if (firstVertexDirty) + { + mVertex.firstVertex = newFirstVertex; + mShaderConstantsDirty.set(gl::ShaderType::Vertex); + } + return firstVertexDirty; +} + +void ShaderConstants11::onSamplerChange(gl::ShaderType shaderType, + unsigned int samplerIndex, + const gl::Texture &texture, + const gl::SamplerState &samplerState) +{ + ASSERT(shaderType != gl::ShaderType::InvalidEnum); + if (updateSamplerMetadata(&mShaderSamplerMetadata[shaderType][samplerIndex], texture, + samplerState)) + { + mNumActiveShaderSamplers[shaderType] = 0; + } +} + +bool ShaderConstants11::onImageChange(gl::ShaderType shaderType, + unsigned int imageIndex, + const gl::ImageUnit &imageUnit) +{ + ASSERT(shaderType != gl::ShaderType::InvalidEnum); + bool dirty = false; + if (imageUnit.access == GL_READ_ONLY) + { + if (updateImageMetadata(&mShaderReadonlyImageMetadata[shaderType][imageIndex], imageUnit)) + { + mNumActiveShaderReadonlyImages[shaderType] = 0; + dirty = true; + } + } + else + { + if (updateImageMetadata(&mShaderImageMetadata[shaderType][imageIndex], imageUnit)) + { + mNumActiveShaderImages[shaderType] = 0; + dirty = true; + } + } + return dirty; +} + +void ShaderConstants11::onClipControlChange(bool lowerLeft, bool zeroToOne) +{ + mVertex.clipControlOrigin = lowerLeft ? -1.0f : 1.0f; + mVertex.clipControlZeroToOne = zeroToOne ? 1.0f : 0.0f; + mShaderConstantsDirty.set(gl::ShaderType::Vertex); +} + +angle::Result ShaderConstants11::updateBuffer(const gl::Context *context, + Renderer11 *renderer, + gl::ShaderType shaderType, + const ProgramD3D &programD3D, + const d3d11::Buffer &driverConstantBuffer) +{ + // Re-upload the sampler meta-data if the current program uses more samplers + // than we previously uploaded. + const int numSamplers = programD3D.getUsedSamplerRange(shaderType).length(); + const int numReadonlyImages = programD3D.getUsedImageRange(shaderType, true).length(); + const int numImages = programD3D.getUsedImageRange(shaderType, false).length(); + + const bool dirty = mShaderConstantsDirty[shaderType] || + (mNumActiveShaderSamplers[shaderType] < numSamplers) || + (mNumActiveShaderReadonlyImages[shaderType] < numReadonlyImages) || + (mNumActiveShaderImages[shaderType] < numImages); + + const size_t dataSize = GetShaderConstantsStructSize(shaderType); + const uint8_t *samplerData = + reinterpret_cast(mShaderSamplerMetadata[shaderType].data()); + const size_t samplerDataSize = sizeof(SamplerMetadata) * numSamplers; + const uint8_t *readonlyImageData = + reinterpret_cast(mShaderReadonlyImageMetadata[shaderType].data()); + const size_t readonlyImageDataSize = sizeof(ImageMetadata) * numReadonlyImages; + const uint8_t *imageData = + reinterpret_cast(mShaderImageMetadata[shaderType].data()); + const size_t imageDataSize = sizeof(ImageMetadata) * numImages; + + mNumActiveShaderSamplers[shaderType] = numSamplers; + mNumActiveShaderReadonlyImages[shaderType] = numReadonlyImages; + mNumActiveShaderImages[shaderType] = numImages; + mShaderConstantsDirty.set(shaderType, false); + + const uint8_t *data = nullptr; + switch (shaderType) + { + case gl::ShaderType::Vertex: + data = reinterpret_cast(&mVertex); + break; + case gl::ShaderType::Fragment: + data = reinterpret_cast(&mPixel); + break; + case gl::ShaderType::Compute: + data = reinterpret_cast(&mCompute); + break; + default: + UNREACHABLE(); + break; + } + + ASSERT(driverConstantBuffer.valid()); + + if (!dirty) + { + return angle::Result::Continue; + } + + // Previous buffer contents are discarded, so we need to refresh the whole buffer. + D3D11_MAPPED_SUBRESOURCE mapping = {}; + ANGLE_TRY(renderer->mapResource(context, driverConstantBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, + 0, &mapping)); + + memcpy(mapping.pData, data, dataSize); + memcpy(static_cast(mapping.pData) + dataSize, samplerData, + sizeof(SamplerMetadata) * numSamplers); + + memcpy(static_cast(mapping.pData) + dataSize + samplerDataSize, readonlyImageData, + readonlyImageDataSize); + memcpy( + static_cast(mapping.pData) + dataSize + samplerDataSize + readonlyImageDataSize, + imageData, imageDataSize); + renderer->getDeviceContext()->Unmap(driverConstantBuffer.get(), 0); + + return angle::Result::Continue; +} + +StateManager11::StateManager11(Renderer11 *renderer) + : mRenderer(renderer), + mInternalDirtyBits(), + mCurSampleAlphaToCoverage(false), + mCurBlendStateExt(), + mCurBlendColor(0, 0, 0, 0), + mCurSampleMask(0), + mCurStencilRef(0), + mCurStencilBackRef(0), + mCurStencilSize(0), + mCurScissorEnabled(false), + mCurScissorRect(), + mCurViewport(), + mCurNear(0.0f), + mCurFar(0.0f), + mViewportBounds(), + mRenderTargetIsDirty(true), + mCurPresentPathFastEnabled(false), + mCurPresentPathFastColorBufferHeight(0), + mDirtyCurrentValueAttribs(), + mCurrentValueAttribs(), + mCurrentInputLayout(), + mDirtyVertexBufferRange(gl::MAX_VERTEX_ATTRIBS, 0), + mCurrentPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_UNDEFINED), + mLastAppliedDrawMode(gl::PrimitiveMode::InvalidEnum), + mCullEverything(false), + mDirtySwizzles(false), + mAppliedIB(nullptr), + mAppliedIBFormat(DXGI_FORMAT_UNKNOWN), + mAppliedIBOffset(0), + mIndexBufferIsDirty(false), + mVertexDataManager(renderer), + mIndexDataManager(renderer), + mIsMultiviewEnabled(false), + mIndependentBlendStates(false), + mEmptySerial(mRenderer->generateSerial()), + mProgramD3D(nullptr), + mVertexArray11(nullptr), + mFramebuffer11(nullptr) +{ + mCurDepthStencilState.depthTest = false; + mCurDepthStencilState.depthFunc = GL_LESS; + mCurDepthStencilState.depthMask = true; + mCurDepthStencilState.stencilTest = false; + mCurDepthStencilState.stencilMask = true; + mCurDepthStencilState.stencilFail = GL_KEEP; + mCurDepthStencilState.stencilPassDepthFail = GL_KEEP; + mCurDepthStencilState.stencilPassDepthPass = GL_KEEP; + mCurDepthStencilState.stencilWritemask = static_cast(-1); + mCurDepthStencilState.stencilBackFunc = GL_ALWAYS; + mCurDepthStencilState.stencilBackMask = static_cast(-1); + mCurDepthStencilState.stencilBackFail = GL_KEEP; + mCurDepthStencilState.stencilBackPassDepthFail = GL_KEEP; + mCurDepthStencilState.stencilBackPassDepthPass = GL_KEEP; + mCurDepthStencilState.stencilBackWritemask = static_cast(-1); + + mCurRasterState.rasterizerDiscard = false; + mCurRasterState.cullFace = false; + mCurRasterState.cullMode = gl::CullFaceMode::Back; + mCurRasterState.frontFace = GL_CCW; + mCurRasterState.polygonOffsetFill = false; + mCurRasterState.polygonOffsetFactor = 0.0f; + mCurRasterState.polygonOffsetUnits = 0.0f; + mCurRasterState.pointDrawMode = false; + mCurRasterState.multiSample = false; + mCurRasterState.dither = false; + + // Start with all internal dirty bits set except the SRV and UAV bits. + mInternalDirtyBits.set(); + mInternalDirtyBits.reset(DIRTY_BIT_GRAPHICS_SRV_STATE); + mInternalDirtyBits.reset(DIRTY_BIT_GRAPHICS_UAV_STATE); + mInternalDirtyBits.reset(DIRTY_BIT_COMPUTE_SRV_STATE); + mInternalDirtyBits.reset(DIRTY_BIT_COMPUTE_UAV_STATE); + + mGraphicsDirtyBitsMask.set(); + mGraphicsDirtyBitsMask.reset(DIRTY_BIT_COMPUTE_SRV_STATE); + mGraphicsDirtyBitsMask.reset(DIRTY_BIT_COMPUTE_UAV_STATE); + mComputeDirtyBitsMask.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE); + mComputeDirtyBitsMask.set(DIRTY_BIT_PROGRAM_UNIFORMS); + mComputeDirtyBitsMask.set(DIRTY_BIT_DRIVER_UNIFORMS); + mComputeDirtyBitsMask.set(DIRTY_BIT_PROGRAM_UNIFORM_BUFFERS); + mComputeDirtyBitsMask.set(DIRTY_BIT_SHADERS); + mComputeDirtyBitsMask.set(DIRTY_BIT_COMPUTE_SRV_STATE); + mComputeDirtyBitsMask.set(DIRTY_BIT_COMPUTE_UAV_STATE); + + // Initially all current value attributes must be updated on first use. + mDirtyCurrentValueAttribs.set(); + + mCurrentVertexBuffers.fill(nullptr); + mCurrentVertexStrides.fill(std::numeric_limits::max()); + mCurrentVertexOffsets.fill(std::numeric_limits::max()); +} + +StateManager11::~StateManager11() {} + +template +void StateManager11::setShaderResourceInternal(gl::ShaderType shaderType, + UINT resourceSlot, + const SRVType *srv) +{ + auto *currentSRVs = getSRVCache(shaderType); + ASSERT(static_cast(resourceSlot) < currentSRVs->size()); + const ViewRecord &record = (*currentSRVs)[resourceSlot]; + + if (record.view != reinterpret_cast(srv)) + { + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + ID3D11ShaderResourceView *srvPtr = srv ? srv->get() : nullptr; + if (srvPtr) + { + uintptr_t resource = reinterpret_cast(GetViewResource(srvPtr)); + unsetConflictingUAVs(gl::PipelineType::GraphicsPipeline, gl::ShaderType::Compute, + resource, nullptr); + } + + switch (shaderType) + { + case gl::ShaderType::Vertex: + deviceContext->VSSetShaderResources(resourceSlot, 1, &srvPtr); + break; + case gl::ShaderType::Fragment: + deviceContext->PSSetShaderResources(resourceSlot, 1, &srvPtr); + break; + case gl::ShaderType::Compute: + { + if (srvPtr) + { + uintptr_t resource = reinterpret_cast(GetViewResource(srvPtr)); + unsetConflictingRTVs(resource); + } + deviceContext->CSSetShaderResources(resourceSlot, 1, &srvPtr); + break; + } + default: + UNREACHABLE(); + } + + currentSRVs->update(resourceSlot, srvPtr); + } +} + +template +void StateManager11::setUnorderedAccessViewInternal(UINT resourceSlot, + const UAVType *uav, + UAVList *uavList) +{ + ASSERT(static_cast(resourceSlot) < mCurComputeUAVs.size()); + const ViewRecord &record = mCurComputeUAVs[resourceSlot]; + + if (record.view != reinterpret_cast(uav)) + { + ID3D11UnorderedAccessView *uavPtr = uav ? uav->get() : nullptr; + // We need to make sure that resource being set to UnorderedAccessView slot |resourceSlot| + // is not bound on SRV. + if (uavPtr) + { + uintptr_t resource = reinterpret_cast(GetViewResource(uavPtr)); + unsetConflictingSRVs(gl::PipelineType::ComputePipeline, gl::ShaderType::Vertex, + resource, nullptr, false); + unsetConflictingSRVs(gl::PipelineType::ComputePipeline, gl::ShaderType::Fragment, + resource, nullptr, false); + unsetConflictingSRVs(gl::PipelineType::ComputePipeline, gl::ShaderType::Compute, + resource, nullptr, false); + } + uavList->data[resourceSlot] = uavPtr; + if (static_cast(resourceSlot) > uavList->highestUsed) + { + uavList->highestUsed = resourceSlot; + } + + mCurComputeUAVs.update(resourceSlot, uavPtr); + } +} + +void StateManager11::updateStencilSizeIfChanged(bool depthStencilInitialized, + unsigned int stencilSize) +{ + if (!depthStencilInitialized || stencilSize != mCurStencilSize) + { + mCurStencilSize = stencilSize; + mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE); + } +} + +void StateManager11::checkPresentPath(const gl::Context *context) +{ + const auto *framebuffer = context->getState().getDrawFramebuffer(); + const auto *firstColorAttachment = framebuffer->getFirstColorAttachment(); + const bool clipSpaceOriginUpperLeft = + context->getState().getClipSpaceOrigin() == gl::ClipSpaceOrigin::UpperLeft; + const bool presentPathFastActive = + UsePresentPathFast(mRenderer, firstColorAttachment) || clipSpaceOriginUpperLeft; + + const int colorBufferHeight = firstColorAttachment ? firstColorAttachment->getSize().height : 0; + + if ((mCurPresentPathFastEnabled != presentPathFastActive) || + (presentPathFastActive && (colorBufferHeight != mCurPresentPathFastColorBufferHeight))) + { + mCurPresentPathFastEnabled = presentPathFastActive; + mCurPresentPathFastColorBufferHeight = colorBufferHeight; + + // Scissor rect may need to be vertically inverted + mInternalDirtyBits.set(DIRTY_BIT_SCISSOR_STATE); + + // Cull Mode may need to be inverted + mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE); + + // Viewport may need to be vertically inverted + invalidateViewport(context); + } +} + +angle::Result StateManager11::updateStateForCompute(const gl::Context *context, + GLuint numGroupsX, + GLuint numGroupsY, + GLuint numGroupsZ) +{ + mShaderConstants.setComputeWorkGroups(numGroupsX, numGroupsY, numGroupsZ); + + if (mProgramD3D->updateSamplerMapping() == ProgramD3D::SamplerMapping::WasDirty) + { + invalidateTexturesAndSamplers(); + } + + if (mDirtySwizzles) + { + ANGLE_TRY(generateSwizzlesForShader(context, gl::ShaderType::Compute)); + mDirtySwizzles = false; + } + + if (mProgramD3D->anyShaderUniformsDirty()) + { + mInternalDirtyBits.set(DIRTY_BIT_PROGRAM_UNIFORMS); + } + + auto dirtyBitsCopy = mInternalDirtyBits & mComputeDirtyBitsMask; + mInternalDirtyBits &= ~mComputeDirtyBitsMask; + + for (auto iter = dirtyBitsCopy.begin(), end = dirtyBitsCopy.end(); iter != end; ++iter) + { + switch (*iter) + { + case DIRTY_BIT_COMPUTE_SRV_STATE: + // Avoid to call syncTexturesForCompute function two times. + iter.resetLaterBit(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE); + ANGLE_TRY(syncTexturesForCompute(context)); + break; + case DIRTY_BIT_COMPUTE_UAV_STATE: + ANGLE_TRY(syncUAVsForCompute(context)); + break; + case DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE: + ANGLE_TRY(syncTexturesForCompute(context)); + break; + case DIRTY_BIT_PROGRAM_UNIFORMS: + case DIRTY_BIT_DRIVER_UNIFORMS: + ANGLE_TRY(applyComputeUniforms(context, mProgramD3D)); + break; + case DIRTY_BIT_PROGRAM_UNIFORM_BUFFERS: + ANGLE_TRY(syncUniformBuffers(context)); + break; + case DIRTY_BIT_SHADERS: + ANGLE_TRY(syncProgramForCompute(context)); + break; + default: + UNREACHABLE(); + break; + } + } + + return angle::Result::Continue; +} + +void StateManager11::syncState(const gl::Context *context, + const gl::State::DirtyBits &dirtyBits, + gl::Command command) +{ + if (!dirtyBits.any()) + { + return; + } + + const gl::State &state = context->getState(); + + for (size_t dirtyBit : dirtyBits) + { + switch (dirtyBit) + { + case gl::State::DIRTY_BIT_BLEND_EQUATIONS: + { + const gl::BlendStateExt &blendStateExt = state.getBlendStateExt(); + ASSERT(mCurBlendStateExt.getDrawBufferCount() == + blendStateExt.getDrawBufferCount()); + // Compare blend equations only for buffers with blending enabled because + // subsequent sync stages enforce default values for buffers with blending disabled. + if ((blendStateExt.getEnabledMask() & + mCurBlendStateExt.compareEquations(blendStateExt)) + .any()) + { + mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE); + } + break; + } + case gl::State::DIRTY_BIT_BLEND_FUNCS: + { + const gl::BlendStateExt &blendStateExt = state.getBlendStateExt(); + ASSERT(mCurBlendStateExt.getDrawBufferCount() == + blendStateExt.getDrawBufferCount()); + // Compare blend factors only for buffers with blending enabled because + // subsequent sync stages enforce default values for buffers with blending disabled. + if ((blendStateExt.getEnabledMask() & + mCurBlendStateExt.compareFactors(blendStateExt)) + .any()) + { + mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE); + } + break; + } + case gl::State::DIRTY_BIT_BLEND_ENABLED: + { + if (state.getBlendStateExt().getEnabledMask() != mCurBlendStateExt.getEnabledMask()) + { + mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE); + } + break; + } + case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED: + if (state.isSampleAlphaToCoverageEnabled() != mCurSampleAlphaToCoverage) + { + mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE); + } + break; + case gl::State::DIRTY_BIT_DITHER_ENABLED: + if (state.getRasterizerState().dither != mCurRasterState.dither) + { + mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE); + } + break; + case gl::State::DIRTY_BIT_COLOR_MASK: + { + if (state.getBlendStateExt().getColorMaskBits() != + mCurBlendStateExt.getColorMaskBits()) + { + mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE); + } + break; + } + case gl::State::DIRTY_BIT_BLEND_COLOR: + if (state.getBlendColor() != mCurBlendColor) + { + mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE); + } + break; + // Depth and stencil redundant state changes are guarded in the + // frontend so for related cases here just set the dirty bit. + case gl::State::DIRTY_BIT_DEPTH_MASK: + mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE); + break; + case gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED: + mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE); + break; + case gl::State::DIRTY_BIT_DEPTH_FUNC: + mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE); + break; + case gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED: + mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE); + break; + case gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT: + mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE); + break; + case gl::State::DIRTY_BIT_STENCIL_FUNCS_BACK: + mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE); + break; + case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT: + mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE); + break; + case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK: + mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE); + break; + case gl::State::DIRTY_BIT_STENCIL_OPS_FRONT: + mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE); + break; + case gl::State::DIRTY_BIT_STENCIL_OPS_BACK: + mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE); + break; + + case gl::State::DIRTY_BIT_CULL_FACE_ENABLED: + if (state.getRasterizerState().cullFace != mCurRasterState.cullFace) + { + mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE); + mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY); + } + break; + case gl::State::DIRTY_BIT_CULL_FACE: + if (state.getRasterizerState().cullMode != mCurRasterState.cullMode) + { + mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE); + mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY); + } + break; + case gl::State::DIRTY_BIT_FRONT_FACE: + if (state.getRasterizerState().frontFace != mCurRasterState.frontFace) + { + mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE); + mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY); + } + break; + case gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED: + if (state.getRasterizerState().polygonOffsetFill != + mCurRasterState.polygonOffsetFill) + { + mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE); + } + break; + case gl::State::DIRTY_BIT_POLYGON_OFFSET: + { + const gl::RasterizerState &rasterState = state.getRasterizerState(); + if (rasterState.polygonOffsetFactor != mCurRasterState.polygonOffsetFactor || + rasterState.polygonOffsetUnits != mCurRasterState.polygonOffsetUnits) + { + mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE); + } + break; + } + case gl::State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED: + if (state.getRasterizerState().rasterizerDiscard != + mCurRasterState.rasterizerDiscard) + { + mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE); + + // Enabling/disabling rasterizer discard affects the pixel shader. + invalidateShaders(); + } + break; + case gl::State::DIRTY_BIT_SCISSOR: + if (state.getScissor() != mCurScissorRect) + { + mInternalDirtyBits.set(DIRTY_BIT_SCISSOR_STATE); + } + break; + case gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED: + if (state.isScissorTestEnabled() != mCurScissorEnabled) + { + mInternalDirtyBits.set(DIRTY_BIT_SCISSOR_STATE); + // Rasterizer state update needs mCurScissorsEnabled and updates when it changes + mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE); + } + break; + case gl::State::DIRTY_BIT_DEPTH_RANGE: + invalidateViewport(context); + break; + case gl::State::DIRTY_BIT_VIEWPORT: + if (state.getViewport() != mCurViewport) + { + invalidateViewport(context); + } + break; + case gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING: + invalidateRenderTarget(); + if (mIsMultiviewEnabled) + { + handleMultiviewDrawFramebufferChange(context); + } + mFramebuffer11 = GetImplAs(state.getDrawFramebuffer()); + break; + case gl::State::DIRTY_BIT_VERTEX_ARRAY_BINDING: + invalidateVertexBuffer(); + // Force invalidate the current value attributes, since the VertexArray11 keeps an + // internal cache of TranslatedAttributes, and they CurrentValue attributes are + // owned by the StateManager11/Context. + mDirtyCurrentValueAttribs.set(); + // Invalidate the cached index buffer. + invalidateIndexBuffer(); + mVertexArray11 = GetImplAs(state.getVertexArray()); + break; + case gl::State::DIRTY_BIT_UNIFORM_BUFFER_BINDINGS: + invalidateProgramUniformBuffers(); + break; + case gl::State::DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING: + invalidateProgramAtomicCounterBuffers(); + break; + case gl::State::DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING: + invalidateProgramShaderStorageBuffers(); + break; + case gl::State::DIRTY_BIT_TEXTURE_BINDINGS: + invalidateTexturesAndSamplers(); + break; + case gl::State::DIRTY_BIT_SAMPLER_BINDINGS: + invalidateTexturesAndSamplers(); + break; + case gl::State::DIRTY_BIT_IMAGE_BINDINGS: + invalidateImageBindings(); + break; + case gl::State::DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING: + invalidateTransformFeedback(); + break; + case gl::State::DIRTY_BIT_PROGRAM_BINDING: + mProgramD3D = GetImplAs(state.getProgram()); + break; + case gl::State::DIRTY_BIT_PROGRAM_EXECUTABLE: + { + invalidateShaders(); + invalidateTexturesAndSamplers(); + invalidateProgramUniforms(); + invalidateProgramUniformBuffers(); + invalidateProgramAtomicCounterBuffers(); + invalidateProgramShaderStorageBuffers(); + invalidateDriverUniforms(); + const gl::ProgramExecutable *executable = state.getProgramExecutable(); + if (!executable || command != gl::Command::Dispatch) + { + mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY); + invalidateVertexBuffer(); + invalidateRenderTarget(); + // If OVR_multiview2 is enabled, the attribute divisor has to be updated for + // each binding. When using compute, there could be no vertex array. + if (mIsMultiviewEnabled && mVertexArray11) + { + ASSERT(mProgramD3D); + ASSERT(mVertexArray11 == GetImplAs(state.getVertexArray())); + const gl::ProgramState &programState = mProgramD3D->getState(); + int numViews = + programState.usesMultiview() ? programState.getNumViews() : 1; + mVertexArray11->markAllAttributeDivisorsForAdjustment(numViews); + } + } + break; + } + case gl::State::DIRTY_BIT_CURRENT_VALUES: + { + for (auto attribIndex : state.getAndResetDirtyCurrentValues()) + { + invalidateCurrentValueAttrib(attribIndex); + } + break; + } + case gl::State::DIRTY_BIT_PROVOKING_VERTEX: + invalidateShaders(); + break; + case gl::State::DIRTY_BIT_EXTENDED: + { + gl::State::ExtendedDirtyBits extendedDirtyBits = + state.getAndResetExtendedDirtyBits(); + + for (size_t extendedDirtyBit : extendedDirtyBits) + { + switch (extendedDirtyBit) + { + case gl::State::EXTENDED_DIRTY_BIT_CLIP_CONTROL: + checkPresentPath(context); + break; + } + } + break; + } + default: + break; + } + } + + // TODO(jmadill): Input layout and vertex buffer state. +} + +void StateManager11::handleMultiviewDrawFramebufferChange(const gl::Context *context) +{ + const auto &glState = context->getState(); + const gl::Framebuffer *drawFramebuffer = glState.getDrawFramebuffer(); + ASSERT(drawFramebuffer != nullptr); + + if (drawFramebuffer->isMultiview()) + { + // Because the base view index is applied as an offset to the 2D texture array when the + // RTV is created, we just have to pass a boolean to select which code path is to be + // used. + mShaderConstants.setMultiviewWriteToViewportIndex(0.0f); + } +} + +angle::Result StateManager11::syncBlendState(const gl::Context *context, + const gl::BlendStateExt &blendStateExt, + const gl::ColorF &blendColor, + unsigned int sampleMask, + bool sampleAlphaToCoverage, + bool emulateConstantAlpha) +{ + const d3d11::BlendState *dxBlendState = nullptr; + const d3d11::BlendStateKey &key = RenderStateCache::GetBlendStateKey( + context, mFramebuffer11, blendStateExt, sampleAlphaToCoverage); + + ANGLE_TRY(mRenderer->getBlendState(context, key, &dxBlendState)); + + ASSERT(dxBlendState != nullptr); + + // D3D11 does not support CONSTANT_ALPHA as source or destination color factor, so ANGLE sets + // the factor to CONSTANT_COLOR and swizzles the color value to aaaa. For this reason, it's + // impossible to simultaneously use CONSTANT_ALPHA and CONSTANT_COLOR as source or destination + // color factors in the same blend state. This is enforced in the validation layer. + float blendColors[4] = {0.0f}; + blendColors[0] = emulateConstantAlpha ? blendColor.alpha : blendColor.red; + blendColors[1] = emulateConstantAlpha ? blendColor.alpha : blendColor.green; + blendColors[2] = emulateConstantAlpha ? blendColor.alpha : blendColor.blue; + blendColors[3] = blendColor.alpha; + + mRenderer->getDeviceContext()->OMSetBlendState(dxBlendState->get(), blendColors, sampleMask); + + mCurBlendStateExt = blendStateExt; + mCurBlendColor = blendColor; + mCurSampleMask = sampleMask; + mCurSampleAlphaToCoverage = sampleAlphaToCoverage; + + return angle::Result::Continue; +} + +angle::Result StateManager11::syncDepthStencilState(const gl::Context *context) +{ + const gl::State &glState = context->getState(); + + mCurDepthStencilState = glState.getDepthStencilState(); + mCurStencilRef = glState.getStencilRef(); + mCurStencilBackRef = glState.getStencilBackRef(); + + // get the maximum size of the stencil ref + unsigned int maxStencil = 0; + if (mCurDepthStencilState.stencilTest && mCurStencilSize > 0) + { + maxStencil = (1 << mCurStencilSize) - 1; + } + ASSERT((mCurDepthStencilState.stencilWritemask & maxStencil) == + (mCurDepthStencilState.stencilBackWritemask & maxStencil)); + ASSERT(gl::clamp(mCurStencilRef, 0, static_cast(maxStencil)) == + gl::clamp(mCurStencilBackRef, 0, static_cast(maxStencil))); + ASSERT((mCurDepthStencilState.stencilMask & maxStencil) == + (mCurDepthStencilState.stencilBackMask & maxStencil)); + + gl::DepthStencilState modifiedGLState = glState.getDepthStencilState(); + + ASSERT(mCurDisableDepth.valid() && mCurDisableStencil.valid()); + + if (mCurDisableDepth.value()) + { + modifiedGLState.depthTest = false; + modifiedGLState.depthMask = false; + } + + if (mCurDisableStencil.value()) + { + modifiedGLState.stencilTest = false; + } + if (!modifiedGLState.stencilTest) + { + modifiedGLState.stencilWritemask = 0; + modifiedGLState.stencilBackWritemask = 0; + } + + // If STENCIL_TEST is disabled in glState, stencil testing and writing should be disabled. + // Verify that's true in the modifiedGLState so it is propagated to d3dState. + ASSERT(glState.getDepthStencilState().stencilTest || + (!modifiedGLState.stencilTest && modifiedGLState.stencilWritemask == 0 && + modifiedGLState.stencilBackWritemask == 0)); + + const d3d11::DepthStencilState *d3dState = nullptr; + ANGLE_TRY(mRenderer->getDepthStencilState(context, modifiedGLState, &d3dState)); + ASSERT(d3dState); + + // Max D3D11 stencil reference value is 0xFF, + // corresponding to the max 8 bits in a stencil buffer + // GL specifies we should clamp the ref value to the + // nearest bit depth when doing stencil ops + static_assert(D3D11_DEFAULT_STENCIL_READ_MASK == 0xFF, + "Unexpected value of D3D11_DEFAULT_STENCIL_READ_MASK"); + static_assert(D3D11_DEFAULT_STENCIL_WRITE_MASK == 0xFF, + "Unexpected value of D3D11_DEFAULT_STENCIL_WRITE_MASK"); + UINT dxStencilRef = static_cast(gl::clamp(mCurStencilRef, 0, 0xFF)); + + mRenderer->getDeviceContext()->OMSetDepthStencilState(d3dState->get(), dxStencilRef); + + return angle::Result::Continue; +} + +angle::Result StateManager11::syncRasterizerState(const gl::Context *context, + gl::PrimitiveMode mode) +{ + // TODO: Remove pointDrawMode and multiSample from gl::RasterizerState. + gl::RasterizerState rasterState = context->getState().getRasterizerState(); + rasterState.pointDrawMode = (mode == gl::PrimitiveMode::Points); + rasterState.multiSample = mCurRasterState.multiSample; + + ID3D11RasterizerState *dxRasterState = nullptr; + + if (mCurPresentPathFastEnabled) + { + gl::RasterizerState modifiedRasterState = rasterState; + + // If prseent path fast is active then we need invert the front face state. + // This ensures that both gl_FrontFacing is correct, and front/back culling + // is performed correctly. + if (modifiedRasterState.frontFace == GL_CCW) + { + modifiedRasterState.frontFace = GL_CW; + } + else + { + ASSERT(modifiedRasterState.frontFace == GL_CW); + modifiedRasterState.frontFace = GL_CCW; + } + + ANGLE_TRY(mRenderer->getRasterizerState(context, modifiedRasterState, mCurScissorEnabled, + &dxRasterState)); + } + else + { + ANGLE_TRY(mRenderer->getRasterizerState(context, rasterState, mCurScissorEnabled, + &dxRasterState)); + } + + mRenderer->getDeviceContext()->RSSetState(dxRasterState); + + mCurRasterState = rasterState; + + return angle::Result::Continue; +} + +void StateManager11::syncScissorRectangle(const gl::Context *context) +{ + const auto &glState = context->getState(); + gl::Framebuffer *framebuffer = glState.getDrawFramebuffer(); + const gl::Rectangle &scissor = glState.getScissor(); + const bool enabled = glState.isScissorTestEnabled(); + + mCurScissorOffset = framebuffer->getSurfaceTextureOffset(); + + int scissorX = scissor.x + mCurScissorOffset.x; + int scissorY = scissor.y + mCurScissorOffset.y; + + if (mCurPresentPathFastEnabled) + { + scissorY = mCurPresentPathFastColorBufferHeight - scissor.height - scissor.y; + } + + if (enabled) + { + D3D11_RECT rect; + int x = scissorX; + int y = scissorY; + rect.left = std::max(0, x); + rect.top = std::max(0, y); + rect.right = x + std::max(0, scissor.width); + rect.bottom = y + std::max(0, scissor.height); + mRenderer->getDeviceContext()->RSSetScissorRects(1, &rect); + } + + mCurScissorRect = scissor; + mCurScissorEnabled = enabled; +} + +void StateManager11::syncViewport(const gl::Context *context) +{ + const auto &glState = context->getState(); + gl::Framebuffer *framebuffer = glState.getDrawFramebuffer(); + float actualZNear = gl::clamp01(glState.getNearPlane()); + float actualZFar = gl::clamp01(glState.getFarPlane()); + + const auto &caps = context->getCaps(); + int dxMaxViewportBoundsX = caps.maxViewportWidth; + int dxMaxViewportBoundsY = caps.maxViewportHeight; + int dxMinViewportBoundsX = -dxMaxViewportBoundsX; + int dxMinViewportBoundsY = -dxMaxViewportBoundsY; + + bool is9_3 = mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3; + + if (is9_3) + { + // Feature Level 9 viewports shouldn't exceed the dimensions of the rendertarget. + dxMaxViewportBoundsX = static_cast(mViewportBounds.width); + dxMaxViewportBoundsY = static_cast(mViewportBounds.height); + dxMinViewportBoundsX = 0; + dxMinViewportBoundsY = 0; + } + + bool clipSpaceOriginLowerLeft = glState.getClipSpaceOrigin() == gl::ClipSpaceOrigin::LowerLeft; + mShaderConstants.onClipControlChange(clipSpaceOriginLowerLeft, + glState.isClipControlDepthZeroToOne()); + + const auto &viewport = glState.getViewport(); + + int dxViewportTopLeftX = 0; + int dxViewportTopLeftY = 0; + int dxViewportWidth = 0; + int dxViewportHeight = 0; + + mCurViewportOffset = framebuffer->getSurfaceTextureOffset(); + + dxViewportTopLeftX = + gl::clamp(viewport.x + mCurViewportOffset.x, dxMinViewportBoundsX, dxMaxViewportBoundsX); + dxViewportTopLeftY = + gl::clamp(viewport.y + mCurViewportOffset.y, dxMinViewportBoundsY, dxMaxViewportBoundsY); + dxViewportWidth = gl::clamp(viewport.width, 0, dxMaxViewportBoundsX - dxViewportTopLeftX); + dxViewportHeight = gl::clamp(viewport.height, 0, dxMaxViewportBoundsY - dxViewportTopLeftY); + + D3D11_VIEWPORT dxViewport; + dxViewport.TopLeftX = static_cast(dxViewportTopLeftX); + if (mCurPresentPathFastEnabled && clipSpaceOriginLowerLeft) + { + // When present path fast is active and we're rendering to framebuffer 0, we must invert + // the viewport in Y-axis. + // NOTE: We delay the inversion until right before the call to RSSetViewports, and leave + // dxViewportTopLeftY unchanged. This allows us to calculate viewAdjust below using the + // unaltered dxViewportTopLeftY value. + dxViewport.TopLeftY = static_cast(mCurPresentPathFastColorBufferHeight - + dxViewportTopLeftY - dxViewportHeight); + } + else + { + dxViewport.TopLeftY = static_cast(dxViewportTopLeftY); + } + + // The es 3.1 spec section 9.2 states that, "If there are no attachments, rendering + // will be limited to a rectangle having a lower left of (0, 0) and an upper right of + // (width, height), where width and height are the framebuffer object's default width + // and height." See http://anglebug.com/1594 + // If the Framebuffer has no color attachment and the default width or height is smaller + // than the current viewport, use the smaller of the two sizes. + // If framebuffer default width or height is 0, the params should not set. + if (!framebuffer->getFirstNonNullAttachment() && + (framebuffer->getDefaultWidth() || framebuffer->getDefaultHeight())) + { + dxViewport.Width = + static_cast(std::min(viewport.width, framebuffer->getDefaultWidth())); + dxViewport.Height = + static_cast(std::min(viewport.height, framebuffer->getDefaultHeight())); + } + else + { + dxViewport.Width = static_cast(dxViewportWidth); + dxViewport.Height = static_cast(dxViewportHeight); + } + dxViewport.MinDepth = actualZNear; + dxViewport.MaxDepth = actualZFar; + + mRenderer->getDeviceContext()->RSSetViewports(1, &dxViewport); + + mCurViewport = viewport; + mCurNear = actualZNear; + mCurFar = actualZFar; + + const D3D11_VIEWPORT adjustViewport = {static_cast(dxViewportTopLeftX), + static_cast(dxViewportTopLeftY), + static_cast(dxViewportWidth), + static_cast(dxViewportHeight), + actualZNear, + actualZFar}; + mShaderConstants.onViewportChange(viewport, adjustViewport, mCurViewportOffset, is9_3, + mCurPresentPathFastEnabled); +} + +void StateManager11::invalidateRenderTarget() +{ + mRenderTargetIsDirty = true; +} + +void StateManager11::processFramebufferInvalidation(const gl::Context *context) +{ + ASSERT(mRenderTargetIsDirty); + ASSERT(context); + + mInternalDirtyBits.set(DIRTY_BIT_RENDER_TARGET); + + // The pixel shader is dependent on the output layout. + invalidateShaders(); + + // The D3D11 blend state is heavily dependent on the current render target. + mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE); + + gl::Framebuffer *fbo = context->getState().getDrawFramebuffer(); + ASSERT(fbo); + + // Dirty scissor and viewport because surface texture offset might have changed. + if (mCurViewportOffset != fbo->getSurfaceTextureOffset()) + { + mInternalDirtyBits.set(DIRTY_BIT_VIEWPORT_STATE); + } + if (mCurScissorOffset != fbo->getSurfaceTextureOffset()) + { + mInternalDirtyBits.set(DIRTY_BIT_SCISSOR_STATE); + } + + // Disable the depth test/depth write if we are using a stencil-only attachment. + // This is because ANGLE emulates stencil-only with D24S8 on D3D11 - we should neither read + // nor write to the unused depth part of this emulated texture. + bool disableDepth = (!fbo->hasDepth() && fbo->hasStencil()); + + // Similarly we disable the stencil portion of the DS attachment if the app only binds depth. + bool disableStencil = (fbo->hasDepth() && !fbo->hasStencil()); + + if (!mCurDisableDepth.valid() || disableDepth != mCurDisableDepth.value() || + !mCurDisableStencil.valid() || disableStencil != mCurDisableStencil.value()) + { + mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE); + mCurDisableDepth = disableDepth; + mCurDisableStencil = disableStencil; + } + + bool multiSample = (fbo->getSamples(context) != 0); + if (multiSample != mCurRasterState.multiSample) + { + mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE); + mCurRasterState.multiSample = multiSample; + } + + checkPresentPath(context); + + if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3) + { + const auto *firstAttachment = fbo->getFirstNonNullAttachment(); + if (firstAttachment) + { + const auto &size = firstAttachment->getSize(); + if (mViewportBounds.width != size.width || mViewportBounds.height != size.height) + { + mViewportBounds = gl::Extents(size.width, size.height, 1); + invalidateViewport(context); + } + } + } +} + +void StateManager11::invalidateBoundViews() +{ + for (SRVCache &curShaderSRV : mCurShaderSRVs) + { + curShaderSRV.clear(); + } + + invalidateRenderTarget(); +} + +void StateManager11::invalidateVertexBuffer() +{ + unsigned int limit = std::min(mRenderer->getNativeCaps().maxVertexAttributes, + gl::MAX_VERTEX_ATTRIBS); + mDirtyVertexBufferRange = gl::RangeUI(0, limit); + invalidateInputLayout(); + invalidateShaders(); + mInternalDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_ATTRIBS); +} + +void StateManager11::invalidateViewport(const gl::Context *context) +{ + mInternalDirtyBits.set(DIRTY_BIT_VIEWPORT_STATE); + + // Viewport affects the driver constants. + invalidateDriverUniforms(); +} + +void StateManager11::invalidateTexturesAndSamplers() +{ + mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE); + invalidateSwizzles(); + + // Texture state affects the driver uniforms (base level, etc). + invalidateDriverUniforms(); +} + +void StateManager11::invalidateSwizzles() +{ + mDirtySwizzles = true; +} + +void StateManager11::invalidateProgramUniforms() +{ + mInternalDirtyBits.set(DIRTY_BIT_PROGRAM_UNIFORMS); +} + +void StateManager11::invalidateDriverUniforms() +{ + mInternalDirtyBits.set(DIRTY_BIT_DRIVER_UNIFORMS); +} + +void StateManager11::invalidateProgramUniformBuffers() +{ + mInternalDirtyBits.set(DIRTY_BIT_PROGRAM_UNIFORM_BUFFERS); +} + +void StateManager11::invalidateProgramAtomicCounterBuffers() +{ + mInternalDirtyBits.set(DIRTY_BIT_GRAPHICS_UAV_STATE); + mInternalDirtyBits.set(DIRTY_BIT_COMPUTE_UAV_STATE); +} + +void StateManager11::invalidateProgramShaderStorageBuffers() +{ + mInternalDirtyBits.set(DIRTY_BIT_GRAPHICS_UAV_STATE); + mInternalDirtyBits.set(DIRTY_BIT_COMPUTE_UAV_STATE); +} + +void StateManager11::invalidateImageBindings() +{ + mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE); + mInternalDirtyBits.set(DIRTY_BIT_GRAPHICS_SRV_STATE); + mInternalDirtyBits.set(DIRTY_BIT_GRAPHICS_UAV_STATE); + mInternalDirtyBits.set(DIRTY_BIT_COMPUTE_SRV_STATE); + mInternalDirtyBits.set(DIRTY_BIT_COMPUTE_UAV_STATE); +} + +void StateManager11::invalidateConstantBuffer(unsigned int slot) +{ + if (slot == d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER) + { + invalidateDriverUniforms(); + } + else if (slot == d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DEFAULT_UNIFORM_BLOCK) + { + invalidateProgramUniforms(); + } + else + { + invalidateProgramUniformBuffers(); + } +} + +void StateManager11::invalidateShaders() +{ + mInternalDirtyBits.set(DIRTY_BIT_SHADERS); +} + +void StateManager11::invalidateTransformFeedback() +{ + // Transform feedback affects the stream-out geometry shader. + invalidateShaders(); + mInternalDirtyBits.set(DIRTY_BIT_TRANSFORM_FEEDBACK); + // syncPrimitiveTopology checks the transform feedback state. + mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY); +} + +void StateManager11::invalidateInputLayout() +{ + mInternalDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS_AND_INPUT_LAYOUT); +} + +void StateManager11::invalidateIndexBuffer() +{ + mIndexBufferIsDirty = true; +} + +void StateManager11::setRenderTarget(ID3D11RenderTargetView *rtv, ID3D11DepthStencilView *dsv) +{ + if (rtv) + { + unsetConflictingView(gl::PipelineType::GraphicsPipeline, rtv, true); + } + + if (dsv) + { + unsetConflictingView(gl::PipelineType::GraphicsPipeline, dsv, true); + } + + mRenderer->getDeviceContext()->OMSetRenderTargets(1, &rtv, dsv); + mCurRTVs.clear(); + mCurRTVs.update(0, rtv); + mInternalDirtyBits.set(DIRTY_BIT_RENDER_TARGET); +} + +void StateManager11::setRenderTargets(ID3D11RenderTargetView **rtvs, + UINT numRTVs, + ID3D11DepthStencilView *dsv) +{ + for (UINT rtvIndex = 0; rtvIndex < numRTVs; ++rtvIndex) + { + unsetConflictingView(gl::PipelineType::GraphicsPipeline, rtvs[rtvIndex], true); + } + + if (dsv) + { + unsetConflictingView(gl::PipelineType::GraphicsPipeline, dsv, true); + } + + mRenderer->getDeviceContext()->OMSetRenderTargets(numRTVs, (numRTVs > 0) ? rtvs : nullptr, dsv); + mCurRTVs.clear(); + for (UINT i = 0; i < numRTVs; i++) + { + mCurRTVs.update(i, rtvs[i]); + } + mInternalDirtyBits.set(DIRTY_BIT_RENDER_TARGET); +} + +void StateManager11::onBeginQuery(Query11 *query) +{ + mCurrentQueries.insert(query); +} + +void StateManager11::onDeleteQueryObject(Query11 *query) +{ + mCurrentQueries.erase(query); +} + +angle::Result StateManager11::onMakeCurrent(const gl::Context *context) +{ + ANGLE_TRY(ensureInitialized(context)); + + const gl::State &state = context->getState(); + + Context11 *context11 = GetImplAs(context); + + for (Query11 *query : mCurrentQueries) + { + ANGLE_TRY(query->pause(context11)); + } + mCurrentQueries.clear(); + + for (gl::QueryType type : angle::AllEnums()) + { + gl::Query *query = state.getActiveQuery(type); + if (query != nullptr) + { + Query11 *query11 = GetImplAs(query); + ANGLE_TRY(query11->resume(context11)); + mCurrentQueries.insert(query11); + } + } + + // Reset the cache objects. + mProgramD3D = nullptr; + mVertexArray11 = nullptr; + mFramebuffer11 = nullptr; + + return angle::Result::Continue; +} + +void StateManager11::unsetConflictingView(gl::PipelineType pipeline, + ID3D11View *view, + bool isRenderTarget) +{ + uintptr_t resource = reinterpret_cast(GetViewResource(view)); + + unsetConflictingSRVs(pipeline, gl::ShaderType::Vertex, resource, nullptr, isRenderTarget); + unsetConflictingSRVs(pipeline, gl::ShaderType::Fragment, resource, nullptr, isRenderTarget); + unsetConflictingSRVs(pipeline, gl::ShaderType::Compute, resource, nullptr, isRenderTarget); + unsetConflictingUAVs(pipeline, gl::ShaderType::Compute, resource, nullptr); +} + +void StateManager11::unsetConflictingSRVs(gl::PipelineType pipeline, + gl::ShaderType shaderType, + uintptr_t resource, + const gl::ImageIndex *index, + bool isRenderTarget) +{ + auto *currentSRVs = getSRVCache(shaderType); + gl::PipelineType conflictPipeline = gl::GetPipelineType(shaderType); + bool foundOne = false; + size_t count = std::min(currentSRVs->size(), currentSRVs->highestUsed()); + for (size_t resourceIndex = 0; resourceIndex < count; ++resourceIndex) + { + auto &record = (*currentSRVs)[resourceIndex]; + + if (record.view && record.resource == resource && + (!index || ImageIndexConflictsWithSRV(*index, record.desc))) + { + setShaderResourceInternal( + shaderType, static_cast(resourceIndex), nullptr); + foundOne = true; + } + } + + if (foundOne && (pipeline != conflictPipeline || isRenderTarget)) + { + switch (conflictPipeline) + { + case gl::PipelineType::GraphicsPipeline: + mInternalDirtyBits.set(DIRTY_BIT_GRAPHICS_SRV_STATE); + break; + case gl::PipelineType::ComputePipeline: + mInternalDirtyBits.set(DIRTY_BIT_COMPUTE_SRV_STATE); + break; + default: + UNREACHABLE(); + } + } +} + +void StateManager11::unsetConflictingUAVs(gl::PipelineType pipeline, + gl::ShaderType shaderType, + uintptr_t resource, + const gl::ImageIndex *index) +{ + ASSERT(shaderType == gl::ShaderType::Compute); + bool foundOne = false; + + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + size_t count = std::min(mCurComputeUAVs.size(), mCurComputeUAVs.highestUsed()); + for (size_t resourceIndex = 0; resourceIndex < count; ++resourceIndex) + { + auto &record = mCurComputeUAVs[resourceIndex]; + + if (record.view && record.resource == resource && + (!index || ImageIndexConflictsWithUAV(*index, record.desc))) + { + deviceContext->CSSetUnorderedAccessViews(static_cast(resourceIndex), 1, + &mNullUAVs[0], nullptr); + mCurComputeUAVs.update(resourceIndex, nullptr); + foundOne = true; + } + } + + if (foundOne && pipeline == gl::PipelineType::GraphicsPipeline) + { + mInternalDirtyBits.set(DIRTY_BIT_COMPUTE_UAV_STATE); + } +} + +void StateManager11::unsetConflictingRTVs(uintptr_t resource) +{ + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + size_t count = std::min(mCurRTVs.size(), mCurRTVs.highestUsed()); + for (size_t resourceIndex = 0; resourceIndex < count; ++resourceIndex) + { + auto &record = mCurRTVs[resourceIndex]; + + if (record.view && record.resource == resource) + { + deviceContext->OMSetRenderTargets(0, nullptr, nullptr); + mCurRTVs.clear(); + mInternalDirtyBits.set(DIRTY_BIT_RENDER_TARGET); + return; + } + } +} + +void StateManager11::unsetConflictingAttachmentResources( + const gl::FramebufferAttachment &attachment, + ID3D11Resource *resource) +{ + // Unbind render target SRVs from the shader here to prevent D3D11 warnings. + if (attachment.type() == GL_TEXTURE) + { + uintptr_t resourcePtr = reinterpret_cast(resource); + const gl::ImageIndex &index = attachment.getTextureImageIndex(); + // The index doesn't need to be corrected for the small compressed texture workaround + // because a rendertarget is never compressed. + unsetConflictingSRVs(gl::PipelineType::GraphicsPipeline, gl::ShaderType::Vertex, + resourcePtr, &index, false); + unsetConflictingSRVs(gl::PipelineType::GraphicsPipeline, gl::ShaderType::Fragment, + resourcePtr, &index, false); + unsetConflictingSRVs(gl::PipelineType::GraphicsPipeline, gl::ShaderType::Compute, + resourcePtr, &index, false); + unsetConflictingUAVs(gl::PipelineType::GraphicsPipeline, gl::ShaderType::Compute, + resourcePtr, &index); + } + else if (attachment.type() == GL_FRAMEBUFFER_DEFAULT) + { + uintptr_t resourcePtr = reinterpret_cast(resource); + unsetConflictingSRVs(gl::PipelineType::GraphicsPipeline, gl::ShaderType::Vertex, + resourcePtr, nullptr, false); + unsetConflictingSRVs(gl::PipelineType::GraphicsPipeline, gl::ShaderType::Fragment, + resourcePtr, nullptr, false); + unsetConflictingSRVs(gl::PipelineType::GraphicsPipeline, gl::ShaderType::Compute, + resourcePtr, nullptr, false); + unsetConflictingUAVs(gl::PipelineType::GraphicsPipeline, gl::ShaderType::Compute, + resourcePtr, nullptr); + } +} + +angle::Result StateManager11::ensureInitialized(const gl::Context *context) +{ + Renderer11 *renderer = GetImplAs(context)->getRenderer(); + + const gl::Caps &caps = renderer->getNativeCaps(); + const gl::Extensions &extensions = renderer->getNativeExtensions(); + + for (gl::ShaderType shaderType : gl::AllShaderTypes()) + { + const GLuint maxShaderTextureImageUnits = + static_cast(caps.maxShaderTextureImageUnits[shaderType]); + + mCurShaderSRVs[shaderType].initialize(maxShaderTextureImageUnits); + mForceSetShaderSamplerStates[shaderType].resize(maxShaderTextureImageUnits, true); + mCurShaderSamplerStates[shaderType].resize(maxShaderTextureImageUnits); + } + mCurRTVs.initialize(caps.maxColorAttachments); + mCurComputeUAVs.initialize(caps.maxImageUnits); + + // Initialize cached NULL SRV block + mNullSRVs.resize(caps.maxShaderTextureImageUnits[gl::ShaderType::Fragment], nullptr); + + mNullUAVs.resize(caps.maxImageUnits, nullptr); + + mCurrentValueAttribs.resize(caps.maxVertexAttributes); + + mShaderConstants.init(caps); + + mIsMultiviewEnabled = extensions.multiviewOVR || extensions.multiview2OVR; + + mIndependentBlendStates = extensions.drawBuffersIndexedAny(); // requires FL10_1 + + // FL9_3 is limited to 4; ES3.1 context on FL11_0 is limited to 7 + mCurBlendStateExt = + gl::BlendStateExt(GetImplAs(context)->getNativeCaps().maxDrawBuffers); + + ANGLE_TRY(mVertexDataManager.initialize(context)); + + mCurrentAttributes.reserve(gl::MAX_VERTEX_ATTRIBS); + + return angle::Result::Continue; +} + +void StateManager11::deinitialize() +{ + mCurrentValueAttribs.clear(); + mInputLayoutCache.clear(); + mVertexDataManager.deinitialize(); + mIndexDataManager.deinitialize(); + + for (d3d11::Buffer &ShaderDriverConstantBuffer : mShaderDriverConstantBuffers) + { + ShaderDriverConstantBuffer.reset(); + } + + mPointSpriteVertexBuffer.reset(); + mPointSpriteIndexBuffer.reset(); +} + +// Applies the render target surface, depth stencil surface, viewport rectangle and +// scissor rectangle to the renderer +angle::Result StateManager11::syncFramebuffer(const gl::Context *context) +{ + // Check for zero-sized default framebuffer, which is a special case. + // in this case we do not wish to modify any state and just silently return false. + // this will not report any gl error but will cause the calling method to return. + if (mFramebuffer11->getState().isDefault()) + { + RenderTarget11 *firstRT = mFramebuffer11->getFirstRenderTarget(); + const gl::Extents &size = firstRT->getExtents(); + if (size.empty()) + { + return angle::Result::Continue; + } + } + + RTVArray framebufferRTVs = {{}}; + const auto &colorRTs = mFramebuffer11->getCachedColorRenderTargets(); + + size_t appliedRTIndex = 0; + bool skipInactiveRTs = mRenderer->getFeatures().mrtPerfWorkaround.enabled; + const auto &drawStates = mFramebuffer11->getState().getDrawBufferStates(); + gl::DrawBufferMask activeProgramOutputs = + mProgramD3D->getState().getExecutable().getActiveOutputVariablesMask(); + UINT maxExistingRT = 0; + const auto &colorAttachments = mFramebuffer11->getState().getColorAttachments(); + + for (size_t rtIndex = 0; rtIndex < colorRTs.size(); ++rtIndex) + { + const RenderTarget11 *renderTarget = colorRTs[rtIndex]; + + // Skip inactive rendertargets if the workaround is enabled. + if (skipInactiveRTs && + (!renderTarget || drawStates[rtIndex] == GL_NONE || !activeProgramOutputs[rtIndex])) + { + continue; + } + + if (renderTarget) + { + framebufferRTVs[appliedRTIndex] = renderTarget->getRenderTargetView().get(); + ASSERT(framebufferRTVs[appliedRTIndex]); + maxExistingRT = static_cast(appliedRTIndex) + 1; + + // Unset conflicting texture SRVs + const gl::FramebufferAttachment &attachment = colorAttachments[rtIndex]; + ASSERT(attachment.isAttached()); + unsetConflictingAttachmentResources(attachment, renderTarget->getTexture().get()); + } + + appliedRTIndex++; + } + + // Get the depth stencil buffers + ID3D11DepthStencilView *framebufferDSV = nullptr; + const auto *depthStencilRenderTarget = mFramebuffer11->getCachedDepthStencilRenderTarget(); + if (depthStencilRenderTarget) + { + framebufferDSV = depthStencilRenderTarget->getDepthStencilView().get(); + ASSERT(framebufferDSV); + + // Unset conflicting texture SRVs + const gl::FramebufferAttachment *attachment = + mFramebuffer11->getState().getDepthOrStencilAttachment(); + ASSERT(attachment); + unsetConflictingAttachmentResources(*attachment, + depthStencilRenderTarget->getTexture().get()); + } + + ASSERT(maxExistingRT <= static_cast(context->getCaps().maxDrawBuffers)); + + // Apply the render target and depth stencil + mRenderer->getDeviceContext()->OMSetRenderTargets(maxExistingRT, framebufferRTVs.data(), + framebufferDSV); + mCurRTVs.clear(); + for (UINT i = 0; i < maxExistingRT; i++) + { + mCurRTVs.update(i, framebufferRTVs[i]); + } + return angle::Result::Continue; +} + +void StateManager11::invalidateCurrentValueAttrib(size_t attribIndex) +{ + mDirtyCurrentValueAttribs.set(attribIndex); + mInternalDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_ATTRIBS); + invalidateInputLayout(); + invalidateShaders(); +} + +angle::Result StateManager11::syncCurrentValueAttribs( + const gl::Context *context, + const std::vector ¤tValues) +{ + const gl::ProgramExecutable &executable = mProgramD3D->getState().getExecutable(); + const auto &activeAttribsMask = executable.getActiveAttribLocationsMask(); + const auto &dirtyActiveAttribs = (activeAttribsMask & mDirtyCurrentValueAttribs); + + if (!dirtyActiveAttribs.any()) + { + return angle::Result::Continue; + } + + const auto &vertexAttributes = mVertexArray11->getState().getVertexAttributes(); + const auto &vertexBindings = mVertexArray11->getState().getVertexBindings(); + mDirtyCurrentValueAttribs = (mDirtyCurrentValueAttribs & ~dirtyActiveAttribs); + + for (auto attribIndex : dirtyActiveAttribs) + { + if (vertexAttributes[attribIndex].enabled) + continue; + + const auto *attrib = &vertexAttributes[attribIndex]; + const auto ¤tValue = currentValues[attribIndex]; + TranslatedAttribute *currentValueAttrib = &mCurrentValueAttribs[attribIndex]; + currentValueAttrib->currentValueType = currentValue.Type; + currentValueAttrib->attribute = attrib; + currentValueAttrib->binding = &vertexBindings[attrib->bindingIndex]; + + mDirtyVertexBufferRange.extend(static_cast(attribIndex)); + + ANGLE_TRY(mVertexDataManager.storeCurrentValue(context, currentValue, currentValueAttrib, + static_cast(attribIndex))); + } + + return angle::Result::Continue; +} + +void StateManager11::setInputLayout(const d3d11::InputLayout *inputLayout) +{ + if (setInputLayoutInternal(inputLayout)) + { + invalidateInputLayout(); + } +} + +bool StateManager11::setInputLayoutInternal(const d3d11::InputLayout *inputLayout) +{ + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + if (inputLayout == nullptr) + { + if (!mCurrentInputLayout.empty()) + { + deviceContext->IASetInputLayout(nullptr); + mCurrentInputLayout.clear(); + return true; + } + } + else if (inputLayout->getSerial() != mCurrentInputLayout) + { + deviceContext->IASetInputLayout(inputLayout->get()); + mCurrentInputLayout = inputLayout->getSerial(); + return true; + } + + return false; +} + +bool StateManager11::queueVertexBufferChange(size_t bufferIndex, + ID3D11Buffer *buffer, + UINT stride, + UINT offset) +{ + if (buffer != mCurrentVertexBuffers[bufferIndex] || + stride != mCurrentVertexStrides[bufferIndex] || + offset != mCurrentVertexOffsets[bufferIndex]) + { + mDirtyVertexBufferRange.extend(static_cast(bufferIndex)); + + mCurrentVertexBuffers[bufferIndex] = buffer; + mCurrentVertexStrides[bufferIndex] = stride; + mCurrentVertexOffsets[bufferIndex] = offset; + return true; + } + + return false; +} + +void StateManager11::applyVertexBufferChanges() +{ + if (mDirtyVertexBufferRange.empty()) + { + return; + } + + ASSERT(mDirtyVertexBufferRange.high() <= gl::MAX_VERTEX_ATTRIBS); + + UINT start = static_cast(mDirtyVertexBufferRange.low()); + + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + deviceContext->IASetVertexBuffers(start, static_cast(mDirtyVertexBufferRange.length()), + &mCurrentVertexBuffers[start], &mCurrentVertexStrides[start], + &mCurrentVertexOffsets[start]); + + mDirtyVertexBufferRange = gl::RangeUI(gl::MAX_VERTEX_ATTRIBS, 0); +} + +void StateManager11::setSingleVertexBuffer(const d3d11::Buffer *buffer, UINT stride, UINT offset) +{ + ID3D11Buffer *native = buffer ? buffer->get() : nullptr; + if (queueVertexBufferChange(0, native, stride, offset)) + { + invalidateInputLayout(); + applyVertexBufferChanges(); + } +} + +angle::Result StateManager11::updateState(const gl::Context *context, + gl::PrimitiveMode mode, + GLint firstVertex, + GLsizei vertexOrIndexCount, + gl::DrawElementsType indexTypeOrInvalid, + const void *indices, + GLsizei instanceCount, + GLint baseVertex, + GLuint baseInstance, + bool promoteDynamic) +{ + const gl::State &glState = context->getState(); + + // TODO(jmadill): Use dirty bits. + if (mRenderTargetIsDirty) + { + processFramebufferInvalidation(context); + mRenderTargetIsDirty = false; + } + + // TODO(jmadill): Use dirty bits. + if (mProgramD3D->updateSamplerMapping() == ProgramD3D::SamplerMapping::WasDirty) + { + invalidateTexturesAndSamplers(); + } + + // TODO(jmadill): Use dirty bits. + if (mProgramD3D->anyShaderUniformsDirty()) + { + mInternalDirtyBits.set(DIRTY_BIT_PROGRAM_UNIFORMS); + } + + // Swizzling can cause internal state changes with blit shaders. + if (mDirtySwizzles) + { + ANGLE_TRY(generateSwizzles(context)); + mDirtySwizzles = false; + } + + ANGLE_TRY(mFramebuffer11->markAttachmentsDirty(context)); + + // TODO(jiawei.shao@intel.com): This can be recomputed only on framebuffer or multisample mask + // state changes. + RenderTarget11 *firstRT = mFramebuffer11->getFirstRenderTarget(); + int samples = (firstRT ? firstRT->getSamples() : 0); + unsigned int sampleMask = GetBlendSampleMask(glState, samples); + if (sampleMask != mCurSampleMask) + { + mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE); + } + + ANGLE_TRY(mVertexArray11->syncStateForDraw(context, firstVertex, vertexOrIndexCount, + indexTypeOrInvalid, indices, instanceCount, + baseVertex, baseInstance, promoteDynamic)); + + // Changes in the draw call can affect the vertex buffer translations. + if (!mLastFirstVertex.valid() || mLastFirstVertex.value() != firstVertex) + { + mLastFirstVertex = firstVertex; + invalidateInputLayout(); + } + + // The ShaderConstants only need to be updated when the program uses vertexID + if (mProgramD3D->usesVertexID()) + { + GLint firstVertexOnChange = firstVertex + baseVertex; + ASSERT(mVertexArray11); + if (mVertexArray11->hasActiveDynamicAttrib(context) && + indexTypeOrInvalid != gl::DrawElementsType::InvalidEnum) + { + // drawElements with Dynamic attribute + // the firstVertex is already including baseVertex when + // doing ComputeStartVertex + firstVertexOnChange = firstVertex; + } + + if (mShaderConstants.onFirstVertexChange(firstVertexOnChange)) + { + mInternalDirtyBits.set(DIRTY_BIT_DRIVER_UNIFORMS); + } + } + + if (indexTypeOrInvalid != gl::DrawElementsType::InvalidEnum) + { + ANGLE_TRY(applyIndexBuffer(context, vertexOrIndexCount, indexTypeOrInvalid, indices)); + } + + if (mLastAppliedDrawMode != mode) + { + mLastAppliedDrawMode = mode; + mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY); + + bool pointDrawMode = (mode == gl::PrimitiveMode::Points); + if (pointDrawMode != mCurRasterState.pointDrawMode) + { + mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE); + + // Changing from points to not points (or vice-versa) affects the geometry shader. + invalidateShaders(); + } + } + + auto dirtyBitsCopy = mInternalDirtyBits & mGraphicsDirtyBitsMask; + + for (auto iter = dirtyBitsCopy.begin(), end = dirtyBitsCopy.end(); iter != end; ++iter) + { + mInternalDirtyBits.reset(*iter); + switch (*iter) + { + case DIRTY_BIT_RENDER_TARGET: + ANGLE_TRY(syncFramebuffer(context)); + break; + case DIRTY_BIT_VIEWPORT_STATE: + syncViewport(context); + break; + case DIRTY_BIT_SCISSOR_STATE: + syncScissorRectangle(context); + break; + case DIRTY_BIT_RASTERIZER_STATE: + ANGLE_TRY(syncRasterizerState(context, mode)); + break; + case DIRTY_BIT_BLEND_STATE: + ANGLE_TRY(syncBlendState( + context, glState.getBlendStateExt(), glState.getBlendColor(), sampleMask, + glState.isSampleAlphaToCoverageEnabled(), glState.hasConstantAlphaBlendFunc())); + break; + case DIRTY_BIT_DEPTH_STENCIL_STATE: + ANGLE_TRY(syncDepthStencilState(context)); + break; + case DIRTY_BIT_GRAPHICS_SRV_STATE: + ANGLE_TRY(syncTextures(context)); + break; + case DIRTY_BIT_GRAPHICS_UAV_STATE: + ANGLE_TRY(syncUAVsForGraphics(context)); + break; + case DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE: + // TODO(jmadill): More fine-grained update. + ANGLE_TRY(syncTextures(context)); + break; + case DIRTY_BIT_PROGRAM_UNIFORMS: + ANGLE_TRY(applyUniforms(context)); + break; + case DIRTY_BIT_DRIVER_UNIFORMS: + // This must happen after viewport sync; the viewport affects builtin uniforms. + ANGLE_TRY(applyDriverUniforms(context)); + break; + case DIRTY_BIT_PROGRAM_UNIFORM_BUFFERS: + ANGLE_TRY(syncUniformBuffers(context)); + break; + case DIRTY_BIT_SHADERS: + ANGLE_TRY(syncProgram(context, mode)); + break; + case DIRTY_BIT_CURRENT_VALUE_ATTRIBS: + ANGLE_TRY(syncCurrentValueAttribs(context, glState.getVertexAttribCurrentValues())); + break; + case DIRTY_BIT_TRANSFORM_FEEDBACK: + ANGLE_TRY(syncTransformFeedbackBuffers(context)); + break; + case DIRTY_BIT_VERTEX_BUFFERS_AND_INPUT_LAYOUT: + ANGLE_TRY(syncVertexBuffersAndInputLayout(context, mode, firstVertex, + vertexOrIndexCount, indexTypeOrInvalid, + instanceCount)); + break; + case DIRTY_BIT_PRIMITIVE_TOPOLOGY: + syncPrimitiveTopology(glState, mode); + break; + default: + UNREACHABLE(); + break; + } + } + + // Check that we haven't set any dirty bits in the flushing of the dirty bits loop, except + // DIRTY_BIT_COMPUTE_SRVUAV_STATE dirty bit. + ASSERT((mInternalDirtyBits & mGraphicsDirtyBitsMask).none()); + + return angle::Result::Continue; +} + +void StateManager11::setShaderResourceShared(gl::ShaderType shaderType, + UINT resourceSlot, + const d3d11::SharedSRV *srv) +{ + setShaderResourceInternal(shaderType, resourceSlot, srv); + + // TODO(jmadill): Narrower dirty region. + mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE); +} + +void StateManager11::setShaderResource(gl::ShaderType shaderType, + UINT resourceSlot, + const d3d11::ShaderResourceView *srv) +{ + setShaderResourceInternal(shaderType, resourceSlot, srv); + + // TODO(jmadill): Narrower dirty region. + mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE); +} + +void StateManager11::setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY primitiveTopology) +{ + if (setPrimitiveTopologyInternal(primitiveTopology)) + { + mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY); + } +} + +bool StateManager11::setPrimitiveTopologyInternal(D3D11_PRIMITIVE_TOPOLOGY primitiveTopology) +{ + if (primitiveTopology != mCurrentPrimitiveTopology) + { + mRenderer->getDeviceContext()->IASetPrimitiveTopology(primitiveTopology); + mCurrentPrimitiveTopology = primitiveTopology; + return true; + } + else + { + return false; + } +} + +void StateManager11::setDrawShaders(const d3d11::VertexShader *vertexShader, + const d3d11::GeometryShader *geometryShader, + const d3d11::PixelShader *pixelShader) +{ + setVertexShader(vertexShader); + setGeometryShader(geometryShader); + setPixelShader(pixelShader); +} + +void StateManager11::setVertexShader(const d3d11::VertexShader *shader) +{ + ResourceSerial serial = shader ? shader->getSerial() : ResourceSerial(0); + + if (serial != mAppliedShaders[gl::ShaderType::Vertex]) + { + ID3D11VertexShader *appliedShader = shader ? shader->get() : nullptr; + mRenderer->getDeviceContext()->VSSetShader(appliedShader, nullptr, 0); + mAppliedShaders[gl::ShaderType::Vertex] = serial; + invalidateShaders(); + } +} + +void StateManager11::setGeometryShader(const d3d11::GeometryShader *shader) +{ + ResourceSerial serial = shader ? shader->getSerial() : ResourceSerial(0); + + if (serial != mAppliedShaders[gl::ShaderType::Geometry]) + { + ID3D11GeometryShader *appliedShader = shader ? shader->get() : nullptr; + mRenderer->getDeviceContext()->GSSetShader(appliedShader, nullptr, 0); + mAppliedShaders[gl::ShaderType::Geometry] = serial; + invalidateShaders(); + } +} + +void StateManager11::setPixelShader(const d3d11::PixelShader *shader) +{ + ResourceSerial serial = shader ? shader->getSerial() : ResourceSerial(0); + + if (serial != mAppliedShaders[gl::ShaderType::Fragment]) + { + ID3D11PixelShader *appliedShader = shader ? shader->get() : nullptr; + mRenderer->getDeviceContext()->PSSetShader(appliedShader, nullptr, 0); + mAppliedShaders[gl::ShaderType::Fragment] = serial; + invalidateShaders(); + } +} + +void StateManager11::setComputeShader(const d3d11::ComputeShader *shader) +{ + ResourceSerial serial = shader ? shader->getSerial() : ResourceSerial(0); + + if (serial != mAppliedShaders[gl::ShaderType::Compute]) + { + ID3D11ComputeShader *appliedShader = shader ? shader->get() : nullptr; + mRenderer->getDeviceContext()->CSSetShader(appliedShader, nullptr, 0); + mAppliedShaders[gl::ShaderType::Compute] = serial; + invalidateShaders(); + } +} + +void StateManager11::setVertexConstantBuffer(unsigned int slot, const d3d11::Buffer *buffer) +{ + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + auto ¤tSerial = mCurrentConstantBufferVS[slot]; + + mCurrentConstantBufferVSOffset[slot] = 0; + mCurrentConstantBufferVSSize[slot] = 0; + + if (buffer) + { + if (currentSerial != buffer->getSerial()) + { + deviceContext->VSSetConstantBuffers(slot, 1, buffer->getPointer()); + currentSerial = buffer->getSerial(); + invalidateConstantBuffer(slot); + } + } + else + { + if (!currentSerial.empty()) + { + ID3D11Buffer *nullBuffer = nullptr; + deviceContext->VSSetConstantBuffers(slot, 1, &nullBuffer); + currentSerial.clear(); + invalidateConstantBuffer(slot); + } + } +} + +void StateManager11::setPixelConstantBuffer(unsigned int slot, const d3d11::Buffer *buffer) +{ + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + auto ¤tSerial = mCurrentConstantBufferPS[slot]; + + mCurrentConstantBufferPSOffset[slot] = 0; + mCurrentConstantBufferPSSize[slot] = 0; + + if (buffer) + { + if (currentSerial != buffer->getSerial()) + { + deviceContext->PSSetConstantBuffers(slot, 1, buffer->getPointer()); + currentSerial = buffer->getSerial(); + invalidateConstantBuffer(slot); + } + } + else + { + if (!currentSerial.empty()) + { + ID3D11Buffer *nullBuffer = nullptr; + deviceContext->PSSetConstantBuffers(slot, 1, &nullBuffer); + currentSerial.clear(); + invalidateConstantBuffer(slot); + } + } +} + +void StateManager11::setDepthStencilState(const d3d11::DepthStencilState *depthStencilState, + UINT stencilRef) +{ + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + if (depthStencilState) + { + deviceContext->OMSetDepthStencilState(depthStencilState->get(), stencilRef); + } + else + { + deviceContext->OMSetDepthStencilState(nullptr, stencilRef); + } + + mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE); +} + +void StateManager11::setSimpleBlendState(const d3d11::BlendState *blendState) +{ + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + if (blendState) + { + deviceContext->OMSetBlendState(blendState->get(), nullptr, 0xFFFFFFFF); + } + else + { + deviceContext->OMSetBlendState(nullptr, nullptr, 0xFFFFFFFF); + } + + mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE); +} + +void StateManager11::setRasterizerState(const d3d11::RasterizerState *rasterizerState) +{ + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + if (rasterizerState) + { + deviceContext->RSSetState(rasterizerState->get()); + } + else + { + deviceContext->RSSetState(nullptr); + } + + mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE); +} + +void StateManager11::setSimpleViewport(const gl::Extents &extents) +{ + setSimpleViewport(extents.width, extents.height); +} + +void StateManager11::setSimpleViewport(int width, int height) +{ + D3D11_VIEWPORT viewport; + viewport.TopLeftX = 0; + viewport.TopLeftY = 0; + viewport.Width = static_cast(width); + viewport.Height = static_cast(height); + viewport.MinDepth = 0.0f; + viewport.MaxDepth = 1.0f; + + mRenderer->getDeviceContext()->RSSetViewports(1, &viewport); + mInternalDirtyBits.set(DIRTY_BIT_VIEWPORT_STATE); +} + +void StateManager11::setSimplePixelTextureAndSampler(const d3d11::SharedSRV &srv, + const d3d11::SamplerState &samplerState) +{ + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + setShaderResourceInternal(gl::ShaderType::Fragment, 0, &srv); + deviceContext->PSSetSamplers(0, 1, samplerState.getPointer()); + + mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE); + mForceSetShaderSamplerStates[gl::ShaderType::Fragment][0] = true; +} + +void StateManager11::setSimpleScissorRect(const gl::Rectangle &glRect) +{ + D3D11_RECT scissorRect; + scissorRect.left = glRect.x; + scissorRect.right = glRect.x + glRect.width; + scissorRect.top = glRect.y; + scissorRect.bottom = glRect.y + glRect.height; + setScissorRectD3D(scissorRect); +} + +void StateManager11::setScissorRectD3D(const D3D11_RECT &d3dRect) +{ + mRenderer->getDeviceContext()->RSSetScissorRects(1, &d3dRect); + mInternalDirtyBits.set(DIRTY_BIT_SCISSOR_STATE); +} + +angle::Result StateManager11::syncTextures(const gl::Context *context) +{ + ANGLE_TRY(applyTexturesForSRVs(context, gl::ShaderType::Vertex)); + ANGLE_TRY(applyTexturesForSRVs(context, gl::ShaderType::Fragment)); + if (mProgramD3D->hasShaderStage(gl::ShaderType::Geometry)) + { + ANGLE_TRY(applyTexturesForSRVs(context, gl::ShaderType::Geometry)); + } + + return angle::Result::Continue; +} + +angle::Result StateManager11::setSamplerState(const gl::Context *context, + gl::ShaderType type, + int index, + gl::Texture *texture, + const gl::SamplerState &samplerState) +{ +#if !defined(NDEBUG) + // Storage should exist, texture should be complete. Only verified in Debug. + TextureD3D *textureD3D = GetImplAs(texture); + TextureStorage *storage = nullptr; + ANGLE_TRY(textureD3D->getNativeTexture(context, &storage)); + ASSERT(storage); +#endif // !defined(NDEBUG) + + auto *deviceContext = mRenderer->getDeviceContext(); + + ASSERT(index < mRenderer->getNativeCaps().maxShaderTextureImageUnits[type]); + + if (mForceSetShaderSamplerStates[type][index] || + memcmp(&samplerState, &mCurShaderSamplerStates[type][index], sizeof(gl::SamplerState)) != 0) + { + ID3D11SamplerState *dxSamplerState = nullptr; + ANGLE_TRY(mRenderer->getSamplerState(context, samplerState, &dxSamplerState)); + + ASSERT(dxSamplerState != nullptr); + + switch (type) + { + case gl::ShaderType::Vertex: + deviceContext->VSSetSamplers(index, 1, &dxSamplerState); + break; + case gl::ShaderType::Fragment: + deviceContext->PSSetSamplers(index, 1, &dxSamplerState); + break; + case gl::ShaderType::Compute: + deviceContext->CSSetSamplers(index, 1, &dxSamplerState); + break; + case gl::ShaderType::Geometry: + deviceContext->GSSetSamplers(index, 1, &dxSamplerState); + break; + default: + UNREACHABLE(); + break; + } + + mCurShaderSamplerStates[type][index] = samplerState; + } + + mForceSetShaderSamplerStates[type][index] = false; + + // Sampler metadata that's passed to shaders in uniforms is stored separately from rest of the + // sampler state since having it in contiguous memory makes it possible to memcpy to a constant + // buffer, and it doesn't affect the state set by + // PSSetSamplers/VSSetSamplers/CSSetSamplers/GSSetSamplers. + mShaderConstants.onSamplerChange(type, index, *texture, samplerState); + + return angle::Result::Continue; +} + +angle::Result StateManager11::setTextureForSampler(const gl::Context *context, + gl::ShaderType type, + int index, + gl::Texture *texture, + const gl::SamplerState &sampler) +{ + const d3d11::SharedSRV *textureSRV = nullptr; + + if (texture) + { + TextureD3D *textureImpl = GetImplAs(texture); + + TextureStorage *texStorage = nullptr; + ANGLE_TRY(textureImpl->getNativeTexture(context, &texStorage)); + + // Texture should be complete and have a storage + ASSERT(texStorage); + + TextureStorage11 *storage11 = GetAs(texStorage); + + ANGLE_TRY( + storage11->getSRVForSampler(context, texture->getTextureState(), sampler, &textureSRV)); + + // If we get an invalid SRV here, something went wrong in the texture class and we're + // unexpectedly missing the shader resource view. + ASSERT(textureSRV->valid()); + + textureImpl->resetDirty(); + } + + ASSERT( + (type == gl::ShaderType::Fragment && + index < mRenderer->getNativeCaps().maxShaderTextureImageUnits[gl::ShaderType::Fragment]) || + (type == gl::ShaderType::Vertex && + index < mRenderer->getNativeCaps().maxShaderTextureImageUnits[gl::ShaderType::Vertex]) || + (type == gl::ShaderType::Compute && + index < mRenderer->getNativeCaps().maxShaderTextureImageUnits[gl::ShaderType::Compute])); + + setShaderResourceInternal(type, index, textureSRV); + return angle::Result::Continue; +} + +angle::Result StateManager11::setImageState(const gl::Context *context, + gl::ShaderType type, + int index, + const gl::ImageUnit &imageUnit) +{ + ASSERT(index < mRenderer->getNativeCaps().maxShaderImageUniforms[type]); + + if (mShaderConstants.onImageChange(type, index, imageUnit)) + { + invalidateProgramUniforms(); + } + + return angle::Result::Continue; +} + +// For each Direct3D sampler of either the pixel or vertex stage, +// looks up the corresponding OpenGL texture image unit and texture type, +// and sets the texture and its addressing/filtering state (or NULL when inactive). +// Sampler mapping needs to be up-to-date on the program object before this is called. +angle::Result StateManager11::applyTexturesForSRVs(const gl::Context *context, + gl::ShaderType shaderType) +{ + const auto &glState = context->getState(); + const auto &caps = context->getCaps(); + + ASSERT(!mProgramD3D->isSamplerMappingDirty()); + + // TODO(jmadill): Use the Program's sampler bindings. + const gl::ActiveTexturesCache &completeTextures = glState.getActiveTexturesCache(); + + const gl::RangeUI samplerRange = mProgramD3D->getUsedSamplerRange(shaderType); + for (unsigned int samplerIndex = samplerRange.low(); samplerIndex < samplerRange.high(); + samplerIndex++) + { + GLint textureUnit = mProgramD3D->getSamplerMapping(shaderType, samplerIndex, caps); + ASSERT(textureUnit != -1); + gl::Texture *texture = completeTextures[textureUnit]; + + // A nullptr texture indicates incomplete. + if (texture) + { + gl::Sampler *samplerObject = glState.getSampler(textureUnit); + + const gl::SamplerState &samplerState = + samplerObject ? samplerObject->getSamplerState() : texture->getSamplerState(); + + ANGLE_TRY(setSamplerState(context, shaderType, samplerIndex, texture, samplerState)); + ANGLE_TRY( + setTextureForSampler(context, shaderType, samplerIndex, texture, samplerState)); + } + else + { + gl::TextureType textureType = + mProgramD3D->getSamplerTextureType(shaderType, samplerIndex); + + // Texture is not sampler complete or it is in use by the framebuffer. Bind the + // incomplete texture. + gl::Texture *incompleteTexture = nullptr; + ANGLE_TRY(mRenderer->getIncompleteTexture(context, textureType, &incompleteTexture)); + ANGLE_TRY(setSamplerState(context, shaderType, samplerIndex, incompleteTexture, + incompleteTexture->getSamplerState())); + ANGLE_TRY(setTextureForSampler(context, shaderType, samplerIndex, incompleteTexture, + incompleteTexture->getSamplerState())); + } + } + + const gl::RangeUI readonlyImageRange = mProgramD3D->getUsedImageRange(shaderType, true); + for (unsigned int readonlyImageIndex = readonlyImageRange.low(); + readonlyImageIndex < readonlyImageRange.high(); readonlyImageIndex++) + { + GLint imageUnitIndex = + mProgramD3D->getImageMapping(shaderType, readonlyImageIndex, true, caps); + ASSERT(imageUnitIndex != -1); + const gl::ImageUnit &imageUnit = glState.getImageUnit(imageUnitIndex); + if (!imageUnit.layered) + { + ANGLE_TRY(setImageState(context, gl::ShaderType::Compute, + readonlyImageIndex - readonlyImageRange.low(), imageUnit)); + } + ANGLE_TRY(setTextureForImage(context, shaderType, readonlyImageIndex, imageUnit)); + } + + return angle::Result::Continue; +} + +angle::Result StateManager11::getUAVsForRWImages(const gl::Context *context, + gl::ShaderType shaderType, + UAVList *uavList) +{ + const auto &glState = context->getState(); + const auto &caps = context->getCaps(); + + const gl::RangeUI imageRange = mProgramD3D->getUsedImageRange(shaderType, false); + for (unsigned int imageIndex = imageRange.low(); imageIndex < imageRange.high(); imageIndex++) + { + GLint imageUnitIndex = mProgramD3D->getImageMapping(shaderType, imageIndex, false, caps); + ASSERT(imageUnitIndex != -1); + const gl::ImageUnit &imageUnit = glState.getImageUnit(imageUnitIndex); + if (!imageUnit.layered) + { + ANGLE_TRY(setImageState(context, shaderType, imageIndex - imageRange.low(), imageUnit)); + } + ANGLE_TRY(getUAVForRWImage(context, shaderType, imageIndex, imageUnit, uavList)); + } + + return angle::Result::Continue; +} + +angle::Result StateManager11::syncTexturesForCompute(const gl::Context *context) +{ + ANGLE_TRY(applyTexturesForSRVs(context, gl::ShaderType::Compute)); + return angle::Result::Continue; +} + +angle::Result StateManager11::setTextureForImage(const gl::Context *context, + gl::ShaderType type, + int index, + const gl::ImageUnit &imageUnit) +{ + TextureD3D *textureImpl = nullptr; + if (!imageUnit.texture.get()) + { + setShaderResourceInternal(type, static_cast(index), + nullptr); + return angle::Result::Continue; + } + + textureImpl = GetImplAs(imageUnit.texture.get()); + + // Ensure that texture has unordered access; convert it if not. + ANGLE_TRY(textureImpl->ensureUnorderedAccess(context)); + + TextureStorage *texStorage = nullptr; + ANGLE_TRY(textureImpl->getNativeTexture(context, &texStorage)); + // Texture should be complete and have a storage + ASSERT(texStorage); + TextureStorage11 *storage11 = GetAs(texStorage); + + const d3d11::SharedSRV *textureSRV = nullptr; + ANGLE_TRY(storage11->getSRVForImage(context, imageUnit, &textureSRV)); + // If we get an invalid SRV here, something went wrong in the texture class and we're + // unexpectedly missing the shader resource view. + ASSERT(textureSRV->valid()); + ASSERT((index < mRenderer->getNativeCaps().maxImageUnits)); + setShaderResourceInternal(type, index, textureSRV); + + textureImpl->resetDirty(); + return angle::Result::Continue; +} + +angle::Result StateManager11::getUAVForRWImage(const gl::Context *context, + gl::ShaderType type, + int index, + const gl::ImageUnit &imageUnit, + UAVList *uavList) +{ + TextureD3D *textureImpl = nullptr; + if (!imageUnit.texture.get()) + { + setUnorderedAccessViewInternal(static_cast(index), + nullptr, uavList); + return angle::Result::Continue; + } + + textureImpl = GetImplAs(imageUnit.texture.get()); + + // Ensure that texture has unordered access; convert it if not. + ANGLE_TRY(textureImpl->ensureUnorderedAccess(context)); + + TextureStorage *texStorage = nullptr; + ANGLE_TRY(textureImpl->getNativeTexture(context, &texStorage)); + // Texture should be complete and have a storage + ASSERT(texStorage); + TextureStorage11 *storage11 = GetAs(texStorage); + + const d3d11::SharedUAV *textureUAV = nullptr; + ANGLE_TRY(storage11->getUAVForImage(context, imageUnit, &textureUAV)); + // If we get an invalid UAV here, something went wrong in the texture class and we're + // unexpectedly missing the unordered access view. + ASSERT(textureUAV->valid()); + ASSERT((index < mRenderer->getNativeCaps().maxImageUnits)); + setUnorderedAccessViewInternal(index, textureUAV, uavList); + + textureImpl->resetDirty(); + return angle::Result::Continue; +} + +// Things that affect a program's dirtyness: +// 1. Directly changing the program executable -> triggered in StateManager11::syncState. +// 2. The vertex attribute layout -> triggered in VertexArray11::syncState/signal. +// 3. The fragment shader's rendertargets -> triggered in Framebuffer11::syncState/signal. +// 4. Enabling/disabling rasterizer discard. -> triggered in StateManager11::syncState. +// 5. Enabling/disabling transform feedback. -> checked in StateManager11::updateState. +// 6. An internal shader was used. -> triggered in StateManager11::set*Shader. +// 7. Drawing with/without point sprites. -> checked in StateManager11::updateState. +// TODO(jmadill): Use dirty bits for transform feedback. +angle::Result StateManager11::syncProgram(const gl::Context *context, gl::PrimitiveMode drawMode) +{ + Context11 *context11 = GetImplAs(context); + ANGLE_TRY(context11->triggerDrawCallProgramRecompilation(context, drawMode)); + + const auto &glState = context->getState(); + + mProgramD3D->updateCachedInputLayout(mVertexArray11->getCurrentStateSerial(), glState); + + // Binaries must be compiled before the sync. + ASSERT(mProgramD3D->hasVertexExecutableForCachedInputLayout()); + ASSERT(mProgramD3D->hasGeometryExecutableForPrimitiveType(glState, drawMode)); + ASSERT(mProgramD3D->hasPixelExecutableForCachedOutputLayout()); + + ShaderExecutableD3D *vertexExe = nullptr; + ANGLE_TRY(mProgramD3D->getVertexExecutableForCachedInputLayout(context11, &vertexExe, nullptr)); + + ShaderExecutableD3D *pixelExe = nullptr; + ANGLE_TRY(mProgramD3D->getPixelExecutableForCachedOutputLayout(context11, &pixelExe, nullptr)); + + ShaderExecutableD3D *geometryExe = nullptr; + ANGLE_TRY(mProgramD3D->getGeometryExecutableForPrimitiveType(context11, glState, drawMode, + &geometryExe, nullptr)); + + const d3d11::VertexShader *vertexShader = + (vertexExe ? &GetAs(vertexExe)->getVertexShader() : nullptr); + + // Skip pixel shader if we're doing rasterizer discard. + const d3d11::PixelShader *pixelShader = nullptr; + if (!glState.getRasterizerState().rasterizerDiscard) + { + pixelShader = (pixelExe ? &GetAs(pixelExe)->getPixelShader() : nullptr); + } + + const d3d11::GeometryShader *geometryShader = nullptr; + if (glState.isTransformFeedbackActiveUnpaused()) + { + geometryShader = + (vertexExe ? &GetAs(vertexExe)->getStreamOutShader() : nullptr); + } + else + { + geometryShader = + (geometryExe ? &GetAs(geometryExe)->getGeometryShader() : nullptr); + } + + setDrawShaders(vertexShader, geometryShader, pixelShader); + + // Explicitly clear the shaders dirty bit. + mInternalDirtyBits.reset(DIRTY_BIT_SHADERS); + + return angle::Result::Continue; +} + +angle::Result StateManager11::syncProgramForCompute(const gl::Context *context) +{ + Context11 *context11 = GetImplAs(context); + ANGLE_TRY(context11->triggerDispatchCallProgramRecompilation(context)); + + mProgramD3D->updateCachedComputeImage2DBindLayout(context); + + // Binaries must be compiled before the sync. + ASSERT(mProgramD3D->hasComputeExecutableForCachedImage2DBindLayout()); + + ShaderExecutableD3D *computeExe = nullptr; + ANGLE_TRY(mProgramD3D->getComputeExecutableForImage2DBindLayout(context, context11, &computeExe, + nullptr)); + + const d3d11::ComputeShader *computeShader = + (computeExe ? &GetAs(computeExe)->getComputeShader() : nullptr); + setComputeShader(computeShader); + // Explicitly clear the shaders dirty bit. + mInternalDirtyBits.reset(DIRTY_BIT_SHADERS); + + return angle::Result::Continue; +} + +angle::Result StateManager11::syncVertexBuffersAndInputLayout( + const gl::Context *context, + gl::PrimitiveMode mode, + GLint firstVertex, + GLsizei vertexOrIndexCount, + gl::DrawElementsType indexTypeOrInvalid, + GLsizei instanceCount) +{ + const auto &vertexArrayAttribs = mVertexArray11->getTranslatedAttribs(); + + // Sort the attributes according to ensure we re-use similar input layouts. + AttribIndexArray sortedSemanticIndices; + SortAttributesByLayout(*mProgramD3D, vertexArrayAttribs, mCurrentValueAttribs, + &sortedSemanticIndices, &mCurrentAttributes); + + D3D_FEATURE_LEVEL featureLevel = mRenderer->getRenderer11DeviceCaps().featureLevel; + + // If we are using FL 9_3, make sure the first attribute is not instanced + if (featureLevel <= D3D_FEATURE_LEVEL_9_3 && !mCurrentAttributes.empty()) + { + if (mCurrentAttributes[0]->divisor > 0) + { + Optional firstNonInstancedIndex = FindFirstNonInstanced(mCurrentAttributes); + if (firstNonInstancedIndex.valid()) + { + size_t index = firstNonInstancedIndex.value(); + std::swap(mCurrentAttributes[0], mCurrentAttributes[index]); + std::swap(sortedSemanticIndices[0], sortedSemanticIndices[index]); + } + } + } + + // Update the applied input layout by querying the cache. + const gl::State &state = context->getState(); + const d3d11::InputLayout *inputLayout = nullptr; + ANGLE_TRY(mInputLayoutCache.getInputLayout(GetImplAs(context), state, + mCurrentAttributes, sortedSemanticIndices, mode, + vertexOrIndexCount, instanceCount, &inputLayout)); + setInputLayoutInternal(inputLayout); + + // Update the applied vertex buffers. + ANGLE_TRY(applyVertexBuffers(context, mode, indexTypeOrInvalid, firstVertex)); + + return angle::Result::Continue; +} + +angle::Result StateManager11::applyVertexBuffers(const gl::Context *context, + gl::PrimitiveMode mode, + gl::DrawElementsType indexTypeOrInvalid, + GLint firstVertex) +{ + bool programUsesInstancedPointSprites = + mProgramD3D->usesPointSize() && mProgramD3D->usesInstancedPointSpriteEmulation(); + bool instancedPointSpritesActive = + programUsesInstancedPointSprites && (mode == gl::PrimitiveMode::Points); + + // Note that if we use instance emulation, we reserve the first buffer slot. + size_t reservedBuffers = GetReservedBufferCount(programUsesInstancedPointSprites); + + for (size_t attribIndex = 0; attribIndex < (gl::MAX_VERTEX_ATTRIBS - reservedBuffers); + ++attribIndex) + { + ID3D11Buffer *buffer = nullptr; + UINT vertexStride = 0; + UINT vertexOffset = 0; + + if (attribIndex < mCurrentAttributes.size()) + { + const TranslatedAttribute &attrib = *mCurrentAttributes[attribIndex]; + Buffer11 *bufferStorage = attrib.storage ? GetAs(attrib.storage) : nullptr; + + // If indexed pointsprite emulation is active, then we need to take a less efficent code + // path. Emulated indexed pointsprite rendering requires that the vertex buffers match + // exactly to the indices passed by the caller. This could expand or shrink the vertex + // buffer depending on the number of points indicated by the index list or how many + // duplicates are found on the index list. + if (bufferStorage == nullptr) + { + ASSERT(attrib.vertexBuffer.get()); + buffer = GetAs(attrib.vertexBuffer.get())->getBuffer().get(); + } + else if (instancedPointSpritesActive && + indexTypeOrInvalid != gl::DrawElementsType::InvalidEnum) + { + ASSERT(mVertexArray11->isCachedIndexInfoValid()); + TranslatedIndexData indexInfo = mVertexArray11->getCachedIndexInfo(); + if (indexInfo.srcIndexData.srcBuffer != nullptr) + { + const uint8_t *bufferData = nullptr; + ANGLE_TRY(indexInfo.srcIndexData.srcBuffer->getData(context, &bufferData)); + ASSERT(bufferData != nullptr); + + ptrdiff_t offset = + reinterpret_cast(indexInfo.srcIndexData.srcIndices); + indexInfo.srcIndexData.srcBuffer = nullptr; + indexInfo.srcIndexData.srcIndices = bufferData + offset; + } + + ANGLE_TRY(bufferStorage->getEmulatedIndexedBuffer(context, &indexInfo.srcIndexData, + attrib, firstVertex, &buffer)); + + mVertexArray11->updateCachedIndexInfo(indexInfo); + } + else + { + ANGLE_TRY(bufferStorage->getBuffer( + context, BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK, &buffer)); + } + + vertexStride = attrib.stride; + ANGLE_TRY(attrib.computeOffset(context, firstVertex, &vertexOffset)); + } + + size_t bufferIndex = reservedBuffers + attribIndex; + + queueVertexBufferChange(bufferIndex, buffer, vertexStride, vertexOffset); + } + + Context11 *context11 = GetImplAs(context); + + // Instanced PointSprite emulation requires two additional ID3D11Buffers. A vertex buffer needs + // to be created and added to the list of current buffers, strides and offsets collections. + // This buffer contains the vertices for a single PointSprite quad. + // An index buffer also needs to be created and applied because rendering instanced data on + // D3D11 FL9_3 requires DrawIndexedInstanced() to be used. Shaders that contain gl_PointSize and + // used without the GL_POINTS rendering mode require a vertex buffer because some drivers cannot + // handle missing vertex data and will TDR the system. + if (programUsesInstancedPointSprites) + { + constexpr UINT kPointSpriteVertexStride = sizeof(float) * 5; + + if (!mPointSpriteVertexBuffer.valid()) + { + static constexpr float kPointSpriteVertices[] = { + // Position | TexCoord + -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, /* v0 */ + -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, /* v1 */ + 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, /* v2 */ + 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, /* v3 */ + -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, /* v4 */ + 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, /* v5 */ + }; + + D3D11_SUBRESOURCE_DATA vertexBufferData = {kPointSpriteVertices, 0, 0}; + D3D11_BUFFER_DESC vertexBufferDesc; + vertexBufferDesc.ByteWidth = sizeof(kPointSpriteVertices); + vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + vertexBufferDesc.Usage = D3D11_USAGE_IMMUTABLE; + vertexBufferDesc.CPUAccessFlags = 0; + vertexBufferDesc.MiscFlags = 0; + vertexBufferDesc.StructureByteStride = 0; + + ANGLE_TRY(mRenderer->allocateResource(context11, vertexBufferDesc, &vertexBufferData, + &mPointSpriteVertexBuffer)); + } + + // Set the stride to 0 if GL_POINTS mode is not being used to instruct the driver to avoid + // indexing into the vertex buffer. + UINT stride = instancedPointSpritesActive ? kPointSpriteVertexStride : 0; + queueVertexBufferChange(0, mPointSpriteVertexBuffer.get(), stride, 0); + + if (!mPointSpriteIndexBuffer.valid()) + { + // Create an index buffer and set it for pointsprite rendering + static constexpr unsigned short kPointSpriteIndices[] = { + 0, 1, 2, 3, 4, 5, + }; + + D3D11_SUBRESOURCE_DATA indexBufferData = {kPointSpriteIndices, 0, 0}; + D3D11_BUFFER_DESC indexBufferDesc; + indexBufferDesc.ByteWidth = sizeof(kPointSpriteIndices); + indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; + indexBufferDesc.Usage = D3D11_USAGE_IMMUTABLE; + indexBufferDesc.CPUAccessFlags = 0; + indexBufferDesc.MiscFlags = 0; + indexBufferDesc.StructureByteStride = 0; + + ANGLE_TRY(mRenderer->allocateResource(context11, indexBufferDesc, &indexBufferData, + &mPointSpriteIndexBuffer)); + } + + if (instancedPointSpritesActive) + { + // The index buffer is applied here because Instanced PointSprite emulation uses the a + // non-indexed rendering path in ANGLE (DrawArrays). This means that applyIndexBuffer() + // on the renderer will not be called and setting this buffer here ensures that the + // rendering path will contain the correct index buffers. + syncIndexBuffer(mPointSpriteIndexBuffer.get(), DXGI_FORMAT_R16_UINT, 0); + } + } + + applyVertexBufferChanges(); + return angle::Result::Continue; +} + +angle::Result StateManager11::applyIndexBuffer(const gl::Context *context, + GLsizei indexCount, + gl::DrawElementsType indexType, + const void *indices) +{ + if (!mIndexBufferIsDirty) + { + // No streaming or index buffer application necessary. + return angle::Result::Continue; + } + + gl::DrawElementsType destElementType = mVertexArray11->getCachedDestinationIndexType(); + gl::Buffer *elementArrayBuffer = mVertexArray11->getState().getElementArrayBuffer(); + + TranslatedIndexData indexInfo; + ANGLE_TRY(mIndexDataManager.prepareIndexData(context, indexType, destElementType, indexCount, + elementArrayBuffer, indices, &indexInfo)); + + ID3D11Buffer *buffer = nullptr; + DXGI_FORMAT bufferFormat = (indexInfo.indexType == gl::DrawElementsType::UnsignedInt) + ? DXGI_FORMAT_R32_UINT + : DXGI_FORMAT_R16_UINT; + + if (indexInfo.storage) + { + Buffer11 *storage = GetAs(indexInfo.storage); + ANGLE_TRY(storage->getBuffer(context, BUFFER_USAGE_INDEX, &buffer)); + } + else + { + IndexBuffer11 *indexBuffer = GetAs(indexInfo.indexBuffer); + buffer = indexBuffer->getBuffer().get(); + } + + // Track dirty indices in the index range cache. + indexInfo.srcIndexData.srcIndicesChanged = + syncIndexBuffer(buffer, bufferFormat, indexInfo.startOffset); + + mIndexBufferIsDirty = false; + + mVertexArray11->updateCachedIndexInfo(indexInfo); + return angle::Result::Continue; +} + +void StateManager11::setIndexBuffer(ID3D11Buffer *buffer, + DXGI_FORMAT indexFormat, + unsigned int offset) +{ + if (syncIndexBuffer(buffer, indexFormat, offset)) + { + invalidateIndexBuffer(); + } +} + +bool StateManager11::syncIndexBuffer(ID3D11Buffer *buffer, + DXGI_FORMAT indexFormat, + unsigned int offset) +{ + if (buffer != mAppliedIB || indexFormat != mAppliedIBFormat || offset != mAppliedIBOffset) + { + mRenderer->getDeviceContext()->IASetIndexBuffer(buffer, indexFormat, offset); + + mAppliedIB = buffer; + mAppliedIBFormat = indexFormat; + mAppliedIBOffset = offset; + return true; + } + + return false; +} + +// Vertex buffer is invalidated outside this function. +angle::Result StateManager11::updateVertexOffsetsForPointSpritesEmulation( + const gl::Context *context, + GLint startVertex, + GLsizei emulatedInstanceId) +{ + size_t reservedBuffers = GetReservedBufferCount(true); + for (size_t attribIndex = 0; attribIndex < mCurrentAttributes.size(); ++attribIndex) + { + const auto &attrib = *mCurrentAttributes[attribIndex]; + size_t bufferIndex = reservedBuffers + attribIndex; + + if (attrib.divisor > 0) + { + unsigned int offset = 0; + ANGLE_TRY(attrib.computeOffset(context, startVertex, &offset)); + offset += (attrib.stride * (emulatedInstanceId / attrib.divisor)); + if (offset != mCurrentVertexOffsets[bufferIndex]) + { + invalidateInputLayout(); + mDirtyVertexBufferRange.extend(static_cast(bufferIndex)); + mCurrentVertexOffsets[bufferIndex] = offset; + } + } + } + + applyVertexBufferChanges(); + return angle::Result::Continue; +} + +angle::Result StateManager11::generateSwizzle(const gl::Context *context, gl::Texture *texture) +{ + if (!texture) + { + return angle::Result::Continue; + } + + TextureD3D *textureD3D = GetImplAs(texture); + ASSERT(textureD3D); + + TextureStorage *texStorage = nullptr; + ANGLE_TRY(textureD3D->getNativeTexture(context, &texStorage)); + + if (texStorage) + { + TextureStorage11 *storage11 = GetAs(texStorage); + const gl::TextureState &textureState = texture->getTextureState(); + ANGLE_TRY(storage11->generateSwizzles(context, textureState)); + } + + return angle::Result::Continue; +} + +angle::Result StateManager11::generateSwizzlesForShader(const gl::Context *context, + gl::ShaderType type) +{ + const gl::State &glState = context->getState(); + const gl::RangeUI samplerRange = mProgramD3D->getUsedSamplerRange(type); + + for (unsigned int i = samplerRange.low(); i < samplerRange.high(); i++) + { + gl::TextureType textureType = mProgramD3D->getSamplerTextureType(type, i); + GLint textureUnit = mProgramD3D->getSamplerMapping(type, i, context->getCaps()); + if (textureUnit != -1) + { + gl::Texture *texture = glState.getSamplerTexture(textureUnit, textureType); + ASSERT(texture); + if (SwizzleRequired(texture->getTextureState())) + { + ANGLE_TRY(generateSwizzle(context, texture)); + } + } + } + + return angle::Result::Continue; +} + +angle::Result StateManager11::generateSwizzles(const gl::Context *context) +{ + ANGLE_TRY(generateSwizzlesForShader(context, gl::ShaderType::Vertex)); + ANGLE_TRY(generateSwizzlesForShader(context, gl::ShaderType::Fragment)); + return angle::Result::Continue; +} + +angle::Result StateManager11::applyUniformsForShader(const gl::Context *context, + gl::ShaderType shaderType) +{ + UniformStorage11 *shaderUniformStorage = + GetAs(mProgramD3D->getShaderUniformStorage(shaderType)); + ASSERT(shaderUniformStorage); + + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + const d3d11::Buffer *shaderConstantBuffer = nullptr; + ANGLE_TRY(shaderUniformStorage->getConstantBuffer(context, mRenderer, &shaderConstantBuffer)); + + if (shaderUniformStorage->size() > 0 && mProgramD3D->areShaderUniformsDirty(shaderType)) + { + UpdateUniformBuffer(deviceContext, shaderUniformStorage, shaderConstantBuffer); + } + + unsigned int slot = d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DEFAULT_UNIFORM_BLOCK; + + switch (shaderType) + { + case gl::ShaderType::Vertex: + if (mCurrentConstantBufferVS[slot] != shaderConstantBuffer->getSerial()) + { + deviceContext->VSSetConstantBuffers(slot, 1, shaderConstantBuffer->getPointer()); + mCurrentConstantBufferVS[slot] = shaderConstantBuffer->getSerial(); + mCurrentConstantBufferVSOffset[slot] = 0; + mCurrentConstantBufferVSSize[slot] = 0; + } + break; + + case gl::ShaderType::Fragment: + if (mCurrentConstantBufferPS[slot] != shaderConstantBuffer->getSerial()) + { + deviceContext->PSSetConstantBuffers(slot, 1, shaderConstantBuffer->getPointer()); + mCurrentConstantBufferPS[slot] = shaderConstantBuffer->getSerial(); + mCurrentConstantBufferPSOffset[slot] = 0; + mCurrentConstantBufferPSSize[slot] = 0; + } + break; + + // TODO(jiawei.shao@intel.com): apply geometry shader uniforms + case gl::ShaderType::Geometry: + UNIMPLEMENTED(); + break; + + default: + UNREACHABLE(); + break; + } + + return angle::Result::Continue; +} + +angle::Result StateManager11::applyUniforms(const gl::Context *context) +{ + ANGLE_TRY(applyUniformsForShader(context, gl::ShaderType::Vertex)); + ANGLE_TRY(applyUniformsForShader(context, gl::ShaderType::Fragment)); + if (mProgramD3D->hasShaderStage(gl::ShaderType::Geometry)) + { + ANGLE_TRY(applyUniformsForShader(context, gl::ShaderType::Geometry)); + } + + mProgramD3D->markUniformsClean(); + + return angle::Result::Continue; +} + +angle::Result StateManager11::applyDriverUniformsForShader(const gl::Context *context, + gl::ShaderType shaderType) +{ + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + d3d11::Buffer &shaderDriverConstantBuffer = mShaderDriverConstantBuffers[shaderType]; + if (!shaderDriverConstantBuffer.valid()) + { + size_t requiredSize = mShaderConstants.getRequiredBufferSize(shaderType); + + D3D11_BUFFER_DESC constantBufferDescription = {}; + d3d11::InitConstantBufferDesc(&constantBufferDescription, requiredSize); + ANGLE_TRY(mRenderer->allocateResource( + GetImplAs(context), constantBufferDescription, &shaderDriverConstantBuffer)); + + ID3D11Buffer *driverConstants = shaderDriverConstantBuffer.get(); + switch (shaderType) + { + case gl::ShaderType::Vertex: + deviceContext->VSSetConstantBuffers(d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER, 1, + &driverConstants); + break; + + case gl::ShaderType::Fragment: + deviceContext->PSSetConstantBuffers(d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER, 1, + &driverConstants); + break; + + case gl::ShaderType::Geometry: + deviceContext->GSSetConstantBuffers(d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER, 1, + &driverConstants); + break; + + default: + UNREACHABLE(); + return angle::Result::Continue; + } + } + + // Sampler metadata and driver constants need to coexist in the same constant buffer to + // conserve constant buffer slots. We update both in the constant buffer if needed. + ANGLE_TRY(mShaderConstants.updateBuffer(context, mRenderer, shaderType, *mProgramD3D, + shaderDriverConstantBuffer)); + + return angle::Result::Continue; +} + +angle::Result StateManager11::applyDriverUniforms(const gl::Context *context) +{ + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + ANGLE_TRY(applyDriverUniformsForShader(context, gl::ShaderType::Vertex)); + ANGLE_TRY(applyDriverUniformsForShader(context, gl::ShaderType::Fragment)); + if (mProgramD3D->hasShaderStage(gl::ShaderType::Geometry)) + { + ANGLE_TRY(applyDriverUniformsForShader(context, gl::ShaderType::Geometry)); + } + + // needed for the point sprite geometry shader + // GSSetConstantBuffers triggers device removal on 9_3, so we should only call it for ES3. + if (mRenderer->isES3Capable()) + { + d3d11::Buffer &driverConstantBufferPS = + mShaderDriverConstantBuffers[gl::ShaderType::Fragment]; + if (mCurrentGeometryConstantBuffer != driverConstantBufferPS.getSerial()) + { + ASSERT(driverConstantBufferPS.valid()); + deviceContext->GSSetConstantBuffers(0, 1, driverConstantBufferPS.getPointer()); + mCurrentGeometryConstantBuffer = driverConstantBufferPS.getSerial(); + } + } + + return angle::Result::Continue; +} + +angle::Result StateManager11::applyComputeUniforms(const gl::Context *context, + ProgramD3D *programD3D) +{ + UniformStorage11 *computeUniformStorage = + GetAs(programD3D->getShaderUniformStorage(gl::ShaderType::Compute)); + ASSERT(computeUniformStorage); + + const d3d11::Buffer *constantBuffer = nullptr; + ANGLE_TRY(computeUniformStorage->getConstantBuffer(context, mRenderer, &constantBuffer)); + + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + if (computeUniformStorage->size() > 0 && + programD3D->areShaderUniformsDirty(gl::ShaderType::Compute)) + { + UpdateUniformBuffer(deviceContext, computeUniformStorage, constantBuffer); + programD3D->markUniformsClean(); + } + + if (mCurrentComputeConstantBuffer != constantBuffer->getSerial()) + { + deviceContext->CSSetConstantBuffers( + d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DEFAULT_UNIFORM_BLOCK, 1, + constantBuffer->getPointer()); + mCurrentComputeConstantBuffer = constantBuffer->getSerial(); + } + + if (!mShaderDriverConstantBuffers[gl::ShaderType::Compute].valid()) + { + size_t requiredSize = mShaderConstants.getRequiredBufferSize(gl::ShaderType::Compute); + + D3D11_BUFFER_DESC constantBufferDescription = {}; + d3d11::InitConstantBufferDesc(&constantBufferDescription, requiredSize); + ANGLE_TRY( + mRenderer->allocateResource(GetImplAs(context), constantBufferDescription, + &mShaderDriverConstantBuffers[gl::ShaderType::Compute])); + ID3D11Buffer *buffer = mShaderDriverConstantBuffers[gl::ShaderType::Compute].get(); + deviceContext->CSSetConstantBuffers(d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER, 1, + &buffer); + } + + ANGLE_TRY(mShaderConstants.updateBuffer(context, mRenderer, gl::ShaderType::Compute, + *programD3D, + mShaderDriverConstantBuffers[gl::ShaderType::Compute])); + + return angle::Result::Continue; +} + +angle::Result StateManager11::syncUniformBuffersForShader(const gl::Context *context, + gl::ShaderType shaderType) +{ + const auto &glState = context->getState(); + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported(); + + const auto &shaderUniformBuffers = mProgramD3D->getShaderUniformBufferCache(shaderType); + + for (size_t bufferIndex = 0; bufferIndex < shaderUniformBuffers.size(); ++bufferIndex) + { + const D3DUBOCache cache = shaderUniformBuffers[bufferIndex]; + if (cache.binding == -1) + { + continue; + } + + const auto &uniformBuffer = glState.getIndexedUniformBuffer(cache.binding); + const GLintptr uniformBufferOffset = uniformBuffer.getOffset(); + const GLsizeiptr uniformBufferSize = uniformBuffer.getSize(); + + if (uniformBuffer.get() == nullptr) + { + continue; + } + + Buffer11 *bufferStorage = GetImplAs(uniformBuffer.get()); + const d3d11::Buffer *constantBuffer = nullptr; + UINT firstConstant = 0; + UINT numConstants = 0; + + ANGLE_TRY(bufferStorage->getConstantBufferRange(context, uniformBufferOffset, + uniformBufferSize, &constantBuffer, + &firstConstant, &numConstants)); + ASSERT(constantBuffer); + + switch (shaderType) + { + case gl::ShaderType::Vertex: + { + if (mCurrentConstantBufferVS[cache.registerIndex] == constantBuffer->getSerial() && + mCurrentConstantBufferVSOffset[cache.registerIndex] == uniformBufferOffset && + mCurrentConstantBufferVSSize[cache.registerIndex] == uniformBufferSize) + { + continue; + } + + if (firstConstant != 0 && uniformBufferSize != 0) + { + ASSERT(numConstants != 0); + deviceContext1->VSSetConstantBuffers1(cache.registerIndex, 1, + constantBuffer->getPointer(), + &firstConstant, &numConstants); + } + else + { + deviceContext->VSSetConstantBuffers(cache.registerIndex, 1, + constantBuffer->getPointer()); + } + + mCurrentConstantBufferVS[cache.registerIndex] = constantBuffer->getSerial(); + mCurrentConstantBufferVSOffset[cache.registerIndex] = uniformBufferOffset; + mCurrentConstantBufferVSSize[cache.registerIndex] = uniformBufferSize; + break; + } + + case gl::ShaderType::Fragment: + { + if (mCurrentConstantBufferPS[cache.registerIndex] == constantBuffer->getSerial() && + mCurrentConstantBufferPSOffset[cache.registerIndex] == uniformBufferOffset && + mCurrentConstantBufferPSSize[cache.registerIndex] == uniformBufferSize) + { + continue; + } + + if (firstConstant != 0 && uniformBufferSize != 0) + { + deviceContext1->PSSetConstantBuffers1(cache.registerIndex, 1, + constantBuffer->getPointer(), + &firstConstant, &numConstants); + } + else + { + deviceContext->PSSetConstantBuffers(cache.registerIndex, 1, + constantBuffer->getPointer()); + } + + mCurrentConstantBufferPS[cache.registerIndex] = constantBuffer->getSerial(); + mCurrentConstantBufferPSOffset[cache.registerIndex] = uniformBufferOffset; + mCurrentConstantBufferPSSize[cache.registerIndex] = uniformBufferSize; + break; + } + + case gl::ShaderType::Compute: + { + if (mCurrentConstantBufferCS[bufferIndex] == constantBuffer->getSerial() && + mCurrentConstantBufferCSOffset[bufferIndex] == uniformBufferOffset && + mCurrentConstantBufferCSSize[bufferIndex] == uniformBufferSize) + { + continue; + } + + if (firstConstant != 0 && uniformBufferSize != 0) + { + deviceContext1->CSSetConstantBuffers1(cache.registerIndex, 1, + constantBuffer->getPointer(), + &firstConstant, &numConstants); + } + else + { + deviceContext->CSSetConstantBuffers(cache.registerIndex, 1, + constantBuffer->getPointer()); + } + + mCurrentConstantBufferCS[cache.registerIndex] = constantBuffer->getSerial(); + mCurrentConstantBufferCSOffset[cache.registerIndex] = uniformBufferOffset; + mCurrentConstantBufferCSSize[cache.registerIndex] = uniformBufferSize; + break; + } + + // TODO(jiawei.shao@intel.com): update geometry shader uniform buffers. + case gl::ShaderType::Geometry: + UNIMPLEMENTED(); + break; + + default: + UNREACHABLE(); + } + } + + const auto &shaderUniformBuffersUseSB = + mProgramD3D->getShaderUniformBufferCacheUseSB(shaderType); + for (size_t bufferIndex = 0; bufferIndex < shaderUniformBuffersUseSB.size(); ++bufferIndex) + { + const D3DUBOCacheUseSB cache = shaderUniformBuffersUseSB[bufferIndex]; + if (cache.binding == -1) + { + continue; + } + + const auto &uniformBuffer = glState.getIndexedUniformBuffer(cache.binding); + if (uniformBuffer.get() == nullptr) + { + continue; + } + const GLintptr uniformBufferOffset = uniformBuffer.getOffset(); + + Buffer11 *bufferStorage = GetImplAs(uniformBuffer.get()); + const d3d11::ShaderResourceView *bufferSRV = nullptr; + ANGLE_TRY(bufferStorage->getStructuredBufferRangeSRV( + context, static_cast(uniformBufferOffset), cache.byteWidth, + cache.structureByteStride, &bufferSRV)); + + ASSERT(bufferSRV->valid()); + setShaderResourceInternal(shaderType, cache.registerIndex, bufferSRV); + } + + return angle::Result::Continue; +} + +angle::Result StateManager11::getUAVsForShaderStorageBuffers(const gl::Context *context, + gl::ShaderType shaderType, + UAVList *uavList) +{ + const gl::State &glState = context->getState(); + const gl::Program *program = glState.getProgram(); + angle::FixedVector + previouslyBound; + for (size_t blockIndex = 0; blockIndex < program->getActiveShaderStorageBlockCount(); + blockIndex++) + { + GLuint binding = program->getShaderStorageBlockBinding(static_cast(blockIndex)); + const unsigned int registerIndex = mProgramD3D->getShaderStorageBufferRegisterIndex( + static_cast(blockIndex), shaderType); + // It means this block is active but not statically used. + if (registerIndex == GL_INVALID_INDEX) + { + continue; + } + const auto &shaderStorageBuffer = glState.getIndexedShaderStorageBuffer(binding); + if (shaderStorageBuffer.get() == nullptr) + { + // We didn't see a driver error like atomic buffer did. But theoretically, the same + // thing should be done. + setUnorderedAccessViewInternal(registerIndex, nullptr, + uavList); + continue; + } + + Buffer11 *bufferStorage = GetImplAs(shaderStorageBuffer.get()); + if (std::find(previouslyBound.begin(), previouslyBound.end(), bufferStorage) != + previouslyBound.end()) + { + // D3D11 doesn't support binding a buffer multiple times + // http://anglebug.com/3032 + ERR() << "Writing to multiple blocks on the same buffer is not allowed."; + return angle::Result::Stop; + } + previouslyBound.push_back(bufferStorage); + + d3d11::UnorderedAccessView *uavPtr = nullptr; + GLsizeiptr viewSize = 0; + // Bindings only have a valid size if bound using glBindBufferRange + if (shaderStorageBuffer.getSize() > 0) + { + viewSize = shaderStorageBuffer.getSize(); + } + // We use the buffer size for glBindBufferBase + else + { + viewSize = bufferStorage->getSize(); + } + ANGLE_TRY(bufferStorage->getRawUAVRange(context, shaderStorageBuffer.getOffset(), viewSize, + &uavPtr)); + + setUnorderedAccessViewInternal(registerIndex, uavPtr, uavList); + } + + return angle::Result::Continue; +} + +angle::Result StateManager11::syncUniformBuffers(const gl::Context *context) +{ + mProgramD3D->updateUniformBufferCache(context->getCaps()); + + if (mProgramD3D->hasShaderStage(gl::ShaderType::Compute)) + { + ANGLE_TRY(syncUniformBuffersForShader(context, gl::ShaderType::Compute)); + } + else + { + ANGLE_TRY(syncUniformBuffersForShader(context, gl::ShaderType::Vertex)); + ANGLE_TRY(syncUniformBuffersForShader(context, gl::ShaderType::Fragment)); + if (mProgramD3D->hasShaderStage(gl::ShaderType::Geometry)) + { + ANGLE_TRY(syncUniformBuffersForShader(context, gl::ShaderType::Geometry)); + } + } + + return angle::Result::Continue; +} + +angle::Result StateManager11::getUAVsForAtomicCounterBuffers(const gl::Context *context, + gl::ShaderType shaderType, + UAVList *uavList) +{ + const gl::State &glState = context->getState(); + const gl::Program *program = glState.getProgram(); + for (const auto &atomicCounterBuffer : program->getState().getAtomicCounterBuffers()) + { + GLuint binding = atomicCounterBuffer.binding; + const auto &buffer = glState.getIndexedAtomicCounterBuffer(binding); + const unsigned int registerIndex = + mProgramD3D->getAtomicCounterBufferRegisterIndex(binding, shaderType); + ASSERT(registerIndex != GL_INVALID_INDEX); + if (buffer.get() == nullptr) + { + // The atomic counter is used in shader. However, there is no buffer binding to it. We + // should clear the corresponding UAV in case the previous view type is a texture not a + // buffer. Otherwise, below error will be reported. The Unordered Access View dimension + // declared in the shader code (BUFFER) does not match the view type bound to slot 0 + // of the Compute Shader unit (TEXTURE2D). + setUnorderedAccessViewInternal(registerIndex, nullptr, + uavList); + continue; + } + + Buffer11 *bufferStorage = GetImplAs(buffer.get()); + // TODO(enrico.galli@intel.com): Check to make sure that we aren't binding the same buffer + // multiple times, as this is unsupported by D3D11. http://anglebug.com/3141 + + // Bindings only have a valid size if bound using glBindBufferRange. Therefore, we use the + // buffer size for glBindBufferBase + GLsizeiptr viewSize = (buffer.getSize() > 0) ? buffer.getSize() : bufferStorage->getSize(); + d3d11::UnorderedAccessView *uavPtr = nullptr; + ANGLE_TRY(bufferStorage->getRawUAVRange(context, buffer.getOffset(), viewSize, &uavPtr)); + + setUnorderedAccessViewInternal(registerIndex, uavPtr, uavList); + } + + return angle::Result::Continue; +} + +angle::Result StateManager11::getUAVsForShader(const gl::Context *context, + gl::ShaderType shaderType, + UAVList *uavList) +{ + ANGLE_TRY(getUAVsForShaderStorageBuffers(context, shaderType, uavList)); + ANGLE_TRY(getUAVsForRWImages(context, shaderType, uavList)); + ANGLE_TRY(getUAVsForAtomicCounterBuffers(context, shaderType, uavList)); + + return angle::Result::Continue; +} + +angle::Result StateManager11::syncUAVsForGraphics(const gl::Context *context) +{ + UAVList uavList(mRenderer->getNativeCaps().maxImageUnits); + + ANGLE_TRY(getUAVsForShader(context, gl::ShaderType::Fragment, &uavList)); + ANGLE_TRY(getUAVsForShader(context, gl::ShaderType::Vertex, &uavList)); + + if (uavList.highestUsed >= 0) + { + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + UINT baseUAVRegister = static_cast(mProgramD3D->getPixelShaderKey().size()); + deviceContext->OMSetRenderTargetsAndUnorderedAccessViews( + D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL, nullptr, nullptr, baseUAVRegister, + uavList.highestUsed + 1, uavList.data.data(), nullptr); + } + + return angle::Result::Continue; +} + +angle::Result StateManager11::syncUAVsForCompute(const gl::Context *context) +{ + UAVList uavList(mRenderer->getNativeCaps().maxImageUnits); + + ANGLE_TRY(getUAVsForShader(context, gl::ShaderType::Compute, &uavList)); + + if (uavList.highestUsed >= 0) + { + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + deviceContext->CSSetUnorderedAccessViews(0, uavList.highestUsed + 1, uavList.data.data(), + nullptr); + } + + return angle::Result::Continue; +} + +angle::Result StateManager11::syncTransformFeedbackBuffers(const gl::Context *context) +{ + const auto &glState = context->getState(); + + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + // If transform feedback is not active, unbind all buffers + if (!glState.isTransformFeedbackActiveUnpaused()) + { + if (mAppliedTFSerial != mEmptySerial) + { + deviceContext->SOSetTargets(0, nullptr, nullptr); + mAppliedTFSerial = mEmptySerial; + } + return angle::Result::Continue; + } + + gl::TransformFeedback *transformFeedback = glState.getCurrentTransformFeedback(); + TransformFeedback11 *tf11 = GetImplAs(transformFeedback); + if (mAppliedTFSerial == tf11->getSerial() && !tf11->isDirty()) + { + return angle::Result::Continue; + } + + const std::vector *soBuffers = nullptr; + ANGLE_TRY(tf11->getSOBuffers(context, &soBuffers)); + const std::vector &soOffsets = tf11->getSOBufferOffsets(); + + deviceContext->SOSetTargets(tf11->getNumSOBuffers(), soBuffers->data(), soOffsets.data()); + + mAppliedTFSerial = tf11->getSerial(); + tf11->onApply(); + + return angle::Result::Continue; +} + +void StateManager11::syncPrimitiveTopology(const gl::State &glState, + gl::PrimitiveMode currentDrawMode) +{ + D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; + // Don't cull everything by default, this also resets if we were previously culling + mCullEverything = false; + + switch (currentDrawMode) + { + case gl::PrimitiveMode::Points: + { + bool usesPointSize = mProgramD3D->usesPointSize(); + + // ProgramBinary assumes non-point rendering if gl_PointSize isn't written, + // which affects varying interpolation. Since the value of gl_PointSize is + // undefined when not written, just skip drawing to avoid unexpected results. + if (!usesPointSize && !glState.isTransformFeedbackActiveUnpaused()) + { + // Notify developers of risking undefined behavior. + WARN() << "Point rendering without writing to gl_PointSize."; + mCullEverything = true; + return; + } + + // If instanced pointsprites are enabled and the shader uses gl_PointSize, the topology + // must be D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST. + if (usesPointSize && mRenderer->getFeatures().useInstancedPointSpriteEmulation.enabled) + { + primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + } + else + { + primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; + } + break; + } + case gl::PrimitiveMode::Lines: + primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINELIST; + break; + case gl::PrimitiveMode::LineLoop: + primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; + break; + case gl::PrimitiveMode::LineStrip: + primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; + break; + case gl::PrimitiveMode::Triangles: + primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + mCullEverything = CullsEverything(glState); + break; + case gl::PrimitiveMode::TriangleStrip: + primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; + mCullEverything = CullsEverything(glState); + break; + // emulate fans via rewriting index buffer + case gl::PrimitiveMode::TriangleFan: + primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + mCullEverything = CullsEverything(glState); + break; + default: + UNREACHABLE(); + break; + } + + setPrimitiveTopologyInternal(primitiveTopology); +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StateManager11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StateManager11.h new file mode 100644 index 0000000000..d8438a48dc --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StateManager11.h @@ -0,0 +1,692 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// StateManager11.h: Defines a class for caching D3D11 state + +#ifndef LIBANGLE_RENDERER_D3D11_STATEMANAGER11_H_ +#define LIBANGLE_RENDERER_D3D11_STATEMANAGER11_H_ + +#include + +#include "libANGLE/State.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/renderer/d3d/IndexDataManager.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" +#include "libANGLE/renderer/d3d/d3d11/InputLayoutCache.h" +#include "libANGLE/renderer/d3d/d3d11/Query11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" + +namespace rx +{ +class Buffer11; +class DisplayD3D; +class Framebuffer11; +struct RenderTargetDesc; +struct Renderer11DeviceCaps; +class VertexArray11; + +class ShaderConstants11 : angle::NonCopyable +{ + public: + ShaderConstants11(); + ~ShaderConstants11(); + + void init(const gl::Caps &caps); + size_t getRequiredBufferSize(gl::ShaderType shaderType) const; + void markDirty(); + + void setComputeWorkGroups(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ); + void setMultiviewWriteToViewportIndex(GLfloat index); + void onViewportChange(const gl::Rectangle &glViewport, + const D3D11_VIEWPORT &dxViewport, + const gl::Offset &glFragCoordOffset, + bool is9_3, + bool presentPathFast); + bool onFirstVertexChange(GLint firstVertex); + void onImageLayerChange(gl::ShaderType shaderType, unsigned int imageIndex, int layer); + void onSamplerChange(gl::ShaderType shaderType, + unsigned int samplerIndex, + const gl::Texture &texture, + const gl::SamplerState &samplerState); + bool onImageChange(gl::ShaderType shaderType, + unsigned int imageIndex, + const gl::ImageUnit &imageUnit); + void onClipControlChange(bool lowerLeft, bool zeroToOne); + + angle::Result updateBuffer(const gl::Context *context, + Renderer11 *renderer, + gl::ShaderType shaderType, + const ProgramD3D &programD3D, + const d3d11::Buffer &driverConstantBuffer); + + private: + struct Vertex + { + Vertex() + : depthRange{.0f}, + viewAdjust{.0f}, + viewCoords{.0f}, + viewScale{.0f}, + multiviewWriteToViewportIndex{.0f}, + clipControlOrigin{-1.0f}, + clipControlZeroToOne{.0f}, + firstVertex{0}, + padding{.0f, .0f} + {} + + float depthRange[4]; + float viewAdjust[4]; + float viewCoords[4]; + float viewScale[2]; + // multiviewWriteToViewportIndex is used to select either the side-by-side or layered + // code-path in the GS. It's value, if set, is either 0.0f or 1.0f. The value is updated + // whenever a multi-view draw framebuffer is made active. + float multiviewWriteToViewportIndex; + + // EXT_clip_control + // Multiplied with Y coordinate: -1.0 for GL_LOWER_LEFT_EXT, 1.0f for GL_UPPER_LEFT_EXT + float clipControlOrigin; + // 0.0 for GL_NEGATIVE_ONE_TO_ONE_EXT, 1.0 for GL_ZERO_TO_ONE_EXT + float clipControlZeroToOne; + + uint32_t firstVertex; + + // Added here to manually pad the struct to 16 byte boundary + float padding[2]; + }; + static_assert(sizeof(Vertex) % 16u == 0, + "D3D11 constant buffers must be multiples of 16 bytes"); + + struct Pixel + { + Pixel() + : depthRange{.0f}, + viewCoords{.0f}, + depthFront{.0f}, + fragCoordOffset{.0f}, + viewScale{.0f}, + multiviewWriteToViewportIndex{.0f}, + padding{.0f} + {} + + float depthRange[4]; + float viewCoords[4]; + float depthFront[4]; + float fragCoordOffset[2]; + float viewScale[2]; + // multiviewWriteToViewportIndex is used to select either the side-by-side or layered + // code-path in the GS. It's value, if set, is either 0.0f or 1.0f. The value is updated + // whenever a multi-view draw framebuffer is made active. + float multiviewWriteToViewportIndex; + + // Added here to manually pad the struct. + float padding[3]; + }; + static_assert(sizeof(Pixel) % 16u == 0, "D3D11 constant buffers must be multiples of 16 bytes"); + + struct Compute + { + Compute() : numWorkGroups{0u}, padding(0u) {} + unsigned int numWorkGroups[3]; + unsigned int padding; // This just pads the struct to 16 bytes + }; + + struct SamplerMetadata + { + SamplerMetadata() + : baseLevel(0), internalFormatBits(0), wrapModes(0), padding(0), intBorderColor{0} + {} + + int baseLevel; + int internalFormatBits; + int wrapModes; + int padding; // This just pads the struct to 32 bytes + int intBorderColor[4]; + }; + + static_assert(sizeof(SamplerMetadata) == 32u, + "Sampler metadata struct must be two 4-vec --> 32 bytes."); + + struct ImageMetadata + { + ImageMetadata() : layer(0), level(0), padding{0} {} + + int layer; + unsigned int level; + int padding[2]; // This just pads the struct to 16 bytes + }; + static_assert(sizeof(ImageMetadata) == 16u, + "Image metadata struct must be one 4-vec --> 16 bytes."); + + static size_t GetShaderConstantsStructSize(gl::ShaderType shaderType); + + // Return true if dirty. + bool updateSamplerMetadata(SamplerMetadata *data, + const gl::Texture &texture, + const gl::SamplerState &samplerState); + + // Return true if dirty. + bool updateImageMetadata(ImageMetadata *data, const gl::ImageUnit &imageUnit); + + Vertex mVertex; + Pixel mPixel; + Compute mCompute; + gl::ShaderBitSet mShaderConstantsDirty; + + gl::ShaderMap> mShaderSamplerMetadata; + gl::ShaderMap mNumActiveShaderSamplers; + gl::ShaderMap> mShaderReadonlyImageMetadata; + gl::ShaderMap mNumActiveShaderReadonlyImages; + gl::ShaderMap> mShaderImageMetadata; + gl::ShaderMap mNumActiveShaderImages; +}; + +class StateManager11 final : angle::NonCopyable +{ + public: + StateManager11(Renderer11 *renderer); + ~StateManager11(); + + void deinitialize(); + + void syncState(const gl::Context *context, + const gl::State::DirtyBits &dirtyBits, + gl::Command command); + + angle::Result updateStateForCompute(const gl::Context *context, + GLuint numGroupsX, + GLuint numGroupsY, + GLuint numGroupsZ); + + void updateStencilSizeIfChanged(bool depthStencilInitialized, unsigned int stencilSize); + + // These invalidations methods are called externally. + + // Called from TextureStorage11. + void invalidateBoundViews(); + + // Called from VertexArray11::updateVertexAttribStorage. + void invalidateCurrentValueAttrib(size_t attribIndex); + + // Checks are done on a framebuffer state change to trigger other state changes. + // The Context is allowed to be nullptr for these methods, when called in EGL init code. + void invalidateRenderTarget(); + + // Called by instanced point sprite emulation. + void invalidateVertexBuffer(); + + // Called by Framebuffer11::syncState for the default sized viewport. + void invalidateViewport(const gl::Context *context); + + // Called by TextureStorage11::markLevelDirty. + void invalidateSwizzles(); + + // Called by the Framebuffer11 and VertexArray11. + void invalidateShaders(); + + // Called by the Program on Uniform Buffer change. Also called internally. + void invalidateProgramUniformBuffers(); + + // Called by TransformFeedback11. + void invalidateTransformFeedback(); + + // Called by VertexArray11. + void invalidateInputLayout(); + + // Called by VertexArray11 element array buffer sync. + void invalidateIndexBuffer(); + + // Called by TextureStorage11. Also called internally. + void invalidateTexturesAndSamplers(); + + void setRenderTarget(ID3D11RenderTargetView *rtv, ID3D11DepthStencilView *dsv); + void setRenderTargets(ID3D11RenderTargetView **rtvs, UINT numRtvs, ID3D11DepthStencilView *dsv); + + void onBeginQuery(Query11 *query); + void onDeleteQueryObject(Query11 *query); + angle::Result onMakeCurrent(const gl::Context *context); + + void setInputLayout(const d3d11::InputLayout *inputLayout); + + void setSingleVertexBuffer(const d3d11::Buffer *buffer, UINT stride, UINT offset); + + angle::Result updateState(const gl::Context *context, + gl::PrimitiveMode mode, + GLint firstVertex, + GLsizei vertexOrIndexCount, + gl::DrawElementsType indexTypeOrInvalid, + const void *indices, + GLsizei instanceCount, + GLint baseVertex, + GLuint baseInstance, + bool promoteDynamic); + + void setShaderResourceShared(gl::ShaderType shaderType, + UINT resourceSlot, + const d3d11::SharedSRV *srv); + void setShaderResource(gl::ShaderType shaderType, + UINT resourceSlot, + const d3d11::ShaderResourceView *srv); + void setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY primitiveTopology); + + void setDrawShaders(const d3d11::VertexShader *vertexShader, + const d3d11::GeometryShader *geometryShader, + const d3d11::PixelShader *pixelShader); + void setVertexShader(const d3d11::VertexShader *shader); + void setGeometryShader(const d3d11::GeometryShader *shader); + void setPixelShader(const d3d11::PixelShader *shader); + void setComputeShader(const d3d11::ComputeShader *shader); + void setVertexConstantBuffer(unsigned int slot, const d3d11::Buffer *buffer); + void setPixelConstantBuffer(unsigned int slot, const d3d11::Buffer *buffer); + void setDepthStencilState(const d3d11::DepthStencilState *depthStencilState, UINT stencilRef); + void setSimpleBlendState(const d3d11::BlendState *blendState); + void setRasterizerState(const d3d11::RasterizerState *rasterizerState); + void setSimpleViewport(const gl::Extents &viewportExtents); + void setSimpleViewport(int width, int height); + void setSimplePixelTextureAndSampler(const d3d11::SharedSRV &srv, + const d3d11::SamplerState &samplerState); + void setSimpleScissorRect(const gl::Rectangle &glRect); + void setScissorRectD3D(const D3D11_RECT &d3dRect); + + void setIndexBuffer(ID3D11Buffer *buffer, DXGI_FORMAT indexFormat, unsigned int offset); + + angle::Result updateVertexOffsetsForPointSpritesEmulation(const gl::Context *context, + GLint startVertex, + GLsizei emulatedInstanceId); + + // TODO(jmadill): Should be private. + angle::Result applyComputeUniforms(const gl::Context *context, ProgramD3D *programD3D); + + // Only used in testing. + InputLayoutCache *getInputLayoutCache() { return &mInputLayoutCache; } + + bool getCullEverything() const { return mCullEverything; } + VertexDataManager *getVertexDataManager() { return &mVertexDataManager; } + + ProgramD3D *getProgramD3D() const { return mProgramD3D; } + + private: + angle::Result ensureInitialized(const gl::Context *context); + + template + void setShaderResourceInternal(gl::ShaderType shaderType, + UINT resourceSlot, + const SRVType *srv); + + struct UAVList + { + UAVList(size_t size) : data(size) {} + std::vector data; + int highestUsed = -1; + }; + + template + void setUnorderedAccessViewInternal(UINT resourceSlot, const UAVType *uav, UAVList *uavList); + + void unsetConflictingView(gl::PipelineType pipeline, ID3D11View *view, bool isRenderTarget); + void unsetConflictingSRVs(gl::PipelineType pipeline, + gl::ShaderType shaderType, + uintptr_t resource, + const gl::ImageIndex *index, + bool isRenderTarget); + void unsetConflictingUAVs(gl::PipelineType pipeline, + gl::ShaderType shaderType, + uintptr_t resource, + const gl::ImageIndex *index); + void unsetConflictingRTVs(uintptr_t resource); + + void unsetConflictingAttachmentResources(const gl::FramebufferAttachment &attachment, + ID3D11Resource *resource); + + angle::Result syncBlendState(const gl::Context *context, + const gl::BlendStateExt &blendStateExt, + const gl::ColorF &blendColor, + unsigned int sampleMask, + bool sampleAlphaToCoverage, + bool emulateConstantAlpha); + + angle::Result syncDepthStencilState(const gl::Context *context); + + angle::Result syncRasterizerState(const gl::Context *context, gl::PrimitiveMode mode); + + void syncScissorRectangle(const gl::Context *context); + + void syncViewport(const gl::Context *context); + + void checkPresentPath(const gl::Context *context); + + angle::Result syncFramebuffer(const gl::Context *context); + angle::Result syncProgram(const gl::Context *context, gl::PrimitiveMode drawMode); + angle::Result syncProgramForCompute(const gl::Context *context); + + angle::Result syncTextures(const gl::Context *context); + angle::Result applyTexturesForSRVs(const gl::Context *context, gl::ShaderType shaderType); + angle::Result applyTexturesForUAVs(const gl::Context *context, gl::ShaderType shaderType); + angle::Result syncTexturesForCompute(const gl::Context *context); + + angle::Result setSamplerState(const gl::Context *context, + gl::ShaderType type, + int index, + gl::Texture *texture, + const gl::SamplerState &sampler); + angle::Result setTextureForSampler(const gl::Context *context, + gl::ShaderType type, + int index, + gl::Texture *texture, + const gl::SamplerState &sampler); + angle::Result setImageState(const gl::Context *context, + gl::ShaderType type, + int index, + const gl::ImageUnit &imageUnit); + angle::Result setTextureForImage(const gl::Context *context, + gl::ShaderType type, + int index, + const gl::ImageUnit &imageUnit); + angle::Result getUAVsForRWImages(const gl::Context *context, + gl::ShaderType shaderType, + UAVList *uavList); + angle::Result getUAVForRWImage(const gl::Context *context, + gl::ShaderType type, + int index, + const gl::ImageUnit &imageUnit, + UAVList *uavList); + + void handleMultiviewDrawFramebufferChange(const gl::Context *context); + + angle::Result syncCurrentValueAttribs( + const gl::Context *context, + const std::vector ¤tValues); + + angle::Result generateSwizzle(const gl::Context *context, gl::Texture *texture); + angle::Result generateSwizzlesForShader(const gl::Context *context, gl::ShaderType type); + angle::Result generateSwizzles(const gl::Context *context); + + angle::Result applyDriverUniforms(const gl::Context *context); + angle::Result applyDriverUniformsForShader(const gl::Context *context, + gl::ShaderType shaderType); + angle::Result applyUniforms(const gl::Context *context); + angle::Result applyUniformsForShader(const gl::Context *context, gl::ShaderType shaderType); + + angle::Result getUAVsForShaderStorageBuffers(const gl::Context *context, + gl::ShaderType shaderType, + UAVList *uavList); + + angle::Result syncUniformBuffers(const gl::Context *context); + angle::Result syncUniformBuffersForShader(const gl::Context *context, + gl::ShaderType shaderType); + angle::Result getUAVsForAtomicCounterBuffers(const gl::Context *context, + gl::ShaderType shaderType, + UAVList *uavList); + angle::Result getUAVsForShader(const gl::Context *context, + gl::ShaderType shaderType, + UAVList *uavList); + angle::Result syncUAVsForGraphics(const gl::Context *context); + angle::Result syncUAVsForCompute(const gl::Context *context); + angle::Result syncTransformFeedbackBuffers(const gl::Context *context); + + // These are currently only called internally. + void invalidateDriverUniforms(); + void invalidateProgramUniforms(); + void invalidateConstantBuffer(unsigned int slot); + void invalidateProgramAtomicCounterBuffers(); + void invalidateProgramShaderStorageBuffers(); + void invalidateImageBindings(); + + // Called by the Framebuffer11 directly. + void processFramebufferInvalidation(const gl::Context *context); + + bool syncIndexBuffer(ID3D11Buffer *buffer, DXGI_FORMAT indexFormat, unsigned int offset); + angle::Result syncVertexBuffersAndInputLayout(const gl::Context *context, + gl::PrimitiveMode mode, + GLint firstVertex, + GLsizei vertexOrIndexCount, + gl::DrawElementsType indexTypeOrInvalid, + GLsizei instanceCount); + + bool setInputLayoutInternal(const d3d11::InputLayout *inputLayout); + + angle::Result applyVertexBuffers(const gl::Context *context, + gl::PrimitiveMode mode, + gl::DrawElementsType indexTypeOrInvalid, + GLint firstVertex); + // TODO(jmadill): Migrate to d3d11::Buffer. + bool queueVertexBufferChange(size_t bufferIndex, + ID3D11Buffer *buffer, + UINT stride, + UINT offset); + void applyVertexBufferChanges(); + bool setPrimitiveTopologyInternal(D3D11_PRIMITIVE_TOPOLOGY primitiveTopology); + void syncPrimitiveTopology(const gl::State &glState, gl::PrimitiveMode currentDrawMode); + + // Not handled by an internal dirty bit because it isn't synced on drawArrays calls. + angle::Result applyIndexBuffer(const gl::Context *context, + GLsizei indexCount, + gl::DrawElementsType indexType, + const void *indices); + + enum DirtyBitType + { + DIRTY_BIT_RENDER_TARGET, + DIRTY_BIT_VIEWPORT_STATE, + DIRTY_BIT_SCISSOR_STATE, + DIRTY_BIT_RASTERIZER_STATE, + DIRTY_BIT_BLEND_STATE, + DIRTY_BIT_DEPTH_STENCIL_STATE, + // DIRTY_BIT_SHADERS and DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE should be dealt before + // DIRTY_BIT_PROGRAM_UNIFORM_BUFFERS for update image layers. + DIRTY_BIT_SHADERS, + // DIRTY_BIT_GRAPHICS_SRV_STATE and DIRTY_BIT_COMPUTE_SRV_STATE should be lower + // bits than DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE. + DIRTY_BIT_GRAPHICS_SRV_STATE, + DIRTY_BIT_GRAPHICS_UAV_STATE, + DIRTY_BIT_COMPUTE_SRV_STATE, + DIRTY_BIT_COMPUTE_UAV_STATE, + DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE, + DIRTY_BIT_PROGRAM_UNIFORMS, + DIRTY_BIT_DRIVER_UNIFORMS, + DIRTY_BIT_PROGRAM_UNIFORM_BUFFERS, + DIRTY_BIT_CURRENT_VALUE_ATTRIBS, + DIRTY_BIT_TRANSFORM_FEEDBACK, + DIRTY_BIT_VERTEX_BUFFERS_AND_INPUT_LAYOUT, + DIRTY_BIT_PRIMITIVE_TOPOLOGY, + DIRTY_BIT_INVALID, + DIRTY_BIT_MAX = DIRTY_BIT_INVALID, + }; + + using DirtyBits = angle::BitSet; + + Renderer11 *mRenderer; + + // Internal dirty bits. + DirtyBits mInternalDirtyBits; + DirtyBits mGraphicsDirtyBitsMask; + DirtyBits mComputeDirtyBitsMask; + + bool mCurSampleAlphaToCoverage; + + // Blend State + gl::BlendStateExt mCurBlendStateExt; + gl::ColorF mCurBlendColor; + unsigned int mCurSampleMask; + + // Currently applied depth stencil state + gl::DepthStencilState mCurDepthStencilState; + int mCurStencilRef; + int mCurStencilBackRef; + unsigned int mCurStencilSize; + Optional mCurDisableDepth; + Optional mCurDisableStencil; + + // Currently applied rasterizer state + gl::RasterizerState mCurRasterState; + + // Currently applied scissor rectangle state + bool mCurScissorEnabled; + gl::Rectangle mCurScissorRect; + + // Currently applied viewport state + gl::Rectangle mCurViewport; + float mCurNear; + float mCurFar; + + // Currently applied offset to viewport and scissor + gl::Offset mCurViewportOffset; + gl::Offset mCurScissorOffset; + + // Things needed in viewport state + ShaderConstants11 mShaderConstants; + + // Render target variables + gl::Extents mViewportBounds; + bool mRenderTargetIsDirty; + + // EGL_ANGLE_experimental_present_path variables + bool mCurPresentPathFastEnabled; + int mCurPresentPathFastColorBufferHeight; + + // Queries that are currently active in this state + std::set mCurrentQueries; + + // Currently applied textures + template + struct ViewRecord + { + uintptr_t view; + uintptr_t resource; + DescType desc; + }; + + // A cache of current Views that also tracks the highest 'used' (non-NULL) View. + // We might want to investigate a more robust approach that is also fast when there's + // a large gap between used Views (e.g. if View 0 and 7 are non-NULL, this approach will + // waste time on Views 1-6.) + template + class ViewCache : angle::NonCopyable + { + public: + ViewCache(); + ~ViewCache(); + + void initialize(size_t size) { mCurrentViews.resize(size); } + + size_t size() const { return mCurrentViews.size(); } + size_t highestUsed() const { return mHighestUsedView; } + + const ViewRecord &operator[](size_t index) const { return mCurrentViews[index]; } + void clear(); + void update(size_t resourceIndex, ViewType *view); + + private: + std::vector> mCurrentViews; + size_t mHighestUsedView; + }; + + using SRVCache = ViewCache; + using UAVCache = ViewCache; + using RTVCache = ViewCache; + gl::ShaderMap mCurShaderSRVs; + UAVCache mCurComputeUAVs; + RTVCache mCurRTVs; + + SRVCache *getSRVCache(gl::ShaderType shaderType); + + // A block of NULL pointers, cached so we don't re-allocate every draw call + std::vector mNullSRVs; + std::vector mNullUAVs; + + // Current translations of "Current-Value" data - owned by Context, not VertexArray. + gl::AttributesMask mDirtyCurrentValueAttribs; + std::vector mCurrentValueAttribs; + + // Current applied input layout. + ResourceSerial mCurrentInputLayout; + + // Current applied vertex states. + // TODO(jmadill): Figure out how to use ResourceSerial here. + gl::AttribArray mCurrentVertexBuffers; + gl::AttribArray mCurrentVertexStrides; + gl::AttribArray mCurrentVertexOffsets; + gl::RangeUI mDirtyVertexBufferRange; + + // Currently applied primitive topology + D3D11_PRIMITIVE_TOPOLOGY mCurrentPrimitiveTopology; + gl::PrimitiveMode mLastAppliedDrawMode; + bool mCullEverything; + + // Currently applied shaders + gl::ShaderMap mAppliedShaders; + + // Currently applied sampler states + gl::ShaderMap> mForceSetShaderSamplerStates; + gl::ShaderMap> mCurShaderSamplerStates; + + // Special dirty bit for swizzles. Since they use internal shaders, must be done in a pre-pass. + bool mDirtySwizzles; + + // Currently applied index buffer + ID3D11Buffer *mAppliedIB; + DXGI_FORMAT mAppliedIBFormat; + unsigned int mAppliedIBOffset; + bool mIndexBufferIsDirty; + + // Vertex, index and input layouts + VertexDataManager mVertexDataManager; + IndexDataManager mIndexDataManager; + InputLayoutCache mInputLayoutCache; + std::vector mCurrentAttributes; + Optional mLastFirstVertex; + + // ANGLE_multiview. + bool mIsMultiviewEnabled; + + bool mIndependentBlendStates; + + // Driver Constants. + gl::ShaderMap mShaderDriverConstantBuffers; + + ResourceSerial mCurrentComputeConstantBuffer; + ResourceSerial mCurrentGeometryConstantBuffer; + + d3d11::Buffer mPointSpriteVertexBuffer; + d3d11::Buffer mPointSpriteIndexBuffer; + + template + using VertexConstantBufferArray = + std::array; + + VertexConstantBufferArray mCurrentConstantBufferVS; + VertexConstantBufferArray mCurrentConstantBufferVSOffset; + VertexConstantBufferArray mCurrentConstantBufferVSSize; + + template + using FragmentConstantBufferArray = + std::array; + + FragmentConstantBufferArray mCurrentConstantBufferPS; + FragmentConstantBufferArray mCurrentConstantBufferPSOffset; + FragmentConstantBufferArray mCurrentConstantBufferPSSize; + + template + using ComputeConstantBufferArray = + std::array; + + ComputeConstantBufferArray mCurrentConstantBufferCS; + ComputeConstantBufferArray mCurrentConstantBufferCSOffset; + ComputeConstantBufferArray mCurrentConstantBufferCSSize; + + // Currently applied transform feedback buffers + Serial mAppliedTFSerial; + + Serial mEmptySerial; + + // These objects are cached to avoid having to query the impls. + ProgramD3D *mProgramD3D; + VertexArray11 *mVertexArray11; + Framebuffer11 *mFramebuffer11; +}; + +} // namespace rx +#endif // LIBANGLE_RENDERER_D3D11_STATEMANAGER11_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.cpp new file mode 100644 index 0000000000..e77eba71da --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.cpp @@ -0,0 +1,166 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// StreamProducerD3DTexture.cpp: Implements the stream producer for D3D11 textures + +#include "libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.h" + +#include "common/utilities.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" + +#include + +namespace rx +{ + +namespace +{ + +egl::Error GetGLDescFromTex(ID3D11Texture2D *const tex, + const UINT planeIndex, + egl::Stream::GLTextureDescription *const out) +{ + if (!tex) + return egl::EglBadParameter() << "Texture is null"; + + D3D11_TEXTURE2D_DESC desc; + tex->GetDesc(&desc); + + if (desc.Width < 1 || desc.Height < 1) + return egl::EglBadParameter() << "Width or height < 1"; + + out->width = desc.Width; + out->height = desc.Height; + out->mipLevels = 0; + + std::array planeFormats = {}; + switch (desc.Format) + { + case DXGI_FORMAT_NV12: + planeFormats = {GL_R8, GL_RG8}; + break; + + case DXGI_FORMAT_P010: + case DXGI_FORMAT_P016: + planeFormats = {GL_R16_EXT, GL_RG16_EXT}; + break; + + case DXGI_FORMAT_R8_UNORM: + planeFormats = {GL_R8}; + break; + case DXGI_FORMAT_R8G8_UNORM: + planeFormats[0] = GL_RG8; + break; + case DXGI_FORMAT_R8G8B8A8_UNORM: + planeFormats[0] = GL_RGBA8; + break; + case DXGI_FORMAT_B8G8R8A8_UNORM: + planeFormats[0] = GL_BGRA8_EXT; + break; + + case DXGI_FORMAT_R16_UNORM: + planeFormats[0] = GL_R16_EXT; + break; + case DXGI_FORMAT_R16G16_UNORM: + planeFormats[0] = GL_RG16_EXT; + break; + case DXGI_FORMAT_R16G16B16A16_UNORM: + planeFormats[0] = GL_RGBA16_EXT; + break; + case DXGI_FORMAT_R16G16B16A16_FLOAT: + planeFormats[0] = GL_RGBA16F; + break; + + default: + return egl::EglBadParameter() << "Unsupported format"; + } + + if (planeFormats[1]) // If we have YUV planes, expect 4:2:0. + { + if ((desc.Width % 2) != 0 || (desc.Height % 2) != 0) + return egl::EglBadParameter() << "YUV 4:2:0 textures must have even width and height."; + } + if (planeIndex > 0) + { + out->width /= 2; + out->height /= 2; + } + + out->internalFormat = 0; + if (planeIndex < planeFormats.size()) + { + out->internalFormat = planeFormats[planeIndex]; + } + if (!out->internalFormat) + return egl::EglBadParameter() << "Plane out of range"; + + return egl::NoError(); +} + +} // namespace + +StreamProducerD3DTexture::StreamProducerD3DTexture(Renderer11 *renderer) + : mRenderer(renderer), mTexture(nullptr), mArraySlice(0), mPlaneOffset(0) +{} + +StreamProducerD3DTexture::~StreamProducerD3DTexture() +{ + SafeRelease(mTexture); +} + +egl::Error StreamProducerD3DTexture::validateD3DTexture(const void *pointer, + const egl::AttributeMap &attributes) const +{ + // We must remove the const qualifier because "GetDevice" and "GetDesc" are non-const in D3D11. + ID3D11Texture2D *textureD3D = static_cast(const_cast(pointer)); + + // Check that the texture originated from our device + angle::ComPtr device; + textureD3D->GetDevice(&device); + if (device.Get() != mRenderer->getDevice()) + { + return egl::EglBadParameter() << "Texture not created on ANGLE D3D device"; + } + + const auto planeId = static_cast(attributes.get(EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG, 0)); + egl::Stream::GLTextureDescription unused; + return GetGLDescFromTex(textureD3D, planeId, &unused); +} + +void StreamProducerD3DTexture::postD3DTexture(void *pointer, const egl::AttributeMap &attributes) +{ + ASSERT(pointer != nullptr); + ID3D11Texture2D *textureD3D = static_cast(pointer); + + // Release the previous texture if there is one + SafeRelease(mTexture); + + mTexture = textureD3D; + mTexture->AddRef(); + mPlaneOffset = static_cast(attributes.get(EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG, 0)); + mArraySlice = static_cast(attributes.get(EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE, 0)); +} + +egl::Stream::GLTextureDescription StreamProducerD3DTexture::getGLFrameDescription(int planeIndex) +{ + const auto planeOffsetIndex = static_cast(planeIndex + mPlaneOffset); + egl::Stream::GLTextureDescription ret; + ANGLE_SWALLOW_ERR(GetGLDescFromTex(mTexture, planeOffsetIndex, &ret)); + return ret; +} + +ID3D11Texture2D *StreamProducerD3DTexture::getD3DTexture() +{ + return mTexture; +} + +UINT StreamProducerD3DTexture::getArraySlice() +{ + return mArraySlice; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.h new file mode 100644 index 0000000000..bcb0057fde --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.h @@ -0,0 +1,44 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// StreamProducerD3DTexture.h: Interface for a D3D11 texture stream producer + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_STREAM11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_STREAM11_H_ + +#include "libANGLE/renderer/StreamProducerImpl.h" + +namespace rx +{ +class Renderer11; + +class StreamProducerD3DTexture : public StreamProducerImpl +{ + public: + StreamProducerD3DTexture(Renderer11 *renderer); + ~StreamProducerD3DTexture() override; + + egl::Error validateD3DTexture(const void *pointer, + const egl::AttributeMap &attributes) const override; + void postD3DTexture(void *pointer, const egl::AttributeMap &attributes) override; + egl::Stream::GLTextureDescription getGLFrameDescription(int planeIndex) override; + + // Gets a pointer to the internal D3D texture + ID3D11Texture2D *getD3DTexture(); + + // Gets the slice index for the D3D texture that the frame is in + UINT getArraySlice(); + + private: + Renderer11 *mRenderer; + + ID3D11Texture2D *mTexture; + UINT mArraySlice; + UINT mPlaneOffset; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_STREAM11_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp new file mode 100644 index 0000000000..8470510ea8 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp @@ -0,0 +1,1119 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// SwapChain11.cpp: Implements a back-end specific class for the D3D11 swap chain. + +#include "libANGLE/renderer/d3d/d3d11/SwapChain11.h" + +#include + +#include "libANGLE/features.h" +#include "libANGLE/renderer/d3d/DisplayD3D.h" +#include "libANGLE/renderer/d3d/d3d11/NativeWindow11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" +#include "libANGLE/trace.h" + +// Precompiled shaders +#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 +#else +# define ANGLE_RESOURCE_SHARE_TYPE D3D11_RESOURCE_MISC_SHARED +#endif + +namespace rx +{ + +namespace +{ +// To avoid overflow in QPC to Microseconds calculations, since we multiply +// by kMicrosecondsPerSecond, then the QPC value should not exceed +// (2^63 - 1) / 1E6. If it exceeds that threshold, we divide then multiply. +static constexpr int64_t kQPCOverflowThreshold = 0x8637BD05AF7; +static constexpr int64_t kMicrosecondsPerSecond = 1000000; + +bool NeedsOffscreenTexture(Renderer11 *renderer, NativeWindow11 *nativeWindow, EGLint orientation) +{ + // We don't need an offscreen texture if either orientation = INVERT_Y, + // or present path fast is enabled and we're not rendering onto an offscreen surface. + return orientation != EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE && + !(renderer->presentPathFastEnabled() && nativeWindow->getNativeWindow()); +} +} // anonymous namespace + +SwapChain11::SwapChain11(Renderer11 *renderer, + NativeWindow11 *nativeWindow, + HANDLE shareHandle, + IUnknown *d3dTexture, + GLenum backBufferFormat, + GLenum depthBufferFormat, + EGLint orientation, + EGLint samples) + : SwapChainD3D(shareHandle, d3dTexture, backBufferFormat, depthBufferFormat), + mRenderer(renderer), + mWidth(-1), + mHeight(-1), + mOrientation(orientation), + mAppCreatedShareHandle(mShareHandle != nullptr), + mSwapInterval(0), + mPassThroughResourcesInit(false), + mNativeWindow(nativeWindow), + mFirstSwap(true), + mSwapChain(nullptr), + mSwapChain1(nullptr), + mKeyedMutex(nullptr), + mBackBufferTexture(), + mBackBufferRTView(), + mBackBufferSRView(), + mNeedsOffscreenTexture(NeedsOffscreenTexture(renderer, nativeWindow, orientation)), + mOffscreenTexture(), + mOffscreenRTView(), + mOffscreenSRView(), + mNeedsOffscreenTextureCopy(false), + mOffscreenTextureCopyForSRV(), + mDepthStencilTexture(), + mDepthStencilDSView(), + mDepthStencilSRView(), + mQuadVB(), + mPassThroughSampler(), + mPassThroughIL(), + mPassThroughVS(), + mPassThroughOrResolvePS(), + mPassThroughRS(), + mColorRenderTarget(this, renderer, false), + mDepthStencilRenderTarget(this, renderer, true), + mEGLSamples(samples) +{ + // Check that if present path fast is active then we're using the default orientation + ASSERT(!mRenderer->presentPathFastEnabled() || orientation == 0); + + // Get the performance counter + LARGE_INTEGER counterFreqency = {}; + BOOL success = QueryPerformanceFrequency(&counterFreqency); + ASSERT(success); + + mQPCFrequency = counterFreqency.QuadPart; +} + +SwapChain11::~SwapChain11() +{ + release(); +} + +void SwapChain11::release() +{ + // TODO(jmadill): Should probably signal that the RenderTarget is dirty. + + SafeRelease(mSwapChain1); + SafeRelease(mSwapChain); + SafeRelease(mKeyedMutex); + mBackBufferTexture.reset(); + mBackBufferRTView.reset(); + mBackBufferSRView.reset(); + mOffscreenTexture.reset(); + mOffscreenRTView.reset(); + mOffscreenSRView.reset(); + mDepthStencilTexture.reset(); + mDepthStencilDSView.reset(); + mDepthStencilSRView.reset(); + mQuadVB.reset(); + mPassThroughSampler.reset(); + mPassThroughIL.reset(); + mPassThroughVS.reset(); + mPassThroughOrResolvePS.reset(); + mPassThroughRS.reset(); + + if (!mAppCreatedShareHandle) + { + mShareHandle = nullptr; + } +} + +void SwapChain11::releaseOffscreenColorBuffer() +{ + mOffscreenTexture.reset(); + mOffscreenRTView.reset(); + mOffscreenSRView.reset(); + mNeedsOffscreenTextureCopy = false; + mOffscreenTextureCopyForSRV.reset(); +} + +void SwapChain11::releaseOffscreenDepthBuffer() +{ + mDepthStencilTexture.reset(); + mDepthStencilDSView.reset(); + mDepthStencilSRView.reset(); +} + +EGLint SwapChain11::resetOffscreenBuffers(DisplayD3D *displayD3D, + int backbufferWidth, + int backbufferHeight) +{ + if (mNeedsOffscreenTexture) + { + EGLint result = resetOffscreenColorBuffer(displayD3D, backbufferWidth, backbufferHeight); + if (result != EGL_SUCCESS) + { + return result; + } + } + + EGLint result = resetOffscreenDepthBuffer(displayD3D, backbufferWidth, backbufferHeight); + if (result != EGL_SUCCESS) + { + return result; + } + + mWidth = backbufferWidth; + mHeight = backbufferHeight; + + return EGL_SUCCESS; +} + +EGLint SwapChain11::resetOffscreenColorBuffer(DisplayD3D *displayD3D, + int backbufferWidth, + int backbufferHeight) +{ + ASSERT(mNeedsOffscreenTexture); + + ANGLE_TRACE_EVENT0("gpu.angle", "SwapChain11::resetOffscreenTexture"); + ID3D11Device *device = mRenderer->getDevice(); + + ASSERT(device != nullptr); + + // D3D11 does not allow zero size textures + ASSERT(backbufferWidth >= 1); + ASSERT(backbufferHeight >= 1); + + // Preserve the render target content + TextureHelper11 previousOffscreenTexture(std::move(mOffscreenTexture)); + const int previousWidth = mWidth; + const int previousHeight = mHeight; + + releaseOffscreenColorBuffer(); + + const d3d11::Format &backbufferFormatInfo = + d3d11::Format::Get(mOffscreenRenderTargetFormat, mRenderer->getRenderer11DeviceCaps()); + D3D11_TEXTURE2D_DESC offscreenTextureDesc = {}; + + // If the app passed in a share handle or D3D texture, open the resource + // See EGL_ANGLE_d3d_share_handle_client_buffer and EGL_ANGLE_d3d_texture_client_buffer + if (mAppCreatedShareHandle || mD3DTexture != nullptr) + { + if (mAppCreatedShareHandle) + { + ID3D11Resource *tempResource11; + HRESULT result = device->OpenSharedResource(mShareHandle, __uuidof(ID3D11Resource), + (void **)&tempResource11); + if (FAILED(result) && mRenderer->getDevice1()) + { + result = mRenderer->getDevice1()->OpenSharedResource1( + mShareHandle, __uuidof(ID3D11Resource), (void **)&tempResource11); + } + + if (FAILED(result)) + { + ERR() << "Could not open shared handle. " << gl::FmtHR(result); + release(); + return EGL_BAD_SURFACE; + } + + mOffscreenTexture.set(d3d11::DynamicCastComObject(tempResource11), + backbufferFormatInfo); + SafeRelease(tempResource11); + } + else if (mD3DTexture != nullptr) + { + mOffscreenTexture.set(d3d11::DynamicCastComObject(mD3DTexture), + backbufferFormatInfo); + } + else + { + UNREACHABLE(); + } + ASSERT(mOffscreenTexture.valid()); + mOffscreenTexture.getDesc(&offscreenTextureDesc); + + // Fail if the offscreen texture is not renderable. + if ((offscreenTextureDesc.BindFlags & D3D11_BIND_RENDER_TARGET) == 0) + { + ERR() << "Could not use provided offscreen texture, texture not renderable."; + release(); + return EGL_BAD_SURFACE; + } + } + else + { + const bool useSharedResource = + !mNativeWindow->getNativeWindow() && mRenderer->getShareHandleSupport(); + + offscreenTextureDesc.Width = backbufferWidth; + offscreenTextureDesc.Height = backbufferHeight; + offscreenTextureDesc.Format = backbufferFormatInfo.texFormat; + offscreenTextureDesc.MipLevels = 1; + offscreenTextureDesc.ArraySize = 1; + offscreenTextureDesc.SampleDesc.Count = getD3DSamples(); + offscreenTextureDesc.SampleDesc.Quality = 0; + offscreenTextureDesc.Usage = D3D11_USAGE_DEFAULT; + offscreenTextureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; + offscreenTextureDesc.CPUAccessFlags = 0; + offscreenTextureDesc.MiscFlags = useSharedResource ? ANGLE_RESOURCE_SHARE_TYPE : 0; + + angle::Result result = mRenderer->allocateTexture(displayD3D, offscreenTextureDesc, + backbufferFormatInfo, &mOffscreenTexture); + if (result == angle::Result::Stop) + { + ERR() << "Could not create offscreen texture, " << displayD3D->getStoredErrorString(); + release(); + return EGL_BAD_ALLOC; + } + + mOffscreenTexture.setInternalName("OffscreenBackBufferTexture"); + + // EGL_ANGLE_surface_d3d_texture_2d_share_handle requires that we store a share handle for + // the client + if (useSharedResource) + { + IDXGIResource *offscreenTextureResource = nullptr; + HRESULT hr = mOffscreenTexture.get()->QueryInterface( + __uuidof(IDXGIResource), (void **)&offscreenTextureResource); + + // Fall back to no share handle on failure + if (FAILED(hr)) + { + ERR() << "Could not query offscreen texture resource, " << gl::FmtHR(hr); + } + else + { + hr = offscreenTextureResource->GetSharedHandle(&mShareHandle); + SafeRelease(offscreenTextureResource); + + if (FAILED(hr)) + { + mShareHandle = nullptr; + ERR() << "Could not get offscreen texture shared handle, " << gl::FmtHR(hr); + } + } + } + } + + // This may return null if the original texture was created without a keyed mutex. + mKeyedMutex = d3d11::DynamicCastComObject(mOffscreenTexture.get()); + + D3D11_RENDER_TARGET_VIEW_DESC offscreenRTVDesc; + offscreenRTVDesc.Format = backbufferFormatInfo.rtvFormat; + offscreenRTVDesc.ViewDimension = + (mEGLSamples <= 1) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS; + offscreenRTVDesc.Texture2D.MipSlice = 0; + + angle::Result result = mRenderer->allocateResource(displayD3D, offscreenRTVDesc, + mOffscreenTexture.get(), &mOffscreenRTView); + if (result == angle::Result::Stop) + { + ERR() << "Could not create offscreen back buffer render target, " + << displayD3D->getStoredErrorString(); + release(); + return EGL_BAD_ALLOC; + } + mOffscreenRTView.setInternalName("OffscreenBackBufferRenderTarget"); + + D3D11_SHADER_RESOURCE_VIEW_DESC offscreenSRVDesc; + offscreenSRVDesc.Format = backbufferFormatInfo.srvFormat; + offscreenSRVDesc.ViewDimension = + (mEGLSamples <= 1) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS; + offscreenSRVDesc.Texture2D.MostDetailedMip = 0; + offscreenSRVDesc.Texture2D.MipLevels = static_cast(-1); + + if (offscreenTextureDesc.BindFlags & D3D11_BIND_SHADER_RESOURCE) + { + result = mRenderer->allocateResource(displayD3D, offscreenSRVDesc, mOffscreenTexture.get(), + &mOffscreenSRView); + if (result == angle::Result::Stop) + { + ERR() << "Could not create offscreen back buffer shader resource, " + << displayD3D->getStoredErrorString(); + release(); + return EGL_BAD_ALLOC; + } + mOffscreenSRView.setInternalName("OffscreenBackBufferShaderResource"); + } + else + { + // Special case for external textures that cannot support sampling. Since internally we + // assume our SwapChain is always readable, we make a copy texture that is compatible. + mNeedsOffscreenTextureCopy = true; + } + + if (previousOffscreenTexture.valid()) + { + D3D11_BOX sourceBox = {}; + sourceBox.left = 0; + sourceBox.right = std::min(previousWidth, backbufferWidth); + sourceBox.top = std::max(previousHeight - backbufferHeight, 0); + sourceBox.bottom = previousHeight; + sourceBox.front = 0; + sourceBox.back = 1; + + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + const int yoffset = std::max(backbufferHeight - previousHeight, 0); + deviceContext->CopySubresourceRegion(mOffscreenTexture.get(), 0, 0, yoffset, 0, + previousOffscreenTexture.get(), 0, &sourceBox); + + if (mSwapChain) + { + swapRect(displayD3D, 0, 0, backbufferWidth, backbufferHeight); + } + } + + return EGL_SUCCESS; +} + +EGLint SwapChain11::resetOffscreenDepthBuffer(DisplayD3D *displayD3D, + int backbufferWidth, + int backbufferHeight) +{ + releaseOffscreenDepthBuffer(); + + if (mDepthBufferFormat != GL_NONE) + { + const d3d11::Format &depthBufferFormatInfo = + d3d11::Format::Get(mDepthBufferFormat, mRenderer->getRenderer11DeviceCaps()); + + D3D11_TEXTURE2D_DESC depthStencilTextureDesc; + depthStencilTextureDesc.Width = backbufferWidth; + depthStencilTextureDesc.Height = backbufferHeight; + depthStencilTextureDesc.Format = depthBufferFormatInfo.texFormat; + depthStencilTextureDesc.MipLevels = 1; + depthStencilTextureDesc.ArraySize = 1; + depthStencilTextureDesc.SampleDesc.Count = getD3DSamples(); + depthStencilTextureDesc.Usage = D3D11_USAGE_DEFAULT; + depthStencilTextureDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; + + // If there is a multisampled offscreen color texture, the offscreen depth-stencil texture + // must also have the same quality value. + if (mOffscreenTexture.valid() && getD3DSamples() > 1) + { + D3D11_TEXTURE2D_DESC offscreenTextureDesc = {}; + mOffscreenTexture.getDesc(&offscreenTextureDesc); + depthStencilTextureDesc.SampleDesc.Quality = offscreenTextureDesc.SampleDesc.Quality; + } + else + { + depthStencilTextureDesc.SampleDesc.Quality = 0; + } + + // Only create an SRV if it is supported + bool depthStencilSRV = + depthBufferFormatInfo.srvFormat != DXGI_FORMAT_UNKNOWN && + (mRenderer->getRenderer11DeviceCaps().supportsMultisampledDepthStencilSRVs || + depthStencilTextureDesc.SampleDesc.Count <= 1); + if (depthStencilSRV) + { + depthStencilTextureDesc.BindFlags |= D3D11_BIND_SHADER_RESOURCE; + } + + depthStencilTextureDesc.CPUAccessFlags = 0; + depthStencilTextureDesc.MiscFlags = 0; + + angle::Result result = mRenderer->allocateTexture( + displayD3D, depthStencilTextureDesc, depthBufferFormatInfo, &mDepthStencilTexture); + if (result == angle::Result::Stop) + { + ERR() << "Could not create depthstencil surface for new swap chain, " + << displayD3D->getStoredErrorString(); + release(); + return EGL_BAD_ALLOC; + } + mDepthStencilTexture.setInternalName("OffscreenDepthStencilTexture"); + + D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilDesc; + depthStencilDesc.Format = depthBufferFormatInfo.dsvFormat; + depthStencilDesc.ViewDimension = + (mEGLSamples <= 1) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS; + depthStencilDesc.Flags = 0; + depthStencilDesc.Texture2D.MipSlice = 0; + + result = mRenderer->allocateResource(displayD3D, depthStencilDesc, + mDepthStencilTexture.get(), &mDepthStencilDSView); + ASSERT(result != angle::Result::Stop); + mDepthStencilDSView.setInternalName("OffscreenDSV"); + + if (depthStencilSRV) + { + D3D11_SHADER_RESOURCE_VIEW_DESC depthStencilSRVDesc; + depthStencilSRVDesc.Format = depthBufferFormatInfo.srvFormat; + depthStencilSRVDesc.ViewDimension = (mEGLSamples <= 1) + ? D3D11_SRV_DIMENSION_TEXTURE2D + : D3D11_SRV_DIMENSION_TEXTURE2DMS; + depthStencilSRVDesc.Texture2D.MostDetailedMip = 0; + depthStencilSRVDesc.Texture2D.MipLevels = static_cast(-1); + + result = mRenderer->allocateResource(displayD3D, depthStencilSRVDesc, + mDepthStencilTexture.get(), &mDepthStencilSRView); + ASSERT(result != angle::Result::Stop); + mDepthStencilSRView.setInternalName("OffscreenDepthStencilSRV"); + } + } + + return EGL_SUCCESS; +} + +EGLint SwapChain11::resize(DisplayD3D *displayD3D, EGLint backbufferWidth, EGLint backbufferHeight) +{ + ANGLE_TRACE_EVENT0("gpu.angle", "SwapChain11::resize"); + ID3D11Device *device = mRenderer->getDevice(); + + if (device == nullptr) + { + return EGL_BAD_ACCESS; + } + + // EGL allows creating a surface with 0x0 dimension, however, DXGI does not like 0x0 swapchains + if (backbufferWidth < 1 || backbufferHeight < 1) + { + return EGL_SUCCESS; + } + + // Don't resize unnecessarily + if (mWidth == backbufferWidth && mHeight == backbufferHeight) + { + return EGL_SUCCESS; + } + + // Can only call resize if we have already created our swap buffer and resources + ASSERT(mSwapChain && mBackBufferTexture.valid() && mBackBufferRTView.valid() && + mBackBufferSRView.valid()); + + mBackBufferTexture.reset(); + mBackBufferRTView.reset(); + mBackBufferSRView.reset(); + + // Resize swap chain + DXGI_SWAP_CHAIN_DESC desc; + HRESULT hr = mSwapChain->GetDesc(&desc); + if (FAILED(hr)) + { + ERR() << "Error reading swap chain description, " << gl::FmtHR(hr); + release(); + return EGL_BAD_ALLOC; + } + + hr = mSwapChain->ResizeBuffers(desc.BufferCount, backbufferWidth, backbufferHeight, + getSwapChainNativeFormat(), 0); + + if (FAILED(hr)) + { + ERR() << "Error resizing swap chain buffers, " << gl::FmtHR(hr); + release(); + + if (d3d11::isDeviceLostError(hr)) + { + HRESULT reason = device->GetDeviceRemovedReason(); + ERR() << "Device lost in SwapChain11::resize " << gl::FmtHR(hr) + << ", reason: " << gl::FmtHR(reason); + return EGL_CONTEXT_LOST; + } + else + { + return EGL_BAD_ALLOC; + } + } + + ID3D11Texture2D *backbufferTexture = nullptr; + hr = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), + reinterpret_cast(&backbufferTexture)); + ASSERT(SUCCEEDED(hr)); + if (SUCCEEDED(hr)) + { + const auto &format = + d3d11::Format::Get(mOffscreenRenderTargetFormat, mRenderer->getRenderer11DeviceCaps()); + mBackBufferTexture.set(backbufferTexture, format); + mBackBufferTexture.setInternalName("BackBufferTexture"); + + angle::Result result = mRenderer->allocateResourceNoDesc( + displayD3D, mBackBufferTexture.get(), &mBackBufferRTView); + ASSERT(result != angle::Result::Stop); + mBackBufferRTView.setInternalName("BackBufferRTV"); + + result = mRenderer->allocateResourceNoDesc(displayD3D, mBackBufferTexture.get(), + &mBackBufferSRView); + ASSERT(result != angle::Result::Stop); + mBackBufferSRView.setInternalName("BackBufferSRV"); + } + + mFirstSwap = true; + + return resetOffscreenBuffers(displayD3D, backbufferWidth, backbufferHeight); +} + +DXGI_FORMAT SwapChain11::getSwapChainNativeFormat() const +{ + // Return a render target format for offscreen rendering is supported by IDXGISwapChain. + // MSDN https://msdn.microsoft.com/en-us/library/windows/desktop/bb173064(v=vs.85).aspx + switch (mOffscreenRenderTargetFormat) + { + case GL_RGBA8: + case GL_RGBA4: + case GL_RGB5_A1: + case GL_RGB8: + case GL_RGB565: + return DXGI_FORMAT_R8G8B8A8_UNORM; + + case GL_BGRA8_EXT: + return DXGI_FORMAT_B8G8R8A8_UNORM; + + case GL_RGB10_A2: + return DXGI_FORMAT_R10G10B10A2_UNORM; + + case GL_RGBA16F: + return DXGI_FORMAT_R16G16B16A16_FLOAT; + + default: + UNREACHABLE(); + return DXGI_FORMAT_UNKNOWN; + } +} + +EGLint SwapChain11::reset(DisplayD3D *displayD3D, + EGLint backbufferWidth, + EGLint backbufferHeight, + EGLint swapInterval) +{ + mSwapInterval = static_cast(swapInterval); + if (mSwapInterval > 4) + { + // IDXGISwapChain::Present documentation states that valid sync intervals are in the [0,4] + // range + return EGL_BAD_PARAMETER; + } + + // If the swap chain already exists, just resize + if (mSwapChain != nullptr) + { + return resize(displayD3D, backbufferWidth, backbufferHeight); + } + + ANGLE_TRACE_EVENT0("gpu.angle", "SwapChain11::reset"); + ID3D11Device *device = mRenderer->getDevice(); + + if (device == nullptr) + { + return EGL_BAD_ACCESS; + } + + // Release specific resources to free up memory for the new render target, while the + // old render target still exists for the purpose of preserving its contents. + SafeRelease(mSwapChain1); + SafeRelease(mSwapChain); + mBackBufferTexture.reset(); + mBackBufferRTView.reset(); + + // EGL allows creating a surface with 0x0 dimension, however, DXGI does not like 0x0 swapchains + if (backbufferWidth < 1 || backbufferHeight < 1) + { + releaseOffscreenColorBuffer(); + return EGL_SUCCESS; + } + + if (mNativeWindow->getNativeWindow()) + { + HRESULT hr = mNativeWindow->createSwapChain( + device, mRenderer->getDxgiFactory(), getSwapChainNativeFormat(), backbufferWidth, + backbufferHeight, mNeedsOffscreenTexture ? 1 : getD3DSamples(), &mSwapChain); + + if (FAILED(hr)) + { + ERR() << "Could not create additional swap chains or offscreen surfaces, " + << gl::FmtHR(hr); + release(); + + if (d3d11::isDeviceLostError(hr)) + { + HRESULT reason = device->GetDeviceRemovedReason(); + ERR() << "Device lost in SwapChain11::reset " << gl::FmtHR(hr) + << ", reason: " << gl::FmtHR(reason); + return EGL_CONTEXT_LOST; + } + else + { + return EGL_BAD_ALLOC; + } + } + + if (mRenderer->getRenderer11DeviceCaps().supportsDXGI1_2) + { + mSwapChain1 = d3d11::DynamicCastComObject(mSwapChain); + } + + ID3D11Texture2D *backbufferTex = nullptr; + hr = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), + reinterpret_cast(&backbufferTex)); + ASSERT(SUCCEEDED(hr)); + const auto &format = + d3d11::Format::Get(mOffscreenRenderTargetFormat, mRenderer->getRenderer11DeviceCaps()); + mBackBufferTexture.set(backbufferTex, format); + mBackBufferTexture.setInternalName("BackBufferTexture"); + + angle::Result result = mRenderer->allocateResourceNoDesc( + displayD3D, mBackBufferTexture.get(), &mBackBufferRTView); + ASSERT(result != angle::Result::Stop); + mBackBufferRTView.setInternalName("BackBufferRTV"); + + result = mRenderer->allocateResourceNoDesc(displayD3D, mBackBufferTexture.get(), + &mBackBufferSRView); + ASSERT(result != angle::Result::Stop); + mBackBufferSRView.setInternalName("BackBufferSRV"); + } + + mFirstSwap = true; + + return resetOffscreenBuffers(displayD3D, backbufferWidth, backbufferHeight); +} + +angle::Result SwapChain11::initPassThroughResources(DisplayD3D *displayD3D) +{ + if (mPassThroughResourcesInit) + { + return angle::Result::Continue; + } + + ANGLE_TRACE_EVENT0("gpu.angle", "SwapChain11::initPassThroughResources"); + ID3D11Device *device = mRenderer->getDevice(); + + ASSERT(device != nullptr); + + // Make sure our resources are all not allocated, when we create + ASSERT(!mQuadVB.valid() && !mPassThroughSampler.valid()); + ASSERT(!mPassThroughIL.valid() && !mPassThroughVS.valid() && !mPassThroughOrResolvePS.valid()); + + D3D11_BUFFER_DESC vbDesc; + vbDesc.ByteWidth = sizeof(d3d11::PositionTexCoordVertex) * 4; + vbDesc.Usage = D3D11_USAGE_DYNAMIC; + vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + vbDesc.MiscFlags = 0; + vbDesc.StructureByteStride = 0; + + ANGLE_TRY(mRenderer->allocateResource(displayD3D, vbDesc, &mQuadVB)); + mQuadVB.setInternalName("SwapChainQuadVB"); + + D3D11_SAMPLER_DESC samplerDesc; + samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; + samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; + samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; + samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; + samplerDesc.MipLODBias = 0.0f; + samplerDesc.MaxAnisotropy = 0; + samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; + samplerDesc.BorderColor[0] = 0.0f; + samplerDesc.BorderColor[1] = 0.0f; + samplerDesc.BorderColor[2] = 0.0f; + samplerDesc.BorderColor[3] = 0.0f; + samplerDesc.MinLOD = 0; + samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; + + ANGLE_TRY(mRenderer->allocateResource(displayD3D, samplerDesc, &mPassThroughSampler)); + mPassThroughSampler.setInternalName("SwapChainPassThroughSampler"); + + D3D11_INPUT_ELEMENT_DESC quadLayout[] = { + {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0}, + }; + + InputElementArray quadElements(quadLayout); + ShaderData vertexShaderData(g_VS_Passthrough2D); + + ANGLE_TRY( + mRenderer->allocateResource(displayD3D, quadElements, &vertexShaderData, &mPassThroughIL)); + mPassThroughIL.setInternalName("SwapChainPassThroughIL"); + + ANGLE_TRY(mRenderer->allocateResource(displayD3D, vertexShaderData, &mPassThroughVS)); + mPassThroughVS.setInternalName("SwapChainPassThroughVS"); + + if (mEGLSamples <= 1) + { + ShaderData pixelShaderData(g_PS_PassthroughRGBA2D); + ANGLE_TRY( + mRenderer->allocateResource(displayD3D, pixelShaderData, &mPassThroughOrResolvePS)); + } + else + { + 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)); + } + } + + mPassThroughOrResolvePS.setInternalName("SwapChainPassThroughPS"); + + // Use the default rasterizer state but without culling + D3D11_RASTERIZER_DESC rasterizerDesc; + rasterizerDesc.FillMode = D3D11_FILL_SOLID; + rasterizerDesc.CullMode = D3D11_CULL_NONE; + rasterizerDesc.FrontCounterClockwise = FALSE; + rasterizerDesc.DepthBias = 0; + rasterizerDesc.SlopeScaledDepthBias = 0.0f; + rasterizerDesc.DepthBiasClamp = 0.0f; + rasterizerDesc.DepthClipEnable = TRUE; + rasterizerDesc.ScissorEnable = FALSE; + rasterizerDesc.MultisampleEnable = FALSE; + rasterizerDesc.AntialiasedLineEnable = FALSE; + + ANGLE_TRY(mRenderer->allocateResource(displayD3D, rasterizerDesc, &mPassThroughRS)); + mPassThroughRS.setInternalName("SwapChainPassThroughRasterizerState"); + + mPassThroughResourcesInit = true; + return angle::Result::Continue; +} + +// parameters should be validated/clamped by caller +EGLint SwapChain11::swapRect(DisplayD3D *displayD3D, + EGLint x, + EGLint y, + EGLint width, + EGLint height) +{ + if (mNeedsOffscreenTexture) + { + EGLint result = copyOffscreenToBackbuffer(displayD3D, x, y, width, height); + if (result != EGL_SUCCESS) + { + return result; + } + } + + EGLint result = present(displayD3D, x, y, width, height); + if (result != EGL_SUCCESS) + { + return result; + } + + mRenderer->onSwap(); + + return EGL_SUCCESS; +} + +EGLint SwapChain11::copyOffscreenToBackbuffer(DisplayD3D *displayD3D, + EGLint x, + EGLint y, + EGLint width, + EGLint height) +{ + if (!mSwapChain) + { + return EGL_SUCCESS; + } + + if (initPassThroughResources(displayD3D) == angle::Result::Stop) + { + return EGL_BAD_ALLOC; + } + + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + // Set vertices + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT result = + deviceContext->Map(mQuadVB.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) + { + return EGL_BAD_ACCESS; + } + + d3d11::PositionTexCoordVertex *vertices = + static_cast(mappedResource.pData); + + // Create a quad in homogeneous coordinates + float x1 = (x / float(mWidth)) * 2.0f - 1.0f; + float y1 = (y / float(mHeight)) * 2.0f - 1.0f; + float x2 = ((x + width) / float(mWidth)) * 2.0f - 1.0f; + float y2 = ((y + height) / float(mHeight)) * 2.0f - 1.0f; + + float u1 = x / float(mWidth); + float v1 = y / float(mHeight); + float u2 = (x + width) / float(mWidth); + float v2 = (y + height) / float(mHeight); + + // Invert the quad vertices depending on the surface orientation. + if ((mOrientation & EGL_SURFACE_ORIENTATION_INVERT_X_ANGLE) != 0) + { + std::swap(x1, x2); + } + if ((mOrientation & EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE) != 0) + { + std::swap(y1, y2); + } + + d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, u1, v1); + d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v2); + d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v1); + d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v2); + + deviceContext->Unmap(mQuadVB.get(), 0); + + StateManager11 *stateManager = mRenderer->getStateManager(); + + constexpr UINT stride = sizeof(d3d11::PositionTexCoordVertex); + stateManager->setSingleVertexBuffer(&mQuadVB, stride, 0); + + // Apply state + stateManager->setDepthStencilState(nullptr, 0xFFFFFFFF); + stateManager->setSimpleBlendState(nullptr); + stateManager->setRasterizerState(&mPassThroughRS); + + // Apply shaders + stateManager->setInputLayout(&mPassThroughIL); + stateManager->setPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + stateManager->setDrawShaders(&mPassThroughVS, nullptr, &mPassThroughOrResolvePS); + + // Apply render targets. Use the proxy context in display. + stateManager->setRenderTarget(mBackBufferRTView.get(), nullptr); + + // Set the viewport + stateManager->setSimpleViewport(mWidth, mHeight); + + // Apply textures + stateManager->setSimplePixelTextureAndSampler(mOffscreenSRView, mPassThroughSampler); + + // Draw + deviceContext->Draw(4, 0); + + return EGL_SUCCESS; +} + +EGLint SwapChain11::present(DisplayD3D *displayD3D, EGLint x, EGLint y, EGLint width, EGLint height) +{ + if (!mSwapChain) + { + return EGL_SUCCESS; + } + + UINT swapInterval = mSwapInterval; +#if ANGLE_VSYNC == ANGLE_DISABLED + swapInterval = 0; +#endif + + HRESULT result = S_OK; + + // Use IDXGISwapChain1::Present1 with a dirty rect if DXGI 1.2 is available. + // Dirty rect present is not supported with a multisampled swapchain. + if (mSwapChain1 != nullptr && mEGLSamples <= 1) + { + if (mFirstSwap) + { + // Can't swap with a dirty rect if this swap chain has never swapped before + DXGI_PRESENT_PARAMETERS params = {0, nullptr, nullptr, nullptr}; + result = mSwapChain1->Present1(swapInterval, 0, ¶ms); + } + else + { + RECT rect = {static_cast(x), static_cast(mHeight - y - height), + static_cast(x + width), static_cast(mHeight - y)}; + DXGI_PRESENT_PARAMETERS params = {1, &rect, nullptr, nullptr}; + result = mSwapChain1->Present1(swapInterval, 0, ¶ms); + } + } + else + { + result = mSwapChain->Present(swapInterval, 0); + } + + mFirstSwap = false; + + // Some swapping mechanisms such as DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL unbind the current render + // target. Mark it dirty. Use the proxy context in display since there is none available. + mRenderer->getStateManager()->invalidateRenderTarget(); + + if (result == DXGI_ERROR_DEVICE_REMOVED) + { + ERR() << "Present failed: the D3D11 device was removed, " + << gl::FmtHR(mRenderer->getDevice()->GetDeviceRemovedReason()); + return EGL_CONTEXT_LOST; + } + else if (result == DXGI_ERROR_DEVICE_RESET) + { + ERR() << "Present failed: the D3D11 device was reset from a bad command."; + return EGL_CONTEXT_LOST; + } + else if (FAILED(result)) + { + ERR() << "Present failed with " << gl::FmtHR(result); + } + + mNativeWindow->commitChange(); + + return EGL_SUCCESS; +} + +const TextureHelper11 &SwapChain11::getOffscreenTexture() +{ + return mNeedsOffscreenTexture ? mOffscreenTexture : mBackBufferTexture; +} + +const d3d11::RenderTargetView &SwapChain11::getRenderTarget() +{ + return mNeedsOffscreenTexture ? mOffscreenRTView : mBackBufferRTView; +} + +angle::Result SwapChain11::getRenderTargetShaderResource(d3d::Context *context, + const d3d11::SharedSRV **outSRV) +{ + *outSRV = nullptr; + + if (!mNeedsOffscreenTexture) + { + ASSERT(mBackBufferSRView.valid()); + *outSRV = &mBackBufferSRView; + return angle::Result::Continue; + } + + if (!mNeedsOffscreenTextureCopy) + { + ASSERT(mOffscreenSRView.valid()); + *outSRV = &mOffscreenSRView; + return angle::Result::Continue; + } + + if (!mOffscreenTextureCopyForSRV.valid()) + { + const d3d11::Format &backbufferFormatInfo = + d3d11::Format::Get(mOffscreenRenderTargetFormat, mRenderer->getRenderer11DeviceCaps()); + + D3D11_TEXTURE2D_DESC offscreenCopyDesc; + mOffscreenTexture.getDesc(&offscreenCopyDesc); + + offscreenCopyDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + offscreenCopyDesc.MiscFlags = 0; + offscreenCopyDesc.CPUAccessFlags = 0; + TextureHelper11 offscreenTextureCopyForSRV; + ANGLE_TRY(mRenderer->allocateTexture(context, offscreenCopyDesc, backbufferFormatInfo, + &offscreenTextureCopyForSRV)); + offscreenTextureCopyForSRV.setInternalName("OffscreenBackBufferCopyForSRV"); + + D3D11_SHADER_RESOURCE_VIEW_DESC offscreenSRVDesc; + offscreenSRVDesc.Format = backbufferFormatInfo.srvFormat; + offscreenSRVDesc.ViewDimension = + (mEGLSamples <= 1) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS; + offscreenSRVDesc.Texture2D.MostDetailedMip = 0; + offscreenSRVDesc.Texture2D.MipLevels = static_cast(-1); + + d3d11::SharedSRV offscreenSRView; + ANGLE_TRY(mRenderer->allocateResource(context, offscreenSRVDesc, + offscreenTextureCopyForSRV.get(), &offscreenSRView)); + offscreenSRView.setInternalName("OffscreenBackBufferSRV"); + + // Commit created objects in one step so we don't end up with half baked member variables. + mOffscreenTextureCopyForSRV = std::move(offscreenTextureCopyForSRV); + mOffscreenSRView = std::move(offscreenSRView); + } + + // Need to copy the offscreen texture into the shader-readable copy, since it's external and + // we don't know if the copy is up-to-date. This works around the problem we have when the app + // passes in a texture that isn't shader-readable. + mRenderer->getDeviceContext()->CopyResource(mOffscreenTextureCopyForSRV.get(), + mOffscreenTexture.get()); + *outSRV = &mOffscreenSRView; + return angle::Result::Continue; +} + +const d3d11::DepthStencilView &SwapChain11::getDepthStencil() +{ + return mDepthStencilDSView; +} + +const d3d11::SharedSRV &SwapChain11::getDepthStencilShaderResource() +{ + return mDepthStencilSRView; +} + +const TextureHelper11 &SwapChain11::getDepthStencilTexture() +{ + return mDepthStencilTexture; +} + +void *SwapChain11::getKeyedMutex() +{ + return mKeyedMutex; +} + +void SwapChain11::recreate() +{ + // possibly should use this method instead of reset +} + +RenderTargetD3D *SwapChain11::getColorRenderTarget() +{ + return &mColorRenderTarget; +} + +RenderTargetD3D *SwapChain11::getDepthStencilRenderTarget() +{ + return &mDepthStencilRenderTarget; +} + +egl::Error SwapChain11::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) +{ + if (!mSwapChain) + { + return egl::EglNotInitialized() << "Swap chain uninitialized"; + } + + DXGI_FRAME_STATISTICS stats = {}; + HRESULT result = mSwapChain->GetFrameStatistics(&stats); + + if (FAILED(result)) + { + return egl::EglBadAlloc() << "Failed to get frame statistics, " << gl::FmtHR(result); + } + + // Conversion from DXGI_FRAME_STATISTICS to the output values: + // stats.SyncRefreshCount -> msc + // stats.PresentCount -> sbc + // stats.SyncQPCTime -> ust with conversion to microseconds via QueryPerformanceFrequency + *msc = stats.SyncRefreshCount; + *sbc = stats.PresentCount; + + LONGLONG syncQPCValue = stats.SyncQPCTime.QuadPart; + // If the QPC Value is below the overflow threshold, we proceed with + // simple multiply and divide. + if (syncQPCValue < kQPCOverflowThreshold) + { + *ust = syncQPCValue * kMicrosecondsPerSecond / mQPCFrequency; + } + else + { + // Otherwise, calculate microseconds in a round about manner to avoid + // overflow and precision issues. + int64_t wholeSeconds = syncQPCValue / mQPCFrequency; + int64_t leftoverTicks = syncQPCValue - (wholeSeconds * mQPCFrequency); + *ust = wholeSeconds * kMicrosecondsPerSecond + + leftoverTicks * kMicrosecondsPerSecond / mQPCFrequency; + } + + return egl::NoError(); +} + +UINT SwapChain11::getD3DSamples() const +{ + return (mEGLSamples == 0) ? 1 : mEGLSamples; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h new file mode 100644 index 0000000000..2d7f0a00ee --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h @@ -0,0 +1,134 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// SwapChain11.h: Defines a back-end specific class for the D3D11 swap chain. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_SWAPCHAIN11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_SWAPCHAIN11_H_ + +#include "common/angleutils.h" +#include "libANGLE/renderer/d3d/SwapChainD3D.h" +#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" + +namespace rx +{ +class Renderer11; +class NativeWindow11; + +class SwapChain11 final : public SwapChainD3D +{ + public: + SwapChain11(Renderer11 *renderer, + NativeWindow11 *nativeWindow, + HANDLE shareHandle, + IUnknown *d3dTexture, + GLenum backBufferFormat, + GLenum depthBufferFormat, + EGLint orientation, + EGLint samples); + ~SwapChain11() override; + + EGLint resize(DisplayD3D *displayD3D, EGLint backbufferWidth, EGLint backbufferHeight) override; + EGLint reset(DisplayD3D *displayD3D, + EGLint backbufferWidth, + EGLint backbufferHeight, + EGLint swapInterval) override; + EGLint swapRect(DisplayD3D *displayD3D, + EGLint x, + EGLint y, + EGLint width, + EGLint height) override; + void recreate() override; + + RenderTargetD3D *getColorRenderTarget() override; + RenderTargetD3D *getDepthStencilRenderTarget() override; + + const TextureHelper11 &getOffscreenTexture(); + const d3d11::RenderTargetView &getRenderTarget(); + angle::Result getRenderTargetShaderResource(d3d::Context *context, + const d3d11::SharedSRV **outSRV); + + const TextureHelper11 &getDepthStencilTexture(); + const d3d11::DepthStencilView &getDepthStencil(); + const d3d11::SharedSRV &getDepthStencilShaderResource(); + + EGLint getWidth() const { return mWidth; } + EGLint getHeight() const { return mHeight; } + void *getKeyedMutex() override; + EGLint getSamples() const { return mEGLSamples; } + + egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) override; + + private: + void release(); + angle::Result initPassThroughResources(DisplayD3D *displayD3D); + + void releaseOffscreenColorBuffer(); + void releaseOffscreenDepthBuffer(); + EGLint resetOffscreenBuffers(DisplayD3D *displayD3D, int backbufferWidth, int backbufferHeight); + EGLint resetOffscreenColorBuffer(DisplayD3D *displayD3D, + int backbufferWidth, + int backbufferHeight); + EGLint resetOffscreenDepthBuffer(DisplayD3D *displayD3D, + int backbufferWidth, + int backbufferHeight); + + DXGI_FORMAT getSwapChainNativeFormat() const; + + EGLint copyOffscreenToBackbuffer(DisplayD3D *displayD3D, + EGLint x, + EGLint y, + EGLint width, + EGLint height); + EGLint present(DisplayD3D *displayD3D, EGLint x, EGLint y, EGLint width, EGLint height); + UINT getD3DSamples() const; + + Renderer11 *mRenderer; + EGLint mWidth; + EGLint mHeight; + const EGLint mOrientation; + bool mAppCreatedShareHandle; + unsigned int mSwapInterval; + bool mPassThroughResourcesInit; + + NativeWindow11 *mNativeWindow; // Handler for the Window that the surface is created for. + + bool mFirstSwap; + IDXGISwapChain *mSwapChain; + IDXGISwapChain1 *mSwapChain1; + IDXGIKeyedMutex *mKeyedMutex; + + TextureHelper11 mBackBufferTexture; + d3d11::RenderTargetView mBackBufferRTView; + d3d11::SharedSRV mBackBufferSRView; + + const bool mNeedsOffscreenTexture; + TextureHelper11 mOffscreenTexture; + d3d11::RenderTargetView mOffscreenRTView; + d3d11::SharedSRV mOffscreenSRView; + bool mNeedsOffscreenTextureCopy; + TextureHelper11 mOffscreenTextureCopyForSRV; + + TextureHelper11 mDepthStencilTexture; + d3d11::DepthStencilView mDepthStencilDSView; + d3d11::SharedSRV mDepthStencilSRView; + + d3d11::Buffer mQuadVB; + d3d11::SamplerState mPassThroughSampler; + d3d11::InputLayout mPassThroughIL; + d3d11::VertexShader mPassThroughVS; + d3d11::PixelShader mPassThroughOrResolvePS; + d3d11::RasterizerState mPassThroughRS; + + SurfaceRenderTarget11 mColorRenderTarget; + SurfaceRenderTarget11 mDepthStencilRenderTarget; + + EGLint mEGLSamples; + LONGLONG mQPCFrequency; +}; + +} // namespace rx +#endif // LIBANGLE_RENDERER_D3D_D3D11_SWAPCHAIN11_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp new file mode 100644 index 0000000000..f1277462a9 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp @@ -0,0 +1,4352 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// TextureStorage11.cpp: Implements the abstract rx::TextureStorage11 class and its concrete derived +// classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 +// texture. + +#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h" + +#include + +#include "common/MemoryBuffer.h" +#include "common/utilities.h" +#include "libANGLE/Context.h" +#include "libANGLE/ImageIndex.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/EGLImageD3D.h" +#include "libANGLE/renderer/d3d/TextureD3D.h" +#include "libANGLE/renderer/d3d/d3d11/Blit11.h" +#include "libANGLE/renderer/d3d/d3d11/Buffer11.h" +#include "libANGLE/renderer/d3d/d3d11/Context11.h" +#include "libANGLE/renderer/d3d/d3d11/Image11.h" +#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.h" +#include "libANGLE/renderer/d3d/d3d11/SwapChain11.h" +#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" + +namespace rx +{ +TextureStorage11::SamplerKey::SamplerKey() + : baseLevel(0), mipLevels(0), swizzle(false), dropStencil(false) +{} + +TextureStorage11::SamplerKey::SamplerKey(int baseLevel, + int mipLevels, + bool swizzle, + bool dropStencil) + : baseLevel(baseLevel), mipLevels(mipLevels), swizzle(swizzle), dropStencil(dropStencil) +{} + +bool TextureStorage11::SamplerKey::operator<(const SamplerKey &rhs) const +{ + return std::tie(baseLevel, mipLevels, swizzle, dropStencil) < + std::tie(rhs.baseLevel, rhs.mipLevels, rhs.swizzle, rhs.dropStencil); +} + +TextureStorage11::ImageKey::ImageKey() + : level(0), layered(false), layer(0), access(GL_READ_ONLY), format(GL_R32UI) +{} + +TextureStorage11::ImageKey::ImageKey(int level, + bool layered, + int layer, + GLenum access, + GLenum format) + : level(level), layered(layered), layer(layer), access(access), format(format) +{} + +bool TextureStorage11::ImageKey::operator<(const ImageKey &rhs) const +{ + return std::tie(level, layered, layer, access, format) < + std::tie(rhs.level, rhs.layered, rhs.layer, rhs.access, rhs.format); +} + +MultisampledRenderToTextureInfo::MultisampledRenderToTextureInfo(const GLsizei samples, + const gl::ImageIndex &indexSS, + const gl::ImageIndex &indexMS) + : samples(samples), indexSS(indexSS), indexMS(indexMS), msTextureNeedsResolve(false) +{} + +MultisampledRenderToTextureInfo::~MultisampledRenderToTextureInfo() {} + +TextureStorage11::TextureStorage11(Renderer11 *renderer, + UINT bindFlags, + UINT miscFlags, + GLenum internalFormat, + const std::string &label) + : TextureStorage(label), + mRenderer(renderer), + mTopLevel(0), + mMipLevels(0), + mFormatInfo(d3d11::Format::Get(internalFormat, mRenderer->getRenderer11DeviceCaps())), + mTextureWidth(0), + mTextureHeight(0), + mTextureDepth(0), + mDropStencilTexture(), + mBindFlags(bindFlags), + mMiscFlags(miscFlags) +{} + +TextureStorage11::~TextureStorage11() +{ + mSrvCacheForSampler.clear(); +} + +DWORD TextureStorage11::GetTextureBindFlags(GLenum internalFormat, + const Renderer11DeviceCaps &renderer11DeviceCaps, + BindFlags flags) +{ + UINT bindFlags = 0; + + const d3d11::Format &formatInfo = d3d11::Format::Get(internalFormat, renderer11DeviceCaps); + if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN) + { + bindFlags |= D3D11_BIND_SHADER_RESOURCE; + } + if (formatInfo.uavFormat != DXGI_FORMAT_UNKNOWN && flags.unorderedAccess) + { + bindFlags |= D3D11_BIND_UNORDERED_ACCESS; + } + if (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN) + { + bindFlags |= D3D11_BIND_DEPTH_STENCIL; + } + if (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN && flags.renderTarget) + { + bindFlags |= D3D11_BIND_RENDER_TARGET; + } + + return bindFlags; +} + +DWORD TextureStorage11::GetTextureMiscFlags(GLenum internalFormat, + const Renderer11DeviceCaps &renderer11DeviceCaps, + BindFlags bindFlags, + int levels) +{ + UINT miscFlags = 0; + + const d3d11::Format &formatInfo = d3d11::Format::Get(internalFormat, renderer11DeviceCaps); + if (bindFlags.renderTarget) + { + if (d3d11::SupportsMipGen(formatInfo.texFormat, renderer11DeviceCaps.featureLevel)) + { + miscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS; + } + } + + return miscFlags; +} + +UINT TextureStorage11::getBindFlags() const +{ + return mBindFlags; +} + +UINT TextureStorage11::getMiscFlags() const +{ + return mMiscFlags; +} + +int TextureStorage11::getTopLevel() const +{ + // Applying top level is meant to be encapsulated inside TextureStorage11. + UNREACHABLE(); + return mTopLevel; +} + +bool TextureStorage11::isRenderTarget() const +{ + return (mBindFlags & (D3D11_BIND_RENDER_TARGET | D3D11_BIND_DEPTH_STENCIL)) != 0; +} + +bool TextureStorage11::isManaged() const +{ + return false; +} + +bool TextureStorage11::supportsNativeMipmapFunction() const +{ + return (mMiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS) != 0; +} + +int TextureStorage11::getLevelCount() const +{ + return mMipLevels - mTopLevel; +} + +int TextureStorage11::getLevelWidth(int mipLevel) const +{ + return std::max(static_cast(mTextureWidth) >> mipLevel, 1); +} + +int TextureStorage11::getLevelHeight(int mipLevel) const +{ + return std::max(static_cast(mTextureHeight) >> mipLevel, 1); +} + +int TextureStorage11::getLevelDepth(int mipLevel) const +{ + return std::max(static_cast(mTextureDepth) >> mipLevel, 1); +} + +angle::Result TextureStorage11::getMippedResource(const gl::Context *context, + const TextureHelper11 **outResource) +{ + return getResource(context, outResource); +} + +angle::Result TextureStorage11::getSubresourceIndex(const gl::Context *context, + const gl::ImageIndex &index, + UINT *outSubresourceIndex) const +{ + UINT mipSlice = static_cast(index.getLevelIndex() + mTopLevel); + UINT arraySlice = static_cast(index.hasLayer() ? index.getLayerIndex() : 0); + UINT subresource = D3D11CalcSubresource(mipSlice, arraySlice, mMipLevels); + ASSERT(subresource != std::numeric_limits::max()); + *outSubresourceIndex = subresource; + return angle::Result::Continue; +} + +angle::Result TextureStorage11::getSRVForSampler(const gl::Context *context, + const gl::TextureState &textureState, + const gl::SamplerState &sampler, + const d3d11::SharedSRV **outSRV) +{ + ANGLE_TRY(resolveTexture(context)); + // Make sure to add the level offset for our tiny compressed texture workaround + const GLuint effectiveBaseLevel = textureState.getEffectiveBaseLevel(); + const bool swizzleRequired = SwizzleRequired(textureState); + const bool mipmapping = gl::IsMipmapFiltered(sampler.getMinFilter()); + unsigned int mipLevels = + mipmapping ? (textureState.getEffectiveMaxLevel() - effectiveBaseLevel + 1) : 1; + + // Make sure there's 'mipLevels' mipmap levels below the base level (offset by the top level, + // which corresponds to GL level 0) + mipLevels = std::min(mipLevels, mMipLevels - mTopLevel - effectiveBaseLevel); + + if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3) + { + ASSERT(!swizzleRequired); + ASSERT(mipLevels == 1 || mipLevels == mMipLevels); + } + + if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled) + { + // We must ensure that the level zero texture is in sync with mipped texture. + ANGLE_TRY(useLevelZeroWorkaroundTexture(context, mipLevels == 1)); + } + + if (swizzleRequired) + { + verifySwizzleExists(GetEffectiveSwizzle(textureState)); + } + + // We drop the stencil when sampling from the SRV if three conditions hold: + // 1. the drop stencil workaround is enabled. + const bool emulateTinyStencilTextures = + mRenderer->getFeatures().emulateTinyStencilTextures.enabled; + // 2. this is a stencil texture. + const bool hasStencil = (mFormatInfo.format().stencilBits > 0); + // 3. the texture has a 1x1 or 2x2 mip. + const int effectiveTopLevel = effectiveBaseLevel + mipLevels - 1; + const bool hasSmallMips = + (getLevelWidth(effectiveTopLevel) <= 2 || getLevelHeight(effectiveTopLevel) <= 2); + + const bool useDropStencil = (emulateTinyStencilTextures && hasStencil && hasSmallMips); + const SamplerKey key(effectiveBaseLevel, mipLevels, swizzleRequired, useDropStencil); + if (useDropStencil) + { + // Ensure drop texture gets created. + DropStencil result = DropStencil::CREATED; + ANGLE_TRY(ensureDropStencilTexture(context, &result)); + + // Clear the SRV cache if necessary. + // TODO(jmadill): Re-use find query result. + const auto srvEntry = mSrvCacheForSampler.find(key); + if (result == DropStencil::CREATED && srvEntry != mSrvCacheForSampler.end()) + { + mSrvCacheForSampler.erase(key); + } + } + + ANGLE_TRY(getCachedOrCreateSRVForSampler(context, key, outSRV)); + + return angle::Result::Continue; +} + +angle::Result TextureStorage11::getCachedOrCreateSRVForSampler(const gl::Context *context, + const SamplerKey &key, + const d3d11::SharedSRV **outSRV) +{ + auto iter = mSrvCacheForSampler.find(key); + if (iter != mSrvCacheForSampler.end()) + { + *outSRV = &iter->second; + return angle::Result::Continue; + } + + const TextureHelper11 *texture = nullptr; + DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; + + if (key.swizzle) + { + const auto &swizzleFormat = + mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()); + ASSERT(!key.dropStencil || swizzleFormat.format().stencilBits == 0); + ANGLE_TRY(getSwizzleTexture(context, &texture)); + format = swizzleFormat.srvFormat; + } + else if (key.dropStencil) + { + ASSERT(mDropStencilTexture.valid()); + texture = &mDropStencilTexture; + format = DXGI_FORMAT_R32_FLOAT; + } + else + { + ANGLE_TRY(getResource(context, &texture)); + format = mFormatInfo.srvFormat; + } + + d3d11::SharedSRV srv; + + ANGLE_TRY(createSRVForSampler(context, key.baseLevel, key.mipLevels, format, *texture, &srv)); + + const auto &insertIt = mSrvCacheForSampler.insert(std::make_pair(key, std::move(srv))); + *outSRV = &insertIt.first->second; + + return angle::Result::Continue; +} + +angle::Result TextureStorage11::getSRVLevel(const gl::Context *context, + int mipLevel, + SRVType srvType, + const d3d11::SharedSRV **outSRV) +{ + ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); + + ANGLE_TRY(resolveTexture(context)); + if (srvType == SRVType::Stencil) + { + if (!mLevelStencilSRVs[mipLevel].valid()) + { + const TextureHelper11 *resource = nullptr; + ANGLE_TRY(getResource(context, &resource)); + + ANGLE_TRY(createSRVForSampler(context, mipLevel, 1, mFormatInfo.stencilSRVFormat, + *resource, &mLevelStencilSRVs[mipLevel])); + } + *outSRV = &mLevelStencilSRVs[mipLevel]; + return angle::Result::Continue; + } + + auto &levelSRVs = srvType == SRVType::Blit ? mLevelBlitSRVs : mLevelSRVs; + auto &otherLevelSRVs = srvType == SRVType::Blit ? mLevelSRVs : mLevelBlitSRVs; + + if (!levelSRVs[mipLevel].valid()) + { + // Only create a different SRV for blit if blit format is different from regular srv format + if (otherLevelSRVs[mipLevel].valid() && mFormatInfo.srvFormat == mFormatInfo.blitSRVFormat) + { + levelSRVs[mipLevel] = otherLevelSRVs[mipLevel].makeCopy(); + } + else + { + const TextureHelper11 *resource = nullptr; + ANGLE_TRY(getResource(context, &resource)); + + DXGI_FORMAT resourceFormat = + srvType == SRVType::Blit ? mFormatInfo.blitSRVFormat : mFormatInfo.srvFormat; + ANGLE_TRY(createSRVForSampler(context, mipLevel, 1, resourceFormat, *resource, + &levelSRVs[mipLevel])); + } + } + + *outSRV = &levelSRVs[mipLevel]; + return angle::Result::Continue; +} + +angle::Result TextureStorage11::getSRVLevels(const gl::Context *context, + GLint baseLevel, + GLint maxLevel, + const d3d11::SharedSRV **outSRV) +{ + ANGLE_TRY(resolveTexture(context)); + unsigned int mipLevels = maxLevel - baseLevel + 1; + + // Make sure there's 'mipLevels' mipmap levels below the base level (offset by the top level, + // which corresponds to GL level 0) + mipLevels = std::min(mipLevels, mMipLevels - mTopLevel - baseLevel); + + if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3) + { + ASSERT(mipLevels == 1 || mipLevels == mMipLevels); + } + + if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled) + { + // We must ensure that the level zero texture is in sync with mipped texture. + ANGLE_TRY(useLevelZeroWorkaroundTexture(context, mipLevels == 1)); + } + + // TODO(jmadill): Assert we don't need to drop stencil. + + SamplerKey key(baseLevel, mipLevels, false, false); + ANGLE_TRY(getCachedOrCreateSRVForSampler(context, key, outSRV)); + + return angle::Result::Continue; +} + +angle::Result TextureStorage11::getSRVForImage(const gl::Context *context, + const gl::ImageUnit &imageUnit, + const d3d11::SharedSRV **outSRV) +{ + ANGLE_TRY(resolveTexture(context)); + // TODO(Xinghua.cao@intel.com): Add solution to handle swizzle required. + ImageKey key(imageUnit.level, (imageUnit.layered == GL_TRUE), imageUnit.layer, imageUnit.access, + imageUnit.format); + ANGLE_TRY(getCachedOrCreateSRVForImage(context, key, outSRV)); + return angle::Result::Continue; +} + +angle::Result TextureStorage11::getCachedOrCreateSRVForImage(const gl::Context *context, + const ImageKey &key, + const d3d11::SharedSRV **outSRV) +{ + auto iter = mSrvCacheForImage.find(key); + if (iter != mSrvCacheForImage.end()) + { + *outSRV = &iter->second; + return angle::Result::Continue; + } + const TextureHelper11 *texture = nullptr; + ANGLE_TRY(getResource(context, &texture)); + DXGI_FORMAT format = + d3d11::Format::Get(key.format, mRenderer->getRenderer11DeviceCaps()).srvFormat; + d3d11::SharedSRV srv; + ANGLE_TRY(createSRVForImage(context, key.level, format, *texture, &srv)); + const auto &insertIt = mSrvCacheForImage.insert(std::make_pair(key, std::move(srv))); + *outSRV = &insertIt.first->second; + return angle::Result::Continue; +} + +angle::Result TextureStorage11::getUAVForImage(const gl::Context *context, + const gl::ImageUnit &imageUnit, + const d3d11::SharedUAV **outUAV) +{ + ANGLE_TRY(resolveTexture(context)); + // TODO(Xinghua.cao@intel.com): Add solution to handle swizzle required. + ImageKey key(imageUnit.level, (imageUnit.layered == GL_TRUE), imageUnit.layer, imageUnit.access, + imageUnit.format); + ANGLE_TRY(getCachedOrCreateUAVForImage(context, key, outUAV)); + return angle::Result::Continue; +} + +angle::Result TextureStorage11::getCachedOrCreateUAVForImage(const gl::Context *context, + const ImageKey &key, + const d3d11::SharedUAV **outUAV) +{ + auto iter = mUavCacheForImage.find(key); + if (iter != mUavCacheForImage.end()) + { + *outUAV = &iter->second; + return angle::Result::Continue; + } + const TextureHelper11 *texture = nullptr; + ANGLE_TRY(getResource(context, &texture)); + DXGI_FORMAT format = + d3d11::Format::Get(key.format, mRenderer->getRenderer11DeviceCaps()).uavFormat; + ASSERT(format != DXGI_FORMAT_UNKNOWN); + d3d11::SharedUAV uav; + ANGLE_TRY(createUAVForImage(context, key.level, format, *texture, &uav)); + const auto &insertIt = mUavCacheForImage.insert(std::make_pair(key, std::move(uav))); + *outUAV = &insertIt.first->second; + return angle::Result::Continue; +} + +const d3d11::Format &TextureStorage11::getFormatSet() const +{ + return mFormatInfo; +} + +angle::Result TextureStorage11::generateSwizzles(const gl::Context *context, + const gl::TextureState &textureState) +{ + ANGLE_TRY(resolveTexture(context)); + gl::SwizzleState swizzleTarget = GetEffectiveSwizzle(textureState); + for (int level = 0; level < getLevelCount(); level++) + { + // Check if the swizzle for this level is out of date + if (mSwizzleCache[level] != swizzleTarget) + { + // Need to re-render the swizzle for this level + const d3d11::SharedSRV *sourceSRV = nullptr; + ANGLE_TRY(getSRVLevel(context, level, + textureState.isStencilMode() ? SRVType::Stencil : SRVType::Blit, + &sourceSRV)); + + const d3d11::RenderTargetView *destRTV; + ANGLE_TRY(getSwizzleRenderTarget(context, level, &destRTV)); + + gl::Extents size(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level)); + + Blit11 *blitter = mRenderer->getBlitter(); + + ANGLE_TRY(blitter->swizzleTexture(context, *sourceSRV, *destRTV, size, swizzleTarget)); + + mSwizzleCache[level] = swizzleTarget; + } + } + + return angle::Result::Continue; +} + +void TextureStorage11::markLevelDirty(int mipLevel) +{ + if (mipLevel >= 0 && static_cast(mipLevel) < mSwizzleCache.size()) + { + // The default constructor of SwizzleState has GL_INVALID_INDEX for all channels which is + // not a valid swizzle combination + if (mSwizzleCache[mipLevel] != gl::SwizzleState()) + { + // TODO(jmadill): Invalidate specific swizzle. + mRenderer->getStateManager()->invalidateSwizzles(); + mSwizzleCache[mipLevel] = gl::SwizzleState(); + } + } + + if (mDropStencilTexture.valid()) + { + mDropStencilTexture.reset(); + } +} + +void TextureStorage11::markDirty() +{ + for (size_t mipLevel = 0; mipLevel < mSwizzleCache.size(); ++mipLevel) + { + markLevelDirty(static_cast(mipLevel)); + } +} + +angle::Result TextureStorage11::updateSubresourceLevel(const gl::Context *context, + const TextureHelper11 &srcTexture, + unsigned int sourceSubresource, + const gl::ImageIndex &index, + const gl::Box ©Area) +{ + ASSERT(srcTexture.valid()); + + ANGLE_TRY(resolveTexture(context)); + const GLint level = index.getLevelIndex(); + + markLevelDirty(level); + + gl::Extents texSize(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level)); + + bool fullCopy = copyArea.coversSameExtent(texSize); + + const TextureHelper11 *dstTexture = nullptr; + + // If the zero-LOD workaround is active and we want to update a level greater than zero, then we + // should update the mipmapped texture, even if mapmaps are currently disabled. + if (level > 0 && mRenderer->getFeatures().zeroMaxLodWorkaround.enabled) + { + ANGLE_TRY(getMippedResource(context, &dstTexture)); + } + else + { + ANGLE_TRY(getResource(context, &dstTexture)); + } + + unsigned int dstSubresource = 0; + ANGLE_TRY(getSubresourceIndex(context, index, &dstSubresource)); + + ASSERT(dstTexture->valid()); + + const d3d11::DXGIFormatSize &dxgiFormatSizeInfo = + d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat); + if (!fullCopy && mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN) + { + // CopySubresourceRegion cannot copy partial depth stencils, use the blitter instead + Blit11 *blitter = mRenderer->getBlitter(); + return blitter->copyDepthStencil(context, srcTexture, sourceSubresource, copyArea, texSize, + *dstTexture, dstSubresource, copyArea, texSize, nullptr); + } + + D3D11_BOX srcBox; + srcBox.left = copyArea.x; + srcBox.top = copyArea.y; + srcBox.right = + copyArea.x + roundUp(static_cast(copyArea.width), dxgiFormatSizeInfo.blockWidth); + srcBox.bottom = + copyArea.y + roundUp(static_cast(copyArea.height), dxgiFormatSizeInfo.blockHeight); + srcBox.front = copyArea.z; + srcBox.back = copyArea.z + copyArea.depth; + + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + deviceContext->CopySubresourceRegion(dstTexture->get(), dstSubresource, copyArea.x, copyArea.y, + copyArea.z, srcTexture.get(), sourceSubresource, + fullCopy ? nullptr : &srcBox); + return angle::Result::Continue; +} + +angle::Result TextureStorage11::copySubresourceLevel(const gl::Context *context, + const TextureHelper11 &dstTexture, + unsigned int dstSubresource, + const gl::ImageIndex &index, + const gl::Box ®ion) +{ + ASSERT(dstTexture.valid()); + + ANGLE_TRY(resolveTexture(context)); + const TextureHelper11 *srcTexture = nullptr; + + // If the zero-LOD workaround is active and we want to update a level greater than zero, then we + // should update the mipmapped texture, even if mapmaps are currently disabled. + if (index.getLevelIndex() > 0 && mRenderer->getFeatures().zeroMaxLodWorkaround.enabled) + { + ANGLE_TRY(getMippedResource(context, &srcTexture)); + } + else + { + ANGLE_TRY(getResource(context, &srcTexture)); + } + + ASSERT(srcTexture->valid()); + + unsigned int srcSubresource = 0; + ANGLE_TRY(getSubresourceIndex(context, index, &srcSubresource)); + + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + // D3D11 can't perform partial CopySubresourceRegion on depth/stencil textures, so pSrcBox + // should be nullptr. + D3D11_BOX srcBox; + D3D11_BOX *pSrcBox = nullptr; + if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3) + { + GLsizei width = region.width; + GLsizei height = region.height; + d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, nullptr); + + // Keep srcbox as nullptr if we're dealing with tiny mips of compressed textures. + if (width == region.width && height == region.height) + { + // However, D3D10Level9 doesn't always perform CopySubresourceRegion correctly unless + // the source box is specified. This is okay, since we don't perform + // CopySubresourceRegion on depth/stencil textures on 9_3. + ASSERT(mFormatInfo.dsvFormat == DXGI_FORMAT_UNKNOWN); + srcBox.left = region.x; + srcBox.right = region.x + region.width; + srcBox.top = region.y; + srcBox.bottom = region.y + region.height; + srcBox.front = region.z; + srcBox.back = region.z + region.depth; + pSrcBox = &srcBox; + } + } + + deviceContext->CopySubresourceRegion(dstTexture.get(), dstSubresource, region.x, region.y, + region.z, srcTexture->get(), srcSubresource, pSrcBox); + + return angle::Result::Continue; +} + +angle::Result TextureStorage11::generateMipmap(const gl::Context *context, + const gl::ImageIndex &sourceIndex, + const gl::ImageIndex &destIndex) +{ + ASSERT(sourceIndex.getLayerIndex() == destIndex.getLayerIndex()); + + ANGLE_TRY(resolveTexture(context)); + markLevelDirty(destIndex.getLevelIndex()); + + RenderTargetD3D *source = nullptr; + ANGLE_TRY(getRenderTarget(context, sourceIndex, 0, &source)); + + // dest will always have 0 since, we have just released the MS Texture struct + RenderTargetD3D *dest = nullptr; + ANGLE_TRY(getRenderTarget(context, destIndex, 0, &dest)); + + RenderTarget11 *srcRT11 = GetAs(source); + RenderTarget11 *dstRT11 = GetAs(dest); + const d3d11::RenderTargetView &destRTV = dstRT11->getRenderTargetView(); + const d3d11::SharedSRV *sourceSRV; + ANGLE_TRY(srcRT11->getBlitShaderResourceView(context, &sourceSRV)); + + gl::Box sourceArea(0, 0, 0, source->getWidth(), source->getHeight(), source->getDepth()); + gl::Extents sourceSize(source->getWidth(), source->getHeight(), source->getDepth()); + + gl::Box destArea(0, 0, 0, dest->getWidth(), dest->getHeight(), dest->getDepth()); + gl::Extents destSize(dest->getWidth(), dest->getHeight(), dest->getDepth()); + + Blit11 *blitter = mRenderer->getBlitter(); + const gl::InternalFormat &sourceInternalFormat = + gl::GetSizedInternalFormatInfo(source->getInternalFormat()); + GLenum format = sourceInternalFormat.format; + GLenum type = sourceInternalFormat.type; + return blitter->copyTexture(context, *sourceSRV, sourceArea, sourceSize, format, destRTV, + destArea, destSize, nullptr, format, type, GL_LINEAR, false, false, + false); +} + +void TextureStorage11::verifySwizzleExists(const gl::SwizzleState &swizzleState) +{ + for (unsigned int level = 0; level < mMipLevels; level++) + { + ASSERT(mSwizzleCache[level] == swizzleState); + } +} + +void TextureStorage11::clearSRVCache() +{ + markDirty(); + mSrvCacheForSampler.clear(); + + for (size_t level = 0; level < mLevelSRVs.size(); level++) + { + mLevelSRVs[level].reset(); + mLevelBlitSRVs[level].reset(); + } +} + +angle::Result TextureStorage11::copyToStorage(const gl::Context *context, + TextureStorage *destStorage) +{ + ASSERT(destStorage); + + ANGLE_TRY(resolveTexture(context)); + const TextureHelper11 *sourceResouce = nullptr; + ANGLE_TRY(getResource(context, &sourceResouce)); + + TextureStorage11 *dest11 = GetAs(destStorage); + const TextureHelper11 *destResource = nullptr; + ANGLE_TRY(dest11->getResource(context, &destResource)); + + ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); + immediateContext->CopyResource(destResource->get(), sourceResouce->get()); + + dest11->markDirty(); + + return angle::Result::Continue; +} + +void TextureStorage11::invalidateTextures() +{ + mRenderer->getStateManager()->invalidateTexturesAndSamplers(); +} + +angle::Result TextureStorage11::setData(const gl::Context *context, + const gl::ImageIndex &index, + ImageD3D *image, + const gl::Box *destBox, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixelData) +{ + ASSERT(!image->isDirty()); + + ANGLE_TRY(resolveTexture(context)); + markLevelDirty(index.getLevelIndex()); + + const TextureHelper11 *resource = nullptr; + ANGLE_TRY(getResource(context, &resource)); + ASSERT(resource && resource->valid()); + + UINT destSubresource = 0; + ANGLE_TRY(getSubresourceIndex(context, index, &destSubresource)); + + const gl::InternalFormat &internalFormatInfo = + gl::GetInternalFormatInfo(image->getInternalFormat(), type); + + gl::Box levelBox(0, 0, 0, getLevelWidth(index.getLevelIndex()), + getLevelHeight(index.getLevelIndex()), getLevelDepth(index.getLevelIndex())); + bool fullUpdate = (destBox == nullptr || *destBox == levelBox); + ASSERT(internalFormatInfo.depthBits == 0 || fullUpdate); + + // TODO(jmadill): Handle compressed formats + // Compressed formats have different load syntax, so we'll have to handle them with slightly + // different logic. Will implemnent this in a follow-up patch, and ensure we do not use SetData + // with compressed formats in the calling logic. + ASSERT(!internalFormatInfo.compressed); + + Context11 *context11 = GetImplAs(context); + + const int width = destBox ? destBox->width : static_cast(image->getWidth()); + const int height = destBox ? destBox->height : static_cast(image->getHeight()); + const int depth = destBox ? destBox->depth : static_cast(image->getDepth()); + GLuint srcRowPitch = 0; + ANGLE_CHECK_GL_MATH(context11, + internalFormatInfo.computeRowPitch(type, width, unpack.alignment, + unpack.rowLength, &srcRowPitch)); + GLuint srcDepthPitch = 0; + ANGLE_CHECK_GL_MATH(context11, internalFormatInfo.computeDepthPitch( + height, unpack.imageHeight, srcRowPitch, &srcDepthPitch)); + GLuint srcSkipBytes = 0; + ANGLE_CHECK_GL_MATH( + context11, internalFormatInfo.computeSkipBytes(type, srcRowPitch, srcDepthPitch, unpack, + index.usesTex3D(), &srcSkipBytes)); + + const d3d11::Format &d3d11Format = + d3d11::Format::Get(image->getInternalFormat(), mRenderer->getRenderer11DeviceCaps()); + const d3d11::DXGIFormatSize &dxgiFormatInfo = + d3d11::GetDXGIFormatSizeInfo(d3d11Format.texFormat); + + const size_t outputPixelSize = dxgiFormatInfo.pixelBytes; + + UINT bufferRowPitch = static_cast(outputPixelSize) * width; + UINT bufferDepthPitch = bufferRowPitch * height; + + const size_t neededSize = bufferDepthPitch * depth; + angle::MemoryBuffer *conversionBuffer = nullptr; + const uint8_t *data = nullptr; + + LoadImageFunctionInfo loadFunctionInfo = d3d11Format.getLoadFunctions()(type); + if (loadFunctionInfo.requiresConversion) + { + ANGLE_TRY(mRenderer->getScratchMemoryBuffer(context11, neededSize, &conversionBuffer)); + loadFunctionInfo.loadFunction(width, height, depth, pixelData + srcSkipBytes, srcRowPitch, + srcDepthPitch, conversionBuffer->data(), bufferRowPitch, + bufferDepthPitch); + data = conversionBuffer->data(); + } + else + { + data = pixelData + srcSkipBytes; + bufferRowPitch = srcRowPitch; + bufferDepthPitch = srcDepthPitch; + } + + ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); + + if (!fullUpdate) + { + ASSERT(destBox); + + D3D11_BOX destD3DBox; + destD3DBox.left = destBox->x; + destD3DBox.right = destBox->x + destBox->width; + destD3DBox.top = destBox->y; + destD3DBox.bottom = destBox->y + destBox->height; + destD3DBox.front = destBox->z; + destD3DBox.back = destBox->z + destBox->depth; + + immediateContext->UpdateSubresource(resource->get(), destSubresource, &destD3DBox, data, + bufferRowPitch, bufferDepthPitch); + } + else + { + immediateContext->UpdateSubresource(resource->get(), destSubresource, nullptr, data, + bufferRowPitch, bufferDepthPitch); + } + + return angle::Result::Continue; +} + +angle::Result TextureStorage11::ensureDropStencilTexture( + const gl::Context *context, + TextureStorage11::DropStencil *dropStencilOut) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result TextureStorage11::initDropStencilTexture(const gl::Context *context, + const gl::ImageIndexIterator &it) +{ + const TextureHelper11 *sourceTexture = nullptr; + ANGLE_TRY(getResource(context, &sourceTexture)); + + gl::ImageIndexIterator itCopy = it; + + while (itCopy.hasNext()) + { + gl::ImageIndex index = itCopy.next(); + gl::Box wholeArea(0, 0, 0, getLevelWidth(index.getLevelIndex()), + getLevelHeight(index.getLevelIndex()), 1); + gl::Extents wholeSize(wholeArea.width, wholeArea.height, 1); + + UINT subresource = 0; + ANGLE_TRY(getSubresourceIndex(context, index, &subresource)); + + ANGLE_TRY(mRenderer->getBlitter()->copyDepthStencil( + context, *sourceTexture, subresource, wholeArea, wholeSize, mDropStencilTexture, + subresource, wholeArea, wholeSize, nullptr)); + } + + return angle::Result::Continue; +} + +angle::Result TextureStorage11::resolveTextureHelper(const gl::Context *context, + const TextureHelper11 &texture) +{ + UINT subresourceIndexSS; + ANGLE_TRY(getSubresourceIndex(context, mMSTexInfo->indexSS, &subresourceIndexSS)); + UINT subresourceIndexMS; + ANGLE_TRY(getSubresourceIndex(context, mMSTexInfo->indexMS, &subresourceIndexMS)); + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + const TextureHelper11 *resource = nullptr; + ANGLE_TRY(mMSTexInfo->msTex->getResource(context, &resource)); + deviceContext->ResolveSubresource(texture.get(), subresourceIndexSS, resource->get(), + subresourceIndexMS, texture.getFormat()); + mMSTexInfo->msTextureNeedsResolve = false; + return angle::Result::Continue; +} + +angle::Result TextureStorage11::releaseMultisampledTexStorageForLevel(size_t level) +{ + if (mMSTexInfo && mMSTexInfo->indexSS.getLevelIndex() == static_cast(level)) + { + mMSTexInfo->msTex.reset(); + onStateChange(angle::SubjectMessage::ContentsChanged); + } + return angle::Result::Continue; +} + +GLsizei TextureStorage11::getRenderToTextureSamples() const +{ + if (mMSTexInfo) + { + return mMSTexInfo->samples; + } + return 0; +} + +angle::Result TextureStorage11::findMultisampledRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) const +{ + const int level = index.getLevelIndex(); + if (!mMSTexInfo || level != mMSTexInfo->indexSS.getLevelIndex() || + samples != mMSTexInfo->samples || !mMSTexInfo->msTex) + { + *outRT = nullptr; + return angle::Result::Continue; + } + RenderTargetD3D *rt; + ANGLE_TRY(mMSTexInfo->msTex->findRenderTarget(context, mMSTexInfo->indexMS, samples, &rt)); + *outRT = rt; + return angle::Result::Continue; +} + +angle::Result TextureStorage11::getMultisampledRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) +{ + const int level = index.getLevelIndex(); + if (!mMSTexInfo || level != mMSTexInfo->indexSS.getLevelIndex() || + samples != mMSTexInfo->samples || !mMSTexInfo->msTex) + { + // if mMSTexInfo already exists, then we want to resolve and release it + // since the mMSTexInfo must be for a different sample count or level + ANGLE_TRY(resolveTexture(context)); + + // Now we can create a new object for the correct sample and level + GLsizei width = getLevelWidth(level); + GLsizei height = getLevelHeight(level); + GLenum internalFormat = mFormatInfo.internalFormat; + std::unique_ptr texMS( + GetAs(mRenderer->createTextureStorage2DMultisample( + internalFormat, width, height, level, samples, true, mKHRDebugLabel))); + + // make sure multisample object has the blitted information. + gl::Rectangle area(0, 0, width, height); + RenderTargetD3D *readRenderTarget = nullptr; + // use incoming index here since the index will correspond to the single sampled texture + ANGLE_TRY(getRenderTarget(context, index, 0, &readRenderTarget)); + gl::ImageIndex indexMS = gl::ImageIndex::Make2DMultisample(); + RenderTargetD3D *drawRenderTarget = nullptr; + ANGLE_TRY(texMS->getRenderTarget(context, indexMS, samples, &drawRenderTarget)); + + // blit SS -> MS + // mask: GL_COLOR_BUFFER_BIT, filter: GL_NEAREST + ANGLE_TRY(mRenderer->blitRenderbufferRect(context, area, area, 0, 0, readRenderTarget, + drawRenderTarget, GL_NEAREST, nullptr, true, + false, false)); + mMSTexInfo = std::make_unique(samples, index, indexMS); + mMSTexInfo->msTex = std::move(texMS); + } + RenderTargetD3D *rt; + ANGLE_TRY(mMSTexInfo->msTex->getRenderTarget(context, mMSTexInfo->indexMS, samples, &rt)); + // By returning the multisampled render target to the caller, the render target + // is expected to be changed so we need to resolve to a single sampled texture + // next time resolveTexture is called. + mMSTexInfo->msTextureNeedsResolve = true; + *outRT = rt; + return angle::Result::Continue; +} + +TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, + SwapChain11 *swapchain, + const std::string &label) + : TextureStorage11(renderer, + D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE, + 0, + swapchain->getRenderTargetInternalFormat(), + label), + mTexture(swapchain->getOffscreenTexture()), + mLevelZeroTexture(), + mLevelZeroRenderTarget(nullptr), + mUseLevelZeroTexture(false), + mSwizzleTexture() +{ + for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) + { + mAssociatedImages[i] = nullptr; + mRenderTarget[i] = nullptr; + } + + D3D11_TEXTURE2D_DESC texDesc; + mTexture.getDesc(&texDesc); + mMipLevels = texDesc.MipLevels; + mTextureWidth = texDesc.Width; + mTextureHeight = texDesc.Height; + mTextureDepth = 1; + mHasKeyedMutex = (texDesc.MiscFlags & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX) != 0; +} + +TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, + GLenum internalformat, + BindFlags bindFlags, + GLsizei width, + GLsizei height, + int levels, + const std::string &label, + bool hintLevelZeroOnly) + : TextureStorage11( + renderer, + GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), bindFlags), + GetTextureMiscFlags(internalformat, + renderer->getRenderer11DeviceCaps(), + bindFlags, + levels), + internalformat, + label), + mTexture(), + mHasKeyedMutex(false), + mLevelZeroTexture(), + mLevelZeroRenderTarget(nullptr), + mUseLevelZeroTexture(hintLevelZeroOnly && levels > 1), + mSwizzleTexture() +{ + for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) + { + mAssociatedImages[i] = nullptr; + mRenderTarget[i] = nullptr; + } + + d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, &mTopLevel); + mMipLevels = mTopLevel + levels; + mTextureWidth = width; + mTextureHeight = height; + mTextureDepth = 1; + + // The LevelZeroOnly hint should only be true if the zero max LOD workaround is active. + ASSERT(!mUseLevelZeroTexture || mRenderer->getFeatures().zeroMaxLodWorkaround.enabled); +} + +void TextureStorage11_2D::onLabelUpdate() +{ + if (mTexture.valid()) + { + mTexture.setKHRDebugLabel(&mKHRDebugLabel); + } + if (mLevelZeroTexture.valid()) + { + mLevelZeroTexture.setKHRDebugLabel(&mKHRDebugLabel); + } + if (mSwizzleTexture.valid()) + { + mSwizzleTexture.setKHRDebugLabel(&mKHRDebugLabel); + } +} + +angle::Result TextureStorage11_2D::onDestroy(const gl::Context *context) +{ + for (unsigned i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) + { + if (mAssociatedImages[i] != nullptr) + { + mAssociatedImages[i]->verifyAssociatedStorageValid(this); + + // We must let the Images recover their data before we delete it from the + // TextureStorage. + ANGLE_TRY(mAssociatedImages[i]->recoverFromAssociatedStorage(context)); + } + } + + if (mHasKeyedMutex) + { + // If the keyed mutex is released that will unbind it and cause the state cache to become + // desynchronized. + mRenderer->getStateManager()->invalidateBoundViews(); + } + + return angle::Result::Continue; +} + +TextureStorage11_2D::~TextureStorage11_2D() {} + +angle::Result TextureStorage11_2D::copyToStorage(const gl::Context *context, + TextureStorage *destStorage) +{ + ASSERT(destStorage); + + TextureStorage11_2D *dest11 = GetAs(destStorage); + ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); + + if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled) + { + // If either mTexture or mLevelZeroTexture exist, then we need to copy them into the + // corresponding textures in destStorage. + if (mTexture.valid()) + { + ANGLE_TRY(dest11->useLevelZeroWorkaroundTexture(context, false)); + + const TextureHelper11 *destResource = nullptr; + ANGLE_TRY(dest11->getResource(context, &destResource)); + + immediateContext->CopyResource(destResource->get(), mTexture.get()); + } + + if (mLevelZeroTexture.valid()) + { + ANGLE_TRY(dest11->useLevelZeroWorkaroundTexture(context, true)); + + const TextureHelper11 *destResource = nullptr; + ANGLE_TRY(dest11->getResource(context, &destResource)); + + immediateContext->CopyResource(destResource->get(), mLevelZeroTexture.get()); + } + + return angle::Result::Continue; + } + + const TextureHelper11 *sourceResouce = nullptr; + ANGLE_TRY(getResource(context, &sourceResouce)); + + const TextureHelper11 *destResource = nullptr; + ANGLE_TRY(dest11->getResource(context, &destResource)); + + immediateContext->CopyResource(destResource->get(), sourceResouce->get()); + dest11->markDirty(); + + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2D::useLevelZeroWorkaroundTexture(const gl::Context *context, + bool useLevelZeroTexture) +{ + if (useLevelZeroTexture && mMipLevels > 1) + { + if (!mUseLevelZeroTexture && mTexture.valid()) + { + ANGLE_TRY(ensureTextureExists(context, 1)); + + // Pull data back from the mipped texture if necessary. + ASSERT(mLevelZeroTexture.valid()); + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + deviceContext->CopySubresourceRegion(mLevelZeroTexture.get(), 0, 0, 0, 0, + mTexture.get(), 0, nullptr); + } + + mUseLevelZeroTexture = true; + } + else + { + if (mUseLevelZeroTexture && mLevelZeroTexture.valid()) + { + ANGLE_TRY(ensureTextureExists(context, mMipLevels)); + + // Pull data back from the level zero texture if necessary. + ASSERT(mTexture.valid()); + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + deviceContext->CopySubresourceRegion(mTexture.get(), 0, 0, 0, 0, + mLevelZeroTexture.get(), 0, nullptr); + } + + mUseLevelZeroTexture = false; + } + + return angle::Result::Continue; +} + +void TextureStorage11_2D::associateImage(Image11 *image, const gl::ImageIndex &index) +{ + const GLint level = index.getLevelIndex(); + + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + mAssociatedImages[level] = image; + } +} + +void TextureStorage11_2D::verifyAssociatedImageValid(const gl::ImageIndex &index, + Image11 *expectedImage) +{ + const GLint level = index.getLevelIndex(); + + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + // This validation check should never return false. It means the Image/TextureStorage + // association is broken. + ASSERT(mAssociatedImages[level] == expectedImage); +} + +// disassociateImage allows an Image to end its association with a Storage. +void TextureStorage11_2D::disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) +{ + const GLint level = index.getLevelIndex(); + + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + ASSERT(mAssociatedImages[level] == expectedImage); + mAssociatedImages[level] = nullptr; +} + +// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image +// recover its data before ending the association. +angle::Result TextureStorage11_2D::releaseAssociatedImage(const gl::Context *context, + const gl::ImageIndex &index, + Image11 *incomingImage) +{ + const GLint level = index.getLevelIndex(); + + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + // No need to let the old Image recover its data, if it is also the incoming Image. + if (mAssociatedImages[level] != nullptr && mAssociatedImages[level] != incomingImage) + { + // Ensure that the Image is still associated with this TextureStorage. + mAssociatedImages[level]->verifyAssociatedStorageValid(this); + + // Force the image to recover from storage before its data is overwritten. + // This will reset mAssociatedImages[level] to nullptr too. + ANGLE_TRY(mAssociatedImages[level]->recoverFromAssociatedStorage(context)); + } + } + + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2D::getResource(const gl::Context *context, + const TextureHelper11 **outResource) +{ + if (mUseLevelZeroTexture && mMipLevels > 1) + { + ANGLE_TRY(ensureTextureExists(context, 1)); + + *outResource = &mLevelZeroTexture; + return angle::Result::Continue; + } + + ANGLE_TRY(ensureTextureExists(context, mMipLevels)); + + *outResource = &mTexture; + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2D::getMippedResource(const gl::Context *context, + const TextureHelper11 **outResource) +{ + // This shouldn't be called unless the zero max LOD workaround is active. + ASSERT(mRenderer->getFeatures().zeroMaxLodWorkaround.enabled); + + ANGLE_TRY(ensureTextureExists(context, mMipLevels)); + + *outResource = &mTexture; + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2D::ensureTextureExists(const gl::Context *context, int mipLevels) +{ + // If mMipLevels = 1 then always use mTexture rather than mLevelZeroTexture. + ANGLE_TRY(resolveTexture(context)); + bool useLevelZeroTexture = mRenderer->getFeatures().zeroMaxLodWorkaround.enabled + ? (mipLevels == 1) && (mMipLevels > 1) + : false; + TextureHelper11 *outputTexture = useLevelZeroTexture ? &mLevelZeroTexture : &mTexture; + + // if the width or height is not positive this should be treated as an incomplete texture + // we handle that here by skipping the d3d texture creation + if (!outputTexture->valid() && mTextureWidth > 0 && mTextureHeight > 0) + { + ASSERT(mipLevels > 0); + + D3D11_TEXTURE2D_DESC desc; + desc.Width = mTextureWidth; // Compressed texture size constraints? + desc.Height = mTextureHeight; + desc.MipLevels = mipLevels; + desc.ArraySize = 1; + desc.Format = isUnorderedAccess() ? mFormatInfo.typelessFormat : mFormatInfo.texFormat; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = getBindFlags(); + desc.CPUAccessFlags = 0; + desc.MiscFlags = getMiscFlags(); + + ANGLE_TRY(mRenderer->allocateTexture(GetImplAs(context), desc, mFormatInfo, + outputTexture)); + + if (useLevelZeroTexture) + { + outputTexture->setLabels("TexStorage2D.Level0Texture", &mKHRDebugLabel); + } + else + { + outputTexture->setLabels("TexStorage2D.Texture", &mKHRDebugLabel); + } + } + + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2D::findRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) const +{ + ASSERT(!index.hasLayer()); + + const int level = index.getLevelIndex(); + ASSERT(level >= 0 && level < getLevelCount()); + + bool needMS = samples > 0; + if (needMS) + { + return findMultisampledRenderTarget(context, index, samples, outRT); + } + + ASSERT(outRT); + if (mRenderTarget[level]) + { + *outRT = mRenderTarget[level].get(); + return angle::Result::Continue; + } + + if (mUseLevelZeroTexture) + { + ASSERT(level == 0); + *outRT = mLevelZeroRenderTarget.get(); + return angle::Result::Continue; + } + + *outRT = nullptr; + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2D::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) +{ + ASSERT(!index.hasLayer()); + + const int level = index.getLevelIndex(); + ASSERT(level >= 0 && level < getLevelCount()); + + bool needMS = samples > 0; + if (needMS) + { + return getMultisampledRenderTarget(context, index, samples, outRT); + } + else + { + ANGLE_TRY(resolveTexture(context)); + } + + // In GL ES 2.0, the application can only render to level zero of the texture (Section 4.4.3 of + // the GLES 2.0 spec, page 113 of version 2.0.25). Other parts of TextureStorage11_2D could + // create RTVs on non-zero levels of the texture (e.g. generateMipmap). + // On Feature Level 9_3, this is unlikely to be useful. The renderer can't create SRVs on the + // individual levels of the texture, so methods like generateMipmap can't do anything useful + // with non-zero-level RTVs. Therefore if level > 0 on 9_3 then there's almost certainly + // something wrong. + ASSERT( + !(mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3 && level > 0)); + ASSERT(outRT); + if (mRenderTarget[level]) + { + *outRT = mRenderTarget[level].get(); + return angle::Result::Continue; + } + + if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled) + { + ASSERT(level == 0); + ANGLE_TRY(useLevelZeroWorkaroundTexture(context, true)); + } + + const TextureHelper11 *texture = nullptr; + ANGLE_TRY(getResource(context, &texture)); + + const d3d11::SharedSRV *srv = nullptr; + ANGLE_TRY(getSRVLevel(context, level, SRVType::Sample, &srv)); + + const d3d11::SharedSRV *blitSRV = nullptr; + ANGLE_TRY(getSRVLevel(context, level, SRVType::Blit, &blitSRV)); + + Context11 *context11 = GetImplAs(context); + + if (mUseLevelZeroTexture) + { + if (!mLevelZeroRenderTarget) + { + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mFormatInfo.rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + rtvDesc.Texture2D.MipSlice = mTopLevel + level; + + d3d11::RenderTargetView rtv; + ANGLE_TRY( + mRenderer->allocateResource(context11, rtvDesc, mLevelZeroTexture.get(), &rtv)); + rtv.setLabels("TexStorage2D.Level0RTV", &mKHRDebugLabel); + + mLevelZeroRenderTarget.reset(new TextureRenderTarget11( + std::move(rtv), mLevelZeroTexture, d3d11::SharedSRV(), d3d11::SharedSRV(), + mFormatInfo.internalFormat, getFormatSet(), getLevelWidth(level), + getLevelHeight(level), 1, 0)); + } + + *outRT = mLevelZeroRenderTarget.get(); + return angle::Result::Continue; + } + + if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN) + { + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mFormatInfo.rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + rtvDesc.Texture2D.MipSlice = mTopLevel + level; + + d3d11::RenderTargetView rtv; + ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, texture->get(), &rtv)); + rtv.setLabels("TexStorage2D.RTV", &mKHRDebugLabel); + + mRenderTarget[level].reset(new TextureRenderTarget11( + std::move(rtv), *texture, *srv, *blitSRV, mFormatInfo.internalFormat, getFormatSet(), + getLevelWidth(level), getLevelHeight(level), 1, 0)); + + *outRT = mRenderTarget[level].get(); + return angle::Result::Continue; + } + + ASSERT(mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN); + + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsvDesc.Format = mFormatInfo.dsvFormat; + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + dsvDesc.Texture2D.MipSlice = mTopLevel + level; + dsvDesc.Flags = 0; + + d3d11::DepthStencilView dsv; + ANGLE_TRY(mRenderer->allocateResource(context11, dsvDesc, texture->get(), &dsv)); + dsv.setLabels("TexStorage2D.DSV", &mKHRDebugLabel); + + mRenderTarget[level].reset(new TextureRenderTarget11( + std::move(dsv), *texture, *srv, mFormatInfo.internalFormat, getFormatSet(), + getLevelWidth(level), getLevelHeight(level), 1, 0)); + + *outRT = mRenderTarget[level].get(); + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2D::createSRVForSampler(const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) +{ + ASSERT(outSRV); + + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = format; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel; + srvDesc.Texture2D.MipLevels = mipLevels; + + const TextureHelper11 *srvTexture = &texture; + + if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled) + { + ASSERT(mTopLevel == 0); + ASSERT(baseLevel == 0); + // This code also assumes that the incoming texture equals either mLevelZeroTexture or + // mTexture. + + if (mipLevels == 1 && mMipLevels > 1) + { + // We must use a SRV on the level-zero-only texture. + ANGLE_TRY(ensureTextureExists(context, 1)); + srvTexture = &mLevelZeroTexture; + } + else + { + ASSERT(mipLevels == static_cast(mMipLevels)); + ASSERT(mTexture.valid() && texture == mTexture); + srvTexture = &mTexture; + } + } + + ANGLE_TRY(mRenderer->allocateResource(GetImplAs(context), srvDesc, srvTexture->get(), + outSRV)); + outSRV->setLabels("TexStorage2D.SRV", &mKHRDebugLabel); + + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2D::createSRVForImage(const gl::Context *context, + int level, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) +{ + ASSERT(outSRV); + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = format; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + srvDesc.Texture2D.MostDetailedMip = mTopLevel + level; + srvDesc.Texture2D.MipLevels = 1; + ANGLE_TRY( + mRenderer->allocateResource(GetImplAs(context), srvDesc, texture.get(), outSRV)); + outSRV->setLabels("TexStorage2D.SRVForImage", &mKHRDebugLabel); + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2D::createUAVForImage(const gl::Context *context, + int level, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedUAV *outUAV) +{ + ASSERT(outUAV); + D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc; + uavDesc.Format = format; + uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D; + uavDesc.Texture2D.MipSlice = mTopLevel + level; + ANGLE_TRY( + mRenderer->allocateResource(GetImplAs(context), uavDesc, texture.get(), outUAV)); + outUAV->setLabels("TexStorage2D.UAVForImage", &mKHRDebugLabel); + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2D::getSwizzleTexture(const gl::Context *context, + const TextureHelper11 **outTexture) +{ + ASSERT(outTexture); + + if (!mSwizzleTexture.valid()) + { + const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()); + + D3D11_TEXTURE2D_DESC desc; + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.MipLevels = mMipLevels; + desc.ArraySize = 1; + desc.Format = format.texFormat; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + ANGLE_TRY(mRenderer->allocateTexture(GetImplAs(context), desc, format, + &mSwizzleTexture)); + mSwizzleTexture.setLabels("TexStorage2D.SwizzleTexture", &mKHRDebugLabel); + } + + *outTexture = &mSwizzleTexture; + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2D::getSwizzleRenderTarget(const gl::Context *context, + int mipLevel, + const d3d11::RenderTargetView **outRTV) +{ + ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); + ASSERT(outRTV); + + if (!mSwizzleRenderTargets[mipLevel].valid()) + { + const TextureHelper11 *swizzleTexture = nullptr; + ANGLE_TRY(getSwizzleTexture(context, &swizzleTexture)); + + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = + mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel; + + ANGLE_TRY(mRenderer->allocateResource(GetImplAs(context), rtvDesc, + mSwizzleTexture.get(), + &mSwizzleRenderTargets[mipLevel])); + } + + *outRTV = &mSwizzleRenderTargets[mipLevel]; + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2D::ensureDropStencilTexture(const gl::Context *context, + DropStencil *dropStencilOut) +{ + if (mDropStencilTexture.valid()) + { + *dropStencilOut = DropStencil::ALREADY_EXISTS; + return angle::Result::Continue; + } + + D3D11_TEXTURE2D_DESC dropDesc = {}; + dropDesc.ArraySize = 1; + dropDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DEPTH_STENCIL; + dropDesc.CPUAccessFlags = 0; + dropDesc.Format = DXGI_FORMAT_R32_TYPELESS; + dropDesc.Height = mTextureHeight; + dropDesc.MipLevels = mMipLevels; + dropDesc.MiscFlags = 0; + dropDesc.SampleDesc.Count = 1; + dropDesc.SampleDesc.Quality = 0; + dropDesc.Usage = D3D11_USAGE_DEFAULT; + dropDesc.Width = mTextureWidth; + + const auto &format = + d3d11::Format::Get(GL_DEPTH_COMPONENT32F, mRenderer->getRenderer11DeviceCaps()); + ANGLE_TRY(mRenderer->allocateTexture(GetImplAs(context), dropDesc, format, + &mDropStencilTexture)); + mDropStencilTexture.setLabels("TexStorage2D.DropStencil", &mKHRDebugLabel); + + ANGLE_TRY(initDropStencilTexture(context, gl::ImageIndexIterator::Make2D(0, mMipLevels))); + + *dropStencilOut = DropStencil::CREATED; + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2D::resolveTexture(const gl::Context *context) +{ + if (mMSTexInfo && mMSTexInfo->msTex && mMSTexInfo->msTextureNeedsResolve) + { + ANGLE_TRY(resolveTextureHelper(context, mTexture)); + onStateChange(angle::SubjectMessage::ContentsChanged); + } + return angle::Result::Continue; +} + +TextureStorage11_External::TextureStorage11_External( + Renderer11 *renderer, + egl::Stream *stream, + const egl::Stream::GLTextureDescription &glDesc, + const std::string &label) + : TextureStorage11(renderer, D3D11_BIND_SHADER_RESOURCE, 0, glDesc.internalFormat, label) +{ + ASSERT(stream->getProducerType() == egl::Stream::ProducerType::D3D11Texture); + auto *producer = static_cast(stream->getImplementation()); + mTexture.set(producer->getD3DTexture(), mFormatInfo); + mSubresourceIndex = producer->getArraySlice(); + mTexture.get()->AddRef(); + mMipLevels = 1; + + D3D11_TEXTURE2D_DESC desc; + mTexture.getDesc(&desc); + mTextureWidth = desc.Width; + mTextureHeight = desc.Height; + mTextureDepth = 1; + mHasKeyedMutex = (desc.MiscFlags & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX) != 0; +} + +angle::Result TextureStorage11_External::onDestroy(const gl::Context *context) +{ + if (mHasKeyedMutex) + { + // If the keyed mutex is released that will unbind it and cause the state cache to become + // desynchronized. + mRenderer->getStateManager()->invalidateBoundViews(); + } + + return angle::Result::Continue; +} + +TextureStorage11_External::~TextureStorage11_External() {} + +angle::Result TextureStorage11_External::copyToStorage(const gl::Context *context, + TextureStorage *destStorage) +{ + UNIMPLEMENTED(); + return angle::Result::Continue; +} + +void TextureStorage11_External::associateImage(Image11 *image, const gl::ImageIndex &index) +{ + ASSERT(index.getLevelIndex() == 0); + mAssociatedImage = image; +} + +void TextureStorage11_External::verifyAssociatedImageValid(const gl::ImageIndex &index, + Image11 *expectedImage) +{ + ASSERT(index.getLevelIndex() == 0 && mAssociatedImage == expectedImage); +} + +void TextureStorage11_External::disassociateImage(const gl::ImageIndex &index, + Image11 *expectedImage) +{ + ASSERT(index.getLevelIndex() == 0); + ASSERT(mAssociatedImage == expectedImage); + mAssociatedImage = nullptr; +} + +angle::Result TextureStorage11_External::releaseAssociatedImage(const gl::Context *context, + const gl::ImageIndex &index, + Image11 *incomingImage) +{ + ASSERT(index.getLevelIndex() == 0); + + if (mAssociatedImage != nullptr && mAssociatedImage != incomingImage) + { + mAssociatedImage->verifyAssociatedStorageValid(this); + + ANGLE_TRY(mAssociatedImage->recoverFromAssociatedStorage(context)); + } + + return angle::Result::Continue; +} + +angle::Result TextureStorage11_External::getResource(const gl::Context *context, + const TextureHelper11 **outResource) +{ + *outResource = &mTexture; + return angle::Result::Continue; +} + +angle::Result TextureStorage11_External::getMippedResource(const gl::Context *context, + const TextureHelper11 **outResource) +{ + *outResource = &mTexture; + return angle::Result::Continue; +} + +angle::Result TextureStorage11_External::findRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) const +{ + // Render targets are not supported for external textures + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result TextureStorage11_External::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) +{ + // Render targets are not supported for external textures + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result TextureStorage11_External::createSRVForSampler(const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) +{ + // Since external textures are treates as non-mipmapped textures, we ignore mipmap levels and + // use the specified subresource ID the storage was created with. + ASSERT(mipLevels == 1); + ASSERT(outSRV); + + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = format; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + // subresource index is equal to the mip level for 2D textures + srvDesc.Texture2DArray.MostDetailedMip = 0; + srvDesc.Texture2DArray.MipLevels = 1; + srvDesc.Texture2DArray.FirstArraySlice = mSubresourceIndex; + srvDesc.Texture2DArray.ArraySize = 1; + + ANGLE_TRY( + mRenderer->allocateResource(GetImplAs(context), srvDesc, texture.get(), outSRV)); + outSRV->setLabels("TexStorage2D.SRV", &mKHRDebugLabel); + + return angle::Result::Continue; +} + +angle::Result TextureStorage11_External::createSRVForImage(const gl::Context *context, + int level, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result TextureStorage11_External::createUAVForImage(const gl::Context *context, + int level, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedUAV *outUAV) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result TextureStorage11_External::getSwizzleTexture(const gl::Context *context, + const TextureHelper11 **outTexture) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result TextureStorage11_External::getSwizzleRenderTarget( + const gl::Context *context, + int mipLevel, + const d3d11::RenderTargetView **outRTV) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +void TextureStorage11_External::onLabelUpdate() +{ + if (mTexture.valid()) + { + mTexture.setKHRDebugLabel(&mKHRDebugLabel); + } +} + +TextureStorage11ImmutableBase::TextureStorage11ImmutableBase(Renderer11 *renderer, + UINT bindFlags, + UINT miscFlags, + GLenum internalFormat, + const std::string &label) + : TextureStorage11(renderer, bindFlags, miscFlags, internalFormat, label) +{} + +void TextureStorage11ImmutableBase::associateImage(Image11 *, const gl::ImageIndex &) {} + +void TextureStorage11ImmutableBase::disassociateImage(const gl::ImageIndex &, Image11 *) {} + +void TextureStorage11ImmutableBase::verifyAssociatedImageValid(const gl::ImageIndex &, Image11 *) {} + +angle::Result TextureStorage11ImmutableBase::releaseAssociatedImage(const gl::Context *context, + const gl::ImageIndex &, + Image11 *) +{ + return angle::Result::Continue; +} + +angle::Result TextureStorage11ImmutableBase::createSRVForImage(const gl::Context *context, + int level, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result TextureStorage11ImmutableBase::createUAVForImage(const gl::Context *context, + int level, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedUAV *outUAV) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +TextureStorage11_EGLImage::TextureStorage11_EGLImage(Renderer11 *renderer, + EGLImageD3D *eglImage, + RenderTarget11 *renderTarget11, + const std::string &label) + : TextureStorage11ImmutableBase(renderer, + D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE, + 0, + renderTarget11->getInternalFormat(), + label), + mImage(eglImage), + mCurrentRenderTarget(0), + mSwizzleTexture(), + mSwizzleRenderTargets(gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) +{ + mCurrentRenderTarget = reinterpret_cast(renderTarget11); + + mMipLevels = 1; + mTextureWidth = renderTarget11->getWidth(); + mTextureHeight = renderTarget11->getHeight(); + mTextureDepth = 1; +} + +TextureStorage11_EGLImage::~TextureStorage11_EGLImage() {} + +angle::Result TextureStorage11_EGLImage::getSubresourceIndex(const gl::Context *context, + const gl::ImageIndex &index, + UINT *outSubresourceIndex) const +{ + ASSERT(index.getType() == gl::TextureType::_2D); + ASSERT(index.getLevelIndex() == 0); + + RenderTarget11 *renderTarget11 = nullptr; + ANGLE_TRY(getImageRenderTarget(context, &renderTarget11)); + *outSubresourceIndex = renderTarget11->getSubresourceIndex(); + return angle::Result::Continue; +} + +angle::Result TextureStorage11_EGLImage::getResource(const gl::Context *context, + const TextureHelper11 **outResource) +{ + ANGLE_TRY(checkForUpdatedRenderTarget(context)); + + RenderTarget11 *renderTarget11 = nullptr; + ANGLE_TRY(getImageRenderTarget(context, &renderTarget11)); + *outResource = &renderTarget11->getTexture(); + return angle::Result::Continue; +} + +angle::Result TextureStorage11_EGLImage::getSRVForSampler(const gl::Context *context, + const gl::TextureState &textureState, + const gl::SamplerState &sampler, + const d3d11::SharedSRV **outSRV) +{ + ANGLE_TRY(checkForUpdatedRenderTarget(context)); + return TextureStorage11::getSRVForSampler(context, textureState, sampler, outSRV); +} + +angle::Result TextureStorage11_EGLImage::getMippedResource(const gl::Context *context, + const TextureHelper11 **) +{ + // This shouldn't be called unless the zero max LOD workaround is active. + // EGL images are unavailable in this configuration. + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result TextureStorage11_EGLImage::findRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) const +{ + // Since the render target of an EGL image will be updated when orphaning, trying to find a + // cache of it can be rarely useful. + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result TextureStorage11_EGLImage::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) +{ + ASSERT(!index.hasLayer()); + ASSERT(index.getLevelIndex() == 0); + + ANGLE_TRY(checkForUpdatedRenderTarget(context)); + + return mImage->getRenderTarget(context, outRT); +} + +angle::Result TextureStorage11_EGLImage::copyToStorage(const gl::Context *context, + TextureStorage *destStorage) +{ + const TextureHelper11 *sourceResouce = nullptr; + ANGLE_TRY(getResource(context, &sourceResouce)); + + ASSERT(destStorage); + TextureStorage11_2D *dest11 = GetAs(destStorage); + const TextureHelper11 *destResource = nullptr; + ANGLE_TRY(dest11->getResource(context, &destResource)); + + ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); + immediateContext->CopyResource(destResource->get(), sourceResouce->get()); + + dest11->markDirty(); + + return angle::Result::Continue; +} + +angle::Result TextureStorage11_EGLImage::useLevelZeroWorkaroundTexture(const gl::Context *context, + bool) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result TextureStorage11_EGLImage::getSwizzleTexture(const gl::Context *context, + const TextureHelper11 **outTexture) +{ + ASSERT(outTexture); + + if (!mSwizzleTexture.valid()) + { + const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()); + + D3D11_TEXTURE2D_DESC desc; + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.MipLevels = mMipLevels; + desc.ArraySize = 1; + desc.Format = format.texFormat; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + ANGLE_TRY(mRenderer->allocateTexture(GetImplAs(context), desc, format, + &mSwizzleTexture)); + mSwizzleTexture.setLabels("TexStorageEGLImage.SwizzleTexture", &mKHRDebugLabel); + } + + *outTexture = &mSwizzleTexture; + return angle::Result::Continue; +} + +angle::Result TextureStorage11_EGLImage::getSwizzleRenderTarget( + const gl::Context *context, + int mipLevel, + const d3d11::RenderTargetView **outRTV) +{ + ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); + ASSERT(outRTV); + + if (!mSwizzleRenderTargets[mipLevel].valid()) + { + const TextureHelper11 *swizzleTexture = nullptr; + ANGLE_TRY(getSwizzleTexture(context, &swizzleTexture)); + + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = + mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel; + + ANGLE_TRY(mRenderer->allocateResource(GetImplAs(context), rtvDesc, + mSwizzleTexture.get(), + &mSwizzleRenderTargets[mipLevel])); + } + + *outRTV = &mSwizzleRenderTargets[mipLevel]; + return angle::Result::Continue; +} + +angle::Result TextureStorage11_EGLImage::checkForUpdatedRenderTarget(const gl::Context *context) +{ + RenderTarget11 *renderTarget11 = nullptr; + ANGLE_TRY(getImageRenderTarget(context, &renderTarget11)); + + if (mCurrentRenderTarget != reinterpret_cast(renderTarget11)) + { + clearSRVCache(); + mCurrentRenderTarget = reinterpret_cast(renderTarget11); + } + + return angle::Result::Continue; +} + +angle::Result TextureStorage11_EGLImage::createSRVForSampler(const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) +{ + ASSERT(baseLevel == 0); + ASSERT(mipLevels == 1); + ASSERT(outSRV); + + // Create a new SRV only for the swizzle texture. Otherwise just return the Image's + // RenderTarget's SRV. + if (texture == mSwizzleTexture) + { + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = format; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel; + srvDesc.Texture2D.MipLevels = mipLevels; + + ANGLE_TRY(mRenderer->allocateResource(GetImplAs(context), srvDesc, texture.get(), + outSRV)); + outSRV->setLabels("TexStorageEGLImage.SRV", &mKHRDebugLabel); + } + else + { + RenderTarget11 *renderTarget = nullptr; + ANGLE_TRY(getImageRenderTarget(context, &renderTarget)); + + ASSERT(texture == renderTarget->getTexture()); + + const d3d11::SharedSRV *srv; + ANGLE_TRY(renderTarget->getShaderResourceView(context, &srv)); + + *outSRV = srv->makeCopy(); + } + + return angle::Result::Continue; +} + +angle::Result TextureStorage11_EGLImage::getImageRenderTarget(const gl::Context *context, + RenderTarget11 **outRT) const +{ + RenderTargetD3D *renderTargetD3D = nullptr; + ANGLE_TRY(mImage->getRenderTarget(context, &renderTargetD3D)); + *outRT = GetAs(renderTargetD3D); + return angle::Result::Continue; +} + +void TextureStorage11_EGLImage::onLabelUpdate() +{ + if (mSwizzleTexture.valid()) + { + mSwizzleTexture.setKHRDebugLabel(&mKHRDebugLabel); + } +} + +TextureStorage11_Cube::TextureStorage11_Cube(Renderer11 *renderer, + GLenum internalformat, + BindFlags bindFlags, + int size, + int levels, + bool hintLevelZeroOnly, + const std::string &label) + : TextureStorage11( + renderer, + GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), bindFlags), + GetTextureMiscFlags(internalformat, + renderer->getRenderer11DeviceCaps(), + bindFlags, + levels), + internalformat, + label), + mTexture(), + mLevelZeroTexture(), + mUseLevelZeroTexture(hintLevelZeroOnly && levels > 1), + mSwizzleTexture() +{ + for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) + { + for (unsigned int face = 0; face < gl::kCubeFaceCount; face++) + { + mAssociatedImages[face][level] = nullptr; + mRenderTarget[face][level] = nullptr; + } + } + + for (unsigned int face = 0; face < gl::kCubeFaceCount; face++) + { + mLevelZeroRenderTarget[face] = nullptr; + } + + // adjust size if needed for compressed textures + int height = size; + d3d11::MakeValidSize(false, mFormatInfo.texFormat, &size, &height, &mTopLevel); + + mMipLevels = mTopLevel + levels; + mTextureWidth = size; + mTextureHeight = size; + mTextureDepth = 1; + + // The LevelZeroOnly hint should only be true if the zero max LOD workaround is active. + ASSERT(!mUseLevelZeroTexture || mRenderer->getFeatures().zeroMaxLodWorkaround.enabled); +} + +angle::Result TextureStorage11_Cube::onDestroy(const gl::Context *context) +{ + for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) + { + for (unsigned int face = 0; face < gl::kCubeFaceCount; face++) + { + if (mAssociatedImages[face][level] != nullptr) + { + mAssociatedImages[face][level]->verifyAssociatedStorageValid(this); + + // We must let the Images recover their data before we delete it from the + // TextureStorage. + ANGLE_TRY(mAssociatedImages[face][level]->recoverFromAssociatedStorage(context)); + } + } + } + + return angle::Result::Continue; +} + +TextureStorage11_Cube::~TextureStorage11_Cube() {} + +angle::Result TextureStorage11_Cube::getSubresourceIndex(const gl::Context *context, + const gl::ImageIndex &index, + UINT *outSubresourceIndex) const +{ + UINT arraySlice = index.cubeMapFaceIndex(); + if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled && mUseLevelZeroTexture && + index.getLevelIndex() == 0) + { + UINT subresource = D3D11CalcSubresource(0, arraySlice, 1); + ASSERT(subresource != std::numeric_limits::max()); + *outSubresourceIndex = subresource; + } + else + { + UINT mipSlice = static_cast(index.getLevelIndex() + mTopLevel); + UINT subresource = D3D11CalcSubresource(mipSlice, arraySlice, mMipLevels); + ASSERT(subresource != std::numeric_limits::max()); + *outSubresourceIndex = subresource; + } + return angle::Result::Continue; +} + +angle::Result TextureStorage11_Cube::copyToStorage(const gl::Context *context, + TextureStorage *destStorage) +{ + ASSERT(destStorage); + + TextureStorage11_Cube *dest11 = GetAs(destStorage); + + if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled) + { + ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); + + // If either mTexture or mLevelZeroTexture exist, then we need to copy them into the + // corresponding textures in destStorage. + if (mTexture.valid()) + { + ANGLE_TRY(dest11->useLevelZeroWorkaroundTexture(context, false)); + + const TextureHelper11 *destResource = nullptr; + ANGLE_TRY(dest11->getResource(context, &destResource)); + + immediateContext->CopyResource(destResource->get(), mTexture.get()); + } + + if (mLevelZeroTexture.valid()) + { + ANGLE_TRY(dest11->useLevelZeroWorkaroundTexture(context, true)); + + const TextureHelper11 *destResource = nullptr; + ANGLE_TRY(dest11->getResource(context, &destResource)); + + immediateContext->CopyResource(destResource->get(), mLevelZeroTexture.get()); + } + } + else + { + const TextureHelper11 *sourceResouce = nullptr; + ANGLE_TRY(getResource(context, &sourceResouce)); + + const TextureHelper11 *destResource = nullptr; + ANGLE_TRY(dest11->getResource(context, &destResource)); + + ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); + immediateContext->CopyResource(destResource->get(), sourceResouce->get()); + } + + dest11->markDirty(); + + return angle::Result::Continue; +} + +angle::Result TextureStorage11_Cube::useLevelZeroWorkaroundTexture(const gl::Context *context, + bool useLevelZeroTexture) +{ + if (useLevelZeroTexture && mMipLevels > 1) + { + if (!mUseLevelZeroTexture && mTexture.valid()) + { + ANGLE_TRY(ensureTextureExists(context, 1)); + + // Pull data back from the mipped texture if necessary. + ASSERT(mLevelZeroTexture.valid()); + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + for (int face = 0; face < 6; face++) + { + deviceContext->CopySubresourceRegion(mLevelZeroTexture.get(), + D3D11CalcSubresource(0, face, 1), 0, 0, 0, + mTexture.get(), face * mMipLevels, nullptr); + } + } + + mUseLevelZeroTexture = true; + } + else + { + if (mUseLevelZeroTexture && mLevelZeroTexture.valid()) + { + ANGLE_TRY(ensureTextureExists(context, mMipLevels)); + + // Pull data back from the level zero texture if necessary. + ASSERT(mTexture.valid()); + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + for (int face = 0; face < 6; face++) + { + deviceContext->CopySubresourceRegion(mTexture.get(), + D3D11CalcSubresource(0, face, mMipLevels), 0, + 0, 0, mLevelZeroTexture.get(), face, nullptr); + } + } + + mUseLevelZeroTexture = false; + } + + return angle::Result::Continue; +} + +void TextureStorage11_Cube::associateImage(Image11 *image, const gl::ImageIndex &index) +{ + const GLint level = index.getLevelIndex(); + const GLint layerTarget = index.cubeMapFaceIndex(); + + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + ASSERT(0 <= layerTarget && layerTarget < static_cast(gl::kCubeFaceCount)); + + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + if (0 <= layerTarget && layerTarget < static_cast(gl::kCubeFaceCount)) + { + mAssociatedImages[layerTarget][level] = image; + } + } +} + +void TextureStorage11_Cube::verifyAssociatedImageValid(const gl::ImageIndex &index, + Image11 *expectedImage) +{ + const GLint level = index.getLevelIndex(); + const GLint layerTarget = index.cubeMapFaceIndex(); + + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + ASSERT(0 <= layerTarget && layerTarget < static_cast(gl::kCubeFaceCount)); + // This validation check should never return false. It means the Image/TextureStorage + // association is broken. + ASSERT(mAssociatedImages[layerTarget][level] == expectedImage); +} + +// disassociateImage allows an Image to end its association with a Storage. +void TextureStorage11_Cube::disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) +{ + const GLint level = index.getLevelIndex(); + const GLint layerTarget = index.cubeMapFaceIndex(); + + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + ASSERT(0 <= layerTarget && layerTarget < static_cast(gl::kCubeFaceCount)); + ASSERT(mAssociatedImages[layerTarget][level] == expectedImage); + mAssociatedImages[layerTarget][level] = nullptr; +} + +// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image +// recover its data before ending the association. +angle::Result TextureStorage11_Cube::releaseAssociatedImage(const gl::Context *context, + const gl::ImageIndex &index, + Image11 *incomingImage) +{ + const GLint level = index.getLevelIndex(); + const GLint layerTarget = index.cubeMapFaceIndex(); + + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + ASSERT(0 <= layerTarget && layerTarget < static_cast(gl::kCubeFaceCount)); + + if ((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)) + { + if (0 <= layerTarget && layerTarget < static_cast(gl::kCubeFaceCount)) + { + // No need to let the old Image recover its data, if it is also the incoming Image. + if (mAssociatedImages[layerTarget][level] != nullptr && + mAssociatedImages[layerTarget][level] != incomingImage) + { + // Ensure that the Image is still associated with this TextureStorage. + mAssociatedImages[layerTarget][level]->verifyAssociatedStorageValid(this); + + // Force the image to recover from storage before its data is overwritten. + // This will reset mAssociatedImages[level] to nullptr too. + ANGLE_TRY( + mAssociatedImages[layerTarget][level]->recoverFromAssociatedStorage(context)); + } + } + } + + return angle::Result::Continue; +} + +angle::Result TextureStorage11_Cube::getResource(const gl::Context *context, + const TextureHelper11 **outResource) +{ + if (mUseLevelZeroTexture && mMipLevels > 1) + { + ANGLE_TRY(ensureTextureExists(context, 1)); + *outResource = &mLevelZeroTexture; + } + else + { + ANGLE_TRY(ensureTextureExists(context, mMipLevels)); + *outResource = &mTexture; + } + return angle::Result::Continue; +} + +angle::Result TextureStorage11_Cube::getMippedResource(const gl::Context *context, + const TextureHelper11 **outResource) +{ + // This shouldn't be called unless the zero max LOD workaround is active. + ASSERT(mRenderer->getFeatures().zeroMaxLodWorkaround.enabled); + + ANGLE_TRY(ensureTextureExists(context, mMipLevels)); + *outResource = &mTexture; + return angle::Result::Continue; +} + +angle::Result TextureStorage11_Cube::ensureTextureExists(const gl::Context *context, int mipLevels) +{ + // If mMipLevels = 1 then always use mTexture rather than mLevelZeroTexture. + ANGLE_TRY(resolveTexture(context)); + bool useLevelZeroTexture = mRenderer->getFeatures().zeroMaxLodWorkaround.enabled + ? (mipLevels == 1) && (mMipLevels > 1) + : false; + TextureHelper11 *outputTexture = useLevelZeroTexture ? &mLevelZeroTexture : &mTexture; + + // if the size is not positive this should be treated as an incomplete texture + // we handle that here by skipping the d3d texture creation + if (!outputTexture->valid() && mTextureWidth > 0 && mTextureHeight > 0) + { + ASSERT(mMipLevels > 0); + + D3D11_TEXTURE2D_DESC desc; + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.MipLevels = mipLevels; + desc.ArraySize = gl::kCubeFaceCount; + desc.Format = isUnorderedAccess() ? mFormatInfo.typelessFormat : mFormatInfo.texFormat; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = getBindFlags(); + desc.CPUAccessFlags = 0; + desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE | getMiscFlags(); + + ANGLE_TRY(mRenderer->allocateTexture(GetImplAs(context), desc, mFormatInfo, + outputTexture)); + outputTexture->setLabels("TexStorageCube.Texture", &mKHRDebugLabel); + } + + return angle::Result::Continue; +} + +angle::Result TextureStorage11_Cube::findRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) const +{ + const int faceIndex = index.cubeMapFaceIndex(); + const int level = index.getLevelIndex(); + + ASSERT(level >= 0 && level < getLevelCount()); + ASSERT(faceIndex >= 0 && faceIndex < static_cast(gl::kCubeFaceCount)); + + bool needMS = samples > 0; + if (needMS) + { + return findMultisampledRenderTarget(context, index, samples, outRT); + } + + if (!mRenderTarget[faceIndex][level]) + { + if (mUseLevelZeroTexture) + { + ASSERT(index.getLevelIndex() == 0); + ASSERT(outRT); + *outRT = mLevelZeroRenderTarget[faceIndex].get(); + return angle::Result::Continue; + } + } + + ASSERT(outRT); + *outRT = mRenderTarget[faceIndex][level].get(); + return angle::Result::Continue; +} + +angle::Result TextureStorage11_Cube::createRenderTargetSRV(const gl::Context *context, + const TextureHelper11 &texture, + const gl::ImageIndex &index, + DXGI_FORMAT resourceFormat, + d3d11::SharedSRV *srv) const +{ + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = resourceFormat; + srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + index.getLevelIndex(); + srvDesc.Texture2DArray.MipLevels = 1; + srvDesc.Texture2DArray.FirstArraySlice = index.cubeMapFaceIndex(); + srvDesc.Texture2DArray.ArraySize = 1; + + if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_10_0) + { + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; + } + else + { + // Will be used with Texture2D sampler, not TextureCube + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + } + + ANGLE_TRY( + mRenderer->allocateResource(GetImplAs(context), srvDesc, texture.get(), srv)); + return angle::Result::Continue; +} + +angle::Result TextureStorage11_Cube::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) +{ + const int faceIndex = index.cubeMapFaceIndex(); + const int level = index.getLevelIndex(); + + ASSERT(level >= 0 && level < getLevelCount()); + ASSERT(faceIndex >= 0 && faceIndex < static_cast(gl::kCubeFaceCount)); + + bool needMS = samples > 0; + if (needMS) + { + return getMultisampledRenderTarget(context, index, samples, outRT); + } + else + { + ANGLE_TRY(resolveTexture(context)); + } + + Context11 *context11 = GetImplAs(context); + + if (!mRenderTarget[faceIndex][level]) + { + if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled) + { + ASSERT(index.getLevelIndex() == 0); + ANGLE_TRY(useLevelZeroWorkaroundTexture(context, true)); + } + + const TextureHelper11 *texture = nullptr; + ANGLE_TRY(getResource(context, &texture)); + + if (mUseLevelZeroTexture) + { + if (!mLevelZeroRenderTarget[faceIndex]) + { + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mFormatInfo.rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = mTopLevel + level; + rtvDesc.Texture2DArray.FirstArraySlice = faceIndex; + rtvDesc.Texture2DArray.ArraySize = 1; + + d3d11::RenderTargetView rtv; + ANGLE_TRY( + mRenderer->allocateResource(context11, rtvDesc, mLevelZeroTexture.get(), &rtv)); + + mLevelZeroRenderTarget[faceIndex].reset(new TextureRenderTarget11( + std::move(rtv), mLevelZeroTexture, d3d11::SharedSRV(), d3d11::SharedSRV(), + mFormatInfo.internalFormat, getFormatSet(), getLevelWidth(level), + getLevelHeight(level), 1, 0)); + } + + ASSERT(outRT); + *outRT = mLevelZeroRenderTarget[faceIndex].get(); + return angle::Result::Continue; + } + + d3d11::SharedSRV srv; + ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.srvFormat, &srv)); + d3d11::SharedSRV blitSRV; + if (mFormatInfo.blitSRVFormat != mFormatInfo.srvFormat) + { + ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.blitSRVFormat, + &blitSRV)); + } + else + { + blitSRV = srv.makeCopy(); + } + + srv.setLabels("TexStorageCube.RenderTargetSRV", &mKHRDebugLabel); + + if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN) + { + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mFormatInfo.rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = mTopLevel + level; + rtvDesc.Texture2DArray.FirstArraySlice = faceIndex; + rtvDesc.Texture2DArray.ArraySize = 1; + + d3d11::RenderTargetView rtv; + ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, texture->get(), &rtv)); + rtv.setLabels("TexStorageCube.RenderTargetRTV", &mKHRDebugLabel); + + mRenderTarget[faceIndex][level].reset(new TextureRenderTarget11( + std::move(rtv), *texture, srv, blitSRV, mFormatInfo.internalFormat, getFormatSet(), + getLevelWidth(level), getLevelHeight(level), 1, 0)); + } + else if (mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN) + { + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsvDesc.Format = mFormatInfo.dsvFormat; + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; + dsvDesc.Flags = 0; + dsvDesc.Texture2DArray.MipSlice = mTopLevel + level; + dsvDesc.Texture2DArray.FirstArraySlice = faceIndex; + dsvDesc.Texture2DArray.ArraySize = 1; + + d3d11::DepthStencilView dsv; + ANGLE_TRY(mRenderer->allocateResource(context11, dsvDesc, texture->get(), &dsv)); + dsv.setLabels("TexStorageCube.RenderTargetDSV", &mKHRDebugLabel); + + mRenderTarget[faceIndex][level].reset(new TextureRenderTarget11( + std::move(dsv), *texture, srv, mFormatInfo.internalFormat, getFormatSet(), + getLevelWidth(level), getLevelHeight(level), 1, 0)); + } + else + { + UNREACHABLE(); + } + } + + ASSERT(outRT); + *outRT = mRenderTarget[faceIndex][level].get(); + return angle::Result::Continue; +} + +angle::Result TextureStorage11_Cube::createSRVForSampler(const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) +{ + ASSERT(outSRV); + + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = format; + + // Unnormalized integer cube maps are not supported by DX11; we emulate them as an array of six + // 2D textures + const GLenum componentType = d3d11::GetComponentType(format); + if (componentType == GL_INT || componentType == GL_UNSIGNED_INT) + { + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel; + srvDesc.Texture2DArray.MipLevels = mipLevels; + srvDesc.Texture2DArray.FirstArraySlice = 0; + srvDesc.Texture2DArray.ArraySize = gl::kCubeFaceCount; + } + else + { + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; + srvDesc.TextureCube.MipLevels = mipLevels; + srvDesc.TextureCube.MostDetailedMip = mTopLevel + baseLevel; + } + + const TextureHelper11 *srvTexture = &texture; + + if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled) + { + ASSERT(mTopLevel == 0); + ASSERT(baseLevel == 0); + // This code also assumes that the incoming texture equals either mLevelZeroTexture or + // mTexture. + + if (mipLevels == 1 && mMipLevels > 1) + { + // We must use a SRV on the level-zero-only texture. + ANGLE_TRY(ensureTextureExists(context, 1)); + srvTexture = &mLevelZeroTexture; + } + else + { + ASSERT(mipLevels == static_cast(mMipLevels)); + ASSERT(mTexture.valid() && texture == mTexture); + srvTexture = &mTexture; + } + } + + ANGLE_TRY(mRenderer->allocateResource(GetImplAs(context), srvDesc, srvTexture->get(), + outSRV)); + outSRV->setLabels("TexStorageCube.SRV", &mKHRDebugLabel); + + return angle::Result::Continue; +} + +angle::Result TextureStorage11_Cube::createSRVForImage(const gl::Context *context, + int level, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) +{ + ASSERT(outSRV); + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = format; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level; + srvDesc.Texture2DArray.MipLevels = 1; + srvDesc.Texture2DArray.FirstArraySlice = 0; + srvDesc.Texture2DArray.ArraySize = gl::kCubeFaceCount; + ANGLE_TRY( + mRenderer->allocateResource(GetImplAs(context), srvDesc, texture.get(), outSRV)); + outSRV->setLabels("TexStorageCube.SRVForImage", &mKHRDebugLabel); + return angle::Result::Continue; +} + +angle::Result TextureStorage11_Cube::createUAVForImage(const gl::Context *context, + int level, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedUAV *outUAV) +{ + ASSERT(outUAV); + D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc; + uavDesc.Format = format; + uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY; + uavDesc.Texture2DArray.MipSlice = mTopLevel + level; + uavDesc.Texture2DArray.FirstArraySlice = 0; + uavDesc.Texture2DArray.ArraySize = gl::kCubeFaceCount; + ANGLE_TRY( + mRenderer->allocateResource(GetImplAs(context), uavDesc, texture.get(), outUAV)); + outUAV->setLabels("TexStorageCube.UAVForImage", &mKHRDebugLabel); + return angle::Result::Continue; +} + +angle::Result TextureStorage11_Cube::getSwizzleTexture(const gl::Context *context, + const TextureHelper11 **outTexture) +{ + ASSERT(outTexture); + + if (!mSwizzleTexture.valid()) + { + const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()); + + D3D11_TEXTURE2D_DESC desc; + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.MipLevels = mMipLevels; + desc.ArraySize = gl::kCubeFaceCount; + desc.Format = format.texFormat; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + desc.CPUAccessFlags = 0; + desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE; + + ANGLE_TRY(mRenderer->allocateTexture(GetImplAs(context), desc, format, + &mSwizzleTexture)); + mSwizzleTexture.setLabels("TexStorageCube.SwizzleTexture", &mKHRDebugLabel); + } + + *outTexture = &mSwizzleTexture; + return angle::Result::Continue; +} + +angle::Result TextureStorage11_Cube::getSwizzleRenderTarget(const gl::Context *context, + int mipLevel, + const d3d11::RenderTargetView **outRTV) +{ + ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); + ASSERT(outRTV); + + if (!mSwizzleRenderTargets[mipLevel].valid()) + { + const TextureHelper11 *swizzleTexture = nullptr; + ANGLE_TRY(getSwizzleTexture(context, &swizzleTexture)); + + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = + mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; + rtvDesc.Texture2DArray.FirstArraySlice = 0; + rtvDesc.Texture2DArray.ArraySize = gl::kCubeFaceCount; + + ANGLE_TRY(mRenderer->allocateResource(GetImplAs(context), rtvDesc, + mSwizzleTexture.get(), + &mSwizzleRenderTargets[mipLevel])); + } + + *outRTV = &mSwizzleRenderTargets[mipLevel]; + return angle::Result::Continue; +} + +angle::Result TextureStorage11_Cube::ensureDropStencilTexture(const gl::Context *context, + DropStencil *dropStencilOut) +{ + if (mDropStencilTexture.valid()) + { + *dropStencilOut = DropStencil::ALREADY_EXISTS; + return angle::Result::Continue; + } + + D3D11_TEXTURE2D_DESC dropDesc = {}; + dropDesc.ArraySize = 6; + dropDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DEPTH_STENCIL; + dropDesc.CPUAccessFlags = 0; + dropDesc.Format = DXGI_FORMAT_R32_TYPELESS; + dropDesc.Height = mTextureHeight; + dropDesc.MipLevels = mMipLevels; + dropDesc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE; + dropDesc.SampleDesc.Count = 1; + dropDesc.SampleDesc.Quality = 0; + dropDesc.Usage = D3D11_USAGE_DEFAULT; + dropDesc.Width = mTextureWidth; + + const auto &format = + d3d11::Format::Get(GL_DEPTH_COMPONENT32F, mRenderer->getRenderer11DeviceCaps()); + ANGLE_TRY(mRenderer->allocateTexture(GetImplAs(context), dropDesc, format, + &mDropStencilTexture)); + mDropStencilTexture.setLabels("TexStorageCube.DropStencil", &mKHRDebugLabel); + + ANGLE_TRY(initDropStencilTexture(context, gl::ImageIndexIterator::MakeCube(0, mMipLevels))); + + *dropStencilOut = DropStencil::CREATED; + return angle::Result::Continue; +} + +angle::Result TextureStorage11_Cube::resolveTexture(const gl::Context *context) +{ + if (mMSTexInfo && mMSTexInfo->msTex && mMSTexInfo->msTextureNeedsResolve) + { + ANGLE_TRY(resolveTextureHelper(context, mTexture)); + onStateChange(angle::SubjectMessage::ContentsChanged); + } + return angle::Result::Continue; +} + +void TextureStorage11_Cube::onLabelUpdate() +{ + if (mTexture.valid()) + { + mTexture.setKHRDebugLabel(&mKHRDebugLabel); + } + if (mLevelZeroTexture.valid()) + { + mLevelZeroTexture.setKHRDebugLabel(&mKHRDebugLabel); + } + if (mSwizzleTexture.valid()) + { + mSwizzleTexture.setKHRDebugLabel(&mKHRDebugLabel); + } +} + +TextureStorage11_3D::TextureStorage11_3D(Renderer11 *renderer, + GLenum internalformat, + BindFlags bindFlags, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels, + const std::string &label) + : TextureStorage11( + renderer, + GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), bindFlags), + GetTextureMiscFlags(internalformat, + renderer->getRenderer11DeviceCaps(), + bindFlags, + levels), + internalformat, + label) +{ + for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) + { + mAssociatedImages[i] = nullptr; + mLevelRenderTargets[i] = nullptr; + } + + // adjust size if needed for compressed textures + d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, &mTopLevel); + + mMipLevels = mTopLevel + levels; + mTextureWidth = width; + mTextureHeight = height; + mTextureDepth = depth; +} + +angle::Result TextureStorage11_3D::onDestroy(const gl::Context *context) +{ + for (unsigned i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) + { + if (mAssociatedImages[i] != nullptr) + { + mAssociatedImages[i]->verifyAssociatedStorageValid(this); + + // We must let the Images recover their data before we delete it from the + // TextureStorage. + ANGLE_TRY(mAssociatedImages[i]->recoverFromAssociatedStorage(context)); + } + } + + return angle::Result::Continue; +} + +TextureStorage11_3D::~TextureStorage11_3D() {} + +void TextureStorage11_3D::associateImage(Image11 *image, const gl::ImageIndex &index) +{ + const GLint level = index.getLevelIndex(); + + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + mAssociatedImages[level] = image; + } +} + +void TextureStorage11_3D::verifyAssociatedImageValid(const gl::ImageIndex &index, + Image11 *expectedImage) +{ + const GLint level = index.getLevelIndex(); + + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + // This validation check should never return false. It means the Image/TextureStorage + // association is broken. + ASSERT(mAssociatedImages[level] == expectedImage); +} + +// disassociateImage allows an Image to end its association with a Storage. +void TextureStorage11_3D::disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) +{ + const GLint level = index.getLevelIndex(); + + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + ASSERT(mAssociatedImages[level] == expectedImage); + mAssociatedImages[level] = nullptr; +} + +// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image +// recover its data before ending the association. +angle::Result TextureStorage11_3D::releaseAssociatedImage(const gl::Context *context, + const gl::ImageIndex &index, + Image11 *incomingImage) +{ + const GLint level = index.getLevelIndex(); + + ASSERT((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)); + + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + // No need to let the old Image recover its data, if it is also the incoming Image. + if (mAssociatedImages[level] != nullptr && mAssociatedImages[level] != incomingImage) + { + // Ensure that the Image is still associated with this TextureStorage. + mAssociatedImages[level]->verifyAssociatedStorageValid(this); + + // Force the image to recover from storage before its data is overwritten. + // This will reset mAssociatedImages[level] to nullptr too. + ANGLE_TRY(mAssociatedImages[level]->recoverFromAssociatedStorage(context)); + } + } + + return angle::Result::Continue; +} + +angle::Result TextureStorage11_3D::getResource(const gl::Context *context, + const TextureHelper11 **outResource) +{ + // If the width, height or depth are not positive this should be treated as an incomplete + // texture. We handle that here by skipping the d3d texture creation. + if (!mTexture.valid() && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0) + { + ASSERT(mMipLevels > 0); + + D3D11_TEXTURE3D_DESC desc; + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.Depth = mTextureDepth; + desc.MipLevels = mMipLevels; + desc.Format = isUnorderedAccess() ? mFormatInfo.typelessFormat : mFormatInfo.texFormat; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = getBindFlags(); + desc.CPUAccessFlags = 0; + desc.MiscFlags = getMiscFlags(); + + ANGLE_TRY(mRenderer->allocateTexture(GetImplAs(context), desc, mFormatInfo, + &mTexture)); + mTexture.setLabels("TexStorage3D.Texture", &mKHRDebugLabel); + } + + *outResource = &mTexture; + return angle::Result::Continue; +} + +angle::Result TextureStorage11_3D::createSRVForSampler(const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) +{ + ASSERT(outSRV); + + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = format; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; + srvDesc.Texture3D.MostDetailedMip = baseLevel; + srvDesc.Texture3D.MipLevels = mipLevels; + + ANGLE_TRY( + mRenderer->allocateResource(GetImplAs(context), srvDesc, texture.get(), outSRV)); + outSRV->setLabels("TexStorage3D.SRV", &mKHRDebugLabel); + + return angle::Result::Continue; +} + +angle::Result TextureStorage11_3D::createSRVForImage(const gl::Context *context, + int level, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) +{ + ASSERT(outSRV); + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = format; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; + srvDesc.Texture3D.MostDetailedMip = mTopLevel + level; + srvDesc.Texture3D.MipLevels = 1; + ANGLE_TRY( + mRenderer->allocateResource(GetImplAs(context), srvDesc, texture.get(), outSRV)); + outSRV->setLabels("TexStorage3D.SRVForImage", &mKHRDebugLabel); + return angle::Result::Continue; +} + +angle::Result TextureStorage11_3D::createUAVForImage(const gl::Context *context, + int level, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedUAV *outUAV) +{ + ASSERT(outUAV); + D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc; + uavDesc.Format = format; + uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D; + uavDesc.Texture3D.MipSlice = mTopLevel + level; + uavDesc.Texture3D.FirstWSlice = 0; + uavDesc.Texture3D.WSize = mTextureDepth; + ANGLE_TRY( + mRenderer->allocateResource(GetImplAs(context), uavDesc, texture.get(), outUAV)); + outUAV->setLabels("TexStorage3D.UAVForImage", &mKHRDebugLabel); + return angle::Result::Continue; +} + +angle::Result TextureStorage11_3D::findRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) const +{ + const int mipLevel = index.getLevelIndex(); + ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); + + if (!index.hasLayer()) + { + ASSERT(outRT); + *outRT = mLevelRenderTargets[mipLevel].get(); + return angle::Result::Continue; + } + + const int layer = index.getLayerIndex(); + + LevelLayerKey key(mipLevel, layer); + if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end()) + { + ASSERT(outRT); + *outRT = nullptr; + return angle::Result::Continue; + } + + ASSERT(outRT); + *outRT = mLevelLayerRenderTargets.at(key).get(); + return angle::Result::Continue; +} + +angle::Result TextureStorage11_3D::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) +{ + const int mipLevel = index.getLevelIndex(); + ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); + + ASSERT(mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN); + + Context11 *context11 = GetImplAs(context); + + if (!index.hasLayer()) + { + if (!mLevelRenderTargets[mipLevel]) + { + const TextureHelper11 *texture = nullptr; + ANGLE_TRY(getResource(context, &texture)); + + const d3d11::SharedSRV *srv = nullptr; + ANGLE_TRY(getSRVLevel(context, mipLevel, SRVType::Sample, &srv)); + + const d3d11::SharedSRV *blitSRV = nullptr; + ANGLE_TRY(getSRVLevel(context, mipLevel, SRVType::Blit, &blitSRV)); + + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mFormatInfo.rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; + rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; + rtvDesc.Texture3D.FirstWSlice = 0; + rtvDesc.Texture3D.WSize = static_cast(-1); + + d3d11::RenderTargetView rtv; + ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, texture->get(), &rtv)); + rtv.setLabels("TexStorage3D.RTV", &mKHRDebugLabel); + + mLevelRenderTargets[mipLevel].reset(new TextureRenderTarget11( + std::move(rtv), *texture, *srv, *blitSRV, mFormatInfo.internalFormat, + getFormatSet(), getLevelWidth(mipLevel), getLevelHeight(mipLevel), + getLevelDepth(mipLevel), 0)); + } + + ASSERT(outRT); + *outRT = mLevelRenderTargets[mipLevel].get(); + return angle::Result::Continue; + } + + const int layer = index.getLayerIndex(); + + LevelLayerKey key(mipLevel, layer); + if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end()) + { + const TextureHelper11 *texture = nullptr; + ANGLE_TRY(getResource(context, &texture)); + + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mFormatInfo.rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; + rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; + rtvDesc.Texture3D.FirstWSlice = layer; + rtvDesc.Texture3D.WSize = 1; + + const d3d11::SharedSRV *srv = nullptr; + ANGLE_TRY(getSRVLevel(context, mipLevel, SRVType::Sample, &srv)); + + const d3d11::SharedSRV *blitSRV = nullptr; + ANGLE_TRY(getSRVLevel(context, mipLevel, SRVType::Blit, &blitSRV)); + + d3d11::RenderTargetView rtv; + ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, texture->get(), &rtv)); + rtv.setLabels("TexStorage3D.LayerRTV", &mKHRDebugLabel); + + mLevelLayerRenderTargets[key].reset(new TextureRenderTarget11( + std::move(rtv), *texture, *srv, *blitSRV, mFormatInfo.internalFormat, getFormatSet(), + getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0)); + } + + ASSERT(outRT); + *outRT = mLevelLayerRenderTargets[key].get(); + return angle::Result::Continue; +} + +angle::Result TextureStorage11_3D::getSwizzleTexture(const gl::Context *context, + const TextureHelper11 **outTexture) +{ + ASSERT(outTexture); + + if (!mSwizzleTexture.valid()) + { + const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()); + + D3D11_TEXTURE3D_DESC desc; + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.Depth = mTextureDepth; + desc.MipLevels = mMipLevels; + desc.Format = format.texFormat; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + ANGLE_TRY(mRenderer->allocateTexture(GetImplAs(context), desc, format, + &mSwizzleTexture)); + mSwizzleTexture.setLabels("TexStorage3D.SwizzleTexture", &mKHRDebugLabel); + } + + *outTexture = &mSwizzleTexture; + return angle::Result::Continue; +} + +angle::Result TextureStorage11_3D::getSwizzleRenderTarget(const gl::Context *context, + int mipLevel, + const d3d11::RenderTargetView **outRTV) +{ + ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); + ASSERT(outRTV); + + if (!mSwizzleRenderTargets[mipLevel].valid()) + { + const TextureHelper11 *swizzleTexture = nullptr; + ANGLE_TRY(getSwizzleTexture(context, &swizzleTexture)); + + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = + mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; + rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; + rtvDesc.Texture3D.FirstWSlice = 0; + rtvDesc.Texture3D.WSize = static_cast(-1); + + ANGLE_TRY(mRenderer->allocateResource(GetImplAs(context), rtvDesc, + mSwizzleTexture.get(), + &mSwizzleRenderTargets[mipLevel])); + mSwizzleRenderTargets[mipLevel].setLabels("TexStorage3D.SwizzleRTV", &mKHRDebugLabel); + } + + *outRTV = &mSwizzleRenderTargets[mipLevel]; + return angle::Result::Continue; +} + +void TextureStorage11_3D::onLabelUpdate() +{ + if (mTexture.valid()) + { + mTexture.setKHRDebugLabel(&mKHRDebugLabel); + } + if (mSwizzleTexture.valid()) + { + mSwizzleTexture.setKHRDebugLabel(&mKHRDebugLabel); + } +} + +TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer11 *renderer, + GLenum internalformat, + BindFlags bindFlags, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels, + const std::string &label) + : TextureStorage11( + renderer, + GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), bindFlags), + GetTextureMiscFlags(internalformat, + renderer->getRenderer11DeviceCaps(), + bindFlags, + levels), + internalformat, + label) +{ + // adjust size if needed for compressed textures + d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, &mTopLevel); + + mMipLevels = mTopLevel + levels; + mTextureWidth = width; + mTextureHeight = height; + mTextureDepth = depth; +} + +angle::Result TextureStorage11_2DArray::onDestroy(const gl::Context *context) +{ + for (auto iter : mAssociatedImages) + { + if (iter.second) + { + iter.second->verifyAssociatedStorageValid(this); + + // We must let the Images recover their data before we delete it from the + // TextureStorage. + ANGLE_TRY(iter.second->recoverFromAssociatedStorage(context)); + } + } + mAssociatedImages.clear(); + + return angle::Result::Continue; +} + +TextureStorage11_2DArray::~TextureStorage11_2DArray() {} + +void TextureStorage11_2DArray::associateImage(Image11 *image, const gl::ImageIndex &index) +{ + const GLint level = index.getLevelIndex(); + const GLint layerTarget = index.getLayerIndex(); + const GLint numLayers = index.getLayerCount(); + + ASSERT(0 <= level && level < getLevelCount()); + + if (0 <= level && level < getLevelCount()) + { + LevelLayerRangeKey key(level, layerTarget, numLayers); + mAssociatedImages[key] = image; + } +} + +void TextureStorage11_2DArray::verifyAssociatedImageValid(const gl::ImageIndex &index, + Image11 *expectedImage) +{ + const GLint level = index.getLevelIndex(); + const GLint layerTarget = index.getLayerIndex(); + const GLint numLayers = index.getLayerCount(); + + LevelLayerRangeKey key(level, layerTarget, numLayers); + + // This validation check should never return false. It means the Image/TextureStorage + // association is broken. + bool retValue = (mAssociatedImages.find(key) != mAssociatedImages.end() && + (mAssociatedImages[key] == expectedImage)); + ASSERT(retValue); +} + +// disassociateImage allows an Image to end its association with a Storage. +void TextureStorage11_2DArray::disassociateImage(const gl::ImageIndex &index, + Image11 *expectedImage) +{ + const GLint level = index.getLevelIndex(); + const GLint layerTarget = index.getLayerIndex(); + const GLint numLayers = index.getLayerCount(); + + LevelLayerRangeKey key(level, layerTarget, numLayers); + + bool imageAssociationCorrect = (mAssociatedImages.find(key) != mAssociatedImages.end() && + (mAssociatedImages[key] == expectedImage)); + ASSERT(imageAssociationCorrect); + mAssociatedImages[key] = nullptr; +} + +// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image +// recover its data before ending the association. +angle::Result TextureStorage11_2DArray::releaseAssociatedImage(const gl::Context *context, + const gl::ImageIndex &index, + Image11 *incomingImage) +{ + const GLint level = index.getLevelIndex(); + const GLint layerTarget = index.getLayerIndex(); + const GLint numLayers = index.getLayerCount(); + + LevelLayerRangeKey key(level, layerTarget, numLayers); + + if (mAssociatedImages.find(key) != mAssociatedImages.end()) + { + if (mAssociatedImages[key] != nullptr && mAssociatedImages[key] != incomingImage) + { + // Ensure that the Image is still associated with this TextureStorage. + mAssociatedImages[key]->verifyAssociatedStorageValid(this); + + // Force the image to recover from storage before its data is overwritten. + // This will reset mAssociatedImages[level] to nullptr too. + ANGLE_TRY(mAssociatedImages[key]->recoverFromAssociatedStorage(context)); + } + } + + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2DArray::getResource(const gl::Context *context, + const TextureHelper11 **outResource) +{ + // if the width, height or depth is not positive this should be treated as an incomplete texture + // we handle that here by skipping the d3d texture creation + if (!mTexture.valid() && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0) + { + ASSERT(mMipLevels > 0); + + D3D11_TEXTURE2D_DESC desc; + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.MipLevels = mMipLevels; + desc.ArraySize = mTextureDepth; + desc.Format = isUnorderedAccess() ? mFormatInfo.typelessFormat : mFormatInfo.texFormat; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = getBindFlags(); + desc.CPUAccessFlags = 0; + desc.MiscFlags = getMiscFlags(); + + ANGLE_TRY(mRenderer->allocateTexture(GetImplAs(context), desc, mFormatInfo, + &mTexture)); + mTexture.setLabels("TexStorage2DArray.Texture", &mKHRDebugLabel); + } + + *outResource = &mTexture; + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2DArray::createSRVForSampler(const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) +{ + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = format; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel; + srvDesc.Texture2DArray.MipLevels = mipLevels; + srvDesc.Texture2DArray.FirstArraySlice = 0; + srvDesc.Texture2DArray.ArraySize = mTextureDepth; + + ANGLE_TRY( + mRenderer->allocateResource(GetImplAs(context), srvDesc, texture.get(), outSRV)); + outSRV->setLabels("TexStorage2DArray.SRV", &mKHRDebugLabel); + + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2DArray::createSRVForImage(const gl::Context *context, + int level, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) +{ + ASSERT(outSRV); + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = format; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level; + srvDesc.Texture2DArray.MipLevels = 1; + srvDesc.Texture2DArray.FirstArraySlice = 0; + srvDesc.Texture2DArray.ArraySize = mTextureDepth; + ANGLE_TRY( + mRenderer->allocateResource(GetImplAs(context), srvDesc, texture.get(), outSRV)); + outSRV->setLabels("TexStorage2DArray.SRVForImage", &mKHRDebugLabel); + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2DArray::createUAVForImage(const gl::Context *context, + int level, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedUAV *outUAV) +{ + ASSERT(outUAV); + D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc; + uavDesc.Format = format; + uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY; + uavDesc.Texture2DArray.MipSlice = mTopLevel + level; + uavDesc.Texture2DArray.FirstArraySlice = 0; + uavDesc.Texture2DArray.ArraySize = mTextureDepth; + ANGLE_TRY( + mRenderer->allocateResource(GetImplAs(context), uavDesc, texture.get(), outUAV)); + outUAV->setLabels("TexStorage2DArray.UAVForImage", &mKHRDebugLabel); + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2DArray::findRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) const +{ + ASSERT(index.hasLayer()); + + const int mipLevel = index.getLevelIndex(); + const int layer = index.getLayerIndex(); + const int numLayers = index.getLayerCount(); + + ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); + + LevelLayerRangeKey key(mipLevel, layer, numLayers); + if (mRenderTargets.find(key) == mRenderTargets.end()) + { + ASSERT(outRT); + *outRT = nullptr; + return angle::Result::Continue; + } + + ASSERT(outRT); + *outRT = mRenderTargets.at(key).get(); + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2DArray::createRenderTargetSRV(const gl::Context *context, + const TextureHelper11 &texture, + const gl::ImageIndex &index, + DXGI_FORMAT resourceFormat, + d3d11::SharedSRV *srv) const +{ + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = resourceFormat; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + index.getLevelIndex(); + srvDesc.Texture2DArray.MipLevels = 1; + srvDesc.Texture2DArray.FirstArraySlice = index.getLayerIndex(); + srvDesc.Texture2DArray.ArraySize = index.getLayerCount(); + + ANGLE_TRY( + mRenderer->allocateResource(GetImplAs(context), srvDesc, texture.get(), srv)); + + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2DArray::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) +{ + ASSERT(index.hasLayer()); + + const int mipLevel = index.getLevelIndex(); + const int layer = index.getLayerIndex(); + const int numLayers = index.getLayerCount(); + + ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); + + LevelLayerRangeKey key(mipLevel, layer, numLayers); + if (mRenderTargets.find(key) == mRenderTargets.end()) + { + const TextureHelper11 *texture = nullptr; + ANGLE_TRY(getResource(context, &texture)); + d3d11::SharedSRV srv; + ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.srvFormat, &srv)); + d3d11::SharedSRV blitSRV; + if (mFormatInfo.blitSRVFormat != mFormatInfo.srvFormat) + { + ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.blitSRVFormat, + &blitSRV)); + } + else + { + blitSRV = srv.makeCopy(); + } + + srv.setLabels("TexStorage2DArray.RenderTargetSRV", &mKHRDebugLabel); + + if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN) + { + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mFormatInfo.rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; + rtvDesc.Texture2DArray.FirstArraySlice = layer; + rtvDesc.Texture2DArray.ArraySize = numLayers; + + d3d11::RenderTargetView rtv; + ANGLE_TRY(mRenderer->allocateResource(GetImplAs(context), rtvDesc, + texture->get(), &rtv)); + rtv.setLabels("TexStorage2DArray.RenderTargetRTV", &mKHRDebugLabel); + + mRenderTargets[key].reset(new TextureRenderTarget11( + std::move(rtv), *texture, srv, blitSRV, mFormatInfo.internalFormat, getFormatSet(), + getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0)); + } + else + { + ASSERT(mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN); + + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsvDesc.Format = mFormatInfo.dsvFormat; + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; + dsvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; + dsvDesc.Texture2DArray.FirstArraySlice = layer; + dsvDesc.Texture2DArray.ArraySize = numLayers; + dsvDesc.Flags = 0; + + d3d11::DepthStencilView dsv; + ANGLE_TRY(mRenderer->allocateResource(GetImplAs(context), dsvDesc, + texture->get(), &dsv)); + dsv.setLabels("TexStorage2DArray.RenderTargetDSV", &mKHRDebugLabel); + + mRenderTargets[key].reset(new TextureRenderTarget11( + std::move(dsv), *texture, srv, mFormatInfo.internalFormat, getFormatSet(), + getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0)); + } + } + + ASSERT(outRT); + *outRT = mRenderTargets[key].get(); + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2DArray::getSwizzleTexture(const gl::Context *context, + const TextureHelper11 **outTexture) +{ + if (!mSwizzleTexture.valid()) + { + const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()); + + D3D11_TEXTURE2D_DESC desc; + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.MipLevels = mMipLevels; + desc.ArraySize = mTextureDepth; + desc.Format = format.texFormat; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + ANGLE_TRY(mRenderer->allocateTexture(GetImplAs(context), desc, format, + &mSwizzleTexture)); + mSwizzleTexture.setLabels("TexStorage2DArray.SwizzleTexture", &mKHRDebugLabel); + } + + *outTexture = &mSwizzleTexture; + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2DArray::getSwizzleRenderTarget( + const gl::Context *context, + int mipLevel, + const d3d11::RenderTargetView **outRTV) +{ + ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); + ASSERT(outRTV); + + if (!mSwizzleRenderTargets[mipLevel].valid()) + { + const TextureHelper11 *swizzleTexture = nullptr; + ANGLE_TRY(getSwizzleTexture(context, &swizzleTexture)); + + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = + mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; + rtvDesc.Texture2DArray.FirstArraySlice = 0; + rtvDesc.Texture2DArray.ArraySize = mTextureDepth; + + ANGLE_TRY(mRenderer->allocateResource(GetImplAs(context), rtvDesc, + mSwizzleTexture.get(), + &mSwizzleRenderTargets[mipLevel])); + } + + *outRTV = &mSwizzleRenderTargets[mipLevel]; + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2DArray::ensureDropStencilTexture(const gl::Context *context, + DropStencil *dropStencilOut) +{ + if (mDropStencilTexture.valid()) + { + *dropStencilOut = DropStencil::ALREADY_EXISTS; + return angle::Result::Continue; + } + + D3D11_TEXTURE2D_DESC dropDesc = {}; + dropDesc.ArraySize = mTextureDepth; + dropDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DEPTH_STENCIL; + dropDesc.CPUAccessFlags = 0; + dropDesc.Format = DXGI_FORMAT_R32_TYPELESS; + dropDesc.Height = mTextureHeight; + dropDesc.MipLevels = mMipLevels; + dropDesc.MiscFlags = 0; + dropDesc.SampleDesc.Count = 1; + dropDesc.SampleDesc.Quality = 0; + dropDesc.Usage = D3D11_USAGE_DEFAULT; + dropDesc.Width = mTextureWidth; + + const auto &format = + d3d11::Format::Get(GL_DEPTH_COMPONENT32F, mRenderer->getRenderer11DeviceCaps()); + ANGLE_TRY(mRenderer->allocateTexture(GetImplAs(context), dropDesc, format, + &mDropStencilTexture)); + mDropStencilTexture.setLabels("TexStorage2DArray.DropStencil", &mKHRDebugLabel); + + std::vector layerCounts(mMipLevels, mTextureDepth); + + ANGLE_TRY(initDropStencilTexture( + context, gl::ImageIndexIterator::Make2DArray(0, mMipLevels, layerCounts.data()))); + + *dropStencilOut = DropStencil::CREATED; + return angle::Result::Continue; +} + +void TextureStorage11_2DArray::onLabelUpdate() +{ + if (mTexture.valid()) + { + mTexture.setKHRDebugLabel(&mKHRDebugLabel); + } + if (mSwizzleTexture.valid()) + { + mSwizzleTexture.setKHRDebugLabel(&mKHRDebugLabel); + } +} + +TextureStorage11_2DMultisample::TextureStorage11_2DMultisample(Renderer11 *renderer, + GLenum internalformat, + GLsizei width, + GLsizei height, + int levels, + int samples, + bool fixedSampleLocations, + const std::string &label) + : TextureStorage11ImmutableBase(renderer, + GetTextureBindFlags(internalformat, + renderer->getRenderer11DeviceCaps(), + BindFlags::RenderTarget()), + GetTextureMiscFlags(internalformat, + renderer->getRenderer11DeviceCaps(), + BindFlags::RenderTarget(), + levels), + internalformat, + label), + mTexture(), + mRenderTarget(nullptr) +{ + // There are no multisampled compressed formats, so there's no need to adjust texture size + // according to block size. + ASSERT(d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat).blockWidth <= 1); + ASSERT(d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat).blockHeight <= 1); + + mMipLevels = 1; + mTextureWidth = width; + mTextureHeight = height; + mTextureDepth = 1; + mSamples = samples; + mFixedSampleLocations = fixedSampleLocations; +} + +angle::Result TextureStorage11_2DMultisample::onDestroy(const gl::Context *context) +{ + mRenderTarget.reset(); + return angle::Result::Continue; +} + +TextureStorage11_2DMultisample::~TextureStorage11_2DMultisample() {} + +angle::Result TextureStorage11_2DMultisample::copyToStorage(const gl::Context *context, + TextureStorage *destStorage) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result TextureStorage11_2DMultisample::getResource(const gl::Context *context, + const TextureHelper11 **outResource) +{ + ANGLE_TRY(ensureTextureExists(context, 1)); + + *outResource = &mTexture; + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2DMultisample::ensureTextureExists(const gl::Context *context, + int mipLevels) +{ + // For Multisampled textures, mipLevels always equals 1. + ASSERT(mipLevels == 1); + + // if the width or height is not positive this should be treated as an incomplete texture + // we handle that here by skipping the d3d texture creation + if (!mTexture.valid() && mTextureWidth > 0 && mTextureHeight > 0) + { + D3D11_TEXTURE2D_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.Width = mTextureWidth; // Compressed texture size constraints? + desc.Height = mTextureHeight; + desc.MipLevels = mipLevels; + desc.ArraySize = 1; + desc.Format = mFormatInfo.texFormat; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = getBindFlags() & ~D3D11_BIND_UNORDERED_ACCESS; + desc.CPUAccessFlags = 0; + desc.MiscFlags = getMiscFlags(); + + const gl::TextureCaps &textureCaps = + mRenderer->getNativeTextureCaps().get(mFormatInfo.internalFormat); + GLuint supportedSamples = textureCaps.getNearestSamples(mSamples); + desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples; + desc.SampleDesc.Quality = mRenderer->getSampleDescQuality(supportedSamples); + + ANGLE_TRY(mRenderer->allocateTexture(GetImplAs(context), desc, mFormatInfo, + &mTexture)); + mTexture.setLabels("TexStorage2DMS.Texture", &mKHRDebugLabel); + } + + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2DMultisample::findRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) const +{ + ASSERT(!index.hasLayer()); + + const int level = index.getLevelIndex(); + ASSERT(level == 0); + + ASSERT(outRT); + *outRT = mRenderTarget.get(); + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2DMultisample::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) +{ + ASSERT(!index.hasLayer()); + + const int level = index.getLevelIndex(); + ASSERT(level == 0); + + ASSERT(outRT); + if (mRenderTarget) + { + *outRT = mRenderTarget.get(); + return angle::Result::Continue; + } + + const TextureHelper11 *texture = nullptr; + ANGLE_TRY(getResource(context, &texture)); + + const d3d11::SharedSRV *srv = nullptr; + ANGLE_TRY(getSRVLevel(context, level, SRVType::Sample, &srv)); + + const d3d11::SharedSRV *blitSRV = nullptr; + ANGLE_TRY(getSRVLevel(context, level, SRVType::Blit, &blitSRV)); + + Context11 *context11 = GetImplAs(context); + + if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN) + { + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mFormatInfo.rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; + + d3d11::RenderTargetView rtv; + ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, texture->get(), &rtv)); + + mRenderTarget.reset(new TextureRenderTarget11( + std::move(rtv), *texture, *srv, *blitSRV, mFormatInfo.internalFormat, getFormatSet(), + getLevelWidth(level), getLevelHeight(level), 1, mSamples)); + + *outRT = mRenderTarget.get(); + return angle::Result::Continue; + } + + ASSERT(mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN); + + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsvDesc.Format = mFormatInfo.dsvFormat; + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS; + dsvDesc.Flags = 0; + + d3d11::DepthStencilView dsv; + ANGLE_TRY(mRenderer->allocateResource(context11, dsvDesc, texture->get(), &dsv)); + + mRenderTarget.reset(new TextureRenderTarget11( + std::move(dsv), *texture, *srv, mFormatInfo.internalFormat, getFormatSet(), + getLevelWidth(level), getLevelHeight(level), 1, mSamples)); + + *outRT = mRenderTarget.get(); + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2DMultisample::createSRVForSampler(const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) +{ + ASSERT(outSRV); + + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = format; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; + + ANGLE_TRY( + mRenderer->allocateResource(GetImplAs(context), srvDesc, texture.get(), outSRV)); + outSRV->setLabels("TexStorage2DMS.SRV", &mKHRDebugLabel); + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2DMultisample::getSwizzleTexture(const gl::Context *context, + const TextureHelper11 **outTexture) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result TextureStorage11_2DMultisample::getSwizzleRenderTarget( + const gl::Context *context, + int mipLevel, + const d3d11::RenderTargetView **outRTV) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result TextureStorage11_2DMultisample::ensureDropStencilTexture(const gl::Context *context, + DropStencil *dropStencilOut) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +void TextureStorage11_2DMultisample::onLabelUpdate() +{ + if (mTexture.valid()) + { + mTexture.setKHRDebugLabel(&mKHRDebugLabel); + } +} + +TextureStorage11_2DMultisampleArray::TextureStorage11_2DMultisampleArray(Renderer11 *renderer, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels, + int samples, + bool fixedSampleLocations, + const std::string &label) + : TextureStorage11ImmutableBase(renderer, + GetTextureBindFlags(internalformat, + renderer->getRenderer11DeviceCaps(), + BindFlags::RenderTarget()), + GetTextureMiscFlags(internalformat, + renderer->getRenderer11DeviceCaps(), + BindFlags::RenderTarget(), + levels), + internalformat, + label), + mTexture() +{ + // There are no multisampled compressed formats, so there's no need to adjust texture size + // according to block size. + ASSERT(d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat).blockWidth <= 1); + ASSERT(d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat).blockHeight <= 1); + + mMipLevels = 1; + mTextureWidth = width; + mTextureHeight = height; + mTextureDepth = depth; + mSamples = samples; + mFixedSampleLocations = fixedSampleLocations; +} + +angle::Result TextureStorage11_2DMultisampleArray::onDestroy(const gl::Context *context) +{ + return angle::Result::Continue; +} + +TextureStorage11_2DMultisampleArray::~TextureStorage11_2DMultisampleArray() {} + +angle::Result TextureStorage11_2DMultisampleArray::copyToStorage(const gl::Context *context, + TextureStorage *destStorage) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result TextureStorage11_2DMultisampleArray::getResource(const gl::Context *context, + const TextureHelper11 **outResource) +{ + ANGLE_TRY(ensureTextureExists(context, 1)); + + *outResource = &mTexture; + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2DMultisampleArray::ensureTextureExists(const gl::Context *context, + int mipLevels) +{ + // For multisampled textures, mipLevels always equals 1. + ASSERT(mipLevels == 1); + + // if the width or height is not positive this should be treated as an incomplete texture + // we handle that here by skipping the d3d texture creation + if (!mTexture.valid() && mTextureWidth > 0 && mTextureHeight > 0) + { + D3D11_TEXTURE2D_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.MipLevels = mipLevels; + desc.ArraySize = mTextureDepth; + desc.Format = mFormatInfo.texFormat; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = getBindFlags() & ~D3D11_BIND_UNORDERED_ACCESS; + desc.CPUAccessFlags = 0; + desc.MiscFlags = getMiscFlags(); + + const gl::TextureCaps &textureCaps = + mRenderer->getNativeTextureCaps().get(mFormatInfo.internalFormat); + GLuint supportedSamples = textureCaps.getNearestSamples(mSamples); + desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples; + desc.SampleDesc.Quality = mRenderer->getSampleDescQuality(supportedSamples); + + ANGLE_TRY(mRenderer->allocateTexture(GetImplAs(context), desc, mFormatInfo, + &mTexture)); + mTexture.setLabels("TexStorage2DMSArray.Texture", &mKHRDebugLabel); + } + + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2DMultisampleArray::findRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) const +{ + ASSERT(index.hasLayer()); + + const int mipLevel = index.getLevelIndex(); + ASSERT(mipLevel == 0); + const int layer = index.getLayerIndex(); + const int numLayers = index.getLayerCount(); + + ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); + + TextureStorage11_2DArray::LevelLayerRangeKey key(mipLevel, layer, numLayers); + if (mRenderTargets.find(key) == mRenderTargets.end()) + { + ASSERT(outRT); + *outRT = nullptr; + return angle::Result::Continue; + } + + ASSERT(outRT); + *outRT = mRenderTargets.at(key).get(); + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2DMultisampleArray::createRenderTargetSRV( + const gl::Context *context, + const TextureHelper11 &texture, + const gl::ImageIndex &index, + DXGI_FORMAT resourceFormat, + d3d11::SharedSRV *srv) const +{ + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = resourceFormat; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY; + srvDesc.Texture2DMSArray.FirstArraySlice = index.getLayerIndex(); + srvDesc.Texture2DMSArray.ArraySize = index.getLayerCount(); + + ANGLE_TRY( + mRenderer->allocateResource(GetImplAs(context), srvDesc, texture.get(), srv)); + + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2DMultisampleArray::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) +{ + ASSERT(index.hasLayer()); + + const int mipLevel = index.getLevelIndex(); + ASSERT(mipLevel == 0); + const int layer = index.getLayerIndex(); + const int numLayers = index.getLayerCount(); + + ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); + + TextureStorage11_2DArray::LevelLayerRangeKey key(mipLevel, layer, numLayers); + if (mRenderTargets.find(key) == mRenderTargets.end()) + { + const TextureHelper11 *texture = nullptr; + ANGLE_TRY(getResource(context, &texture)); + d3d11::SharedSRV srv; + ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.srvFormat, &srv)); + d3d11::SharedSRV blitSRV; + if (mFormatInfo.blitSRVFormat != mFormatInfo.srvFormat) + { + ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.blitSRVFormat, + &blitSRV)); + } + else + { + blitSRV = srv.makeCopy(); + } + + srv.setLabels("TexStorage2DMSArray.RenderTargetSRV", &mKHRDebugLabel); + + if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN) + { + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mFormatInfo.rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY; + rtvDesc.Texture2DMSArray.FirstArraySlice = layer; + rtvDesc.Texture2DMSArray.ArraySize = numLayers; + + d3d11::RenderTargetView rtv; + ANGLE_TRY(mRenderer->allocateResource(GetImplAs(context), rtvDesc, + texture->get(), &rtv)); + rtv.setLabels("TexStorage2DMSArray.RenderTargetRTV", &mKHRDebugLabel); + + mRenderTargets[key].reset(new TextureRenderTarget11( + std::move(rtv), *texture, srv, blitSRV, mFormatInfo.internalFormat, getFormatSet(), + getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, mSamples)); + } + else + { + ASSERT(mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN); + + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsvDesc.Format = mFormatInfo.dsvFormat; + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY; + dsvDesc.Texture2DMSArray.FirstArraySlice = layer; + dsvDesc.Texture2DMSArray.ArraySize = numLayers; + dsvDesc.Flags = 0; + + d3d11::DepthStencilView dsv; + ANGLE_TRY(mRenderer->allocateResource(GetImplAs(context), dsvDesc, + texture->get(), &dsv)); + dsv.setLabels("TexStorage2DMSArray.RenderTargetDSV", &mKHRDebugLabel); + + mRenderTargets[key].reset(new TextureRenderTarget11( + std::move(dsv), *texture, srv, mFormatInfo.internalFormat, getFormatSet(), + getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, mSamples)); + } + } + + ASSERT(outRT); + *outRT = mRenderTargets[key].get(); + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2DMultisampleArray::createSRVForSampler( + const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) +{ + ASSERT(outSRV); + + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = format; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY; + srvDesc.Texture2DMSArray.FirstArraySlice = 0; + srvDesc.Texture2DMSArray.ArraySize = mTextureDepth; + + ANGLE_TRY( + mRenderer->allocateResource(GetImplAs(context), srvDesc, texture.get(), outSRV)); + outSRV->setLabels("TexStorage2DMSArray.SRV", &mKHRDebugLabel); + return angle::Result::Continue; +} + +angle::Result TextureStorage11_2DMultisampleArray::getSwizzleTexture( + const gl::Context *context, + const TextureHelper11 **outTexture) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result TextureStorage11_2DMultisampleArray::getSwizzleRenderTarget( + const gl::Context *context, + int mipLevel, + const d3d11::RenderTargetView **outRTV) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result TextureStorage11_2DMultisampleArray::ensureDropStencilTexture( + const gl::Context *context, + DropStencil *dropStencilOut) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +void TextureStorage11_2DMultisampleArray::onLabelUpdate() +{ + if (mTexture.valid()) + { + mTexture.setKHRDebugLabel(&mKHRDebugLabel); + } +} + +TextureStorage11_Buffer::TextureStorage11_Buffer(Renderer11 *renderer, + const gl::OffsetBindingPointer &buffer, + GLenum internalFormat, + const std::string &label) + : TextureStorage11(renderer, + D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE, + 0, + internalFormat, + label), + mTexture(), + mBuffer(buffer), + mDataSize(GetBoundBufferAvailableSize(buffer)) +{ + unsigned int bytesPerPixel = + static_cast(d3d11::GetDXGIFormatSizeInfo(mFormatInfo.srvFormat).pixelBytes); + mMipLevels = 1; + mTextureWidth = static_cast(mDataSize / bytesPerPixel); + mTextureHeight = 1; + mTextureDepth = 1; +} + +TextureStorage11_Buffer::~TextureStorage11_Buffer() {} + +angle::Result TextureStorage11_Buffer::initTexture(const gl::Context *context) +{ + if (!mTexture.valid()) + { + ID3D11Buffer *buffer = nullptr; + Buffer11 *buffer11 = GetImplAs(mBuffer.get()); + ANGLE_TRY(buffer11->getBuffer(context, rx::BufferUsage::BUFFER_USAGE_TYPED_UAV, &buffer)); + mTexture.set(buffer, mFormatInfo); + mTexture.get()->AddRef(); + } + return angle::Result::Continue; +} + +angle::Result TextureStorage11_Buffer::getResource(const gl::Context *context, + const TextureHelper11 **outResource) +{ + ANGLE_TRY(initTexture(context)); + *outResource = &mTexture; + return angle::Result::Continue; +} + +angle::Result TextureStorage11_Buffer::getMippedResource(const gl::Context *context, + const TextureHelper11 **) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result TextureStorage11_Buffer::findRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) const +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result TextureStorage11_Buffer::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result TextureStorage11_Buffer::getSwizzleTexture(const gl::Context *context, + const TextureHelper11 **outTexture) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result TextureStorage11_Buffer::getSwizzleRenderTarget( + const gl::Context *context, + int mipLevel, + const d3d11::RenderTargetView **outRTV) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result TextureStorage11_Buffer::createSRVForSampler(const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) +{ + ASSERT(baseLevel == 0); + ASSERT(mipLevels == 1); + ASSERT(outSRV); + ANGLE_TRY(initTexture(context)); + UINT bytesPerPixel = static_cast(d3d11::GetDXGIFormatSizeInfo(format).pixelBytes); + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = format; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; + ASSERT(mBuffer.getOffset() % bytesPerPixel == 0); + srvDesc.Buffer.FirstElement = static_cast(mBuffer.getOffset() / bytesPerPixel); + srvDesc.Buffer.NumElements = static_cast(mDataSize / bytesPerPixel); + + ANGLE_TRY( + mRenderer->allocateResource(GetImplAs(context), srvDesc, texture.get(), outSRV)); + outSRV->setLabels("TexBuffer.SRV", &mKHRDebugLabel); + + return angle::Result::Continue; +} + +angle::Result TextureStorage11_Buffer::createSRVForImage(const gl::Context *context, + int level, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) +{ + ANGLE_TRY(initTexture(context)); + UINT bytesPerPixel = static_cast(d3d11::GetDXGIFormatSizeInfo(format).pixelBytes); + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = format; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; + ASSERT(mBuffer.getOffset() % bytesPerPixel == 0); + srvDesc.Buffer.FirstElement = static_cast(mBuffer.getOffset() / bytesPerPixel); + srvDesc.Buffer.NumElements = static_cast(mDataSize / bytesPerPixel); + + ANGLE_TRY( + mRenderer->allocateResource(GetImplAs(context), srvDesc, texture.get(), outSRV)); + outSRV->setLabels("TexBuffer.SRVForImage", &mKHRDebugLabel); + + return angle::Result::Continue; +} +angle::Result TextureStorage11_Buffer::createUAVForImage(const gl::Context *context, + int level, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedUAV *outUAV) +{ + ANGLE_TRY(initTexture(context)); + unsigned bytesPerPixel = d3d11::GetDXGIFormatSizeInfo(format).pixelBytes; + D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc; + uavDesc.Format = format; + uavDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; + ASSERT(mBuffer.getOffset() % bytesPerPixel == 0); + uavDesc.Buffer.FirstElement = static_cast(mBuffer.getOffset() / bytesPerPixel); + uavDesc.Buffer.NumElements = static_cast(mDataSize / bytesPerPixel); + uavDesc.Buffer.Flags = 0; + + ANGLE_TRY( + mRenderer->allocateResource(GetImplAs(context), uavDesc, texture.get(), outUAV)); + outUAV->setLabels("TexBuffer.UAVForImage", &mKHRDebugLabel); + + return angle::Result::Continue; +} + +void TextureStorage11_Buffer::associateImage(Image11 *image, const gl::ImageIndex &index) {} +void TextureStorage11_Buffer::disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) +{} +void TextureStorage11_Buffer::verifyAssociatedImageValid(const gl::ImageIndex &index, + Image11 *expectedImage) +{} +angle::Result TextureStorage11_Buffer::releaseAssociatedImage(const gl::Context *context, + const gl::ImageIndex &index, + Image11 *incomingImage) +{ + return angle::Result::Continue; +} + +void TextureStorage11_Buffer::onLabelUpdate() +{ + if (mTexture.valid()) + { + mTexture.setKHRDebugLabel(&mKHRDebugLabel); + } +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h new file mode 100644 index 0000000000..72bc1b802c --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h @@ -0,0 +1,1003 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// TextureStorage11.h: Defines the abstract rx::TextureStorage11 class and its concrete derived +// classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 +// texture. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_TEXTURESTORAGE11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_TEXTURESTORAGE11_H_ + +#include "libANGLE/Error.h" +#include "libANGLE/Texture.h" +#include "libANGLE/renderer/d3d/TextureStorage.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" + +#include +#include + +namespace gl +{ +class ImageIndex; +} // namespace gl + +namespace rx +{ +class EGLImageD3D; +class RenderTargetD3D; +class RenderTarget11; +class Renderer11; +class SwapChain11; +class Image11; +struct Renderer11DeviceCaps; +class TextureStorage11_2DMultisample; + +template +using CubeFaceArray = std::array; + +struct MultisampledRenderToTextureInfo +{ + MultisampledRenderToTextureInfo(const GLsizei samples, + const gl::ImageIndex &indexSS, + const gl::ImageIndex &indexMS); + ~MultisampledRenderToTextureInfo(); + + // How many samples the multisampled texture contains + GLsizei samples; + // This is the image index for the single sampled texture + // This will hold the relevant level information + gl::ImageIndex indexSS; + // This is the image index for the multisampled texture + // For multisampled indexes, there is no level Index since they should + // account for the entire level. + gl::ImageIndex indexMS; + // True when multisampled texture has been written to and needs to be + // resolved to the single sampled texture + bool msTextureNeedsResolve; + std::unique_ptr msTex; +}; + +class TextureStorage11 : public TextureStorage +{ + public: + ~TextureStorage11() override; + + static DWORD GetTextureBindFlags(GLenum internalFormat, + const Renderer11DeviceCaps &renderer11DeviceCaps, + BindFlags flags); + static DWORD GetTextureMiscFlags(GLenum internalFormat, + const Renderer11DeviceCaps &renderer11DeviceCaps, + BindFlags flags, + int levels); + + UINT getBindFlags() const; + UINT getMiscFlags() const; + const d3d11::Format &getFormatSet() const; + angle::Result getSRVLevels(const gl::Context *context, + GLint baseLevel, + GLint maxLevel, + const d3d11::SharedSRV **outSRV); + angle::Result generateSwizzles(const gl::Context *context, + const gl::TextureState &textureState); + void markLevelDirty(int mipLevel); + void markDirty(); + + angle::Result updateSubresourceLevel(const gl::Context *context, + const TextureHelper11 &texture, + unsigned int sourceSubresource, + const gl::ImageIndex &index, + const gl::Box ©Area); + + angle::Result copySubresourceLevel(const gl::Context *context, + const TextureHelper11 &dstTexture, + unsigned int dstSubresource, + const gl::ImageIndex &index, + const gl::Box ®ion); + + // TextureStorage virtual functions + int getTopLevel() const override; + bool isRenderTarget() const override; + bool isManaged() const override; + bool supportsNativeMipmapFunction() const override; + int getLevelCount() const override; + bool isUnorderedAccess() const override { return mBindFlags & D3D11_BIND_UNORDERED_ACCESS; } + angle::Result generateMipmap(const gl::Context *context, + const gl::ImageIndex &sourceIndex, + const gl::ImageIndex &destIndex) override; + angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override; + angle::Result setData(const gl::Context *context, + const gl::ImageIndex &index, + ImageD3D *image, + const gl::Box *destBox, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixelData) override; + void invalidateTextures() override; + + virtual angle::Result getSRVForSampler(const gl::Context *context, + const gl::TextureState &textureState, + const gl::SamplerState &sampler, + const d3d11::SharedSRV **outSRV); + angle::Result getSRVForImage(const gl::Context *context, + const gl::ImageUnit &imageUnit, + const d3d11::SharedSRV **outSRV); + angle::Result getUAVForImage(const gl::Context *context, + const gl::ImageUnit &imageUnit, + const d3d11::SharedUAV **outUAV); + virtual angle::Result getSubresourceIndex(const gl::Context *context, + const gl::ImageIndex &index, + UINT *outSubresourceIndex) const; + virtual angle::Result getResource(const gl::Context *context, + const TextureHelper11 **outResource) = 0; + virtual void associateImage(Image11 *image, const gl::ImageIndex &index) = 0; + virtual void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) = 0; + virtual void verifyAssociatedImageValid(const gl::ImageIndex &index, + Image11 *expectedImage) = 0; + virtual angle::Result releaseAssociatedImage(const gl::Context *context, + const gl::ImageIndex &index, + Image11 *incomingImage) = 0; + + GLsizei getRenderToTextureSamples() const override; + + protected: + TextureStorage11(Renderer11 *renderer, + UINT bindFlags, + UINT miscFlags, + GLenum internalFormat, + const std::string &label); + int getLevelWidth(int mipLevel) const; + int getLevelHeight(int mipLevel) const; + int getLevelDepth(int mipLevel) const; + + // Some classes (e.g. TextureStorage11_2D) will override getMippedResource. + virtual angle::Result getMippedResource(const gl::Context *context, + const TextureHelper11 **outResource); + + virtual angle::Result getSwizzleTexture(const gl::Context *context, + const TextureHelper11 **outTexture) = 0; + virtual angle::Result getSwizzleRenderTarget(const gl::Context *context, + int mipLevel, + const d3d11::RenderTargetView **outRTV) = 0; + + enum class SRVType + { + Sample, + Blit, + Stencil + }; + angle::Result getSRVLevel(const gl::Context *context, + int mipLevel, + SRVType srvType, + const d3d11::SharedSRV **outSRV); + + // Get a version of a depth texture with only depth information, not stencil. + enum DropStencil + { + CREATED, + ALREADY_EXISTS + }; + virtual angle::Result ensureDropStencilTexture(const gl::Context *context, + DropStencil *dropStencilOut); + angle::Result initDropStencilTexture(const gl::Context *context, + const gl::ImageIndexIterator &it); + + // The baseLevel parameter should *not* have mTopLevel applied. + virtual angle::Result createSRVForSampler(const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) = 0; + virtual angle::Result createSRVForImage(const gl::Context *context, + int level, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) = 0; + virtual angle::Result createUAVForImage(const gl::Context *context, + int level, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedUAV *outUAV) = 0; + + void verifySwizzleExists(const gl::SwizzleState &swizzleState); + + // Clear all cached non-swizzle SRVs and invalidate the swizzle cache. + void clearSRVCache(); + + // Helper for resolving MS shadowed texture + angle::Result resolveTextureHelper(const gl::Context *context, const TextureHelper11 &texture); + angle::Result releaseMultisampledTexStorageForLevel(size_t level) override; + angle::Result findMultisampledRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) const; + angle::Result getMultisampledRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT); + + Renderer11 *mRenderer; + int mTopLevel; + unsigned int mMipLevels; + + const d3d11::Format &mFormatInfo; + unsigned int mTextureWidth; + unsigned int mTextureHeight; + unsigned int mTextureDepth; + + gl::TexLevelArray mSwizzleCache; + TextureHelper11 mDropStencilTexture; + + std::unique_ptr mMSTexInfo; + + private: + const UINT mBindFlags; + const UINT mMiscFlags; + + struct SamplerKey + { + SamplerKey(); + SamplerKey(int baseLevel, int mipLevels, bool swizzle, bool dropStencil); + + bool operator<(const SamplerKey &rhs) const; + + int baseLevel; + int mipLevels; + bool swizzle; + bool dropStencil; + }; + + angle::Result getCachedOrCreateSRVForSampler(const gl::Context *context, + const SamplerKey &key, + const d3d11::SharedSRV **outSRV); + + using SRVCacheForSampler = std::map; + SRVCacheForSampler mSrvCacheForSampler; + + struct ImageKey + { + ImageKey(); + ImageKey(int level, bool layered, int layer, GLenum access, GLenum format); + bool operator<(const ImageKey &rhs) const; + int level; + bool layered; + int layer; + GLenum access; + GLenum format; + }; + + angle::Result getCachedOrCreateSRVForImage(const gl::Context *context, + const ImageKey &key, + const d3d11::SharedSRV **outSRV); + angle::Result getCachedOrCreateUAVForImage(const gl::Context *context, + const ImageKey &key, + const d3d11::SharedUAV **outUAV); + + using SRVCacheForImage = std::map; + SRVCacheForImage mSrvCacheForImage; + using UAVCacheForImage = std::map; + UAVCacheForImage mUavCacheForImage; + + gl::TexLevelArray mLevelSRVs; + gl::TexLevelArray mLevelBlitSRVs; + gl::TexLevelArray mLevelStencilSRVs; +}; + +class TextureStorage11_2D : public TextureStorage11 +{ + public: + TextureStorage11_2D(Renderer11 *renderer, SwapChain11 *swapchain, const std::string &label); + TextureStorage11_2D(Renderer11 *renderer, + GLenum internalformat, + BindFlags bindFlags, + GLsizei width, + GLsizei height, + int levels, + const std::string &label, + bool hintLevelZeroOnly = false); + ~TextureStorage11_2D() override; + + angle::Result onDestroy(const gl::Context *context) override; + + angle::Result getResource(const gl::Context *context, + const TextureHelper11 **outResource) override; + angle::Result getMippedResource(const gl::Context *context, + const TextureHelper11 **outResource) override; + angle::Result findRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) const override; + angle::Result getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) override; + + angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override; + + void associateImage(Image11 *image, const gl::ImageIndex &index) override; + void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override; + void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override; + angle::Result releaseAssociatedImage(const gl::Context *context, + const gl::ImageIndex &index, + Image11 *incomingImage) override; + + angle::Result useLevelZeroWorkaroundTexture(const gl::Context *context, + bool useLevelZeroTexture) override; + void onLabelUpdate() override; + + protected: + angle::Result getSwizzleTexture(const gl::Context *context, + const TextureHelper11 **outTexture) override; + angle::Result getSwizzleRenderTarget(const gl::Context *context, + int mipLevel, + const d3d11::RenderTargetView **outRTV) override; + + angle::Result ensureDropStencilTexture(const gl::Context *context, + DropStencil *dropStencilOut) override; + + angle::Result ensureTextureExists(const gl::Context *context, int mipLevels); + + angle::Result resolveTexture(const gl::Context *context) override; + + private: + angle::Result createSRVForSampler(const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) override; + angle::Result createSRVForImage(const gl::Context *context, + int level, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) override; + angle::Result createUAVForImage(const gl::Context *context, + int level, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedUAV *outUAV) override; + + TextureHelper11 mTexture; + gl::TexLevelArray> mRenderTarget; + bool mHasKeyedMutex; + + // These are members related to the zero max-LOD workaround. + // D3D11 Feature Level 9_3 can't disable mipmaps on a mipmapped texture (i.e. solely sample from + // level zero). These members are used to work around this limitation. Usually only mTexture XOR + // mLevelZeroTexture will exist. For example, if an app creates a texture with only one level, + // then 9_3 will only create mLevelZeroTexture. However, in some scenarios, both textures have + // to be created. This incurs additional memory overhead. One example of this is an application + // that creates a texture, calls glGenerateMipmap, and then disables mipmaps on the texture. A + // more likely example is an app that creates an empty texture, renders to it, and then calls + // glGenerateMipmap + // TODO: In this rendering scenario, release the mLevelZeroTexture after mTexture has been + // created to save memory. + TextureHelper11 mLevelZeroTexture; + std::unique_ptr mLevelZeroRenderTarget; + bool mUseLevelZeroTexture; + + // Swizzle-related variables + TextureHelper11 mSwizzleTexture; + gl::TexLevelArray mSwizzleRenderTargets; + + gl::TexLevelArray mAssociatedImages; +}; + +class TextureStorage11_External : public TextureStorage11 +{ + public: + TextureStorage11_External(Renderer11 *renderer, + egl::Stream *stream, + const egl::Stream::GLTextureDescription &glDesc, + const std::string &label); + ~TextureStorage11_External() override; + + angle::Result onDestroy(const gl::Context *context) override; + + angle::Result getResource(const gl::Context *context, + const TextureHelper11 **outResource) override; + angle::Result getMippedResource(const gl::Context *context, + const TextureHelper11 **outResource) override; + angle::Result findRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) const override; + angle::Result getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) override; + + angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override; + + void associateImage(Image11 *image, const gl::ImageIndex &index) override; + void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override; + void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override; + angle::Result releaseAssociatedImage(const gl::Context *context, + const gl::ImageIndex &index, + Image11 *incomingImage) override; + void onLabelUpdate() override; + + protected: + angle::Result getSwizzleTexture(const gl::Context *context, + const TextureHelper11 **outTexture) override; + angle::Result getSwizzleRenderTarget(const gl::Context *context, + int mipLevel, + const d3d11::RenderTargetView **outRTV) override; + + private: + angle::Result createSRVForSampler(const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) override; + angle::Result createSRVForImage(const gl::Context *context, + int level, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) override; + angle::Result createUAVForImage(const gl::Context *context, + int level, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedUAV *outUAV) override; + + TextureHelper11 mTexture; + int mSubresourceIndex; + bool mHasKeyedMutex; + + Image11 *mAssociatedImage; +}; + +// A base class for texture storage classes where the associated images are not changed, nor are +// they accessible as images in GLES3.1+ shaders. +class TextureStorage11ImmutableBase : public TextureStorage11 +{ + public: + TextureStorage11ImmutableBase(Renderer11 *renderer, + UINT bindFlags, + UINT miscFlags, + GLenum internalFormat, + const std::string &label); + + void associateImage(Image11 *image, const gl::ImageIndex &index) override; + void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override; + void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override; + angle::Result releaseAssociatedImage(const gl::Context *context, + const gl::ImageIndex &index, + Image11 *incomingImage) override; + + angle::Result createSRVForImage(const gl::Context *context, + int level, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) override; + angle::Result createUAVForImage(const gl::Context *context, + int level, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedUAV *outUAV) override; +}; + +class TextureStorage11_EGLImage final : public TextureStorage11ImmutableBase +{ + public: + TextureStorage11_EGLImage(Renderer11 *renderer, + EGLImageD3D *eglImage, + RenderTarget11 *renderTarget11, + const std::string &label); + ~TextureStorage11_EGLImage() override; + + angle::Result getSubresourceIndex(const gl::Context *context, + const gl::ImageIndex &index, + UINT *outSubresourceIndex) const override; + angle::Result getResource(const gl::Context *context, + const TextureHelper11 **outResource) override; + angle::Result getSRVForSampler(const gl::Context *context, + const gl::TextureState &textureState, + const gl::SamplerState &sampler, + const d3d11::SharedSRV **outSRV) override; + angle::Result getMippedResource(const gl::Context *context, + const TextureHelper11 **outResource) override; + angle::Result findRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) const override; + angle::Result getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) override; + + angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override; + + angle::Result useLevelZeroWorkaroundTexture(const gl::Context *context, + bool useLevelZeroTexture) override; + void onLabelUpdate() override; + + protected: + angle::Result getSwizzleTexture(const gl::Context *context, + const TextureHelper11 **outTexture) override; + angle::Result getSwizzleRenderTarget(const gl::Context *context, + int mipLevel, + const d3d11::RenderTargetView **outRTV) override; + + private: + // Check if the EGL image's render target has been updated due to orphaning and delete + // any SRVs and other resources based on the image's old render target. + angle::Result checkForUpdatedRenderTarget(const gl::Context *context); + + angle::Result createSRVForSampler(const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) override; + + angle::Result getImageRenderTarget(const gl::Context *context, RenderTarget11 **outRT) const; + + EGLImageD3D *mImage; + uintptr_t mCurrentRenderTarget; + + // Swizzle-related variables + TextureHelper11 mSwizzleTexture; + std::vector mSwizzleRenderTargets; +}; + +class TextureStorage11_Cube : public TextureStorage11 +{ + public: + TextureStorage11_Cube(Renderer11 *renderer, + GLenum internalformat, + BindFlags bindFlags, + int size, + int levels, + bool hintLevelZeroOnly, + const std::string &label); + ~TextureStorage11_Cube() override; + + angle::Result onDestroy(const gl::Context *context) override; + + angle::Result getSubresourceIndex(const gl::Context *context, + const gl::ImageIndex &index, + UINT *outSubresourceIndex) const override; + + angle::Result getResource(const gl::Context *context, + const TextureHelper11 **outResource) override; + angle::Result getMippedResource(const gl::Context *context, + const TextureHelper11 **outResource) override; + angle::Result findRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) const override; + angle::Result getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) override; + + angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override; + + void associateImage(Image11 *image, const gl::ImageIndex &index) override; + void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override; + void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override; + angle::Result releaseAssociatedImage(const gl::Context *context, + const gl::ImageIndex &index, + Image11 *incomingImage) override; + + angle::Result useLevelZeroWorkaroundTexture(const gl::Context *context, + bool useLevelZeroTexture) override; + void onLabelUpdate() override; + + protected: + angle::Result getSwizzleTexture(const gl::Context *context, + const TextureHelper11 **outTexture) override; + angle::Result getSwizzleRenderTarget(const gl::Context *context, + int mipLevel, + const d3d11::RenderTargetView **outRTV) override; + + angle::Result ensureDropStencilTexture(const gl::Context *context, + DropStencil *dropStencilOut) override; + + angle::Result ensureTextureExists(const gl::Context *context, int mipLevels); + + angle::Result resolveTexture(const gl::Context *context) override; + + private: + angle::Result createSRVForSampler(const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) override; + angle::Result createSRVForImage(const gl::Context *context, + int level, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) override; + angle::Result createUAVForImage(const gl::Context *context, + int level, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedUAV *outUAV) override; + angle::Result createRenderTargetSRV(const gl::Context *context, + const TextureHelper11 &texture, + const gl::ImageIndex &index, + DXGI_FORMAT resourceFormat, + d3d11::SharedSRV *srv) const; + + TextureHelper11 mTexture; + CubeFaceArray>> mRenderTarget; + + // Level-zero workaround members. See TextureStorage11_2D's workaround members for a + // description. + TextureHelper11 mLevelZeroTexture; + CubeFaceArray> mLevelZeroRenderTarget; + bool mUseLevelZeroTexture; + + TextureHelper11 mSwizzleTexture; + gl::TexLevelArray mSwizzleRenderTargets; + + CubeFaceArray> mAssociatedImages; +}; + +class TextureStorage11_3D : public TextureStorage11 +{ + public: + TextureStorage11_3D(Renderer11 *renderer, + GLenum internalformat, + BindFlags bindFlags, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels, + const std::string &label); + ~TextureStorage11_3D() override; + + angle::Result onDestroy(const gl::Context *context) override; + + angle::Result getResource(const gl::Context *context, + const TextureHelper11 **outResource) override; + + // Handles both layer and non-layer RTs + angle::Result findRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) const override; + angle::Result getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) override; + + void associateImage(Image11 *image, const gl::ImageIndex &index) override; + void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override; + void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override; + angle::Result releaseAssociatedImage(const gl::Context *context, + const gl::ImageIndex &index, + Image11 *incomingImage) override; + void onLabelUpdate() override; + + protected: + angle::Result getSwizzleTexture(const gl::Context *context, + const TextureHelper11 **outTexture) override; + angle::Result getSwizzleRenderTarget(const gl::Context *context, + int mipLevel, + const d3d11::RenderTargetView **outRTV) override; + + private: + angle::Result createSRVForSampler(const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) override; + angle::Result createSRVForImage(const gl::Context *context, + int level, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) override; + angle::Result createUAVForImage(const gl::Context *context, + int level, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedUAV *outUAV) override; + + typedef std::pair LevelLayerKey; + std::map> mLevelLayerRenderTargets; + + gl::TexLevelArray> mLevelRenderTargets; + + TextureHelper11 mTexture; + TextureHelper11 mSwizzleTexture; + gl::TexLevelArray mSwizzleRenderTargets; + + gl::TexLevelArray mAssociatedImages; +}; + +class TextureStorage11_2DArray : public TextureStorage11 +{ + public: + TextureStorage11_2DArray(Renderer11 *renderer, + GLenum internalformat, + BindFlags bindFlags, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels, + const std::string &label); + ~TextureStorage11_2DArray() override; + + angle::Result onDestroy(const gl::Context *context) override; + + angle::Result getResource(const gl::Context *context, + const TextureHelper11 **outResource) override; + angle::Result findRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) const override; + angle::Result getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) override; + + void associateImage(Image11 *image, const gl::ImageIndex &index) override; + void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override; + void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override; + angle::Result releaseAssociatedImage(const gl::Context *context, + const gl::ImageIndex &index, + Image11 *incomingImage) override; + void onLabelUpdate() override; + + struct LevelLayerRangeKey + { + LevelLayerRangeKey(int mipLevelIn, int layerIn, int numLayersIn) + : mipLevel(mipLevelIn), layer(layerIn), numLayers(numLayersIn) + {} + bool operator<(const LevelLayerRangeKey &other) const + { + if (mipLevel != other.mipLevel) + { + return mipLevel < other.mipLevel; + } + if (layer != other.layer) + { + return layer < other.layer; + } + return numLayers < other.numLayers; + } + int mipLevel; + int layer; + int numLayers; + }; + + protected: + angle::Result getSwizzleTexture(const gl::Context *context, + const TextureHelper11 **outTexture) override; + angle::Result getSwizzleRenderTarget(const gl::Context *context, + int mipLevel, + const d3d11::RenderTargetView **outRTV) override; + + angle::Result ensureDropStencilTexture(const gl::Context *context, + DropStencil *dropStencilOut) override; + + private: + angle::Result createSRVForSampler(const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) override; + angle::Result createSRVForImage(const gl::Context *context, + int level, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) override; + angle::Result createUAVForImage(const gl::Context *context, + int level, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedUAV *outUAV) override; + angle::Result createRenderTargetSRV(const gl::Context *context, + const TextureHelper11 &texture, + const gl::ImageIndex &index, + DXGI_FORMAT resourceFormat, + d3d11::SharedSRV *srv) const; + + std::map> mRenderTargets; + + TextureHelper11 mTexture; + + TextureHelper11 mSwizzleTexture; + gl::TexLevelArray mSwizzleRenderTargets; + + typedef std::map ImageMap; + ImageMap mAssociatedImages; +}; + +class TextureStorage11_2DMultisample final : public TextureStorage11ImmutableBase +{ + public: + TextureStorage11_2DMultisample(Renderer11 *renderer, + GLenum internalformat, + GLsizei width, + GLsizei height, + int levels, + int samples, + bool fixedSampleLocations, + const std::string &label); + ~TextureStorage11_2DMultisample() override; + + angle::Result onDestroy(const gl::Context *context) override; + + angle::Result getResource(const gl::Context *context, + const TextureHelper11 **outResource) override; + angle::Result findRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) const override; + angle::Result getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) override; + + angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override; + void onLabelUpdate() override; + + protected: + angle::Result getSwizzleTexture(const gl::Context *context, + const TextureHelper11 **outTexture) override; + angle::Result getSwizzleRenderTarget(const gl::Context *context, + int mipLevel, + const d3d11::RenderTargetView **outRTV) override; + + angle::Result ensureDropStencilTexture(const gl::Context *context, + DropStencil *dropStencilOut) override; + + angle::Result ensureTextureExists(const gl::Context *context, int mipLevels); + + private: + angle::Result createSRVForSampler(const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) override; + + TextureHelper11 mTexture; + std::unique_ptr mRenderTarget; + + unsigned int mSamples; + GLboolean mFixedSampleLocations; +}; + +class TextureStorage11_2DMultisampleArray final : public TextureStorage11ImmutableBase +{ + public: + TextureStorage11_2DMultisampleArray(Renderer11 *renderer, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels, + int samples, + bool fixedSampleLocations, + const std::string &label); + ~TextureStorage11_2DMultisampleArray() override; + + angle::Result onDestroy(const gl::Context *context) override; + + angle::Result getResource(const gl::Context *context, + const TextureHelper11 **outResource) override; + angle::Result findRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) const override; + angle::Result getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) override; + + angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override; + void onLabelUpdate() override; + + protected: + angle::Result getSwizzleTexture(const gl::Context *context, + const TextureHelper11 **outTexture) override; + angle::Result getSwizzleRenderTarget(const gl::Context *context, + int mipLevel, + const d3d11::RenderTargetView **outRTV) override; + + angle::Result ensureDropStencilTexture(const gl::Context *context, + DropStencil *dropStencilOut) override; + + angle::Result ensureTextureExists(const gl::Context *context, int mipLevels); + + private: + angle::Result createRenderTargetSRV(const gl::Context *context, + const TextureHelper11 &texture, + const gl::ImageIndex &index, + DXGI_FORMAT resourceFormat, + d3d11::SharedSRV *srv) const; + + angle::Result createSRVForSampler(const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) override; + + TextureHelper11 mTexture; + std::map> + mRenderTargets; + + unsigned int mSamples; + GLboolean mFixedSampleLocations; +}; + +class TextureStorage11_Buffer : public TextureStorage11 +{ + public: + TextureStorage11_Buffer(Renderer11 *renderer, + const gl::OffsetBindingPointer &buffer, + GLenum internalFormat, + const std::string &label); + ~TextureStorage11_Buffer() override; + + angle::Result getResource(const gl::Context *context, + const TextureHelper11 **outResource) override; + angle::Result getMippedResource(const gl::Context *context, + const TextureHelper11 **outResource) override; + angle::Result findRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) const override; + angle::Result getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) override; + + void onLabelUpdate() override; + + void associateImage(Image11 *image, const gl::ImageIndex &index) override; + void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override; + void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override; + angle::Result releaseAssociatedImage(const gl::Context *context, + const gl::ImageIndex &index, + Image11 *incomingImage) override; + + protected: + angle::Result getSwizzleTexture(const gl::Context *context, + const TextureHelper11 **outTexture) override; + angle::Result getSwizzleRenderTarget(const gl::Context *context, + int mipLevel, + const d3d11::RenderTargetView **outRTV) override; + + private: + angle::Result createSRVForSampler(const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) override; + angle::Result createSRVForImage(const gl::Context *context, + int level, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) override; + angle::Result createUAVForImage(const gl::Context *context, + int level, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedUAV *outUAV) override; + + angle::Result initTexture(const gl::Context *context); + + TextureHelper11 mTexture; + const gl::OffsetBindingPointer &mBuffer; + GLint64 mDataSize; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_TEXTURESTORAGE11_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.cpp new file mode 100644 index 0000000000..1dcd62cd45 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.cpp @@ -0,0 +1,131 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// TransformFeedbackD3D.cpp is a no-op implementation for both the D3D9 and D3D11 renderers. + +#include "libANGLE/renderer/d3d/d3d11/TransformFeedback11.h" + +#include "libANGLE/Buffer.h" +#include "libANGLE/renderer/d3d/d3d11/Buffer11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" + +namespace rx +{ + +TransformFeedback11::TransformFeedback11(const gl::TransformFeedbackState &state, + Renderer11 *renderer) + : TransformFeedbackImpl(state), + mRenderer(renderer), + mIsDirty(true), + mBuffers(state.getIndexedBuffers().size(), nullptr), + mBufferOffsets(state.getIndexedBuffers().size(), 0), + mSerial(mRenderer->generateSerial()) +{} + +TransformFeedback11::~TransformFeedback11() {} + +angle::Result TransformFeedback11::begin(const gl::Context *context, + gl::PrimitiveMode primitiveMode) +{ + // Reset all the cached offsets to the binding offsets + mIsDirty = true; + for (size_t bindingIdx = 0; bindingIdx < mBuffers.size(); bindingIdx++) + { + const auto &binding = mState.getIndexedBuffer(bindingIdx); + if (binding.get() != nullptr) + { + mBufferOffsets[bindingIdx] = static_cast(binding.getOffset()); + } + else + { + mBufferOffsets[bindingIdx] = 0; + } + } + mRenderer->getStateManager()->invalidateTransformFeedback(); + return angle::Result::Continue; +} + +angle::Result TransformFeedback11::end(const gl::Context *context) +{ + mRenderer->getStateManager()->invalidateTransformFeedback(); + if (mRenderer->getFeatures().flushAfterEndingTransformFeedback.enabled) + { + mRenderer->getDeviceContext()->Flush(); + } + return angle::Result::Continue; +} + +angle::Result TransformFeedback11::pause(const gl::Context *context) +{ + mRenderer->getStateManager()->invalidateTransformFeedback(); + return angle::Result::Continue; +} + +angle::Result TransformFeedback11::resume(const gl::Context *context) +{ + mRenderer->getStateManager()->invalidateTransformFeedback(); + return angle::Result::Continue; +} + +angle::Result TransformFeedback11::bindIndexedBuffer( + const gl::Context *context, + size_t index, + const gl::OffsetBindingPointer &binding) +{ + mIsDirty = true; + mBufferOffsets[index] = static_cast(binding.getOffset()); + mRenderer->getStateManager()->invalidateTransformFeedback(); + return angle::Result::Continue; +} + +void TransformFeedback11::onApply() +{ + mIsDirty = false; + + // Change all buffer offsets to -1 so that if any of them need to be re-applied, the are set to + // append + std::fill(mBufferOffsets.begin(), mBufferOffsets.end(), -1); +} + +bool TransformFeedback11::isDirty() const +{ + return mIsDirty; +} + +UINT TransformFeedback11::getNumSOBuffers() const +{ + return static_cast(mBuffers.size()); +} + +angle::Result TransformFeedback11::getSOBuffers(const gl::Context *context, + const std::vector **buffersOut) +{ + for (size_t bindingIdx = 0; bindingIdx < mBuffers.size(); bindingIdx++) + { + const auto &binding = mState.getIndexedBuffer(bindingIdx); + if (binding.get() != nullptr) + { + Buffer11 *storage = GetImplAs(binding.get()); + ANGLE_TRY(storage->getBuffer(context, BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK, + &mBuffers[bindingIdx])); + } + } + + *buffersOut = &mBuffers; + return angle::Result::Continue; +} + +const std::vector &TransformFeedback11::getSOBufferOffsets() const +{ + return mBufferOffsets; +} + +Serial TransformFeedback11::getSerial() const +{ + return mSerial; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.h new file mode 100644 index 0000000000..69ae90671b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.h @@ -0,0 +1,61 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// TransformFeedback11.h: Implements the abstract rx::TransformFeedbackImpl class. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_TRANSFORMFEEDBACK11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_TRANSFORMFEEDBACK11_H_ + +#include "common/platform.h" + +#include "libANGLE/Error.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/renderer/TransformFeedbackImpl.h" +#include "libANGLE/renderer/serial_utils.h" + +namespace rx +{ + +class Renderer11; + +class TransformFeedback11 : public TransformFeedbackImpl +{ + public: + TransformFeedback11(const gl::TransformFeedbackState &state, Renderer11 *renderer); + ~TransformFeedback11() override; + + angle::Result begin(const gl::Context *context, gl::PrimitiveMode primitiveMode) override; + angle::Result end(const gl::Context *context) override; + angle::Result pause(const gl::Context *context) override; + angle::Result resume(const gl::Context *context) override; + + angle::Result bindIndexedBuffer(const gl::Context *context, + size_t index, + const gl::OffsetBindingPointer &binding) override; + + void onApply(); + + bool isDirty() const; + + UINT getNumSOBuffers() const; + angle::Result getSOBuffers(const gl::Context *context, + const std::vector **buffersOut); + const std::vector &getSOBufferOffsets() const; + + Serial getSerial() const; + + private: + Renderer11 *mRenderer; + + bool mIsDirty; + std::vector mBuffers; + std::vector mBufferOffsets; + + Serial mSerial; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_TRANSFORMFEEDBACK11_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Trim11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Trim11.cpp new file mode 100644 index 0000000000..ac6d9a5220 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Trim11.cpp @@ -0,0 +1,103 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Trim11.cpp: Trim support utility class. + +#include "libANGLE/renderer/d3d/d3d11/Trim11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" + +#if defined(ANGLE_ENABLE_WINDOWS_UWP) +# include +# include +# include +using namespace Microsoft::WRL; +using namespace Microsoft::WRL::Wrappers; +using namespace ABI::Windows::ApplicationModel; +using namespace ABI::Windows::ApplicationModel::Core; +using namespace ABI::Windows::Foundation; +using namespace ABI::Windows::Foundation::Collections; +#endif + +namespace rx +{ + +Trim11::Trim11(rx::Renderer11 *renderer) : mRenderer(renderer) +{ + bool result = true; + result = registerForRendererTrimRequest(); + ASSERT(result); +} + +Trim11::~Trim11() +{ + unregisterForRendererTrimRequest(); +} + +void Trim11::trim() +{ + if (!mRenderer) + { + return; + } + +#if defined(ANGLE_ENABLE_WINDOWS_UWP) + ID3D11Device *device = mRenderer->getDevice(); + IDXGIDevice3 *dxgiDevice3 = d3d11::DynamicCastComObject(device); + if (dxgiDevice3) + { + dxgiDevice3->Trim(); + } + SafeRelease(dxgiDevice3); +#endif +} + +bool Trim11::registerForRendererTrimRequest() +{ +#if defined(ANGLE_ENABLE_WINDOWS_UWP) + ICoreApplication *coreApplication = nullptr; + HRESULT result = GetActivationFactory( + HStringReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(), + &coreApplication); + if (SUCCEEDED(result)) + { + auto suspendHandler = Callback>( + [this](IInspectable *, ISuspendingEventArgs *) -> HRESULT { + trim(); + return S_OK; + }); + result = + coreApplication->add_Suspending(suspendHandler.Get(), &mApplicationSuspendedEventToken); + } + SafeRelease(coreApplication); + + if (FAILED(result)) + { + return false; + } +#endif + return true; +} + +void Trim11::unregisterForRendererTrimRequest() +{ +#if defined(ANGLE_ENABLE_WINDOWS_UWP) + if (mApplicationSuspendedEventToken.value != 0) + { + ICoreApplication *coreApplication = nullptr; + if (SUCCEEDED(GetActivationFactory( + HStringReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(), + &coreApplication))) + { + coreApplication->remove_Suspending(mApplicationSuspendedEventToken); + } + mApplicationSuspendedEventToken.value = 0; + SafeRelease(coreApplication); + } +#endif +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Trim11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Trim11.h new file mode 100644 index 0000000000..eb1f3e7e13 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Trim11.h @@ -0,0 +1,43 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Trim11.h: Trim support utility class. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_TRIM11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_TRIM11_H_ + +#include "common/angleutils.h" +#include "libANGLE/Error.h" +#include "libANGLE/angletypes.h" + +#if defined(ANGLE_ENABLE_WINDOWS_UWP) +# include +#endif + +namespace rx +{ +class Renderer11; + +class Trim11 : angle::NonCopyable +{ + public: + explicit Trim11(Renderer11 *renderer); + ~Trim11(); + + private: + Renderer11 *mRenderer; +#if defined(ANGLE_ENABLE_WINDOWS_UWP) + EventRegistrationToken mApplicationSuspendedEventToken; +#endif + + void trim(); + bool registerForRendererTrimRequest(); + void unregisterForRendererTrimRequest(); +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_TRIM11_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexArray11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexArray11.cpp new file mode 100644 index 0000000000..a5f8b6a176 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexArray11.cpp @@ -0,0 +1,375 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// VertexArray11: +// Implementation of rx::VertexArray11. +// + +#include "libANGLE/renderer/d3d/d3d11/VertexArray11.h" + +#include "common/bitset_utils.h" +#include "libANGLE/Context.h" +#include "libANGLE/renderer/d3d/IndexBuffer.h" +#include "libANGLE/renderer/d3d/d3d11/Buffer11.h" +#include "libANGLE/renderer/d3d/d3d11/Context11.h" + +using namespace angle; + +namespace rx +{ +VertexArray11::VertexArray11(const gl::VertexArrayState &data) + : VertexArrayImpl(data), + mAttributeStorageTypes(data.getMaxAttribs(), VertexStorageType::CURRENT_VALUE), + mTranslatedAttribs(data.getMaxAttribs()), + mAppliedNumViewsToDivisor(1), + mCurrentElementArrayStorage(IndexStorageType::Invalid), + mCachedDestinationIndexType(gl::DrawElementsType::InvalidEnum) +{} + +VertexArray11::~VertexArray11() {} + +void VertexArray11::destroy(const gl::Context *context) {} + +// As VertexAttribPointer can modify both attribute and binding, we should also set other attributes +// that are also using this binding dirty. +#define ANGLE_VERTEX_DIRTY_ATTRIB_FUNC(INDEX) \ + case gl::VertexArray::DIRTY_BIT_ATTRIB_0 + INDEX: \ + if ((*attribBits)[INDEX][gl::VertexArray::DirtyAttribBitType::DIRTY_ATTRIB_POINTER]) \ + { \ + attributesToUpdate |= mState.getBindingToAttributesMask(INDEX); \ + } \ + else \ + { \ + attributesToUpdate.set(INDEX); \ + } \ + invalidateVertexBuffer = true; \ + (*attribBits)[INDEX].reset(); \ + break; + +#define ANGLE_VERTEX_DIRTY_BINDING_FUNC(INDEX) \ + case gl::VertexArray::DIRTY_BIT_BINDING_0 + INDEX: \ + attributesToUpdate |= mState.getBindingToAttributesMask(INDEX); \ + invalidateVertexBuffer = true; \ + (*bindingBits)[INDEX].reset(); \ + break; + +#define ANGLE_VERTEX_DIRTY_BUFFER_DATA_FUNC(INDEX) \ + case gl::VertexArray::DIRTY_BIT_BUFFER_DATA_0 + INDEX: \ + if (mAttributeStorageTypes[INDEX] == VertexStorageType::STATIC) \ + { \ + invalidateVertexBuffer = true; \ + mAttribsToTranslate.set(INDEX); \ + } \ + break; + +angle::Result VertexArray11::syncState(const gl::Context *context, + const gl::VertexArray::DirtyBits &dirtyBits, + gl::VertexArray::DirtyAttribBitsArray *attribBits, + gl::VertexArray::DirtyBindingBitsArray *bindingBits) +{ + ASSERT(dirtyBits.any()); + + Renderer11 *renderer = GetImplAs(context)->getRenderer(); + StateManager11 *stateManager = renderer->getStateManager(); + + // Generate a state serial. This serial is used in the program class to validate the cached + // input layout, and skip recomputation in the fast path. + mCurrentStateSerial = renderer->generateSerial(); + + bool invalidateVertexBuffer = false; + + gl::AttributesMask attributesToUpdate; + + // Make sure we trigger re-translation for static index or vertex data. + for (size_t dirtyBit : dirtyBits) + { + switch (dirtyBit) + { + case gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER: + case gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER_DATA: + { + mLastDrawElementsType.reset(); + mLastDrawElementsIndices.reset(); + mLastPrimitiveRestartEnabled.reset(); + mCachedIndexInfo.reset(); + break; + } + + ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_ATTRIB_FUNC) + ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_BINDING_FUNC) + ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_BUFFER_DATA_FUNC) + + default: + UNREACHABLE(); + break; + } + } + + for (size_t attribIndex : attributesToUpdate) + { + updateVertexAttribStorage(context, stateManager, attribIndex); + } + + if (invalidateVertexBuffer) + { + // TODO(jmadill): Individual attribute invalidation. + stateManager->invalidateVertexBuffer(); + } + + return angle::Result::Continue; +} + +angle::Result VertexArray11::syncStateForDraw(const gl::Context *context, + GLint firstVertex, + GLsizei vertexOrIndexCount, + gl::DrawElementsType indexTypeOrInvalid, + const void *indices, + GLsizei instances, + GLint baseVertex, + GLuint baseInstance, + bool promoteDynamic) +{ + Renderer11 *renderer = GetImplAs(context)->getRenderer(); + StateManager11 *stateManager = renderer->getStateManager(); + + const gl::State &glState = context->getState(); + const gl::Program *program = glState.getProgram(); + ASSERT(program); + const gl::ProgramExecutable &executable = program->getExecutable(); + + mAppliedNumViewsToDivisor = (program->usesMultiview() ? program->getNumViews() : 1); + + if (mAttribsToTranslate.any()) + { + const gl::AttributesMask &activeLocations = executable.getActiveAttribLocationsMask(); + gl::AttributesMask activeDirtyAttribs = (mAttribsToTranslate & activeLocations); + if (activeDirtyAttribs.any()) + { + ANGLE_TRY(updateDirtyAttribs(context, activeDirtyAttribs)); + stateManager->invalidateInputLayout(); + } + } + + if (mDynamicAttribsMask.any()) + { + const gl::AttributesMask &activeLocations = executable.getActiveAttribLocationsMask(); + gl::AttributesMask activeDynamicAttribs = (mDynamicAttribsMask & activeLocations); + + if (activeDynamicAttribs.any()) + { + ANGLE_TRY(updateDynamicAttribs(context, stateManager->getVertexDataManager(), + firstVertex, vertexOrIndexCount, indexTypeOrInvalid, + indices, instances, baseVertex, baseInstance, + promoteDynamic, activeDynamicAttribs)); + stateManager->invalidateInputLayout(); + } + } + + if (indexTypeOrInvalid != gl::DrawElementsType::InvalidEnum) + { + bool restartEnabled = context->getState().isPrimitiveRestartEnabled(); + if (!mLastDrawElementsType.valid() || mLastDrawElementsType.value() != indexTypeOrInvalid || + mLastDrawElementsIndices.value() != indices || + mLastPrimitiveRestartEnabled.value() != restartEnabled) + { + mLastDrawElementsType = indexTypeOrInvalid; + mLastDrawElementsIndices = indices; + mLastPrimitiveRestartEnabled = restartEnabled; + + ANGLE_TRY(updateElementArrayStorage(context, vertexOrIndexCount, indexTypeOrInvalid, + indices, restartEnabled)); + stateManager->invalidateIndexBuffer(); + } + else if (mCurrentElementArrayStorage == IndexStorageType::Dynamic) + { + stateManager->invalidateIndexBuffer(); + } + } + + return angle::Result::Continue; +} + +angle::Result VertexArray11::updateElementArrayStorage(const gl::Context *context, + GLsizei indexCount, + gl::DrawElementsType indexType, + const void *indices, + bool restartEnabled) +{ + bool usePrimitiveRestartWorkaround = UsePrimitiveRestartWorkaround(restartEnabled, indexType); + + ANGLE_TRY(GetIndexTranslationDestType(context, indexCount, indexType, indices, + usePrimitiveRestartWorkaround, + &mCachedDestinationIndexType)); + + unsigned int offset = static_cast(reinterpret_cast(indices)); + + mCurrentElementArrayStorage = + ClassifyIndexStorage(context->getState(), mState.getElementArrayBuffer(), indexType, + mCachedDestinationIndexType, offset); + + return angle::Result::Continue; +} + +void VertexArray11::updateVertexAttribStorage(const gl::Context *context, + StateManager11 *stateManager, + size_t attribIndex) +{ + const gl::VertexAttribute &attrib = mState.getVertexAttribute(attribIndex); + const gl::VertexBinding &binding = mState.getBindingFromAttribIndex(attribIndex); + + VertexStorageType newStorageType = ClassifyAttributeStorage(context, attrib, binding); + + // Note: having an unchanged storage type doesn't mean the attribute is clean. + mAttribsToTranslate.set(attribIndex, newStorageType != VertexStorageType::DYNAMIC); + + if (mAttributeStorageTypes[attribIndex] == newStorageType) + return; + + mAttributeStorageTypes[attribIndex] = newStorageType; + mDynamicAttribsMask.set(attribIndex, newStorageType == VertexStorageType::DYNAMIC); + + if (newStorageType == VertexStorageType::CURRENT_VALUE) + { + stateManager->invalidateCurrentValueAttrib(attribIndex); + } +} + +bool VertexArray11::hasActiveDynamicAttrib(const gl::Context *context) +{ + const auto &activeLocations = + context->getState().getProgramExecutable()->getActiveAttribLocationsMask(); + gl::AttributesMask activeDynamicAttribs = (mDynamicAttribsMask & activeLocations); + return activeDynamicAttribs.any(); +} + +angle::Result VertexArray11::updateDirtyAttribs(const gl::Context *context, + const gl::AttributesMask &activeDirtyAttribs) +{ + const auto &glState = context->getState(); + const auto &attribs = mState.getVertexAttributes(); + const auto &bindings = mState.getVertexBindings(); + + for (size_t dirtyAttribIndex : activeDirtyAttribs) + { + auto *translatedAttrib = &mTranslatedAttribs[dirtyAttribIndex]; + const auto ¤tValue = glState.getVertexAttribCurrentValue(dirtyAttribIndex); + + // Record basic attrib info + translatedAttrib->attribute = &attribs[dirtyAttribIndex]; + translatedAttrib->binding = &bindings[translatedAttrib->attribute->bindingIndex]; + translatedAttrib->currentValueType = currentValue.Type; + translatedAttrib->divisor = + translatedAttrib->binding->getDivisor() * mAppliedNumViewsToDivisor; + + switch (mAttributeStorageTypes[dirtyAttribIndex]) + { + case VertexStorageType::DIRECT: + VertexDataManager::StoreDirectAttrib(context, translatedAttrib); + break; + case VertexStorageType::STATIC: + { + ANGLE_TRY(VertexDataManager::StoreStaticAttrib(context, translatedAttrib)); + break; + } + case VertexStorageType::CURRENT_VALUE: + // Current value attribs are managed by the StateManager11. + break; + default: + UNREACHABLE(); + break; + } + + // Make sure we reset the dirty bit after the switch because STATIC can early exit. + mAttribsToTranslate.reset(dirtyAttribIndex); + } + + return angle::Result::Continue; +} + +angle::Result VertexArray11::updateDynamicAttribs(const gl::Context *context, + VertexDataManager *vertexDataManager, + GLint firstVertex, + GLsizei vertexOrIndexCount, + gl::DrawElementsType indexTypeOrInvalid, + const void *indices, + GLsizei instances, + GLint baseVertex, + GLuint baseInstance, + bool promoteDynamic, + const gl::AttributesMask &activeDynamicAttribs) +{ + const auto &glState = context->getState(); + const auto &attribs = mState.getVertexAttributes(); + const auto &bindings = mState.getVertexBindings(); + + GLint startVertex; + size_t vertexCount; + ANGLE_TRY(GetVertexRangeInfo(context, firstVertex, vertexOrIndexCount, indexTypeOrInvalid, + indices, baseVertex, &startVertex, &vertexCount)); + + for (size_t dynamicAttribIndex : activeDynamicAttribs) + { + auto *dynamicAttrib = &mTranslatedAttribs[dynamicAttribIndex]; + const auto ¤tValue = glState.getVertexAttribCurrentValue(dynamicAttribIndex); + + // Record basic attrib info + dynamicAttrib->attribute = &attribs[dynamicAttribIndex]; + dynamicAttrib->binding = &bindings[dynamicAttrib->attribute->bindingIndex]; + dynamicAttrib->currentValueType = currentValue.Type; + dynamicAttrib->divisor = dynamicAttrib->binding->getDivisor() * mAppliedNumViewsToDivisor; + } + + ANGLE_TRY(vertexDataManager->storeDynamicAttribs(context, &mTranslatedAttribs, + activeDynamicAttribs, startVertex, vertexCount, + instances, baseInstance)); + + if (promoteDynamic) + { + VertexDataManager::PromoteDynamicAttribs(context, mTranslatedAttribs, activeDynamicAttribs, + vertexCount); + } + + return angle::Result::Continue; +} + +const std::vector &VertexArray11::getTranslatedAttribs() const +{ + return mTranslatedAttribs; +} + +void VertexArray11::markAllAttributeDivisorsForAdjustment(int numViews) +{ + if (mAppliedNumViewsToDivisor != numViews) + { + mAppliedNumViewsToDivisor = numViews; + mAttribsToTranslate.set(); + // mDynamicAttribsMask may have already been set (updateVertexAttribStorage + // We don't want to override DYNAMIC attribs as they will be handled separately. + mAttribsToTranslate = mAttribsToTranslate ^ mDynamicAttribsMask; + } +} + +const TranslatedIndexData &VertexArray11::getCachedIndexInfo() const +{ + ASSERT(mCachedIndexInfo.valid()); + return mCachedIndexInfo.value(); +} + +void VertexArray11::updateCachedIndexInfo(const TranslatedIndexData &indexInfo) +{ + mCachedIndexInfo = indexInfo; +} + +bool VertexArray11::isCachedIndexInfoValid() const +{ + return mCachedIndexInfo.valid(); +} + +gl::DrawElementsType VertexArray11::getCachedDestinationIndexType() const +{ + return mCachedDestinationIndexType; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h new file mode 100644 index 0000000000..a0ac5d74f1 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h @@ -0,0 +1,112 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// VertexArray11.h: Defines the rx::VertexArray11 class which implements rx::VertexArrayImpl. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_VERTEXARRAY11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_VERTEXARRAY11_H_ + +#include "libANGLE/Framebuffer.h" +#include "libANGLE/renderer/VertexArrayImpl.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" + +namespace rx +{ +class Renderer11; + +class VertexArray11 : public VertexArrayImpl +{ + public: + VertexArray11(const gl::VertexArrayState &data); + ~VertexArray11() override; + void destroy(const gl::Context *context) override; + + // Does not apply any state updates - these are done in syncStateForDraw which as access to + // the draw call parameters. + angle::Result syncState(const gl::Context *context, + const gl::VertexArray::DirtyBits &dirtyBits, + gl::VertexArray::DirtyAttribBitsArray *attribBits, + gl::VertexArray::DirtyBindingBitsArray *bindingBits) override; + + // Applied buffer pointers are updated here. + angle::Result syncStateForDraw(const gl::Context *context, + GLint firstVertex, + GLsizei vertexOrIndexCount, + gl::DrawElementsType indexTypeOrInvalid, + const void *indices, + GLsizei instances, + GLint baseVertex, + GLuint baseInstance, + bool promoteDynamic); + + // This will check the dynamic attribs mask. + bool hasActiveDynamicAttrib(const gl::Context *context); + + const std::vector &getTranslatedAttribs() const; + + Serial getCurrentStateSerial() const { return mCurrentStateSerial; } + + // In case of a multi-view program change, we have to update all attributes so that the divisor + // is adjusted. + void markAllAttributeDivisorsForAdjustment(int numViews); + + const TranslatedIndexData &getCachedIndexInfo() const; + void updateCachedIndexInfo(const TranslatedIndexData &indexInfo); + bool isCachedIndexInfoValid() const; + + gl::DrawElementsType getCachedDestinationIndexType() const; + + private: + void updateVertexAttribStorage(const gl::Context *context, + StateManager11 *stateManager, + size_t attribIndex); + angle::Result updateDirtyAttribs(const gl::Context *context, + const gl::AttributesMask &activeDirtyAttribs); + angle::Result updateDynamicAttribs(const gl::Context *context, + VertexDataManager *vertexDataManager, + GLint firstVertex, + GLsizei vertexOrIndexCount, + gl::DrawElementsType indexTypeOrInvalid, + const void *indices, + GLsizei instances, + GLint baseVertex, + GLuint baseInstance, + bool promoteDynamic, + const gl::AttributesMask &activeDynamicAttribs); + + angle::Result updateElementArrayStorage(const gl::Context *context, + GLsizei indexCount, + gl::DrawElementsType indexType, + const void *indices, + bool restartEnabled); + + std::vector mAttributeStorageTypes; + std::vector mTranslatedAttribs; + + // The mask of attributes marked as dynamic. + gl::AttributesMask mDynamicAttribsMask; + + // A set of attributes we know are dirty, and need to be re-translated. + gl::AttributesMask mAttribsToTranslate; + + Serial mCurrentStateSerial; + + // The numViews value used to adjust the divisor. + int mAppliedNumViewsToDivisor; + + // If the index buffer needs re-streaming. + Optional mLastDrawElementsType; + Optional mLastDrawElementsIndices; + Optional mLastPrimitiveRestartEnabled; + IndexStorageType mCurrentElementArrayStorage; + Optional mCachedIndexInfo; + gl::DrawElementsType mCachedDestinationIndexType; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_VERTEXARRAY11_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp new file mode 100644 index 0000000000..9daa8f83f9 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp @@ -0,0 +1,167 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// VertexBuffer11.cpp: Defines the D3D11 VertexBuffer implementation. + +#include "libANGLE/renderer/d3d/d3d11/VertexBuffer11.h" + +#include "libANGLE/Buffer.h" +#include "libANGLE/Context.h" +#include "libANGLE/VertexAttribute.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/d3d11/Buffer11.h" +#include "libANGLE/renderer/d3d/d3d11/Context11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" + +namespace rx +{ + +VertexBuffer11::VertexBuffer11(Renderer11 *const renderer) + : mRenderer(renderer), + mBuffer(), + mBufferSize(0), + mDynamicUsage(false), + mMappedResourceData(nullptr) +{} + +VertexBuffer11::~VertexBuffer11() +{ + ASSERT(mMappedResourceData == nullptr); +} + +angle::Result VertexBuffer11::initialize(const gl::Context *context, + unsigned int size, + bool dynamicUsage) +{ + mBuffer.reset(); + updateSerial(); + + if (size > 0) + { + D3D11_BUFFER_DESC bufferDesc; + bufferDesc.ByteWidth = size; + bufferDesc.Usage = D3D11_USAGE_DYNAMIC; + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + bufferDesc.MiscFlags = 0; + bufferDesc.StructureByteStride = 0; + + ANGLE_TRY(mRenderer->allocateResource(GetImplAs(context), bufferDesc, &mBuffer)); + + if (dynamicUsage) + { + mBuffer.setInternalName("VertexBuffer11(dynamic)"); + } + else + { + mBuffer.setInternalName("VertexBuffer11(static)"); + } + } + + mBufferSize = size; + mDynamicUsage = dynamicUsage; + + return angle::Result::Continue; +} + +angle::Result VertexBuffer11::mapResource(const gl::Context *context) +{ + if (mMappedResourceData == nullptr) + { + D3D11_MAPPED_SUBRESOURCE mappedResource; + + ANGLE_TRY(mRenderer->mapResource(context, mBuffer.get(), 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, + &mappedResource)); + + mMappedResourceData = static_cast(mappedResource.pData); + } + + return angle::Result::Continue; +} + +void VertexBuffer11::hintUnmapResource() +{ + if (mMappedResourceData != nullptr) + { + ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); + dxContext->Unmap(mBuffer.get(), 0); + + mMappedResourceData = nullptr; + } +} + +angle::Result VertexBuffer11::storeVertexAttributes(const gl::Context *context, + const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + gl::VertexAttribType currentValueType, + GLint start, + size_t count, + GLsizei instances, + unsigned int offset, + const uint8_t *sourceData) +{ + ASSERT(mBuffer.valid()); + + int inputStride = static_cast(ComputeVertexAttributeStride(attrib, binding)); + + // This will map the resource if it isn't already mapped. + ANGLE_TRY(mapResource(context)); + + uint8_t *output = mMappedResourceData + offset; + + const uint8_t *input = sourceData; + + if (instances == 0 || binding.getDivisor() == 0) + { + input += inputStride * start; + } + + angle::FormatID vertexFormatID = gl::GetVertexFormatID(attrib, currentValueType); + const D3D_FEATURE_LEVEL featureLevel = mRenderer->getRenderer11DeviceCaps().featureLevel; + const d3d11::VertexFormat &vertexFormatInfo = + d3d11::GetVertexFormatInfo(vertexFormatID, featureLevel); + ASSERT(vertexFormatInfo.copyFunction != nullptr); + vertexFormatInfo.copyFunction(input, inputStride, count, output); + + return angle::Result::Continue; +} + +unsigned int VertexBuffer11::getBufferSize() const +{ + return mBufferSize; +} + +angle::Result VertexBuffer11::setBufferSize(const gl::Context *context, unsigned int size) +{ + if (size > mBufferSize) + { + return initialize(context, size, mDynamicUsage); + } + + return angle::Result::Continue; +} + +angle::Result VertexBuffer11::discard(const gl::Context *context) +{ + ASSERT(mBuffer.valid()); + + D3D11_MAPPED_SUBRESOURCE mappedResource; + ANGLE_TRY(mRenderer->mapResource(context, mBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, + &mappedResource)); + + mRenderer->getDeviceContext()->Unmap(mBuffer.get(), 0); + + return angle::Result::Continue; +} + +const d3d11::Buffer &VertexBuffer11::getBuffer() const +{ + return mBuffer; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.h new file mode 100644 index 0000000000..46b52cb602 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.h @@ -0,0 +1,65 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// VertexBuffer11.h: Defines the D3D11 VertexBuffer implementation. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_VERTEXBUFFER11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_VERTEXBUFFER11_H_ + +#include + +#include "libANGLE/renderer/d3d/VertexBuffer.h" +#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h" + +namespace rx +{ +class Renderer11; + +class VertexBuffer11 : public VertexBuffer +{ + public: + explicit VertexBuffer11(Renderer11 *const renderer); + + angle::Result initialize(const gl::Context *context, + unsigned int size, + bool dynamicUsage) override; + + // Warning: you should ensure binding really matches attrib.bindingIndex before using this + // function. + angle::Result storeVertexAttributes(const gl::Context *context, + const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + gl::VertexAttribType currentValueType, + GLint start, + size_t count, + GLsizei instances, + unsigned int offset, + const uint8_t *sourceData) override; + + unsigned int getBufferSize() const override; + angle::Result setBufferSize(const gl::Context *context, unsigned int size) override; + angle::Result discard(const gl::Context *context) override; + + void hintUnmapResource() override; + + const d3d11::Buffer &getBuffer() const; + + private: + ~VertexBuffer11() override; + angle::Result mapResource(const gl::Context *context); + + Renderer11 *const mRenderer; + + d3d11::Buffer mBuffer; + unsigned int mBufferSize; + bool mDynamicUsage; + + uint8_t *mMappedResourceData; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_VERTEXBUFFER11_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/converged/CompositorNativeWindow11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/converged/CompositorNativeWindow11.cpp new file mode 100644 index 0000000000..0e64f78d53 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/converged/CompositorNativeWindow11.cpp @@ -0,0 +1,457 @@ +// +// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// CompositorNativeWindow11.cpp: Implementation of NativeWindow11 using Windows.UI.Composition APIs +// which work in both Win32 and WinRT contexts. + +#include "libANGLE/renderer/d3d/d3d11/converged/CompositorNativeWindow11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" + +#include "common/debug.h" + +using namespace Microsoft::WRL; + +namespace rx +{ + +CompositorNativeWindow11::CompositorNativeWindow11(EGLNativeWindowType window, bool hasAlpha) + : NativeWindow11(window), mHasAlpha(hasAlpha) +{ + ABI::Windows::UI::Composition::ISpriteVisual *inspPtr = + reinterpret_cast(window); + mHostVisual = Microsoft::WRL::ComPtr{inspPtr}; +} + +CompositorNativeWindow11::~CompositorNativeWindow11() = default; + +bool CompositorNativeWindow11::initialize() +{ + return true; +} + +bool CompositorNativeWindow11::getClientRect(LPRECT rect) const +{ + ComPtr visual; + mHostVisual.As(&visual); + + ABI::Windows::Foundation::Numerics::Vector2 size; + HRESULT hr = visual->get_Size(&size); + if (FAILED(hr)) + { + return false; + } + + ABI::Windows::Foundation::Numerics::Vector3 offset; + hr = visual->get_Offset(&offset); + if (FAILED(hr)) + { + return false; + } + + rect->top = static_cast(offset.Y); + rect->left = static_cast(offset.X); + rect->right = static_cast(offset.X) + static_cast(size.X); + rect->bottom = static_cast(offset.Y) + static_cast(size.Y); + + return true; +} + +bool CompositorNativeWindow11::isIconic() const +{ + return false; +} + +HRESULT CompositorNativeWindow11::createSwapChain(ID3D11Device *device, + IDXGIFactory *factory, + DXGI_FORMAT format, + UINT width, + UINT height, + UINT samples, + IDXGISwapChain **swapChain) +{ + if (device == nullptr || factory == nullptr || swapChain == nullptr || width == 0 || + height == 0) + { + return E_INVALIDARG; + } + + HRESULT hr{E_FAIL}; + + ComPtr hostVisual; + hr = mHostVisual.As(&hostVisual); + if (FAILED(hr)) + { + return hr; + } + + Microsoft::WRL::ComPtr compositor; + hr = hostVisual->get_Compositor(&compositor); + if (FAILED(hr)) + { + return hr; + } + + ComPtr interop; + + hr = compositor.As(&interop); + if (FAILED(hr)) + { + return hr; + } + + ComPtr factory2; + factory2.Attach(d3d11::DynamicCastComObject(factory)); + + DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {}; + swapChainDesc.Width = width; + swapChainDesc.Height = height; + swapChainDesc.Format = format; + swapChainDesc.Stereo = FALSE; + swapChainDesc.SampleDesc.Count = 1; + swapChainDesc.SampleDesc.Quality = 0; + swapChainDesc.BufferUsage = + DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER | DXGI_USAGE_SHADER_INPUT; + swapChainDesc.BufferCount = 2; + swapChainDesc.Scaling = DXGI_SCALING_STRETCH; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; + swapChainDesc.AlphaMode = mHasAlpha ? DXGI_ALPHA_MODE_PREMULTIPLIED : DXGI_ALPHA_MODE_IGNORE; +#ifndef ANGLE_ENABLE_WINDOWS_UWP + swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG::DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT; +#endif + Microsoft::WRL::ComPtr swapChain1; + hr = factory2->CreateSwapChainForComposition(device, &swapChainDesc, nullptr, &swapChain1); + if (SUCCEEDED(hr)) + { + swapChain1.CopyTo(swapChain); + } + + hr = interop->CreateCompositionSurfaceForSwapChain(swapChain1.Get(), &mSurface); + if (FAILED(hr)) + { + return hr; + } + + hr = compositor->CreateSurfaceBrushWithSurface(mSurface.Get(), &mSurfaceBrush); + if (FAILED(hr)) + { + return hr; + } + + hr = mSurfaceBrush.As(&mCompositionBrush); + if (FAILED(hr)) + { + return hr; + } + + hr = mHostVisual->put_Brush(mCompositionBrush.Get()); + if (FAILED(hr)) + { + return hr; + } + + return hr; +} + +void CompositorNativeWindow11::commitChange() +{ + // Windows::UI::Composition uses an implicit commit model hence no action needed here +} + +// static +bool CompositorNativeWindow11::IsValidNativeWindow(EGLNativeWindowType window) +{ + return IsSupportedWinRelease() && IsSpriteVisual(window); +} + +// static +bool CompositorNativeWindow11::IsSupportedWinRelease() +{ + RoHelper helper; + if (!helper.WinRtAvailable()) + { + return false; + } + + return helper.SupportedWindowsRelease(); +} + +bool CompositorNativeWindow11::IsSpriteVisual(EGLNativeWindowType window) +{ + RoHelper helper; + + ABI::Windows::UI::Composition::ISpriteVisual *inspp = + reinterpret_cast(window); + HSTRING className, spriteClassName; + HSTRING_HEADER spriteClassNameHeader; + + auto hr = helper.GetStringReference(RuntimeClass_Windows_UI_Composition_SpriteVisual, + &spriteClassName, &spriteClassNameHeader); + if (FAILED(hr)) + { + return false; + } + + hr = inspp->GetRuntimeClassName(&className); + if (FAILED(hr)) + { + return false; + } + + INT32 result = -1; + hr = helper.WindowsCompareStringOrdinal(className, spriteClassName, &result); + + helper.WindowsDeleteString(className); + + if (FAILED(hr)) + { + return false; + } + + if (result == 0) + { + return true; + } + + return false; +} + +// RoHelperImpl + +template +bool AssignProcAddress(HMODULE comBaseModule, const char *name, T *&outProc) +{ + outProc = reinterpret_cast(GetProcAddress(comBaseModule, name)); + return *outProc != nullptr; +} + +RoHelper::RoHelper() + : mFpWindowsCreateStringReference(nullptr), + mFpGetActivationFactory(nullptr), + mFpWindowsCompareStringOrdinal(nullptr), + mFpCreateDispatcherQueueController(nullptr), + mFpWindowsDeleteString(nullptr), + mFpRoInitialize(nullptr), + mFpRoUninitialize(nullptr), + mWinRtAvailable(false), + mWinRtInitialized(false), + mComBaseModule(nullptr), + mCoreMessagingModule(nullptr) +{ + +#ifdef ANGLE_ENABLE_WINDOWS_UWP + mFpWindowsCreateStringReference = &::WindowsCreateStringReference; + mFpRoInitialize = &::RoInitialize; + mFpRoUninitialize = &::RoUninitialize; + mFpWindowsDeleteString = &::WindowsDeleteString; + mFpGetActivationFactory = &::RoGetActivationFactory; + mFpWindowsCompareStringOrdinal = &::WindowsCompareStringOrdinal; + mFpCreateDispatcherQueueController = &::CreateDispatcherQueueController; + mWinRtAvailable = true; +#else + + mComBaseModule = LoadLibraryA("ComBase.dll"); + + if (mComBaseModule == nullptr) + { + return; + } + + if (!AssignProcAddress(mComBaseModule, "WindowsCreateStringReference", + mFpWindowsCreateStringReference)) + { + return; + } + + if (!AssignProcAddress(mComBaseModule, "RoGetActivationFactory", mFpGetActivationFactory)) + { + return; + } + + if (!AssignProcAddress(mComBaseModule, "WindowsCompareStringOrdinal", + mFpWindowsCompareStringOrdinal)) + { + return; + } + + if (!AssignProcAddress(mComBaseModule, "WindowsDeleteString", mFpWindowsDeleteString)) + { + return; + } + + if (!AssignProcAddress(mComBaseModule, "RoInitialize", mFpRoInitialize)) + { + return; + } + + if (!AssignProcAddress(mComBaseModule, "RoUninitialize", mFpRoUninitialize)) + { + return; + } + + mCoreMessagingModule = LoadLibraryA("coremessaging.dll"); + + if (mCoreMessagingModule == nullptr) + { + return; + } + + if (!AssignProcAddress(mCoreMessagingModule, "CreateDispatcherQueueController", + mFpCreateDispatcherQueueController)) + { + return; + } + + auto result = RoInitialize(RO_INIT_MULTITHREADED); + + if (SUCCEEDED(result) || result == RPC_E_CHANGED_MODE) + { + mWinRtAvailable = true; + + if (SUCCEEDED(result)) + { + mWinRtInitialized = true; + } + } +#endif +} + +RoHelper::~RoHelper() +{ +#ifndef ANGLE_ENABLE_WINDOWS_UWP + if (mWinRtInitialized) + { + RoUninitialize(); + } + + if (mCoreMessagingModule != nullptr) + { + FreeLibrary(mCoreMessagingModule); + mCoreMessagingModule = nullptr; + } + + if (mComBaseModule != nullptr) + { + FreeLibrary(mComBaseModule); + mComBaseModule = nullptr; + } +#endif +} + +bool RoHelper::WinRtAvailable() const +{ + return mWinRtAvailable; +} + +bool RoHelper::SupportedWindowsRelease() +{ + if (!mWinRtAvailable) + { + return false; + } + + HSTRING className, contractName; + HSTRING_HEADER classNameHeader, contractNameHeader; + boolean isSupported = false; + + HRESULT hr = GetStringReference(RuntimeClass_Windows_Foundation_Metadata_ApiInformation, + &className, &classNameHeader); + + if (FAILED(hr)) + { + return !!isSupported; + } + + Microsoft::WRL::ComPtr api; + + hr = GetActivationFactory( + className, __uuidof(ABI::Windows::Foundation::Metadata::IApiInformationStatics), &api); + + if (FAILED(hr)) + { + return !!isSupported; + } + + hr = GetStringReference(L"Windows.Foundation.UniversalApiContract", &contractName, + &contractNameHeader); + if (FAILED(hr)) + { + return !!isSupported; + } + + api->IsApiContractPresentByMajor(contractName, 6, &isSupported); + + return !!isSupported; +} + +HRESULT RoHelper::GetStringReference(PCWSTR source, HSTRING *act, HSTRING_HEADER *header) +{ + if (!mWinRtAvailable) + { + return E_FAIL; + } + + const wchar_t *str = static_cast(source); + + unsigned int length; + HRESULT hr = SizeTToUInt32(::wcslen(str), &length); + if (FAILED(hr)) + { + return hr; + } + + return mFpWindowsCreateStringReference(source, length, header, act); +} + +HRESULT RoHelper::GetActivationFactory(const HSTRING act, const IID &interfaceId, void **fac) +{ + if (!mWinRtAvailable) + { + return E_FAIL; + } + auto hr = mFpGetActivationFactory(act, interfaceId, fac); + return hr; +} + +HRESULT RoHelper::WindowsCompareStringOrdinal(HSTRING one, HSTRING two, int *result) +{ + if (!mWinRtAvailable) + { + return E_FAIL; + } + return mFpWindowsCompareStringOrdinal(one, two, result); +} + +HRESULT RoHelper::CreateDispatcherQueueController( + DispatcherQueueOptions options, + ABI::Windows::System::IDispatcherQueueController **dispatcherQueueController) +{ + if (!mWinRtAvailable) + { + return E_FAIL; + } + return mFpCreateDispatcherQueueController(options, dispatcherQueueController); +} + +HRESULT RoHelper::WindowsDeleteString(HSTRING one) +{ + if (!mWinRtAvailable) + { + return E_FAIL; + } + return mFpWindowsDeleteString(one); +} + +HRESULT RoHelper::RoInitialize(RO_INIT_TYPE type) +{ + return mFpRoInitialize(type); +} + +void RoHelper::RoUninitialize() +{ + mFpRoUninitialize(); +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/converged/CompositorNativeWindow11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/converged/CompositorNativeWindow11.h new file mode 100644 index 0000000000..82857322e0 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/converged/CompositorNativeWindow11.h @@ -0,0 +1,116 @@ +// +// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// CompositorNativeWindow11.h: Implementation of NativeWindow11 using Windows.UI.Composition APIs +// which work in both Win32 and WinRT contexts. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_CONVERGED_COMPOSITORNATIVEWINDOW11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_CONVERGED_COMPOSITORNATIVEWINDOW11_H_ + +#include "libANGLE/renderer/d3d/d3d11/NativeWindow11.h" + +#include +#include +#include +#include +#include +#include + +namespace rx +{ + +class RoHelper +{ + public: + RoHelper(); + ~RoHelper(); + bool WinRtAvailable() const; + bool SupportedWindowsRelease(); + HRESULT GetStringReference(PCWSTR source, HSTRING *act, HSTRING_HEADER *header); + HRESULT GetActivationFactory(const HSTRING act, const IID &interfaceId, void **fac); + HRESULT WindowsCompareStringOrdinal(HSTRING one, HSTRING two, int *result); + HRESULT CreateDispatcherQueueController( + DispatcherQueueOptions options, + ABI::Windows::System::IDispatcherQueueController **dispatcherQueueController); + HRESULT WindowsDeleteString(HSTRING one); + HRESULT RoInitialize(RO_INIT_TYPE type); + void RoUninitialize(); + + private: + using WindowsCreateStringReference_ = HRESULT __stdcall(PCWSTR, + UINT32, + HSTRING_HEADER *, + HSTRING *); + + using GetActivationFactory_ = HRESULT __stdcall(HSTRING, REFIID, void **); + + using WindowsCompareStringOrginal_ = HRESULT __stdcall(HSTRING, HSTRING, int *); + + using WindowsDeleteString_ = HRESULT __stdcall(HSTRING); + + using CreateDispatcherQueueController_ = + HRESULT __stdcall(DispatcherQueueOptions, + ABI::Windows::System::IDispatcherQueueController **); + + using RoInitialize_ = HRESULT __stdcall(RO_INIT_TYPE); + using RoUninitialize_ = void __stdcall(); + + WindowsCreateStringReference_ *mFpWindowsCreateStringReference; + GetActivationFactory_ *mFpGetActivationFactory; + WindowsCompareStringOrginal_ *mFpWindowsCompareStringOrdinal; + CreateDispatcherQueueController_ *mFpCreateDispatcherQueueController; + WindowsDeleteString_ *mFpWindowsDeleteString; + RoInitialize_ *mFpRoInitialize; + RoUninitialize_ *mFpRoUninitialize; + + bool mWinRtAvailable; + bool mWinRtInitialized; + + HMODULE mComBaseModule; + HMODULE mCoreMessagingModule; +}; + +class CompositorNativeWindow11 : public NativeWindow11 +{ + public: + CompositorNativeWindow11(EGLNativeWindowType window, bool hasAlpha); + ~CompositorNativeWindow11() override; + + bool initialize() override; + bool getClientRect(LPRECT rect) const override; + bool isIconic() const override; + + HRESULT createSwapChain(ID3D11Device *device, + IDXGIFactory *factory, + DXGI_FORMAT format, + UINT width, + UINT height, + UINT samples, + IDXGISwapChain **swapChain) override; + + void commitChange() override; + + static bool IsValidNativeWindow(EGLNativeWindowType window); + + static bool IsSupportedWinRelease(); + + private: + static bool IsSpriteVisual(EGLNativeWindowType window); + + bool mHasAlpha; + + RoHelper mRoHelper; + + // Namespace prefix required here for some reason despite using namespace + Microsoft::WRL::ComPtr mHostVisual; + Microsoft::WRL::ComPtr mCompositionBrush; + Microsoft::WRL::ComPtr mSurface; + Microsoft::WRL::ComPtr mSurfaceBrush; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_CONVERGED_COMPOSITORNATIVEWINDOW11_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp new file mode 100644 index 0000000000..75ddbd9ea1 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp @@ -0,0 +1,1029 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// formatutils11.cpp: Queries for GL image formats and their translations to D3D11 +// formats. + +#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" + +#include "image_util/copyimage.h" +#include "image_util/generatemip.h" +#include "image_util/loadimage.h" + +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/copyvertex.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" +#include "libANGLE/renderer/dxgi_support_table.h" + +namespace rx +{ + +namespace d3d11 +{ + +bool SupportsMipGen(DXGI_FORMAT dxgiFormat, D3D_FEATURE_LEVEL featureLevel) +{ + const auto &support = GetDXGISupport(dxgiFormat, featureLevel); + ASSERT((support.optionallySupportedFlags & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN) == 0); + return ((support.alwaysSupportedFlags & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN) != 0); +} + +DXGIFormatSize::DXGIFormatSize(GLuint pixelBits, GLuint blockWidth, GLuint blockHeight) + : pixelBytes(pixelBits / 8), blockWidth(blockWidth), blockHeight(blockHeight) +{} + +const DXGIFormatSize &GetDXGIFormatSizeInfo(DXGI_FORMAT format) +{ + static const DXGIFormatSize sizeUnknown(0, 0, 0); + static const DXGIFormatSize size128(128, 1, 1); + static const DXGIFormatSize size96(96, 1, 1); + static const DXGIFormatSize size64(64, 1, 1); + static const DXGIFormatSize size32(32, 1, 1); + static const DXGIFormatSize size16(16, 1, 1); + static const DXGIFormatSize size8(8, 1, 1); + static const DXGIFormatSize sizeBC1(64, 4, 4); + static const DXGIFormatSize sizeBC2(128, 4, 4); + static const DXGIFormatSize sizeBC3(128, 4, 4); + static const DXGIFormatSize sizeBC4(64, 4, 4); + static const DXGIFormatSize sizeBC5(128, 4, 4); + static const DXGIFormatSize sizeBC6H(128, 4, 4); + static const DXGIFormatSize sizeBC7(128, 4, 4); + switch (format) + { + case DXGI_FORMAT_UNKNOWN: + return sizeUnknown; + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + case DXGI_FORMAT_R32G32B32A32_FLOAT: + case DXGI_FORMAT_R32G32B32A32_UINT: + case DXGI_FORMAT_R32G32B32A32_SINT: + return size128; + case DXGI_FORMAT_R32G32B32_TYPELESS: + case DXGI_FORMAT_R32G32B32_FLOAT: + case DXGI_FORMAT_R32G32B32_UINT: + case DXGI_FORMAT_R32G32B32_SINT: + return size96; + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + case DXGI_FORMAT_R16G16B16A16_FLOAT: + case DXGI_FORMAT_R16G16B16A16_UNORM: + case DXGI_FORMAT_R16G16B16A16_UINT: + case DXGI_FORMAT_R16G16B16A16_SNORM: + case DXGI_FORMAT_R16G16B16A16_SINT: + case DXGI_FORMAT_R32G32_TYPELESS: + case DXGI_FORMAT_R32G32_FLOAT: + case DXGI_FORMAT_R32G32_UINT: + case DXGI_FORMAT_R32G32_SINT: + case DXGI_FORMAT_R32G8X24_TYPELESS: + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + return size64; + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + case DXGI_FORMAT_R10G10B10A2_UNORM: + case DXGI_FORMAT_R10G10B10A2_UINT: + case DXGI_FORMAT_R11G11B10_FLOAT: + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DXGI_FORMAT_R8G8B8A8_UINT: + case DXGI_FORMAT_R8G8B8A8_SNORM: + case DXGI_FORMAT_R8G8B8A8_SINT: + case DXGI_FORMAT_R16G16_TYPELESS: + case DXGI_FORMAT_R16G16_FLOAT: + case DXGI_FORMAT_R16G16_UNORM: + case DXGI_FORMAT_R16G16_UINT: + case DXGI_FORMAT_R16G16_SNORM: + case DXGI_FORMAT_R16G16_SINT: + case DXGI_FORMAT_R32_TYPELESS: + case DXGI_FORMAT_D32_FLOAT: + case DXGI_FORMAT_R32_FLOAT: + case DXGI_FORMAT_R32_UINT: + case DXGI_FORMAT_R32_SINT: + case DXGI_FORMAT_R24G8_TYPELESS: + case DXGI_FORMAT_D24_UNORM_S8_UINT: + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + return size32; + case DXGI_FORMAT_R8G8_TYPELESS: + case DXGI_FORMAT_R8G8_UNORM: + case DXGI_FORMAT_R8G8_UINT: + case DXGI_FORMAT_R8G8_SNORM: + case DXGI_FORMAT_R8G8_SINT: + case DXGI_FORMAT_R16_TYPELESS: + case DXGI_FORMAT_R16_FLOAT: + case DXGI_FORMAT_D16_UNORM: + case DXGI_FORMAT_R16_UNORM: + case DXGI_FORMAT_R16_UINT: + case DXGI_FORMAT_R16_SNORM: + case DXGI_FORMAT_R16_SINT: + return size16; + case DXGI_FORMAT_R8_TYPELESS: + case DXGI_FORMAT_R8_UNORM: + case DXGI_FORMAT_R8_UINT: + case DXGI_FORMAT_R8_SNORM: + case DXGI_FORMAT_R8_SINT: + case DXGI_FORMAT_A8_UNORM: + return size8; + case DXGI_FORMAT_R1_UNORM: + UNREACHABLE(); + return sizeUnknown; + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + case DXGI_FORMAT_R8G8_B8G8_UNORM: + case DXGI_FORMAT_G8R8_G8B8_UNORM: + return size32; + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC1_UNORM_SRGB: + return sizeBC1; + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC2_UNORM_SRGB: + return sizeBC2; + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC3_UNORM_SRGB: + return sizeBC3; + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_UNORM: + case DXGI_FORMAT_BC4_SNORM: + return sizeBC4; + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT_BC5_SNORM: + return sizeBC5; + case DXGI_FORMAT_B5G6R5_UNORM: + case DXGI_FORMAT_B5G5R5A1_UNORM: + return size16; + case DXGI_FORMAT_B8G8R8A8_UNORM: + case DXGI_FORMAT_B8G8R8X8_UNORM: + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: + return size32; + case DXGI_FORMAT_BC6H_TYPELESS: + case DXGI_FORMAT_BC6H_UF16: + case DXGI_FORMAT_BC6H_SF16: + return sizeBC6H; + case DXGI_FORMAT_BC7_TYPELESS: + case DXGI_FORMAT_BC7_UNORM: + case DXGI_FORMAT_BC7_UNORM_SRGB: + return sizeBC7; + case DXGI_FORMAT_AYUV: + case DXGI_FORMAT_Y410: + case DXGI_FORMAT_Y416: + case DXGI_FORMAT_NV12: + case DXGI_FORMAT_P010: + case DXGI_FORMAT_P016: + case DXGI_FORMAT_420_OPAQUE: + case DXGI_FORMAT_YUY2: + case DXGI_FORMAT_Y210: + case DXGI_FORMAT_Y216: + case DXGI_FORMAT_NV11: + case DXGI_FORMAT_AI44: + case DXGI_FORMAT_IA44: + case DXGI_FORMAT_P8: + case DXGI_FORMAT_A8P8: + UNREACHABLE(); + return sizeUnknown; + case DXGI_FORMAT_B4G4R4A4_UNORM: + return size16; + default: + UNREACHABLE(); + return sizeUnknown; + } +} + +constexpr VertexFormat::VertexFormat() + : conversionType(VERTEX_CONVERT_NONE), nativeFormat(DXGI_FORMAT_UNKNOWN), copyFunction(nullptr) +{} + +constexpr VertexFormat::VertexFormat(VertexConversionType conversionTypeIn, + DXGI_FORMAT nativeFormatIn, + VertexCopyFunction copyFunctionIn) + : conversionType(conversionTypeIn), nativeFormat(nativeFormatIn), copyFunction(copyFunctionIn) +{} + +const VertexFormat *GetVertexFormatInfo_FL_9_3(angle::FormatID vertexFormatID) +{ + // D3D11 Feature Level 9_3 doesn't support as many formats for vertex buffer resource as Feature + // Level 10_0+. + // http://msdn.microsoft.com/en-us/library/windows/desktop/ff471324(v=vs.85).aspx + + switch (vertexFormatID) + { + // GL_BYTE -- unnormalized + case angle::FormatID::R8_SSCALED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16_SINT, + &Copy8SintTo16SintVertexData<1, 2>); + return &info; + } + case angle::FormatID::R8G8_SSCALED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16_SINT, + &Copy8SintTo16SintVertexData<2, 2>); + return &info; + } + case angle::FormatID::R8G8B8_SSCALED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_SINT, + &Copy8SintTo16SintVertexData<3, 4>); + return &info; + } + case angle::FormatID::R8G8B8A8_SSCALED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_SINT, + &Copy8SintTo16SintVertexData<4, 4>); + return &info; + } + + // GL_BYTE -- normalized + case angle::FormatID::R8_SNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16_SNORM, + &Copy8SnormTo16SnormVertexData<1, 2>); + return &info; + } + case angle::FormatID::R8G8_SNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16_SNORM, + &Copy8SnormTo16SnormVertexData<2, 2>); + return &info; + } + case angle::FormatID::R8G8B8_SNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SNORM, + &Copy8SnormTo16SnormVertexData<3, 4>); + return &info; + } + case angle::FormatID::R8G8B8A8_SNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SNORM, + &Copy8SnormTo16SnormVertexData<4, 4>); + return &info; + } + + // GL_UNSIGNED_BYTE -- un-normalized + // NOTE: 3 and 4 component unnormalized GL_UNSIGNED_BYTE should use the default format + // table. + case angle::FormatID::R8_USCALED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_UINT, + &CopyNativeVertexData); + return &info; + } + case angle::FormatID::R8G8_USCALED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_UINT, + &CopyNativeVertexData); + return &info; + } + + // GL_UNSIGNED_BYTE -- normalized + // NOTE: 3 and 4 component normalized GL_UNSIGNED_BYTE should use the default format table. + + // GL_UNSIGNED_BYTE -- normalized + case angle::FormatID::R8_UNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UNORM, + &CopyNativeVertexData); + return &info; + } + case angle::FormatID::R8G8_UNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UNORM, + &CopyNativeVertexData); + return &info; + } + + // GL_SHORT -- un-normalized + // NOTE: 2, 3 and 4 component unnormalized GL_SHORT should use the default format table. + case angle::FormatID::R16_SSCALED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16_SINT, + &CopyNativeVertexData); + return &info; + } + + // GL_SHORT -- normalized + // NOTE: 2, 3 and 4 component normalized GL_SHORT should use the default format table. + case angle::FormatID::R16_SNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16_SNORM, + &CopyNativeVertexData); + return &info; + } + + // GL_UNSIGNED_SHORT -- un-normalized + case angle::FormatID::R16_USCALED: + { + static constexpr VertexFormat info( + VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, + &CopyToFloatVertexData); + return &info; + } + case angle::FormatID::R16G16_USCALED: + { + static constexpr VertexFormat info( + VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, + &CopyToFloatVertexData); + return &info; + } + case angle::FormatID::R16G16B16_USCALED: + { + static constexpr VertexFormat info( + VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, + &CopyToFloatVertexData); + return &info; + } + case angle::FormatID::R16G16B16A16_USCALED: + { + static constexpr VertexFormat info( + VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, + &CopyToFloatVertexData); + return &info; + } + + // GL_UNSIGNED_SHORT -- normalized + case angle::FormatID::R16_UNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, + &CopyToFloatVertexData); + return &info; + } + case angle::FormatID::R16G16_UNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, + &CopyToFloatVertexData); + return &info; + } + case angle::FormatID::R16G16B16_UNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, + &CopyToFloatVertexData); + return &info; + } + case angle::FormatID::R16G16B16A16_UNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, + &CopyToFloatVertexData); + return &info; + } + + // GL_FIXED + // TODO: Add test to verify that this works correctly. + // NOTE: 2, 3 and 4 component GL_FIXED should use the default format table. + case angle::FormatID::R32_FIXED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, + &Copy32FixedTo32FVertexData<1, 2>); + return &info; + } + + // GL_FLOAT + // TODO: Add test to verify that this works correctly. + // NOTE: 2, 3 and 4 component GL_FLOAT should use the default format table. + case angle::FormatID::R32_FLOAT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, + &CopyNativeVertexData); + return &info; + } + + default: + return nullptr; + } +} + +const VertexFormat &GetVertexFormatInfo(angle::FormatID vertexFormatID, + D3D_FEATURE_LEVEL featureLevel) +{ + if (featureLevel == D3D_FEATURE_LEVEL_9_3) + { + const VertexFormat *result = GetVertexFormatInfo_FL_9_3(vertexFormatID); + if (result) + { + return *result; + } + } + + switch (vertexFormatID) + { + // + // Float formats + // + + // GL_BYTE -- un-normalized + case angle::FormatID::R8_SSCALED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8_SINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R8G8_SSCALED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8_SINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R8G8B8_SSCALED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_SINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R8G8B8A8_SSCALED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8B8A8_SINT, + &CopyNativeVertexData); + return info; + } + + // GL_BYTE -- normalized + case angle::FormatID::R8_SNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_SNORM, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R8G8_SNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SNORM, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R8G8B8_SNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_SNORM, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R8G8B8A8_SNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SNORM, + &CopyNativeVertexData); + return info; + } + + // GL_UNSIGNED_BYTE -- un-normalized + case angle::FormatID::R8_USCALED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8_UINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R8G8_USCALED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8_UINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R8G8B8_USCALED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_UINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R8G8B8A8_USCALED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8B8A8_UINT, + &CopyNativeVertexData); + return info; + } + + // GL_UNSIGNED_BYTE -- normalized + case angle::FormatID::R8_UNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_UNORM, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R8G8_UNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UNORM, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R8G8B8_UNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UNORM, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R8G8B8A8_UNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UNORM, + &CopyNativeVertexData); + return info; + } + + // GL_SHORT -- un-normalized + case angle::FormatID::R16_SSCALED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16_SINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R16G16_SSCALED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16_SINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R16G16B16_SSCALED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_SINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R16G16B16A16_SSCALED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16B16A16_SINT, + &CopyNativeVertexData); + return info; + } + + // GL_SHORT -- normalized + case angle::FormatID::R16_SNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_SNORM, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R16G16_SNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SNORM, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R16G16B16_SNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SNORM, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R16G16B16A16_SNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SNORM, + &CopyNativeVertexData); + return info; + } + + // GL_UNSIGNED_SHORT -- un-normalized + case angle::FormatID::R16_USCALED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16_UINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R16G16_USCALED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16_UINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R16G16B16_USCALED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_UINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R16G16B16A16_USCALED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16B16A16_UINT, + &CopyNativeVertexData); + return info; + } + + // GL_UNSIGNED_SHORT -- normalized + case angle::FormatID::R16_UNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_UNORM, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R16G16_UNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UNORM, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R16G16B16_UNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_UNORM, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R16G16B16A16_UNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UNORM, + &CopyNativeVertexData); + return info; + } + + // GL_INT -- un-normalized + case angle::FormatID::R32_SSCALED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32_SINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R32G32_SSCALED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32_SINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R32G32B32_SSCALED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32_SINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R32G32B32A32_SSCALED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32A32_SINT, + &CopyNativeVertexData); + return info; + } + + // GL_INT -- normalized + case angle::FormatID::R32_SNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT, + &CopyToFloatVertexData); + return info; + } + case angle::FormatID::R32G32_SNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, + &CopyToFloatVertexData); + return info; + } + case angle::FormatID::R32G32B32_SNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, + &CopyToFloatVertexData); + return info; + } + case angle::FormatID::R32G32B32A32_SNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, + &CopyToFloatVertexData); + return info; + } + + // GL_UNSIGNED_INT -- un-normalized + case angle::FormatID::R32_USCALED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32_UINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R32G32_USCALED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32_UINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R32G32B32_USCALED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32_UINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R32G32B32A32_USCALED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32A32_UINT, + &CopyNativeVertexData); + return info; + } + + // GL_UNSIGNED_INT -- normalized + case angle::FormatID::R32_UNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT, + &CopyToFloatVertexData); + return info; + } + case angle::FormatID::R32G32_UNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, + &CopyToFloatVertexData); + return info; + } + case angle::FormatID::R32G32B32_UNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, + &CopyToFloatVertexData); + return info; + } + case angle::FormatID::R32G32B32A32_UNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, + &CopyToFloatVertexData); + return info; + } + + // GL_FIXED + case angle::FormatID::R32_FIXED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT, + &Copy32FixedTo32FVertexData<1, 1>); + return info; + } + case angle::FormatID::R32G32_FIXED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, + &Copy32FixedTo32FVertexData<2, 2>); + return info; + } + case angle::FormatID::R32G32B32_FIXED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, + &Copy32FixedTo32FVertexData<3, 3>); + return info; + } + case angle::FormatID::R32G32B32A32_FIXED: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, + &Copy32FixedTo32FVertexData<4, 4>); + return info; + } + + // GL_HALF_FLOAT + case angle::FormatID::R16_FLOAT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_FLOAT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R16G16_FLOAT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_FLOAT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R16G16B16_FLOAT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_FLOAT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R16G16B16A16_FLOAT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_FLOAT, + &CopyNativeVertexData); + return info; + } + + // GL_FLOAT + case angle::FormatID::R32_FLOAT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_FLOAT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R32G32_FLOAT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_FLOAT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R32G32B32_FLOAT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_FLOAT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R32G32B32A32_FLOAT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_FLOAT, + &CopyNativeVertexData); + return info; + } + + // GL_INT_2_10_10_10_REV + case angle::FormatID::R10G10B10A2_SSCALED: + { + static constexpr VertexFormat info( + VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, + &CopyXYZ10W2ToXYZWFloatVertexData); + return info; + } + case angle::FormatID::R10G10B10A2_SNORM: + { + static constexpr VertexFormat info( + VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, + &CopyXYZ10W2ToXYZWFloatVertexData); + return info; + } + + // GL_UNSIGNED_INT_2_10_10_10_REV + case angle::FormatID::R10G10B10A2_USCALED: + { + static constexpr VertexFormat info( + VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, + &CopyXYZ10W2ToXYZWFloatVertexData); + return info; + } + case angle::FormatID::R10G10B10A2_UNORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R10G10B10A2_UNORM, + &CopyNativeVertexData); + return info; + } + + // + // Integer Formats + // + + // GL_BYTE + case angle::FormatID::R8_SINT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_SINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R8G8_SINT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R8G8B8_SINT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_SINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R8G8B8A8_SINT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SINT, + &CopyNativeVertexData); + return info; + } + + // GL_UNSIGNED_BYTE + case angle::FormatID::R8_UINT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_UINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R8G8_UINT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R8G8B8_UINT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R8G8B8A8_UINT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UINT, + &CopyNativeVertexData); + return info; + } + + // GL_SHORT + case angle::FormatID::R16_SINT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_SINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R16G16_SINT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R16G16B16_SINT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R16G16B16A16_SINT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SINT, + &CopyNativeVertexData); + return info; + } + + // GL_UNSIGNED_SHORT + case angle::FormatID::R16_UINT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_UINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R16G16_UINT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R16G16B16_UINT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_UINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R16G16B16A16_UINT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UINT, + &CopyNativeVertexData); + return info; + } + + // GL_INT + case angle::FormatID::R32_SINT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_SINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R32G32_SINT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_SINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R32G32B32_SINT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_SINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R32G32B32A32_SINT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_SINT, + &CopyNativeVertexData); + return info; + } + + // GL_UNSIGNED_INT + case angle::FormatID::R32_UINT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_SINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R32G32_UINT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_SINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R32G32B32_UINT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_SINT, + &CopyNativeVertexData); + return info; + } + case angle::FormatID::R32G32B32A32_UINT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_SINT, + &CopyNativeVertexData); + return info; + } + + // GL_INT_2_10_10_10_REV + case angle::FormatID::R10G10B10A2_SINT: + { + static constexpr VertexFormat info( + VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SINT, + &CopyXYZ10W2ToXYZWFloatVertexData); + return info; + } + + // GL_UNSIGNED_INT_2_10_10_10_REV + case angle::FormatID::R10G10B10A2_UINT: + { + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R10G10B10A2_UINT, + &CopyNativeVertexData); + return info; + } + + default: + { + static constexpr VertexFormat info; + return info; + } + } +} + +} // namespace d3d11 + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/formatutils11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/formatutils11.h new file mode 100644 index 0000000000..e4c3994280 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/formatutils11.h @@ -0,0 +1,64 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// formatutils11.h: Queries for GL image formats and their translations to D3D11 +// formats. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_FORMATUTILS11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_FORMATUTILS11_H_ + +#include + +#include "common/platform.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/copyvertex.h" +#include "libANGLE/renderer/d3d/formatutilsD3D.h" +#include "libANGLE/renderer/dxgi_format_map.h" +#include "libANGLE/renderer/renderer_utils.h" + +namespace rx +{ +struct Renderer11DeviceCaps; + +namespace d3d11 +{ + +// A texture might be stored as DXGI_FORMAT_R16_TYPELESS but store integer components, +// which are accessed through an DXGI_FORMAT_R16_SINT view. It's easy to write code which queries +// information about the wrong format. Therefore, use of this should be avoided where possible. + +bool SupportsMipGen(DXGI_FORMAT dxgiFormat, D3D_FEATURE_LEVEL featureLevel); + +struct DXGIFormatSize +{ + DXGIFormatSize(GLuint pixelBits, GLuint blockWidth, GLuint blockHeight); + + GLuint pixelBytes; + GLuint blockWidth; + GLuint blockHeight; +}; +const DXGIFormatSize &GetDXGIFormatSizeInfo(DXGI_FORMAT format); + +struct VertexFormat : private angle::NonCopyable +{ + constexpr VertexFormat(); + constexpr VertexFormat(VertexConversionType conversionType, + DXGI_FORMAT nativeFormat, + VertexCopyFunction copyFunction); + + VertexConversionType conversionType; + DXGI_FORMAT nativeFormat; + VertexCopyFunction copyFunction; +}; + +const VertexFormat &GetVertexFormatInfo(angle::FormatID vertexFormatID, + D3D_FEATURE_LEVEL featureLevel); +} // namespace d3d11 + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_FORMATUTILS11_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp new file mode 100644 index 0000000000..8cd97ee43d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp @@ -0,0 +1,2751 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// renderer11_utils.cpp: Conversion functions and other utility routines +// specific to the D3D11 renderer. + +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" + +#include +#include + +#include "common/debug.h" +#include "libANGLE/Buffer.h" +#include "libANGLE/Context.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/Program.h" +#include "libANGLE/State.h" +#include "libANGLE/VertexArray.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/BufferD3D.h" +#include "libANGLE/renderer/d3d/FramebufferD3D.h" +#include "libANGLE/renderer/d3d/d3d11/Context11.h" +#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" +#include "libANGLE/renderer/driver_utils.h" +#include "libANGLE/renderer/dxgi_support_table.h" +#include "platform/FeaturesD3D_autogen.h" +#include "platform/PlatformMethods.h" + +namespace rx +{ + +namespace d3d11_gl +{ +namespace +{ +// TODO(xinghua.cao@intel.com): Get a more accurate limit. +static D3D_FEATURE_LEVEL kMinimumFeatureLevelForES31 = D3D_FEATURE_LEVEL_11_0; + +// Helper functor for querying DXGI support. Saves passing the parameters repeatedly. +class DXGISupportHelper : angle::NonCopyable +{ + public: + DXGISupportHelper(ID3D11Device *device, D3D_FEATURE_LEVEL featureLevel) + : mDevice(device), mFeatureLevel(featureLevel) + {} + + bool query(DXGI_FORMAT dxgiFormat, UINT supportMask) + { + if (dxgiFormat == DXGI_FORMAT_UNKNOWN) + return false; + + auto dxgiSupport = d3d11::GetDXGISupport(dxgiFormat, mFeatureLevel); + + UINT supportedBits = dxgiSupport.alwaysSupportedFlags; + + if ((dxgiSupport.optionallySupportedFlags & supportMask) != 0) + { + UINT formatSupport; + if (SUCCEEDED(mDevice->CheckFormatSupport(dxgiFormat, &formatSupport))) + { + supportedBits |= (formatSupport & supportMask); + } + else + { + // TODO(jmadill): find out why we fail this call sometimes in FL9_3 + // ERR() << "Error checking format support for format 0x" << std::hex << dxgiFormat; + } + } + + return ((supportedBits & supportMask) == supportMask); + } + + private: + ID3D11Device *mDevice; + D3D_FEATURE_LEVEL mFeatureLevel; +}; + +gl::TextureCaps GenerateTextureFormatCaps(gl::Version maxClientVersion, + GLenum internalFormat, + ID3D11Device *device, + const Renderer11DeviceCaps &renderer11DeviceCaps) +{ + gl::TextureCaps textureCaps; + + DXGISupportHelper support(device, renderer11DeviceCaps.featureLevel); + const d3d11::Format &formatInfo = d3d11::Format::Get(internalFormat, renderer11DeviceCaps); + + const gl::InternalFormat &internalFormatInfo = gl::GetSizedInternalFormatInfo(internalFormat); + + UINT texSupportMask = D3D11_FORMAT_SUPPORT_TEXTURE2D; + if (internalFormatInfo.depthBits == 0 && internalFormatInfo.stencilBits == 0) + { + texSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURECUBE; + if (maxClientVersion.major > 2) + { + texSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURE3D; + } + } + + textureCaps.texturable = support.query(formatInfo.texFormat, texSupportMask); + textureCaps.filterable = + support.query(formatInfo.srvFormat, D3D11_FORMAT_SUPPORT_SHADER_SAMPLE); + textureCaps.textureAttachment = + (support.query(formatInfo.rtvFormat, D3D11_FORMAT_SUPPORT_RENDER_TARGET)) || + (support.query(formatInfo.dsvFormat, D3D11_FORMAT_SUPPORT_DEPTH_STENCIL)); + textureCaps.renderbuffer = textureCaps.textureAttachment; + textureCaps.blendable = textureCaps.renderbuffer; + + DXGI_FORMAT renderFormat = DXGI_FORMAT_UNKNOWN; + if (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN) + { + renderFormat = formatInfo.dsvFormat; + } + else if (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN) + { + renderFormat = formatInfo.rtvFormat; + } + if (renderFormat != DXGI_FORMAT_UNKNOWN && + support.query(renderFormat, D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET)) + { + // Assume 1x + textureCaps.sampleCounts.insert(1); + + for (unsigned int sampleCount = 2; sampleCount <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; + sampleCount *= 2) + { + UINT qualityCount = 0; + if (SUCCEEDED(device->CheckMultisampleQualityLevels(renderFormat, sampleCount, + &qualityCount))) + { + // Assume we always support lower sample counts + if (qualityCount == 0) + { + break; + } + textureCaps.sampleCounts.insert(sampleCount); + } + } + } + + return textureCaps; +} + +bool GetNPOTTextureSupport(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return true; + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return false; + + default: + UNREACHABLE(); + return false; + } +} + +float GetMaximumAnisotropy(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_MAX_MAXANISOTROPY; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_MAX_MAXANISOTROPY; + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + return 16; + + case D3D_FEATURE_LEVEL_9_1: + return D3D_FL9_1_DEFAULT_MAX_ANISOTROPY; + + default: + UNREACHABLE(); + return 0; + } +} + +bool GetOcclusionQuerySupport(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return true; + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx + // ID3D11Device::CreateQuery + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + return true; + case D3D_FEATURE_LEVEL_9_1: + return false; + + default: + UNREACHABLE(); + return false; + } +} + +bool GetEventQuerySupport(D3D_FEATURE_LEVEL featureLevel) +{ + // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx + // ID3D11Device::CreateQuery + + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return true; + + default: + UNREACHABLE(); + return false; + } +} + +bool GetInstancingSupport(D3D_FEATURE_LEVEL featureLevel) +{ + // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx + // ID3D11Device::CreateInputLayout + + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return true; + + // Feature Level 9_3 supports instancing, but slot 0 in the input layout must not be + // instanced. + // D3D9 has a similar restriction, where stream 0 must not be instanced. + // This restriction can be worked around by remapping any non-instanced slot to slot + // 0. + // This works because HLSL uses shader semantics to match the vertex inputs to the + // elements in the input layout, rather than the slots. + // Note that we only support instancing via ANGLE_instanced_array on 9_3, since 9_3 + // doesn't support OpenGL ES 3.0 + case D3D_FEATURE_LEVEL_9_3: + return true; + + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return false; + + default: + UNREACHABLE(); + return false; + } +} + +bool GetFramebufferMultisampleSupport(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return true; + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return false; + + default: + UNREACHABLE(); + return false; + } +} + +bool GetFramebufferBlitSupport(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return true; + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return false; + + default: + UNREACHABLE(); + return false; + } +} + +bool GetDerivativeInstructionSupport(D3D_FEATURE_LEVEL featureLevel) +{ + // http://msdn.microsoft.com/en-us/library/windows/desktop/bb509588.aspx states that + // shader model + // ps_2_x is required for the ddx (and other derivative functions). + + // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx states that + // feature level + // 9.3 supports shader model ps_2_x. + + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + case D3D_FEATURE_LEVEL_9_3: + return true; + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return false; + + default: + UNREACHABLE(); + return false; + } +} + +bool GetShaderTextureLODSupport(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return true; + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return false; + + default: + UNREACHABLE(); + return false; + } +} + +int GetMaximumSimultaneousRenderTargets(D3D_FEATURE_LEVEL featureLevel) +{ + // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx + // ID3D11Device::CreateInputLayout + + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT; + + case D3D_FEATURE_LEVEL_9_3: + return D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT; + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT; + + default: + UNREACHABLE(); + return 0; + } +} + +int GetMaximum2DTextureSize(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; + + case D3D_FEATURE_LEVEL_9_3: + return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; + + default: + UNREACHABLE(); + return 0; + } +} + +int GetMaximumCubeMapTextureSize(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_REQ_TEXTURECUBE_DIMENSION; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_REQ_TEXTURECUBE_DIMENSION; + + case D3D_FEATURE_LEVEL_9_3: + return D3D_FL9_3_REQ_TEXTURECUBE_DIMENSION; + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION; + + default: + UNREACHABLE(); + return 0; + } +} + +int GetMaximum2DTextureArraySize(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION; + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 0; + + default: + UNREACHABLE(); + return 0; + } +} + +int GetMaximum3DTextureSize(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_REQ_TEXTURE3D_U_V_OR_W_DIMENSION; + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION; + + default: + UNREACHABLE(); + return 0; + } +} + +int GetMaximumViewportSize(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_VIEWPORT_BOUNDS_MAX; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_VIEWPORT_BOUNDS_MAX; + + // No constants for D3D11 Feature Level 9 viewport size limits, use the maximum + // texture sizes + case D3D_FEATURE_LEVEL_9_3: + return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; + + default: + UNREACHABLE(); + return 0; + } +} + +int GetMaximumDrawIndexedIndexCount(D3D_FEATURE_LEVEL featureLevel) +{ + // D3D11 allows up to 2^32 elements, but we report max signed int for convenience since + // that's what's + // returned from glGetInteger + static_assert(D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32, + "Unexpected D3D11 constant value."); + static_assert(D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32, + "Unexpected D3D11 constant value."); + + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return std::numeric_limits::max(); + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + return D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT; + case D3D_FEATURE_LEVEL_9_1: + return D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT; + + default: + UNREACHABLE(); + return 0; + } +} + +int GetMaximumDrawVertexCount(D3D_FEATURE_LEVEL featureLevel) +{ + // D3D11 allows up to 2^32 elements, but we report max signed int for convenience since + // that's what's + // returned from glGetInteger + static_assert(D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32, "Unexpected D3D11 constant value."); + static_assert(D3D10_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32, "Unexpected D3D11 constant value."); + + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return std::numeric_limits::max(); + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + return D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT; + case D3D_FEATURE_LEVEL_9_1: + return D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT; + + default: + UNREACHABLE(); + return 0; + } +} + +int GetMaximumVertexInputSlots(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_STANDARD_VERTEX_ELEMENT_COUNT; + + case D3D_FEATURE_LEVEL_10_1: + return D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT; + case D3D_FEATURE_LEVEL_10_0: + return D3D10_STANDARD_VERTEX_ELEMENT_COUNT; + + // From http://http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx + // "Max Input Slots" + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 16; + + default: + UNREACHABLE(); + return 0; + } +} + +int GetMaximumVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx + // ID3D11DeviceContext::VSSetConstantBuffers + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 255 - d3d11_gl::GetReservedVertexUniformVectors(featureLevel); + + default: + UNREACHABLE(); + return 0; + } +} + +int GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - + d3d11::RESERVED_CONSTANT_BUFFER_SLOT_COUNT; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - + d3d11::RESERVED_CONSTANT_BUFFER_SLOT_COUNT; + + // Uniform blocks not supported on D3D11 Feature Level 9 + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 0; + + default: + UNREACHABLE(); + return 0; + } +} + +int GetReservedVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel) +{ + // According to The OpenGL ES Shading Language specifications + // (Language Version 1.00 section 10.16, Language Version 3.10 section 12.21) + // built-in special variables (e.g. gl_FragCoord, or gl_PointCoord) + // which are statically used in the shader should be included in the variable packing + // algorithm. + // Therefore, we should not reserve output vectors for them. + + switch (featureLevel) + { + // We must reserve one output vector for dx_Position. + // We also reserve one for gl_Position, which we unconditionally output on Feature + // Levels 10_0+, + // even if it's unused in the shader (e.g. for transform feedback). TODO: This could + // be improved. + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return 2; + + // Just reserve dx_Position on Feature Level 9, since we don't ever need to output + // gl_Position. + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 1; + + default: + UNREACHABLE(); + return 0; + } +} + +int GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel) +{ + static_assert(gl::IMPLEMENTATION_MAX_VARYING_VECTORS == D3D11_VS_OUTPUT_REGISTER_COUNT, + "Unexpected D3D11 constant value."); + + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel); + + case D3D_FEATURE_LEVEL_10_1: + return D3D10_1_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel); + case D3D_FEATURE_LEVEL_10_0: + return D3D10_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel); + + // Use Shader Model 2.X limits + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 8 - GetReservedVertexOutputVectors(featureLevel); + + default: + UNREACHABLE(); + return 0; + } +} + +int GetMaximumVertexTextureUnits(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; + + // Vertex textures not supported on D3D11 Feature Level 9 according to + // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx + // ID3D11DeviceContext::VSSetSamplers and ID3D11DeviceContext::VSSetShaderResources + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 0; + + default: + UNREACHABLE(); + return 0; + } +} + +int GetMaximumPixelUniformVectors(D3D_FEATURE_LEVEL featureLevel) +{ + // TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return 1024; // D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx + // ID3D11DeviceContext::PSSetConstantBuffers + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 32 - d3d11_gl::GetReservedFragmentUniformVectors(featureLevel); + + default: + UNREACHABLE(); + return 0; + } +} + +int GetMaximumPixelUniformBlocks(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - + d3d11::RESERVED_CONSTANT_BUFFER_SLOT_COUNT; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - + d3d11::RESERVED_CONSTANT_BUFFER_SLOT_COUNT; + + // Uniform blocks not supported on D3D11 Feature Level 9 + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 0; + + default: + UNREACHABLE(); + return 0; + } +} + +int GetMaximumPixelInputVectors(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel); + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel); + + // Use Shader Model 2.X limits + case D3D_FEATURE_LEVEL_9_3: + return 8 - GetReservedVertexOutputVectors(featureLevel); + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 8 - GetReservedVertexOutputVectors(featureLevel); + + default: + UNREACHABLE(); + return 0; + } +} + +int GetMaximumPixelTextureUnits(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; + + // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx + // ID3D11DeviceContext::PSSetShaderResources + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 16; + + default: + UNREACHABLE(); + return 0; + } +} + +std::array GetMaxComputeWorkGroupCount(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return {{D3D11_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION, + D3D11_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION, + D3D11_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION}}; + default: + return {{0, 0, 0}}; + } +} + +std::array GetMaxComputeWorkGroupSize(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return {{D3D11_CS_THREAD_GROUP_MAX_X, D3D11_CS_THREAD_GROUP_MAX_Y, + D3D11_CS_THREAD_GROUP_MAX_Z}}; + default: + return {{0, 0, 0}}; + } +} + +int GetMaxComputeWorkGroupInvocations(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_CS_THREAD_GROUP_MAX_THREADS_PER_GROUP; + default: + return 0; + } +} + +int GetMaxComputeSharedMemorySize(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + // In D3D11 the maximum total size of all variables with the groupshared storage class is + // 32kb. + // https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/dx-graphics-hlsl-variable-syntax + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return 32768; + default: + return 0; + } +} + +int GetMaximumComputeUniformVectors(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; + default: + return 0; + } +} + +int GetMaximumComputeUniformBlocks(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - + d3d11::RESERVED_CONSTANT_BUFFER_SLOT_COUNT; + default: + return 0; + } +} + +int GetMaximumComputeTextureUnits(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; + default: + return 0; + } +} + +void SetUAVRelatedResourceLimits(D3D_FEATURE_LEVEL featureLevel, gl::Caps *caps) +{ + ASSERT(caps); + + GLuint reservedUAVsForAtomicCounterBuffers = 0u; + + // For pixel shaders, the render targets and unordered access views share the same resource + // slots when being written out. + // https://msdn.microsoft.com/en-us/library/windows/desktop/ff476465(v=vs.85).aspx + GLuint maxNumRTVsAndUAVs = 0u; + + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + // Currently we allocate 4 UAV slots for atomic counter buffers on feature level 11_1. + reservedUAVsForAtomicCounterBuffers = 4u; + maxNumRTVsAndUAVs = D3D11_1_UAV_SLOT_COUNT; + break; + case D3D_FEATURE_LEVEL_11_0: + // Currently we allocate 1 UAV slot for atomic counter buffers on feature level 11_0. + reservedUAVsForAtomicCounterBuffers = 1u; + maxNumRTVsAndUAVs = D3D11_PS_CS_UAV_REGISTER_COUNT; + break; + default: + return; + } + + // Set limits on atomic counter buffers in fragment shaders and compute shaders. + caps->maxCombinedAtomicCounterBuffers = reservedUAVsForAtomicCounterBuffers; + caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Compute] = + reservedUAVsForAtomicCounterBuffers; + caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Fragment] = + reservedUAVsForAtomicCounterBuffers; + caps->maxAtomicCounterBufferBindings = reservedUAVsForAtomicCounterBuffers; + + // Setting MAX_COMPUTE_ATOMIC_COUNTERS to a conservative number of 1024 * the number of UAV + // reserved for atomic counters. It could theoretically be set to max buffer size / 4 but that + // number could cause problems. + caps->maxCombinedAtomicCounters = reservedUAVsForAtomicCounterBuffers * 1024; + caps->maxShaderAtomicCounters[gl::ShaderType::Compute] = caps->maxCombinedAtomicCounters; + + // See + // https://docs.microsoft.com/en-us/windows/desktop/direct3d11/overviews-direct3d-11-resources-limits + // Resource size (in MB) for any of the preceding resources is min(max(128,0.25f * (amount of + // dedicated VRAM)), 2048) MB. So we set it to 128MB to keep same with GL backend. + caps->maxShaderStorageBlockSize = + D3D11_REQ_RESOURCE_SIZE_IN_MEGABYTES_EXPRESSION_A_TERM * 1024 * 1024; + + // Allocate the remaining slots for images and shader storage blocks. + // The maximum number of fragment shader outputs depends on the current context version, so we + // will not set it here. See comments in Context11::initialize(). + caps->maxCombinedShaderOutputResources = + maxNumRTVsAndUAVs - reservedUAVsForAtomicCounterBuffers; + + // Set limits on images and shader storage blocks in fragment shaders and compute shaders. + caps->maxCombinedShaderStorageBlocks = caps->maxCombinedShaderOutputResources; + caps->maxShaderStorageBlocks[gl::ShaderType::Compute] = caps->maxCombinedShaderOutputResources; + caps->maxShaderStorageBlocks[gl::ShaderType::Fragment] = caps->maxCombinedShaderOutputResources; + caps->maxShaderStorageBufferBindings = caps->maxCombinedShaderOutputResources; + + caps->maxImageUnits = caps->maxCombinedShaderOutputResources; + caps->maxCombinedImageUniforms = caps->maxCombinedShaderOutputResources; + caps->maxShaderImageUniforms[gl::ShaderType::Compute] = caps->maxCombinedShaderOutputResources; + caps->maxShaderImageUniforms[gl::ShaderType::Fragment] = caps->maxCombinedShaderOutputResources; + + // On feature level 11_1, UAVs are also available in vertex shaders and geometry shaders. + if (featureLevel == D3D_FEATURE_LEVEL_11_1) + { + caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Vertex] = + caps->maxCombinedAtomicCounterBuffers; + caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Geometry] = + caps->maxCombinedAtomicCounterBuffers; + + caps->maxShaderImageUniforms[gl::ShaderType::Vertex] = + caps->maxCombinedShaderOutputResources; + caps->maxShaderStorageBlocks[gl::ShaderType::Vertex] = + caps->maxCombinedShaderOutputResources; + caps->maxShaderImageUniforms[gl::ShaderType::Geometry] = + caps->maxCombinedShaderOutputResources; + caps->maxShaderStorageBlocks[gl::ShaderType::Geometry] = + caps->maxCombinedShaderOutputResources; + } +} + +int GetMinimumTexelOffset(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE; + + // Sampling functions with offsets are not available below shader model 4.0. + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 0; + + default: + UNREACHABLE(); + return 0; + } +} + +int GetMaximumTexelOffset(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE; + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE; + + // Sampling functions with offsets are not available below shader model 4.0. + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 0; + + default: + UNREACHABLE(); + return 0; + } +} + +int GetMinimumTextureGatherOffset(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + // https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/gather4-po--sm5---asm- + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return -32; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 0; + + default: + UNREACHABLE(); + return 0; + } +} + +int GetMaximumTextureGatherOffset(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + // https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/gather4-po--sm5---asm- + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return 31; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 0; + + default: + UNREACHABLE(); + return 0; + } +} + +size_t GetMaximumConstantBufferSize(D3D_FEATURE_LEVEL featureLevel) +{ + // Returns a size_t despite the limit being a GLuint64 because size_t is the maximum + // size of + // any buffer that could be allocated. + + const size_t bytesPerComponent = 4 * sizeof(float); + + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent; + + // Limits from http://msdn.microsoft.com/en-us/library/windows/desktop/ff476501.aspx + // remarks section + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 4096 * bytesPerComponent; + + default: + UNREACHABLE(); + return 0; + } +} + +int GetMaximumStreamOutputBuffers(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_SO_BUFFER_SLOT_COUNT; + + case D3D_FEATURE_LEVEL_10_1: + return D3D10_1_SO_BUFFER_SLOT_COUNT; + case D3D_FEATURE_LEVEL_10_0: + return D3D10_SO_BUFFER_SLOT_COUNT; + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 0; + + default: + UNREACHABLE(); + return 0; + } +} + +int GetMaximumStreamOutputInterleavedComponents(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return GetMaximumVertexOutputVectors(featureLevel) * 4; + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 0; + + default: + UNREACHABLE(); + return 0; + } +} + +int GetMaximumStreamOutputSeparateComponents(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return GetMaximumStreamOutputInterleavedComponents(featureLevel) / + GetMaximumStreamOutputBuffers(featureLevel); + + // D3D 10 and 10.1 only allow one output per output slot if an output slot other + // than zero is used. + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return 4; + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 0; + + default: + UNREACHABLE(); + return 0; + } +} + +int GetMaximumRenderToBufferWindowSize(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_REQ_RENDER_TO_BUFFER_WINDOW_WIDTH; + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_REQ_RENDER_TO_BUFFER_WINDOW_WIDTH; + + // REQ_RENDER_TO_BUFFER_WINDOW_WIDTH not supported on D3D11 Feature Level 9, + // use the maximum texture sizes + case D3D_FEATURE_LEVEL_9_3: + return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; + + default: + UNREACHABLE(); + return 0; + } +} + +IntelDriverVersion GetIntelDriverVersion(const Optional driverVersion) +{ + if (!driverVersion.valid()) + return IntelDriverVersion(0); + + DWORD lowPart = driverVersion.value().LowPart; + return IntelDriverVersion(HIWORD(lowPart) * 10000 + LOWORD(lowPart)); +} + +} // anonymous namespace + +unsigned int GetReservedVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return 0; + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 3; // dx_ViewAdjust, dx_ViewCoords and dx_ViewScale + + default: + UNREACHABLE(); + return 0; + } +} + +unsigned int GetReservedFragmentUniformVectors(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return 0; + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 4; // dx_ViewCoords, dx_DepthFront, dx_DepthRange, dx_FragCoordOffset + + default: + UNREACHABLE(); + return 0; + } +} + +gl::Version GetMaximumClientVersion(const Renderer11DeviceCaps &caps) +{ + switch (caps.featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return gl::Version(3, 1); + case D3D_FEATURE_LEVEL_10_1: + return gl::Version(3, 0); + + case D3D_FEATURE_LEVEL_10_0: + if (caps.allowES3OnFL10_0) + { + return gl::Version(3, 0); + } + else + { + return gl::Version(2, 0); + } + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return gl::Version(2, 0); + + default: + UNREACHABLE(); + return gl::Version(0, 0); + } +} + +D3D_FEATURE_LEVEL GetMinimumFeatureLevelForES31() +{ + return kMinimumFeatureLevelForES31; +} + +unsigned int GetMaxViewportAndScissorRectanglesPerPipeline(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 1; + default: + UNREACHABLE(); + return 0; + } +} + +bool IsMultiviewSupported(D3D_FEATURE_LEVEL featureLevel) +{ + // The ANGLE_multiview extension can always be supported in D3D11 through geometry shaders. + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return true; + default: + return false; + } +} + +int GetMaxSampleMaskWords(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + // D3D10+ only allows 1 sample mask. + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return 1; + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 0; + default: + UNREACHABLE(); + return 0; + } +} + +bool HasTextureBufferSupport(ID3D11Device *device, const Renderer11DeviceCaps &renderer11DeviceCaps) +{ + if (renderer11DeviceCaps.featureLevel < D3D_FEATURE_LEVEL_11_0) + return false; + + if (!renderer11DeviceCaps.supportsTypedUAVLoadAdditionalFormats) + return false; + + // https://docs.microsoft.com/en-us/windows/win32/direct3d12/typed-unordered-access-view-loads + // we don't need to check the typed store. from the spec, + // https://microsoft.github.io/DirectX-Specs/d3d/archive/D3D11_3_FunctionalSpec.htm#FormatList + // all the following format support typed stored. + // According to spec, + // https://www.khronos.org/registry/OpenGL-Refpages/es3/html/glBindImageTexture.xhtml the + // required image unit format are GL_RGBA32F, GL_RGBA32UI, GL_RGBA32I, GL_RGBA16F, GL_RGBA16UI, + // GL_RGBA16I, GL_RGBA8, GL_RGBAUI, GL_RGBA8I, GL_RGBA8_SNORM, GL_R32F, GL_R32UI, GL_R32I, + const std::array &optionalFormats = { + DXGI_FORMAT_R32G32B32A32_FLOAT, // test for GL_RGBA32(UIF), GL_RGBA16(UIF), + // GL_RGBA8(UIUnorm) + DXGI_FORMAT_R8G8B8A8_SNORM, // test for GL_RGBA8_SNORM, + }; + + for (DXGI_FORMAT dxgiFormat : optionalFormats) + { + D3D11_FEATURE_DATA_FORMAT_SUPPORT FormatSupport = {dxgiFormat, 0}; + if (!SUCCEEDED(device->CheckFeatureSupport(D3D11_FEATURE_FORMAT_SUPPORT, &FormatSupport, + sizeof(FormatSupport)))) + { + WARN() << "Error checking typed load support for format 0x" << std::hex << dxgiFormat; + return false; + } + if ((FormatSupport.OutFormatSupport & D3D11_FORMAT_SUPPORT2_UAV_TYPED_LOAD) == 0) + return false; + } + return true; +} + +void GenerateCaps(ID3D11Device *device, + ID3D11DeviceContext *deviceContext, + const Renderer11DeviceCaps &renderer11DeviceCaps, + const angle::FeaturesD3D &features, + const char *description, + gl::Caps *caps, + gl::TextureCapsMap *textureCapsMap, + gl::Extensions *extensions, + gl::Limitations *limitations) +{ + D3D_FEATURE_LEVEL featureLevel = renderer11DeviceCaps.featureLevel; + const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats(); + for (GLenum internalFormat : allFormats) + { + gl::TextureCaps textureCaps = + GenerateTextureFormatCaps(GetMaximumClientVersion(renderer11DeviceCaps), internalFormat, + device, renderer11DeviceCaps); + textureCapsMap->insert(internalFormat, textureCaps); + } + + // GL core feature limits + // Reserve MAX_UINT for D3D11's primitive restart. + caps->maxElementIndex = static_cast(std::numeric_limits::max() - 1); + caps->max3DTextureSize = GetMaximum3DTextureSize(featureLevel); + caps->max2DTextureSize = GetMaximum2DTextureSize(featureLevel); + caps->maxCubeMapTextureSize = GetMaximumCubeMapTextureSize(featureLevel); + caps->maxArrayTextureLayers = GetMaximum2DTextureArraySize(featureLevel); + + // Unimplemented, set to minimum required + caps->maxLODBias = 2.0f; + + // No specific limits on render target size, maximum 2D texture size is equivalent + caps->maxRenderbufferSize = caps->max2DTextureSize; + + // Maximum draw buffers and color attachments are the same, max color attachments could + // eventually be increased to 16 + caps->maxDrawBuffers = GetMaximumSimultaneousRenderTargets(featureLevel); + caps->maxColorAttachments = GetMaximumSimultaneousRenderTargets(featureLevel); + + // D3D11 has the same limit for viewport width and height + caps->maxViewportWidth = GetMaximumViewportSize(featureLevel); + caps->maxViewportHeight = caps->maxViewportWidth; + + // Choose a reasonable maximum, enforced in the shader. + caps->minAliasedPointSize = 1.0f; + caps->maxAliasedPointSize = 1024.0f; + + // Wide lines not supported + caps->minAliasedLineWidth = 1.0f; + caps->maxAliasedLineWidth = 1.0f; + + // Primitive count limits + caps->maxElementsIndices = GetMaximumDrawIndexedIndexCount(featureLevel); + caps->maxElementsVertices = GetMaximumDrawVertexCount(featureLevel); + + // Program and shader binary formats (no supported shader binary formats) + caps->programBinaryFormats.push_back(GL_PROGRAM_BINARY_ANGLE); + + caps->vertexHighpFloat.setIEEEFloat(); + caps->vertexMediumpFloat.setIEEEFloat(); + caps->vertexLowpFloat.setIEEEFloat(); + caps->fragmentHighpFloat.setIEEEFloat(); + caps->fragmentMediumpFloat.setIEEEFloat(); + caps->fragmentLowpFloat.setIEEEFloat(); + + // 32-bit integers are natively supported + caps->vertexHighpInt.setTwosComplementInt(32); + caps->vertexMediumpInt.setTwosComplementInt(32); + caps->vertexLowpInt.setTwosComplementInt(32); + caps->fragmentHighpInt.setTwosComplementInt(32); + caps->fragmentMediumpInt.setTwosComplementInt(32); + caps->fragmentLowpInt.setTwosComplementInt(32); + + // We do not wait for server fence objects internally, so report a max timeout of zero. + caps->maxServerWaitTimeout = 0; + + // Vertex shader limits + caps->maxVertexAttributes = GetMaximumVertexInputSlots(featureLevel); + caps->maxVertexUniformVectors = GetMaximumVertexUniformVectors(featureLevel); + if (features.skipVSConstantRegisterZero.enabled) + { + caps->maxVertexUniformVectors -= 1; + } + caps->maxShaderUniformComponents[gl::ShaderType::Vertex] = caps->maxVertexUniformVectors * 4; + caps->maxShaderUniformBlocks[gl::ShaderType::Vertex] = + GetMaximumVertexUniformBlocks(featureLevel); + caps->maxVertexOutputComponents = GetMaximumVertexOutputVectors(featureLevel) * 4; + caps->maxShaderTextureImageUnits[gl::ShaderType::Vertex] = + GetMaximumVertexTextureUnits(featureLevel); + + // Vertex Attribute Bindings are emulated on D3D11. + caps->maxVertexAttribBindings = caps->maxVertexAttributes; + // Experimental testing confirmed there is no explicit limit on maximum buffer offset in D3D11. + caps->maxVertexAttribRelativeOffset = std::numeric_limits::max(); + // Experimental testing confirmed 2048 is the maximum stride that D3D11 can support on all + // platforms. + caps->maxVertexAttribStride = 2048; + + // Fragment shader limits + caps->maxFragmentUniformVectors = GetMaximumPixelUniformVectors(featureLevel); + caps->maxShaderUniformComponents[gl::ShaderType::Fragment] = + caps->maxFragmentUniformVectors * 4; + caps->maxShaderUniformBlocks[gl::ShaderType::Fragment] = + GetMaximumPixelUniformBlocks(featureLevel); + caps->maxFragmentInputComponents = GetMaximumPixelInputVectors(featureLevel) * 4; + caps->maxShaderTextureImageUnits[gl::ShaderType::Fragment] = + GetMaximumPixelTextureUnits(featureLevel); + caps->minProgramTexelOffset = GetMinimumTexelOffset(featureLevel); + caps->maxProgramTexelOffset = GetMaximumTexelOffset(featureLevel); + + // Compute shader limits + caps->maxComputeWorkGroupCount = GetMaxComputeWorkGroupCount(featureLevel); + caps->maxComputeWorkGroupSize = GetMaxComputeWorkGroupSize(featureLevel); + caps->maxComputeWorkGroupInvocations = GetMaxComputeWorkGroupInvocations(featureLevel); + caps->maxComputeSharedMemorySize = GetMaxComputeSharedMemorySize(featureLevel); + caps->maxShaderUniformComponents[gl::ShaderType::Compute] = + GetMaximumComputeUniformVectors(featureLevel) * 4; + caps->maxShaderUniformBlocks[gl::ShaderType::Compute] = + GetMaximumComputeUniformBlocks(featureLevel); + caps->maxShaderTextureImageUnits[gl::ShaderType::Compute] = + GetMaximumComputeTextureUnits(featureLevel); + + SetUAVRelatedResourceLimits(featureLevel, caps); + + // Aggregate shader limits + caps->maxUniformBufferBindings = caps->maxShaderUniformBlocks[gl::ShaderType::Vertex] + + caps->maxShaderUniformBlocks[gl::ShaderType::Fragment]; + caps->maxUniformBlockSize = static_cast(GetMaximumConstantBufferSize(featureLevel)); + + // TODO(oetuaho): Get a more accurate limit. For now using the minimum requirement for GLES 3.1. + caps->maxUniformLocations = 1024; + + // With DirectX 11.1, constant buffer offset and size must be a multiple of 16 constants of 16 + // bytes each. + // https://msdn.microsoft.com/en-us/library/windows/desktop/hh404649%28v=vs.85%29.aspx + // With DirectX 11.0, we emulate UBO offsets using copies of ranges of the UBO however + // we still keep the same alignment as 11.1 for consistency. + caps->uniformBufferOffsetAlignment = 256; + + caps->maxCombinedUniformBlocks = caps->maxShaderUniformBlocks[gl::ShaderType::Vertex] + + caps->maxShaderUniformBlocks[gl::ShaderType::Fragment]; + + // A shader storage block will be translated to a structure in HLSL. So We reference the HLSL + // structure packing rules + // https://msdn.microsoft.com/en-us/library/windows/desktop/bb509632(v=vs.85).aspx. The + // resulting size of any structure will always be evenly divisible by sizeof(four-component + // vector). + caps->shaderStorageBufferOffsetAlignment = 16; + + for (gl::ShaderType shaderType : gl::AllShaderTypes()) + { + caps->maxCombinedShaderUniformComponents[shaderType] = + static_cast(caps->maxShaderUniformBlocks[shaderType]) * + static_cast(caps->maxUniformBlockSize / 4) + + static_cast(caps->maxShaderUniformComponents[shaderType]); + } + + caps->maxVaryingComponents = GetMaximumVertexOutputVectors(featureLevel) * 4; + caps->maxVaryingVectors = GetMaximumVertexOutputVectors(featureLevel); + caps->maxCombinedTextureImageUnits = caps->maxShaderTextureImageUnits[gl::ShaderType::Vertex] + + caps->maxShaderTextureImageUnits[gl::ShaderType::Fragment]; + + // Transform feedback limits + caps->maxTransformFeedbackInterleavedComponents = + GetMaximumStreamOutputInterleavedComponents(featureLevel); + caps->maxTransformFeedbackSeparateAttributes = GetMaximumStreamOutputBuffers(featureLevel); + caps->maxTransformFeedbackSeparateComponents = + GetMaximumStreamOutputSeparateComponents(featureLevel); + + // Defer the computation of multisample limits to Context::updateCaps() where max*Samples values + // are determined according to available sample counts for each individual format. + caps->maxSamples = std::numeric_limits::max(); + caps->maxColorTextureSamples = std::numeric_limits::max(); + caps->maxDepthTextureSamples = std::numeric_limits::max(); + caps->maxIntegerSamples = std::numeric_limits::max(); + + // Sample mask words limits + caps->maxSampleMaskWords = GetMaxSampleMaskWords(featureLevel); + + // Framebuffer limits + caps->maxFramebufferSamples = std::numeric_limits::max(); + caps->maxFramebufferWidth = GetMaximumRenderToBufferWindowSize(featureLevel); + caps->maxFramebufferHeight = caps->maxFramebufferWidth; + + // Texture gather offset limits + caps->minProgramTextureGatherOffset = GetMinimumTextureGatherOffset(featureLevel); + caps->maxProgramTextureGatherOffset = GetMaximumTextureGatherOffset(featureLevel); + + caps->maxTextureAnisotropy = GetMaximumAnisotropy(featureLevel); + caps->queryCounterBitsTimeElapsed = 64; + caps->queryCounterBitsTimestamp = 0; // Timestamps cannot be supported due to D3D11 limitations + caps->maxDualSourceDrawBuffers = 1; + + // GL extension support + extensions->setTextureExtensionSupport(*textureCapsMap); + + // Explicitly disable GL_OES_compressed_ETC1_RGB8_texture because it's emulated and never + // becomes core. WebGL doesn't want to expose it unless there is native support. + extensions->compressedETC1RGB8TextureOES = false; + extensions->compressedETC1RGB8SubTextureEXT = false; + + extensions->elementIndexUintOES = true; + extensions->getProgramBinaryOES = true; + extensions->rgb8Rgba8OES = true; + extensions->readFormatBgraEXT = true; + extensions->pixelBufferObjectNV = true; + extensions->mapbufferOES = true; + extensions->mapBufferRangeEXT = true; + extensions->textureNpotOES = GetNPOTTextureSupport(featureLevel); + extensions->drawBuffersEXT = GetMaximumSimultaneousRenderTargets(featureLevel) > 1; + extensions->drawBuffersIndexedEXT = + (renderer11DeviceCaps.featureLevel >= D3D_FEATURE_LEVEL_10_1); + extensions->drawBuffersIndexedOES = extensions->drawBuffersIndexedEXT; + extensions->textureStorageEXT = true; + extensions->textureFilterAnisotropicEXT = true; + extensions->occlusionQueryBooleanEXT = GetOcclusionQuerySupport(featureLevel); + extensions->fenceNV = GetEventQuerySupport(featureLevel); + extensions->disjointTimerQueryEXT = true; + extensions->robustnessEXT = true; + // Direct3D guarantees to return zero for any resource that is accessed out of bounds. + // See https://msdn.microsoft.com/en-us/library/windows/desktop/ff476332(v=vs.85).aspx + // and https://msdn.microsoft.com/en-us/library/windows/desktop/ff476900(v=vs.85).aspx + extensions->robustBufferAccessBehaviorKHR = true; + extensions->blendMinmaxEXT = true; + // https://docs.microsoft.com/en-us/windows/desktop/direct3ddxgi/format-support-for-direct3d-11-0-feature-level-hardware + extensions->floatBlendEXT = true; + extensions->framebufferBlitANGLE = GetFramebufferBlitSupport(featureLevel); + extensions->framebufferBlitNV = extensions->framebufferBlitANGLE; + extensions->framebufferMultisampleANGLE = GetFramebufferMultisampleSupport(featureLevel); + extensions->instancedArraysANGLE = GetInstancingSupport(featureLevel); + extensions->instancedArraysEXT = GetInstancingSupport(featureLevel); + extensions->packReverseRowOrderANGLE = true; + extensions->standardDerivativesOES = GetDerivativeInstructionSupport(featureLevel); + extensions->shaderTextureLodEXT = GetShaderTextureLODSupport(featureLevel); + extensions->fragDepthEXT = true; + extensions->multiviewOVR = IsMultiviewSupported(featureLevel); + extensions->multiview2OVR = IsMultiviewSupported(featureLevel); + if (extensions->multiviewOVR || extensions->multiview2OVR) + { + caps->maxViews = std::min(static_cast(GetMaximum2DTextureArraySize(featureLevel)), + GetMaxViewportAndScissorRectanglesPerPipeline(featureLevel)); + } + extensions->textureUsageANGLE = true; // This could be false since it has no effect in D3D11 + extensions->discardFramebufferEXT = true; + extensions->translatedShaderSourceANGLE = true; + extensions->fboRenderMipmapOES = true; + extensions->debugMarkerEXT = true; + extensions->EGLImageOES = true; + extensions->EGLImageExternalOES = true; + extensions->EGLImageExternalWrapModesEXT = true; + extensions->EGLImageExternalEssl3OES = true; + extensions->EGLStreamConsumerExternalNV = true; + extensions->unpackSubimageEXT = true; + extensions->packSubimageNV = true; + extensions->lossyEtcDecodeANGLE = true; + extensions->syncQueryCHROMIUM = GetEventQuerySupport(featureLevel); + extensions->copyTextureCHROMIUM = true; + extensions->copyCompressedTextureCHROMIUM = true; + extensions->textureStorageMultisample2dArrayOES = true; + extensions->multiviewMultisampleANGLE = + ((extensions->multiviewOVR || extensions->multiview2OVR) && + extensions->textureStorageMultisample2dArrayOES); + extensions->copyTexture3dANGLE = true; + extensions->textureBorderClampOES = true; + extensions->multiDrawIndirectEXT = true; + extensions->textureMultisampleANGLE = true; + extensions->provokingVertexANGLE = true; + extensions->blendFuncExtendedEXT = true; + // http://anglebug.com/4926 + extensions->texture3DOES = false; + extensions->baseInstanceEXT = true; + extensions->baseVertexBaseInstanceANGLE = true; + extensions->baseVertexBaseInstanceShaderBuiltinANGLE = true; + extensions->drawElementsBaseVertexOES = true; + extensions->drawElementsBaseVertexEXT = true; + if (!strstr(description, "Adreno")) + { + extensions->multisampledRenderToTextureEXT = true; + } + extensions->videoTextureWEBGL = true; + + // D3D11 cannot support reading depth texture as a luminance texture. + // It treats it as a red-channel-only texture. + extensions->depthTextureOES = false; + + // readPixels on depth & stencil not working with D3D11 backend. + extensions->readDepthNV = false; + extensions->readStencilNV = false; + extensions->depthBufferFloat2NV = false; + + // GL_EXT_clip_control + extensions->clipControlEXT = (renderer11DeviceCaps.featureLevel >= D3D_FEATURE_LEVEL_9_3); + + // GL_KHR_parallel_shader_compile + extensions->parallelShaderCompileKHR = true; + + // GL_EXT_texture_buffer + extensions->textureBufferEXT = HasTextureBufferSupport(device, renderer11DeviceCaps); + + // GL_OES_texture_buffer + extensions->textureBufferOES = extensions->textureBufferEXT; + + // ANGLE_shader_pixel_local_storage -- fragment shader UAVs appear in D3D 11.0. + extensions->shaderPixelLocalStorageANGLE = (featureLevel >= D3D_FEATURE_LEVEL_11_0); + extensions->shaderPixelLocalStorageCoherentANGLE = + renderer11DeviceCaps.supportsRasterizerOrderViews; + + // D3D11 Feature Level 10_0+ uses SV_IsFrontFace in HLSL to emulate gl_FrontFacing. + // D3D11 Feature Level 9_3 doesn't support SV_IsFrontFace, and has no equivalent, so can't + // support gl_FrontFacing. + limitations->noFrontFacingSupport = + (renderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3); + + // D3D11 Feature Level 9_3 doesn't support alpha-to-coverage + limitations->noSampleAlphaToCoverageSupport = + (renderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3); + + // D3D11 Feature Levels 9_3 and below do not support non-constant loop indexing and require + // additional + // pre-validation of the shader at compile time to produce a better error message. + limitations->shadersRequireIndexedLoopValidation = + (renderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3); + + // D3D11 has no concept of separate masks and refs for front and back faces in the depth stencil + // state. + limitations->noSeparateStencilRefsAndMasks = true; + + // D3D11 cannot support constant color and alpha blend funcs together + limitations->noSimultaneousConstantColorAndAlphaBlendFunc = true; + + // D3D11 does not support multiple transform feedback outputs writing to the same buffer. + limitations->noDoubleBoundTransformFeedbackBuffers = true; + + // D3D11 does not support vertex attribute aliasing + limitations->noVertexAttributeAliasing = true; + + // D3D11 does not support compressed textures where the base mip level is not a multiple of 4 + limitations->compressedBaseMipLevelMultipleOfFour = true; + + if (extensions->textureBufferAny()) + { + caps->maxTextureBufferSize = 1 << D3D11_REQ_BUFFER_RESOURCE_TEXEL_COUNT_2_TO_EXP; + // this maybe touble for RGB32 format. + caps->textureBufferOffsetAlignment = 16; + } + +#ifdef ANGLE_ENABLE_WINDOWS_UWP + // Setting a non-zero divisor on attribute zero doesn't work on certain Windows Phone 8-era + // devices. We should prevent developers from doing this on ALL Windows Store devices. This will + // maintain consistency across all Windows devices. We allow non-zero divisors on attribute zero + // if the Client Version >= 3, since devices affected by this issue don't support ES3+. + limitations->attributeZeroRequiresZeroDivisorInEXT = true; +#endif +} + +} // namespace d3d11_gl + +namespace gl_d3d11 +{ + +D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha) +{ + D3D11_BLEND d3dBlend = D3D11_BLEND_ZERO; + + switch (glBlend) + { + case GL_ZERO: + d3dBlend = D3D11_BLEND_ZERO; + break; + case GL_ONE: + d3dBlend = D3D11_BLEND_ONE; + break; + case GL_SRC_COLOR: + d3dBlend = (isAlpha ? D3D11_BLEND_SRC_ALPHA : D3D11_BLEND_SRC_COLOR); + break; + case GL_ONE_MINUS_SRC_COLOR: + d3dBlend = (isAlpha ? D3D11_BLEND_INV_SRC_ALPHA : D3D11_BLEND_INV_SRC_COLOR); + break; + case GL_DST_COLOR: + d3dBlend = (isAlpha ? D3D11_BLEND_DEST_ALPHA : D3D11_BLEND_DEST_COLOR); + break; + case GL_ONE_MINUS_DST_COLOR: + d3dBlend = (isAlpha ? D3D11_BLEND_INV_DEST_ALPHA : D3D11_BLEND_INV_DEST_COLOR); + break; + case GL_SRC_ALPHA: + d3dBlend = D3D11_BLEND_SRC_ALPHA; + break; + case GL_ONE_MINUS_SRC_ALPHA: + d3dBlend = D3D11_BLEND_INV_SRC_ALPHA; + break; + case GL_DST_ALPHA: + d3dBlend = D3D11_BLEND_DEST_ALPHA; + break; + case GL_ONE_MINUS_DST_ALPHA: + d3dBlend = D3D11_BLEND_INV_DEST_ALPHA; + break; + case GL_CONSTANT_COLOR: + d3dBlend = D3D11_BLEND_BLEND_FACTOR; + break; + case GL_ONE_MINUS_CONSTANT_COLOR: + d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR; + break; + case GL_CONSTANT_ALPHA: + d3dBlend = D3D11_BLEND_BLEND_FACTOR; + break; + case GL_ONE_MINUS_CONSTANT_ALPHA: + d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR; + break; + case GL_SRC_ALPHA_SATURATE: + d3dBlend = D3D11_BLEND_SRC_ALPHA_SAT; + break; + case GL_SRC1_COLOR_EXT: + d3dBlend = (isAlpha ? D3D11_BLEND_SRC1_ALPHA : D3D11_BLEND_SRC1_COLOR); + break; + case GL_SRC1_ALPHA_EXT: + d3dBlend = D3D11_BLEND_SRC1_ALPHA; + break; + case GL_ONE_MINUS_SRC1_COLOR_EXT: + d3dBlend = (isAlpha ? D3D11_BLEND_INV_SRC1_ALPHA : D3D11_BLEND_INV_SRC1_COLOR); + break; + case GL_ONE_MINUS_SRC1_ALPHA_EXT: + d3dBlend = D3D11_BLEND_INV_SRC1_ALPHA; + break; + default: + UNREACHABLE(); + } + + return d3dBlend; +} + +D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp) +{ + D3D11_BLEND_OP d3dBlendOp = D3D11_BLEND_OP_ADD; + + switch (glBlendOp) + { + case GL_FUNC_ADD: + d3dBlendOp = D3D11_BLEND_OP_ADD; + break; + case GL_FUNC_SUBTRACT: + d3dBlendOp = D3D11_BLEND_OP_SUBTRACT; + break; + case GL_FUNC_REVERSE_SUBTRACT: + d3dBlendOp = D3D11_BLEND_OP_REV_SUBTRACT; + break; + case GL_MIN: + d3dBlendOp = D3D11_BLEND_OP_MIN; + break; + case GL_MAX: + d3dBlendOp = D3D11_BLEND_OP_MAX; + break; + default: + UNREACHABLE(); + } + + return d3dBlendOp; +} + +UINT8 ConvertColorMask(bool red, bool green, bool blue, bool alpha) +{ + UINT8 mask = 0; + if (red) + { + mask |= D3D11_COLOR_WRITE_ENABLE_RED; + } + if (green) + { + mask |= D3D11_COLOR_WRITE_ENABLE_GREEN; + } + if (blue) + { + mask |= D3D11_COLOR_WRITE_ENABLE_BLUE; + } + if (alpha) + { + mask |= D3D11_COLOR_WRITE_ENABLE_ALPHA; + } + return mask; +} + +D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, gl::CullFaceMode cullMode) +{ + D3D11_CULL_MODE cull = D3D11_CULL_NONE; + + if (cullEnabled) + { + switch (cullMode) + { + case gl::CullFaceMode::Front: + cull = D3D11_CULL_FRONT; + break; + case gl::CullFaceMode::Back: + cull = D3D11_CULL_BACK; + break; + case gl::CullFaceMode::FrontAndBack: + cull = D3D11_CULL_NONE; + break; + default: + UNREACHABLE(); + } + } + else + { + cull = D3D11_CULL_NONE; + } + + return cull; +} + +D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison) +{ + D3D11_COMPARISON_FUNC d3dComp = D3D11_COMPARISON_NEVER; + switch (comparison) + { + case GL_NEVER: + d3dComp = D3D11_COMPARISON_NEVER; + break; + case GL_ALWAYS: + d3dComp = D3D11_COMPARISON_ALWAYS; + break; + case GL_LESS: + d3dComp = D3D11_COMPARISON_LESS; + break; + case GL_LEQUAL: + d3dComp = D3D11_COMPARISON_LESS_EQUAL; + break; + case GL_EQUAL: + d3dComp = D3D11_COMPARISON_EQUAL; + break; + case GL_GREATER: + d3dComp = D3D11_COMPARISON_GREATER; + break; + case GL_GEQUAL: + d3dComp = D3D11_COMPARISON_GREATER_EQUAL; + break; + case GL_NOTEQUAL: + d3dComp = D3D11_COMPARISON_NOT_EQUAL; + break; + default: + UNREACHABLE(); + } + + return d3dComp; +} + +D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled) +{ + return depthWriteEnabled ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO; +} + +UINT8 ConvertStencilMask(GLuint stencilmask) +{ + return static_cast(stencilmask); +} + +D3D11_STENCIL_OP ConvertStencilOp(GLenum stencilOp) +{ + D3D11_STENCIL_OP d3dStencilOp = D3D11_STENCIL_OP_KEEP; + + switch (stencilOp) + { + case GL_ZERO: + d3dStencilOp = D3D11_STENCIL_OP_ZERO; + break; + case GL_KEEP: + d3dStencilOp = D3D11_STENCIL_OP_KEEP; + break; + case GL_REPLACE: + d3dStencilOp = D3D11_STENCIL_OP_REPLACE; + break; + case GL_INCR: + d3dStencilOp = D3D11_STENCIL_OP_INCR_SAT; + break; + case GL_DECR: + d3dStencilOp = D3D11_STENCIL_OP_DECR_SAT; + break; + case GL_INVERT: + d3dStencilOp = D3D11_STENCIL_OP_INVERT; + break; + case GL_INCR_WRAP: + d3dStencilOp = D3D11_STENCIL_OP_INCR; + break; + case GL_DECR_WRAP: + d3dStencilOp = D3D11_STENCIL_OP_DECR; + break; + default: + UNREACHABLE(); + } + + return d3dStencilOp; +} + +D3D11_FILTER ConvertFilter(GLenum minFilter, + GLenum magFilter, + float maxAnisotropy, + GLenum comparisonMode) +{ + bool comparison = comparisonMode != GL_NONE; + + if (maxAnisotropy > 1.0f) + { + return D3D11_ENCODE_ANISOTROPIC_FILTER(static_cast(comparison)); + } + else + { + D3D11_FILTER_TYPE dxMin = D3D11_FILTER_TYPE_POINT; + D3D11_FILTER_TYPE dxMip = D3D11_FILTER_TYPE_POINT; + switch (minFilter) + { + case GL_NEAREST: + dxMin = D3D11_FILTER_TYPE_POINT; + dxMip = D3D11_FILTER_TYPE_POINT; + break; + case GL_LINEAR: + dxMin = D3D11_FILTER_TYPE_LINEAR; + dxMip = D3D11_FILTER_TYPE_POINT; + break; + case GL_NEAREST_MIPMAP_NEAREST: + dxMin = D3D11_FILTER_TYPE_POINT; + dxMip = D3D11_FILTER_TYPE_POINT; + break; + case GL_LINEAR_MIPMAP_NEAREST: + dxMin = D3D11_FILTER_TYPE_LINEAR; + dxMip = D3D11_FILTER_TYPE_POINT; + break; + case GL_NEAREST_MIPMAP_LINEAR: + dxMin = D3D11_FILTER_TYPE_POINT; + dxMip = D3D11_FILTER_TYPE_LINEAR; + break; + case GL_LINEAR_MIPMAP_LINEAR: + dxMin = D3D11_FILTER_TYPE_LINEAR; + dxMip = D3D11_FILTER_TYPE_LINEAR; + break; + default: + UNREACHABLE(); + } + + D3D11_FILTER_TYPE dxMag = D3D11_FILTER_TYPE_POINT; + switch (magFilter) + { + case GL_NEAREST: + dxMag = D3D11_FILTER_TYPE_POINT; + break; + case GL_LINEAR: + dxMag = D3D11_FILTER_TYPE_LINEAR; + break; + default: + UNREACHABLE(); + } + + return D3D11_ENCODE_BASIC_FILTER(dxMin, dxMag, dxMip, + static_cast(comparison)); + } +} + +D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap) +{ + switch (wrap) + { + case GL_REPEAT: + return D3D11_TEXTURE_ADDRESS_WRAP; + case GL_CLAMP_TO_EDGE: + return D3D11_TEXTURE_ADDRESS_CLAMP; + case GL_CLAMP_TO_BORDER: + return D3D11_TEXTURE_ADDRESS_BORDER; + case GL_MIRRORED_REPEAT: + return D3D11_TEXTURE_ADDRESS_MIRROR; + default: + UNREACHABLE(); + } + + return D3D11_TEXTURE_ADDRESS_WRAP; +} + +UINT ConvertMaxAnisotropy(float maxAnisotropy, D3D_FEATURE_LEVEL featureLevel) +{ + return static_cast(std::min(maxAnisotropy, d3d11_gl::GetMaximumAnisotropy(featureLevel))); +} + +D3D11_QUERY ConvertQueryType(gl::QueryType type) +{ + switch (type) + { + case gl::QueryType::AnySamples: + case gl::QueryType::AnySamplesConservative: + return D3D11_QUERY_OCCLUSION; + case gl::QueryType::TransformFeedbackPrimitivesWritten: + return D3D11_QUERY_SO_STATISTICS; + case gl::QueryType::TimeElapsed: + // Two internal queries are also created for begin/end timestamps + return D3D11_QUERY_TIMESTAMP_DISJOINT; + case gl::QueryType::CommandsCompleted: + return D3D11_QUERY_EVENT; + default: + UNREACHABLE(); + return D3D11_QUERY_EVENT; + } +} + +// Get the D3D11 write mask covering all color channels of a given format +UINT8 GetColorMask(const gl::InternalFormat &format) +{ + return ConvertColorMask(format.redBits > 0, format.greenBits > 0, format.blueBits > 0, + format.alphaBits > 0); +} + +} // namespace gl_d3d11 + +namespace d3d11 +{ + +ANGLED3D11DeviceType GetDeviceType(ID3D11Device *device) +{ + // Note that this function returns an ANGLED3D11DeviceType rather than a D3D_DRIVER_TYPE value, + // since it is difficult to tell Software and Reference devices apart + + IDXGIDevice *dxgiDevice = nullptr; + IDXGIAdapter *dxgiAdapter = nullptr; + IDXGIAdapter2 *dxgiAdapter2 = nullptr; + + ANGLED3D11DeviceType retDeviceType = ANGLE_D3D11_DEVICE_TYPE_UNKNOWN; + + HRESULT hr = device->QueryInterface(__uuidof(IDXGIDevice), (void **)&dxgiDevice); + if (SUCCEEDED(hr)) + { + hr = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void **)&dxgiAdapter); + if (SUCCEEDED(hr)) + { + std::wstring adapterString; + HRESULT adapter2hr = + dxgiAdapter->QueryInterface(__uuidof(dxgiAdapter2), (void **)&dxgiAdapter2); + if (SUCCEEDED(adapter2hr)) + { + // On D3D_FEATURE_LEVEL_9_*, IDXGIAdapter::GetDesc returns "Software Adapter" + // for the description string. Try to use IDXGIAdapter2::GetDesc2 to get the + // actual hardware values if possible. + DXGI_ADAPTER_DESC2 adapterDesc2; + dxgiAdapter2->GetDesc2(&adapterDesc2); + adapterString = std::wstring(adapterDesc2.Description); + } + else + { + DXGI_ADAPTER_DESC adapterDesc; + dxgiAdapter->GetDesc(&adapterDesc); + adapterString = std::wstring(adapterDesc.Description); + } + + // Both Reference and Software adapters will be 'Software Adapter' + const bool isSoftwareDevice = + (adapterString.find(std::wstring(L"Software Adapter")) != std::string::npos); + const bool isNullDevice = (adapterString == L""); + const bool isWARPDevice = + (adapterString.find(std::wstring(L"Basic Render")) != std::string::npos); + + if (isSoftwareDevice || isNullDevice) + { + ASSERT(!isWARPDevice); + retDeviceType = ANGLE_D3D11_DEVICE_TYPE_SOFTWARE_REF_OR_NULL; + } + else if (isWARPDevice) + { + retDeviceType = ANGLE_D3D11_DEVICE_TYPE_WARP; + } + else + { + retDeviceType = ANGLE_D3D11_DEVICE_TYPE_HARDWARE; + } + } + } + + SafeRelease(dxgiDevice); + SafeRelease(dxgiAdapter); + SafeRelease(dxgiAdapter2); + + return retDeviceType; +} + +void MakeValidSize(bool isImage, + DXGI_FORMAT format, + GLsizei *requestWidth, + GLsizei *requestHeight, + int *levelOffset) +{ + const DXGIFormatSize &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(format); + bool validFormat = format != DXGI_FORMAT_UNKNOWN; + bool validImage = isImage && validFormat; + + int upsampleCount = 0; + // Don't expand the size of full textures that are at least (blockWidth x blockHeight) already. + if (validImage || *requestWidth < static_cast(dxgiFormatInfo.blockWidth) || + *requestHeight < static_cast(dxgiFormatInfo.blockHeight)) + { + while (*requestWidth % dxgiFormatInfo.blockWidth != 0 || + *requestHeight % dxgiFormatInfo.blockHeight != 0) + { + *requestWidth <<= 1; + *requestHeight <<= 1; + upsampleCount++; + } + } + else if (validFormat) + { + if (*requestWidth % dxgiFormatInfo.blockWidth != 0) + { + *requestWidth = roundUp(*requestWidth, static_cast(dxgiFormatInfo.blockWidth)); + } + + if (*requestHeight % dxgiFormatInfo.blockHeight != 0) + { + *requestHeight = + roundUp(*requestHeight, static_cast(dxgiFormatInfo.blockHeight)); + } + } + + if (levelOffset) + { + *levelOffset = upsampleCount; + } +} + +angle::Result GenerateInitialTextureData( + const gl::Context *context, + GLint internalFormat, + const Renderer11DeviceCaps &renderer11DeviceCaps, + GLuint width, + GLuint height, + GLuint depth, + GLuint mipLevels, + gl::TexLevelArray *outSubresourceData) +{ + const d3d11::Format &d3dFormatInfo = d3d11::Format::Get(internalFormat, renderer11DeviceCaps); + ASSERT(d3dFormatInfo.dataInitializerFunction != nullptr); + + const d3d11::DXGIFormatSize &dxgiFormatInfo = + d3d11::GetDXGIFormatSizeInfo(d3dFormatInfo.texFormat); + + using CheckedSize = angle::CheckedNumeric; + CheckedSize rowPitch = CheckedSize(dxgiFormatInfo.pixelBytes) * CheckedSize(width); + CheckedSize depthPitch = rowPitch * CheckedSize(height); + CheckedSize maxImageSize = depthPitch * CheckedSize(depth); + + Context11 *context11 = GetImplAs(context); + ANGLE_CHECK_GL_ALLOC(context11, maxImageSize.IsValid()); + + angle::MemoryBuffer *scratchBuffer = nullptr; + ANGLE_CHECK_GL_ALLOC(context11, + context->getScratchBuffer(maxImageSize.ValueOrDie(), &scratchBuffer)); + + d3dFormatInfo.dataInitializerFunction(width, height, depth, scratchBuffer->data(), + rowPitch.ValueOrDie(), depthPitch.ValueOrDie()); + + for (unsigned int i = 0; i < mipLevels; i++) + { + unsigned int mipWidth = std::max(width >> i, 1U); + unsigned int mipHeight = std::max(height >> i, 1U); + + using CheckedUINT = angle::CheckedNumeric; + CheckedUINT mipRowPitch = CheckedUINT(dxgiFormatInfo.pixelBytes) * CheckedUINT(mipWidth); + CheckedUINT mipDepthPitch = mipRowPitch * CheckedUINT(mipHeight); + + ANGLE_CHECK_GL_ALLOC(context11, mipRowPitch.IsValid() && mipDepthPitch.IsValid()); + + outSubresourceData->at(i).pSysMem = scratchBuffer->data(); + outSubresourceData->at(i).SysMemPitch = mipRowPitch.ValueOrDie(); + outSubresourceData->at(i).SysMemSlicePitch = mipDepthPitch.ValueOrDie(); + } + + return angle::Result::Continue; +} + +UINT GetPrimitiveRestartIndex() +{ + return std::numeric_limits::max(); +} + +void SetPositionTexCoordVertex(PositionTexCoordVertex *vertex, float x, float y, float u, float v) +{ + vertex->x = x; + vertex->y = y; + vertex->u = u; + vertex->v = v; +} + +void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex *vertex, + float x, + float y, + unsigned int layer, + float u, + float v, + float s) +{ + vertex->x = x; + vertex->y = y; + vertex->l = layer; + vertex->u = u; + vertex->v = v; + vertex->s = s; +} + +BlendStateKey::BlendStateKey() +{ + memset(this, 0, sizeof(BlendStateKey)); + blendStateExt = gl::BlendStateExt(); +} + +BlendStateKey::BlendStateKey(const BlendStateKey &other) +{ + memcpy(this, &other, sizeof(BlendStateKey)); +} + +bool operator==(const BlendStateKey &a, const BlendStateKey &b) +{ + return memcmp(&a, &b, sizeof(BlendStateKey)) == 0; +} + +bool operator!=(const BlendStateKey &a, const BlendStateKey &b) +{ + return !(a == b); +} + +RasterizerStateKey::RasterizerStateKey() +{ + memset(this, 0, sizeof(RasterizerStateKey)); +} + +bool operator==(const RasterizerStateKey &a, const RasterizerStateKey &b) +{ + return memcmp(&a, &b, sizeof(RasterizerStateKey)) == 0; +} + +bool operator!=(const RasterizerStateKey &a, const RasterizerStateKey &b) +{ + return !(a == b); +} + +HRESULT SetDebugName(ID3D11DeviceChild *resource, + const char *internalName, + const std::string *khrDebugName) +{ + // Prepend ANGLE to separate names from other components in the same process. + std::string d3dName = "ANGLE"; + bool sendNameToD3D = false; + if (internalName && internalName[0] != '\0') + { + d3dName += std::string("_") + internalName; + sendNameToD3D = true; + } + if (khrDebugName && !khrDebugName->empty()) + { + d3dName += std::string("_") + *khrDebugName; + sendNameToD3D = true; + } + // If both internalName and khrDebugName are empty, avoid sending the string to d3d. + if (sendNameToD3D) + { + return resource->SetPrivateData(WKPDID_D3DDebugObjectName, + static_cast(d3dName.size()), d3dName.c_str()); + } + return S_OK; +} + +// Keep this in cpp file where it has visibility of Renderer11.h, otherwise calling +// allocateResource is only compatible with Clang and MSVS, which support calling a +// method on a forward declared class in a template. +template +angle::Result LazyResource::resolveImpl(d3d::Context *context, + Renderer11 *renderer, + const GetDescType &desc, + GetInitDataType *initData, + const char *name) +{ + if (!mResource.valid()) + { + ANGLE_TRY(renderer->allocateResource(context, desc, initData, &mResource)); + mResource.setInternalName(name); + } + return angle::Result::Continue; +} + +template angle::Result LazyResource::resolveImpl( + d3d::Context *context, + Renderer11 *renderer, + const D3D11_BLEND_DESC &desc, + void *initData, + const char *name); +template angle::Result LazyResource::resolveImpl( + d3d::Context *context, + Renderer11 *renderer, + const ShaderData &desc, + void *initData, + const char *name); +template angle::Result LazyResource::resolveImpl( + d3d::Context *context, + Renderer11 *renderer, + const ShaderData &desc, + const std::vector *initData, + const char *name); +template angle::Result LazyResource::resolveImpl( + d3d::Context *context, + Renderer11 *renderer, + const InputElementArray &desc, + const ShaderData *initData, + const char *name); +template angle::Result LazyResource::resolveImpl(d3d::Context *context, + Renderer11 *renderer, + const ShaderData &desc, + void *initData, + const char *name); +template angle::Result LazyResource::resolveImpl(d3d::Context *context, + Renderer11 *renderer, + const ShaderData &desc, + void *initData, + const char *name); + +LazyInputLayout::LazyInputLayout(const D3D11_INPUT_ELEMENT_DESC *inputDesc, + size_t inputDescLen, + const BYTE *byteCode, + size_t byteCodeLen, + const char *debugName) + : mInputDesc(inputDesc, inputDescLen), mByteCode(byteCode, byteCodeLen), mDebugName(debugName) +{} + +LazyInputLayout::~LazyInputLayout() {} + +angle::Result LazyInputLayout::resolve(d3d::Context *context, Renderer11 *renderer) +{ + return resolveImpl(context, renderer, mInputDesc, &mByteCode, mDebugName); +} + +LazyBlendState::LazyBlendState(const D3D11_BLEND_DESC &desc, const char *debugName) + : mDesc(desc), mDebugName(debugName) +{} + +angle::Result LazyBlendState::resolve(d3d::Context *context, Renderer11 *renderer) +{ + return resolveImpl(context, renderer, mDesc, nullptr, mDebugName); +} + +void InitializeFeatures(const Renderer11DeviceCaps &deviceCaps, + const DXGI_ADAPTER_DESC &adapterDesc, + angle::FeaturesD3D *features) +{ + bool isNvidia = IsNvidia(adapterDesc.VendorId); + bool isIntel = IsIntel(adapterDesc.VendorId); + bool isSkylake = false; + bool isBroadwell = false; + bool isHaswell = false; + bool isIvyBridge = false; + bool isSandyBridge = false; + bool isAMD = IsAMD(adapterDesc.VendorId); + bool isFeatureLevel9_3 = (deviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3); + + IntelDriverVersion capsVersion = IntelDriverVersion(0); + if (isIntel) + { + capsVersion = d3d11_gl::GetIntelDriverVersion(deviceCaps.driverVersion); + + isSkylake = IsSkylake(adapterDesc.DeviceId); + isBroadwell = IsBroadwell(adapterDesc.DeviceId); + isHaswell = IsHaswell(adapterDesc.DeviceId); + isIvyBridge = IsIvyBridge(adapterDesc.DeviceId); + isSandyBridge = IsSandyBridge(adapterDesc.DeviceId); + } + + if (isNvidia) + { + // TODO(jmadill): Narrow problematic driver range. + bool driverVersionValid = deviceCaps.driverVersion.valid(); + if (driverVersionValid) + { + WORD part1 = HIWORD(deviceCaps.driverVersion.value().LowPart); + WORD part2 = LOWORD(deviceCaps.driverVersion.value().LowPart); + + // Disable the workaround to fix a second driver bug on newer NVIDIA. + ANGLE_FEATURE_CONDITION( + features, depthStencilBlitExtraCopy, + (part1 <= 13u && part2 < 6881) && isNvidia && driverVersionValid); + } + else + { + ANGLE_FEATURE_CONDITION(features, depthStencilBlitExtraCopy, + isNvidia && !driverVersionValid); + } + } + + ANGLE_FEATURE_CONDITION(features, mrtPerfWorkaround, true); + ANGLE_FEATURE_CONDITION(features, zeroMaxLodWorkaround, isFeatureLevel9_3); + ANGLE_FEATURE_CONDITION(features, useInstancedPointSpriteEmulation, isFeatureLevel9_3); + ANGLE_FEATURE_CONDITION(features, allowES3OnFL100, false); + + // TODO(jmadill): Disable workaround when we have a fixed compiler DLL. + ANGLE_FEATURE_CONDITION(features, expandIntegerPowExpressions, true); + + ANGLE_FEATURE_CONDITION(features, flushAfterEndingTransformFeedback, isNvidia); + ANGLE_FEATURE_CONDITION(features, getDimensionsIgnoresBaseLevel, isNvidia); + ANGLE_FEATURE_CONDITION(features, skipVSConstantRegisterZero, isNvidia); + ANGLE_FEATURE_CONDITION(features, forceAtomicValueResolution, isNvidia); + + ANGLE_FEATURE_CONDITION(features, preAddTexelFetchOffsets, isIntel); + ANGLE_FEATURE_CONDITION(features, useSystemMemoryForConstantBuffers, isIntel); + + // ClearView on Skylake seems to incorrectly clear with unaligned rects (edge has saw tooth + // pattern instead of straight). + ANGLE_FEATURE_CONDITION(features, scissoredClearArtifacts, isIntel && isSkylake); + + ANGLE_FEATURE_CONDITION(features, callClearTwice, + isIntel && isSkylake && capsVersion >= IntelDriverVersion(160000) && + capsVersion < IntelDriverVersion(164771)); + ANGLE_FEATURE_CONDITION(features, emulateIsnanFloat, + isIntel && isSkylake && capsVersion >= IntelDriverVersion(160000) && + capsVersion < IntelDriverVersion(164542)); + ANGLE_FEATURE_CONDITION(features, rewriteUnaryMinusOperator, + isIntel && (isBroadwell || isHaswell) && + capsVersion >= IntelDriverVersion(150000) && + capsVersion < IntelDriverVersion(154624)); + + ANGLE_FEATURE_CONDITION(features, addMockTextureNoRenderTarget, + isIntel && capsVersion >= IntelDriverVersion(160000) && + capsVersion < IntelDriverVersion(164815)); + + // Haswell drivers occasionally corrupt (small?) (vertex?) texture data uploads for 128bit + // formats. + ANGLE_FEATURE_CONDITION(features, setDataFasterThanImageUpload, true); + ANGLE_FEATURE_CONDITION(features, setDataFasterThanImageUploadOn128bitFormats, + !(isIvyBridge || isBroadwell || isHaswell)); + + ANGLE_FEATURE_CONDITION(features, emulateClearViewAfterDualSourceBlending, isSandyBridge); + + ANGLE_FEATURE_CONDITION(features, disableB5G6R5Support, + (isIntel && capsVersion >= IntelDriverVersion(150000) && + capsVersion < IntelDriverVersion(154539)) || + isAMD); + + // TODO(jmadill): Disable when we have a fixed driver version. + // The tiny stencil texture workaround involves using CopySubresource or UpdateSubresource on a + // depth stencil texture. This is not allowed until feature level 10.1 but since it is not + // possible to support ES3 on these devices, there is no need for the workaround to begin with + // (anglebug.com/1572). + ANGLE_FEATURE_CONDITION(features, emulateTinyStencilTextures, + isAMD && !(deviceCaps.featureLevel < D3D_FEATURE_LEVEL_10_1)); + + // If the VPAndRTArrayIndexFromAnyShaderFeedingRasterizer feature is not available, we have to + // select the viewport / RT array index in the geometry shader. + ANGLE_FEATURE_CONDITION(features, selectViewInGeometryShader, + !deviceCaps.supportsVpRtIndexWriteFromVertexShader); + + // NVidia drivers have no trouble clearing textures without showing corruption. + // Intel and AMD drivers that have trouble have been blocklisted by Chromium. In the case of + // Intel, they've been blocklisted to the DX9 runtime. + ANGLE_FEATURE_CONDITION(features, allowClearForRobustResourceInit, true); + + // Allow translating uniform block to StructuredBuffer on Windows 10. This is targeted + // to work around a slow fxc compile performance issue with dynamic uniform indexing. + ANGLE_FEATURE_CONDITION(features, allowTranslateUniformBlockToStructuredBuffer, + IsWin10OrGreater()); +} + +void InitializeFrontendFeatures(const DXGI_ADAPTER_DESC &adapterDesc, + angle::FrontendFeatures *features) +{ + bool isAMD = IsAMD(adapterDesc.VendorId); + + ANGLE_FEATURE_CONDITION(features, forceDepthAttachmentInitOnClear, isAMD); +} + +void InitConstantBufferDesc(D3D11_BUFFER_DESC *constantBufferDescription, size_t byteWidth) +{ + constantBufferDescription->ByteWidth = static_cast(byteWidth); + constantBufferDescription->Usage = D3D11_USAGE_DYNAMIC; + constantBufferDescription->BindFlags = D3D11_BIND_CONSTANT_BUFFER; + constantBufferDescription->CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + constantBufferDescription->MiscFlags = 0; + constantBufferDescription->StructureByteStride = 0; +} + +} // namespace d3d11 + +// TextureHelper11 implementation. +TextureHelper11::TextureHelper11() : mFormatSet(nullptr), mSampleCount(0) {} + +TextureHelper11::TextureHelper11(TextureHelper11 &&toCopy) : TextureHelper11() +{ + *this = std::move(toCopy); +} + +TextureHelper11::TextureHelper11(const TextureHelper11 &other) + : mFormatSet(other.mFormatSet), mExtents(other.mExtents), mSampleCount(other.mSampleCount) +{ + mData = other.mData; +} + +TextureHelper11::~TextureHelper11() {} + +void TextureHelper11::getDesc(D3D11_TEXTURE2D_DESC *desc) const +{ + static_cast(mData->object)->GetDesc(desc); +} + +void TextureHelper11::getDesc(D3D11_TEXTURE3D_DESC *desc) const +{ + static_cast(mData->object)->GetDesc(desc); +} + +void TextureHelper11::getDesc(D3D11_BUFFER_DESC *desc) const +{ + static_cast(mData->object)->GetDesc(desc); +} + +void TextureHelper11::initDesc(const D3D11_TEXTURE2D_DESC &desc2D) +{ + mData->resourceType = ResourceType::Texture2D; + mExtents.width = static_cast(desc2D.Width); + mExtents.height = static_cast(desc2D.Height); + mExtents.depth = 1; + mSampleCount = desc2D.SampleDesc.Count; +} + +void TextureHelper11::initDesc(const D3D11_TEXTURE3D_DESC &desc3D) +{ + mData->resourceType = ResourceType::Texture3D; + mExtents.width = static_cast(desc3D.Width); + mExtents.height = static_cast(desc3D.Height); + mExtents.depth = static_cast(desc3D.Depth); + mSampleCount = 1; +} + +void TextureHelper11::initDesc(const D3D11_BUFFER_DESC &descBuffer) +{ + mData->resourceType = ResourceType::Buffer; + mExtents.width = static_cast(descBuffer.ByteWidth); + mExtents.height = 1; + mExtents.depth = 1; + mSampleCount = 1; +} + +TextureHelper11 &TextureHelper11::operator=(TextureHelper11 &&other) +{ + std::swap(mData, other.mData); + std::swap(mExtents, other.mExtents); + std::swap(mFormatSet, other.mFormatSet); + std::swap(mSampleCount, other.mSampleCount); + return *this; +} + +TextureHelper11 &TextureHelper11::operator=(const TextureHelper11 &other) +{ + mData = other.mData; + mExtents = other.mExtents; + mFormatSet = other.mFormatSet; + mSampleCount = other.mSampleCount; + return *this; +} + +bool TextureHelper11::operator==(const TextureHelper11 &other) const +{ + return mData->object == other.mData->object; +} + +bool TextureHelper11::operator!=(const TextureHelper11 &other) const +{ + return mData->object != other.mData->object; +} + +bool UsePresentPathFast(const Renderer11 *renderer, + const gl::FramebufferAttachment *framebufferAttachment) +{ + if (framebufferAttachment == nullptr) + { + return false; + } + + return (framebufferAttachment->type() == GL_FRAMEBUFFER_DEFAULT && + renderer->presentPathFastEnabled()); +} + +bool UsePrimitiveRestartWorkaround(bool primitiveRestartFixedIndexEnabled, + gl::DrawElementsType type) +{ + // We should never have to deal with primitive restart workaround issue with GL_UNSIGNED_INT + // indices, since we restrict it via MAX_ELEMENT_INDEX. + return (!primitiveRestartFixedIndexEnabled && type == gl::DrawElementsType::UnsignedShort); +} + +IndexStorageType ClassifyIndexStorage(const gl::State &glState, + const gl::Buffer *elementArrayBuffer, + gl::DrawElementsType elementType, + gl::DrawElementsType destElementType, + unsigned int offset) +{ + // No buffer bound means we are streaming from a client pointer. + if (!elementArrayBuffer || !IsOffsetAligned(elementType, offset)) + { + return IndexStorageType::Dynamic; + } + + // The buffer can be used directly if the storage supports it and no translation needed. + BufferD3D *bufferD3D = GetImplAs(elementArrayBuffer); + if (bufferD3D->supportsDirectBinding() && destElementType == elementType) + { + return IndexStorageType::Direct; + } + + // Use a static copy when available. + StaticIndexBufferInterface *staticBuffer = bufferD3D->getStaticIndexBuffer(); + if (staticBuffer != nullptr) + { + return IndexStorageType::Static; + } + + // Static buffer not available, fall back to streaming. + return IndexStorageType::Dynamic; +} + +bool SwizzleRequired(const gl::TextureState &textureState) +{ + // When sampling stencil, a swizzle is needed to move the stencil channel from G to R. + return textureState.swizzleRequired() || textureState.isStencilMode(); +} + +gl::SwizzleState GetEffectiveSwizzle(const gl::TextureState &textureState) +{ + const gl::SwizzleState &swizzle = textureState.getSwizzleState(); + if (textureState.isStencilMode()) + { + // Per GL semantics, the stencil value should be in the red channel, while D3D11 formats + // leave stencil in the green channel. So copy the stencil value from green to all + // components requesting red. Green and blue become zero; alpha becomes one. + std::unordered_map map = {{GL_RED, GL_GREEN}, {GL_GREEN, GL_ZERO}, + {GL_BLUE, GL_ZERO}, {GL_ALPHA, GL_ONE}, + {GL_ZERO, GL_ZERO}, {GL_ONE, GL_ONE}}; + + return gl::SwizzleState(map[swizzle.swizzleRed], map[swizzle.swizzleGreen], + map[swizzle.swizzleBlue], map[swizzle.swizzleAlpha]); + } + return swizzle; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h new file mode 100644 index 0000000000..a8cd430bc6 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h @@ -0,0 +1,478 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// renderer11_utils.h: Conversion functions and other utility routines +// specific to the D3D11 renderer. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_UTILS_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_UTILS_H_ + +#include +#include +#include + +#include "common/Color.h" + +#include "libANGLE/Caps.h" +#include "libANGLE/Error.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" +#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" + +namespace gl +{ +class FramebufferAttachment; +} + +namespace rx +{ +class Context11; +class Renderer11; +class RenderTarget11; +struct Renderer11DeviceCaps; + +using RTVArray = std::array; + +namespace gl_d3d11 +{ + +D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha); +D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp); +UINT8 ConvertColorMask(bool maskRed, bool maskGreen, bool maskBlue, bool maskAlpha); + +D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, gl::CullFaceMode cullMode); + +D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison); +D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled); +UINT8 ConvertStencilMask(GLuint stencilmask); +D3D11_STENCIL_OP ConvertStencilOp(GLenum stencilOp); + +D3D11_FILTER ConvertFilter(GLenum minFilter, + GLenum magFilter, + float maxAnisotropy, + GLenum comparisonMode); +D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap); +UINT ConvertMaxAnisotropy(float maxAnisotropy, D3D_FEATURE_LEVEL featureLevel); + +D3D11_QUERY ConvertQueryType(gl::QueryType type); + +UINT8 GetColorMask(const gl::InternalFormat &formatInfo); + +} // namespace gl_d3d11 + +namespace d3d11_gl +{ + +unsigned int GetReservedVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel); + +unsigned int GetReservedFragmentUniformVectors(D3D_FEATURE_LEVEL featureLevel); + +gl::Version GetMaximumClientVersion(const Renderer11DeviceCaps &caps); +void GenerateCaps(ID3D11Device *device, + ID3D11DeviceContext *deviceContext, + const Renderer11DeviceCaps &renderer11DeviceCaps, + const angle::FeaturesD3D &features, + const char *description, + gl::Caps *caps, + gl::TextureCapsMap *textureCapsMap, + gl::Extensions *extensions, + gl::Limitations *limitations); + +D3D_FEATURE_LEVEL GetMinimumFeatureLevelForES31(); + +} // namespace d3d11_gl + +namespace d3d11 +{ + +enum ANGLED3D11DeviceType +{ + ANGLE_D3D11_DEVICE_TYPE_UNKNOWN, + ANGLE_D3D11_DEVICE_TYPE_HARDWARE, + ANGLE_D3D11_DEVICE_TYPE_SOFTWARE_REF_OR_NULL, + ANGLE_D3D11_DEVICE_TYPE_WARP, +}; + +ANGLED3D11DeviceType GetDeviceType(ID3D11Device *device); + +void MakeValidSize(bool isImage, + DXGI_FORMAT format, + GLsizei *requestWidth, + GLsizei *requestHeight, + int *levelOffset); + +angle::Result GenerateInitialTextureData( + const gl::Context *context, + GLint internalFormat, + const Renderer11DeviceCaps &renderer11DeviceCaps, + GLuint width, + GLuint height, + GLuint depth, + GLuint mipLevels, + gl::TexLevelArray *outSubresourceData); + +UINT GetPrimitiveRestartIndex(); + +struct PositionTexCoordVertex +{ + float x, y; + float u, v; +}; +void SetPositionTexCoordVertex(PositionTexCoordVertex *vertex, float x, float y, float u, float v); + +struct PositionLayerTexCoord3DVertex +{ + float x, y; + unsigned int l; + float u, v, s; +}; +void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex *vertex, + float x, + float y, + unsigned int layer, + float u, + float v, + float s); + +struct PositionVertex +{ + float x, y, z, w; +}; + +struct BlendStateKey final +{ + // This will zero-initialize the struct, including padding. + BlendStateKey(); + BlendStateKey(const BlendStateKey &other); + + gl::BlendStateExt blendStateExt; + + // Use two 16-bit ints to round the struct nicely. + uint16_t rtvMax; + uint16_t sampleAlphaToCoverage; +}; + +bool operator==(const BlendStateKey &a, const BlendStateKey &b); +bool operator!=(const BlendStateKey &a, const BlendStateKey &b); + +struct RasterizerStateKey final +{ + // This will zero-initialize the struct, including padding. + RasterizerStateKey(); + + gl::RasterizerState rasterizerState; + + // Use a 32-bit int to round the struct nicely. + uint32_t scissorEnabled; +}; + +bool operator==(const RasterizerStateKey &a, const RasterizerStateKey &b); +bool operator!=(const RasterizerStateKey &a, const RasterizerStateKey &b); + +template +outType *DynamicCastComObject(IUnknown *object) +{ + outType *outObject = nullptr; + HRESULT result = + object->QueryInterface(__uuidof(outType), reinterpret_cast(&outObject)); + if (SUCCEEDED(result)) + { + return outObject; + } + else + { + SafeRelease(outObject); + return nullptr; + } +} + +template +angle::ComPtr DynamicCastComObjectToComPtr(IUnknown *object) +{ + angle::ComPtr outObject; + const HRESULT hr = object->QueryInterface(IID_PPV_ARGS(&outObject)); + if (SUCCEEDED(hr)) + { + return outObject; + } + else + { + return nullptr; + } +} + +inline bool isDeviceLostError(HRESULT errorCode) +{ + switch (errorCode) + { + case DXGI_ERROR_DEVICE_HUNG: + case DXGI_ERROR_DEVICE_REMOVED: + case DXGI_ERROR_DEVICE_RESET: + case DXGI_ERROR_DRIVER_INTERNAL_ERROR: + case DXGI_ERROR_NOT_CURRENTLY_AVAILABLE: + return true; + default: + return false; + } +} + +template +class LazyResource : angle::NonCopyable +{ + public: + constexpr LazyResource() : mResource() {} + virtual ~LazyResource() {} + + virtual angle::Result resolve(d3d::Context *context, Renderer11 *renderer) = 0; + void reset() { mResource.reset(); } + GetD3D11Type *get() const + { + ASSERT(mResource.valid()); + return mResource.get(); + } + + const Resource11> &getObj() const { return mResource; } + + protected: + LazyResource(LazyResource &&other) : mResource(std::move(other.mResource)) {} + + // Specialized in the cpp file to avoid MSVS/Clang specific code. + angle::Result resolveImpl(d3d::Context *context, + Renderer11 *renderer, + const GetDescType &desc, + GetInitDataType *initData, + const char *name); + + Resource11> mResource; +}; + +template +class LazyShader final : public LazyResource()> +{ + public: + // All parameters must be constexpr. Not supported in VS2013. + constexpr LazyShader(const BYTE *byteCode, size_t byteCodeSize, const char *name) + : mByteCode(byteCode, byteCodeSize), mName(name) + {} + + constexpr LazyShader(LazyShader &&shader) + : LazyResource()>(std::move(shader)), + mByteCode(std::move(shader.mByteCode)), + mName(shader.mName) + {} + + angle::Result resolve(d3d::Context *context, Renderer11 *renderer) override + { + return this->resolveImpl(context, renderer, mByteCode, nullptr, mName); + } + + private: + ShaderData mByteCode; + const char *mName; +}; + +class LazyInputLayout final : public LazyResource +{ + public: + LazyInputLayout(const D3D11_INPUT_ELEMENT_DESC *inputDesc, + size_t inputDescLen, + const BYTE *byteCode, + size_t byteCodeLen, + const char *debugName); + ~LazyInputLayout() override; + + angle::Result resolve(d3d::Context *context, Renderer11 *renderer) override; + + private: + InputElementArray mInputDesc; + ShaderData mByteCode; + const char *mDebugName; +}; + +class LazyBlendState final : public LazyResource +{ + public: + LazyBlendState(const D3D11_BLEND_DESC &desc, const char *debugName); + + angle::Result resolve(d3d::Context *context, Renderer11 *renderer) override; + + private: + D3D11_BLEND_DESC mDesc; + const char *mDebugName; +}; + +// Copy data to small D3D11 buffers, such as for small constant buffers, which use one struct to +// represent an entire buffer. +template +void SetBufferData(ID3D11DeviceContext *context, ID3D11Buffer *constantBuffer, const T &value) +{ + D3D11_MAPPED_SUBRESOURCE mappedResource = {}; + HRESULT result = context->Map(constantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + ASSERT(SUCCEEDED(result)); + if (SUCCEEDED(result)) + { + memcpy(mappedResource.pData, &value, sizeof(T)); + context->Unmap(constantBuffer, 0); + } +} + +void InitializeFeatures(const Renderer11DeviceCaps &deviceCaps, + const DXGI_ADAPTER_DESC &adapterDesc, + angle::FeaturesD3D *features); + +void InitializeFrontendFeatures(const DXGI_ADAPTER_DESC &adapterDesc, + angle::FrontendFeatures *features); + +enum ReservedConstantBufferSlot +{ + RESERVED_CONSTANT_BUFFER_SLOT_DEFAULT_UNIFORM_BLOCK = 0, + RESERVED_CONSTANT_BUFFER_SLOT_DRIVER = 1, + + RESERVED_CONSTANT_BUFFER_SLOT_COUNT = 2 +}; + +void InitConstantBufferDesc(D3D11_BUFFER_DESC *constantBufferDescription, size_t byteWidth); + +// Helper class for RAII patterning. +template +class [[nodiscard]] ScopedUnmapper final : angle::NonCopyable +{ + public: + ScopedUnmapper(T *object) : mObject(object) {} + ~ScopedUnmapper() { mObject->unmap(); } + + private: + T *mObject; +}; +} // namespace d3d11 + +struct GenericData +{ + GenericData() {} + ~GenericData() + { + if (object) + { + // We can have a nullptr factory when holding passed-in resources. + if (manager) + { + manager->onReleaseGeneric(resourceType, object); + manager = nullptr; + } + object->Release(); + object = nullptr; + } + } + + ResourceType resourceType = ResourceType::Last; + ID3D11Resource *object = nullptr; + ResourceManager11 *manager = nullptr; +}; + +// A helper class which wraps a 2D or 3D texture. +class TextureHelper11 : public Resource11Base +{ + public: + TextureHelper11(); + TextureHelper11(TextureHelper11 &&other); + TextureHelper11(const TextureHelper11 &other); + ~TextureHelper11() override; + TextureHelper11 &operator=(TextureHelper11 &&other); + TextureHelper11 &operator=(const TextureHelper11 &other); + + bool isBuffer() const { return mData->resourceType == ResourceType::Buffer; } + bool is2D() const { return mData->resourceType == ResourceType::Texture2D; } + bool is3D() const { return mData->resourceType == ResourceType::Texture3D; } + ResourceType getTextureType() const { return mData->resourceType; } + gl::Extents getExtents() const { return mExtents; } + DXGI_FORMAT getFormat() const { return mFormatSet->texFormat; } + const d3d11::Format &getFormatSet() const { return *mFormatSet; } + int getSampleCount() const { return mSampleCount; } + + template + void init(Resource11 &&texture, const DescT &desc, const d3d11::Format &format) + { + std::swap(mData->manager, texture.mData->manager); + + // Can't use std::swap because texture is typed, and here we use ID3D11Resource. + ID3D11Resource *temp = mData->object; + mData->object = texture.mData->object; + texture.mData->object = static_cast(temp); + + mFormatSet = &format; + initDesc(desc); + } + + template + void set(ResourceT *object, const d3d11::Format &format) + { + ASSERT(!valid()); + + mFormatSet = &format; + mData->object = object; + mData->manager = nullptr; + + GetDescFromD3D11 desc; + getDesc(&desc); + initDesc(desc); + } + + bool operator==(const TextureHelper11 &other) const; + bool operator!=(const TextureHelper11 &other) const; + + void getDesc(D3D11_TEXTURE2D_DESC *desc) const; + void getDesc(D3D11_TEXTURE3D_DESC *desc) const; + void getDesc(D3D11_BUFFER_DESC *desc) const; + + private: + void initDesc(const D3D11_TEXTURE2D_DESC &desc2D); + void initDesc(const D3D11_TEXTURE3D_DESC &desc3D); + void initDesc(const D3D11_BUFFER_DESC &descBuffer); + + const d3d11::Format *mFormatSet; + gl::Extents mExtents; + int mSampleCount; +}; + +enum class StagingAccess +{ + READ, + READ_WRITE, +}; + +bool UsePresentPathFast(const Renderer11 *renderer, const gl::FramebufferAttachment *colorbuffer); +bool UsePrimitiveRestartWorkaround(bool primitiveRestartFixedIndexEnabled, + gl::DrawElementsType type); + +enum class IndexStorageType +{ + // Dynamic indexes are re-streamed every frame. They come from a client data pointer or + // from buffers that are updated frequently. + Dynamic, + + // Static indexes are translated from the original storage once, and re-used multiple times. + Static, + + // Direct indexes are never transated and are used directly from the source buffer. They are + // the fastest available path. + Direct, + + // Not a real storage type. + Invalid, +}; + +IndexStorageType ClassifyIndexStorage(const gl::State &glState, + const gl::Buffer *elementArrayBuffer, + gl::DrawElementsType elementType, + gl::DrawElementsType destElementType, + unsigned int offset); + +bool SwizzleRequired(const gl::TextureState &textureState); +gl::SwizzleState GetEffectiveSwizzle(const gl::TextureState &textureState); + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_UTILS_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_gs.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_gs.h new file mode 100644 index 0000000000..9bfc750765 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_gs.h @@ -0,0 +1,80 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float xyzw +// TEXCOORD 0 x 1 NONE uint x +// LAYER 0 y 1 NONE uint y +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float xyzw +// TEXCOORD 0 x 1 NONE uint x +// SV_RenderTargetArrayIndex 0 y 1 RTINDEX uint y +// +gs_4_0 +dcl_input_siv v[1][0].xyzw, position +dcl_input v[1][1].x +dcl_input v[1][1].y +dcl_inputprimitive point +dcl_outputtopology pointlist +dcl_output_siv o0.xyzw, position +dcl_output o1.x +dcl_output_siv o1.y, rendertarget_array_index +dcl_maxout 1 +mov o0.xyzw, v[0][0].xyzw +mov o1.x, v[0][1].x +mov o1.y, v[0][1].y +emit +ret +// Approximately 5 instruction slots used +#endif + +const BYTE g_GS_BufferToTexture[] = { + 68, 88, 66, 67, 181, 104, 45, 14, 26, 142, 216, 235, 63, 167, 110, 6, 1, 170, 134, + 100, 1, 0, 0, 0, 200, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 128, 0, + 0, 0, 244, 0, 0, 0, 124, 1, 0, 0, 76, 2, 0, 0, 82, 68, 69, 70, 68, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 83, 71, 0, 1, 0, 0, 28, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 108, + 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, 15, 0, 0, 92, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, + 0, 0, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 2, 2, 0, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, + 84, 69, 88, 67, 79, 79, 82, 68, 0, 76, 65, 89, 69, 82, 0, 171, 79, 83, 71, + 78, 128, 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, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 14, 0, 0, 101, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 2, 13, 0, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, + 110, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 82, 101, 110, 100, 101, + 114, 84, 97, 114, 103, 101, 116, 65, 114, 114, 97, 121, 73, 110, 100, 101, 120, 0, 171, + 83, 72, 68, 82, 200, 0, 0, 0, 64, 0, 2, 0, 50, 0, 0, 0, 97, 0, 0, + 5, 242, 16, 32, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 95, 0, + 0, 4, 18, 16, 32, 0, 1, 0, 0, 0, 1, 0, 0, 0, 95, 0, 0, 4, 34, + 16, 32, 0, 1, 0, 0, 0, 1, 0, 0, 0, 93, 8, 0, 1, 92, 8, 0, 1, + 103, 0, 0, 4, 242, 32, 16, 0, 0, 0, 0, 0, 1, 0, 0, 0, 101, 0, 0, + 3, 18, 32, 16, 0, 1, 0, 0, 0, 103, 0, 0, 4, 34, 32, 16, 0, 1, 0, + 0, 0, 4, 0, 0, 0, 94, 0, 0, 2, 1, 0, 0, 0, 54, 0, 0, 6, 242, + 32, 16, 0, 0, 0, 0, 0, 70, 30, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 32, 16, 0, 1, 0, 0, 0, 10, 16, 32, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 54, 0, 0, 6, 34, 32, 16, 0, 1, 0, 0, 0, 26, 16, + 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 19, 0, 0, 1, 62, 0, 0, 1, 83, + 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 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, 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, 0, 0, 0, 0, + 0, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4f.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4f.h new file mode 100644 index 0000000000..87730ffe5c --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4f.h @@ -0,0 +1,65 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Buffer4F texture float4 buf t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float +// TEXCOORD 0 x 1 NONE uint x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_resource_buffer (float,float,float,float) t0 +dcl_input_ps constant v1.x +dcl_output o0.xyzw +ld o0.xyzw, v1.xxxx, t0.xyzw +ret +// Approximately 2 instruction slots used +#endif + +const BYTE g_PS_BufferToTexture_4F[] = { + 68, 88, 66, 67, 156, 38, 137, 246, 11, 113, 21, 186, 20, 101, 47, 15, 216, 211, 176, + 224, 1, 0, 0, 0, 12, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0, + 0, 0, 4, 1, 0, 0, 56, 1, 0, 0, 144, 1, 0, 0, 82, 68, 69, 70, 112, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 69, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0, + 0, 5, 0, 0, 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 66, 117, 102, 102, 101, 114, 52, 70, 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, 49, 48, 46, 49, 0, 171, 171, + 171, 73, 83, 71, 78, 80, 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, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 1, 0, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, + 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 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, + 97, 114, 103, 101, 116, 0, 171, 171, 83, 72, 68, 82, 80, 0, 0, 0, 64, 0, 0, + 0, 20, 0, 0, 0, 88, 8, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, + 0, 0, 98, 8, 0, 3, 18, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, + 32, 16, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, + 6, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 62, 0, 0, + 1, 83, 84, 65, 84, 116, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4i.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4i.h new file mode 100644 index 0000000000..64304f956d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4i.h @@ -0,0 +1,65 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Buffer4I texture sint4 buf t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float +// TEXCOORD 0 x 1 NONE uint x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_resource_buffer (sint,sint,sint,sint) t0 +dcl_input_ps constant v1.x +dcl_output o0.xyzw +ld o0.xyzw, v1.xxxx, t0.xyzw +ret +// Approximately 2 instruction slots used +#endif + +const BYTE g_PS_BufferToTexture_4I[] = { + 68, 88, 66, 67, 162, 203, 46, 4, 155, 72, 142, 126, 228, 80, 83, 117, 139, 11, 48, + 250, 1, 0, 0, 0, 12, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0, + 0, 0, 4, 1, 0, 0, 56, 1, 0, 0, 144, 1, 0, 0, 82, 68, 69, 70, 112, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 69, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0, + 0, 3, 0, 0, 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 66, 117, 102, 102, 101, 114, 52, 73, 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, 49, 48, 46, 49, 0, 171, 171, + 171, 73, 83, 71, 78, 80, 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, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 1, 0, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, + 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 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, 2, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, + 97, 114, 103, 101, 116, 0, 171, 171, 83, 72, 68, 82, 80, 0, 0, 0, 64, 0, 0, + 0, 20, 0, 0, 0, 88, 8, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 51, 51, + 0, 0, 98, 8, 0, 3, 18, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, + 32, 16, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, + 6, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 62, 0, 0, + 1, 83, 84, 65, 84, 116, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h new file mode 100644 index 0000000000..9504753bde --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h @@ -0,0 +1,65 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Buffer4UI texture uint4 buf t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float +// TEXCOORD 0 x 1 NONE uint x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_resource_buffer (uint,uint,uint,uint) t0 +dcl_input_ps constant v1.x +dcl_output o0.xyzw +ld o0.xyzw, v1.xxxx, t0.xyzw +ret +// Approximately 2 instruction slots used +#endif + +const BYTE g_PS_BufferToTexture_4UI[] = { + 68, 88, 66, 67, 168, 39, 110, 5, 143, 0, 75, 136, 251, 25, 27, 24, 35, 191, 3, + 64, 1, 0, 0, 0, 12, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0, + 0, 0, 4, 1, 0, 0, 56, 1, 0, 0, 144, 1, 0, 0, 82, 68, 69, 70, 112, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 70, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0, + 0, 4, 0, 0, 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 66, 117, 102, 102, 101, 114, 52, 85, 73, 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, 49, 48, 46, 49, 0, 171, + 171, 73, 83, 71, 78, 80, 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, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 1, 0, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, + 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 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, 1, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, + 97, 114, 103, 101, 116, 0, 171, 171, 83, 72, 68, 82, 80, 0, 0, 0, 64, 0, 0, + 0, 20, 0, 0, 0, 88, 8, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 68, 68, + 0, 0, 98, 8, 0, 3, 18, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, + 32, 16, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, + 6, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 62, 0, 0, + 1, 83, 84, 65, 84, 116, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_vs.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_vs.h new file mode 100644 index 0000000000..b9ce502123 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_vs.h @@ -0,0 +1,145 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer BufferCopyParams +// { +// +// uint FirstPixelOffset; // Offset: 0 Size: 4 +// uint PixelsPerRow; // Offset: 4 Size: 4 +// uint RowStride; // Offset: 8 Size: 4 +// uint RowsPerSlice; // Offset: 12 Size: 4 +// float2 PositionOffset; // Offset: 16 Size: 8 +// float2 PositionScale; // Offset: 24 Size: 8 +// int2 TexLocationOffset; // Offset: 32 Size: 8 [unused] +// int2 TexLocationScale; // Offset: 40 Size: 8 [unused] +// uint FirstSlice; // Offset: 48 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// BufferCopyParams cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_VertexID 0 x 0 VERTID uint x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float xyzw +// TEXCOORD 0 x 1 NONE uint x +// LAYER 0 y 1 NONE uint y +// +vs_4_0 +dcl_constantbuffer CB0[4], immediateIndexed +dcl_input_sgv v0.x, vertex_id +dcl_output_siv o0.xyzw, position +dcl_output o1.x +dcl_output o1.y +dcl_temps 2 +mov o0.zw, l(0,0,0,1.000000) +imul null, r0.xy, cb0[0].wwww, cb0[0].yzyy +udiv r0.z, null, v0.x, r0.x +imad r0.x, -r0.z, r0.x, v0.x +imad r0.y, r0.z, r0.y, cb0[0].x +iadd o1.y, r0.z, cb0[3].x +udiv r0.z, null, r0.x, cb0[0].y +imad r0.x, -r0.z, cb0[0].y, r0.x +utof r1.xy, r0.xzxx +imad r0.y, r0.z, cb0[0].z, r0.y +iadd o1.x, r0.x, r0.y +mad o0.xy, cb0[1].zwzz, r1.xyxx, cb0[1].xyxx +ret +// Approximately 13 instruction slots used +#endif + +const BYTE g_VS_BufferToTexture[] = { + 68, 88, 66, 67, 153, 33, 196, 57, 209, 115, 237, 17, 59, 231, 206, 105, 1, 81, 121, + 39, 1, 0, 0, 0, 140, 5, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 88, 2, + 0, 0, 140, 2, 0, 0, 0, 3, 0, 0, 16, 5, 0, 0, 82, 68, 69, 70, 28, + 2, 0, 0, 1, 0, 0, 0, 80, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 254, 255, 0, 1, 0, 0, 244, 1, 0, 0, 60, 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, 1, 0, 0, 0, 66, 117, 102, 102, 101, 114, 67, 111, 112, 121, 80, 97, 114, + 97, 109, 115, 0, 171, 171, 171, 60, 0, 0, 0, 9, 0, 0, 0, 104, 0, 0, 0, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 1, 0, 0, 0, 0, 0, + 0, 4, 0, 0, 0, 2, 0, 0, 0, 84, 1, 0, 0, 0, 0, 0, 0, 100, 1, + 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 84, 1, 0, 0, 0, + 0, 0, 0, 113, 1, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 84, 1, 0, 0, 0, 0, 0, 0, 123, 1, 0, 0, 12, 0, 0, 0, 4, 0, 0, + 0, 2, 0, 0, 0, 84, 1, 0, 0, 0, 0, 0, 0, 136, 1, 0, 0, 16, 0, + 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 152, 1, 0, 0, 0, 0, 0, 0, 168, + 1, 0, 0, 24, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 152, 1, 0, 0, + 0, 0, 0, 0, 182, 1, 0, 0, 32, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 200, 1, 0, 0, 0, 0, 0, 0, 216, 1, 0, 0, 40, 0, 0, 0, 8, 0, + 0, 0, 0, 0, 0, 0, 200, 1, 0, 0, 0, 0, 0, 0, 233, 1, 0, 0, 48, + 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 84, 1, 0, 0, 0, 0, 0, 0, + 70, 105, 114, 115, 116, 80, 105, 120, 101, 108, 79, 102, 102, 115, 101, 116, 0, 171, 171, + 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 105, + 120, 101, 108, 115, 80, 101, 114, 82, 111, 119, 0, 82, 111, 119, 83, 116, 114, 105, 100, + 101, 0, 82, 111, 119, 115, 80, 101, 114, 83, 108, 105, 99, 101, 0, 80, 111, 115, 105, + 116, 105, 111, 110, 79, 102, 102, 115, 101, 116, 0, 171, 1, 0, 3, 0, 1, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 83, 99, + 97, 108, 101, 0, 84, 101, 120, 76, 111, 99, 97, 116, 105, 111, 110, 79, 102, 102, 115, + 101, 116, 0, 1, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 84, 101, 120, 76, 111, 99, 97, 116, 105, 111, 110, 83, 99, 97, 108, 101, 0, 70, 105, + 114, 115, 116, 83, 108, 105, 99, 101, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, 0, + 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 83, 86, 95, 86, 101, 114, + 116, 101, 120, 73, 68, 0, 79, 83, 71, 78, 108, 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, 1, 0, 0, 0, 1, 0, 0, 0, 1, 14, 0, 0, 101, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 13, 0, 0, 83, + 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 84, 69, 88, 67, 79, 79, 82, 68, + 0, 76, 65, 89, 69, 82, 0, 171, 83, 72, 68, 82, 8, 2, 0, 0, 64, 0, 1, + 0, 130, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 4, 0, + 0, 0, 96, 0, 0, 4, 18, 16, 16, 0, 0, 0, 0, 0, 6, 0, 0, 0, 103, + 0, 0, 4, 242, 32, 16, 0, 0, 0, 0, 0, 1, 0, 0, 0, 101, 0, 0, 3, + 18, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 34, 32, 16, 0, 1, 0, 0, + 0, 104, 0, 0, 2, 2, 0, 0, 0, 54, 0, 0, 8, 194, 32, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 128, 63, 38, 0, 0, 10, 0, 208, 0, 0, 50, 0, 16, 0, 0, 0, 0, 0, + 246, 143, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 133, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 78, 0, 0, 8, 66, 0, 16, 0, 0, 0, 0, 0, 0, 208, + 0, 0, 10, 16, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 35, + 0, 0, 10, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 128, 65, 0, 0, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 0, 0, 0, + 0, 35, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 8, 34, 32, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 78, 0, 0, + 9, 66, 0, 16, 0, 0, 0, 0, 0, 0, 208, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 26, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 11, 18, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, + 26, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 86, 0, 0, 5, 50, 0, 16, 0, 1, 0, 0, 0, 134, 0, 16, 0, 0, 0, + 0, 0, 35, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, + 0, 0, 0, 42, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 18, 32, 16, 0, 1, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 50, 0, 0, 11, 50, 32, + 16, 0, 0, 0, 0, 0, 230, 138, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 70, + 0, 16, 0, 1, 0, 0, 0, 70, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 13, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 2, 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, 0, 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, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11_fl9vs.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11_fl9vs.h new file mode 100644 index 0000000000..9b4ccfb902 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11_fl9vs.h @@ -0,0 +1,71 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// POSITION 0 xyzw 0 NONE float xyzw +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float xyzw +// +// +// Runtime generated constant mappings: +// +// Target Reg Constant Description +// ---------- -------------------------------------------------- +// c0 Vertex Shader position offset +// +// +// Level9 shader bytecode: +// + vs_2_x + dcl_texcoord v0 + mad oPos.xy, v0.w, c0, v0 + mov oPos.zw, v0 + +// approximately 2 instruction slots used +vs_4_0 +dcl_input v0.xyzw +dcl_output_siv o0.xyzw, position +mov o0.xyzw, v0.xyzw +ret +// Approximately 2 instruction slots used +#endif + +const BYTE g_VS_Clear_FL9[] = { + 68, 88, 66, 67, 166, 109, 78, 113, 107, 98, 65, 70, 91, 88, 250, 161, 103, 22, 241, 76, + 1, 0, 0, 0, 16, 2, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 156, 0, 0, 0, + 224, 0, 0, 0, 92, 1, 0, 0, 168, 1, 0, 0, 220, 1, 0, 0, 65, 111, 110, 57, + 92, 0, 0, 0, 92, 0, 0, 0, 0, 2, 254, 255, 52, 0, 0, 0, 40, 0, 0, 0, + 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 1, 0, 36, 0, + 0, 0, 0, 0, 1, 2, 254, 255, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, + 4, 0, 0, 4, 0, 0, 3, 192, 0, 0, 255, 144, 0, 0, 228, 160, 0, 0, 228, 144, + 1, 0, 0, 2, 0, 0, 12, 192, 0, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, + 60, 0, 0, 0, 64, 0, 1, 0, 15, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, + 0, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 54, 0, 0, 5, 242, 32, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 0, 0, 0, 0, + 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 68, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 0, 1, 0, 0, + 28, 0, 0, 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, 49, + 48, 46, 49, 0, 73, 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, 15, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 171, 171, 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, + 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11multiviewgs.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11multiviewgs.h new file mode 100644 index 0000000000..92b192107b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11multiviewgs.h @@ -0,0 +1,83 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float xyzw +// TEXCOORD 0 x 1 NONE uint x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float xyzw +// SV_RenderTargetArrayIndex 0 x 1 RTINDEX uint x +// +gs_4_0 +dcl_input_siv v[3][0].xyzw, position +dcl_input v[3][1].x +dcl_temps 1 +dcl_inputprimitive triangle +dcl_outputtopology trianglestrip +dcl_output_siv o0.xyzw, position +dcl_output_siv o1.x, rendertarget_array_index +dcl_maxout 3 +mov r0.x, l(0) +loop + ige r0.y, r0.x, l(3) + breakc_nz r0.y + mov o0.xyzw, v[r0.x + 0][0].xyzw + mov o1.x, v[r0.x + 0][1].x + emit + iadd r0.x, r0.x, l(1) +endloop +cut +ret +// Approximately 11 instruction slots used +#endif + +const BYTE g_GS_Multiview_Clear[] = { + 68, 88, 66, 67, 110, 37, 141, 207, 15, 59, 27, 66, 207, 215, 205, 198, 147, 31, 42, + 22, 1, 0, 0, 0, 204, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 128, 0, + 0, 0, 216, 0, 0, 0, 64, 1, 0, 0, 80, 2, 0, 0, 82, 68, 69, 70, 68, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 83, 71, 0, 1, 0, 0, 28, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 80, + 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, 15, 0, 0, 68, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, + 0, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 84, 69, 88, 67, 79, + 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 96, 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, 4, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 14, 0, 0, 83, 86, 95, 80, 111, + 115, 105, 116, 105, 111, 110, 0, 83, 86, 95, 82, 101, 110, 100, 101, 114, 84, 97, 114, + 103, 101, 116, 65, 114, 114, 97, 121, 73, 110, 100, 101, 120, 0, 171, 171, 83, 72, 68, + 82, 8, 1, 0, 0, 64, 0, 2, 0, 66, 0, 0, 0, 97, 0, 0, 5, 242, 16, + 32, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 95, 0, 0, 4, 18, + 16, 32, 0, 3, 0, 0, 0, 1, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, + 93, 24, 0, 1, 92, 40, 0, 1, 103, 0, 0, 4, 242, 32, 16, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 103, 0, 0, 4, 18, 32, 16, 0, 1, 0, 0, 0, 4, 0, + 0, 0, 94, 0, 0, 2, 3, 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, 33, 0, 0, 7, + 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 54, 0, + 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, 70, 30, 160, 0, 10, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 18, 32, 16, 0, 1, 0, 0, 0, + 10, 16, 160, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 0, 19, 0, 0, + 1, 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, 9, 0, 0, 1, 62, + 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11multiviewvs.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11multiviewvs.h new file mode 100644 index 0000000000..ba1c5425e2 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11multiviewvs.h @@ -0,0 +1,80 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_VertexID 0 x 0 VERTID uint x +// SV_InstanceID 0 x 1 INSTID uint x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float xyzw +// TEXCOORD 0 x 1 NONE uint x +// +vs_4_0 +dcl_immediateConstantBuffer { { -1.000000, 1.000000, 0, 0}, + { 1.000000, -1.000000, 0, 0}, + { -1.000000, -1.000000, 0, 0}, + { -1.000000, 1.000000, 0, 0}, + { 1.000000, 1.000000, 0, 0}, + { 1.000000, -1.000000, 0, 0} } +dcl_input_sgv v0.x, vertex_id +dcl_input_sgv v1.x, instance_id +dcl_output_siv o0.xyzw, position +dcl_output o1.x +dcl_temps 1 +mov r0.x, v0.x +mov o0.xy, icb[r0.x + 0].xyxx +mov o0.zw, l(0,0,0,1.000000) +mov o1.x, v1.x +ret +// Approximately 5 instruction slots used +#endif + +const BYTE g_VS_Multiview_Clear[] = { + 68, 88, 66, 67, 29, 63, 249, 196, 208, 130, 142, 190, 155, 101, 165, 213, 91, 14, 122, + 2, 1, 0, 0, 0, 208, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 128, 0, + 0, 0, 220, 0, 0, 0, 52, 1, 0, 0, 84, 2, 0, 0, 82, 68, 69, 70, 68, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 254, 255, 0, 1, 0, 0, 28, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 84, + 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 68, 0, 0, + 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, + 0, 0, 83, 86, 95, 86, 101, 114, 116, 101, 120, 73, 68, 0, 83, 86, 95, 73, 110, + 115, 116, 97, 110, 99, 101, 73, 68, 0, 171, 171, 79, 83, 71, 78, 80, 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, 1, 0, 0, 0, 1, 0, 0, 0, 1, 14, 0, 0, 83, + 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 84, 69, 88, 67, 79, 79, 82, 68, + 0, 171, 171, 171, 83, 72, 68, 82, 24, 1, 0, 0, 64, 0, 1, 0, 70, 0, 0, + 0, 53, 24, 0, 0, 26, 0, 0, 0, 0, 0, 128, 191, 0, 0, 128, 63, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, 0, 0, 128, 191, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 128, 191, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, + 63, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, 0, 0, + 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 4, 18, 16, 16, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 96, 0, 0, 4, 18, 16, 16, 0, 1, 0, 0, 0, + 8, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 101, 0, 0, 3, 18, 32, 16, 0, 1, 0, 0, 0, 104, 0, 0, 2, 1, 0, + 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 0, + 0, 0, 0, 54, 0, 0, 6, 50, 32, 16, 0, 0, 0, 0, 0, 70, 144, 144, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 32, 16, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 128, 63, 54, 0, 0, 5, 18, 32, 16, 0, 1, 0, 0, 0, 10, 16, 16, 0, 1, + 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0, + 1, 0, 0, 0, 6, 0, 0, 0, 4, 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 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, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11vs.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11vs.h new file mode 100644 index 0000000000..035a1fdca0 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11vs.h @@ -0,0 +1,69 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_VertexID 0 x 0 VERTID uint x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float xyzw +// +vs_4_0 +dcl_immediateConstantBuffer { { -1.000000, 1.000000, 0, 0}, + { 1.000000, -1.000000, 0, 0}, + { -1.000000, -1.000000, 0, 0}, + { -1.000000, 1.000000, 0, 0}, + { 1.000000, 1.000000, 0, 0}, + { 1.000000, -1.000000, 0, 0} } +dcl_input_sgv v0.x, vertex_id +dcl_output_siv o0.xyzw, position +dcl_temps 1 +mov r0.x, v0.x +mov o0.xy, icb[r0.x + 0].xyxx +mov o0.zw, l(0,0,0,1.000000) +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_VS_Clear[] = { + 68, 88, 66, 67, 142, 0, 156, 121, 128, 35, 189, 41, 14, 141, 59, 193, 158, 19, 28, + 184, 1, 0, 0, 0, 84, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 128, 0, + 0, 0, 180, 0, 0, 0, 232, 0, 0, 0, 216, 1, 0, 0, 82, 68, 69, 70, 68, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 254, 255, 0, 1, 0, 0, 28, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, + 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 83, 86, 95, + 86, 101, 114, 116, 101, 120, 73, 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, 1, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, + 73, 79, 78, 0, 83, 72, 68, 82, 232, 0, 0, 0, 64, 0, 1, 0, 58, 0, 0, + 0, 53, 24, 0, 0, 26, 0, 0, 0, 0, 0, 128, 191, 0, 0, 128, 63, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, 0, 0, 128, 191, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 128, 191, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, + 63, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, 0, 0, + 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 4, 18, 16, 16, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, + 0, 0, 0, 0, 0, 10, 16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 50, 32, + 16, 0, 0, 0, 0, 0, 70, 144, 144, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, + 0, 0, 8, 194, 32, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, + 84, 116, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 2, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, 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, 0, + 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/cleardepth11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/cleardepth11ps.h new file mode 100644 index 0000000000..41a39aead9 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/cleardepth11ps.h @@ -0,0 +1,74 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer DepthOnlyData +// { +// +// float zValue_Depth; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// DepthOnlyData cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_DEPTH 0 N/A oDepth DEPTH float YES +// +ps_4_0 +dcl_constantbuffer CB0[2], immediateIndexed +dcl_output oDepth +mov oDepth, cb0[1].x +ret +// Approximately 2 instruction slots used +#endif + +const BYTE g_PS_ClearDepth[] = { + 68, 88, 66, 67, 27, 164, 102, 59, 78, 154, 233, 127, 65, 17, 101, 9, 4, 119, 201, + 97, 1, 0, 0, 0, 36, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 0, 1, + 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 168, 1, 0, 0, 82, 68, 69, 70, 196, + 0, 0, 0, 1, 0, 0, 0, 76, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 156, 0, 0, 0, 60, 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, 1, 0, 0, 0, 68, 101, 112, 116, 104, 79, 110, 108, 121, 68, 97, 116, 97, + 0, 171, 171, 60, 0, 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, + 0, 2, 0, 0, 0, 140, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97, 108, 117, 101, + 95, 68, 101, 112, 116, 104, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, + 73, 79, 78, 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, 255, 255, + 255, 255, 1, 14, 0, 0, 83, 86, 95, 68, 69, 80, 84, 72, 0, 171, 171, 171, 83, + 72, 68, 82, 56, 0, 0, 0, 64, 0, 0, 0, 14, 0, 0, 0, 89, 0, 0, 4, + 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 101, 0, 0, 2, 1, 192, 0, + 0, 54, 0, 0, 5, 1, 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 2, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11_fl9ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11_fl9ps.h new file mode 100644 index 0000000000..cebc263110 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11_fl9ps.h @@ -0,0 +1,128 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer ColorAndDepthDataFloat +// { +// +// float4 color_Float; // Offset: 0 Size: 16 +// float zValueF_Float; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// ColorAndDepthDataFloat cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// SV_TARGET 1 xyzw 1 TARGET float xyzw +// SV_TARGET 2 xyzw 2 TARGET float xyzw +// SV_TARGET 3 xyzw 3 TARGET float xyzw +// SV_DEPTH 0 N/A oDepth DEPTH float YES +// +// +// Constant buffer to DX9 shader constant mappings: +// +// Target Reg Buffer Start Reg # of Regs Data Conversion +// ---------- ------- --------- --------- ---------------------- +// c0 cb0 0 2 ( FLT, FLT, FLT, FLT) +// +// +// Level9 shader bytecode: +// + ps_2_x + mov oC0, c0 + mov oC1, c0 + mov oC2, c0 + mov oC3, c0 + mov oDepth, c1.x + +// approximately 5 instruction slots used +ps_4_0 +dcl_constantbuffer CB0[2], immediateIndexed +dcl_output o0.xyzw +dcl_output o1.xyzw +dcl_output o2.xyzw +dcl_output o3.xyzw +dcl_output oDepth +mov o0.xyzw, cb0[0].xyzw +mov o1.xyzw, cb0[0].xyzw +mov o2.xyzw, cb0[0].xyzw +mov o3.xyzw, cb0[0].xyzw +mov oDepth, cb0[1].x +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_ClearFloat_FL9[] = { + 68, 88, 66, 67, 85, 216, 43, 21, 188, 93, 222, 90, 179, 114, 11, 205, 194, 17, 203, + 168, 1, 0, 0, 0, 216, 3, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 180, 0, + 0, 0, 132, 1, 0, 0, 0, 2, 0, 0, 8, 3, 0, 0, 60, 3, 0, 0, 65, + 111, 110, 57, 116, 0, 0, 0, 116, 0, 0, 0, 0, 2, 255, 255, 68, 0, 0, 0, + 48, 0, 0, 0, 1, 0, 36, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 36, + 0, 0, 0, 48, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 2, + 255, 255, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 160, 1, 0, 0, 2, 1, + 8, 15, 128, 0, 0, 228, 160, 1, 0, 0, 2, 2, 8, 15, 128, 0, 0, 228, 160, + 1, 0, 0, 2, 3, 8, 15, 128, 0, 0, 228, 160, 1, 0, 0, 2, 0, 8, 15, + 144, 1, 0, 0, 160, 255, 255, 0, 0, 83, 72, 68, 82, 200, 0, 0, 0, 64, 0, + 0, 0, 50, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0, + 0, 101, 0, 0, 3, 242, 32, 16, 0, 3, 0, 0, 0, 101, 0, 0, 2, 1, 192, + 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0, 0, 0, + 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, + 0, 2, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 6, 242, 32, 16, 0, 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 5, 1, 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 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, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 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, 0, 0, 0, 0, 0, 0, 0, 0, 82, + 68, 69, 70, 0, 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, + 101, 112, 116, 104, 68, 97, 116, 97, 70, 108, 111, 97, 116, 0, 171, 60, 0, 0, 0, + 2, 0, 0, 0, 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 156, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, + 0, 0, 0, 0, 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, + 0, 0, 0, 200, 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 70, 108, + 111, 97, 116, 0, 1, 0, 3, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 122, 86, 97, 108, 117, 101, 70, 95, 70, 108, 111, 97, 116, 0, 171, 171, 0, 0, + 3, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, + 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, + 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 148, 0, 0, 0, + 5, 0, 0, 0, 8, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 128, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 128, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, + 15, 0, 0, 0, 128, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 15, 0, 0, 0, 138, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 1, 14, 0, 0, 83, 86, 95, 84, 65, + 82, 71, 69, 84, 0, 83, 86, 95, 68, 69, 80, 84, 72, 0, 171}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps1.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps1.h new file mode 100644 index 0000000000..d2845b994b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps1.h @@ -0,0 +1,85 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer ColorAndDepthDataFloat +// { +// +// float4 color_Float; // Offset: 0 Size: 16 +// float zValueF_Float; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// ColorAndDepthDataFloat cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// SV_DEPTH 0 N/A oDepth DEPTH float YES +// +ps_4_0 +dcl_constantbuffer CB0[2], immediateIndexed +dcl_output o0.xyzw +dcl_output oDepth +mov o0.xyzw, cb0[0].xyzw +mov oDepth, cb0[1].x +ret +// Approximately 3 instruction slots used +#endif + +const BYTE g_PS_ClearFloat1[] = { + 68, 88, 66, 67, 249, 37, 129, 249, 125, 252, 189, 145, 109, 207, 171, 136, 14, 159, 102, + 81, 1, 0, 0, 0, 164, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, 196, 1, 0, 0, 40, 2, 0, 0, 82, 68, 69, 70, 0, + 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104, + 68, 97, 116, 97, 70, 108, 111, 97, 116, 0, 171, 60, 0, 0, 0, 2, 0, 0, 0, + 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0, + 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200, + 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 70, 108, 111, 97, 116, 0, + 1, 0, 3, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97, + 108, 117, 101, 70, 95, 70, 108, 111, 97, 116, 0, 171, 171, 0, 0, 3, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, + 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79, + 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 76, 0, 0, 0, 2, 0, 0, 0, + 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 15, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 1, 14, 0, 0, 83, 86, 95, 84, 65, + 82, 71, 69, 84, 0, 83, 86, 95, 68, 69, 80, 84, 72, 0, 171, 83, 72, 68, 82, + 92, 0, 0, 0, 64, 0, 0, 0, 23, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, + 0, 0, 101, 0, 0, 2, 1, 192, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0, + 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 1, 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 62, 0, 0, + 1, 83, 84, 65, 84, 116, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 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, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps2.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps2.h new file mode 100644 index 0000000000..b1b3a4e441 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps2.h @@ -0,0 +1,91 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer ColorAndDepthDataFloat +// { +// +// float4 color_Float; // Offset: 0 Size: 16 +// float zValueF_Float; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// ColorAndDepthDataFloat cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// SV_TARGET 1 xyzw 1 TARGET float xyzw +// SV_DEPTH 0 N/A oDepth DEPTH float YES +// +ps_4_0 +dcl_constantbuffer CB0[2], immediateIndexed +dcl_output o0.xyzw +dcl_output o1.xyzw +dcl_output oDepth +mov o0.xyzw, cb0[0].xyzw +mov o1.xyzw, cb0[0].xyzw +mov oDepth, cb0[1].x +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_ClearFloat2[] = { + 68, 88, 66, 67, 47, 142, 59, 204, 239, 80, 8, 161, 169, 171, 199, 199, 129, 33, 42, + 115, 1, 0, 0, 0, 224, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, 220, 1, 0, 0, 100, 2, 0, 0, 82, 68, 69, 70, 0, + 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104, + 68, 97, 116, 97, 70, 108, 111, 97, 116, 0, 171, 60, 0, 0, 0, 2, 0, 0, 0, + 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0, + 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200, + 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 70, 108, 111, 97, 116, 0, + 1, 0, 3, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97, + 108, 117, 101, 70, 95, 70, 108, 111, 97, 116, 0, 171, 171, 0, 0, 3, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, + 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79, + 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 100, 0, 0, 0, 3, 0, 0, 0, + 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 15, 0, 0, 0, 80, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 90, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 1, 14, 0, 0, + 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 83, 86, 95, 68, 69, 80, 84, 72, 0, + 171, 83, 72, 68, 82, 128, 0, 0, 0, 64, 0, 0, 0, 32, 0, 0, 0, 89, 0, + 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, + 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, + 101, 0, 0, 2, 1, 192, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0, + 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, + 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 5, 1, 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 4, 0, 0, 0, 0, 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, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps3.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps3.h new file mode 100644 index 0000000000..e84854ff68 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps3.h @@ -0,0 +1,97 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer ColorAndDepthDataFloat +// { +// +// float4 color_Float; // Offset: 0 Size: 16 +// float zValueF_Float; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// ColorAndDepthDataFloat cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// SV_TARGET 1 xyzw 1 TARGET float xyzw +// SV_TARGET 2 xyzw 2 TARGET float xyzw +// SV_DEPTH 0 N/A oDepth DEPTH float YES +// +ps_4_0 +dcl_constantbuffer CB0[2], immediateIndexed +dcl_output o0.xyzw +dcl_output o1.xyzw +dcl_output o2.xyzw +dcl_output oDepth +mov o0.xyzw, cb0[0].xyzw +mov o1.xyzw, cb0[0].xyzw +mov o2.xyzw, cb0[0].xyzw +mov oDepth, cb0[1].x +ret +// Approximately 5 instruction slots used +#endif + +const BYTE g_PS_ClearFloat3[] = { + 68, 88, 66, 67, 98, 17, 13, 150, 202, 50, 172, 72, 101, 93, 116, 134, 154, 66, 233, + 63, 1, 0, 0, 0, 28, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, 244, 1, 0, 0, 160, 2, 0, 0, 82, 68, 69, 70, 0, + 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104, + 68, 97, 116, 97, 70, 108, 111, 97, 116, 0, 171, 60, 0, 0, 0, 2, 0, 0, 0, + 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0, + 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200, + 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 70, 108, 111, 97, 116, 0, + 1, 0, 3, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97, + 108, 117, 101, 70, 95, 70, 108, 111, 97, 116, 0, 171, 171, 0, 0, 3, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, + 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79, + 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 124, 0, 0, 0, 4, 0, 0, 0, + 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 15, 0, 0, 0, 104, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 104, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, + 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 255, 255, 255, + 255, 1, 14, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 83, 86, 95, 68, + 69, 80, 84, 72, 0, 171, 83, 72, 68, 82, 164, 0, 0, 0, 64, 0, 0, 0, 41, + 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, + 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0, 0, 101, 0, + 0, 2, 1, 192, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70, + 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, + 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 6, 242, 32, 16, 0, 2, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 5, 1, 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 4, 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 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, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps4.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps4.h new file mode 100644 index 0000000000..60584aceef --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps4.h @@ -0,0 +1,104 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer ColorAndDepthDataFloat +// { +// +// float4 color_Float; // Offset: 0 Size: 16 +// float zValueF_Float; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// ColorAndDepthDataFloat cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// SV_TARGET 1 xyzw 1 TARGET float xyzw +// SV_TARGET 2 xyzw 2 TARGET float xyzw +// SV_TARGET 3 xyzw 3 TARGET float xyzw +// SV_DEPTH 0 N/A oDepth DEPTH float YES +// +ps_4_0 +dcl_constantbuffer CB0[2], immediateIndexed +dcl_output o0.xyzw +dcl_output o1.xyzw +dcl_output o2.xyzw +dcl_output o3.xyzw +dcl_output oDepth +mov o0.xyzw, cb0[0].xyzw +mov o1.xyzw, cb0[0].xyzw +mov o2.xyzw, cb0[0].xyzw +mov o3.xyzw, cb0[0].xyzw +mov oDepth, cb0[1].x +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_ClearFloat4[] = { + 68, 88, 66, 67, 138, 36, 21, 91, 225, 8, 214, 250, 89, 152, 40, 168, 243, 126, 8, + 187, 1, 0, 0, 0, 88, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, 12, 2, 0, 0, 220, 2, 0, 0, 82, 68, 69, 70, 0, + 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104, + 68, 97, 116, 97, 70, 108, 111, 97, 116, 0, 171, 60, 0, 0, 0, 2, 0, 0, 0, + 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0, + 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200, + 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 70, 108, 111, 97, 116, 0, + 1, 0, 3, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97, + 108, 117, 101, 70, 95, 70, 108, 111, 97, 116, 0, 171, 171, 0, 0, 3, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, + 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79, + 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 148, 0, 0, 0, 5, 0, 0, 0, + 8, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 15, 0, 0, 0, 128, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 128, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, + 128, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 15, 0, 0, 0, 138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 255, 255, 255, 255, 1, 14, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, + 0, 83, 86, 95, 68, 69, 80, 84, 72, 0, 171, 83, 72, 68, 82, 200, 0, 0, 0, + 64, 0, 0, 0, 50, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, + 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 3, 0, 0, 0, 101, 0, 0, 2, + 1, 192, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0, + 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, + 32, 16, 0, 2, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 242, 32, 16, 0, 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 5, 1, 192, 0, 0, 10, 128, 32, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + 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, 0, 0, 0, 0, 0, 0, 0, + 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps5.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps5.h new file mode 100644 index 0000000000..15c0545fee --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps5.h @@ -0,0 +1,110 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer ColorAndDepthDataFloat +// { +// +// float4 color_Float; // Offset: 0 Size: 16 +// float zValueF_Float; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// ColorAndDepthDataFloat cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// SV_TARGET 1 xyzw 1 TARGET float xyzw +// SV_TARGET 2 xyzw 2 TARGET float xyzw +// SV_TARGET 3 xyzw 3 TARGET float xyzw +// SV_TARGET 4 xyzw 4 TARGET float xyzw +// SV_DEPTH 0 N/A oDepth DEPTH float YES +// +ps_4_0 +dcl_constantbuffer CB0[2], immediateIndexed +dcl_output o0.xyzw +dcl_output o1.xyzw +dcl_output o2.xyzw +dcl_output o3.xyzw +dcl_output o4.xyzw +dcl_output oDepth +mov o0.xyzw, cb0[0].xyzw +mov o1.xyzw, cb0[0].xyzw +mov o2.xyzw, cb0[0].xyzw +mov o3.xyzw, cb0[0].xyzw +mov o4.xyzw, cb0[0].xyzw +mov oDepth, cb0[1].x +ret +// Approximately 7 instruction slots used +#endif + +const BYTE g_PS_ClearFloat5[] = { + 68, 88, 66, 67, 19, 82, 125, 81, 104, 222, 105, 50, 128, 46, 184, 118, 230, 154, 80, + 52, 1, 0, 0, 0, 148, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, 36, 2, 0, 0, 24, 3, 0, 0, 82, 68, 69, 70, 0, + 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104, + 68, 97, 116, 97, 70, 108, 111, 97, 116, 0, 171, 60, 0, 0, 0, 2, 0, 0, 0, + 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0, + 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200, + 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 70, 108, 111, 97, 116, 0, + 1, 0, 3, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97, + 108, 117, 101, 70, 95, 70, 108, 111, 97, 116, 0, 171, 171, 0, 0, 3, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, + 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79, + 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 172, 0, 0, 0, 6, 0, 0, 0, + 8, 0, 0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 15, 0, 0, 0, 152, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 152, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, + 152, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 15, 0, 0, 0, 152, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 162, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 1, 14, 0, 0, 83, 86, 95, 84, + 65, 82, 71, 69, 84, 0, 83, 86, 95, 68, 69, 80, 84, 72, 0, 171, 83, 72, 68, + 82, 236, 0, 0, 0, 64, 0, 0, 0, 59, 0, 0, 0, 89, 0, 0, 4, 70, 142, + 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, + 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 3, 0, 0, + 0, 101, 0, 0, 3, 242, 32, 16, 0, 4, 0, 0, 0, 101, 0, 0, 2, 1, 192, + 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0, 0, 0, + 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, + 0, 2, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 6, 242, 32, 16, 0, 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 4, 0, 0, 0, 70, 142, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 1, 192, 0, 0, 10, 128, 32, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 6, 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, 0, 0, 0, 0, + 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps6.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps6.h new file mode 100644 index 0000000000..7cd6a03188 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps6.h @@ -0,0 +1,116 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer ColorAndDepthDataFloat +// { +// +// float4 color_Float; // Offset: 0 Size: 16 +// float zValueF_Float; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// ColorAndDepthDataFloat cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// SV_TARGET 1 xyzw 1 TARGET float xyzw +// SV_TARGET 2 xyzw 2 TARGET float xyzw +// SV_TARGET 3 xyzw 3 TARGET float xyzw +// SV_TARGET 4 xyzw 4 TARGET float xyzw +// SV_TARGET 5 xyzw 5 TARGET float xyzw +// SV_DEPTH 0 N/A oDepth DEPTH float YES +// +ps_4_0 +dcl_constantbuffer CB0[2], immediateIndexed +dcl_output o0.xyzw +dcl_output o1.xyzw +dcl_output o2.xyzw +dcl_output o3.xyzw +dcl_output o4.xyzw +dcl_output o5.xyzw +dcl_output oDepth +mov o0.xyzw, cb0[0].xyzw +mov o1.xyzw, cb0[0].xyzw +mov o2.xyzw, cb0[0].xyzw +mov o3.xyzw, cb0[0].xyzw +mov o4.xyzw, cb0[0].xyzw +mov o5.xyzw, cb0[0].xyzw +mov oDepth, cb0[1].x +ret +// Approximately 8 instruction slots used +#endif + +const BYTE g_PS_ClearFloat6[] = { + 68, 88, 66, 67, 115, 157, 164, 56, 254, 153, 37, 126, 220, 182, 131, 196, 87, 71, 44, + 30, 1, 0, 0, 0, 208, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, 60, 2, 0, 0, 84, 3, 0, 0, 82, 68, 69, 70, 0, + 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104, + 68, 97, 116, 97, 70, 108, 111, 97, 116, 0, 171, 60, 0, 0, 0, 2, 0, 0, 0, + 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0, + 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200, + 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 70, 108, 111, 97, 116, 0, + 1, 0, 3, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97, + 108, 117, 101, 70, 95, 70, 108, 111, 97, 116, 0, 171, 171, 0, 0, 3, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, + 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79, + 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 196, 0, 0, 0, 7, 0, 0, 0, + 8, 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 15, 0, 0, 0, 176, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 176, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, + 176, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 15, 0, 0, 0, 176, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 176, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 186, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 1, 14, 0, + 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 83, 86, 95, 68, 69, 80, 84, 72, + 0, 171, 83, 72, 68, 82, 16, 1, 0, 0, 64, 0, 0, 0, 68, 0, 0, 0, 89, + 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, + 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, + 16, 0, 3, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 4, 0, 0, 0, 101, + 0, 0, 3, 242, 32, 16, 0, 5, 0, 0, 0, 101, 0, 0, 2, 1, 192, 0, 0, + 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0, 0, 0, 70, 142, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 2, + 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, + 242, 32, 16, 0, 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 0, 0, 6, 242, 32, 16, 0, 4, 0, 0, 0, 70, 142, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 5, 0, 0, 0, 70, + 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 1, 192, 0, 0, + 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, + 84, 116, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 7, 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, 0, + 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps7.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps7.h new file mode 100644 index 0000000000..048471ad6b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps7.h @@ -0,0 +1,122 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer ColorAndDepthDataFloat +// { +// +// float4 color_Float; // Offset: 0 Size: 16 +// float zValueF_Float; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// ColorAndDepthDataFloat cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// SV_TARGET 1 xyzw 1 TARGET float xyzw +// SV_TARGET 2 xyzw 2 TARGET float xyzw +// SV_TARGET 3 xyzw 3 TARGET float xyzw +// SV_TARGET 4 xyzw 4 TARGET float xyzw +// SV_TARGET 5 xyzw 5 TARGET float xyzw +// SV_TARGET 6 xyzw 6 TARGET float xyzw +// SV_DEPTH 0 N/A oDepth DEPTH float YES +// +ps_4_0 +dcl_constantbuffer CB0[2], immediateIndexed +dcl_output o0.xyzw +dcl_output o1.xyzw +dcl_output o2.xyzw +dcl_output o3.xyzw +dcl_output o4.xyzw +dcl_output o5.xyzw +dcl_output o6.xyzw +dcl_output oDepth +mov o0.xyzw, cb0[0].xyzw +mov o1.xyzw, cb0[0].xyzw +mov o2.xyzw, cb0[0].xyzw +mov o3.xyzw, cb0[0].xyzw +mov o4.xyzw, cb0[0].xyzw +mov o5.xyzw, cb0[0].xyzw +mov o6.xyzw, cb0[0].xyzw +mov oDepth, cb0[1].x +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_ClearFloat7[] = { + 68, 88, 66, 67, 142, 12, 138, 6, 10, 107, 58, 43, 178, 14, 208, 224, 48, 233, 91, + 50, 1, 0, 0, 0, 12, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, 84, 2, 0, 0, 144, 3, 0, 0, 82, 68, 69, 70, 0, + 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104, + 68, 97, 116, 97, 70, 108, 111, 97, 116, 0, 171, 60, 0, 0, 0, 2, 0, 0, 0, + 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0, + 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200, + 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 70, 108, 111, 97, 116, 0, + 1, 0, 3, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97, + 108, 117, 101, 70, 95, 70, 108, 111, 97, 116, 0, 171, 171, 0, 0, 3, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, + 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79, + 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 220, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 15, 0, 0, 0, 200, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 200, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, + 200, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 15, 0, 0, 0, 200, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 200, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 200, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, + 0, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 255, 255, + 255, 255, 1, 14, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 83, 86, 95, + 68, 69, 80, 84, 72, 0, 171, 83, 72, 68, 82, 52, 1, 0, 0, 64, 0, 0, 0, + 77, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, + 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0, 0, 101, + 0, 0, 3, 242, 32, 16, 0, 3, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, + 4, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 5, 0, 0, 0, 101, 0, 0, + 3, 242, 32, 16, 0, 6, 0, 0, 0, 101, 0, 0, 2, 1, 192, 0, 0, 54, 0, + 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 2, 0, 0, + 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, + 16, 0, 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 6, 242, 32, 16, 0, 4, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 5, 0, 0, 0, 70, 142, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 6, 0, + 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 1, + 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 8, 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, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 8, 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, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps8.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps8.h new file mode 100644 index 0000000000..b338868e18 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps8.h @@ -0,0 +1,128 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer ColorAndDepthDataFloat +// { +// +// float4 color_Float; // Offset: 0 Size: 16 +// float zValueF_Float; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// ColorAndDepthDataFloat cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// SV_TARGET 1 xyzw 1 TARGET float xyzw +// SV_TARGET 2 xyzw 2 TARGET float xyzw +// SV_TARGET 3 xyzw 3 TARGET float xyzw +// SV_TARGET 4 xyzw 4 TARGET float xyzw +// SV_TARGET 5 xyzw 5 TARGET float xyzw +// SV_TARGET 6 xyzw 6 TARGET float xyzw +// SV_TARGET 7 xyzw 7 TARGET float xyzw +// SV_DEPTH 0 N/A oDepth DEPTH float YES +// +ps_4_0 +dcl_constantbuffer CB0[2], immediateIndexed +dcl_output o0.xyzw +dcl_output o1.xyzw +dcl_output o2.xyzw +dcl_output o3.xyzw +dcl_output o4.xyzw +dcl_output o5.xyzw +dcl_output o6.xyzw +dcl_output o7.xyzw +dcl_output oDepth +mov o0.xyzw, cb0[0].xyzw +mov o1.xyzw, cb0[0].xyzw +mov o2.xyzw, cb0[0].xyzw +mov o3.xyzw, cb0[0].xyzw +mov o4.xyzw, cb0[0].xyzw +mov o5.xyzw, cb0[0].xyzw +mov o6.xyzw, cb0[0].xyzw +mov o7.xyzw, cb0[0].xyzw +mov oDepth, cb0[1].x +ret +// Approximately 10 instruction slots used +#endif + +const BYTE g_PS_ClearFloat8[] = { + 68, 88, 66, 67, 228, 232, 153, 58, 173, 161, 124, 75, 45, 184, 173, 123, 62, 150, 36, + 145, 1, 0, 0, 0, 72, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, 108, 2, 0, 0, 204, 3, 0, 0, 82, 68, 69, 70, 0, + 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104, + 68, 97, 116, 97, 70, 108, 111, 97, 116, 0, 171, 60, 0, 0, 0, 2, 0, 0, 0, + 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0, + 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200, + 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 70, 108, 111, 97, 116, 0, + 1, 0, 3, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97, + 108, 117, 101, 70, 95, 70, 108, 111, 97, 116, 0, 171, 171, 0, 0, 3, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, + 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79, + 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 244, 0, 0, 0, 9, 0, 0, 0, + 8, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 15, 0, 0, 0, 224, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 224, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, + 224, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 15, 0, 0, 0, 224, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 224, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 224, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, + 0, 224, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 7, 0, + 0, 0, 15, 0, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 255, 255, 255, 255, 1, 14, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, + 84, 0, 83, 86, 95, 68, 69, 80, 84, 72, 0, 171, 83, 72, 68, 82, 88, 1, 0, + 0, 64, 0, 0, 0, 86, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 101, + 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, + 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 3, 0, 0, 0, 101, 0, 0, + 3, 242, 32, 16, 0, 4, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 5, 0, + 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 6, 0, 0, 0, 101, 0, 0, 3, 242, + 32, 16, 0, 7, 0, 0, 0, 101, 0, 0, 2, 1, 192, 0, 0, 54, 0, 0, 6, + 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 2, 0, 0, 0, 70, + 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, + 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 6, 242, 32, 16, 0, 4, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 5, 0, 0, 0, 70, 142, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 6, 0, 0, 0, + 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, + 0, 7, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 1, 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 62, + 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 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, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 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, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps1.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps1.h new file mode 100644 index 0000000000..d6139430ee --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps1.h @@ -0,0 +1,85 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer ColorAndDepthDataSint +// { +// +// int4 color_Sint; // Offset: 0 Size: 16 +// float zValueF_Sint; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// ColorAndDepthDataSint cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// SV_DEPTH 0 N/A oDepth DEPTH float YES +// +ps_4_0 +dcl_constantbuffer CB0[2], immediateIndexed +dcl_output o0.xyzw +dcl_output oDepth +mov o0.xyzw, cb0[0].xyzw +mov oDepth, cb0[1].x +ret +// Approximately 3 instruction slots used +#endif + +const BYTE g_PS_ClearSint1[] = { + 68, 88, 66, 67, 231, 188, 2, 59, 91, 73, 220, 119, 245, 143, 245, 143, 240, 202, 170, + 163, 1, 0, 0, 0, 164, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, 196, 1, 0, 0, 40, 2, 0, 0, 82, 68, 69, 70, 0, + 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104, + 68, 97, 116, 97, 83, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0, + 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0, + 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200, + 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 83, 105, 110, 116, 0, 171, + 1, 0, 2, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97, + 108, 117, 101, 70, 95, 83, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, + 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79, + 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 76, 0, 0, 0, 2, 0, 0, 0, + 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 15, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 1, 14, 0, 0, 83, 86, 95, 84, 65, + 82, 71, 69, 84, 0, 83, 86, 95, 68, 69, 80, 84, 72, 0, 171, 83, 72, 68, 82, + 92, 0, 0, 0, 64, 0, 0, 0, 23, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, + 0, 0, 101, 0, 0, 2, 1, 192, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0, + 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 1, 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 62, 0, 0, + 1, 83, 84, 65, 84, 116, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 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, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps2.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps2.h new file mode 100644 index 0000000000..a7cc7221ce --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps2.h @@ -0,0 +1,91 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer ColorAndDepthDataSint +// { +// +// int4 color_Sint; // Offset: 0 Size: 16 +// float zValueF_Sint; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// ColorAndDepthDataSint cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// SV_TARGET 1 xyzw 1 TARGET int xyzw +// SV_DEPTH 0 N/A oDepth DEPTH float YES +// +ps_4_0 +dcl_constantbuffer CB0[2], immediateIndexed +dcl_output o0.xyzw +dcl_output o1.xyzw +dcl_output oDepth +mov o0.xyzw, cb0[0].xyzw +mov o1.xyzw, cb0[0].xyzw +mov oDepth, cb0[1].x +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_ClearSint2[] = { + 68, 88, 66, 67, 85, 225, 210, 35, 166, 97, 84, 193, 114, 210, 51, 82, 238, 19, 251, + 198, 1, 0, 0, 0, 224, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, 220, 1, 0, 0, 100, 2, 0, 0, 82, 68, 69, 70, 0, + 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104, + 68, 97, 116, 97, 83, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0, + 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0, + 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200, + 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 83, 105, 110, 116, 0, 171, + 1, 0, 2, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97, + 108, 117, 101, 70, 95, 83, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, + 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79, + 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 100, 0, 0, 0, 3, 0, 0, 0, + 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 15, 0, 0, 0, 80, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 90, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 1, 14, 0, 0, + 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 83, 86, 95, 68, 69, 80, 84, 72, 0, + 171, 83, 72, 68, 82, 128, 0, 0, 0, 64, 0, 0, 0, 32, 0, 0, 0, 89, 0, + 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, + 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, + 101, 0, 0, 2, 1, 192, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0, + 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, + 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 5, 1, 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 4, 0, 0, 0, 0, 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, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps3.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps3.h new file mode 100644 index 0000000000..053de6d738 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps3.h @@ -0,0 +1,97 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer ColorAndDepthDataSint +// { +// +// int4 color_Sint; // Offset: 0 Size: 16 +// float zValueF_Sint; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// ColorAndDepthDataSint cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// SV_TARGET 1 xyzw 1 TARGET int xyzw +// SV_TARGET 2 xyzw 2 TARGET int xyzw +// SV_DEPTH 0 N/A oDepth DEPTH float YES +// +ps_4_0 +dcl_constantbuffer CB0[2], immediateIndexed +dcl_output o0.xyzw +dcl_output o1.xyzw +dcl_output o2.xyzw +dcl_output oDepth +mov o0.xyzw, cb0[0].xyzw +mov o1.xyzw, cb0[0].xyzw +mov o2.xyzw, cb0[0].xyzw +mov oDepth, cb0[1].x +ret +// Approximately 5 instruction slots used +#endif + +const BYTE g_PS_ClearSint3[] = { + 68, 88, 66, 67, 101, 236, 110, 148, 64, 148, 5, 108, 246, 70, 148, 1, 36, 90, 92, + 9, 1, 0, 0, 0, 28, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, 244, 1, 0, 0, 160, 2, 0, 0, 82, 68, 69, 70, 0, + 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104, + 68, 97, 116, 97, 83, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0, + 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0, + 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200, + 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 83, 105, 110, 116, 0, 171, + 1, 0, 2, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97, + 108, 117, 101, 70, 95, 83, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, + 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79, + 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 124, 0, 0, 0, 4, 0, 0, 0, + 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 15, 0, 0, 0, 104, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 104, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, + 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 255, 255, 255, + 255, 1, 14, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 83, 86, 95, 68, + 69, 80, 84, 72, 0, 171, 83, 72, 68, 82, 164, 0, 0, 0, 64, 0, 0, 0, 41, + 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, + 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0, 0, 101, 0, + 0, 2, 1, 192, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70, + 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, + 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 6, 242, 32, 16, 0, 2, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 5, 1, 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 4, 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 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, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps4.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps4.h new file mode 100644 index 0000000000..134f6253ee --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps4.h @@ -0,0 +1,104 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer ColorAndDepthDataSint +// { +// +// int4 color_Sint; // Offset: 0 Size: 16 +// float zValueF_Sint; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// ColorAndDepthDataSint cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// SV_TARGET 1 xyzw 1 TARGET int xyzw +// SV_TARGET 2 xyzw 2 TARGET int xyzw +// SV_TARGET 3 xyzw 3 TARGET int xyzw +// SV_DEPTH 0 N/A oDepth DEPTH float YES +// +ps_4_0 +dcl_constantbuffer CB0[2], immediateIndexed +dcl_output o0.xyzw +dcl_output o1.xyzw +dcl_output o2.xyzw +dcl_output o3.xyzw +dcl_output oDepth +mov o0.xyzw, cb0[0].xyzw +mov o1.xyzw, cb0[0].xyzw +mov o2.xyzw, cb0[0].xyzw +mov o3.xyzw, cb0[0].xyzw +mov oDepth, cb0[1].x +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_ClearSint4[] = { + 68, 88, 66, 67, 206, 59, 157, 191, 139, 37, 109, 85, 193, 141, 185, 200, 81, 149, 0, + 246, 1, 0, 0, 0, 88, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, 12, 2, 0, 0, 220, 2, 0, 0, 82, 68, 69, 70, 0, + 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104, + 68, 97, 116, 97, 83, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0, + 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0, + 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200, + 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 83, 105, 110, 116, 0, 171, + 1, 0, 2, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97, + 108, 117, 101, 70, 95, 83, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, + 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79, + 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 148, 0, 0, 0, 5, 0, 0, 0, + 8, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 15, 0, 0, 0, 128, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 128, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, + 128, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, + 0, 15, 0, 0, 0, 138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 255, 255, 255, 255, 1, 14, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, + 0, 83, 86, 95, 68, 69, 80, 84, 72, 0, 171, 83, 72, 68, 82, 200, 0, 0, 0, + 64, 0, 0, 0, 50, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, + 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 3, 0, 0, 0, 101, 0, 0, 2, + 1, 192, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0, + 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, + 32, 16, 0, 2, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 242, 32, 16, 0, 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 5, 1, 192, 0, 0, 10, 128, 32, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + 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, 0, 0, 0, 0, 0, 0, 0, + 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps5.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps5.h new file mode 100644 index 0000000000..3466e72460 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps5.h @@ -0,0 +1,110 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer ColorAndDepthDataSint +// { +// +// int4 color_Sint; // Offset: 0 Size: 16 +// float zValueF_Sint; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// ColorAndDepthDataSint cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// SV_TARGET 1 xyzw 1 TARGET int xyzw +// SV_TARGET 2 xyzw 2 TARGET int xyzw +// SV_TARGET 3 xyzw 3 TARGET int xyzw +// SV_TARGET 4 xyzw 4 TARGET int xyzw +// SV_DEPTH 0 N/A oDepth DEPTH float YES +// +ps_4_0 +dcl_constantbuffer CB0[2], immediateIndexed +dcl_output o0.xyzw +dcl_output o1.xyzw +dcl_output o2.xyzw +dcl_output o3.xyzw +dcl_output o4.xyzw +dcl_output oDepth +mov o0.xyzw, cb0[0].xyzw +mov o1.xyzw, cb0[0].xyzw +mov o2.xyzw, cb0[0].xyzw +mov o3.xyzw, cb0[0].xyzw +mov o4.xyzw, cb0[0].xyzw +mov oDepth, cb0[1].x +ret +// Approximately 7 instruction slots used +#endif + +const BYTE g_PS_ClearSint5[] = { + 68, 88, 66, 67, 91, 91, 66, 76, 160, 92, 0, 147, 5, 30, 128, 248, 1, 125, 140, + 124, 1, 0, 0, 0, 148, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, 36, 2, 0, 0, 24, 3, 0, 0, 82, 68, 69, 70, 0, + 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104, + 68, 97, 116, 97, 83, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0, + 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0, + 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200, + 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 83, 105, 110, 116, 0, 171, + 1, 0, 2, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97, + 108, 117, 101, 70, 95, 83, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, + 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79, + 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 172, 0, 0, 0, 6, 0, 0, 0, + 8, 0, 0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 15, 0, 0, 0, 152, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 152, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, + 152, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, + 0, 15, 0, 0, 0, 152, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 162, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 1, 14, 0, 0, 83, 86, 95, 84, + 65, 82, 71, 69, 84, 0, 83, 86, 95, 68, 69, 80, 84, 72, 0, 171, 83, 72, 68, + 82, 236, 0, 0, 0, 64, 0, 0, 0, 59, 0, 0, 0, 89, 0, 0, 4, 70, 142, + 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, + 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 3, 0, 0, + 0, 101, 0, 0, 3, 242, 32, 16, 0, 4, 0, 0, 0, 101, 0, 0, 2, 1, 192, + 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0, 0, 0, + 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, + 0, 2, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 6, 242, 32, 16, 0, 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 4, 0, 0, 0, 70, 142, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 1, 192, 0, 0, 10, 128, 32, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 6, 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, 0, 0, 0, 0, + 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps6.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps6.h new file mode 100644 index 0000000000..b54bcf1fea --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps6.h @@ -0,0 +1,116 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer ColorAndDepthDataSint +// { +// +// int4 color_Sint; // Offset: 0 Size: 16 +// float zValueF_Sint; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// ColorAndDepthDataSint cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// SV_TARGET 1 xyzw 1 TARGET int xyzw +// SV_TARGET 2 xyzw 2 TARGET int xyzw +// SV_TARGET 3 xyzw 3 TARGET int xyzw +// SV_TARGET 4 xyzw 4 TARGET int xyzw +// SV_TARGET 5 xyzw 5 TARGET int xyzw +// SV_DEPTH 0 N/A oDepth DEPTH float YES +// +ps_4_0 +dcl_constantbuffer CB0[2], immediateIndexed +dcl_output o0.xyzw +dcl_output o1.xyzw +dcl_output o2.xyzw +dcl_output o3.xyzw +dcl_output o4.xyzw +dcl_output o5.xyzw +dcl_output oDepth +mov o0.xyzw, cb0[0].xyzw +mov o1.xyzw, cb0[0].xyzw +mov o2.xyzw, cb0[0].xyzw +mov o3.xyzw, cb0[0].xyzw +mov o4.xyzw, cb0[0].xyzw +mov o5.xyzw, cb0[0].xyzw +mov oDepth, cb0[1].x +ret +// Approximately 8 instruction slots used +#endif + +const BYTE g_PS_ClearSint6[] = { + 68, 88, 66, 67, 245, 94, 2, 129, 134, 247, 241, 8, 253, 220, 200, 172, 215, 17, 127, + 35, 1, 0, 0, 0, 208, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, 60, 2, 0, 0, 84, 3, 0, 0, 82, 68, 69, 70, 0, + 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104, + 68, 97, 116, 97, 83, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0, + 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0, + 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200, + 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 83, 105, 110, 116, 0, 171, + 1, 0, 2, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97, + 108, 117, 101, 70, 95, 83, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, + 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79, + 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 196, 0, 0, 0, 7, 0, 0, 0, + 8, 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 15, 0, 0, 0, 176, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 176, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, + 176, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, + 0, 15, 0, 0, 0, 176, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 176, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 186, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 1, 14, 0, + 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 83, 86, 95, 68, 69, 80, 84, 72, + 0, 171, 83, 72, 68, 82, 16, 1, 0, 0, 64, 0, 0, 0, 68, 0, 0, 0, 89, + 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, + 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, + 16, 0, 3, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 4, 0, 0, 0, 101, + 0, 0, 3, 242, 32, 16, 0, 5, 0, 0, 0, 101, 0, 0, 2, 1, 192, 0, 0, + 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0, 0, 0, 70, 142, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 2, + 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, + 242, 32, 16, 0, 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 0, 0, 6, 242, 32, 16, 0, 4, 0, 0, 0, 70, 142, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 5, 0, 0, 0, 70, + 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 1, 192, 0, 0, + 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, + 84, 116, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 7, 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, 0, + 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps7.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps7.h new file mode 100644 index 0000000000..0c7755d295 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps7.h @@ -0,0 +1,122 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer ColorAndDepthDataSint +// { +// +// int4 color_Sint; // Offset: 0 Size: 16 +// float zValueF_Sint; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// ColorAndDepthDataSint cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// SV_TARGET 1 xyzw 1 TARGET int xyzw +// SV_TARGET 2 xyzw 2 TARGET int xyzw +// SV_TARGET 3 xyzw 3 TARGET int xyzw +// SV_TARGET 4 xyzw 4 TARGET int xyzw +// SV_TARGET 5 xyzw 5 TARGET int xyzw +// SV_TARGET 6 xyzw 6 TARGET int xyzw +// SV_DEPTH 0 N/A oDepth DEPTH float YES +// +ps_4_0 +dcl_constantbuffer CB0[2], immediateIndexed +dcl_output o0.xyzw +dcl_output o1.xyzw +dcl_output o2.xyzw +dcl_output o3.xyzw +dcl_output o4.xyzw +dcl_output o5.xyzw +dcl_output o6.xyzw +dcl_output oDepth +mov o0.xyzw, cb0[0].xyzw +mov o1.xyzw, cb0[0].xyzw +mov o2.xyzw, cb0[0].xyzw +mov o3.xyzw, cb0[0].xyzw +mov o4.xyzw, cb0[0].xyzw +mov o5.xyzw, cb0[0].xyzw +mov o6.xyzw, cb0[0].xyzw +mov oDepth, cb0[1].x +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_ClearSint7[] = { + 68, 88, 66, 67, 203, 48, 20, 196, 108, 146, 109, 165, 143, 63, 145, 150, 29, 34, 214, + 22, 1, 0, 0, 0, 12, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, 84, 2, 0, 0, 144, 3, 0, 0, 82, 68, 69, 70, 0, + 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104, + 68, 97, 116, 97, 83, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0, + 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0, + 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200, + 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 83, 105, 110, 116, 0, 171, + 1, 0, 2, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97, + 108, 117, 101, 70, 95, 83, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, + 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79, + 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 220, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 15, 0, 0, 0, 200, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 200, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, + 200, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, + 0, 15, 0, 0, 0, 200, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 200, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 200, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, + 0, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 255, 255, + 255, 255, 1, 14, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 83, 86, 95, + 68, 69, 80, 84, 72, 0, 171, 83, 72, 68, 82, 52, 1, 0, 0, 64, 0, 0, 0, + 77, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, + 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0, 0, 101, + 0, 0, 3, 242, 32, 16, 0, 3, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, + 4, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 5, 0, 0, 0, 101, 0, 0, + 3, 242, 32, 16, 0, 6, 0, 0, 0, 101, 0, 0, 2, 1, 192, 0, 0, 54, 0, + 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 2, 0, 0, + 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, + 16, 0, 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 6, 242, 32, 16, 0, 4, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 5, 0, 0, 0, 70, 142, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 6, 0, + 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 1, + 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 8, 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, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 8, 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, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps8.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps8.h new file mode 100644 index 0000000000..10e77dfcc3 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps8.h @@ -0,0 +1,128 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer ColorAndDepthDataSint +// { +// +// int4 color_Sint; // Offset: 0 Size: 16 +// float zValueF_Sint; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// ColorAndDepthDataSint cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// SV_TARGET 1 xyzw 1 TARGET int xyzw +// SV_TARGET 2 xyzw 2 TARGET int xyzw +// SV_TARGET 3 xyzw 3 TARGET int xyzw +// SV_TARGET 4 xyzw 4 TARGET int xyzw +// SV_TARGET 5 xyzw 5 TARGET int xyzw +// SV_TARGET 6 xyzw 6 TARGET int xyzw +// SV_TARGET 7 xyzw 7 TARGET int xyzw +// SV_DEPTH 0 N/A oDepth DEPTH float YES +// +ps_4_0 +dcl_constantbuffer CB0[2], immediateIndexed +dcl_output o0.xyzw +dcl_output o1.xyzw +dcl_output o2.xyzw +dcl_output o3.xyzw +dcl_output o4.xyzw +dcl_output o5.xyzw +dcl_output o6.xyzw +dcl_output o7.xyzw +dcl_output oDepth +mov o0.xyzw, cb0[0].xyzw +mov o1.xyzw, cb0[0].xyzw +mov o2.xyzw, cb0[0].xyzw +mov o3.xyzw, cb0[0].xyzw +mov o4.xyzw, cb0[0].xyzw +mov o5.xyzw, cb0[0].xyzw +mov o6.xyzw, cb0[0].xyzw +mov o7.xyzw, cb0[0].xyzw +mov oDepth, cb0[1].x +ret +// Approximately 10 instruction slots used +#endif + +const BYTE g_PS_ClearSint8[] = { + 68, 88, 66, 67, 199, 7, 207, 179, 143, 119, 139, 38, 92, 223, 215, 110, 33, 171, 222, + 186, 1, 0, 0, 0, 72, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, 108, 2, 0, 0, 204, 3, 0, 0, 82, 68, 69, 70, 0, + 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104, + 68, 97, 116, 97, 83, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0, + 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0, + 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200, + 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 83, 105, 110, 116, 0, 171, + 1, 0, 2, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97, + 108, 117, 101, 70, 95, 83, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, + 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79, + 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 244, 0, 0, 0, 9, 0, 0, 0, + 8, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 15, 0, 0, 0, 224, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 224, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, + 224, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, + 0, 15, 0, 0, 0, 224, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 224, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 224, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, + 0, 224, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, + 0, 0, 15, 0, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 255, 255, 255, 255, 1, 14, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, + 84, 0, 83, 86, 95, 68, 69, 80, 84, 72, 0, 171, 83, 72, 68, 82, 88, 1, 0, + 0, 64, 0, 0, 0, 86, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 101, + 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, + 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 3, 0, 0, 0, 101, 0, 0, + 3, 242, 32, 16, 0, 4, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 5, 0, + 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 6, 0, 0, 0, 101, 0, 0, 3, 242, + 32, 16, 0, 7, 0, 0, 0, 101, 0, 0, 2, 1, 192, 0, 0, 54, 0, 0, 6, + 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 2, 0, 0, 0, 70, + 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, + 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 6, 242, 32, 16, 0, 4, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 5, 0, 0, 0, 70, 142, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 6, 0, 0, 0, + 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, + 0, 7, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 1, 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 62, + 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 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, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 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, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps1.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps1.h new file mode 100644 index 0000000000..10f1a56e51 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps1.h @@ -0,0 +1,85 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer ColorAndDepthDataUint +// { +// +// uint4 color_Uint; // Offset: 0 Size: 16 +// float zValueF_Uint; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// ColorAndDepthDataUint cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// SV_DEPTH 0 N/A oDepth DEPTH float YES +// +ps_4_0 +dcl_constantbuffer CB0[2], immediateIndexed +dcl_output o0.xyzw +dcl_output oDepth +mov o0.xyzw, cb0[0].xyzw +mov oDepth, cb0[1].x +ret +// Approximately 3 instruction slots used +#endif + +const BYTE g_PS_ClearUint1[] = { + 68, 88, 66, 67, 153, 3, 197, 234, 233, 241, 61, 147, 138, 167, 150, 193, 156, 181, 197, + 213, 1, 0, 0, 0, 164, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, 196, 1, 0, 0, 40, 2, 0, 0, 82, 68, 69, 70, 0, + 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104, + 68, 97, 116, 97, 85, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0, + 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0, + 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200, + 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 85, 105, 110, 116, 0, 171, + 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97, + 108, 117, 101, 70, 95, 85, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, + 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79, + 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 76, 0, 0, 0, 2, 0, 0, 0, + 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 15, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 1, 14, 0, 0, 83, 86, 95, 84, 65, + 82, 71, 69, 84, 0, 83, 86, 95, 68, 69, 80, 84, 72, 0, 171, 83, 72, 68, 82, + 92, 0, 0, 0, 64, 0, 0, 0, 23, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, + 0, 0, 101, 0, 0, 2, 1, 192, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0, + 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 1, 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 62, 0, 0, + 1, 83, 84, 65, 84, 116, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 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, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps2.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps2.h new file mode 100644 index 0000000000..8c94b388f9 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps2.h @@ -0,0 +1,91 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer ColorAndDepthDataUint +// { +// +// uint4 color_Uint; // Offset: 0 Size: 16 +// float zValueF_Uint; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// ColorAndDepthDataUint cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// SV_TARGET 1 xyzw 1 TARGET uint xyzw +// SV_DEPTH 0 N/A oDepth DEPTH float YES +// +ps_4_0 +dcl_constantbuffer CB0[2], immediateIndexed +dcl_output o0.xyzw +dcl_output o1.xyzw +dcl_output oDepth +mov o0.xyzw, cb0[0].xyzw +mov o1.xyzw, cb0[0].xyzw +mov oDepth, cb0[1].x +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_ClearUint2[] = { + 68, 88, 66, 67, 192, 246, 30, 248, 11, 186, 26, 252, 71, 98, 86, 143, 152, 241, 57, + 66, 1, 0, 0, 0, 224, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, 220, 1, 0, 0, 100, 2, 0, 0, 82, 68, 69, 70, 0, + 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104, + 68, 97, 116, 97, 85, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0, + 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0, + 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200, + 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 85, 105, 110, 116, 0, 171, + 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97, + 108, 117, 101, 70, 95, 85, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, + 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79, + 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 100, 0, 0, 0, 3, 0, 0, 0, + 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 15, 0, 0, 0, 80, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 90, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 1, 14, 0, 0, + 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 83, 86, 95, 68, 69, 80, 84, 72, 0, + 171, 83, 72, 68, 82, 128, 0, 0, 0, 64, 0, 0, 0, 32, 0, 0, 0, 89, 0, + 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, + 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, + 101, 0, 0, 2, 1, 192, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0, + 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, + 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 5, 1, 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 4, 0, 0, 0, 0, 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, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps3.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps3.h new file mode 100644 index 0000000000..3c31a85656 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps3.h @@ -0,0 +1,97 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer ColorAndDepthDataUint +// { +// +// uint4 color_Uint; // Offset: 0 Size: 16 +// float zValueF_Uint; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// ColorAndDepthDataUint cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// SV_TARGET 1 xyzw 1 TARGET uint xyzw +// SV_TARGET 2 xyzw 2 TARGET uint xyzw +// SV_DEPTH 0 N/A oDepth DEPTH float YES +// +ps_4_0 +dcl_constantbuffer CB0[2], immediateIndexed +dcl_output o0.xyzw +dcl_output o1.xyzw +dcl_output o2.xyzw +dcl_output oDepth +mov o0.xyzw, cb0[0].xyzw +mov o1.xyzw, cb0[0].xyzw +mov o2.xyzw, cb0[0].xyzw +mov oDepth, cb0[1].x +ret +// Approximately 5 instruction slots used +#endif + +const BYTE g_PS_ClearUint3[] = { + 68, 88, 66, 67, 122, 152, 146, 15, 20, 60, 207, 219, 181, 233, 35, 208, 96, 171, 60, + 29, 1, 0, 0, 0, 28, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, 244, 1, 0, 0, 160, 2, 0, 0, 82, 68, 69, 70, 0, + 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104, + 68, 97, 116, 97, 85, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0, + 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0, + 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200, + 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 85, 105, 110, 116, 0, 171, + 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97, + 108, 117, 101, 70, 95, 85, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, + 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79, + 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 124, 0, 0, 0, 4, 0, 0, 0, + 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 15, 0, 0, 0, 104, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 104, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, + 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 255, 255, 255, + 255, 1, 14, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 83, 86, 95, 68, + 69, 80, 84, 72, 0, 171, 83, 72, 68, 82, 164, 0, 0, 0, 64, 0, 0, 0, 41, + 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, + 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0, 0, 101, 0, + 0, 2, 1, 192, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70, + 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, + 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 6, 242, 32, 16, 0, 2, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 5, 1, 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 4, 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 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, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps4.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps4.h new file mode 100644 index 0000000000..722f1f0acc --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps4.h @@ -0,0 +1,104 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer ColorAndDepthDataUint +// { +// +// uint4 color_Uint; // Offset: 0 Size: 16 +// float zValueF_Uint; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// ColorAndDepthDataUint cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// SV_TARGET 1 xyzw 1 TARGET uint xyzw +// SV_TARGET 2 xyzw 2 TARGET uint xyzw +// SV_TARGET 3 xyzw 3 TARGET uint xyzw +// SV_DEPTH 0 N/A oDepth DEPTH float YES +// +ps_4_0 +dcl_constantbuffer CB0[2], immediateIndexed +dcl_output o0.xyzw +dcl_output o1.xyzw +dcl_output o2.xyzw +dcl_output o3.xyzw +dcl_output oDepth +mov o0.xyzw, cb0[0].xyzw +mov o1.xyzw, cb0[0].xyzw +mov o2.xyzw, cb0[0].xyzw +mov o3.xyzw, cb0[0].xyzw +mov oDepth, cb0[1].x +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_ClearUint4[] = { + 68, 88, 66, 67, 255, 94, 158, 125, 94, 174, 68, 246, 120, 231, 8, 70, 114, 202, 111, + 31, 1, 0, 0, 0, 88, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, 12, 2, 0, 0, 220, 2, 0, 0, 82, 68, 69, 70, 0, + 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104, + 68, 97, 116, 97, 85, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0, + 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0, + 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200, + 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 85, 105, 110, 116, 0, 171, + 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97, + 108, 117, 101, 70, 95, 85, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, + 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79, + 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 148, 0, 0, 0, 5, 0, 0, 0, + 8, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 15, 0, 0, 0, 128, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 128, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, + 128, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, + 0, 15, 0, 0, 0, 138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 255, 255, 255, 255, 1, 14, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, + 0, 83, 86, 95, 68, 69, 80, 84, 72, 0, 171, 83, 72, 68, 82, 200, 0, 0, 0, + 64, 0, 0, 0, 50, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, + 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 3, 0, 0, 0, 101, 0, 0, 2, + 1, 192, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0, + 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, + 32, 16, 0, 2, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 242, 32, 16, 0, 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 5, 1, 192, 0, 0, 10, 128, 32, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + 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, 0, 0, 0, 0, 0, 0, 0, + 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps5.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps5.h new file mode 100644 index 0000000000..d387a76848 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps5.h @@ -0,0 +1,110 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer ColorAndDepthDataUint +// { +// +// uint4 color_Uint; // Offset: 0 Size: 16 +// float zValueF_Uint; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// ColorAndDepthDataUint cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// SV_TARGET 1 xyzw 1 TARGET uint xyzw +// SV_TARGET 2 xyzw 2 TARGET uint xyzw +// SV_TARGET 3 xyzw 3 TARGET uint xyzw +// SV_TARGET 4 xyzw 4 TARGET uint xyzw +// SV_DEPTH 0 N/A oDepth DEPTH float YES +// +ps_4_0 +dcl_constantbuffer CB0[2], immediateIndexed +dcl_output o0.xyzw +dcl_output o1.xyzw +dcl_output o2.xyzw +dcl_output o3.xyzw +dcl_output o4.xyzw +dcl_output oDepth +mov o0.xyzw, cb0[0].xyzw +mov o1.xyzw, cb0[0].xyzw +mov o2.xyzw, cb0[0].xyzw +mov o3.xyzw, cb0[0].xyzw +mov o4.xyzw, cb0[0].xyzw +mov oDepth, cb0[1].x +ret +// Approximately 7 instruction slots used +#endif + +const BYTE g_PS_ClearUint5[] = { + 68, 88, 66, 67, 208, 22, 91, 140, 204, 34, 72, 161, 50, 27, 2, 156, 220, 29, 44, + 80, 1, 0, 0, 0, 148, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, 36, 2, 0, 0, 24, 3, 0, 0, 82, 68, 69, 70, 0, + 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104, + 68, 97, 116, 97, 85, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0, + 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0, + 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200, + 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 85, 105, 110, 116, 0, 171, + 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97, + 108, 117, 101, 70, 95, 85, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, + 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79, + 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 172, 0, 0, 0, 6, 0, 0, 0, + 8, 0, 0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 15, 0, 0, 0, 152, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 152, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, + 152, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, + 0, 15, 0, 0, 0, 152, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 162, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 1, 14, 0, 0, 83, 86, 95, 84, + 65, 82, 71, 69, 84, 0, 83, 86, 95, 68, 69, 80, 84, 72, 0, 171, 83, 72, 68, + 82, 236, 0, 0, 0, 64, 0, 0, 0, 59, 0, 0, 0, 89, 0, 0, 4, 70, 142, + 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, + 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 3, 0, 0, + 0, 101, 0, 0, 3, 242, 32, 16, 0, 4, 0, 0, 0, 101, 0, 0, 2, 1, 192, + 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0, 0, 0, + 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, + 0, 2, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 6, 242, 32, 16, 0, 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 4, 0, 0, 0, 70, 142, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 1, 192, 0, 0, 10, 128, 32, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 6, 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, 0, 0, 0, 0, + 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps6.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps6.h new file mode 100644 index 0000000000..b3dce8228d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps6.h @@ -0,0 +1,116 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer ColorAndDepthDataUint +// { +// +// uint4 color_Uint; // Offset: 0 Size: 16 +// float zValueF_Uint; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// ColorAndDepthDataUint cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// SV_TARGET 1 xyzw 1 TARGET uint xyzw +// SV_TARGET 2 xyzw 2 TARGET uint xyzw +// SV_TARGET 3 xyzw 3 TARGET uint xyzw +// SV_TARGET 4 xyzw 4 TARGET uint xyzw +// SV_TARGET 5 xyzw 5 TARGET uint xyzw +// SV_DEPTH 0 N/A oDepth DEPTH float YES +// +ps_4_0 +dcl_constantbuffer CB0[2], immediateIndexed +dcl_output o0.xyzw +dcl_output o1.xyzw +dcl_output o2.xyzw +dcl_output o3.xyzw +dcl_output o4.xyzw +dcl_output o5.xyzw +dcl_output oDepth +mov o0.xyzw, cb0[0].xyzw +mov o1.xyzw, cb0[0].xyzw +mov o2.xyzw, cb0[0].xyzw +mov o3.xyzw, cb0[0].xyzw +mov o4.xyzw, cb0[0].xyzw +mov o5.xyzw, cb0[0].xyzw +mov oDepth, cb0[1].x +ret +// Approximately 8 instruction slots used +#endif + +const BYTE g_PS_ClearUint6[] = { + 68, 88, 66, 67, 78, 113, 96, 10, 75, 203, 142, 20, 121, 52, 202, 19, 182, 137, 113, + 117, 1, 0, 0, 0, 208, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, 60, 2, 0, 0, 84, 3, 0, 0, 82, 68, 69, 70, 0, + 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104, + 68, 97, 116, 97, 85, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0, + 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0, + 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200, + 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 85, 105, 110, 116, 0, 171, + 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97, + 108, 117, 101, 70, 95, 85, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, + 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79, + 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 196, 0, 0, 0, 7, 0, 0, 0, + 8, 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 15, 0, 0, 0, 176, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 176, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, + 176, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, + 0, 15, 0, 0, 0, 176, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 176, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 186, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 1, 14, 0, + 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 83, 86, 95, 68, 69, 80, 84, 72, + 0, 171, 83, 72, 68, 82, 16, 1, 0, 0, 64, 0, 0, 0, 68, 0, 0, 0, 89, + 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, + 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, + 16, 0, 3, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 4, 0, 0, 0, 101, + 0, 0, 3, 242, 32, 16, 0, 5, 0, 0, 0, 101, 0, 0, 2, 1, 192, 0, 0, + 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0, 0, 0, 70, 142, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 2, + 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, + 242, 32, 16, 0, 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 0, 0, 6, 242, 32, 16, 0, 4, 0, 0, 0, 70, 142, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 5, 0, 0, 0, 70, + 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 1, 192, 0, 0, + 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, + 84, 116, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 7, 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, 0, + 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps7.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps7.h new file mode 100644 index 0000000000..95987043f2 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps7.h @@ -0,0 +1,122 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer ColorAndDepthDataUint +// { +// +// uint4 color_Uint; // Offset: 0 Size: 16 +// float zValueF_Uint; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// ColorAndDepthDataUint cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// SV_TARGET 1 xyzw 1 TARGET uint xyzw +// SV_TARGET 2 xyzw 2 TARGET uint xyzw +// SV_TARGET 3 xyzw 3 TARGET uint xyzw +// SV_TARGET 4 xyzw 4 TARGET uint xyzw +// SV_TARGET 5 xyzw 5 TARGET uint xyzw +// SV_TARGET 6 xyzw 6 TARGET uint xyzw +// SV_DEPTH 0 N/A oDepth DEPTH float YES +// +ps_4_0 +dcl_constantbuffer CB0[2], immediateIndexed +dcl_output o0.xyzw +dcl_output o1.xyzw +dcl_output o2.xyzw +dcl_output o3.xyzw +dcl_output o4.xyzw +dcl_output o5.xyzw +dcl_output o6.xyzw +dcl_output oDepth +mov o0.xyzw, cb0[0].xyzw +mov o1.xyzw, cb0[0].xyzw +mov o2.xyzw, cb0[0].xyzw +mov o3.xyzw, cb0[0].xyzw +mov o4.xyzw, cb0[0].xyzw +mov o5.xyzw, cb0[0].xyzw +mov o6.xyzw, cb0[0].xyzw +mov oDepth, cb0[1].x +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_ClearUint7[] = { + 68, 88, 66, 67, 187, 93, 194, 62, 133, 16, 185, 196, 51, 199, 55, 8, 8, 169, 14, + 118, 1, 0, 0, 0, 12, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, 84, 2, 0, 0, 144, 3, 0, 0, 82, 68, 69, 70, 0, + 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104, + 68, 97, 116, 97, 85, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0, + 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0, + 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200, + 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 85, 105, 110, 116, 0, 171, + 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97, + 108, 117, 101, 70, 95, 85, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, + 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79, + 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 220, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 15, 0, 0, 0, 200, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 200, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, + 200, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, + 0, 15, 0, 0, 0, 200, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 200, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 200, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, + 0, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 255, 255, + 255, 255, 1, 14, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 83, 86, 95, + 68, 69, 80, 84, 72, 0, 171, 83, 72, 68, 82, 52, 1, 0, 0, 64, 0, 0, 0, + 77, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, + 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0, 0, 101, + 0, 0, 3, 242, 32, 16, 0, 3, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, + 4, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 5, 0, 0, 0, 101, 0, 0, + 3, 242, 32, 16, 0, 6, 0, 0, 0, 101, 0, 0, 2, 1, 192, 0, 0, 54, 0, + 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 2, 0, 0, + 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, + 16, 0, 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 6, 242, 32, 16, 0, 4, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 5, 0, 0, 0, 70, 142, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 6, 0, + 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 1, + 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 8, 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, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 8, 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, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps8.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps8.h new file mode 100644 index 0000000000..c470ab47bf --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps8.h @@ -0,0 +1,128 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer ColorAndDepthDataUint +// { +// +// uint4 color_Uint; // Offset: 0 Size: 16 +// float zValueF_Uint; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// ColorAndDepthDataUint cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// SV_TARGET 1 xyzw 1 TARGET uint xyzw +// SV_TARGET 2 xyzw 2 TARGET uint xyzw +// SV_TARGET 3 xyzw 3 TARGET uint xyzw +// SV_TARGET 4 xyzw 4 TARGET uint xyzw +// SV_TARGET 5 xyzw 5 TARGET uint xyzw +// SV_TARGET 6 xyzw 6 TARGET uint xyzw +// SV_TARGET 7 xyzw 7 TARGET uint xyzw +// SV_DEPTH 0 N/A oDepth DEPTH float YES +// +ps_4_0 +dcl_constantbuffer CB0[2], immediateIndexed +dcl_output o0.xyzw +dcl_output o1.xyzw +dcl_output o2.xyzw +dcl_output o3.xyzw +dcl_output o4.xyzw +dcl_output o5.xyzw +dcl_output o6.xyzw +dcl_output o7.xyzw +dcl_output oDepth +mov o0.xyzw, cb0[0].xyzw +mov o1.xyzw, cb0[0].xyzw +mov o2.xyzw, cb0[0].xyzw +mov o3.xyzw, cb0[0].xyzw +mov o4.xyzw, cb0[0].xyzw +mov o5.xyzw, cb0[0].xyzw +mov o6.xyzw, cb0[0].xyzw +mov o7.xyzw, cb0[0].xyzw +mov oDepth, cb0[1].x +ret +// Approximately 10 instruction slots used +#endif + +const BYTE g_PS_ClearUint8[] = { + 68, 88, 66, 67, 206, 106, 135, 121, 179, 175, 105, 51, 32, 41, 211, 246, 201, 25, 75, + 237, 1, 0, 0, 0, 72, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, 108, 2, 0, 0, 204, 3, 0, 0, 82, 68, 69, 70, 0, + 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104, + 68, 97, 116, 97, 85, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0, + 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0, + 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200, + 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 85, 105, 110, 116, 0, 171, + 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97, + 108, 117, 101, 70, 95, 85, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, + 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79, + 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 244, 0, 0, 0, 9, 0, 0, 0, + 8, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 15, 0, 0, 0, 224, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 224, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, + 224, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, + 0, 15, 0, 0, 0, 224, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 224, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 224, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, + 0, 224, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 7, 0, + 0, 0, 15, 0, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 255, 255, 255, 255, 1, 14, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, + 84, 0, 83, 86, 95, 68, 69, 80, 84, 72, 0, 171, 83, 72, 68, 82, 88, 1, 0, + 0, 64, 0, 0, 0, 86, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 101, + 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, + 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 3, 0, 0, 0, 101, 0, 0, + 3, 242, 32, 16, 0, 4, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 5, 0, + 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 6, 0, 0, 0, 101, 0, 0, 3, 242, + 32, 16, 0, 7, 0, 0, 0, 101, 0, 0, 2, 1, 192, 0, 0, 54, 0, 0, 6, + 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 2, 0, 0, 0, 70, + 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, + 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 6, 242, 32, 16, 0, 4, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 5, 0, 0, 0, 70, 142, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 6, 0, 0, 0, + 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, + 0, 7, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 1, 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 62, + 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 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, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 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, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_2d_ps.h new file mode 100644 index 0000000000..215c315abf --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_2d_ps.h @@ -0,0 +1,76 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 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_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +mul o0.xyz, r0.wwww, r0.xxxx +mov o0.w, l(1.000000) +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_FtoF_PM_LUMA_2D[] = { + 68, 88, 66, 67, 196, 88, 192, 127, 243, 30, 81, 182, 148, 19, 99, 57, 115, 181, 138, + 146, 1, 0, 0, 0, 128, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 4, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 156, 0, 0, 0, 64, + 0, 0, 0, 39, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, + 88, 24, 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, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, + 0, 96, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 32, 16, 0, 0, 0, 0, + 0, 246, 15, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 62, + 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 1, 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, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_2darray_ps.h new file mode 100644 index 0000000000..6918bb1bb3 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_2darray_ps.h @@ -0,0 +1,86 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_2DArray texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +mul o0.xyz, r0.wwww, r0.xxxx +mov o0.w, l(1.000000) +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_FtoF_PM_LUMA_2DArray[] = { + 68, 88, 66, 67, 96, 91, 207, 234, 31, 106, 235, 231, 220, 198, 196, 200, 17, 9, 209, + 197, 1, 0, 0, 0, 240, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0, + 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 116, 2, 0, 0, 82, 68, 69, 70, 160, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 117, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 50, 68, + 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, + 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, + 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 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, 212, 0, 0, 0, 64, 0, + 0, 0, 53, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, + 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, + 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, + 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, + 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 32, 16, 0, 0, 0, 0, 0, 246, + 15, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 62, 0, 0, + 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 1, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_3d_ps.h new file mode 100644 index 0000000000..0c5f9d3b26 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_3d_ps.h @@ -0,0 +1,80 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_3D texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +mul o0.xyz, r0.wwww, r0.xxxx +mov o0.w, l(1.000000) +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_FtoF_PM_LUMA_3D[] = { + 68, 88, 66, 67, 241, 186, 22, 7, 74, 156, 103, 227, 226, 7, 140, 127, 65, 83, 2, + 111, 1, 0, 0, 0, 176, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 52, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 112, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 51, 68, + 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, 49, 48, + 46, 49, 0, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 156, 0, 0, 0, 64, 0, 0, 0, 39, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 7, 114, 32, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, + 6, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, + 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, + 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, 1, 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_2d_ps.h new file mode 100644 index 0000000000..5904f217e3 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_2d_ps.h @@ -0,0 +1,76 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 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_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +mul o0.xyz, r0.wwww, r0.xxxx +mov o0.w, r0.w +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_FtoF_PM_LUMAALPHA_2D[] = { + 68, 88, 66, 67, 101, 29, 108, 117, 250, 233, 255, 220, 65, 43, 102, 162, 164, 247, 189, + 112, 1, 0, 0, 0, 128, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 4, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 156, 0, 0, 0, 64, + 0, 0, 0, 39, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, + 88, 24, 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, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, + 0, 96, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 32, 16, 0, 0, 0, 0, + 0, 246, 15, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 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, 2, 0, 0, 0, 1, 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, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_2darray_ps.h new file mode 100644 index 0000000000..09d9bad5c0 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_2darray_ps.h @@ -0,0 +1,86 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_2DArray texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +mul o0.xyz, r0.wwww, r0.xxxx +mov o0.w, r0.w +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_FtoF_PM_LUMAALPHA_2DArray[] = { + 68, 88, 66, 67, 16, 148, 215, 158, 112, 164, 42, 84, 33, 70, 148, 190, 238, 94, 245, + 128, 1, 0, 0, 0, 240, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0, + 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 116, 2, 0, 0, 82, 68, 69, 70, 160, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 117, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 50, 68, + 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, + 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, + 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 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, 212, 0, 0, 0, 64, 0, + 0, 0, 53, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, + 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, + 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, + 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, + 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 32, 16, 0, 0, 0, 0, 0, 246, + 15, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 130, 32, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, + 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 1, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_3d_ps.h new file mode 100644 index 0000000000..d8ca1c845a --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_3d_ps.h @@ -0,0 +1,80 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_3D texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +mul o0.xyz, r0.wwww, r0.xxxx +mov o0.w, r0.w +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_FtoF_PM_LUMAALPHA_3D[] = { + 68, 88, 66, 67, 9, 39, 6, 28, 108, 109, 23, 108, 237, 131, 58, 1, 102, 159, 191, + 61, 1, 0, 0, 0, 176, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 52, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 112, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 51, 68, + 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, 49, 48, + 46, 49, 0, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 156, 0, 0, 0, 64, 0, 0, 0, 39, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 7, 114, 32, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, + 6, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 0, 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, 2, 0, 0, 0, 1, + 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, 1, 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_2d_ps.h new file mode 100644 index 0000000000..be18a987f8 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_2d_ps.h @@ -0,0 +1,76 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 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_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +mul o0.xyz, r0.wwww, r0.xyzx +mov o0.w, l(1.000000) +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_FtoF_PM_RGB_2D[] = { + 68, 88, 66, 67, 87, 204, 158, 94, 75, 152, 102, 217, 0, 88, 222, 29, 232, 182, 2, + 132, 1, 0, 0, 0, 128, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 4, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 156, 0, 0, 0, 64, + 0, 0, 0, 39, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, + 88, 24, 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, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, + 0, 96, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 32, 16, 0, 0, 0, 0, + 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 62, + 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 1, 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, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_2darray_ps.h new file mode 100644 index 0000000000..7f18036816 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_2darray_ps.h @@ -0,0 +1,86 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_2DArray texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +mul o0.xyz, r0.wwww, r0.xyzx +mov o0.w, l(1.000000) +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_FtoF_PM_RGB_2DArray[] = { + 68, 88, 66, 67, 73, 224, 127, 95, 171, 173, 116, 230, 242, 111, 205, 239, 210, 69, 91, + 238, 1, 0, 0, 0, 240, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0, + 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 116, 2, 0, 0, 82, 68, 69, 70, 160, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 117, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 50, 68, + 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, + 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, + 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 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, 212, 0, 0, 0, 64, 0, + 0, 0, 53, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, + 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, + 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, + 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, + 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 32, 16, 0, 0, 0, 0, 0, 246, + 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 62, 0, 0, + 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 1, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_3d_ps.h new file mode 100644 index 0000000000..78ed86a6cf --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_3d_ps.h @@ -0,0 +1,80 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_3D texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +mul o0.xyz, r0.wwww, r0.xyzx +mov o0.w, l(1.000000) +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_FtoF_PM_RGB_3D[] = { + 68, 88, 66, 67, 188, 235, 5, 90, 236, 180, 172, 101, 155, 220, 117, 214, 110, 8, 67, + 121, 1, 0, 0, 0, 176, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 52, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 112, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 51, 68, + 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, 49, 48, + 46, 49, 0, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 156, 0, 0, 0, 64, 0, 0, 0, 39, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 7, 114, 32, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, + 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, + 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, 1, 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_565_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_565_2d_ps.h new file mode 100644 index 0000000000..05af034cf3 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_565_2d_ps.h @@ -0,0 +1,84 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 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_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +mul r0.xyz, r0.wwww, r0.xyzx +mul r0.xyz, r0.xyzx, l(31.000000, 63.000000, 31.000000, 0.000000) +round_ne r0.xyz, r0.xyzx +mul o0.xyz, r0.xyzx, l(0.032258, 0.015873, 0.032258, 0.000000) +mov o0.w, l(1.000000) +ret +// Approximately 7 instruction slots used +#endif + +const BYTE g_PS_FtoF_PM_RGB_565_2D[] = { + 68, 88, 66, 67, 107, 29, 4, 204, 154, 16, 239, 118, 140, 65, 255, 118, 32, 171, 247, + 239, 1, 0, 0, 0, 228, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 104, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 0, 1, 0, 0, 64, + 0, 0, 0, 64, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, + 88, 24, 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, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, + 0, 96, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, + 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, + 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 248, 65, 0, 0, 124, 66, 0, 0, 248, 65, 0, 0, 0, 0, + 64, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, + 0, 56, 0, 0, 10, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 8, 33, 4, 61, 33, 8, 130, 60, 8, 33, 4, 61, 0, + 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 7, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 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, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_565_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_565_2darray_ps.h new file mode 100644 index 0000000000..af5eb349ba --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_565_2darray_ps.h @@ -0,0 +1,94 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_2DArray texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +mul r0.xyz, r0.wwww, r0.xyzx +mul r0.xyz, r0.xyzx, l(31.000000, 63.000000, 31.000000, 0.000000) +round_ne r0.xyz, r0.xyzx +mul o0.xyz, r0.xyzx, l(0.032258, 0.015873, 0.032258, 0.000000) +mov o0.w, l(1.000000) +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_FtoF_PM_RGB_565_2DArray[] = { + 68, 88, 66, 67, 45, 176, 85, 221, 234, 218, 205, 113, 163, 153, 221, 15, 166, 157, 230, + 200, 1, 0, 0, 0, 84, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0, + 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 216, 2, 0, 0, 82, 68, 69, 70, 160, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 117, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 50, 68, + 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, + 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, + 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 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, 56, 1, 0, 0, 64, 0, + 0, 0, 78, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, + 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, + 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, + 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, + 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, 0, 246, + 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, + 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 248, 65, 0, 0, 124, 66, 0, 0, 248, 65, 0, 0, 0, 0, 64, 0, + 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 10, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 8, 33, 4, 61, 33, 8, 130, 60, 8, 33, 4, 61, 0, 0, 0, + 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 9, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 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, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_565_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_565_3d_ps.h new file mode 100644 index 0000000000..bf02050d89 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_565_3d_ps.h @@ -0,0 +1,88 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_3D texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +mul r0.xyz, r0.wwww, r0.xyzx +mul r0.xyz, r0.xyzx, l(31.000000, 63.000000, 31.000000, 0.000000) +round_ne r0.xyz, r0.xyzx +mul o0.xyz, r0.xyzx, l(0.032258, 0.015873, 0.032258, 0.000000) +mov o0.w, l(1.000000) +ret +// Approximately 7 instruction slots used +#endif + +const BYTE g_PS_FtoF_PM_RGB_565_3D[] = { + 68, 88, 66, 67, 72, 210, 100, 140, 147, 53, 29, 56, 170, 112, 233, 37, 175, 201, 198, + 250, 1, 0, 0, 0, 20, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 152, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 112, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 51, 68, + 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, 49, 48, + 46, 49, 0, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 0, 1, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, + 124, 66, 0, 0, 248, 65, 0, 0, 0, 0, 64, 0, 0, 5, 114, 0, 16, 0, 0, + 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 32, 16, 0, + 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 33, 4, + 61, 33, 8, 130, 60, 8, 33, 4, 61, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 62, 0, 0, 1, 83, + 84, 65, 84, 116, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 4, 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, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_2d_ps.h new file mode 100644 index 0000000000..68712ef7f5 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_2d_ps.h @@ -0,0 +1,76 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 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_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +mul o0.xyz, r0.wwww, r0.xyzx +mov o0.w, r0.w +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_FtoF_PM_RGBA_2D[] = { + 68, 88, 66, 67, 132, 105, 208, 138, 186, 182, 112, 82, 173, 16, 240, 222, 116, 72, 178, + 126, 1, 0, 0, 0, 128, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 4, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 156, 0, 0, 0, 64, + 0, 0, 0, 39, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, + 88, 24, 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, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, + 0, 96, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 32, 16, 0, 0, 0, 0, + 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 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, 2, 0, 0, 0, 1, 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, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_2darray_ps.h new file mode 100644 index 0000000000..2f0b59abe0 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_2darray_ps.h @@ -0,0 +1,86 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_2DArray texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +mul o0.xyz, r0.wwww, r0.xyzx +mov o0.w, r0.w +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_FtoF_PM_RGBA_2DArray[] = { + 68, 88, 66, 67, 61, 17, 53, 94, 235, 123, 58, 146, 86, 204, 96, 4, 97, 221, 95, + 134, 1, 0, 0, 0, 240, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0, + 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 116, 2, 0, 0, 82, 68, 69, 70, 160, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 117, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 50, 68, + 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, + 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, + 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 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, 212, 0, 0, 0, 64, 0, + 0, 0, 53, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, + 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, + 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, + 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, + 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 32, 16, 0, 0, 0, 0, 0, 246, + 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 130, 32, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, + 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 1, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_3d_ps.h new file mode 100644 index 0000000000..62d18d62db --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_3d_ps.h @@ -0,0 +1,80 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_3D texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +mul o0.xyz, r0.wwww, r0.xyzx +mov o0.w, r0.w +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_FtoF_PM_RGBA_3D[] = { + 68, 88, 66, 67, 80, 173, 64, 240, 1, 143, 85, 115, 221, 254, 89, 145, 213, 191, 49, + 141, 1, 0, 0, 0, 176, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 52, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 112, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 51, 68, + 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, 49, 48, + 46, 49, 0, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 156, 0, 0, 0, 64, 0, 0, 0, 39, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 7, 114, 32, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 0, 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, 2, 0, 0, 0, 1, + 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, 1, 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_4444_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_4444_2d_ps.h new file mode 100644 index 0000000000..62e59d2e4e --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_4444_2d_ps.h @@ -0,0 +1,82 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 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_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +mul r0.xyz, r0.wwww, r0.xyzx +mul r0.xyzw, r0.xyzw, l(15.000000, 15.000000, 15.000000, 15.000000) +round_ne r0.xyzw, r0.xyzw +mul o0.xyzw, r0.xyzw, l(0.066667, 0.066667, 0.066667, 0.066667) +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_FtoF_PM_RGBA_4444_2D[] = { + 68, 88, 66, 67, 52, 89, 222, 242, 25, 197, 40, 54, 79, 232, 156, 234, 251, 41, 41, + 226, 1, 0, 0, 0, 208, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 84, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 236, 0, 0, 0, 64, + 0, 0, 0, 59, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, + 88, 24, 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, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, + 0, 96, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, + 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, + 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, 65, + 64, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, + 0, 56, 0, 0, 10, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 137, 136, 136, 61, 137, 136, 136, 61, 137, 136, 136, 61, 137, + 136, 136, 61, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_4444_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_4444_2darray_ps.h new file mode 100644 index 0000000000..ebfce59f6a --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_4444_2darray_ps.h @@ -0,0 +1,92 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_2DArray texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +mul r0.xyz, r0.wwww, r0.xyzx +mul r0.xyzw, r0.xyzw, l(15.000000, 15.000000, 15.000000, 15.000000) +round_ne r0.xyzw, r0.xyzw +mul o0.xyzw, r0.xyzw, l(0.066667, 0.066667, 0.066667, 0.066667) +ret +// Approximately 8 instruction slots used +#endif + +const BYTE g_PS_FtoF_PM_RGBA_4444_2DArray[] = { + 68, 88, 66, 67, 119, 1, 180, 34, 213, 167, 228, 86, 205, 242, 230, 17, 87, 32, 74, + 6, 1, 0, 0, 0, 64, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0, + 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 196, 2, 0, 0, 82, 68, 69, 70, 160, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 117, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 50, 68, + 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, + 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, + 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 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, 36, 1, 0, 0, 64, 0, + 0, 0, 73, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, + 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, + 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, + 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, + 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, 0, 246, + 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, + 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, 65, 64, 0, + 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 10, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 137, 136, 136, 61, 137, 136, 136, 61, 137, 136, 136, 61, 137, 136, 136, + 61, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 8, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 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, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_4444_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_4444_3d_ps.h new file mode 100644 index 0000000000..a5dd42a2a7 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_4444_3d_ps.h @@ -0,0 +1,86 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_3D texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +mul r0.xyz, r0.wwww, r0.xyzx +mul r0.xyzw, r0.xyzw, l(15.000000, 15.000000, 15.000000, 15.000000) +round_ne r0.xyzw, r0.xyzw +mul o0.xyzw, r0.xyzw, l(0.066667, 0.066667, 0.066667, 0.066667) +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_FtoF_PM_RGBA_4444_3D[] = { + 68, 88, 66, 67, 233, 160, 206, 221, 201, 110, 121, 251, 163, 213, 234, 30, 171, 187, 79, + 242, 1, 0, 0, 0, 0, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 132, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 112, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 51, 68, + 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, 49, 48, + 46, 49, 0, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 236, 0, 0, 0, 64, 0, 0, 0, 59, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 112, 65, 0, 0, + 112, 65, 0, 0, 112, 65, 0, 0, 112, 65, 64, 0, 0, 5, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 32, 16, 0, + 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 137, 136, 136, + 61, 137, 136, 136, 61, 137, 136, 136, 61, 137, 136, 136, 61, 62, 0, 0, 1, 83, 84, + 65, 84, 116, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 4, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_5551_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_5551_2d_ps.h new file mode 100644 index 0000000000..fca424ebc2 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_5551_2d_ps.h @@ -0,0 +1,82 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 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_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +mul r0.xyz, r0.wwww, r0.xyzx +mul r0.xyzw, r0.xyzw, l(31.000000, 31.000000, 31.000000, 1.000000) +round_ne r0.xyzw, r0.xyzw +mul o0.xyzw, r0.xyzw, l(0.032258, 0.032258, 0.032258, 1.000000) +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_FtoF_PM_RGBA_5551_2D[] = { + 68, 88, 66, 67, 157, 187, 40, 209, 230, 225, 190, 246, 40, 140, 167, 190, 61, 115, 94, + 70, 1, 0, 0, 0, 208, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 84, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 236, 0, 0, 0, 64, + 0, 0, 0, 59, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, + 88, 24, 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, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, + 0, 96, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, + 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, + 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, 128, 63, + 64, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, + 0, 56, 0, 0, 10, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 8, 33, 4, 61, 8, 33, 4, 61, 8, 33, 4, 61, 0, + 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_5551_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_5551_2darray_ps.h new file mode 100644 index 0000000000..ee5c7d6e27 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_5551_2darray_ps.h @@ -0,0 +1,92 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_2DArray texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +mul r0.xyz, r0.wwww, r0.xyzx +mul r0.xyzw, r0.xyzw, l(31.000000, 31.000000, 31.000000, 1.000000) +round_ne r0.xyzw, r0.xyzw +mul o0.xyzw, r0.xyzw, l(0.032258, 0.032258, 0.032258, 1.000000) +ret +// Approximately 8 instruction slots used +#endif + +const BYTE g_PS_FtoF_PM_RGBA_5551_2DArray[] = { + 68, 88, 66, 67, 66, 21, 128, 163, 11, 21, 65, 137, 107, 224, 148, 78, 244, 169, 148, + 247, 1, 0, 0, 0, 64, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0, + 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 196, 2, 0, 0, 82, 68, 69, 70, 160, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 117, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 50, 68, + 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, + 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, + 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 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, 36, 1, 0, 0, 64, 0, + 0, 0, 73, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, + 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, + 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, + 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, + 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, 0, 246, + 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, + 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, 128, 63, 64, 0, + 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 10, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 8, 33, 4, 61, 8, 33, 4, 61, 8, 33, 4, 61, 0, 0, 128, + 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 8, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 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, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_5551_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_5551_3d_ps.h new file mode 100644 index 0000000000..f4b47c002f --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_5551_3d_ps.h @@ -0,0 +1,86 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_3D texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +mul r0.xyz, r0.wwww, r0.xyzx +mul r0.xyzw, r0.xyzw, l(31.000000, 31.000000, 31.000000, 1.000000) +round_ne r0.xyzw, r0.xyzw +mul o0.xyzw, r0.xyzw, l(0.032258, 0.032258, 0.032258, 1.000000) +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_FtoF_PM_RGBA_5551_3D[] = { + 68, 88, 66, 67, 74, 0, 199, 89, 200, 147, 93, 64, 244, 239, 156, 102, 110, 132, 22, + 10, 1, 0, 0, 0, 0, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 132, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 112, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 51, 68, + 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, 49, 48, + 46, 49, 0, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 236, 0, 0, 0, 64, 0, 0, 0, 59, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, + 248, 65, 0, 0, 248, 65, 0, 0, 128, 63, 64, 0, 0, 5, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 32, 16, 0, + 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 33, 4, + 61, 8, 33, 4, 61, 8, 33, 4, 61, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, + 65, 84, 116, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 4, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_2d_ps.h new file mode 100644 index 0000000000..a0023c0013 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_2d_ps.h @@ -0,0 +1,82 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 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_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 2 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r0.w, r0.x, r0.w +movc o0.xyz, r1.xxxx, r0.wwww, r0.xyzx +mov o0.w, l(1.000000) +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_FtoF_UM_LUMA_2D[] = { + 68, 88, 66, 67, 75, 92, 229, 222, 23, 169, 5, 92, 146, 12, 107, 229, 137, 155, 179, + 250, 1, 0, 0, 0, 192, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 68, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 220, 0, 0, 0, 64, + 0, 0, 0, 55, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, + 88, 24, 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, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, + 0, 96, 16, 0, 0, 0, 0, 0, 49, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, + 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 32, 16, 0, 0, 0, 0, 0, + 6, 0, 16, 0, 1, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, + 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 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, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, + 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_2darray_ps.h new file mode 100644 index 0000000000..4ad691bef4 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_2darray_ps.h @@ -0,0 +1,91 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_2DArray texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 2 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r0.w, r0.x, r0.w +movc o0.xyz, r1.xxxx, r0.wwww, r0.xyzx +mov o0.w, l(1.000000) +ret +// Approximately 8 instruction slots used +#endif + +const BYTE g_PS_FtoF_UM_LUMA_2DArray[] = { + 68, 88, 66, 67, 2, 234, 137, 29, 211, 208, 186, 172, 235, 8, 55, 155, 195, 91, 134, + 133, 1, 0, 0, 0, 48, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0, + 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 180, 2, 0, 0, 82, 68, 69, 70, 160, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 117, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 50, 68, + 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, + 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, + 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 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, 20, 1, 0, 0, 64, 0, + 0, 0, 69, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, + 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, + 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 2, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, + 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, + 16, 0, 0, 0, 0, 0, 49, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, 0, 7, + 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, + 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 32, 16, 0, 0, 0, 0, 0, 6, 0, + 16, 0, 1, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, + 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 8, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 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, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 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, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_3d_ps.h new file mode 100644 index 0000000000..4eed8c15ba --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_3d_ps.h @@ -0,0 +1,85 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_3D texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 2 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r0.w, r0.x, r0.w +movc o0.xyz, r1.xxxx, r0.wwww, r0.xyzx +mov o0.w, l(1.000000) +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_FtoF_UM_LUMA_3D[] = { + 68, 88, 66, 67, 120, 214, 14, 47, 69, 88, 46, 178, 8, 214, 190, 124, 42, 131, 170, + 151, 1, 0, 0, 0, 240, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 116, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 112, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 51, 68, + 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, 49, 48, + 46, 49, 0, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 220, 0, 0, 0, 64, 0, 0, 0, 55, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 2, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 49, + 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 55, 0, + 0, 9, 114, 32, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 246, + 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 62, 0, 0, + 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 2, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_2d_ps.h new file mode 100644 index 0000000000..7501fae643 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_2d_ps.h @@ -0,0 +1,82 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 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_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 2 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r1.y, r0.x, r0.w +movc o0.xyz, r1.xxxx, r1.yyyy, r0.xyzx +mov o0.w, r0.w +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_FtoF_UM_LUMAALPHA_2D[] = { + 68, 88, 66, 67, 190, 69, 123, 211, 19, 130, 132, 1, 132, 116, 62, 1, 233, 115, 38, + 22, 1, 0, 0, 0, 192, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 68, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 220, 0, 0, 0, 64, + 0, 0, 0, 55, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, + 88, 24, 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, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, + 0, 96, 16, 0, 0, 0, 0, 0, 49, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, + 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 32, 16, 0, 0, 0, 0, 0, + 6, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, 2, 16, + 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 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, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, + 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_2darray_ps.h new file mode 100644 index 0000000000..40eb1f480c --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_2darray_ps.h @@ -0,0 +1,91 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_2DArray texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 2 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r1.y, r0.x, r0.w +movc o0.xyz, r1.xxxx, r1.yyyy, r0.xyzx +mov o0.w, r0.w +ret +// Approximately 8 instruction slots used +#endif + +const BYTE g_PS_FtoF_UM_LUMAALPHA_2DArray[] = { + 68, 88, 66, 67, 222, 131, 31, 168, 174, 145, 73, 243, 164, 132, 216, 2, 103, 0, 142, + 101, 1, 0, 0, 0, 48, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0, + 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 180, 2, 0, 0, 82, 68, 69, 70, 160, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 117, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 50, 68, + 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, + 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, + 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 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, 20, 1, 0, 0, 64, 0, + 0, 0, 69, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, + 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, + 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 2, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, + 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, + 16, 0, 0, 0, 0, 0, 49, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, 0, 7, + 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, + 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 32, 16, 0, 0, 0, 0, 0, 6, 0, + 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, + 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 8, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 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, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 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, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_3d_ps.h new file mode 100644 index 0000000000..f6bbc8cc01 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_3d_ps.h @@ -0,0 +1,85 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_3D texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 2 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r1.y, r0.x, r0.w +movc o0.xyz, r1.xxxx, r1.yyyy, r0.xyzx +mov o0.w, r0.w +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_FtoF_UM_LUMAALPHA_3D[] = { + 68, 88, 66, 67, 160, 196, 1, 185, 15, 156, 153, 67, 85, 102, 198, 128, 138, 216, 238, + 143, 1, 0, 0, 0, 240, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 116, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 112, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 51, 68, + 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, 49, 48, + 46, 49, 0, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 220, 0, 0, 0, 64, 0, 0, 0, 55, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 2, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 49, + 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 55, 0, + 0, 9, 114, 32, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 86, + 5, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 130, 32, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, + 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 2, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_2d_ps.h new file mode 100644 index 0000000000..ce44a394d7 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_2d_ps.h @@ -0,0 +1,82 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 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_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 2 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r1.yzw, r0.xxyz, r0.wwww +movc o0.xyz, r1.xxxx, r1.yzwy, r0.xyzx +mov o0.w, l(1.000000) +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_FtoF_UM_RGB_2D[] = { + 68, 88, 66, 67, 93, 55, 14, 204, 55, 114, 238, 111, 6, 213, 4, 64, 58, 99, 168, + 104, 1, 0, 0, 0, 192, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 68, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 220, 0, 0, 0, 64, + 0, 0, 0, 55, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, + 88, 24, 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, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, + 0, 96, 16, 0, 0, 0, 0, 0, 49, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, + 0, 7, 226, 0, 16, 0, 1, 0, 0, 0, 6, 9, 16, 0, 0, 0, 0, 0, 246, + 15, 16, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 32, 16, 0, 0, 0, 0, 0, + 6, 0, 16, 0, 1, 0, 0, 0, 150, 7, 16, 0, 1, 0, 0, 0, 70, 2, 16, + 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 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, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, + 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_2darray_ps.h new file mode 100644 index 0000000000..ea38e2e559 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_2darray_ps.h @@ -0,0 +1,91 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_2DArray texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 2 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r1.yzw, r0.xxyz, r0.wwww +movc o0.xyz, r1.xxxx, r1.yzwy, r0.xyzx +mov o0.w, l(1.000000) +ret +// Approximately 8 instruction slots used +#endif + +const BYTE g_PS_FtoF_UM_RGB_2DArray[] = { + 68, 88, 66, 67, 224, 13, 199, 125, 145, 168, 88, 56, 242, 2, 144, 118, 87, 186, 241, + 248, 1, 0, 0, 0, 48, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0, + 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 180, 2, 0, 0, 82, 68, 69, 70, 160, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 117, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 50, 68, + 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, + 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, + 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 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, 20, 1, 0, 0, 64, 0, + 0, 0, 69, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, + 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, + 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 2, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, + 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, + 16, 0, 0, 0, 0, 0, 49, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, 0, 7, + 226, 0, 16, 0, 1, 0, 0, 0, 6, 9, 16, 0, 0, 0, 0, 0, 246, 15, 16, + 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 32, 16, 0, 0, 0, 0, 0, 6, 0, + 16, 0, 1, 0, 0, 0, 150, 7, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, + 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 8, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 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, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 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, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_3d_ps.h new file mode 100644 index 0000000000..da862eb119 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_3d_ps.h @@ -0,0 +1,85 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_3D texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 2 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r1.yzw, r0.xxyz, r0.wwww +movc o0.xyz, r1.xxxx, r1.yzwy, r0.xyzx +mov o0.w, l(1.000000) +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_FtoF_UM_RGB_3D[] = { + 68, 88, 66, 67, 200, 37, 175, 150, 106, 41, 102, 69, 21, 246, 40, 148, 142, 99, 101, + 71, 1, 0, 0, 0, 240, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 116, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 112, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 51, 68, + 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, 49, 48, + 46, 49, 0, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 220, 0, 0, 0, 64, 0, 0, 0, 55, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 2, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 49, + 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, 0, 7, 226, 0, 16, 0, 1, 0, 0, + 0, 6, 9, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 55, 0, + 0, 9, 114, 32, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 150, + 7, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 62, 0, 0, + 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 2, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_565_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_565_2d_ps.h new file mode 100644 index 0000000000..5996ba335e --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_565_2d_ps.h @@ -0,0 +1,90 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 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_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 2 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r1.yzw, r0.xxyz, r0.wwww +movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx +mul r0.xyz, r0.xyzx, l(31.000000, 63.000000, 31.000000, 0.000000) +round_ne r0.xyz, r0.xyzx +mul o0.xyz, r0.xyzx, l(0.032258, 0.015873, 0.032258, 0.000000) +mov o0.w, l(1.000000) +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_FtoF_UM_RGB_565_2D[] = { + 68, 88, 66, 67, 120, 138, 72, 172, 147, 159, 222, 80, 129, 231, 133, 236, 125, 211, 201, + 82, 1, 0, 0, 0, 36, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 168, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 64, 1, 0, 0, 64, + 0, 0, 0, 80, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, + 88, 24, 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, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, + 0, 96, 16, 0, 0, 0, 0, 0, 49, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, + 0, 7, 226, 0, 16, 0, 1, 0, 0, 0, 6, 9, 16, 0, 0, 0, 0, 0, 246, + 15, 16, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 0, 0, 0, 0, + 6, 0, 16, 0, 1, 0, 0, 0, 150, 7, 16, 0, 1, 0, 0, 0, 70, 2, 16, + 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, + 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 124, 66, 0, + 0, 248, 65, 0, 0, 0, 0, 64, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 32, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 33, 4, 61, 33, 8, + 130, 60, 8, 33, 4, 61, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, + 116, 0, 0, 0, 9, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 5, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 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, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_565_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_565_2darray_ps.h new file mode 100644 index 0000000000..b36c06adb0 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_565_2darray_ps.h @@ -0,0 +1,100 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_2DArray texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 2 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r1.yzw, r0.xxyz, r0.wwww +movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx +mul r0.xyz, r0.xyzx, l(31.000000, 63.000000, 31.000000, 0.000000) +round_ne r0.xyz, r0.xyzx +mul o0.xyz, r0.xyzx, l(0.032258, 0.015873, 0.032258, 0.000000) +mov o0.w, l(1.000000) +ret +// Approximately 11 instruction slots used +#endif + +const BYTE g_PS_FtoF_UM_RGB_565_2DArray[] = { + 68, 88, 66, 67, 44, 2, 174, 208, 118, 237, 233, 207, 57, 29, 178, 223, 138, 140, 88, + 102, 1, 0, 0, 0, 148, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0, + 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 24, 3, 0, 0, 82, 68, 69, 70, 160, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 117, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 50, 68, + 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, + 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, + 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 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, 120, 1, 0, 0, 64, 0, + 0, 0, 94, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, + 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, + 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 2, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, + 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, + 16, 0, 0, 0, 0, 0, 49, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, 0, 7, + 226, 0, 16, 0, 1, 0, 0, 0, 6, 9, 16, 0, 0, 0, 0, 0, 246, 15, 16, + 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 0, 0, 0, 0, 6, 0, + 16, 0, 1, 0, 0, 0, 150, 7, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, + 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 124, 66, 0, 0, 248, + 65, 0, 0, 0, 0, 64, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, + 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 32, 16, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 33, 4, 61, 33, 8, 130, 60, + 8, 33, 4, 61, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, + 0, 0, 11, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 5, + 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 1, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_565_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_565_3d_ps.h new file mode 100644 index 0000000000..8de8d85d37 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_565_3d_ps.h @@ -0,0 +1,93 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_3D texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 2 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r1.yzw, r0.xxyz, r0.wwww +movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx +mul r0.xyz, r0.xyzx, l(31.000000, 63.000000, 31.000000, 0.000000) +round_ne r0.xyz, r0.xyzx +mul o0.xyz, r0.xyzx, l(0.032258, 0.015873, 0.032258, 0.000000) +mov o0.w, l(1.000000) +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_FtoF_UM_RGB_565_3D[] = { + 68, 88, 66, 67, 250, 168, 68, 191, 15, 51, 156, 108, 63, 18, 251, 133, 207, 174, 26, + 44, 1, 0, 0, 0, 84, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 216, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 112, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 51, 68, + 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, 49, 48, + 46, 49, 0, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 64, 1, 0, 0, 64, 0, 0, 0, 80, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 2, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 49, + 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, 0, 7, 226, 0, 16, 0, 1, 0, 0, + 0, 6, 9, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 55, 0, + 0, 9, 114, 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 150, + 7, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, + 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 248, 65, 0, 0, 124, 66, 0, 0, 248, 65, 0, 0, 0, 0, 64, 0, + 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 10, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 8, 33, 4, 61, 33, 8, 130, 60, 8, 33, 4, 61, 0, 0, 0, + 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 9, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 5, 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, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_2d_ps.h new file mode 100644 index 0000000000..764b560d78 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_2d_ps.h @@ -0,0 +1,82 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 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_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 2 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r1.yzw, r0.xxyz, r0.wwww +movc o0.xyz, r1.xxxx, r1.yzwy, r0.xyzx +mov o0.w, r0.w +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_FtoF_UM_RGBA_2D[] = { + 68, 88, 66, 67, 43, 116, 27, 96, 239, 39, 33, 81, 44, 127, 180, 166, 1, 156, 105, + 167, 1, 0, 0, 0, 192, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 68, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 220, 0, 0, 0, 64, + 0, 0, 0, 55, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, + 88, 24, 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, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, + 0, 96, 16, 0, 0, 0, 0, 0, 49, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, + 0, 7, 226, 0, 16, 0, 1, 0, 0, 0, 6, 9, 16, 0, 0, 0, 0, 0, 246, + 15, 16, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 32, 16, 0, 0, 0, 0, 0, + 6, 0, 16, 0, 1, 0, 0, 0, 150, 7, 16, 0, 1, 0, 0, 0, 70, 2, 16, + 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 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, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, + 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_2darray_ps.h new file mode 100644 index 0000000000..84cf6ebefa --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_2darray_ps.h @@ -0,0 +1,91 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_2DArray texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 2 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r1.yzw, r0.xxyz, r0.wwww +movc o0.xyz, r1.xxxx, r1.yzwy, r0.xyzx +mov o0.w, r0.w +ret +// Approximately 8 instruction slots used +#endif + +const BYTE g_PS_FtoF_UM_RGBA_2DArray[] = { + 68, 88, 66, 67, 226, 210, 183, 205, 237, 244, 131, 11, 158, 229, 134, 100, 181, 52, 86, + 124, 1, 0, 0, 0, 48, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0, + 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 180, 2, 0, 0, 82, 68, 69, 70, 160, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 117, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 50, 68, + 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, + 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, + 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 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, 20, 1, 0, 0, 64, 0, + 0, 0, 69, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, + 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, + 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 2, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, + 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, + 16, 0, 0, 0, 0, 0, 49, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, 0, 7, + 226, 0, 16, 0, 1, 0, 0, 0, 6, 9, 16, 0, 0, 0, 0, 0, 246, 15, 16, + 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 32, 16, 0, 0, 0, 0, 0, 6, 0, + 16, 0, 1, 0, 0, 0, 150, 7, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, + 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 8, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 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, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 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, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_3d_ps.h new file mode 100644 index 0000000000..d0725735e4 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_3d_ps.h @@ -0,0 +1,85 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_3D texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 2 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r1.yzw, r0.xxyz, r0.wwww +movc o0.xyz, r1.xxxx, r1.yzwy, r0.xyzx +mov o0.w, r0.w +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_FtoF_UM_RGBA_3D[] = { + 68, 88, 66, 67, 47, 35, 68, 46, 230, 212, 160, 221, 21, 19, 140, 22, 115, 9, 100, + 58, 1, 0, 0, 0, 240, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 116, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 112, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 51, 68, + 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, 49, 48, + 46, 49, 0, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 220, 0, 0, 0, 64, 0, 0, 0, 55, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 2, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 49, + 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, 0, 7, 226, 0, 16, 0, 1, 0, 0, + 0, 6, 9, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 55, 0, + 0, 9, 114, 32, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 150, + 7, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 130, 32, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, + 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 2, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_4444_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_4444_2d_ps.h new file mode 100644 index 0000000000..cfa23a7bf9 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_4444_2d_ps.h @@ -0,0 +1,88 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 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_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 2 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r1.yzw, r0.xxyz, r0.wwww +movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx +mul r0.xyzw, r0.xyzw, l(15.000000, 15.000000, 15.000000, 15.000000) +round_ne r0.xyzw, r0.xyzw +mul o0.xyzw, r0.xyzw, l(0.066667, 0.066667, 0.066667, 0.066667) +ret +// Approximately 8 instruction slots used +#endif + +const BYTE g_PS_FtoF_UM_RGBA_4444_2D[] = { + 68, 88, 66, 67, 233, 41, 159, 52, 49, 178, 50, 48, 148, 28, 18, 200, 140, 164, 4, + 13, 1, 0, 0, 0, 16, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 148, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 44, 1, 0, 0, 64, + 0, 0, 0, 75, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, + 88, 24, 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, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, + 0, 96, 16, 0, 0, 0, 0, 0, 49, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, + 0, 7, 226, 0, 16, 0, 1, 0, 0, 0, 6, 9, 16, 0, 0, 0, 0, 0, 246, + 15, 16, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 0, 0, 0, 0, + 6, 0, 16, 0, 1, 0, 0, 0, 150, 7, 16, 0, 1, 0, 0, 0, 70, 2, 16, + 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, + 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 112, 65, 0, 0, 112, 65, 0, + 0, 112, 65, 0, 0, 112, 65, 64, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 32, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 137, 136, 136, 61, 137, 136, + 136, 61, 137, 136, 136, 61, 137, 136, 136, 61, 62, 0, 0, 1, 83, 84, 65, 84, 116, + 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 5, 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, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_4444_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_4444_2darray_ps.h new file mode 100644 index 0000000000..1a08e60147 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_4444_2darray_ps.h @@ -0,0 +1,98 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_2DArray texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 2 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r1.yzw, r0.xxyz, r0.wwww +movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx +mul r0.xyzw, r0.xyzw, l(15.000000, 15.000000, 15.000000, 15.000000) +round_ne r0.xyzw, r0.xyzw +mul o0.xyzw, r0.xyzw, l(0.066667, 0.066667, 0.066667, 0.066667) +ret +// Approximately 10 instruction slots used +#endif + +const BYTE g_PS_FtoF_UM_RGBA_4444_2DArray[] = { + 68, 88, 66, 67, 51, 224, 15, 241, 219, 215, 90, 241, 40, 140, 3, 53, 152, 74, 169, + 200, 1, 0, 0, 0, 128, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0, + 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 4, 3, 0, 0, 82, 68, 69, 70, 160, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 117, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 50, 68, + 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, + 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, + 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 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, 100, 1, 0, 0, 64, 0, + 0, 0, 89, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, + 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, + 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 2, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, + 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, + 16, 0, 0, 0, 0, 0, 49, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, 0, 7, + 226, 0, 16, 0, 1, 0, 0, 0, 6, 9, 16, 0, 0, 0, 0, 0, 246, 15, 16, + 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 0, 0, 0, 0, 6, 0, + 16, 0, 1, 0, 0, 0, 150, 7, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, + 65, 0, 0, 112, 65, 64, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, + 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 32, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 137, 136, 136, 61, 137, 136, 136, 61, + 137, 136, 136, 61, 137, 136, 136, 61, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, + 0, 10, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 5, 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, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 1, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_4444_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_4444_3d_ps.h new file mode 100644 index 0000000000..ef493e3f4b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_4444_3d_ps.h @@ -0,0 +1,91 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_3D texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 2 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r1.yzw, r0.xxyz, r0.wwww +movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx +mul r0.xyzw, r0.xyzw, l(15.000000, 15.000000, 15.000000, 15.000000) +round_ne r0.xyzw, r0.xyzw +mul o0.xyzw, r0.xyzw, l(0.066667, 0.066667, 0.066667, 0.066667) +ret +// Approximately 8 instruction slots used +#endif + +const BYTE g_PS_FtoF_UM_RGBA_4444_3D[] = { + 68, 88, 66, 67, 210, 247, 48, 228, 222, 252, 207, 191, 86, 78, 158, 63, 239, 245, 179, + 7, 1, 0, 0, 0, 64, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 196, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 112, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 51, 68, + 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, 49, 48, + 46, 49, 0, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 44, 1, 0, 0, 64, 0, 0, 0, 75, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 2, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 49, + 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, 0, 7, 226, 0, 16, 0, 1, 0, 0, + 0, 6, 9, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 55, 0, + 0, 9, 114, 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 150, + 7, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, + 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, 65, 64, 0, + 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 10, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 137, 136, 136, 61, 137, 136, 136, 61, 137, 136, 136, 61, 137, 136, 136, + 61, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 8, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 5, 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, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_5551_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_5551_2d_ps.h new file mode 100644 index 0000000000..42829c90c9 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_5551_2d_ps.h @@ -0,0 +1,88 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 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_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 2 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r1.yzw, r0.xxyz, r0.wwww +movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx +mul r0.xyzw, r0.xyzw, l(31.000000, 31.000000, 31.000000, 1.000000) +round_ne r0.xyzw, r0.xyzw +mul o0.xyzw, r0.xyzw, l(0.032258, 0.032258, 0.032258, 1.000000) +ret +// Approximately 8 instruction slots used +#endif + +const BYTE g_PS_FtoF_UM_RGBA_5551_2D[] = { + 68, 88, 66, 67, 140, 39, 186, 158, 51, 211, 162, 56, 171, 90, 89, 241, 42, 247, 30, + 222, 1, 0, 0, 0, 16, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 148, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 44, 1, 0, 0, 64, + 0, 0, 0, 75, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, + 88, 24, 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, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, + 0, 96, 16, 0, 0, 0, 0, 0, 49, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, + 0, 7, 226, 0, 16, 0, 1, 0, 0, 0, 6, 9, 16, 0, 0, 0, 0, 0, 246, + 15, 16, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 0, 0, 0, 0, + 6, 0, 16, 0, 1, 0, 0, 0, 150, 7, 16, 0, 1, 0, 0, 0, 70, 2, 16, + 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, + 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 248, 65, 0, + 0, 248, 65, 0, 0, 128, 63, 64, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 32, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 33, 4, 61, 8, 33, + 4, 61, 8, 33, 4, 61, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, + 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 5, 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, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_5551_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_5551_2darray_ps.h new file mode 100644 index 0000000000..22389cfa5d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_5551_2darray_ps.h @@ -0,0 +1,98 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_2DArray texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 2 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r1.yzw, r0.xxyz, r0.wwww +movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx +mul r0.xyzw, r0.xyzw, l(31.000000, 31.000000, 31.000000, 1.000000) +round_ne r0.xyzw, r0.xyzw +mul o0.xyzw, r0.xyzw, l(0.032258, 0.032258, 0.032258, 1.000000) +ret +// Approximately 10 instruction slots used +#endif + +const BYTE g_PS_FtoF_UM_RGBA_5551_2DArray[] = { + 68, 88, 66, 67, 17, 161, 17, 46, 139, 141, 231, 172, 21, 139, 205, 213, 78, 192, 111, + 150, 1, 0, 0, 0, 128, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0, + 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 4, 3, 0, 0, 82, 68, 69, 70, 160, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 117, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 50, 68, + 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, + 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, + 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 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, 100, 1, 0, 0, 64, 0, + 0, 0, 89, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, + 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, + 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 2, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, + 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, + 16, 0, 0, 0, 0, 0, 49, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, 0, 7, + 226, 0, 16, 0, 1, 0, 0, 0, 6, 9, 16, 0, 0, 0, 0, 0, 246, 15, 16, + 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 0, 0, 0, 0, 6, 0, + 16, 0, 1, 0, 0, 0, 150, 7, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, 248, + 65, 0, 0, 128, 63, 64, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, + 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 32, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 33, 4, 61, 8, 33, 4, 61, + 8, 33, 4, 61, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, + 0, 10, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 5, 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, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 1, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_5551_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_5551_3d_ps.h new file mode 100644 index 0000000000..a97e54f1d2 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_5551_3d_ps.h @@ -0,0 +1,91 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_3D texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 2 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r1.yzw, r0.xxyz, r0.wwww +movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx +mul r0.xyzw, r0.xyzw, l(31.000000, 31.000000, 31.000000, 1.000000) +round_ne r0.xyzw, r0.xyzw +mul o0.xyzw, r0.xyzw, l(0.032258, 0.032258, 0.032258, 1.000000) +ret +// Approximately 8 instruction slots used +#endif + +const BYTE g_PS_FtoF_UM_RGBA_5551_3D[] = { + 68, 88, 66, 67, 95, 144, 206, 44, 123, 213, 142, 219, 42, 152, 39, 211, 195, 66, 184, + 29, 1, 0, 0, 0, 64, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 196, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 112, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 51, 68, + 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, 49, 48, + 46, 49, 0, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 44, 1, 0, 0, 64, 0, 0, 0, 75, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 2, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 49, + 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, 0, 7, 226, 0, 16, 0, 1, 0, 0, + 0, 6, 9, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 55, 0, + 0, 9, 114, 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 150, + 7, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, + 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, 128, 63, 64, 0, + 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 10, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 8, 33, 4, 61, 8, 33, 4, 61, 8, 33, 4, 61, 0, 0, 128, + 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 8, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 5, 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, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgb_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgb_2darray_ps.h new file mode 100644 index 0000000000..2921c17e7d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgb_2darray_ps.h @@ -0,0 +1,96 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_2DArray texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +mul r0.xyz, r0.wwww, r0.xyzx +mul r0.xyz, r0.xyzx, l(127.000000, 127.000000, 127.000000, 0.000000) +round_ne r0.xyz, r0.xyzx +mul r0.xyz, r0.xyzx, l(1.000000, 1.000000, 1.000000, 0.000000) +ftoi o0.xyz, r0.xyzx +mov o0.w, l(1) +ret +// Approximately 10 instruction slots used +#endif + +const BYTE g_PS_FtoI_PM_RGB_2DArray[] = { + 68, 88, 66, 67, 214, 86, 133, 76, 36, 73, 187, 120, 120, 177, 199, 23, 161, 34, 44, + 41, 1, 0, 0, 0, 104, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0, + 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 236, 2, 0, 0, 82, 68, 69, 70, 160, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 117, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 50, 68, + 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, + 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, + 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 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, 2, 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, 76, 1, 0, 0, 64, 0, + 0, 0, 83, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, + 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, + 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, + 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, + 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, 0, 246, + 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, + 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 254, 66, 0, 0, 254, 66, 0, 0, 254, 66, 0, 0, 0, 0, 64, 0, + 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 0, + 0, 27, 0, 0, 5, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 10, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 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, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 3, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgb_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgb_3d_ps.h new file mode 100644 index 0000000000..18741678e1 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgb_3d_ps.h @@ -0,0 +1,90 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_3D texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +mul r0.xyz, r0.wwww, r0.xyzx +mul r0.xyz, r0.xyzx, l(127.000000, 127.000000, 127.000000, 0.000000) +round_ne r0.xyz, r0.xyzx +mul r0.xyz, r0.xyzx, l(1.000000, 1.000000, 1.000000, 0.000000) +ftoi o0.xyz, r0.xyzx +mov o0.w, l(1) +ret +// Approximately 8 instruction slots used +#endif + +const BYTE g_PS_FtoI_PM_RGB_3D[] = { + 68, 88, 66, 67, 233, 244, 68, 31, 244, 75, 174, 119, 157, 230, 155, 216, 124, 72, 238, + 41, 1, 0, 0, 0, 40, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 172, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 112, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 51, 68, + 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, 49, 48, + 46, 49, 0, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 2, 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, 20, 1, 0, 0, 64, 0, 0, 0, 69, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 254, 66, 0, 0, + 254, 66, 0, 0, 254, 66, 0, 0, 0, 0, 64, 0, 0, 5, 114, 0, 16, 0, 0, + 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, + 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, + 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 0, 0, 27, 0, 0, 5, 114, 32, + 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, + 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 4, 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, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgba_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgba_2darray_ps.h new file mode 100644 index 0000000000..f877df2d74 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgba_2darray_ps.h @@ -0,0 +1,94 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_2DArray texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +mul r0.xyz, r0.wwww, r0.xyzx +mul r0.xyzw, r0.xyzw, l(127.000000, 127.000000, 127.000000, 127.000000) +round_ne r0.xyzw, r0.xyzw +mul r0.xyzw, r0.xyzw, l(1.000000, 1.000000, 1.000000, 1.000000) +ftoi o0.xyzw, r0.xyzw +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_FtoI_PM_RGBA_2DArray[] = { + 68, 88, 66, 67, 6, 46, 120, 27, 94, 101, 87, 132, 53, 181, 154, 63, 109, 237, 51, + 143, 1, 0, 0, 0, 84, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0, + 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 216, 2, 0, 0, 82, 68, 69, 70, 160, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 117, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 50, 68, + 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, + 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, + 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 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, 2, 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, 56, 1, 0, 0, 64, 0, + 0, 0, 78, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, + 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, + 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, + 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, + 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, 0, 246, + 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, + 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 254, 66, 0, 0, 254, 66, 0, 0, 254, 66, 0, 0, 254, 66, 64, 0, + 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, + 63, 27, 0, 0, 5, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, + 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 9, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 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, 1, 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, 3, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgba_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgba_3d_ps.h new file mode 100644 index 0000000000..e4b96a279b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgba_3d_ps.h @@ -0,0 +1,88 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_3D texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +mul r0.xyz, r0.wwww, r0.xyzx +mul r0.xyzw, r0.xyzw, l(127.000000, 127.000000, 127.000000, 127.000000) +round_ne r0.xyzw, r0.xyzw +mul r0.xyzw, r0.xyzw, l(1.000000, 1.000000, 1.000000, 1.000000) +ftoi o0.xyzw, r0.xyzw +ret +// Approximately 7 instruction slots used +#endif + +const BYTE g_PS_FtoI_PM_RGBA_3D[] = { + 68, 88, 66, 67, 249, 90, 79, 118, 112, 44, 159, 0, 189, 165, 140, 198, 201, 78, 213, + 100, 1, 0, 0, 0, 20, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 152, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 112, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 51, 68, + 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, 49, 48, + 46, 49, 0, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 2, 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, 0, 1, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 254, 66, 0, 0, + 254, 66, 0, 0, 254, 66, 0, 0, 254, 66, 64, 0, 0, 5, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, + 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, + 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 27, 0, 0, 5, 242, 32, + 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, + 84, 65, 84, 116, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 4, 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, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgb_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgb_2darray_ps.h new file mode 100644 index 0000000000..8970316b3d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgb_2darray_ps.h @@ -0,0 +1,94 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_2DArray texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +mul r0.xyz, r0.xyzx, l(127.000000, 127.000000, 127.000000, 0.000000) +round_ne r0.xyz, r0.xyzx +mul r0.xyz, r0.xyzx, l(1.000000, 1.000000, 1.000000, 0.000000) +ftoi o0.xyz, r0.xyzx +mov o0.w, l(1) +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_FtoI_PT_RGB_2DArray[] = { + 68, 88, 66, 67, 168, 185, 143, 219, 147, 147, 203, 58, 217, 196, 122, 65, 228, 189, 209, + 238, 1, 0, 0, 0, 76, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0, + 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 208, 2, 0, 0, 82, 68, 69, 70, 160, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 117, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 50, 68, + 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, + 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, + 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 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, 2, 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, 48, 1, 0, 0, 64, 0, + 0, 0, 76, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, + 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, + 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, + 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, + 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 254, 66, 0, 0, 254, 66, + 0, 0, 254, 66, 0, 0, 0, 0, 64, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, + 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 63, 0, + 0, 128, 63, 0, 0, 128, 63, 0, 0, 0, 0, 27, 0, 0, 5, 114, 32, 16, 0, + 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, + 65, 84, 116, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 3, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgb_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgb_3d_ps.h new file mode 100644 index 0000000000..3f93541ea7 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgb_3d_ps.h @@ -0,0 +1,88 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_3D texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +mul r0.xyz, r0.xyzx, l(127.000000, 127.000000, 127.000000, 0.000000) +round_ne r0.xyz, r0.xyzx +mul r0.xyz, r0.xyzx, l(1.000000, 1.000000, 1.000000, 0.000000) +ftoi o0.xyz, r0.xyzx +mov o0.w, l(1) +ret +// Approximately 7 instruction slots used +#endif + +const BYTE g_PS_FtoI_PT_RGB_3D[] = { + 68, 88, 66, 67, 65, 66, 171, 227, 204, 106, 7, 188, 141, 169, 26, 209, 77, 251, 140, + 247, 1, 0, 0, 0, 12, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 144, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 112, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 51, 68, + 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, 49, 48, + 46, 49, 0, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 2, 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, 248, 0, 0, 0, 64, 0, 0, 0, 62, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 254, 66, 0, 0, 254, 66, 0, 0, 254, 66, 0, 0, 0, + 0, 64, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, + 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, + 0, 0, 0, 0, 27, 0, 0, 5, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, + 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 7, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 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, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgba_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgba_2darray_ps.h new file mode 100644 index 0000000000..493fc2292b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgba_2darray_ps.h @@ -0,0 +1,92 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_2DArray texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +mul r0.xyzw, r0.xyzw, l(127.000000, 127.000000, 127.000000, 127.000000) +round_ne r0.xyzw, r0.xyzw +mul r0.xyzw, r0.xyzw, l(1.000000, 1.000000, 1.000000, 1.000000) +ftoi o0.xyzw, r0.xyzw +ret +// Approximately 8 instruction slots used +#endif + +const BYTE g_PS_FtoI_PT_RGBA_2DArray[] = { + 68, 88, 66, 67, 157, 78, 228, 79, 217, 28, 225, 96, 83, 195, 47, 176, 240, 168, 229, + 128, 1, 0, 0, 0, 56, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0, + 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 188, 2, 0, 0, 82, 68, 69, 70, 160, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 117, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 50, 68, + 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, + 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, + 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 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, 2, 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, 28, 1, 0, 0, 64, 0, + 0, 0, 71, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, + 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, + 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, + 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, + 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 254, 66, 0, 0, 254, 66, + 0, 0, 254, 66, 0, 0, 254, 66, 64, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 63, 0, + 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 27, 0, 0, 5, 242, 32, 16, 0, + 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, + 84, 116, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 3, 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, 1, 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, 3, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgba_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgba_3d_ps.h new file mode 100644 index 0000000000..c602d2fb2e --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgba_3d_ps.h @@ -0,0 +1,85 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_3D texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +mul r0.xyzw, r0.xyzw, l(127.000000, 127.000000, 127.000000, 127.000000) +round_ne r0.xyzw, r0.xyzw +mul r0.xyzw, r0.xyzw, l(1.000000, 1.000000, 1.000000, 1.000000) +ftoi o0.xyzw, r0.xyzw +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_FtoI_PT_RGBA_3D[] = { + 68, 88, 66, 67, 73, 236, 106, 44, 249, 119, 115, 91, 94, 156, 145, 139, 146, 47, 33, + 36, 1, 0, 0, 0, 248, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 124, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 112, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 51, 68, + 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, 49, 48, + 46, 49, 0, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 2, 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, 228, 0, 0, 0, 64, 0, 0, 0, 57, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 254, 66, 0, 0, 254, 66, 0, 0, 254, 66, 0, 0, 254, + 66, 64, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, + 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, + 0, 0, 128, 63, 27, 0, 0, 5, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, + 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 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, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgb_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgb_2darray_ps.h new file mode 100644 index 0000000000..8335a149c6 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgb_2darray_ps.h @@ -0,0 +1,102 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_2DArray texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 2 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r1.yzw, r0.xxyz, r0.wwww +movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx +mul r0.xyz, r0.xyzx, l(127.000000, 127.000000, 127.000000, 0.000000) +round_ne r0.xyz, r0.xyzx +mul r0.xyz, r0.xyzx, l(1.000000, 1.000000, 1.000000, 0.000000) +ftoi o0.xyz, r0.xyzx +mov o0.w, l(1) +ret +// Approximately 12 instruction slots used +#endif + +const BYTE g_PS_FtoI_UM_RGB_2DArray[] = { + 68, 88, 66, 67, 229, 156, 153, 172, 30, 111, 168, 172, 47, 75, 227, 206, 198, 78, 62, + 42, 1, 0, 0, 0, 168, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0, + 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 44, 3, 0, 0, 82, 68, 69, 70, 160, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 117, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 50, 68, + 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, + 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, + 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 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, 2, 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, 140, 1, 0, 0, 64, 0, + 0, 0, 99, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, + 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, + 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 2, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, + 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, + 16, 0, 0, 0, 0, 0, 49, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, 0, 7, + 226, 0, 16, 0, 1, 0, 0, 0, 6, 9, 16, 0, 0, 0, 0, 0, 246, 15, 16, + 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 0, 0, 0, 0, 6, 0, + 16, 0, 1, 0, 0, 0, 150, 7, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, + 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 254, 66, 0, 0, 254, 66, 0, 0, 254, + 66, 0, 0, 0, 0, 64, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, + 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, + 0, 0, 128, 63, 0, 0, 0, 0, 27, 0, 0, 5, 114, 32, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, + 0, 0, 0, 12, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, + 5, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 3, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgb_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgb_3d_ps.h new file mode 100644 index 0000000000..2df877322f --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgb_3d_ps.h @@ -0,0 +1,95 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_3D texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 2 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r1.yzw, r0.xxyz, r0.wwww +movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx +mul r0.xyz, r0.xyzx, l(127.000000, 127.000000, 127.000000, 0.000000) +round_ne r0.xyz, r0.xyzx +mul r0.xyz, r0.xyzx, l(1.000000, 1.000000, 1.000000, 0.000000) +ftoi o0.xyz, r0.xyzx +mov o0.w, l(1) +ret +// Approximately 10 instruction slots used +#endif + +const BYTE g_PS_FtoI_UM_RGB_3D[] = { + 68, 88, 66, 67, 23, 5, 101, 80, 190, 217, 192, 233, 141, 228, 109, 126, 239, 211, 129, + 244, 1, 0, 0, 0, 104, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 236, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 112, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 51, 68, + 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, 49, 48, + 46, 49, 0, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 2, 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, 84, 1, 0, 0, 64, 0, 0, 0, 85, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 2, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 49, + 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, 0, 7, 226, 0, 16, 0, 1, 0, 0, + 0, 6, 9, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 55, 0, + 0, 9, 114, 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 150, + 7, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, + 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 254, 66, 0, 0, 254, 66, 0, 0, 254, 66, 0, 0, 0, 0, 64, 0, + 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 0, + 0, 27, 0, 0, 5, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 10, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 5, 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, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgba_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgba_2darray_ps.h new file mode 100644 index 0000000000..3d4dfa2bb9 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgba_2darray_ps.h @@ -0,0 +1,100 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_2DArray texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 2 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r1.yzw, r0.xxyz, r0.wwww +movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx +mul r0.xyzw, r0.xyzw, l(127.000000, 127.000000, 127.000000, 127.000000) +round_ne r0.xyzw, r0.xyzw +mul r0.xyzw, r0.xyzw, l(1.000000, 1.000000, 1.000000, 1.000000) +ftoi o0.xyzw, r0.xyzw +ret +// Approximately 11 instruction slots used +#endif + +const BYTE g_PS_FtoI_UM_RGBA_2DArray[] = { + 68, 88, 66, 67, 131, 143, 223, 155, 139, 202, 127, 87, 193, 203, 100, 239, 91, 19, 167, + 10, 1, 0, 0, 0, 148, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0, + 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 24, 3, 0, 0, 82, 68, 69, 70, 160, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 117, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 50, 68, + 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, + 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, + 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 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, 2, 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, 120, 1, 0, 0, 64, 0, + 0, 0, 94, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, + 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, + 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 2, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, + 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, + 16, 0, 0, 0, 0, 0, 49, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, 0, 7, + 226, 0, 16, 0, 1, 0, 0, 0, 6, 9, 16, 0, 0, 0, 0, 0, 246, 15, 16, + 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 0, 0, 0, 0, 6, 0, + 16, 0, 1, 0, 0, 0, 150, 7, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 254, 66, 0, 0, 254, 66, 0, 0, 254, + 66, 0, 0, 254, 66, 64, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, + 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, + 0, 0, 128, 63, 0, 0, 128, 63, 27, 0, 0, 5, 242, 32, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, + 0, 0, 11, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 5, + 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgba_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgba_3d_ps.h new file mode 100644 index 0000000000..89b06059e3 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgba_3d_ps.h @@ -0,0 +1,93 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_3D texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 2 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r1.yzw, r0.xxyz, r0.wwww +movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx +mul r0.xyzw, r0.xyzw, l(127.000000, 127.000000, 127.000000, 127.000000) +round_ne r0.xyzw, r0.xyzw +mul r0.xyzw, r0.xyzw, l(1.000000, 1.000000, 1.000000, 1.000000) +ftoi o0.xyzw, r0.xyzw +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_FtoI_UM_RGBA_3D[] = { + 68, 88, 66, 67, 221, 247, 207, 180, 133, 35, 246, 152, 57, 87, 23, 116, 186, 51, 233, + 199, 1, 0, 0, 0, 84, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 216, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 112, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 51, 68, + 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, 49, 48, + 46, 49, 0, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 2, 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, 64, 1, 0, 0, 64, 0, 0, 0, 80, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 2, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 49, + 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, 0, 7, 226, 0, 16, 0, 1, 0, 0, + 0, 6, 9, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 55, 0, + 0, 9, 114, 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 150, + 7, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, + 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 254, 66, 0, 0, 254, 66, 0, 0, 254, 66, 0, 0, 254, 66, 64, 0, + 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, + 63, 27, 0, 0, 5, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, + 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 9, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 5, 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, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_2d_ps.h new file mode 100644 index 0000000000..29a60b7f93 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_2d_ps.h @@ -0,0 +1,81 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +mul r0.xyz, r0.wwww, r0.xyzx +mul r0.xyz, r0.xyzx, l(255.000000, 255.000000, 255.000000, 0.000000) +ftou o0.xyz, r0.xyzx +mov o0.w, l(1) +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_FtoU_PM_RGB_2D[] = { + 68, 88, 66, 67, 157, 10, 67, 137, 249, 135, 12, 161, 255, 107, 225, 32, 54, 65, 72, + 121, 1, 0, 0, 0, 188, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 64, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 1, 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, 216, 0, 0, 0, 64, + 0, 0, 0, 54, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, + 88, 24, 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, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, + 0, 96, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, + 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, + 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 0, 0, + 28, 0, 0, 5, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, + 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 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, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_2darray_ps.h new file mode 100644 index 0000000000..f5937d6336 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_2darray_ps.h @@ -0,0 +1,91 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_2DArray texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +mul r0.xyz, r0.wwww, r0.xyzx +mul r0.xyz, r0.xyzx, l(255.000000, 255.000000, 255.000000, 0.000000) +ftou o0.xyz, r0.xyzx +mov o0.w, l(1) +ret +// Approximately 8 instruction slots used +#endif + +const BYTE g_PS_FtoU_PM_RGB_2DArray[] = { + 68, 88, 66, 67, 42, 230, 32, 82, 5, 44, 80, 225, 105, 151, 142, 19, 19, 183, 76, + 193, 1, 0, 0, 0, 44, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0, + 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 176, 2, 0, 0, 82, 68, 69, 70, 160, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 117, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 50, 68, + 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, + 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, + 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 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, 1, 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, 16, 1, 0, 0, 64, 0, + 0, 0, 68, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, + 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, + 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, + 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, + 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, 0, 246, + 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, + 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 0, 0, 28, 0, + 0, 5, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 54, + 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, + 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 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, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_3d_ps.h new file mode 100644 index 0000000000..1e074f9236 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_3d_ps.h @@ -0,0 +1,85 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_3D texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +mul r0.xyz, r0.wwww, r0.xyzx +mul r0.xyz, r0.xyzx, l(255.000000, 255.000000, 255.000000, 0.000000) +ftou o0.xyz, r0.xyzx +mov o0.w, l(1) +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_FtoU_PM_RGB_3D[] = { + 68, 88, 66, 67, 181, 194, 196, 252, 71, 44, 79, 110, 172, 188, 24, 27, 37, 220, 16, + 181, 1, 0, 0, 0, 236, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 112, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 112, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 51, 68, + 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, 49, 48, + 46, 49, 0, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 1, 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, 216, 0, 0, 0, 64, 0, 0, 0, 54, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, + 127, 67, 0, 0, 127, 67, 0, 0, 0, 0, 28, 0, 0, 5, 114, 32, 16, 0, 0, + 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, + 84, 116, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 2, 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, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_2d_ps.h new file mode 100644 index 0000000000..f33e4d5bac --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_2d_ps.h @@ -0,0 +1,79 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +mul r0.xyz, r0.wwww, r0.xyzx +mul r0.xyzw, r0.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000) +ftou o0.xyzw, r0.xyzw +ret +// Approximately 5 instruction slots used +#endif + +const BYTE g_PS_FtoU_PM_RGBA_2D[] = { + 68, 88, 66, 67, 40, 207, 117, 251, 196, 95, 200, 222, 47, 24, 239, 143, 252, 25, 140, + 25, 1, 0, 0, 0, 168, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 44, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 1, 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, 0, 0, 0, 64, + 0, 0, 0, 49, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, + 88, 24, 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, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, + 0, 96, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, + 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, + 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, + 28, 0, 0, 5, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, + 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 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, 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_2darray_ps.h new file mode 100644 index 0000000000..42ceb4a597 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_2darray_ps.h @@ -0,0 +1,89 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_2DArray texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +mul r0.xyz, r0.wwww, r0.xyzx +mul r0.xyzw, r0.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000) +ftou o0.xyzw, r0.xyzw +ret +// Approximately 7 instruction slots used +#endif + +const BYTE g_PS_FtoU_PM_RGBA_2DArray[] = { + 68, 88, 66, 67, 72, 177, 176, 126, 150, 61, 34, 127, 37, 128, 200, 148, 82, 84, 84, + 63, 1, 0, 0, 0, 24, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0, + 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 156, 2, 0, 0, 82, 68, 69, 70, 160, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 117, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 50, 68, + 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, + 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, + 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 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, 1, 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, 252, 0, 0, 0, 64, 0, + 0, 0, 63, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, + 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, + 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, + 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, + 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, 0, 246, + 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, + 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 28, 0, + 0, 5, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 62, + 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 2, 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, 1, 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, + 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_3d_ps.h new file mode 100644 index 0000000000..1e91151b5a --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_3d_ps.h @@ -0,0 +1,83 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_3D texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +mul r0.xyz, r0.wwww, r0.xyzx +mul r0.xyzw, r0.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000) +ftou o0.xyzw, r0.xyzw +ret +// Approximately 5 instruction slots used +#endif + +const BYTE g_PS_FtoU_PM_RGBA_3D[] = { + 68, 88, 66, 67, 108, 177, 182, 169, 224, 190, 112, 68, 155, 228, 67, 226, 65, 238, 217, + 116, 1, 0, 0, 0, 216, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 92, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 112, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 51, 68, + 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, 49, 48, + 46, 49, 0, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 1, 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, 0, 0, 0, 64, 0, 0, 0, 49, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, + 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 28, 0, 0, 5, 242, 32, 16, 0, 0, + 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, + 116, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 2, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_2d_ps.h new file mode 100644 index 0000000000..c74a48f769 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_2d_ps.h @@ -0,0 +1,79 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +mul r0.xyz, r0.xyzx, l(255.000000, 255.000000, 255.000000, 0.000000) +ftou o0.xyz, r0.xyzx +mov o0.w, l(1) +ret +// Approximately 5 instruction slots used +#endif + +const BYTE g_PS_FtoU_PT_RGB_2D[] = { + 68, 88, 66, 67, 21, 43, 226, 215, 164, 244, 10, 22, 123, 34, 48, 235, 95, 92, 229, + 201, 1, 0, 0, 0, 160, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 36, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 1, 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, 188, 0, 0, 0, 64, + 0, 0, 0, 47, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, + 88, 24, 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, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, + 0, 96, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, + 127, 67, 0, 0, 127, 67, 0, 0, 0, 0, 28, 0, 0, 5, 114, 32, 16, 0, 0, + 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, + 84, 116, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 1, 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, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_2darray_ps.h new file mode 100644 index 0000000000..dd66bae38b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_2darray_ps.h @@ -0,0 +1,89 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_2DArray texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +mul r0.xyz, r0.xyzx, l(255.000000, 255.000000, 255.000000, 0.000000) +ftou o0.xyz, r0.xyzx +mov o0.w, l(1) +ret +// Approximately 7 instruction slots used +#endif + +const BYTE g_PS_FtoU_PT_RGB_2DArray[] = { + 68, 88, 66, 67, 135, 27, 134, 107, 134, 245, 87, 208, 181, 1, 171, 9, 139, 65, 67, + 42, 1, 0, 0, 0, 16, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0, + 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 148, 2, 0, 0, 82, 68, 69, 70, 160, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 117, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 50, 68, + 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, + 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, + 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 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, 1, 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, 244, 0, 0, 0, 64, 0, + 0, 0, 61, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, + 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, + 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, + 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, + 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, + 0, 0, 127, 67, 0, 0, 0, 0, 28, 0, 0, 5, 114, 32, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, + 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, + 1, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_3d_ps.h new file mode 100644 index 0000000000..cedb2554e8 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_3d_ps.h @@ -0,0 +1,80 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_3D texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +mul r0.xyz, r0.xyzx, l(255.000000, 255.000000, 255.000000, 0.000000) +ftou o0.xyz, r0.xyzx +mov o0.w, l(1) +ret +// Approximately 5 instruction slots used +#endif + +const BYTE g_PS_FtoU_PT_RGB_3D[] = { + 68, 88, 66, 67, 198, 108, 113, 77, 139, 67, 45, 18, 83, 139, 168, 237, 165, 209, 182, 76, + 1, 0, 0, 0, 208, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, 0, 0, + 92, 1, 0, 0, 144, 1, 0, 0, 84, 2, 0, 0, 82, 68, 69, 70, 152, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, + 0, 1, 0, 0, 112, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 83, 97, 109, 112, 108, 101, 114, 0, + 84, 101, 120, 116, 117, 114, 101, 70, 95, 51, 68, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 128, 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, + 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, + 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, + 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, + 88, 67, 79, 79, 82, 68, 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, 1, 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, 188, 0, 0, 0, 64, 0, 0, 0, 47, 0, 0, 0, 90, 0, 0, 3, + 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, + 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 69, 0, 0, 9, + 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 70, 126, 16, 0, + 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, + 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 127, 67, + 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 0, 0, 28, 0, 0, 5, 114, 32, 16, 0, + 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, + 116, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 1, 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, + 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_2d_ps.h new file mode 100644 index 0000000000..22bce837e4 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_2d_ps.h @@ -0,0 +1,77 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +mul r0.xyzw, r0.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000) +ftou o0.xyzw, r0.xyzw +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_FtoU_PT_RGBA_2D[] = { + 68, 88, 66, 67, 15, 203, 215, 26, 226, 132, 179, 250, 218, 76, 219, 205, 201, 184, 211, + 22, 1, 0, 0, 0, 140, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 16, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 1, 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, 64, + 0, 0, 0, 42, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, + 88, 24, 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, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, + 0, 96, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, + 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 28, 0, 0, 5, 242, 32, 16, 0, 0, + 0, 0, 0, 70, 14, 16, 0, 0, 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, 2, 0, 0, + 0, 1, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_2darray_ps.h new file mode 100644 index 0000000000..3fffb1c2d3 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_2darray_ps.h @@ -0,0 +1,87 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_2DArray texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +mul r0.xyzw, r0.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000) +ftou o0.xyzw, r0.xyzw +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_FtoU_PT_RGBA_2DArray[] = { + 68, 88, 66, 67, 141, 122, 224, 133, 227, 61, 69, 44, 172, 221, 157, 131, 76, 235, 81, + 130, 1, 0, 0, 0, 252, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0, + 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 128, 2, 0, 0, 82, 68, 69, 70, 160, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 117, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 50, 68, + 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, + 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, + 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 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, 1, 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, 224, 0, 0, 0, 64, 0, + 0, 0, 56, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, + 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, + 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, + 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, + 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, + 0, 0, 127, 67, 0, 0, 127, 67, 28, 0, 0, 5, 242, 32, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, + 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, + 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, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_3d_ps.h new file mode 100644 index 0000000000..bd50542b5d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_3d_ps.h @@ -0,0 +1,80 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_3D texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +mul r0.xyzw, r0.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000) +ftou o0.xyzw, r0.xyzw +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_FtoU_PT_RGBA_3D[] = { + 68, 88, 66, 67, 60, 29, 156, 198, 163, 110, 141, 222, 219, 229, 175, 1, 103, 9, 217, + 156, 1, 0, 0, 0, 188, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 64, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 112, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 51, 68, + 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, 49, 48, + 46, 49, 0, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 1, 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, 64, 0, 0, 0, 42, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, + 67, 28, 0, 0, 5, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 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, 2, 0, 0, 0, 1, 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, 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, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_2d_ps.h new file mode 100644 index 0000000000..25149b232d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_2d_ps.h @@ -0,0 +1,87 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 2 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r1.yzw, r0.xxyz, r0.wwww +movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx +mul r0.xyz, r0.xyzx, l(255.000000, 255.000000, 255.000000, 0.000000) +ftou o0.xyz, r0.xyzx +mov o0.w, l(1) +ret +// Approximately 8 instruction slots used +#endif + +const BYTE g_PS_FtoU_UM_RGB_2D[] = { + 68, 88, 66, 67, 104, 222, 184, 218, 135, 243, 133, 232, 177, 236, 20, 60, 64, 9, 17, + 90, 1, 0, 0, 0, 252, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 128, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 1, 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, 24, 1, 0, 0, 64, + 0, 0, 0, 70, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, + 88, 24, 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, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, + 0, 96, 16, 0, 0, 0, 0, 0, 49, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, + 0, 7, 226, 0, 16, 0, 1, 0, 0, 0, 6, 9, 16, 0, 0, 0, 0, 0, 246, + 15, 16, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 0, 0, 0, 0, + 6, 0, 16, 0, 1, 0, 0, 0, 150, 7, 16, 0, 1, 0, 0, 0, 70, 2, 16, + 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, + 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, + 0, 127, 67, 0, 0, 0, 0, 28, 0, 0, 5, 114, 32, 16, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, + 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, + 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, + 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_2darray_ps.h new file mode 100644 index 0000000000..8b8d1d3b7f --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_2darray_ps.h @@ -0,0 +1,97 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_2DArray texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 2 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r1.yzw, r0.xxyz, r0.wwww +movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx +mul r0.xyz, r0.xyzx, l(255.000000, 255.000000, 255.000000, 0.000000) +ftou o0.xyz, r0.xyzx +mov o0.w, l(1) +ret +// Approximately 10 instruction slots used +#endif + +const BYTE g_PS_FtoU_UM_RGB_2DArray[] = { + 68, 88, 66, 67, 211, 11, 247, 147, 13, 61, 188, 52, 49, 20, 122, 213, 216, 130, 203, + 211, 1, 0, 0, 0, 108, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0, + 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 240, 2, 0, 0, 82, 68, 69, 70, 160, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 117, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 50, 68, + 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, + 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, + 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 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, 1, 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, 80, 1, 0, 0, 64, 0, + 0, 0, 84, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, + 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, + 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 2, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, + 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, + 16, 0, 0, 0, 0, 0, 49, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, 0, 7, + 226, 0, 16, 0, 1, 0, 0, 0, 6, 9, 16, 0, 0, 0, 0, 0, 246, 15, 16, + 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 0, 0, 0, 0, 6, 0, + 16, 0, 1, 0, 0, 0, 150, 7, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, + 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, + 67, 0, 0, 0, 0, 28, 0, 0, 5, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, + 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, + 10, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 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, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 1, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_3d_ps.h new file mode 100644 index 0000000000..f7746e87ee --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_3d_ps.h @@ -0,0 +1,90 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_3D texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 2 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r1.yzw, r0.xxyz, r0.wwww +movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx +mul r0.xyz, r0.xyzx, l(255.000000, 255.000000, 255.000000, 0.000000) +ftou o0.xyz, r0.xyzx +mov o0.w, l(1) +ret +// Approximately 8 instruction slots used +#endif + +const BYTE g_PS_FtoU_UM_RGB_3D[] = { + 68, 88, 66, 67, 211, 77, 171, 115, 172, 101, 224, 185, 62, 127, 82, 90, 150, 163, 227, + 209, 1, 0, 0, 0, 44, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 176, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 112, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 51, 68, + 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, 49, 48, + 46, 49, 0, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 1, 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, 24, 1, 0, 0, 64, 0, 0, 0, 70, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 2, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 49, + 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, 0, 7, 226, 0, 16, 0, 1, 0, 0, + 0, 6, 9, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 55, 0, + 0, 9, 114, 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 150, + 7, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, + 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 0, 0, 28, 0, + 0, 5, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 54, + 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, + 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 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, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_2d_ps.h new file mode 100644 index 0000000000..71530637ef --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_2d_ps.h @@ -0,0 +1,85 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 2 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r1.yzw, r0.xxyz, r0.wwww +movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx +mul r0.xyzw, r0.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000) +ftou o0.xyzw, r0.xyzw +ret +// Approximately 7 instruction slots used +#endif + +const BYTE g_PS_FtoU_UM_RGBA_2D[] = { + 68, 88, 66, 67, 79, 47, 172, 229, 63, 231, 120, 201, 52, 133, 90, 84, 23, 233, 153, + 100, 1, 0, 0, 0, 232, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 108, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 1, 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, 4, 1, 0, 0, 64, + 0, 0, 0, 65, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, + 88, 24, 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, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, + 0, 96, 16, 0, 0, 0, 0, 0, 49, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, + 0, 7, 226, 0, 16, 0, 1, 0, 0, 0, 6, 9, 16, 0, 0, 0, 0, 0, 246, + 15, 16, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 0, 0, 0, 0, + 6, 0, 16, 0, 1, 0, 0, 0, 150, 7, 16, 0, 1, 0, 0, 0, 70, 2, 16, + 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, + 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, + 0, 127, 67, 0, 0, 127, 67, 28, 0, 0, 5, 242, 32, 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, + 0, 7, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 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, + 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_2darray_ps.h new file mode 100644 index 0000000000..5d75b8df6d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_2darray_ps.h @@ -0,0 +1,95 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_2DArray texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 2 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r1.yzw, r0.xxyz, r0.wwww +movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx +mul r0.xyzw, r0.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000) +ftou o0.xyzw, r0.xyzw +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_FtoU_UM_RGBA_2DArray[] = { + 68, 88, 66, 67, 237, 98, 226, 3, 103, 212, 163, 240, 153, 59, 189, 19, 100, 209, 34, + 202, 1, 0, 0, 0, 88, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0, + 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 220, 2, 0, 0, 82, 68, 69, 70, 160, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 117, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 50, 68, + 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, + 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, + 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 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, 1, 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, 60, 1, 0, 0, 64, 0, + 0, 0, 79, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, + 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, + 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 2, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, + 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, + 16, 0, 0, 0, 0, 0, 49, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, 0, 7, + 226, 0, 16, 0, 1, 0, 0, 0, 6, 9, 16, 0, 0, 0, 0, 0, 246, 15, 16, + 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 0, 0, 0, 0, 6, 0, + 16, 0, 1, 0, 0, 0, 150, 7, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, + 67, 0, 0, 127, 67, 28, 0, 0, 5, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, + 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 9, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 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, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 1, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_3d_ps.h new file mode 100644 index 0000000000..7d98511943 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_3d_ps.h @@ -0,0 +1,88 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF_3D texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 2 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r1.yzw, r0.xxyz, r0.wwww +movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx +mul r0.xyzw, r0.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000) +ftou o0.xyzw, r0.xyzw +ret +// Approximately 7 instruction slots used +#endif + +const BYTE g_PS_FtoU_UM_RGBA_3D[] = { + 68, 88, 66, 67, 9, 246, 142, 132, 23, 145, 144, 223, 33, 247, 146, 14, 116, 28, 69, + 175, 1, 0, 0, 0, 24, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 156, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 112, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 51, 68, + 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, 49, 48, + 46, 49, 0, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 1, 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, 4, 1, 0, 0, 64, 0, 0, 0, 65, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 2, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 49, + 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, 0, 7, 226, 0, 16, 0, 1, 0, 0, + 0, 6, 9, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 55, 0, + 0, 9, 114, 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 150, + 7, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, + 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 28, 0, + 0, 5, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 62, + 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 7, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 3, 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, 1, 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, + 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h new file mode 100644 index 0000000000..fdeae67ad9 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h @@ -0,0 +1,91 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// POSITION 0 xy 0 NONE float xy +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float xyzw +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Runtime generated constant mappings: +// +// Target Reg Constant Description +// ---------- -------------------------------------------------- +// c0 Vertex Shader position offset +// +// +// Level9 shader bytecode: +// + vs_2_x + def c1, 0, 1, 0, 0 + dcl_texcoord v0 + dcl_texcoord1 v1 + add oPos.xy, v0, c0 + mov oPos.zw, c1.xyxy + mov oT0.xy, v1 + +// approximately 3 instruction slots used +vs_4_0 +dcl_input v0.xy +dcl_input v1.xy +dcl_output_siv o0.xyzw, position +dcl_output o1.xy +mov o0.xy, v0.xyxx +mov o0.zw, l(0,0,0,1.000000) +mov o1.xy, v1.xyxx +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_VS_Passthrough2D[] = { + 68, 88, 66, 67, 157, 119, 222, 216, 39, 186, 195, 24, 174, 138, 22, 73, 223, 185, 107, + 36, 1, 0, 0, 0, 204, 2, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 200, 0, + 0, 0, 88, 1, 0, 0, 212, 1, 0, 0, 32, 2, 0, 0, 116, 2, 0, 0, 65, + 111, 110, 57, 136, 0, 0, 0, 136, 0, 0, 0, 0, 2, 254, 255, 96, 0, 0, 0, + 40, 0, 0, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, + 0, 1, 0, 36, 0, 0, 0, 0, 0, 1, 2, 254, 255, 81, 0, 0, 5, 1, 0, + 15, 160, 0, 0, 0, 0, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 31, + 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, + 1, 0, 15, 144, 2, 0, 0, 3, 0, 0, 3, 192, 0, 0, 228, 144, 0, 0, 228, + 160, 1, 0, 0, 2, 0, 0, 12, 192, 1, 0, 68, 160, 1, 0, 0, 2, 0, 0, + 3, 224, 1, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 136, 0, 0, 0, 64, + 0, 1, 0, 34, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, + 95, 0, 0, 3, 50, 16, 16, 0, 1, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 1, 0, + 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, + 0, 0, 0, 54, 0, 0, 8, 194, 32, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, 54, 0, 0, + 5, 50, 32, 16, 0, 1, 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 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, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 68, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 4, + 254, 255, 0, 1, 0, 0, 28, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 76, 0, 0, + 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 65, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 3, 3, 0, 0, + 80, 79, 83, 73, 84, 73, 79, 78, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, + 171, 79, 83, 71, 78, 80, 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, 12, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, + 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11gs.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11gs.h new file mode 100644 index 0000000000..23fc7f99ea --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11gs.h @@ -0,0 +1,93 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float xyzw +// LAYER 0 x 1 NONE uint x +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float xyzw +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xyz +// +gs_4_0 +dcl_input_siv v[3][0].xyzw, position +dcl_input v[3][1].x +dcl_input v[3][2].xyz +dcl_temps 1 +dcl_inputprimitive triangle +dcl_outputtopology trianglestrip +dcl_output_siv o0.xyzw, position +dcl_output_siv o1.x, rendertarget_array_index +dcl_output o2.xyz +dcl_maxout 3 +mov r0.x, l(0) +loop + ige r0.y, r0.x, l(3) + breakc_nz r0.y + mov o0.xyzw, v[r0.x + 0][0].xyzw + mov o1.x, v[r0.x + 0][1].x + mov o2.xyz, v[r0.x + 0][2].xyzx + emit + iadd r0.x, r0.x, l(1) +endloop +ret +// Approximately 11 instruction slots used +#endif + +const BYTE g_GS_Passthrough3D[] = { + 68, 88, 66, 67, 226, 188, 145, 36, 193, 19, 254, 1, 249, 51, 174, 53, 33, 65, 233, + 89, 1, 0, 0, 0, 60, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 128, 0, + 0, 0, 244, 0, 0, 0, 124, 1, 0, 0, 192, 2, 0, 0, 82, 68, 69, 70, 68, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 83, 71, 0, 1, 0, 0, 28, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 108, + 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, 15, 0, 0, 92, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, + 0, 0, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, + 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, + 76, 65, 89, 69, 82, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 79, 83, 71, + 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 14, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 2, 0, 0, 0, 7, 8, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, + 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, + 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, + 83, 72, 68, 82, 60, 1, 0, 0, 64, 0, 2, 0, 79, 0, 0, 0, 97, 0, 0, + 5, 242, 16, 32, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 95, 0, + 0, 4, 18, 16, 32, 0, 3, 0, 0, 0, 1, 0, 0, 0, 95, 0, 0, 4, 114, + 16, 32, 0, 3, 0, 0, 0, 2, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, + 93, 24, 0, 1, 92, 40, 0, 1, 103, 0, 0, 4, 242, 32, 16, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 103, 0, 0, 4, 18, 32, 16, 0, 1, 0, 0, 0, 4, 0, + 0, 0, 101, 0, 0, 3, 114, 32, 16, 0, 2, 0, 0, 0, 94, 0, 0, 2, 3, + 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, 33, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 7, 242, 32, 16, 0, 0, + 0, 0, 0, 70, 30, 160, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 7, 18, 32, 16, 0, 1, 0, 0, 0, 10, 16, 160, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 7, 114, 32, 16, 0, 2, 0, + 0, 0, 70, 18, 160, 0, 10, 0, 16, 0, 0, 0, 0, 0, 2, 0, 0, 0, 19, + 0, 0, 1, 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, 62, 0, 0, + 1, 83, 84, 65, 84, 116, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 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, 1, 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, 5, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11vs.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11vs.h new file mode 100644 index 0000000000..3c833f79a8 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11vs.h @@ -0,0 +1,75 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// POSITION 0 xy 0 NONE float xy +// LAYER 0 x 1 NONE uint x +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float xyzw +// LAYER 0 x 1 NONE uint x +// TEXCOORD 0 xyz 2 NONE float xyz +// +vs_4_0 +dcl_input v0.xy +dcl_input v1.x +dcl_input v2.xyz +dcl_output_siv o0.xyzw, position +dcl_output o1.x +dcl_output o2.xyz +mov o0.xy, v0.xyxx +mov o0.zw, l(0,0,0,1.000000) +mov o1.x, v1.x +mov o2.xyz, v2.xyzx +ret +// Approximately 5 instruction slots used +#endif + +const BYTE g_VS_Passthrough3D[] = { + 68, 88, 66, 67, 136, 150, 103, 162, 167, 195, 182, 112, 150, 17, 18, 65, 73, 164, 12, + 142, 1, 0, 0, 0, 156, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 128, 0, + 0, 0, 240, 0, 0, 0, 100, 1, 0, 0, 32, 2, 0, 0, 82, 68, 69, 70, 68, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 254, 255, 0, 1, 0, 0, 28, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 104, + 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 89, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, + 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, + 0, 0, 0, 7, 7, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 76, 65, 89, + 69, 82, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 78, 108, 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, 1, 0, 0, 0, 1, 0, 0, 0, 1, 14, 0, 0, + 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, + 0, 7, 8, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 76, 65, + 89, 69, 82, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 83, 72, 68, 82, 180, + 0, 0, 0, 64, 0, 1, 0, 45, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, + 0, 0, 0, 0, 95, 0, 0, 3, 18, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0, + 3, 114, 16, 16, 0, 2, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 101, 0, 0, 3, 18, 32, 16, 0, 1, 0, 0, 0, 101, + 0, 0, 3, 114, 32, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, + 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 32, 16, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 128, 63, 54, 0, 0, 5, 18, 32, 16, 0, 1, 0, 0, 0, 10, + 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 114, 32, 16, 0, 2, 0, 0, 0, + 70, 18, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4, 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, 0, 0, 0, 0, 0, + 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrougha2d11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrougha2d11ps.h new file mode 100644 index 0000000000..a338628659 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrougha2d11ps.h @@ -0,0 +1,103 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +// +// Sampler/Resource to DX9 shader sampler mappings: +// +// Target Sampler Source Sampler Source Resource +// -------------- --------------- ---------------- +// s0 s0 t0 +// +// +// Level9 shader bytecode: +// + ps_2_x + def c0, 0, 1, 0, 0 + dcl t0.xy + dcl_2d s0 + texld r0, t0, s0 + mul r0, r0.w, c0.xxxy + mov oC0, r0 + +// approximately 3 instruction slots used (1 texture, 2 arithmetic) +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +mov o0.w, r0.w +mov o0.xyz, l(0,0,0,0) +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_PassthroughA2D[] = { + 68, 88, 66, 67, 194, 169, 124, 165, 14, 7, 97, 151, 180, 238, 123, 252, 63, 248, 162, + 165, 1, 0, 0, 0, 28, 3, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 204, 0, + 0, 0, 116, 1, 0, 0, 240, 1, 0, 0, 144, 2, 0, 0, 232, 2, 0, 0, 65, + 111, 110, 57, 140, 0, 0, 0, 140, 0, 0, 0, 0, 2, 255, 255, 100, 0, 0, 0, + 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, + 0, 0, 0, 40, 0, 0, 0, 0, 0, 1, 2, 255, 255, 81, 0, 0, 5, 0, 0, + 15, 160, 0, 0, 0, 0, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 31, + 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 144, + 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, + 160, 5, 0, 0, 3, 0, 0, 15, 128, 0, 0, 255, 128, 0, 0, 64, 160, 1, 0, + 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 160, + 0, 0, 0, 64, 0, 0, 0, 40, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, + 0, 0, 0, 0, 88, 24, 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, 1, 0, 0, 0, 69, 0, 0, 9, 242, + 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, + 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, + 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 8, 114, 32, + 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, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, + 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 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, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, + 0, 0, 82, 68, 69, 70, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, + 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, + 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, + 0, 0, 0, 13, 0, 0, 0, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, + 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, + 171, 171, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2d11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2d11ps.h new file mode 100644 index 0000000000..e8790cade6 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2d11ps.h @@ -0,0 +1,73 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_DEPTH 0 N/A oDepth DEPTH float YES +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output oDepth +dcl_temps 1 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +mov oDepth, r0.x +ret +// Approximately 3 instruction slots used +#endif + +const BYTE g_PS_PassthroughDepth2D[] = { + 68, 88, 66, 67, 215, 216, 149, 20, 177, 67, 115, 222, 9, 179, 226, 21, 58, 197, 172, + 136, 1, 0, 0, 0, 92, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 224, 1, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 255, 255, 255, 255, 1, 14, 0, 0, 83, 86, + 95, 68, 69, 80, 84, 72, 0, 171, 171, 171, 83, 72, 68, 82, 120, 0, 0, 0, 64, + 0, 0, 0, 30, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, + 88, 24, 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, 2, 1, 192, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, + 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, + 0, 0, 0, 0, 54, 0, 0, 4, 1, 192, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 3, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 2, 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, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum2d11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum2d11ps.h new file mode 100644 index 0000000000..c8a472e9b6 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum2d11ps.h @@ -0,0 +1,103 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +// +// Sampler/Resource to DX9 shader sampler mappings: +// +// Target Sampler Source Sampler Source Resource +// -------------- --------------- ---------------- +// s0 s0 t0 +// +// +// Level9 shader bytecode: +// + ps_2_x + def c0, 1, 0, 0, 0 + dcl t0.xy + dcl_2d s0 + texld r0, t0, s0 + mad r0, r0.x, c0.xxxy, c0.yyyx + mov oC0, r0 + +// approximately 3 instruction slots used (1 texture, 2 arithmetic) +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +mov o0.xyz, r0.xxxx +mov o0.w, l(1.000000) +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_PassthroughLum2D[] = { + 68, 88, 66, 67, 241, 199, 66, 51, 118, 205, 236, 165, 244, 231, 234, 126, 203, 25, 231, + 134, 1, 0, 0, 0, 20, 3, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 208, 0, + 0, 0, 108, 1, 0, 0, 232, 1, 0, 0, 136, 2, 0, 0, 224, 2, 0, 0, 65, + 111, 110, 57, 144, 0, 0, 0, 144, 0, 0, 0, 0, 2, 255, 255, 104, 0, 0, 0, + 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, + 0, 0, 0, 40, 0, 0, 0, 0, 0, 1, 2, 255, 255, 81, 0, 0, 5, 0, 0, + 15, 160, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, + 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 144, + 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, + 160, 4, 0, 0, 4, 0, 0, 15, 128, 0, 0, 0, 128, 0, 0, 64, 160, 0, 0, + 21, 160, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, + 72, 68, 82, 148, 0, 0, 0, 64, 0, 0, 0, 37, 0, 0, 0, 90, 0, 0, 3, + 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 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, 1, 0, 0, 0, 69, + 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, + 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, 0, 0, + 5, 114, 32, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 62, + 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 2, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 152, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, + 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 83, + 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, 171, + 171, 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum2darray11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum2darray11ps.h new file mode 100644 index 0000000000..4741497d93 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum2darray11ps.h @@ -0,0 +1,85 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +mov o0.xyz, r0.xxxx +mov o0.w, l(1.000000) +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_PassthroughLum2DArray[] = { + 68, 88, 66, 67, 84, 131, 205, 28, 3, 168, 120, 6, 89, 75, 169, 140, 154, 126, 61, + 31, 1, 0, 0, 0, 224, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 100, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 204, 0, 0, 0, 64, 0, 0, 0, 51, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 64, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, 18, 16, 16, 0, 1, 0, 0, 0, + 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, + 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 86, 0, + 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 1, 0, 0, 0, 54, + 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 2, 0, 0, 0, + 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, + 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 114, 32, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 54, + 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, + 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, 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, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum3d11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum3d11ps.h new file mode 100644 index 0000000000..5c9ffc039a --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum3d11ps.h @@ -0,0 +1,79 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +mov o0.xyz, r0.xxxx +mov o0.w, l(1.000000) +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_PassthroughLum3D[] = { + 68, 88, 66, 67, 15, 80, 145, 76, 93, 127, 194, 208, 106, 29, 26, 87, 147, 62, 128, + 143, 1, 0, 0, 0, 168, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 44, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 148, 0, 0, 0, 64, 0, 0, 0, 37, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, + 0, 0, 5, 114, 32, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, + 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 4, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 2, 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, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h new file mode 100644 index 0000000000..6229e57ea2 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h @@ -0,0 +1,98 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +// +// Sampler/Resource to DX9 shader sampler mappings: +// +// Target Sampler Source Sampler Source Resource +// -------------- --------------- ---------------- +// s0 s0 t0 +// +// +// Level9 shader bytecode: +// + ps_2_x + dcl t0.xy + dcl_2d s0 + texld r0, t0, s0 + mov r0, r0.xxxw + mov oC0, r0 + +// approximately 3 instruction slots used (1 texture, 2 arithmetic) +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +mov o0.xyzw, r0.xxxw +ret +// Approximately 3 instruction slots used +#endif + +const BYTE g_PS_PassthroughLumAlpha2D[] = { + 68, 88, 66, 67, 19, 109, 76, 235, 225, 193, 54, 241, 78, 207, 77, 62, 148, 127, 172, + 73, 1, 0, 0, 0, 224, 2, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 176, 0, + 0, 0, 56, 1, 0, 0, 180, 1, 0, 0, 84, 2, 0, 0, 172, 2, 0, 0, 65, + 111, 110, 57, 112, 0, 0, 0, 112, 0, 0, 0, 0, 2, 255, 255, 72, 0, 0, 0, + 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, + 0, 0, 0, 40, 0, 0, 0, 0, 0, 1, 2, 255, 255, 31, 0, 0, 2, 0, 0, + 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, + 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 1, 0, 0, 2, + 0, 0, 15, 128, 0, 0, 192, 128, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, + 128, 255, 255, 0, 0, 83, 72, 68, 82, 128, 0, 0, 0, 64, 0, 0, 0, 32, 0, + 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 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, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 16, + 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, + 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 0, 0, 0, 0, 6, 12, 16, 0, + 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 3, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 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, 1, 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, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, + 68, 69, 70, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 28, 0, 0, 0, 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, + 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, + 13, 0, 0, 0, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, + 70, 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, 49, + 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2darray11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2darray11ps.h new file mode 100644 index 0000000000..cdc91561bc --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2darray11ps.h @@ -0,0 +1,83 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +mov o0.xyzw, r0.xxxw +ret +// Approximately 5 instruction slots used +#endif + +const BYTE g_PS_PassthroughLumAlpha2DArray[] = { + 68, 88, 66, 67, 117, 33, 119, 91, 15, 156, 83, 232, 200, 231, 183, 116, 40, 238, 79, + 163, 1, 0, 0, 0, 204, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 80, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 184, 0, 0, 0, 64, 0, 0, 0, 46, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 64, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, 18, 16, 16, 0, 1, 0, 0, 0, + 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, + 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 86, 0, + 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 1, 0, 0, 0, 54, + 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 2, 0, 0, 0, + 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, + 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 242, 32, 16, 0, 0, 0, 0, 0, 6, 12, 16, 0, 0, 0, 0, 0, 62, + 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 5, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h new file mode 100644 index 0000000000..941b5b2b86 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h @@ -0,0 +1,77 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +mov o0.xyzw, r0.xxxw +ret +// Approximately 3 instruction slots used +#endif + +const BYTE g_PS_PassthroughLumAlpha3D[] = { + 68, 88, 66, 67, 158, 22, 231, 90, 211, 81, 99, 1, 181, 209, 159, 145, 140, 162, 254, + 17, 1, 0, 0, 0, 148, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 24, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 128, 0, 0, 0, 64, 0, 0, 0, 32, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, + 0, 0, 5, 242, 32, 16, 0, 0, 0, 0, 0, 6, 12, 16, 0, 0, 0, 0, 0, + 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 2, 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, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2d11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2d11ps.h new file mode 100644 index 0000000000..1b41ed1602 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2d11ps.h @@ -0,0 +1,104 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +// +// Sampler/Resource to DX9 shader sampler mappings: +// +// Target Sampler Source Sampler Source Resource +// -------------- --------------- ---------------- +// s0 s0 t0 +// +// +// Level9 shader bytecode: +// + ps_2_x + def c0, 1, 0, 0, 0 + dcl t0.xy + dcl_2d s0 + texld r0, t0, s0 + mad r0, r0.x, c0.xyyy, c0.yyyx + mov oC0, r0 + +// approximately 3 instruction slots used (1 texture, 2 arithmetic) +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +mov o0.x, r0.x +mov o0.yzw, l(0,0,0,1.000000) +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_PassthroughR2D[] = { + 68, 88, 66, 67, 14, 165, 206, 90, 117, 2, 221, 45, 225, 30, 128, 173, 62, 238, 39, + 64, 1, 0, 0, 0, 32, 3, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 208, 0, + 0, 0, 120, 1, 0, 0, 244, 1, 0, 0, 148, 2, 0, 0, 236, 2, 0, 0, 65, + 111, 110, 57, 144, 0, 0, 0, 144, 0, 0, 0, 0, 2, 255, 255, 104, 0, 0, 0, + 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, + 0, 0, 0, 40, 0, 0, 0, 0, 0, 1, 2, 255, 255, 81, 0, 0, 5, 0, 0, + 15, 160, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, + 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 144, + 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, + 160, 4, 0, 0, 4, 0, 0, 15, 128, 0, 0, 0, 128, 0, 0, 84, 160, 0, 0, + 21, 160, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, + 72, 68, 82, 160, 0, 0, 0, 64, 0, 0, 0, 40, 0, 0, 0, 90, 0, 0, 3, + 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 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, 1, 0, 0, 0, 69, + 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, + 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, 0, 0, + 5, 18, 32, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, + 0, 8, 226, 32, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, + 116, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, + 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 152, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 0, 1, 0, 0, + 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 100, 0, + 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 83, 97, 109, 112, 108, 101, 114, 0, + 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 80, + 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, + 79, 82, 68, 0, 171, 171, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2darray11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2darray11ps.h new file mode 100644 index 0000000000..a5e3d5e52e --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2darray11ps.h @@ -0,0 +1,86 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +mov o0.x, r0.x +mov o0.yzw, l(0,0,0,1.000000) +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_PassthroughR2DArray[] = { + 68, 88, 66, 67, 67, 125, 115, 154, 244, 73, 25, 207, 88, 140, 76, 46, 206, 166, 161, + 193, 1, 0, 0, 0, 236, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 112, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 216, 0, 0, 0, 64, 0, 0, 0, 54, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 64, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, 18, 16, 16, 0, 1, 0, 0, 0, + 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, + 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 86, 0, + 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 1, 0, 0, 0, 54, + 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 2, 0, 0, 0, + 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, + 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 18, 32, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, + 0, 0, 8, 226, 32, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, + 84, 116, 0, 0, 0, 6, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2darrayi11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2darrayi11ps.h new file mode 100644 index 0000000000..eb41a93e37 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2darrayi11ps.h @@ -0,0 +1,90 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureI texture sint4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_resource_texture2darray (sint,sint,sint,sint) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v2.xyxx +ftoi r0.xy, r0.xyxx +mov r0.z, v1.x +mov r0.w, l(0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov o0.x, r0.x +mov o0.yzw, l(0,0,0,1) +ret +// Approximately 10 instruction slots used +#endif + +const BYTE g_PS_PassthroughR2DArrayI[] = { + 68, 88, 66, 67, 200, 92, 148, 185, 17, 79, 183, 61, 19, 121, 215, 3, 144, 133, 210, + 72, 1, 0, 0, 0, 16, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0, + 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 148, 2, 0, 0, 82, 68, 69, 70, 112, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 69, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0, + 0, 3, 0, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 73, 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, 49, 48, 46, 49, 0, 171, 171, + 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, + 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, + 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, + 82, 68, 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, 2, 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, 36, 1, 0, 0, 64, 0, 0, 0, 73, 0, 0, 0, 88, 64, 0, 4, + 0, 112, 16, 0, 0, 0, 0, 0, 51, 51, 0, 0, 100, 8, 0, 4, 18, 16, 16, + 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0, + 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, + 0, 0, 0, 61, 16, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 70, 126, 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, 2, + 0, 0, 0, 27, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, + 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 18, 32, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, + 8, 226, 32, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, + 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, + 1, 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, 4, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2darrayui11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2darrayui11ps.h new file mode 100644 index 0000000000..12825c89e6 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2darrayui11ps.h @@ -0,0 +1,90 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureUI texture uint4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_resource_texture2darray (uint,uint,uint,uint) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v2.xyxx +ftoi r0.xy, r0.xyxx +mov r0.z, v1.x +mov r0.w, l(0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov o0.x, r0.x +mov o0.yzw, l(0,0,0,1) +ret +// Approximately 10 instruction slots used +#endif + +const BYTE g_PS_PassthroughR2DArrayUI[] = { + 68, 88, 66, 67, 201, 224, 137, 9, 164, 198, 146, 11, 60, 99, 27, 27, 235, 209, 108, + 242, 1, 0, 0, 0, 16, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0, + 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 148, 2, 0, 0, 82, 68, 69, 70, 112, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 70, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0, + 0, 4, 0, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 85, 73, 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, 49, 48, 46, 49, 0, 171, + 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, + 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, + 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, + 82, 68, 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, 1, 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, 36, 1, 0, 0, 64, 0, 0, 0, 73, 0, 0, 0, 88, 64, 0, 4, + 0, 112, 16, 0, 0, 0, 0, 0, 68, 68, 0, 0, 100, 8, 0, 4, 18, 16, 16, + 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0, + 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, + 0, 0, 0, 61, 16, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 70, 126, 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, 2, + 0, 0, 0, 27, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, + 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 18, 32, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, + 8, 226, 32, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, + 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, + 1, 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, 4, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2di11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2di11ps.h new file mode 100644 index 0000000000..ea6bbcd460 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2di11ps.h @@ -0,0 +1,83 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureI texture sint4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_resource_texture2d (sint,sint,sint,sint) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v1.xyxx +ftoi r0.xy, r0.xyxx +mov r0.zw, l(0,0,0,0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov o0.x, r0.x +mov o0.yzw, l(0,0,0,0) +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_PassthroughR2DI[] = { + 68, 88, 66, 67, 8, 16, 169, 157, 145, 179, 119, 85, 36, 37, 85, 107, 44, 112, 158, + 100, 1, 0, 0, 0, 200, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0, + 0, 0, 4, 1, 0, 0, 56, 1, 0, 0, 76, 2, 0, 0, 82, 68, 69, 70, 112, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 69, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0, + 0, 3, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 73, 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, 49, 48, 46, 49, 0, 171, 171, + 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 2, 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, 12, 1, 0, 0, 64, 0, 0, + 0, 67, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 51, 51, + 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, 1, 0, 0, 0, 61, 16, 0, 7, + 242, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 126, 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, 27, 0, 0, 5, + 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 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, 45, 0, 0, 7, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 18, 32, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 54, 0, 0, 8, 226, 32, 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, 62, 0, 0, 1, 83, + 84, 65, 84, 116, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2dui11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2dui11ps.h new file mode 100644 index 0000000000..bc034faaf6 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2dui11ps.h @@ -0,0 +1,83 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureUI texture uint4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_resource_texture2d (uint,uint,uint,uint) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v1.xyxx +ftoi r0.xy, r0.xyxx +mov r0.zw, l(0,0,0,0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov o0.x, r0.x +mov o0.yzw, l(0,0,0,0) +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_PassthroughR2DUI[] = { + 68, 88, 66, 67, 6, 47, 175, 167, 62, 144, 171, 206, 77, 165, 245, 226, 135, 124, 142, + 188, 1, 0, 0, 0, 200, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0, + 0, 0, 4, 1, 0, 0, 56, 1, 0, 0, 76, 2, 0, 0, 82, 68, 69, 70, 112, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 70, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0, + 0, 4, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 85, 73, 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, 49, 48, 46, 49, 0, 171, + 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 1, 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, 12, 1, 0, 0, 64, 0, 0, + 0, 67, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 68, 68, + 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, 1, 0, 0, 0, 61, 16, 0, 7, + 242, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 126, 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, 27, 0, 0, 5, + 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 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, 45, 0, 0, 7, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 18, 32, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 54, 0, 0, 8, 226, 32, 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, 62, 0, 0, 1, 83, + 84, 65, 84, 116, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3d11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3d11ps.h new file mode 100644 index 0000000000..010e3eae14 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3d11ps.h @@ -0,0 +1,80 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +mov o0.x, r0.x +mov o0.yzw, l(0,0,0,1.000000) +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_PassthroughR3D[] = { + 68, 88, 66, 67, 134, 101, 76, 73, 205, 199, 65, 249, 170, 201, 40, 128, 129, 87, 93, + 148, 1, 0, 0, 0, 180, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 56, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 160, 0, 0, 0, 64, 0, 0, 0, 40, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, + 0, 0, 5, 18, 32, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 226, 32, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, + 65, 84, 116, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, + 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, + 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3di11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3di11ps.h new file mode 100644 index 0000000000..447690e35e --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3di11ps.h @@ -0,0 +1,86 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureI texture sint4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_resource_texture3d (sint,sint,sint,sint) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xyz, r0.xyzx +mul r0.xyz, r0.xyzx, v2.xyzx +ftoi r0.xyz, r0.xyzx +mov r0.w, l(0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov o0.x, r0.x +mov o0.yzw, l(0,0,0,0) +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_PassthroughR3DI[] = { + 68, 88, 66, 67, 250, 224, 56, 242, 8, 157, 92, 236, 205, 252, 68, 242, 80, 46, 223, + 98, 1, 0, 0, 0, 236, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0, + 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 112, 2, 0, 0, 82, 68, 69, 70, 112, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 69, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0, + 0, 3, 0, 0, 0, 8, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 73, 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, 49, 48, 46, 49, 0, 171, 171, + 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, 79, 83, + 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, + 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, + 82, 68, 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, 2, 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, 0, 1, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 88, 40, 0, 4, + 0, 112, 16, 0, 0, 0, 0, 0, 51, 51, 0, 0, 98, 16, 0, 3, 114, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, 61, 16, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 86, 0, 0, 5, + 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, + 7, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18, + 16, 0, 2, 0, 0, 0, 27, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 18, 32, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, + 0, 0, 8, 226, 32, 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, 62, 0, 0, 1, 83, 84, 65, + 84, 116, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3dui11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3dui11ps.h new file mode 100644 index 0000000000..040b333116 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3dui11ps.h @@ -0,0 +1,86 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureUI texture uint4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_resource_texture3d (uint,uint,uint,uint) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xyz, r0.xyzx +mul r0.xyz, r0.xyzx, v2.xyzx +ftoi r0.xyz, r0.xyzx +mov r0.w, l(0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov o0.x, r0.x +mov o0.yzw, l(0,0,0,0) +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_PassthroughR3DUI[] = { + 68, 88, 66, 67, 125, 15, 246, 192, 16, 228, 182, 55, 2, 24, 75, 71, 132, 253, 233, + 61, 1, 0, 0, 0, 236, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0, + 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 112, 2, 0, 0, 82, 68, 69, 70, 112, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 70, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0, + 0, 4, 0, 0, 0, 8, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 85, 73, 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, 49, 48, 46, 49, 0, 171, + 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, 79, 83, + 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, + 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, + 82, 68, 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, 1, 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, 0, 1, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 88, 40, 0, 4, + 0, 112, 16, 0, 0, 0, 0, 0, 68, 68, 0, 0, 98, 16, 0, 3, 114, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, 61, 16, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 86, 0, 0, 5, + 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, + 7, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18, + 16, 0, 2, 0, 0, 0, 27, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 18, 32, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, + 0, 0, 8, 226, 32, 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, 62, 0, 0, 1, 83, 84, 65, + 84, 116, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2d11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2d11ps.h new file mode 100644 index 0000000000..a9373f69ab --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2d11ps.h @@ -0,0 +1,104 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +// +// Sampler/Resource to DX9 shader sampler mappings: +// +// Target Sampler Source Sampler Source Resource +// -------------- --------------- ---------------- +// s0 s0 t0 +// +// +// Level9 shader bytecode: +// + ps_2_x + def c0, 1, 0, 0, 0 + dcl t0.xy + dcl_2d s0 + texld r0, t0, s0 + mad r0, r0.xyxx, c0.xxyy, c0.yyyx + mov oC0, r0 + +// approximately 3 instruction slots used (1 texture, 2 arithmetic) +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +mov o0.xy, r0.xyxx +mov o0.zw, l(0,0,0,1.000000) +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_PassthroughRG2D[] = { + 68, 88, 66, 67, 151, 54, 111, 200, 187, 200, 177, 214, 12, 69, 246, 113, 254, 31, 23, + 45, 1, 0, 0, 0, 32, 3, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 208, 0, + 0, 0, 120, 1, 0, 0, 244, 1, 0, 0, 148, 2, 0, 0, 236, 2, 0, 0, 65, + 111, 110, 57, 144, 0, 0, 0, 144, 0, 0, 0, 0, 2, 255, 255, 104, 0, 0, 0, + 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, + 0, 0, 0, 40, 0, 0, 0, 0, 0, 1, 2, 255, 255, 81, 0, 0, 5, 0, 0, + 15, 160, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, + 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 144, + 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, + 160, 4, 0, 0, 4, 0, 0, 15, 128, 0, 0, 4, 128, 0, 0, 80, 160, 0, 0, + 21, 160, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, + 72, 68, 82, 160, 0, 0, 0, 64, 0, 0, 0, 40, 0, 0, 0, 90, 0, 0, 3, + 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 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, 1, 0, 0, 0, 69, + 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, + 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, 0, 0, + 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 54, 0, + 0, 8, 194, 32, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, + 116, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, + 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 152, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 0, 1, 0, 0, + 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 100, 0, + 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 83, 97, 109, 112, 108, 101, 114, 0, + 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 80, + 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, + 79, 82, 68, 0, 171, 171, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2darray11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2darray11ps.h new file mode 100644 index 0000000000..e97f66a770 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2darray11ps.h @@ -0,0 +1,86 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +mov o0.xy, r0.xyxx +mov o0.zw, l(0,0,0,1.000000) +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_PassthroughRG2DArray[] = { + 68, 88, 66, 67, 20, 85, 120, 206, 181, 139, 167, 245, 44, 89, 37, 135, 242, 39, 108, + 150, 1, 0, 0, 0, 236, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 112, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 216, 0, 0, 0, 64, 0, 0, 0, 54, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 64, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, 18, 16, 16, 0, 1, 0, 0, 0, + 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, + 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 86, 0, + 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 1, 0, 0, 0, 54, + 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 2, 0, 0, 0, + 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, + 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 54, + 0, 0, 8, 194, 32, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, + 84, 116, 0, 0, 0, 6, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2darrayi11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2darrayi11ps.h new file mode 100644 index 0000000000..f7ac20960d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2darrayi11ps.h @@ -0,0 +1,90 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureI texture sint4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_resource_texture2darray (sint,sint,sint,sint) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v2.xyxx +ftoi r0.xy, r0.xyxx +mov r0.z, v1.x +mov r0.w, l(0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov o0.xy, r0.xyxx +mov o0.zw, l(0,0,0,1) +ret +// Approximately 10 instruction slots used +#endif + +const BYTE g_PS_PassthroughRG2DArrayI[] = { + 68, 88, 66, 67, 221, 150, 25, 83, 110, 171, 138, 218, 81, 94, 8, 224, 63, 191, 253, + 25, 1, 0, 0, 0, 16, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0, + 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 148, 2, 0, 0, 82, 68, 69, 70, 112, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 69, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0, + 0, 3, 0, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 73, 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, 49, 48, 46, 49, 0, 171, 171, + 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, + 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, + 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, + 82, 68, 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, 2, 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, 36, 1, 0, 0, 64, 0, 0, 0, 73, 0, 0, 0, 88, 64, 0, 4, + 0, 112, 16, 0, 0, 0, 0, 0, 51, 51, 0, 0, 100, 8, 0, 4, 18, 16, 16, + 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0, + 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, + 0, 0, 0, 61, 16, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 70, 126, 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, 2, + 0, 0, 0, 27, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, + 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 50, 32, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, + 8, 194, 32, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, + 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, + 1, 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, 4, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2darrayui11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2darrayui11ps.h new file mode 100644 index 0000000000..2caa7b3b80 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2darrayui11ps.h @@ -0,0 +1,90 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureUI texture uint4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_resource_texture2darray (uint,uint,uint,uint) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v2.xyxx +ftoi r0.xy, r0.xyxx +mov r0.z, v1.x +mov r0.w, l(0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov o0.xy, r0.xyxx +mov o0.zw, l(0,0,0,1) +ret +// Approximately 10 instruction slots used +#endif + +const BYTE g_PS_PassthroughRG2DArrayUI[] = { + 68, 88, 66, 67, 120, 173, 124, 47, 122, 95, 175, 210, 44, 74, 36, 182, 242, 25, 225, + 20, 1, 0, 0, 0, 16, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0, + 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 148, 2, 0, 0, 82, 68, 69, 70, 112, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 70, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0, + 0, 4, 0, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 85, 73, 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, 49, 48, 46, 49, 0, 171, + 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, + 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, + 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, + 82, 68, 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, 1, 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, 36, 1, 0, 0, 64, 0, 0, 0, 73, 0, 0, 0, 88, 64, 0, 4, + 0, 112, 16, 0, 0, 0, 0, 0, 68, 68, 0, 0, 100, 8, 0, 4, 18, 16, 16, + 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0, + 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, + 0, 0, 0, 61, 16, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 70, 126, 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, 2, + 0, 0, 0, 27, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, + 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 50, 32, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, + 8, 194, 32, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, + 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, + 1, 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, 4, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2di11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2di11ps.h new file mode 100644 index 0000000000..25f0638e82 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2di11ps.h @@ -0,0 +1,83 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureI texture sint4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_resource_texture2d (sint,sint,sint,sint) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v1.xyxx +ftoi r0.xy, r0.xyxx +mov r0.zw, l(0,0,0,0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov o0.xy, r0.xyxx +mov o0.zw, l(0,0,0,0) +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_PassthroughRG2DI[] = { + 68, 88, 66, 67, 161, 76, 0, 115, 100, 69, 2, 128, 179, 140, 112, 55, 172, 151, 175, + 231, 1, 0, 0, 0, 200, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0, + 0, 0, 4, 1, 0, 0, 56, 1, 0, 0, 76, 2, 0, 0, 82, 68, 69, 70, 112, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 69, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0, + 0, 3, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 73, 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, 49, 48, 46, 49, 0, 171, 171, + 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 2, 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, 12, 1, 0, 0, 64, 0, 0, + 0, 67, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 51, 51, + 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, 1, 0, 0, 0, 61, 16, 0, 7, + 242, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 126, 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, 27, 0, 0, 5, + 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 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, 45, 0, 0, 7, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, + 0, 54, 0, 0, 8, 194, 32, 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, 62, 0, 0, 1, 83, + 84, 65, 84, 116, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2dui11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2dui11ps.h new file mode 100644 index 0000000000..cf9f8c793b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2dui11ps.h @@ -0,0 +1,83 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureUI texture uint4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_resource_texture2d (uint,uint,uint,uint) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v1.xyxx +ftoi r0.xy, r0.xyxx +mov r0.zw, l(0,0,0,0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov o0.xy, r0.xyxx +mov o0.zw, l(0,0,0,0) +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_PassthroughRG2DUI[] = { + 68, 88, 66, 67, 161, 19, 0, 215, 231, 88, 50, 183, 124, 43, 107, 122, 144, 150, 193, + 168, 1, 0, 0, 0, 200, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0, + 0, 0, 4, 1, 0, 0, 56, 1, 0, 0, 76, 2, 0, 0, 82, 68, 69, 70, 112, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 70, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0, + 0, 4, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 85, 73, 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, 49, 48, 46, 49, 0, 171, + 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 1, 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, 12, 1, 0, 0, 64, 0, 0, + 0, 67, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 68, 68, + 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, 1, 0, 0, 0, 61, 16, 0, 7, + 242, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 126, 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, 27, 0, 0, 5, + 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 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, 45, 0, 0, 7, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, + 0, 54, 0, 0, 8, 194, 32, 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, 62, 0, 0, 1, 83, + 84, 65, 84, 116, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3d11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3d11ps.h new file mode 100644 index 0000000000..f9d91f7bd7 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3d11ps.h @@ -0,0 +1,80 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +mov o0.xy, r0.xyxx +mov o0.zw, l(0,0,0,1.000000) +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_PassthroughRG3D[] = { + 68, 88, 66, 67, 234, 174, 205, 77, 197, 154, 113, 172, 235, 131, 32, 212, 121, 65, 136, + 164, 1, 0, 0, 0, 180, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 56, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 160, 0, 0, 0, 64, 0, 0, 0, 40, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, + 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 32, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, + 65, 84, 116, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, + 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, + 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3di11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3di11ps.h new file mode 100644 index 0000000000..53b5685cd6 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3di11ps.h @@ -0,0 +1,86 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureI texture sint4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_resource_texture3d (sint,sint,sint,sint) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xyz, r0.xyzx +mul r0.xyz, r0.xyzx, v2.xyzx +ftoi r0.xyz, r0.xyzx +mov r0.w, l(0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov o0.xy, r0.xyxx +mov o0.zw, l(0,0,0,0) +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_PassthroughRG3DI[] = { + 68, 88, 66, 67, 215, 62, 152, 236, 50, 188, 41, 213, 133, 37, 41, 228, 13, 20, 9, + 166, 1, 0, 0, 0, 236, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0, + 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 112, 2, 0, 0, 82, 68, 69, 70, 112, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 69, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0, + 0, 3, 0, 0, 0, 8, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 73, 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, 49, 48, 46, 49, 0, 171, 171, + 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, 79, 83, + 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, + 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, + 82, 68, 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, 2, 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, 0, 1, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 88, 40, 0, 4, + 0, 112, 16, 0, 0, 0, 0, 0, 51, 51, 0, 0, 98, 16, 0, 3, 114, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, 61, 16, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 86, 0, 0, 5, + 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, + 7, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18, + 16, 0, 2, 0, 0, 0, 27, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 54, + 0, 0, 8, 194, 32, 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, 62, 0, 0, 1, 83, 84, 65, + 84, 116, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3dui11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3dui11ps.h new file mode 100644 index 0000000000..de7c00b8cb --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3dui11ps.h @@ -0,0 +1,86 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureUI texture uint4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_resource_texture3d (uint,uint,uint,uint) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xyz, r0.xyzx +mul r0.xyz, r0.xyzx, v2.xyzx +ftoi r0.xyz, r0.xyzx +mov r0.w, l(0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov o0.xy, r0.xyxx +mov o0.zw, l(0,0,0,0) +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_PassthroughRG3DUI[] = { + 68, 88, 66, 67, 136, 113, 120, 69, 210, 200, 206, 216, 193, 132, 168, 220, 72, 141, 170, + 116, 1, 0, 0, 0, 236, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0, + 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 112, 2, 0, 0, 82, 68, 69, 70, 112, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 70, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0, + 0, 4, 0, 0, 0, 8, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 85, 73, 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, 49, 48, 46, 49, 0, 171, + 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, 79, 83, + 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, + 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, + 82, 68, 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, 1, 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, 0, 1, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 88, 40, 0, 4, + 0, 112, 16, 0, 0, 0, 0, 0, 68, 68, 0, 0, 98, 16, 0, 3, 114, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, 61, 16, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 86, 0, 0, 5, + 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, + 7, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18, + 16, 0, 2, 0, 0, 0, 27, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 54, + 0, 0, 8, 194, 32, 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, 62, 0, 0, 1, 83, 84, 65, + 84, 116, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d11ps.h new file mode 100644 index 0000000000..7187de985f --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d11ps.h @@ -0,0 +1,103 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +// +// Sampler/Resource to DX9 shader sampler mappings: +// +// Target Sampler Source Sampler Source Resource +// -------------- --------------- ---------------- +// s0 s0 t0 +// +// +// Level9 shader bytecode: +// + ps_2_x + def c0, 1, 0, 0, 0 + dcl t0.xy + dcl_2d s0 + texld r0, t0, s0 + mad r0, r0.xyzx, c0.xxxy, c0.yyyx + mov oC0, r0 + +// approximately 3 instruction slots used (1 texture, 2 arithmetic) +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +mov o0.xyz, r0.xyzx +mov o0.w, l(1.000000) +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGB2D[] = { + 68, 88, 66, 67, 250, 48, 137, 17, 146, 199, 249, 10, 198, 141, 227, 123, 246, 248, 120, + 90, 1, 0, 0, 0, 20, 3, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 208, 0, + 0, 0, 108, 1, 0, 0, 232, 1, 0, 0, 136, 2, 0, 0, 224, 2, 0, 0, 65, + 111, 110, 57, 144, 0, 0, 0, 144, 0, 0, 0, 0, 2, 255, 255, 104, 0, 0, 0, + 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, + 0, 0, 0, 40, 0, 0, 0, 0, 0, 1, 2, 255, 255, 81, 0, 0, 5, 0, 0, + 15, 160, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, + 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 144, + 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, + 160, 4, 0, 0, 4, 0, 0, 15, 128, 0, 0, 36, 128, 0, 0, 64, 160, 0, 0, + 21, 160, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, + 72, 68, 82, 148, 0, 0, 0, 64, 0, 0, 0, 37, 0, 0, 0, 90, 0, 0, 3, + 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 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, 1, 0, 0, 0, 69, + 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, + 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, 0, 0, + 5, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 62, + 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 2, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 152, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, + 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 83, + 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, 171, + 171, 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d_565_11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d_565_11ps.h new file mode 100644 index 0000000000..7807225fa7 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d_565_11ps.h @@ -0,0 +1,118 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +// +// Sampler/Resource to DX9 shader sampler mappings: +// +// Target Sampler Source Sampler Source Resource +// -------------- --------------- ---------------- +// s0 s0 t0 +// +// +// Level9 shader bytecode: +// + ps_2_x + def c0, 31, 63, 0.5, 1 + def c1, 0.0322580636, 0.0158730168, 0, 0 + dcl t0.xy + dcl_2d s0 + texld r0, t0, s0 + mad r0.xyz, r0, c0.xyxw, c0.z + frc r1.xyz, r0 + add r0.xyz, r0, -r1 + mul r0.xyz, r0, c1.xyxw + mov r0.w, c0.w + mov oC0, r0 + +// approximately 7 instruction slots used (1 texture, 6 arithmetic) +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +mul r0.xyz, r0.xyzx, l(31.000000, 63.000000, 31.000000, 0.000000) +round_ne r0.xyz, r0.xyzx +mul o0.xyz, r0.xyzx, l(0.032258, 0.015873, 0.032258, 0.000000) +mov o0.w, l(1.000000) +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGB2D_565[] = { + 68, 88, 66, 67, 120, 69, 206, 120, 97, 29, 104, 168, 87, 8, 112, 9, 57, 119, 88, + 99, 1, 0, 0, 0, 180, 3, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 32, 1, + 0, 0, 12, 2, 0, 0, 136, 2, 0, 0, 40, 3, 0, 0, 128, 3, 0, 0, 65, + 111, 110, 57, 224, 0, 0, 0, 224, 0, 0, 0, 0, 2, 255, 255, 184, 0, 0, 0, + 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, + 0, 0, 0, 40, 0, 0, 0, 0, 0, 1, 2, 255, 255, 81, 0, 0, 5, 0, 0, + 15, 160, 0, 0, 248, 65, 0, 0, 124, 66, 0, 0, 0, 63, 0, 0, 128, 63, 81, + 0, 0, 5, 1, 0, 15, 160, 8, 33, 4, 61, 33, 8, 130, 60, 0, 0, 0, 0, + 0, 0, 0, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, + 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, + 228, 176, 0, 8, 228, 160, 4, 0, 0, 4, 0, 0, 7, 128, 0, 0, 228, 128, 0, + 0, 196, 160, 0, 0, 170, 160, 19, 0, 0, 2, 1, 0, 7, 128, 0, 0, 228, 128, + 2, 0, 0, 3, 0, 0, 7, 128, 0, 0, 228, 128, 1, 0, 228, 129, 5, 0, 0, + 3, 0, 0, 7, 128, 0, 0, 228, 128, 1, 0, 196, 160, 1, 0, 0, 2, 0, 0, + 8, 128, 0, 0, 255, 160, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, + 255, 0, 0, 83, 72, 68, 82, 228, 0, 0, 0, 64, 0, 0, 0, 57, 0, 0, 0, + 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 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, 1, + 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, + 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, + 0, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 124, 66, 0, 0, 248, 65, 0, + 0, 0, 0, 64, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, + 0, 0, 0, 0, 56, 0, 0, 10, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 33, 4, 61, 33, 8, 130, 60, 8, 33, + 4, 61, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, + 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 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, 1, + 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, 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, 82, 68, 69, 70, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, + 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, + 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, + 0, 0, 0, 13, 0, 0, 0, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, + 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, + 171, 171, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darray11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darray11ps.h new file mode 100644 index 0000000000..22fc48b370 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darray11ps.h @@ -0,0 +1,85 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +mov o0.xyz, r0.xyzx +mov o0.w, l(1.000000) +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGB2DArray[] = { + 68, 88, 66, 67, 26, 40, 103, 223, 174, 169, 46, 176, 180, 125, 61, 98, 234, 113, 13, + 48, 1, 0, 0, 0, 224, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 100, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 204, 0, 0, 0, 64, 0, 0, 0, 51, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 64, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, 18, 16, 16, 0, 1, 0, 0, 0, + 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, + 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 86, 0, + 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 1, 0, 0, 0, 54, + 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 2, 0, 0, 0, + 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, + 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 54, + 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, + 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, 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, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darray_565_11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darray_565_11ps.h new file mode 100644 index 0000000000..93c8675762 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darray_565_11ps.h @@ -0,0 +1,91 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +mul r0.xyz, r0.xyzx, l(31.000000, 63.000000, 31.000000, 0.000000) +round_ne r0.xyz, r0.xyzx +mul o0.xyz, r0.xyzx, l(0.032258, 0.015873, 0.032258, 0.000000) +mov o0.w, l(1.000000) +ret +// Approximately 8 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGB2DArray_565[] = { + 68, 88, 66, 67, 185, 16, 51, 115, 29, 189, 183, 180, 27, 245, 224, 140, 177, 41, 213, + 79, 1, 0, 0, 0, 48, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 180, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 28, 1, 0, 0, 64, 0, 0, 0, 71, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 64, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, 18, 16, 16, 0, 1, 0, 0, 0, + 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, + 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 86, 0, + 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 1, 0, 0, 0, 54, + 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 2, 0, 0, 0, + 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, + 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56, 0, + 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 248, 65, 0, 0, 124, 66, 0, 0, 248, 65, 0, 0, 0, 0, + 64, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, + 0, 56, 0, 0, 10, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 8, 33, 4, 61, 33, 8, 130, 60, 8, 33, 4, 61, 0, + 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 8, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 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, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darrayi11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darrayi11ps.h new file mode 100644 index 0000000000..da517dedc7 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darrayi11ps.h @@ -0,0 +1,89 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureI texture sint4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_resource_texture2darray (sint,sint,sint,sint) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v2.xyxx +ftoi r0.xy, r0.xyxx +mov r0.z, v1.x +mov r0.w, l(0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov o0.xyz, r0.xyzx +mov o0.w, l(1) +ret +// Approximately 10 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGB2DArrayI[] = { + 68, 88, 66, 67, 176, 173, 178, 89, 17, 53, 136, 1, 253, 33, 56, 172, 20, 106, 131, + 127, 1, 0, 0, 0, 4, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0, + 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 136, 2, 0, 0, 82, 68, 69, 70, 112, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 69, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0, + 0, 3, 0, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 73, 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, 49, 48, 46, 49, 0, 171, 171, + 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, + 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, + 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, + 82, 68, 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, 2, 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, 24, 1, 0, 0, 64, 0, 0, 0, 70, 0, 0, 0, 88, 64, 0, 4, + 0, 112, 16, 0, 0, 0, 0, 0, 51, 51, 0, 0, 100, 8, 0, 4, 18, 16, 16, + 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0, + 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, + 0, 0, 0, 61, 16, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 70, 126, 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, 2, + 0, 0, 0, 27, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, + 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, + 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 1, 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, 4, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darrayui11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darrayui11ps.h new file mode 100644 index 0000000000..3b33754c28 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darrayui11ps.h @@ -0,0 +1,89 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureUI texture uint4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_resource_texture2darray (uint,uint,uint,uint) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v2.xyxx +ftoi r0.xy, r0.xyxx +mov r0.z, v1.x +mov r0.w, l(0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov o0.xyz, r0.xyzx +mov o0.w, l(1) +ret +// Approximately 10 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGB2DArrayUI[] = { + 68, 88, 66, 67, 239, 124, 234, 46, 158, 116, 212, 164, 152, 122, 22, 86, 114, 177, 255, + 160, 1, 0, 0, 0, 4, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0, + 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 136, 2, 0, 0, 82, 68, 69, 70, 112, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 70, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0, + 0, 4, 0, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 85, 73, 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, 49, 48, 46, 49, 0, 171, + 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, + 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, + 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, + 82, 68, 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, 1, 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, 24, 1, 0, 0, 64, 0, 0, 0, 70, 0, 0, 0, 88, 64, 0, 4, + 0, 112, 16, 0, 0, 0, 0, 0, 68, 68, 0, 0, 100, 8, 0, 4, 18, 16, 16, + 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0, + 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, + 0, 0, 0, 61, 16, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 70, 126, 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, 2, + 0, 0, 0, 27, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, + 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, + 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 1, 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, 4, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2di11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2di11ps.h new file mode 100644 index 0000000000..79ff3c4168 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2di11ps.h @@ -0,0 +1,82 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureI texture sint4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_resource_texture2d (sint,sint,sint,sint) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v1.xyxx +ftoi r0.xy, r0.xyxx +mov r0.zw, l(0,0,0,0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov o0.xyz, r0.xyzx +mov o0.w, l(0) +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGB2DI[] = { + 68, 88, 66, 67, 190, 234, 127, 190, 151, 71, 156, 183, 160, 74, 156, 153, 91, 12, 95, + 85, 1, 0, 0, 0, 188, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0, + 0, 0, 4, 1, 0, 0, 56, 1, 0, 0, 64, 2, 0, 0, 82, 68, 69, 70, 112, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 69, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0, + 0, 3, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 73, 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, 49, 48, 46, 49, 0, 171, 171, + 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 2, 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, 0, 1, 0, 0, 64, 0, 0, + 0, 64, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 51, 51, + 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, 1, 0, 0, 0, 61, 16, 0, 7, + 242, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 126, 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, 27, 0, 0, 5, + 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 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, 45, 0, 0, 7, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, + 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 9, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2dui11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2dui11ps.h new file mode 100644 index 0000000000..74ef0a2236 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2dui11ps.h @@ -0,0 +1,82 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureUI texture uint4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_resource_texture2d (uint,uint,uint,uint) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v1.xyxx +ftoi r0.xy, r0.xyxx +mov r0.zw, l(0,0,0,0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov o0.xyz, r0.xyzx +mov o0.w, l(0) +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGB2DUI[] = { + 68, 88, 66, 67, 240, 47, 31, 84, 32, 155, 233, 36, 235, 43, 92, 251, 152, 13, 113, + 169, 1, 0, 0, 0, 188, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0, + 0, 0, 4, 1, 0, 0, 56, 1, 0, 0, 64, 2, 0, 0, 82, 68, 69, 70, 112, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 70, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0, + 0, 4, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 85, 73, 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, 49, 48, 46, 49, 0, 171, + 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 1, 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, 0, 1, 0, 0, 64, 0, 0, + 0, 64, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 68, 68, + 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, 1, 0, 0, 0, 61, 16, 0, 7, + 242, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 126, 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, 27, 0, 0, 5, + 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 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, 45, 0, 0, 7, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, + 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 9, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d11ps.h new file mode 100644 index 0000000000..b533c74d77 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d11ps.h @@ -0,0 +1,79 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +mov o0.xyz, r0.xyzx +mov o0.w, l(1.000000) +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGB3D[] = { + 68, 88, 66, 67, 121, 178, 78, 177, 99, 144, 108, 81, 39, 245, 135, 91, 55, 31, 56, + 111, 1, 0, 0, 0, 168, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 44, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 148, 0, 0, 0, 64, 0, 0, 0, 37, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, + 0, 0, 5, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, + 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 4, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 2, 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, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d_565_11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d_565_11ps.h new file mode 100644 index 0000000000..5222d51cc3 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d_565_11ps.h @@ -0,0 +1,85 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +mul r0.xyz, r0.xyzx, l(31.000000, 63.000000, 31.000000, 0.000000) +round_ne r0.xyz, r0.xyzx +mul o0.xyz, r0.xyzx, l(0.032258, 0.015873, 0.032258, 0.000000) +mov o0.w, l(1.000000) +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGB3D_565[] = { + 68, 88, 66, 67, 190, 139, 108, 54, 112, 70, 128, 98, 155, 40, 89, 132, 48, 127, 91, + 244, 1, 0, 0, 0, 248, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 124, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 228, 0, 0, 0, 64, 0, 0, 0, 57, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 124, 66, 0, 0, 248, 65, 0, 0, 0, + 0, 64, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, + 0, 0, 56, 0, 0, 10, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 8, 33, 4, 61, 33, 8, 130, 60, 8, 33, 4, 61, + 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 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, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3di11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3di11ps.h new file mode 100644 index 0000000000..9e590b3ebb --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3di11ps.h @@ -0,0 +1,85 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureI texture sint4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_resource_texture3d (sint,sint,sint,sint) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xyz, r0.xyzx +mul r0.xyz, r0.xyzx, v2.xyzx +ftoi r0.xyz, r0.xyzx +mov r0.w, l(0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov o0.xyz, r0.xyzx +mov o0.w, l(0) +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGB3DI[] = { + 68, 88, 66, 67, 122, 80, 149, 91, 225, 62, 16, 173, 12, 194, 248, 74, 159, 33, 217, + 135, 1, 0, 0, 0, 224, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0, + 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 100, 2, 0, 0, 82, 68, 69, 70, 112, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 69, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0, + 0, 3, 0, 0, 0, 8, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 73, 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, 49, 48, 46, 49, 0, 171, 171, + 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, 79, 83, + 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, + 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, + 82, 68, 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, 2, 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, 244, 0, 0, 0, 64, 0, 0, 0, 61, 0, 0, 0, 88, 40, 0, 4, + 0, 112, 16, 0, 0, 0, 0, 0, 51, 51, 0, 0, 98, 16, 0, 3, 114, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, 61, 16, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 86, 0, 0, 5, + 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, + 7, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18, + 16, 0, 2, 0, 0, 0, 27, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 54, + 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3dui11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3dui11ps.h new file mode 100644 index 0000000000..534b9d9faa --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3dui11ps.h @@ -0,0 +1,85 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureUI texture uint4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_resource_texture3d (uint,uint,uint,uint) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xyz, r0.xyzx +mul r0.xyz, r0.xyzx, v2.xyzx +ftoi r0.xyz, r0.xyzx +mov r0.w, l(0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov o0.xyz, r0.xyzx +mov o0.w, l(0) +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGB3DUI[] = { + 68, 88, 66, 67, 177, 156, 23, 109, 67, 253, 176, 134, 182, 213, 173, 70, 148, 235, 60, + 205, 1, 0, 0, 0, 224, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0, + 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 100, 2, 0, 0, 82, 68, 69, 70, 112, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 70, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0, + 0, 4, 0, 0, 0, 8, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 85, 73, 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, 49, 48, 46, 49, 0, 171, + 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, 79, 83, + 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, + 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, + 82, 68, 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, 1, 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, 244, 0, 0, 0, 64, 0, 0, 0, 61, 0, 0, 0, 88, 40, 0, 4, + 0, 112, 16, 0, 0, 0, 0, 0, 68, 68, 0, 0, 98, 16, 0, 3, 114, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, 61, 16, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 86, 0, 0, 5, + 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, + 7, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18, + 16, 0, 2, 0, 0, 0, 27, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 54, + 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h new file mode 100644 index 0000000000..f8b36063f2 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h @@ -0,0 +1,93 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +// +// Sampler/Resource to DX9 shader sampler mappings: +// +// Target Sampler Source Sampler Source Resource +// -------------- --------------- ---------------- +// s0 s0 t0 +// +// +// Level9 shader bytecode: +// + ps_2_x + dcl t0.xy + dcl_2d s0 + texld r0, t0, s0 + mov oC0, r0 + +// approximately 2 instruction slots used (1 texture, 1 arithmetic) +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +sample o0.xyzw, v1.xyxx, t0.xyzw, s0 +ret +// Approximately 2 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGBA2D[] = { + 68, 88, 66, 67, 23, 65, 12, 167, 50, 71, 137, 250, 170, 67, 18, 134, 110, 213, 196, + 219, 1, 0, 0, 0, 184, 2, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 164, 0, + 0, 0, 16, 1, 0, 0, 140, 1, 0, 0, 44, 2, 0, 0, 132, 2, 0, 0, 65, + 111, 110, 57, 100, 0, 0, 0, 100, 0, 0, 0, 0, 2, 255, 255, 60, 0, 0, 0, + 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, + 0, 0, 0, 40, 0, 0, 0, 0, 0, 1, 2, 255, 255, 31, 0, 0, 2, 0, 0, + 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, + 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 1, 0, 0, 2, + 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 100, 0, 0, + 0, 64, 0, 0, 0, 25, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, + 0, 0, 88, 24, 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, 69, 0, 0, 9, 242, 32, 16, 0, 0, 0, 0, 0, 70, 16, 16, + 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, + 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 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, 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, 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, 82, 68, 69, + 70, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, + 0, 0, 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, + 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, + 0, 0, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, + 49, 0, 171, 171, 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d_4444_11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d_4444_11ps.h new file mode 100644 index 0000000000..2f94f13c12 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d_4444_11ps.h @@ -0,0 +1,112 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +// +// Sampler/Resource to DX9 shader sampler mappings: +// +// Target Sampler Source Sampler Source Resource +// -------------- --------------- ---------------- +// s0 s0 t0 +// +// +// Level9 shader bytecode: +// + ps_2_x + def c0, 15, 0.5, 0.0666666701, 0 + dcl t0.xy + dcl_2d s0 + texld r0, t0, s0 + mad r0, r0, c0.x, c0.y + frc r1, r0 + add r0, r0, -r1 + mul r0, r0, c0.z + mov oC0, r0 + +// approximately 6 instruction slots used (1 texture, 5 arithmetic) +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +mul r0.xyzw, r0.xyzw, l(15.000000, 15.000000, 15.000000, 15.000000) +round_ne r0.xyzw, r0.xyzw +mul o0.xyzw, r0.xyzw, l(0.066667, 0.066667, 0.066667, 0.066667) +ret +// Approximately 5 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGBA2D_4444[] = { + 68, 88, 66, 67, 188, 56, 0, 47, 220, 85, 24, 210, 59, 166, 131, 1, 131, 90, 227, + 171, 1, 0, 0, 0, 124, 3, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 252, 0, + 0, 0, 212, 1, 0, 0, 80, 2, 0, 0, 240, 2, 0, 0, 72, 3, 0, 0, 65, + 111, 110, 57, 188, 0, 0, 0, 188, 0, 0, 0, 0, 2, 255, 255, 148, 0, 0, 0, + 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, + 0, 0, 0, 40, 0, 0, 0, 0, 0, 1, 2, 255, 255, 81, 0, 0, 5, 0, 0, + 15, 160, 0, 0, 112, 65, 0, 0, 0, 63, 137, 136, 136, 61, 0, 0, 0, 0, 31, + 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 144, + 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, + 160, 4, 0, 0, 4, 0, 0, 15, 128, 0, 0, 228, 128, 0, 0, 0, 160, 0, 0, + 85, 160, 19, 0, 0, 2, 1, 0, 15, 128, 0, 0, 228, 128, 2, 0, 0, 3, 0, + 0, 15, 128, 0, 0, 228, 128, 1, 0, 228, 129, 5, 0, 0, 3, 0, 0, 15, 128, + 0, 0, 228, 128, 0, 0, 170, 160, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, + 128, 255, 255, 0, 0, 83, 72, 68, 82, 208, 0, 0, 0, 64, 0, 0, 0, 52, 0, + 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 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, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 16, + 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, + 65, 0, 0, 112, 65, 64, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, + 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 32, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 137, 136, 136, 61, 137, 136, 136, 61, + 137, 136, 136, 61, 137, 136, 136, 61, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, + 0, 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 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, + 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 82, 68, 69, 70, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, + 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, + 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 13, 0, 0, 0, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, + 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, + 0, 171, 171, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d_5551_11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d_5551_11ps.h new file mode 100644 index 0000000000..44966d6a9b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d_5551_11ps.h @@ -0,0 +1,112 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +// +// Sampler/Resource to DX9 shader sampler mappings: +// +// Target Sampler Source Sampler Source Resource +// -------------- --------------- ---------------- +// s0 s0 t0 +// +// +// Level9 shader bytecode: +// + ps_2_x + def c0, 31, 1, 0.5, 0.0322580636 + dcl t0.xy + dcl_2d s0 + texld r0, t0, s0 + mad r0, r0, c0.xxxy, c0.z + frc r1, r0 + add r0, r0, -r1 + mul r0, r0, c0.wwwy + mov oC0, r0 + +// approximately 6 instruction slots used (1 texture, 5 arithmetic) +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +mul r0.xyzw, r0.xyzw, l(31.000000, 31.000000, 31.000000, 1.000000) +round_ne r0.xyzw, r0.xyzw +mul o0.xyzw, r0.xyzw, l(0.032258, 0.032258, 0.032258, 1.000000) +ret +// Approximately 5 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGBA2D_5551[] = { + 68, 88, 66, 67, 202, 32, 204, 89, 54, 13, 5, 203, 247, 109, 207, 183, 162, 90, 24, + 32, 1, 0, 0, 0, 124, 3, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 252, 0, + 0, 0, 212, 1, 0, 0, 80, 2, 0, 0, 240, 2, 0, 0, 72, 3, 0, 0, 65, + 111, 110, 57, 188, 0, 0, 0, 188, 0, 0, 0, 0, 2, 255, 255, 148, 0, 0, 0, + 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, + 0, 0, 0, 40, 0, 0, 0, 0, 0, 1, 2, 255, 255, 81, 0, 0, 5, 0, 0, + 15, 160, 0, 0, 248, 65, 0, 0, 128, 63, 0, 0, 0, 63, 8, 33, 4, 61, 31, + 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 144, + 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, + 160, 4, 0, 0, 4, 0, 0, 15, 128, 0, 0, 228, 128, 0, 0, 64, 160, 0, 0, + 170, 160, 19, 0, 0, 2, 1, 0, 15, 128, 0, 0, 228, 128, 2, 0, 0, 3, 0, + 0, 15, 128, 0, 0, 228, 128, 1, 0, 228, 129, 5, 0, 0, 3, 0, 0, 15, 128, + 0, 0, 228, 128, 0, 0, 127, 160, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, + 128, 255, 255, 0, 0, 83, 72, 68, 82, 208, 0, 0, 0, 64, 0, 0, 0, 52, 0, + 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 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, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 16, + 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, 248, + 65, 0, 0, 128, 63, 64, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, + 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 32, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 33, 4, 61, 8, 33, 4, 61, + 8, 33, 4, 61, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, + 0, 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 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, + 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 82, 68, 69, 70, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, + 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, + 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 13, 0, 0, 0, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, + 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, + 0, 171, 171, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darray11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darray11ps.h new file mode 100644 index 0000000000..227aab3bf9 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darray11ps.h @@ -0,0 +1,81 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample o0.xyzw, r0.xyzx, t0.xyzw, s0 +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGBA2DArray[] = { + 68, 88, 66, 67, 200, 215, 233, 151, 66, 46, 221, 224, 83, 242, 34, 162, 166, 5, 137, + 148, 1, 0, 0, 0, 184, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 60, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 164, 0, 0, 0, 64, 0, 0, 0, 41, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 64, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, 18, 16, 16, 0, 1, 0, 0, 0, + 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, + 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 86, 0, + 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 1, 0, 0, 0, 54, + 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 2, 0, 0, 0, + 69, 0, 0, 9, 242, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, + 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 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, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darray_4444_11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darray_4444_11ps.h new file mode 100644 index 0000000000..24011717c7 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darray_4444_11ps.h @@ -0,0 +1,89 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +mul r0.xyzw, r0.xyzw, l(15.000000, 15.000000, 15.000000, 15.000000) +round_ne r0.xyzw, r0.xyzw +mul o0.xyzw, r0.xyzw, l(0.066667, 0.066667, 0.066667, 0.066667) +ret +// Approximately 7 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGBA2DArray_4444[] = { + 68, 88, 66, 67, 88, 17, 60, 194, 201, 5, 168, 96, 74, 117, 234, 137, 214, 224, 224, + 134, 1, 0, 0, 0, 28, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 160, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 8, 1, 0, 0, 64, 0, 0, 0, 66, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 64, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, 18, 16, 16, 0, 1, 0, 0, 0, + 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, + 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 86, 0, + 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 1, 0, 0, 0, 54, + 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 2, 0, 0, 0, + 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, + 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56, 0, + 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, 65, + 64, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, + 0, 56, 0, 0, 10, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 137, 136, 136, 61, 137, 136, 136, 61, 137, 136, 136, 61, 137, + 136, 136, 61, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 7, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 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, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darray_5551_11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darray_5551_11ps.h new file mode 100644 index 0000000000..f6335bccef --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darray_5551_11ps.h @@ -0,0 +1,89 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +mul r0.xyzw, r0.xyzw, l(31.000000, 31.000000, 31.000000, 1.000000) +round_ne r0.xyzw, r0.xyzw +mul o0.xyzw, r0.xyzw, l(0.032258, 0.032258, 0.032258, 1.000000) +ret +// Approximately 7 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGBA2DArray_5551[] = { + 68, 88, 66, 67, 68, 140, 194, 251, 165, 142, 204, 154, 232, 236, 200, 233, 255, 120, 4, + 27, 1, 0, 0, 0, 28, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 160, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 8, 1, 0, 0, 64, 0, 0, 0, 66, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 64, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, 18, 16, 16, 0, 1, 0, 0, 0, + 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, + 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 86, 0, + 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 1, 0, 0, 0, 54, + 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 2, 0, 0, 0, + 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, + 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56, 0, + 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, 128, 63, + 64, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, + 0, 56, 0, 0, 10, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 8, 33, 4, 61, 8, 33, 4, 61, 8, 33, 4, 61, 0, + 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 7, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 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, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darrayi11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darrayi11ps.h new file mode 100644 index 0000000000..457935a252 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darrayi11ps.h @@ -0,0 +1,85 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureI texture sint4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_resource_texture2darray (sint,sint,sint,sint) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v2.xyxx +ftoi r0.xy, r0.xyxx +mov r0.z, v1.x +mov r0.w, l(0) +ld o0.xyzw, r0.xyzw, t0.xyzw +ret +// Approximately 8 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGBA2DArrayI[] = { + 68, 88, 66, 67, 215, 68, 211, 98, 73, 229, 148, 22, 136, 6, 112, 36, 206, 148, 145, + 188, 1, 0, 0, 0, 220, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0, + 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 96, 2, 0, 0, 82, 68, 69, 70, 112, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 69, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0, + 0, 3, 0, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 73, 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, 49, 48, 46, 49, 0, 171, 171, + 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, + 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, + 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, + 82, 68, 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, 2, 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, 240, 0, 0, 0, 64, 0, 0, 0, 60, 0, 0, 0, 88, 64, 0, 4, + 0, 112, 16, 0, 0, 0, 0, 0, 51, 51, 0, 0, 100, 8, 0, 4, 18, 16, 16, + 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0, + 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, + 0, 0, 0, 61, 16, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 70, 126, 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, 2, + 0, 0, 0, 27, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, + 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 1, 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, 2, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darrayui11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darrayui11ps.h new file mode 100644 index 0000000000..58b67ac728 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darrayui11ps.h @@ -0,0 +1,85 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureUI texture uint4 2darray t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_resource_texture2darray (uint,uint,uint,uint) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v2.xyxx +ftoi r0.xy, r0.xyxx +mov r0.z, v1.x +mov r0.w, l(0) +ld o0.xyzw, r0.xyzw, t0.xyzw +ret +// Approximately 8 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGBA2DArrayUI[] = { + 68, 88, 66, 67, 31, 32, 146, 134, 107, 181, 50, 167, 97, 108, 64, 57, 238, 167, 69, + 217, 1, 0, 0, 0, 220, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0, + 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 96, 2, 0, 0, 82, 68, 69, 70, 112, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 70, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0, + 0, 4, 0, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 85, 73, 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, 49, 48, 46, 49, 0, 171, + 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, + 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, + 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, + 82, 68, 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, 1, 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, 240, 0, 0, 0, 64, 0, 0, 0, 60, 0, 0, 0, 88, 64, 0, 4, + 0, 112, 16, 0, 0, 0, 0, 0, 68, 68, 0, 0, 100, 8, 0, 4, 18, 16, 16, + 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0, + 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, + 0, 0, 0, 61, 16, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 70, 126, 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, 2, + 0, 0, 0, 27, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, + 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 1, 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, 2, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2di11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2di11ps.h new file mode 100644 index 0000000000..eb0ebbd6ea --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2di11ps.h @@ -0,0 +1,78 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureI texture sint4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_resource_texture2d (sint,sint,sint,sint) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v1.xyxx +ftoi r0.xy, r0.xyxx +mov r0.zw, l(0,0,0,0) +ld o0.xyzw, r0.xyzw, t0.xyzw +ret +// Approximately 7 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGBA2DI[] = { + 68, 88, 66, 67, 11, 194, 121, 174, 53, 241, 53, 229, 116, 76, 99, 226, 54, 79, 165, + 216, 1, 0, 0, 0, 148, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0, + 0, 0, 4, 1, 0, 0, 56, 1, 0, 0, 24, 2, 0, 0, 82, 68, 69, 70, 112, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 69, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0, + 0, 3, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 73, 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, 49, 48, 46, 49, 0, 171, 171, + 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 2, 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, 216, 0, 0, 0, 64, 0, 0, + 0, 54, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 51, 51, + 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, 1, 0, 0, 0, 61, 16, 0, 7, + 242, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 126, 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, 27, 0, 0, 5, + 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 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, 45, 0, 0, 7, 242, 32, 16, 0, 0, + 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, + 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dms11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dms11ps.h new file mode 100644 index 0000000000..76361532d2 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dms11ps.h @@ -0,0 +1,80 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureF_MS texture float4 2dMS t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 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 constant 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, 49, 75, 69, 135, 188, 202, 223, 102, 144, 42, 4, 30, 173, 255, 143, + 210, 1, 0, 0, 0, 136, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0, + 0, 0, 40, 1, 0, 0, 92, 1, 0, 0, 12, 2, 0, 0, 82, 68, 69, 70, 112, + 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, 49, 48, 46, 49, + 0, 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, 101, 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, 79, 82, 68, 0, 83, 86, 95, 83, + 65, 77, 80, 76, 69, 73, 78, 68, 69, 88, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dui11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dui11ps.h new file mode 100644 index 0000000000..31f84d0d74 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dui11ps.h @@ -0,0 +1,78 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureUI texture uint4 2d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_resource_texture2d (uint,uint,uint,uint) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v1.xyxx +ftoi r0.xy, r0.xyxx +mov r0.zw, l(0,0,0,0) +ld o0.xyzw, r0.xyzw, t0.xyzw +ret +// Approximately 7 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGBA2DUI[] = { + 68, 88, 66, 67, 116, 109, 92, 124, 46, 28, 237, 165, 173, 42, 6, 53, 183, 101, 128, + 93, 1, 0, 0, 0, 148, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0, + 0, 0, 4, 1, 0, 0, 56, 1, 0, 0, 24, 2, 0, 0, 82, 68, 69, 70, 112, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 70, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0, + 0, 4, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 85, 73, 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, 49, 48, 46, 49, 0, 171, + 171, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 1, 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, 216, 0, 0, 0, 64, 0, 0, + 0, 54, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 68, 68, + 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, 1, 0, 0, 0, 61, 16, 0, 7, + 242, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 126, 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, 27, 0, 0, 5, + 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 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, 45, 0, 0, 7, 242, 32, 16, 0, 0, + 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, + 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d11ps.h new file mode 100644 index 0000000000..4aef441bcd --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d11ps.h @@ -0,0 +1,74 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +sample o0.xyzw, v2.xyzx, t0.xyzw, s0 +ret +// Approximately 2 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGBA3D[] = { + 68, 88, 66, 67, 68, 93, 216, 66, 165, 49, 226, 52, 230, 199, 150, 143, 253, 53, 233, + 213, 1, 0, 0, 0, 120, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 252, 1, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 100, 0, 0, 0, 64, 0, 0, 0, 25, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 69, 0, 0, 9, 242, 32, 16, + 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 70, 126, 16, 0, 0, 0, + 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 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, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d_4444_11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d_4444_11ps.h new file mode 100644 index 0000000000..d6c7a28333 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d_4444_11ps.h @@ -0,0 +1,83 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +mul r0.xyzw, r0.xyzw, l(15.000000, 15.000000, 15.000000, 15.000000) +round_ne r0.xyzw, r0.xyzw +mul o0.xyzw, r0.xyzw, l(0.066667, 0.066667, 0.066667, 0.066667) +ret +// Approximately 5 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGBA3D_4444[] = { + 68, 88, 66, 67, 244, 22, 101, 89, 172, 184, 153, 143, 94, 198, 255, 75, 136, 76, 172, + 69, 1, 0, 0, 0, 228, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 104, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 208, 0, 0, 0, 64, 0, 0, 0, 52, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, + 65, 64, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, + 0, 0, 56, 0, 0, 10, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 137, 136, 136, 61, 137, 136, 136, 61, 137, 136, 136, 61, + 137, 136, 136, 61, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d_5551_11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d_5551_11ps.h new file mode 100644 index 0000000000..3329c4d2ce --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d_5551_11ps.h @@ -0,0 +1,83 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF texture float4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +mul r0.xyzw, r0.xyzw, l(31.000000, 31.000000, 31.000000, 1.000000) +round_ne r0.xyzw, r0.xyzw +mul o0.xyzw, r0.xyzw, l(0.032258, 0.032258, 0.032258, 1.000000) +ret +// Approximately 5 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGBA3D_5551[] = { + 68, 88, 66, 67, 84, 84, 9, 48, 70, 52, 100, 237, 108, 219, 183, 20, 215, 148, 144, + 173, 1, 0, 0, 0, 228, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, + 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 104, 2, 0, 0, 82, 68, 69, 70, 152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 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, 49, 48, 46, 49, 0, + 171, 171, 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, + 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 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, 208, 0, 0, 0, 64, 0, 0, 0, 52, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, + 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, 128, + 63, 64, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, + 0, 0, 56, 0, 0, 10, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 8, 33, 4, 61, 8, 33, 4, 61, 8, 33, 4, 61, + 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3di11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3di11ps.h new file mode 100644 index 0000000000..81adb14ca9 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3di11ps.h @@ -0,0 +1,81 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureI texture sint4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_resource_texture3d (sint,sint,sint,sint) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xyz, r0.xyzx +mul r0.xyz, r0.xyzx, v2.xyzx +ftoi r0.xyz, r0.xyzx +mov r0.w, l(0) +ld o0.xyzw, r0.xyzw, t0.xyzw +ret +// Approximately 7 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGBA3DI[] = { + 68, 88, 66, 67, 112, 154, 25, 211, 170, 223, 11, 97, 14, 10, 139, 203, 225, 190, 33, + 158, 1, 0, 0, 0, 184, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0, + 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 60, 2, 0, 0, 82, 68, 69, 70, 112, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 69, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0, + 0, 3, 0, 0, 0, 8, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 73, 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, 49, 48, 46, 49, 0, 171, 171, + 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, 79, 83, + 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, + 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, + 82, 68, 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, 2, 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, 204, 0, 0, 0, 64, 0, 0, 0, 51, 0, 0, 0, 88, 40, 0, 4, + 0, 112, 16, 0, 0, 0, 0, 0, 51, 51, 0, 0, 98, 16, 0, 3, 114, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, 61, 16, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 86, 0, 0, 5, + 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, + 7, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18, + 16, 0, 2, 0, 0, 0, 27, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3dui11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3dui11ps.h new file mode 100644 index 0000000000..31bc39204d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3dui11ps.h @@ -0,0 +1,81 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureUI texture uint4 3d t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_resource_texture3d (uint,uint,uint,uint) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xyz, r0.xyzx +mul r0.xyz, r0.xyzx, v2.xyzx +ftoi r0.xyz, r0.xyzx +mov r0.w, l(0) +ld o0.xyzw, r0.xyzw, t0.xyzw +ret +// Approximately 7 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGBA3DUI[] = { + 68, 88, 66, 67, 136, 72, 192, 109, 253, 59, 232, 36, 69, 34, 127, 153, 17, 12, 205, + 209, 1, 0, 0, 0, 184, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0, + 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 60, 2, 0, 0, 82, 68, 69, 70, 112, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 70, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0, + 0, 4, 0, 0, 0, 8, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 85, 73, 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, 49, 48, 46, 49, 0, 171, + 171, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, 79, 83, + 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, + 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, + 82, 68, 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, 1, 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, 204, 0, 0, 0, 64, 0, 0, 0, 51, 0, 0, 0, 88, 40, 0, 4, + 0, 112, 16, 0, 0, 0, 0, 0, 68, 68, 0, 0, 98, 16, 0, 3, 114, 16, 16, + 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, 61, 16, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 86, 0, 0, 5, + 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, + 7, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18, + 16, 0, 2, 0, 0, 0, 27, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 1, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvecolor2dps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvecolor2dps.h new file mode 100644 index 0000000000..8283ea9c4c --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvecolor2dps.h @@ -0,0 +1,103 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureF_MS texture float4 2dMS t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 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, 93, 61, 55, 147, 13, 181, 1, 129, 207, 120, 176, 100, 210, 126, 243, + 242, 1, 0, 0, 0, 128, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0, + 0, 0, 4, 1, 0, 0, 56, 1, 0, 0, 4, 3, 0, 0, 82, 68, 69, 70, 112, + 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, 49, 48, 46, 49, + 0, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepth11_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepth11_ps.h new file mode 100644 index 0000000000..0f986c7843 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepth11_ps.h @@ -0,0 +1,81 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Depth texture float 2dMS t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Depth 0 N/A oDepth DEPTH float YES +// +ps_4_1 +dcl_globalFlags refactoringAllowed +dcl_resource_texture2dms(0) (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output oDepth +dcl_temps 1 +resinfo_uint r0.xy, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v1.xyxx +ftou r0.xy, r0.xyxx +mov r0.zw, l(0,0,0,0) +ldms r0.x, r0.xyzw, t0.xyzw, l(0) +mov oDepth, r0.x +ret +// Approximately 8 instruction slots used +#endif + +const BYTE g_PS_ResolveDepth[] = { + 68, 88, 66, 67, 133, 15, 63, 40, 192, 212, 199, 79, 7, 253, 243, 47, 246, 158, 13, + 45, 1, 0, 0, 0, 168, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 168, 0, + 0, 0, 0, 1, 0, 0, 52, 1, 0, 0, 44, 2, 0, 0, 82, 68, 69, 70, 108, + 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, 66, 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, 1, 0, 0, 0, 68, 101, 112, 116, 104, 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, 49, 48, 46, 49, 0, 171, 171, 73, 83, 71, + 78, 80, 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, 111, 115, 105, 116, 105, 111, 110, 0, 84, 69, 88, + 67, 79, 79, 82, 68, 0, 171, 171, 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, 255, 255, 255, 255, 1, 14, 0, 0, 83, 86, 95, 68, 101, 112, 116, 104, + 0, 171, 171, 171, 83, 72, 68, 82, 240, 0, 0, 0, 65, 0, 0, 0, 60, 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, 2, 1, + 192, 0, 0, 104, 0, 0, 2, 1, 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, 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, + 0, 0, 0, 0, 70, 0, 16, 0, 0, 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, 18, 0, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 4, 1, 192, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 8, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 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, 2, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_ps.h new file mode 100644 index 0000000000..449fbdbed9 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_ps.h @@ -0,0 +1,92 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Depth texture float 2dMS t0 1 +// Stencil texture uint2 2dMS t1 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 xy 0 TARGET float xy +// +ps_4_1 +dcl_globalFlags refactoringAllowed +dcl_resource_texture2dms(0) (float,float,float,float) t0 +dcl_resource_texture2dms(0) (uint,uint,uint,uint) t1 +dcl_input_ps linear v1.xy +dcl_output o0.xy +dcl_temps 1 +resinfo_uint r0.xy, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v1.xyxx +ftou r0.xy, r0.xyxx +mov r0.zw, l(0,0,0,0) +ldms r0.z, r0.xyzw, t1.xzyw, l(0) +ldms r0.x, r0.xyww, t0.xyzw, l(0) +mov o0.x, r0.x +utof o0.y, r0.z +ret +// Approximately 10 instruction slots used +#endif + +const BYTE g_PS_ResolveDepthStencil[] = { + 68, 88, 66, 67, 89, 136, 221, 180, 85, 229, 18, 205, 242, 112, 176, 35, 107, 34, 5, + 254, 1, 0, 0, 0, 32, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 208, 0, + 0, 0, 40, 1, 0, 0, 92, 1, 0, 0, 164, 2, 0, 0, 82, 68, 69, 70, 148, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 1, 4, 255, 255, 0, 1, 0, 0, 106, 0, 0, 0, 92, 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, 1, 0, 0, 0, 98, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, + 68, 101, 112, 116, 104, 0, 83, 116, 101, 110, 99, 105, 108, 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, 49, 48, 46, 49, 0, 171, 171, 73, + 83, 71, 78, 80, 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, 111, 115, 105, 116, 105, 111, 110, 0, 84, + 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 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, 3, 12, 0, 0, 83, 86, 95, 84, 97, 114, + 103, 101, 116, 0, 171, 171, 83, 72, 68, 82, 64, 1, 0, 0, 65, 0, 0, 0, 80, + 0, 0, 0, 106, 8, 0, 1, 88, 32, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, + 85, 85, 0, 0, 88, 32, 0, 4, 0, 112, 16, 0, 1, 0, 0, 0, 68, 68, 0, + 0, 98, 16, 0, 3, 50, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 50, 32, + 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 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, 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, 0, 0, 0, 0, 70, 0, 16, 0, 0, 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, 66, 0, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 134, 125, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 46, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, + 70, 15, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 32, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 86, 0, 0, 5, 34, 32, 16, 0, 0, 0, 0, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, + 10, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 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, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 3, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_vs.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_vs.h new file mode 100644 index 0000000000..162168be33 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_vs.h @@ -0,0 +1,83 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_VertexID 0 x 0 VERTID uint x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float xyzw +// TEXCOORD 0 xy 1 NONE float xy +// +vs_4_1 +dcl_globalFlags refactoringAllowed +dcl_immediateConstantBuffer { { -1.000000, 1.000000, 0, 0}, + { 1.000000, -1.000000, 0, 0}, + { -1.000000, -1.000000, 0, 0}, + { -1.000000, 1.000000, 0, 0}, + { 1.000000, 1.000000, 0, 0}, + { 1.000000, -1.000000, 0, 0} } +dcl_input_sgv v0.x, vertex_id +dcl_output_siv o0.xyzw, position +dcl_output o1.xy +dcl_temps 1 +mov o0.zw, l(0,0,0,1.000000) +mov r0.x, v0.x +mov o0.xy, icb[r0.x + 0].xyxx +add r0.y, l(1.000000), icb[r0.x + 0].x +add r0.x, l(1.000000), -icb[r0.x + 0].y +mul o1.xy, r0.yxyy, l(0.500000, 0.500000, 0.000000, 0.000000) +ret +// Approximately 7 instruction slots used +#endif + +const BYTE g_VS_ResolveDepthStencil[] = { + 68, 88, 66, 67, 151, 71, 251, 149, 26, 9, 107, 111, 231, 137, 148, 94, 92, 2, 252, + 182, 1, 0, 0, 0, 244, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 128, 0, + 0, 0, 180, 0, 0, 0, 12, 1, 0, 0, 120, 2, 0, 0, 82, 68, 69, 70, 68, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, + 1, 4, 254, 255, 0, 1, 0, 0, 28, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, + 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 83, 86, 95, + 86, 101, 114, 116, 101, 120, 73, 68, 0, 79, 83, 71, 78, 80, 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, 12, 0, 0, 83, 86, 95, + 80, 111, 115, 105, 116, 105, 111, 110, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, + 171, 171, 83, 72, 68, 82, 100, 1, 0, 0, 65, 0, 1, 0, 89, 0, 0, 0, 106, + 8, 0, 1, 53, 24, 0, 0, 26, 0, 0, 0, 0, 0, 128, 191, 0, 0, 128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, 0, 0, 128, 191, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 128, 191, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 128, 63, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, + 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 4, 18, 16, 16, + 0, 0, 0, 0, 0, 6, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 1, 0, 0, 0, 104, + 0, 0, 2, 1, 0, 0, 0, 54, 0, 0, 8, 194, 32, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, + 63, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 6, 50, 32, 16, 0, 0, 0, 0, 0, 70, 144, 144, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 8, 34, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 128, 63, 10, 144, 144, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 128, 63, 26, 144, 144, 128, 65, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 10, 50, 32, 16, 0, 1, 0, 0, 0, 22, 5, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, + 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 7, 0, 0, 0, 1, 0, + 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 3, 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, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvestencil11_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvestencil11_ps.h new file mode 100644 index 0000000000..0f96154858 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvestencil11_ps.h @@ -0,0 +1,84 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Stencil texture uint2 2dMS t1 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 xy 0 TARGET float xy +// +ps_4_1 +dcl_globalFlags refactoringAllowed +dcl_resource_texture2dms(0) (uint,uint,uint,uint) t1 +dcl_input_ps linear v1.xy +dcl_output o0.xy +dcl_temps 1 +resinfo_uint r0.xy, l(0), t1.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v1.xyxx +ftou r0.xy, r0.xyxx +mov r0.zw, l(0,0,0,0) +ldms r0.x, r0.xyzw, t1.yxzw, l(0) +utof o0.y, r0.x +mov o0.x, l(0) +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_ResolveStencil[] = { + 68, 88, 66, 67, 123, 66, 135, 11, 171, 75, 198, 85, 15, 70, 47, 122, 95, 167, 34, + 235, 1, 0, 0, 0, 196, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 168, 0, + 0, 0, 0, 1, 0, 0, 52, 1, 0, 0, 72, 2, 0, 0, 82, 68, 69, 70, 108, + 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, 68, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0, + 0, 4, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 5, 0, 0, 0, 83, 116, 101, 110, 99, 105, 108, 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, 49, 48, 46, 49, 0, 73, 83, 71, + 78, 80, 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, 111, 115, 105, 116, 105, 111, 110, 0, 84, 69, 88, + 67, 79, 79, 82, 68, 0, 171, 171, 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, 3, 12, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, + 116, 0, 171, 171, 83, 72, 68, 82, 12, 1, 0, 0, 65, 0, 0, 0, 67, 0, 0, + 0, 106, 8, 0, 1, 88, 32, 0, 4, 0, 112, 16, 0, 1, 0, 0, 0, 68, 68, + 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 50, + 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 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, 1, 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, 0, 0, 0, 0, 70, 0, 16, 0, 0, 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, 18, 0, 16, 0, 0, + 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 22, 126, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, 34, 32, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 32, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, + 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 1, 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, 2, 0, 0, 0, 0, 0, 0, 0, 3, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2darrayps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2darrayps.h new file mode 100644 index 0000000000..d3d5c0f0e3 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2darrayps.h @@ -0,0 +1,135 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer SwizzleProperties +// { +// +// uint4 SwizzleIndices; // Offset: 0 Size: 16 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF2DArray texture float4 2darray t0 1 +// SwizzleProperties cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_constantbuffer CB0[1], immediateIndexed +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +dcl_indexableTemp x0[6], 4 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +mov x0[0].x, r0.x +mov x0[1].x, r0.y +mov x0[2].x, r0.z +mov x0[3].x, r0.w +mov x0[4].x, l(0) +mov x0[5].x, l(1.000000) +mov r0.x, cb0[0].x +mov o0.x, x0[r0.x + 0].x +mov r0.x, cb0[0].y +mov o0.y, x0[r0.x + 0].x +mov r0.x, cb0[0].z +mov o0.z, x0[r0.x + 0].x +mov r0.x, cb0[0].w +mov o0.w, x0[r0.x + 0].x +ret +// Approximately 18 instruction slots used +#endif + +const BYTE g_PS_SwizzleF2DArray[] = { + 68, 88, 66, 67, 43, 191, 227, 129, 77, 88, 223, 209, 64, 17, 168, 91, 78, 216, 210, + 134, 1, 0, 0, 0, 192, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 92, 1, + 0, 0, 228, 1, 0, 0, 24, 2, 0, 0, 68, 4, 0, 0, 82, 68, 69, 70, 32, + 1, 0, 0, 1, 0, 0, 0, 168, 0, 0, 0, 3, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 248, 0, 0, 0, 124, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 148, 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, 1, 0, 0, 0, 83, 97, 109, 112, 108, 101, + 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 50, 68, 65, 114, 114, 97, 121, 0, 83, + 119, 105, 122, 122, 108, 101, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 0, 171, 171, + 148, 0, 0, 0, 1, 0, 0, 0, 192, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, + 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 73, 110, + 100, 105, 99, 101, 115, 0, 171, 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, + 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 128, 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, 4, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, + 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, + 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, + 69, 88, 67, 79, 79, 82, 68, 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, 36, 2, 0, 0, 64, 0, 0, 0, 137, 0, 0, + 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 64, 0, 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, 18, 16, 16, 0, 1, 0, 0, 0, + 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, + 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 105, 0, + 0, 4, 0, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 86, 0, 0, 5, 66, + 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, + 50, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, + 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, + 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, + 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, + 18, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 128, 63, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 10, + 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 18, 32, 16, 0, + 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 34, 32, 16, 0, 0, 0, 0, 0, 10, + 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, + 18, 0, 16, 0, 0, 0, 0, 0, 42, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 0, 0, 7, 66, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, + 0, 0, 0, 58, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, + 130, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 18, 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, + 6, 0, 0, 0, 10, 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, 5, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2dps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2dps.h new file mode 100644 index 0000000000..091c3e29ea --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2dps.h @@ -0,0 +1,126 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer SwizzleProperties +// { +// +// uint4 SwizzleIndices; // Offset: 0 Size: 16 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF2D texture float4 2d t0 1 +// SwizzleProperties cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 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_0 +dcl_constantbuffer CB0[1], immediateIndexed +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +dcl_indexableTemp x0[6], 4 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +mov x0[0].x, r0.x +mov x0[1].x, r0.y +mov x0[2].x, r0.z +mov x0[3].x, r0.w +mov x0[4].x, l(0) +mov x0[5].x, l(1.000000) +mov r0.x, cb0[0].x +mov o0.x, x0[r0.x + 0].x +mov r0.x, cb0[0].y +mov o0.y, x0[r0.x + 0].x +mov r0.x, cb0[0].z +mov o0.z, x0[r0.x + 0].x +mov r0.x, cb0[0].w +mov o0.w, x0[r0.x + 0].x +ret +// Approximately 16 instruction slots used +#endif + +const BYTE g_PS_SwizzleF2D[] = { + 68, 88, 66, 67, 221, 55, 186, 66, 171, 208, 86, 211, 37, 150, 98, 209, 236, 60, 108, + 41, 1, 0, 0, 0, 84, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 88, 1, + 0, 0, 176, 1, 0, 0, 228, 1, 0, 0, 216, 3, 0, 0, 82, 68, 69, 70, 28, + 1, 0, 0, 1, 0, 0, 0, 164, 0, 0, 0, 3, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 244, 0, 0, 0, 124, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 143, 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, 1, 0, 0, 0, 83, 97, 109, 112, 108, 101, + 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 50, 68, 0, 83, 119, 105, 122, 122, 108, + 101, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 0, 171, 171, 171, 143, 0, 0, 0, + 1, 0, 0, 0, 188, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 212, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 228, 0, + 0, 0, 0, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 73, 110, 100, 105, 99, 101, + 115, 0, 171, 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, + 49, 0, 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 236, 1, 0, 0, 64, 0, + 0, 0, 123, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 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, 1, 0, 0, 0, 105, 0, 0, 4, 0, 0, 0, 0, 6, 0, 0, 0, 4, + 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, + 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, + 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, + 6, 18, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 54, 0, 0, 6, 18, 0, 16, + 0, 0, 0, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 7, 18, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, + 26, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 34, 32, 16, + 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 42, 128, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 66, 32, 16, 0, 0, 0, 0, 0, + 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, + 6, 18, 0, 16, 0, 0, 0, 0, 0, 58, 128, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 7, 130, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, + 116, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 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, 6, 0, 0, 0, 10, 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, 4, 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, 0, 0, + 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef3dps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef3dps.h new file mode 100644 index 0000000000..042cd18005 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef3dps.h @@ -0,0 +1,129 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer SwizzleProperties +// { +// +// uint4 SwizzleIndices; // Offset: 0 Size: 16 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// Sampler sampler NA NA s0 1 +// TextureF3D texture float4 3d t0 1 +// SwizzleProperties cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_constantbuffer CB0[1], immediateIndexed +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +dcl_indexableTemp x0[6], 4 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +mov x0[0].x, r0.x +mov x0[1].x, r0.y +mov x0[2].x, r0.z +mov x0[3].x, r0.w +mov x0[4].x, l(0) +mov x0[5].x, l(1.000000) +mov r0.x, cb0[0].x +mov o0.x, x0[r0.x + 0].x +mov r0.x, cb0[0].y +mov o0.y, x0[r0.x + 0].x +mov r0.x, cb0[0].z +mov o0.z, x0[r0.x + 0].x +mov r0.x, cb0[0].w +mov o0.w, x0[r0.x + 0].x +ret +// Approximately 16 instruction slots used +#endif + +const BYTE g_PS_SwizzleF3D[] = { + 68, 88, 66, 67, 73, 214, 47, 221, 178, 220, 225, 86, 113, 45, 198, 41, 129, 110, 186, + 79, 1, 0, 0, 0, 132, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 88, 1, + 0, 0, 224, 1, 0, 0, 20, 2, 0, 0, 8, 4, 0, 0, 82, 68, 69, 70, 28, + 1, 0, 0, 1, 0, 0, 0, 164, 0, 0, 0, 3, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 244, 0, 0, 0, 124, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, + 143, 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, 1, 0, 0, 0, 83, 97, 109, 112, 108, 101, + 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 51, 68, 0, 83, 119, 105, 122, 122, 108, + 101, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 0, 171, 171, 171, 143, 0, 0, 0, + 1, 0, 0, 0, 188, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 212, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 228, 0, + 0, 0, 0, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 73, 110, 100, 105, 99, 101, + 115, 0, 171, 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, + 49, 0, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, 79, + 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, + 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, + 79, 82, 68, 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, 236, 1, 0, 0, 64, 0, 0, 0, 123, 0, 0, 0, 89, 0, 0, + 4, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 90, 0, 0, 3, 0, 96, + 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, + 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 105, 0, 0, + 4, 0, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 69, 0, 0, 9, 242, 0, + 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 70, 126, 16, 0, 0, + 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, + 6, 18, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, + 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 128, 63, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 18, 32, 16, 0, 0, 0, 0, + 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, + 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 7, 34, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, + 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, + 0, 0, 0, 0, 0, 42, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 7, 66, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, + 58, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 130, 32, 16, + 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 16, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 2, 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, 6, 0, 0, + 0, 10, 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, 4, 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, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2darrayps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2darrayps.h new file mode 100644 index 0000000000..08c48427e2 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2darrayps.h @@ -0,0 +1,139 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer SwizzleProperties +// { +// +// uint4 SwizzleIndices; // Offset: 0 Size: 16 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureI2DArray texture sint4 2darray t0 1 +// SwizzleProperties cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_constantbuffer CB0[1], immediateIndexed +dcl_resource_texture2darray (sint,sint,sint,sint) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +dcl_indexableTemp x0[6], 4 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v2.xyxx +ftoi r0.xy, r0.xyxx +mov r0.z, v1.x +mov r0.w, l(0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov x0[0].x, r0.x +mov x0[1].x, r0.y +mov x0[2].x, r0.z +mov x0[3].x, r0.w +mov x0[4].x, l(0) +mov x0[5].x, l(1) +mov r0.x, cb0[0].x +mov o0.x, x0[r0.x + 0].x +mov r0.x, cb0[0].y +mov o0.y, x0[r0.x + 0].x +mov r0.x, cb0[0].z +mov o0.z, x0[r0.x + 0].x +mov r0.x, cb0[0].w +mov o0.w, x0[r0.x + 0].x +ret +// Approximately 22 instruction slots used +#endif + +const BYTE g_PS_SwizzleI2DArray[] = { + 68, 88, 66, 67, 212, 163, 121, 141, 10, 113, 132, 178, 58, 176, 145, 98, 43, 111, 211, + 61, 1, 0, 0, 0, 228, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 52, 1, + 0, 0, 188, 1, 0, 0, 240, 1, 0, 0, 104, 4, 0, 0, 82, 68, 69, 70, 248, + 0, 0, 0, 1, 0, 0, 0, 128, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 208, 0, 0, 0, 92, 0, 0, 0, 2, 0, 0, + 0, 3, 0, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 108, 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, 1, 0, 0, 0, + 84, 101, 120, 116, 117, 114, 101, 73, 50, 68, 65, 114, 114, 97, 121, 0, 83, 119, 105, + 122, 122, 108, 101, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 0, 171, 171, 108, 0, + 0, 0, 1, 0, 0, 0, 152, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, + 192, 0, 0, 0, 0, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 73, 110, 100, 105, + 99, 101, 115, 0, 171, 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 0, 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, 49, + 48, 46, 49, 0, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, + 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, + 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, + 67, 79, 79, 82, 68, 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, 2, 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, 112, 2, 0, 0, 64, 0, 0, 0, 156, 0, 0, 0, 89, + 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 88, 64, 0, 4, + 0, 112, 16, 0, 0, 0, 0, 0, 51, 51, 0, 0, 100, 8, 0, 4, 18, 16, 16, + 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0, + 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, + 0, 0, 0, 105, 0, 0, 4, 0, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, + 61, 16, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 70, 126, 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, 2, 0, 0, 0, + 27, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, + 0, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 1, 0, + 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, + 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 18, 32, 16, 0, 0, 0, + 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, + 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 7, 34, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, + 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0, + 16, 0, 0, 0, 0, 0, 42, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 7, 66, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, + 0, 58, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 130, 32, + 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, + 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 22, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 10, 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, 6, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h new file mode 100644 index 0000000000..fbce5942df --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h @@ -0,0 +1,132 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer SwizzleProperties +// { +// +// uint4 SwizzleIndices; // Offset: 0 Size: 16 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureI2D texture sint4 2d t0 1 +// SwizzleProperties cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_constantbuffer CB0[1], immediateIndexed +dcl_resource_texture2d (sint,sint,sint,sint) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +dcl_indexableTemp x0[6], 4 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v1.xyxx +ftoi r0.xy, r0.xyxx +mov r0.zw, l(0,0,0,0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov x0[0].x, r0.x +mov x0[1].x, r0.y +mov x0[2].x, r0.z +mov x0[3].x, r0.w +mov x0[4].x, l(0) +mov x0[5].x, l(1) +mov r0.x, cb0[0].x +mov o0.x, x0[r0.x + 0].x +mov r0.x, cb0[0].y +mov o0.y, x0[r0.x + 0].x +mov r0.x, cb0[0].z +mov o0.z, x0[r0.x + 0].x +mov r0.x, cb0[0].w +mov o0.w, x0[r0.x + 0].x +ret +// Approximately 21 instruction slots used +#endif + +const BYTE g_PS_SwizzleI2D[] = { + 68, 88, 66, 67, 177, 45, 190, 185, 217, 208, 59, 28, 232, 250, 124, 179, 32, 246, 26, + 206, 1, 0, 0, 0, 152, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 48, 1, + 0, 0, 136, 1, 0, 0, 188, 1, 0, 0, 28, 4, 0, 0, 82, 68, 69, 70, 244, + 0, 0, 0, 1, 0, 0, 0, 124, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 204, 0, 0, 0, 92, 0, 0, 0, 2, 0, 0, + 0, 3, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 103, 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, 1, 0, 0, 0, + 84, 101, 120, 116, 117, 114, 101, 73, 50, 68, 0, 83, 119, 105, 122, 122, 108, 101, 80, + 114, 111, 112, 101, 114, 116, 105, 101, 115, 0, 171, 171, 171, 103, 0, 0, 0, 1, 0, + 0, 0, 148, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, + 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 188, 0, 0, 0, + 0, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 73, 110, 100, 105, 99, 101, 115, 0, + 171, 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, + 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 2, 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, 88, 2, 0, 0, 64, 0, 0, 0, + 150, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 51, 51, 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, 1, 0, 0, 0, 105, 0, 0, 4, 0, 0, 0, 0, + 6, 0, 0, 0, 4, 0, 0, 0, 61, 16, 0, 7, 242, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 126, 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, 27, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, + 0, 70, 0, 16, 0, 0, 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, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, + 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 18, 32, 16, 0, 0, 0, + 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, + 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 7, 34, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, + 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0, + 16, 0, 0, 0, 0, 0, 42, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 7, 66, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, + 0, 58, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 130, 32, + 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, + 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 21, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 10, 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, 5, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei3dps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei3dps.h new file mode 100644 index 0000000000..1ce3ce47c8 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei3dps.h @@ -0,0 +1,135 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer SwizzleProperties +// { +// +// uint4 SwizzleIndices; // Offset: 0 Size: 16 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureI3D texture sint4 3d t0 1 +// SwizzleProperties cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_constantbuffer CB0[1], immediateIndexed +dcl_resource_texture3d (sint,sint,sint,sint) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +dcl_indexableTemp x0[6], 4 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xyz, r0.xyzx +mul r0.xyz, r0.xyzx, v2.xyzx +ftoi r0.xyz, r0.xyzx +mov r0.w, l(0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov x0[0].x, r0.x +mov x0[1].x, r0.y +mov x0[2].x, r0.z +mov x0[3].x, r0.w +mov x0[4].x, l(0) +mov x0[5].x, l(1) +mov r0.x, cb0[0].x +mov o0.x, x0[r0.x + 0].x +mov r0.x, cb0[0].y +mov o0.y, x0[r0.x + 0].x +mov r0.x, cb0[0].z +mov o0.z, x0[r0.x + 0].x +mov r0.x, cb0[0].w +mov o0.w, x0[r0.x + 0].x +ret +// Approximately 21 instruction slots used +#endif + +const BYTE g_PS_SwizzleI3D[] = { + 68, 88, 66, 67, 239, 203, 72, 66, 58, 92, 169, 191, 239, 77, 187, 21, 109, 161, 64, + 95, 1, 0, 0, 0, 188, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 48, 1, + 0, 0, 184, 1, 0, 0, 236, 1, 0, 0, 64, 4, 0, 0, 82, 68, 69, 70, 244, + 0, 0, 0, 1, 0, 0, 0, 124, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 204, 0, 0, 0, 92, 0, 0, 0, 2, 0, 0, + 0, 3, 0, 0, 0, 8, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 103, 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, 1, 0, 0, 0, + 84, 101, 120, 116, 117, 114, 101, 73, 51, 68, 0, 83, 119, 105, 122, 122, 108, 101, 80, + 114, 111, 112, 101, 114, 116, 105, 101, 115, 0, 171, 171, 171, 103, 0, 0, 0, 1, 0, + 0, 0, 148, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, + 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 188, 0, 0, 0, + 0, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 73, 110, 100, 105, 99, 101, 115, 0, + 171, 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, + 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, 79, 83, 73, + 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, + 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, + 68, 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, 2, 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, 76, 2, 0, 0, 64, 0, 0, 0, 147, 0, 0, 0, 89, 0, 0, 4, 70, + 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, + 0, 0, 0, 0, 51, 51, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, + 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, + 0, 0, 105, 0, 0, 4, 0, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 61, + 16, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 70, 126, 16, 0, 0, 0, 0, 0, 86, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 0, 0, + 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 27, + 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, + 18, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 6, 18, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 18, 32, 16, 0, 0, 0, 0, 0, + 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, + 6, 18, 0, 16, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 7, 34, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, + 0, 0, 0, 0, 42, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 7, 66, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 58, + 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 130, 32, 16, 0, + 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 21, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, + 10, 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, 5, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2darrayps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2darrayps.h new file mode 100644 index 0000000000..d3d479f7b0 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2darrayps.h @@ -0,0 +1,139 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer SwizzleProperties +// { +// +// uint4 SwizzleIndices; // Offset: 0 Size: 16 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureUI2DArray texture uint4 2darray t0 1 +// SwizzleProperties cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_constantbuffer CB0[1], immediateIndexed +dcl_resource_texture2darray (uint,uint,uint,uint) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +dcl_indexableTemp x0[6], 4 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v2.xyxx +ftoi r0.xy, r0.xyxx +mov r0.z, v1.x +mov r0.w, l(0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov x0[0].x, r0.x +mov x0[1].x, r0.y +mov x0[2].x, r0.z +mov x0[3].x, r0.w +mov x0[4].x, l(0) +mov x0[5].x, l(1) +mov r0.x, cb0[0].x +mov o0.x, x0[r0.x + 0].x +mov r0.x, cb0[0].y +mov o0.y, x0[r0.x + 0].x +mov r0.x, cb0[0].z +mov o0.z, x0[r0.x + 0].x +mov r0.x, cb0[0].w +mov o0.w, x0[r0.x + 0].x +ret +// Approximately 22 instruction slots used +#endif + +const BYTE g_PS_SwizzleUI2DArray[] = { + 68, 88, 66, 67, 116, 247, 215, 129, 4, 49, 47, 120, 164, 87, 225, 112, 75, 76, 233, + 53, 1, 0, 0, 0, 228, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 52, 1, + 0, 0, 188, 1, 0, 0, 240, 1, 0, 0, 104, 4, 0, 0, 82, 68, 69, 70, 248, + 0, 0, 0, 1, 0, 0, 0, 128, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 208, 0, 0, 0, 92, 0, 0, 0, 2, 0, 0, + 0, 4, 0, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 109, 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, 1, 0, 0, 0, + 84, 101, 120, 116, 117, 114, 101, 85, 73, 50, 68, 65, 114, 114, 97, 121, 0, 83, 119, + 105, 122, 122, 108, 101, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 0, 171, 109, 0, + 0, 0, 1, 0, 0, 0, 152, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, + 192, 0, 0, 0, 0, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 73, 110, 100, 105, + 99, 101, 115, 0, 171, 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 0, 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, 49, + 48, 46, 49, 0, 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, + 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, + 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, + 67, 79, 79, 82, 68, 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, 1, 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, 112, 2, 0, 0, 64, 0, 0, 0, 156, 0, 0, 0, 89, + 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 88, 64, 0, 4, + 0, 112, 16, 0, 0, 0, 0, 0, 68, 68, 0, 0, 100, 8, 0, 4, 18, 16, 16, + 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0, + 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, + 0, 0, 0, 105, 0, 0, 4, 0, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, + 61, 16, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 70, 126, 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, 2, 0, 0, 0, + 27, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, + 0, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 1, 0, + 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, + 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 18, 32, 16, 0, 0, 0, + 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, + 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 7, 34, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, + 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0, + 16, 0, 0, 0, 0, 0, 42, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 7, 66, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, + 0, 58, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 130, 32, + 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, + 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 22, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 10, 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, 6, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2dps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2dps.h new file mode 100644 index 0000000000..b83bd117be --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2dps.h @@ -0,0 +1,132 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer SwizzleProperties +// { +// +// uint4 SwizzleIndices; // Offset: 0 Size: 16 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureUI2D texture uint4 2d t0 1 +// SwizzleProperties cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_constantbuffer CB0[1], immediateIndexed +dcl_resource_texture2d (uint,uint,uint,uint) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +dcl_indexableTemp x0[6], 4 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v1.xyxx +ftoi r0.xy, r0.xyxx +mov r0.zw, l(0,0,0,0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov x0[0].x, r0.x +mov x0[1].x, r0.y +mov x0[2].x, r0.z +mov x0[3].x, r0.w +mov x0[4].x, l(0) +mov x0[5].x, l(1) +mov r0.x, cb0[0].x +mov o0.x, x0[r0.x + 0].x +mov r0.x, cb0[0].y +mov o0.y, x0[r0.x + 0].x +mov r0.x, cb0[0].z +mov o0.z, x0[r0.x + 0].x +mov r0.x, cb0[0].w +mov o0.w, x0[r0.x + 0].x +ret +// Approximately 21 instruction slots used +#endif + +const BYTE g_PS_SwizzleUI2D[] = { + 68, 88, 66, 67, 5, 230, 100, 22, 104, 28, 143, 55, 98, 102, 32, 210, 129, 6, 68, + 183, 1, 0, 0, 0, 152, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 48, 1, + 0, 0, 136, 1, 0, 0, 188, 1, 0, 0, 28, 4, 0, 0, 82, 68, 69, 70, 244, + 0, 0, 0, 1, 0, 0, 0, 124, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 204, 0, 0, 0, 92, 0, 0, 0, 2, 0, 0, + 0, 4, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 104, 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, 1, 0, 0, 0, + 84, 101, 120, 116, 117, 114, 101, 85, 73, 50, 68, 0, 83, 119, 105, 122, 122, 108, 101, + 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 0, 171, 171, 104, 0, 0, 0, 1, 0, + 0, 0, 148, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, + 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 188, 0, 0, 0, + 0, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 73, 110, 100, 105, 99, 101, 115, 0, + 171, 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, + 73, 83, 71, 78, 80, 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, 79, 82, 68, 0, 171, 171, 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, 1, 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, 88, 2, 0, 0, 64, 0, 0, 0, + 150, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 68, 68, 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, 1, 0, 0, 0, 105, 0, 0, 4, 0, 0, 0, 0, + 6, 0, 0, 0, 4, 0, 0, 0, 61, 16, 0, 7, 242, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 126, 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, 27, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, + 0, 70, 0, 16, 0, 0, 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, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, + 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 18, 32, 16, 0, 0, 0, + 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, + 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 7, 34, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, + 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0, + 16, 0, 0, 0, 0, 0, 42, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 7, 66, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, + 0, 58, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 130, 32, + 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, + 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 21, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 10, 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, 5, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui3dps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui3dps.h new file mode 100644 index 0000000000..a7024e22db --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui3dps.h @@ -0,0 +1,135 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer SwizzleProperties +// { +// +// uint4 SwizzleIndices; // Offset: 0 Size: 16 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureUI3D texture uint4 3d t0 1 +// SwizzleProperties cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_constantbuffer CB0[1], immediateIndexed +dcl_resource_texture3d (uint,uint,uint,uint) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +dcl_indexableTemp x0[6], 4 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xyz, r0.xyzx +mul r0.xyz, r0.xyzx, v2.xyzx +ftoi r0.xyz, r0.xyzx +mov r0.w, l(0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov x0[0].x, r0.x +mov x0[1].x, r0.y +mov x0[2].x, r0.z +mov x0[3].x, r0.w +mov x0[4].x, l(0) +mov x0[5].x, l(1) +mov r0.x, cb0[0].x +mov o0.x, x0[r0.x + 0].x +mov r0.x, cb0[0].y +mov o0.y, x0[r0.x + 0].x +mov r0.x, cb0[0].z +mov o0.z, x0[r0.x + 0].x +mov r0.x, cb0[0].w +mov o0.w, x0[r0.x + 0].x +ret +// Approximately 21 instruction slots used +#endif + +const BYTE g_PS_SwizzleUI3D[] = { + 68, 88, 66, 67, 234, 128, 119, 252, 97, 217, 113, 192, 202, 15, 92, 121, 106, 82, 46, + 102, 1, 0, 0, 0, 188, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 48, 1, + 0, 0, 184, 1, 0, 0, 236, 1, 0, 0, 64, 4, 0, 0, 82, 68, 69, 70, 244, + 0, 0, 0, 1, 0, 0, 0, 124, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, 0, 0, 204, 0, 0, 0, 92, 0, 0, 0, 2, 0, 0, + 0, 4, 0, 0, 0, 8, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, 104, 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, 1, 0, 0, 0, + 84, 101, 120, 116, 117, 114, 101, 85, 73, 51, 68, 0, 83, 119, 105, 122, 122, 108, 101, + 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 0, 171, 171, 104, 0, 0, 0, 1, 0, + 0, 0, 148, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, + 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 188, 0, 0, 0, + 0, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 73, 110, 100, 105, 99, 101, 115, 0, + 171, 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, + 73, 83, 71, 78, 128, 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, 4, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, 79, 83, 73, + 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, + 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, + 68, 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, 1, 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, 76, 2, 0, 0, 64, 0, 0, 0, 147, 0, 0, 0, 89, 0, 0, 4, 70, + 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, + 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, + 0, 0, 105, 0, 0, 4, 0, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 61, + 16, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 70, 126, 16, 0, 0, 0, 0, 0, 86, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 0, 0, + 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 27, + 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, + 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, + 18, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 6, 18, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 18, 32, 16, 0, 0, 0, 0, 0, + 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, + 6, 18, 0, 16, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 7, 34, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, + 0, 0, 0, 0, 42, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 7, 66, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 58, + 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 130, 32, 16, 0, + 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 21, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, + 10, 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, 5, 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}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table.cpp new file mode 100644 index 0000000000..a9dfec56b8 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table.cpp @@ -0,0 +1,35 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Helper routines for the D3D11 texture format table. + +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" + +#include "libANGLE/renderer/load_functions_table.h" + +namespace rx +{ + +namespace d3d11 +{ + +const Format &Format::getSwizzleFormat(const Renderer11DeviceCaps &deviceCaps) const +{ + return (swizzleFormat == internalFormat ? *this : Format::Get(swizzleFormat, deviceCaps)); +} + +LoadFunctionMap Format::getLoadFunctions() const +{ + return GetLoadFunctionsMap(internalFormat, formatID); +} + +const angle::Format &Format::format() const +{ + return angle::Format::Get(formatID); +} + +} // namespace d3d11 + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table.h new file mode 100644 index 0000000000..1797476f62 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table.h @@ -0,0 +1,118 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// texture_format_table: +// Queries for full textureFormat information based on internalFormat +// + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_TEXTUREFORMATTABLE_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_TEXTUREFORMATTABLE_H_ + +#include + +#include "common/angleutils.h" +#include "common/platform.h" +#include "libANGLE/renderer/Format.h" +#include "libANGLE/renderer/d3d/formatutilsD3D.h" +#include "libANGLE/renderer/renderer_utils.h" + +namespace rx +{ + +struct Renderer11DeviceCaps; + +namespace d3d11 +{ + +// For sized GL internal formats, there are several possible corresponding D3D11 formats depending +// on device capabilities. +// This structure allows querying for the DXGI texture formats to use for textures, SRVs, RTVs and +// DSVs given a GL internal format. +struct Format final : private angle::NonCopyable +{ + inline constexpr Format(); + inline constexpr Format(GLenum internalFormat, + angle::FormatID formatID, + DXGI_FORMAT texFormat, + DXGI_FORMAT srvFormat, + DXGI_FORMAT uavFormat, + DXGI_FORMAT rtvFormat, + DXGI_FORMAT dsvFormat, + DXGI_FORMAT blitSRVFormat, + DXGI_FORMAT stencilSRVFormat, + DXGI_FORMAT typelessFormat, + GLenum swizzleFormat, + InitializeTextureDataFunction internalFormatInitializer); + + static const Format &Get(GLenum internalFormat, const Renderer11DeviceCaps &deviceCaps); + + const Format &getSwizzleFormat(const Renderer11DeviceCaps &deviceCaps) const; + LoadFunctionMap getLoadFunctions() const; + const angle::Format &format() const; + + GLenum internalFormat; + angle::FormatID formatID; + + DXGI_FORMAT texFormat; + DXGI_FORMAT srvFormat; + DXGI_FORMAT uavFormat; + DXGI_FORMAT rtvFormat; + DXGI_FORMAT dsvFormat; + + DXGI_FORMAT blitSRVFormat; + DXGI_FORMAT stencilSRVFormat; + DXGI_FORMAT typelessFormat; + + GLenum swizzleFormat; + + InitializeTextureDataFunction dataInitializerFunction; +}; + +constexpr Format::Format() + : internalFormat(GL_NONE), + formatID(angle::FormatID::NONE), + texFormat(DXGI_FORMAT_UNKNOWN), + srvFormat(DXGI_FORMAT_UNKNOWN), + uavFormat(DXGI_FORMAT_UNKNOWN), + rtvFormat(DXGI_FORMAT_UNKNOWN), + dsvFormat(DXGI_FORMAT_UNKNOWN), + blitSRVFormat(DXGI_FORMAT_UNKNOWN), + stencilSRVFormat(DXGI_FORMAT_UNKNOWN), + typelessFormat(DXGI_FORMAT_UNKNOWN), + swizzleFormat(GL_NONE), + dataInitializerFunction(nullptr) +{} + +constexpr Format::Format(GLenum internalFormat, + angle::FormatID formatID, + DXGI_FORMAT texFormat, + DXGI_FORMAT srvFormat, + DXGI_FORMAT uavFormat, + DXGI_FORMAT rtvFormat, + DXGI_FORMAT dsvFormat, + DXGI_FORMAT blitSRVFormat, + DXGI_FORMAT stencilSRVFormat, + DXGI_FORMAT typelessFormat, + GLenum swizzleFormat, + InitializeTextureDataFunction internalFormatInitializer) + : internalFormat(internalFormat), + formatID(formatID), + texFormat(texFormat), + srvFormat(srvFormat), + uavFormat(uavFormat), + rtvFormat(rtvFormat), + dsvFormat(dsvFormat), + blitSRVFormat(blitSRVFormat), + stencilSRVFormat(stencilSRVFormat), + typelessFormat(typelessFormat), + swizzleFormat(swizzleFormat), + dataInitializerFunction(internalFormatInitializer) +{} + +} // namespace d3d11 + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_TEXTUREFORMATTABLE_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp new file mode 100644 index 0000000000..39d03a93fd --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp @@ -0,0 +1,3269 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_texture_format_table.py using data from texture_format_data.json +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// texture_format_table: +// Queries for full textureFormat information based in internalFormat +// + +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" + +#include "image_util/copyimage.h" +#include "image_util/generatemip.h" +#include "image_util/loadimage.h" + +#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table_utils.h" + +using namespace angle; + +namespace rx +{ + +namespace d3d11 +{ + +// static +const Format &Format::Get(GLenum internalFormat, const Renderer11DeviceCaps &deviceCaps) +{ + // clang-format off + switch (internalFormat) + { + case GL_ALPHA16F_EXT: + { + static constexpr Format info(GL_ALPHA16F_EXT, + angle::FormatID::R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_TYPELESS, + GL_RGBA16F, + nullptr); + return info; + } + case GL_ALPHA32F_EXT: + { + static constexpr Format info(GL_ALPHA32F_EXT, + angle::FormatID::R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_TYPELESS, + GL_RGBA32F, + nullptr); + return info; + } + case GL_ALPHA8_EXT: + { + if (OnlyFL10Plus(deviceCaps)) + { + static constexpr Format info(GL_ALPHA8_EXT, + angle::FormatID::A8_UNORM, + DXGI_FORMAT_A8_UNORM, + DXGI_FORMAT_A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA8, + nullptr); + return info; + } + else + { + static constexpr Format info(GL_ALPHA8_EXT, + angle::FormatID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_TYPELESS, + GL_RGBA8, + nullptr); + return info; + } + } + case GL_BGR10_A2_ANGLEX: + { + static constexpr Format info(GL_BGR10_A2_ANGLEX, + angle::FormatID::B10G10R10A2_UNORM, + DXGI_FORMAT_R10G10B10A2_UNORM, + DXGI_FORMAT_R10G10B10A2_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R10G10B10A2_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R10G10B10A2_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R10G10B10A2_TYPELESS, + GL_RGBA16_EXT, + nullptr); + return info; + } + case GL_BGR565_ANGLEX: + { + if (SupportsFormat(DXGI_FORMAT_B5G6R5_UNORM, deviceCaps)) + { + static constexpr Format info(GL_BGR565_ANGLEX, + angle::FormatID::B5G6R5_UNORM, + DXGI_FORMAT_B5G6R5_UNORM, + DXGI_FORMAT_B5G6R5_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B5G6R5_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B5G6R5_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA8, + nullptr); + return info; + } + else + { + static constexpr Format info(GL_BGR565_ANGLEX, + angle::FormatID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_TYPELESS, + GL_RGBA8, + nullptr); + return info; + } + } + case GL_BGR5_A1_ANGLEX: + { + static constexpr Format info(GL_BGR5_A1_ANGLEX, + angle::FormatID::B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B8G8R8A8_TYPELESS, + GL_BGRA8_EXT, + nullptr); + return info; + } + case GL_BGRA4_ANGLEX: + { + static constexpr Format info(GL_BGRA4_ANGLEX, + angle::FormatID::B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B8G8R8A8_TYPELESS, + GL_BGRA8_EXT, + nullptr); + return info; + } + case GL_BGRA8_EXT: + { + static constexpr Format info(GL_BGRA8_EXT, + angle::FormatID::B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B8G8R8A8_TYPELESS, + GL_BGRA8_EXT, + nullptr); + return info; + } + case GL_BGRA8_SRGB_ANGLEX: + { + static constexpr Format info(GL_BGRA8_SRGB_ANGLEX, + angle::FormatID::B8G8R8A8_UNORM_SRGB, + DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, + DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B8G8R8A8_TYPELESS, + GL_BGRA8_SRGB_ANGLEX, + nullptr); + return info; + } + case GL_BGRX8_ANGLEX: + { + if (OnlyFL11_1Plus(deviceCaps)) + { + static constexpr Format info(GL_BGRX8_ANGLEX, + angle::FormatID::B8G8R8X8_UNORM, + DXGI_FORMAT_B8G8R8X8_UNORM, + DXGI_FORMAT_B8G8R8X8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B8G8R8X8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B8G8R8X8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B8G8R8X8_TYPELESS, + GL_BGRX8_ANGLEX, + nullptr); + return info; + } + else + { + static constexpr Format info(GL_BGRX8_ANGLEX, + angle::FormatID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_TYPELESS, + GL_RGBA8, + nullptr); + return info; + } + } + case GL_COMPRESSED_R11_EAC: + { + static constexpr Format info(GL_COMPRESSED_R11_EAC, + angle::FormatID::R16_UNORM, + DXGI_FORMAT_R16_UNORM, + DXGI_FORMAT_R16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_TYPELESS, + GL_RGBA16_EXT, + nullptr); + return info; + } + case GL_COMPRESSED_RED_GREEN_RGTC2_EXT: + { + static constexpr Format info(GL_COMPRESSED_RED_GREEN_RGTC2_EXT, + angle::FormatID::BC5_RG_UNORM_BLOCK, + DXGI_FORMAT_BC5_UNORM, + DXGI_FORMAT_BC5_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC5_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA8, + nullptr); + return info; + } + case GL_COMPRESSED_RED_RGTC1_EXT: + { + static constexpr Format info(GL_COMPRESSED_RED_RGTC1_EXT, + angle::FormatID::BC4_RED_UNORM_BLOCK, + DXGI_FORMAT_BC4_UNORM, + DXGI_FORMAT_BC4_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC4_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA8, + nullptr); + return info; + } + case GL_COMPRESSED_RG11_EAC: + { + static constexpr Format info(GL_COMPRESSED_RG11_EAC, + angle::FormatID::R16G16_UNORM, + DXGI_FORMAT_R16G16_UNORM, + DXGI_FORMAT_R16G16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_TYPELESS, + GL_RGBA16_EXT, + nullptr); + return info; + } + case GL_COMPRESSED_RGB8_ETC2: + { + static constexpr Format info(GL_COMPRESSED_RGB8_ETC2, + angle::FormatID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_TYPELESS, + GL_RGBA8, + Initialize4ComponentData); + return info; + } + case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE: + { + static constexpr Format info(GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE, + angle::FormatID::BC1_RGB_UNORM_BLOCK, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA8, + nullptr); + return info; + } + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + { + static constexpr Format info(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, + angle::FormatID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_TYPELESS, + GL_RGBA8, + Initialize4ComponentData); + return info; + } + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE: + { + static constexpr Format info(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE, + angle::FormatID::BC1_RGBA_UNORM_BLOCK, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA8, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA8_ETC2_EAC: + { + static constexpr Format info(GL_COMPRESSED_RGBA8_ETC2_EAC, + angle::FormatID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_TYPELESS, + GL_RGBA8, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_10x10_KHR: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_10x10_KHR, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_10x5_KHR: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_10x5_KHR, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_10x6_KHR: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_10x6_KHR, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_10x8_KHR: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_10x8_KHR, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_12x10_KHR: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_12x10_KHR, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_12x12_KHR: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_12x12_KHR, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_3x3x3_OES: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_3x3x3_OES, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_4x3x3_OES: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_4x3x3_OES, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_4x4_KHR: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_4x4_KHR, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_4x4x3_OES: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_4x4x3_OES, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_4x4x4_OES: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_4x4x4_OES, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_5x4_KHR: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_5x4_KHR, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_5x4x4_OES: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_5x4x4_OES, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_5x5_KHR: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_5x5_KHR, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_5x5x4_OES: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_5x5x4_OES, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_5x5x5_OES: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_5x5x5_OES, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_6x5_KHR: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_6x5_KHR, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_6x5x5_OES: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_6x5x5_OES, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_6x6_KHR: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_6x6_KHR, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_6x6x5_OES: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_6x6x5_OES, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_6x6x6_OES: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_6x6x6_OES, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_8x5_KHR: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_8x5_KHR, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_8x6_KHR: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_8x6_KHR, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_8x8_KHR: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_8x8_KHR, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT: + { + static constexpr Format info(GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, + angle::FormatID::BC7_RGBA_UNORM_BLOCK, + DXGI_FORMAT_BC7_UNORM, + DXGI_FORMAT_BC7_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC7_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA8, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: + { + static constexpr Format info(GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: + { + static constexpr Format info(GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + { + static constexpr Format info(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, + angle::FormatID::BC1_RGBA_UNORM_BLOCK, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA8, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + { + static constexpr Format info(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, + angle::FormatID::BC2_RGBA_UNORM_BLOCK, + DXGI_FORMAT_BC2_UNORM, + DXGI_FORMAT_BC2_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC2_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA8, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + { + static constexpr Format info(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, + angle::FormatID::BC3_RGBA_UNORM_BLOCK, + DXGI_FORMAT_BC3_UNORM, + DXGI_FORMAT_BC3_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC3_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA8, + nullptr); + return info; + } + case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT: + { + static constexpr Format info(GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT, + angle::FormatID::BC6H_RGB_SFLOAT_BLOCK, + DXGI_FORMAT_BC6H_SF16, + DXGI_FORMAT_BC6H_SF16, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC6H_SF16, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA32F, + nullptr); + return info; + } + case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT: + { + static constexpr Format info(GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT, + angle::FormatID::BC6H_RGB_UFLOAT_BLOCK, + DXGI_FORMAT_BC6H_UF16, + DXGI_FORMAT_BC6H_UF16, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC6H_UF16, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA32F, + nullptr); + return info; + } + case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG: + { + static constexpr Format info(GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG: + { + static constexpr Format info(GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + { + static constexpr Format info(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, + angle::FormatID::BC1_RGB_UNORM_BLOCK, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA8, + nullptr); + return info; + } + case GL_COMPRESSED_SIGNED_R11_EAC: + { + static constexpr Format info(GL_COMPRESSED_SIGNED_R11_EAC, + angle::FormatID::R16_SNORM, + DXGI_FORMAT_R16_SNORM, + DXGI_FORMAT_R16_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_TYPELESS, + GL_RGBA16_SNORM_EXT, + nullptr); + return info; + } + case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT: + { + static constexpr Format info(GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT, + angle::FormatID::BC5_RG_SNORM_BLOCK, + DXGI_FORMAT_BC5_SNORM, + DXGI_FORMAT_BC5_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC5_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA8_SNORM, + nullptr); + return info; + } + case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT: + { + static constexpr Format info(GL_COMPRESSED_SIGNED_RED_RGTC1_EXT, + angle::FormatID::BC4_RED_SNORM_BLOCK, + DXGI_FORMAT_BC4_SNORM, + DXGI_FORMAT_BC4_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC4_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA8_SNORM, + nullptr); + return info; + } + case GL_COMPRESSED_SIGNED_RG11_EAC: + { + static constexpr Format info(GL_COMPRESSED_SIGNED_RG11_EAC, + angle::FormatID::R16G16_SNORM, + DXGI_FORMAT_R16G16_SNORM, + DXGI_FORMAT_R16G16_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_TYPELESS, + GL_RGBA16_SNORM_EXT, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, + angle::FormatID::R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_TYPELESS, + GL_SRGB8_ALPHA8, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ETC2: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ETC2, + angle::FormatID::R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_TYPELESS, + GL_SRGB8_ALPHA8, + Initialize4ComponentData); + return info; + } + case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE, + angle::FormatID::BC1_RGB_UNORM_SRGB_BLOCK, + DXGI_FORMAT_BC1_UNORM_SRGB, + DXGI_FORMAT_BC1_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC1_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA8, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, + angle::FormatID::R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_TYPELESS, + GL_SRGB8_ALPHA8, + Initialize4ComponentData); + return info; + } + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE, + angle::FormatID::BC1_RGBA_UNORM_SRGB_BLOCK, + DXGI_FORMAT_BC1_UNORM_SRGB, + DXGI_FORMAT_BC1_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC1_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA8, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT: + { + static constexpr Format info(GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT, + angle::FormatID::BC7_RGBA_UNORM_SRGB_BLOCK, + DXGI_FORMAT_BC7_UNORM_SRGB, + DXGI_FORMAT_BC7_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC7_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_SRGB8_ALPHA8, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT: + { + static constexpr Format info(GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT: + { + static constexpr Format info(GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + { + static constexpr Format info(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, + angle::FormatID::BC1_RGBA_UNORM_SRGB_BLOCK, + DXGI_FORMAT_BC1_UNORM_SRGB, + DXGI_FORMAT_BC1_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC1_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA8, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + { + static constexpr Format info(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, + angle::FormatID::BC2_RGBA_UNORM_SRGB_BLOCK, + DXGI_FORMAT_BC2_UNORM_SRGB, + DXGI_FORMAT_BC2_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC2_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA8, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + { + static constexpr Format info(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, + angle::FormatID::BC3_RGBA_UNORM_SRGB_BLOCK, + DXGI_FORMAT_BC3_UNORM_SRGB, + DXGI_FORMAT_BC3_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC3_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA8, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT: + { + static constexpr Format info(GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT: + { + static constexpr Format info(GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + { + static constexpr Format info(GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, + angle::FormatID::BC1_RGB_UNORM_SRGB_BLOCK, + DXGI_FORMAT_BC1_UNORM_SRGB, + DXGI_FORMAT_BC1_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC1_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA8, + nullptr); + return info; + } + case GL_DEPTH24_STENCIL8: + { + if (OnlyFL10Plus(deviceCaps)) + { + static constexpr Format info(GL_DEPTH24_STENCIL8, + angle::FormatID::D24_UNORM_S8_UINT, + DXGI_FORMAT_R24G8_TYPELESS, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS, + DXGI_FORMAT_X24_TYPELESS_G8_UINT, + DXGI_FORMAT_UNKNOWN, + GL_RGBA32F, + nullptr); + return info; + } + else + { + static constexpr Format info(GL_DEPTH24_STENCIL8, + angle::FormatID::D24_UNORM_S8_UINT, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA32F, + nullptr); + return info; + } + } + case GL_DEPTH32F_STENCIL8: + { + static constexpr Format info(GL_DEPTH32F_STENCIL8, + angle::FormatID::D32_FLOAT_S8X24_UINT, + DXGI_FORMAT_R32G8X24_TYPELESS, + DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D32_FLOAT_S8X24_UINT, + DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, + DXGI_FORMAT_X32_TYPELESS_G8X24_UINT, + DXGI_FORMAT_UNKNOWN, + GL_RGBA32F, + nullptr); + return info; + } + case GL_DEPTH_COMPONENT16: + { + if (OnlyFL10Plus(deviceCaps)) + { + static constexpr Format info(GL_DEPTH_COMPONENT16, + angle::FormatID::D16_UNORM, + DXGI_FORMAT_R16_TYPELESS, + DXGI_FORMAT_R16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D16_UNORM, + DXGI_FORMAT_R16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA16_EXT, + nullptr); + return info; + } + else + { + static constexpr Format info(GL_DEPTH_COMPONENT16, + angle::FormatID::D16_UNORM, + DXGI_FORMAT_D16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA16_EXT, + nullptr); + return info; + } + } + case GL_DEPTH_COMPONENT24: + { + if (OnlyFL10Plus(deviceCaps)) + { + static constexpr Format info(GL_DEPTH_COMPONENT24, + angle::FormatID::D24_UNORM_S8_UINT, + DXGI_FORMAT_R24G8_TYPELESS, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS, + DXGI_FORMAT_X24_TYPELESS_G8_UINT, + DXGI_FORMAT_UNKNOWN, + GL_RGBA32F, + nullptr); + return info; + } + else + { + static constexpr Format info(GL_DEPTH_COMPONENT24, + angle::FormatID::D24_UNORM_S8_UINT, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA32F, + nullptr); + return info; + } + } + case GL_DEPTH_COMPONENT32F: + { + static constexpr Format info(GL_DEPTH_COMPONENT32F, + angle::FormatID::D32_FLOAT, + DXGI_FORMAT_R32_TYPELESS, + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D32_FLOAT, + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA32F, + nullptr); + return info; + } + case GL_DEPTH_COMPONENT32_OES: + { + if (OnlyFL10Plus(deviceCaps)) + { + static constexpr Format info(GL_DEPTH_COMPONENT32_OES, + angle::FormatID::D24_UNORM_S8_UINT, + DXGI_FORMAT_R24G8_TYPELESS, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS, + DXGI_FORMAT_X24_TYPELESS_G8_UINT, + DXGI_FORMAT_UNKNOWN, + GL_RGBA32F, + nullptr); + return info; + } + else + { + static constexpr Format info(GL_DEPTH_COMPONENT32_OES, + angle::FormatID::D24_UNORM_S8_UINT, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA32F, + nullptr); + return info; + } + } + case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE: + { + static constexpr Format info(GL_ETC1_RGB8_LOSSY_DECODE_ANGLE, + angle::FormatID::BC1_RGB_UNORM_BLOCK, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA8, + nullptr); + return info; + } + case GL_ETC1_RGB8_OES: + { + static constexpr Format info(GL_ETC1_RGB8_OES, + angle::FormatID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_TYPELESS, + GL_RGBA8, + Initialize4ComponentData); + return info; + } + case GL_G8_B8R8_2PLANE_420_UNORM_ANGLE: + { + static constexpr Format info(GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE: + { + static constexpr Format info(GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_LUMINANCE16F_EXT: + { + static constexpr Format info(GL_LUMINANCE16F_EXT, + angle::FormatID::R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_TYPELESS, + GL_RGBA16F, + Initialize4ComponentData); + return info; + } + case GL_LUMINANCE32F_EXT: + { + static constexpr Format info(GL_LUMINANCE32F_EXT, + angle::FormatID::R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_TYPELESS, + GL_RGBA32F, + Initialize4ComponentData); + return info; + } + case GL_LUMINANCE8_ALPHA8_EXT: + { + static constexpr Format info(GL_LUMINANCE8_ALPHA8_EXT, + angle::FormatID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_TYPELESS, + GL_RGBA8, + nullptr); + return info; + } + case GL_LUMINANCE8_EXT: + { + static constexpr Format info(GL_LUMINANCE8_EXT, + angle::FormatID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_TYPELESS, + GL_RGBA8, + Initialize4ComponentData); + return info; + } + case GL_LUMINANCE_ALPHA16F_EXT: + { + static constexpr Format info(GL_LUMINANCE_ALPHA16F_EXT, + angle::FormatID::R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_TYPELESS, + GL_RGBA16F, + nullptr); + return info; + } + case GL_LUMINANCE_ALPHA32F_EXT: + { + static constexpr Format info(GL_LUMINANCE_ALPHA32F_EXT, + angle::FormatID::R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_TYPELESS, + GL_RGBA32F, + nullptr); + return info; + } + case GL_NONE: + { + static constexpr Format info(GL_NONE, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_PALETTE4_R5_G6_B5_OES: + { + static constexpr Format info(GL_PALETTE4_R5_G6_B5_OES, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_PALETTE4_RGB5_A1_OES: + { + static constexpr Format info(GL_PALETTE4_RGB5_A1_OES, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_PALETTE4_RGB8_OES: + { + static constexpr Format info(GL_PALETTE4_RGB8_OES, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_PALETTE4_RGBA4_OES: + { + static constexpr Format info(GL_PALETTE4_RGBA4_OES, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_PALETTE4_RGBA8_OES: + { + static constexpr Format info(GL_PALETTE4_RGBA8_OES, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_PALETTE8_R5_G6_B5_OES: + { + static constexpr Format info(GL_PALETTE8_R5_G6_B5_OES, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_PALETTE8_RGB5_A1_OES: + { + static constexpr Format info(GL_PALETTE8_RGB5_A1_OES, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_PALETTE8_RGB8_OES: + { + static constexpr Format info(GL_PALETTE8_RGB8_OES, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_PALETTE8_RGBA4_OES: + { + static constexpr Format info(GL_PALETTE8_RGBA4_OES, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_PALETTE8_RGBA8_OES: + { + static constexpr Format info(GL_PALETTE8_RGBA8_OES, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_R11F_G11F_B10F: + { + static constexpr Format info(GL_R11F_G11F_B10F, + angle::FormatID::R11G11B10_FLOAT, + DXGI_FORMAT_R11G11B10_FLOAT, + DXGI_FORMAT_R11G11B10_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R11G11B10_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R11G11B10_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA16F_EXT, + nullptr); + return info; + } + case GL_R16F: + { + static constexpr Format info(GL_R16F, + angle::FormatID::R16_FLOAT, + DXGI_FORMAT_R16_FLOAT, + DXGI_FORMAT_R16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_TYPELESS, + GL_RGBA16F_EXT, + nullptr); + return info; + } + case GL_R16I: + { + static constexpr Format info(GL_R16I, + angle::FormatID::R16_SINT, + DXGI_FORMAT_R16_SINT, + DXGI_FORMAT_R16_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_TYPELESS, + GL_RGBA16I, + nullptr); + return info; + } + case GL_R16UI: + { + static constexpr Format info(GL_R16UI, + angle::FormatID::R16_UINT, + DXGI_FORMAT_R16_UINT, + DXGI_FORMAT_R16_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_TYPELESS, + GL_RGBA16I, + nullptr); + return info; + } + case GL_R16_EXT: + { + static constexpr Format info(GL_R16_EXT, + angle::FormatID::R16_UNORM, + DXGI_FORMAT_R16_UNORM, + DXGI_FORMAT_R16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_TYPELESS, + GL_RGBA16_EXT, + nullptr); + return info; + } + case GL_R16_SNORM_EXT: + { + static constexpr Format info(GL_R16_SNORM_EXT, + angle::FormatID::R16_SNORM, + DXGI_FORMAT_R16_SNORM, + DXGI_FORMAT_R16_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_TYPELESS, + GL_RGBA16_SNORM_EXT, + nullptr); + return info; + } + case GL_R32F: + { + static constexpr Format info(GL_R32F, + angle::FormatID::R32_FLOAT, + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32_TYPELESS, + GL_RGBA32F, + nullptr); + return info; + } + case GL_R32I: + { + static constexpr Format info(GL_R32I, + angle::FormatID::R32_SINT, + DXGI_FORMAT_R32_SINT, + DXGI_FORMAT_R32_SINT, + DXGI_FORMAT_R32_SINT, + DXGI_FORMAT_R32_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32_TYPELESS, + GL_RGBA32I, + nullptr); + return info; + } + case GL_R32UI: + { + static constexpr Format info(GL_R32UI, + angle::FormatID::R32_UINT, + DXGI_FORMAT_R32_UINT, + DXGI_FORMAT_R32_UINT, + DXGI_FORMAT_R32_UINT, + DXGI_FORMAT_R32_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32_TYPELESS, + GL_RGBA32I, + nullptr); + return info; + } + case GL_R8: + { + static constexpr Format info(GL_R8, + angle::FormatID::R8_UNORM, + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8_TYPELESS, + GL_RGBA8, + nullptr); + return info; + } + case GL_R8I: + { + static constexpr Format info(GL_R8I, + angle::FormatID::R8_SINT, + DXGI_FORMAT_R8_SINT, + DXGI_FORMAT_R8_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8_TYPELESS, + GL_RGBA8I, + nullptr); + return info; + } + case GL_R8UI: + { + static constexpr Format info(GL_R8UI, + angle::FormatID::R8_UINT, + DXGI_FORMAT_R8_UINT, + DXGI_FORMAT_R8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8_TYPELESS, + GL_RGBA8I, + nullptr); + return info; + } + case GL_R8_SNORM: + { + static constexpr Format info(GL_R8_SNORM, + angle::FormatID::R8_SNORM, + DXGI_FORMAT_R8_SNORM, + DXGI_FORMAT_R8_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8_TYPELESS, + GL_RGBA8_SNORM, + nullptr); + return info; + } + case GL_RG16F: + { + static constexpr Format info(GL_RG16F, + angle::FormatID::R16G16_FLOAT, + DXGI_FORMAT_R16G16_FLOAT, + DXGI_FORMAT_R16G16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_TYPELESS, + GL_RGBA16F_EXT, + nullptr); + return info; + } + case GL_RG16I: + { + static constexpr Format info(GL_RG16I, + angle::FormatID::R16G16_SINT, + DXGI_FORMAT_R16G16_SINT, + DXGI_FORMAT_R16G16_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_TYPELESS, + GL_RGBA16I, + nullptr); + return info; + } + case GL_RG16UI: + { + static constexpr Format info(GL_RG16UI, + angle::FormatID::R16G16_UINT, + DXGI_FORMAT_R16G16_UINT, + DXGI_FORMAT_R16G16_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_TYPELESS, + GL_RGBA16I, + nullptr); + return info; + } + case GL_RG16_EXT: + { + static constexpr Format info(GL_RG16_EXT, + angle::FormatID::R16G16_UNORM, + DXGI_FORMAT_R16G16_UNORM, + DXGI_FORMAT_R16G16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_TYPELESS, + GL_RGBA16_EXT, + nullptr); + return info; + } + case GL_RG16_SNORM_EXT: + { + static constexpr Format info(GL_RG16_SNORM_EXT, + angle::FormatID::R16G16_SNORM, + DXGI_FORMAT_R16G16_SNORM, + DXGI_FORMAT_R16G16_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_TYPELESS, + GL_RGBA16_SNORM_EXT, + nullptr); + return info; + } + case GL_RG32F: + { + static constexpr Format info(GL_RG32F, + angle::FormatID::R32G32_FLOAT, + DXGI_FORMAT_R32G32_FLOAT, + DXGI_FORMAT_R32G32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32_TYPELESS, + GL_RGBA32F, + nullptr); + return info; + } + case GL_RG32I: + { + static constexpr Format info(GL_RG32I, + angle::FormatID::R32G32_SINT, + DXGI_FORMAT_R32G32_SINT, + DXGI_FORMAT_R32G32_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32_TYPELESS, + GL_RGBA32I, + nullptr); + return info; + } + case GL_RG32UI: + { + static constexpr Format info(GL_RG32UI, + angle::FormatID::R32G32_UINT, + DXGI_FORMAT_R32G32_UINT, + DXGI_FORMAT_R32G32_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32_TYPELESS, + GL_RGBA32I, + nullptr); + return info; + } + case GL_RG8: + { + static constexpr Format info(GL_RG8, + angle::FormatID::R8G8_UNORM, + DXGI_FORMAT_R8G8_UNORM, + DXGI_FORMAT_R8G8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8_TYPELESS, + GL_RGBA8, + nullptr); + return info; + } + case GL_RG8I: + { + static constexpr Format info(GL_RG8I, + angle::FormatID::R8G8_SINT, + DXGI_FORMAT_R8G8_SINT, + DXGI_FORMAT_R8G8_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8_TYPELESS, + GL_RGBA8I, + nullptr); + return info; + } + case GL_RG8UI: + { + static constexpr Format info(GL_RG8UI, + angle::FormatID::R8G8_UINT, + DXGI_FORMAT_R8G8_UINT, + DXGI_FORMAT_R8G8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8_TYPELESS, + GL_RGBA8I, + nullptr); + return info; + } + case GL_RG8_SNORM: + { + static constexpr Format info(GL_RG8_SNORM, + angle::FormatID::R8G8_SNORM, + DXGI_FORMAT_R8G8_SNORM, + DXGI_FORMAT_R8G8_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8_TYPELESS, + GL_RGBA8_SNORM, + nullptr); + return info; + } + case GL_RGB: + { + static constexpr Format info(GL_RGB, + angle::FormatID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_TYPELESS, + GL_RGBA8, + Initialize4ComponentData); + return info; + } + case GL_RGB10_A2: + { + static constexpr Format info(GL_RGB10_A2, + angle::FormatID::R10G10B10A2_UNORM, + DXGI_FORMAT_R10G10B10A2_UNORM, + DXGI_FORMAT_R10G10B10A2_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R10G10B10A2_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R10G10B10A2_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R10G10B10A2_TYPELESS, + GL_RGBA16_EXT, + nullptr); + return info; + } + case GL_RGB10_A2UI: + { + static constexpr Format info(GL_RGB10_A2UI, + angle::FormatID::R10G10B10A2_UINT, + DXGI_FORMAT_R10G10B10A2_UINT, + DXGI_FORMAT_R10G10B10A2_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R10G10B10A2_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R10G10B10A2_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R10G10B10A2_TYPELESS, + GL_RGBA16I, + nullptr); + return info; + } + case GL_RGB10_UNORM_ANGLEX: + { + static constexpr Format info(GL_RGB10_UNORM_ANGLEX, + angle::FormatID::R10G10B10X2_UNORM, + DXGI_FORMAT_R10G10B10A2_UNORM, + DXGI_FORMAT_R10G10B10A2_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R10G10B10A2_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R10G10B10A2_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R10G10B10A2_TYPELESS, + GL_RGBA16_EXT, + nullptr); + return info; + } + case GL_RGB16F: + { + static constexpr Format info(GL_RGB16F, + angle::FormatID::R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_TYPELESS, + GL_RGBA16F, + Initialize4ComponentData); + return info; + } + case GL_RGB16I: + { + static constexpr Format info(GL_RGB16I, + angle::FormatID::R16G16B16A16_SINT, + DXGI_FORMAT_R16G16B16A16_SINT, + DXGI_FORMAT_R16G16B16A16_SINT, + DXGI_FORMAT_R16G16B16A16_SINT, + DXGI_FORMAT_R16G16B16A16_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_TYPELESS, + GL_RGBA16I, + Initialize4ComponentData); + return info; + } + case GL_RGB16UI: + { + static constexpr Format info(GL_RGB16UI, + angle::FormatID::R16G16B16A16_UINT, + DXGI_FORMAT_R16G16B16A16_UINT, + DXGI_FORMAT_R16G16B16A16_UINT, + DXGI_FORMAT_R16G16B16A16_UINT, + DXGI_FORMAT_R16G16B16A16_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_TYPELESS, + GL_RGBA16UI, + Initialize4ComponentData); + return info; + } + case GL_RGB16_EXT: + { + static constexpr Format info(GL_RGB16_EXT, + angle::FormatID::R16G16B16A16_UNORM, + DXGI_FORMAT_R16G16B16A16_UNORM, + DXGI_FORMAT_R16G16B16A16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_TYPELESS, + GL_RGBA16_EXT, + Initialize4ComponentData); + return info; + } + case GL_RGB16_SNORM_EXT: + { + static constexpr Format info(GL_RGB16_SNORM_EXT, + angle::FormatID::R16G16B16A16_SNORM, + DXGI_FORMAT_R16G16B16A16_SNORM, + DXGI_FORMAT_R16G16B16A16_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_TYPELESS, + GL_RGBA16_SNORM_EXT, + Initialize4ComponentData); + return info; + } + case GL_RGB32F: + { + static constexpr Format info(GL_RGB32F, + angle::FormatID::R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_TYPELESS, + GL_RGBA32F, + Initialize4ComponentData); + return info; + } + case GL_RGB32I: + { + static constexpr Format info(GL_RGB32I, + angle::FormatID::R32G32B32A32_SINT, + DXGI_FORMAT_R32G32B32A32_SINT, + DXGI_FORMAT_R32G32B32A32_SINT, + DXGI_FORMAT_R32G32B32A32_SINT, + DXGI_FORMAT_R32G32B32A32_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_TYPELESS, + GL_RGBA32I, + Initialize4ComponentData); + return info; + } + case GL_RGB32UI: + { + static constexpr Format info(GL_RGB32UI, + angle::FormatID::R32G32B32A32_UINT, + DXGI_FORMAT_R32G32B32A32_UINT, + DXGI_FORMAT_R32G32B32A32_UINT, + DXGI_FORMAT_R32G32B32A32_UINT, + DXGI_FORMAT_R32G32B32A32_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_TYPELESS, + GL_RGBA32UI, + Initialize4ComponentData); + return info; + } + case GL_RGB565: + { + if (SupportsFormat(DXGI_FORMAT_B5G6R5_UNORM, deviceCaps)) + { + static constexpr Format info(GL_RGB565, + angle::FormatID::B5G6R5_UNORM, + DXGI_FORMAT_B5G6R5_UNORM, + DXGI_FORMAT_B5G6R5_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B5G6R5_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B5G6R5_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA8, + nullptr); + return info; + } + else + { + static constexpr Format info(GL_RGB565, + angle::FormatID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_TYPELESS, + GL_RGBA8, + Initialize4ComponentData); + return info; + } + } + case GL_RGB5_A1: + { + if (SupportsFormat(DXGI_FORMAT_B5G5R5A1_UNORM, deviceCaps)) + { + static constexpr Format info(GL_RGB5_A1, + angle::FormatID::B5G5R5A1_UNORM, + DXGI_FORMAT_B5G5R5A1_UNORM, + DXGI_FORMAT_B5G5R5A1_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B5G5R5A1_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B5G5R5A1_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA8, + nullptr); + return info; + } + else + { + static constexpr Format info(GL_RGB5_A1, + angle::FormatID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_TYPELESS, + GL_RGBA8, + nullptr); + return info; + } + } + case GL_RGB8: + { + static constexpr Format info(GL_RGB8, + angle::FormatID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_TYPELESS, + GL_RGBA8, + Initialize4ComponentData); + return info; + } + case GL_RGB8I: + { + static constexpr Format info(GL_RGB8I, + angle::FormatID::R8G8B8A8_SINT, + DXGI_FORMAT_R8G8B8A8_SINT, + DXGI_FORMAT_R8G8B8A8_SINT, + DXGI_FORMAT_R8G8B8A8_SINT, + DXGI_FORMAT_R8G8B8A8_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_TYPELESS, + GL_RGBA8I, + Initialize4ComponentData); + return info; + } + case GL_RGB8UI: + { + static constexpr Format info(GL_RGB8UI, + angle::FormatID::R8G8B8A8_UINT, + DXGI_FORMAT_R8G8B8A8_UINT, + DXGI_FORMAT_R8G8B8A8_UINT, + DXGI_FORMAT_R8G8B8A8_UINT, + DXGI_FORMAT_R8G8B8A8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_TYPELESS, + GL_RGBA8UI, + Initialize4ComponentData); + return info; + } + case GL_RGB8_SNORM: + { + static constexpr Format info(GL_RGB8_SNORM, + angle::FormatID::R8G8B8A8_SNORM, + DXGI_FORMAT_R8G8B8A8_SNORM, + DXGI_FORMAT_R8G8B8A8_SNORM, + DXGI_FORMAT_R8G8B8A8_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_TYPELESS, + GL_RGBA8_SNORM, + Initialize4ComponentData); + return info; + } + case GL_RGB9_E5: + { + static constexpr Format info(GL_RGB9_E5, + angle::FormatID::R9G9B9E5_SHAREDEXP, + DXGI_FORMAT_R9G9B9E5_SHAREDEXP, + DXGI_FORMAT_R9G9B9E5_SHAREDEXP, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R9G9B9E5_SHAREDEXP, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA16F_EXT, + nullptr); + return info; + } + case GL_RGBA: + { + static constexpr Format info(GL_RGBA, + angle::FormatID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_TYPELESS, + GL_RGBA8, + nullptr); + return info; + } + case GL_RGBA16F: + { + static constexpr Format info(GL_RGBA16F, + angle::FormatID::R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_TYPELESS, + GL_RGBA16F, + nullptr); + return info; + } + case GL_RGBA16I: + { + static constexpr Format info(GL_RGBA16I, + angle::FormatID::R16G16B16A16_SINT, + DXGI_FORMAT_R16G16B16A16_SINT, + DXGI_FORMAT_R16G16B16A16_SINT, + DXGI_FORMAT_R16G16B16A16_SINT, + DXGI_FORMAT_R16G16B16A16_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_TYPELESS, + GL_RGBA16I, + nullptr); + return info; + } + case GL_RGBA16UI: + { + static constexpr Format info(GL_RGBA16UI, + angle::FormatID::R16G16B16A16_UINT, + DXGI_FORMAT_R16G16B16A16_UINT, + DXGI_FORMAT_R16G16B16A16_UINT, + DXGI_FORMAT_R16G16B16A16_UINT, + DXGI_FORMAT_R16G16B16A16_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_TYPELESS, + GL_RGBA16UI, + nullptr); + return info; + } + case GL_RGBA16_EXT: + { + static constexpr Format info(GL_RGBA16_EXT, + angle::FormatID::R16G16B16A16_UNORM, + DXGI_FORMAT_R16G16B16A16_UNORM, + DXGI_FORMAT_R16G16B16A16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_TYPELESS, + GL_RGBA16_EXT, + nullptr); + return info; + } + case GL_RGBA16_SNORM_EXT: + { + static constexpr Format info(GL_RGBA16_SNORM_EXT, + angle::FormatID::R16G16B16A16_SNORM, + DXGI_FORMAT_R16G16B16A16_SNORM, + DXGI_FORMAT_R16G16B16A16_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_TYPELESS, + GL_RGBA16_SNORM_EXT, + nullptr); + return info; + } + case GL_RGBA32F: + { + static constexpr Format info(GL_RGBA32F, + angle::FormatID::R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_TYPELESS, + GL_RGBA32F, + nullptr); + return info; + } + case GL_RGBA32I: + { + static constexpr Format info(GL_RGBA32I, + angle::FormatID::R32G32B32A32_SINT, + DXGI_FORMAT_R32G32B32A32_SINT, + DXGI_FORMAT_R32G32B32A32_SINT, + DXGI_FORMAT_R32G32B32A32_SINT, + DXGI_FORMAT_R32G32B32A32_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_TYPELESS, + GL_RGBA32I, + nullptr); + return info; + } + case GL_RGBA32UI: + { + static constexpr Format info(GL_RGBA32UI, + angle::FormatID::R32G32B32A32_UINT, + DXGI_FORMAT_R32G32B32A32_UINT, + DXGI_FORMAT_R32G32B32A32_UINT, + DXGI_FORMAT_R32G32B32A32_UINT, + DXGI_FORMAT_R32G32B32A32_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_TYPELESS, + GL_RGBA32UI, + nullptr); + return info; + } + case GL_RGBA4: + { + if (SupportsFormat(DXGI_FORMAT_B4G4R4A4_UNORM, deviceCaps)) + { + static constexpr Format info(GL_RGBA4, + angle::FormatID::B4G4R4A4_UNORM, + DXGI_FORMAT_B4G4R4A4_UNORM, + DXGI_FORMAT_B4G4R4A4_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B4G4R4A4_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B4G4R4A4_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA4, + nullptr); + return info; + } + else + { + static constexpr Format info(GL_RGBA4, + angle::FormatID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_TYPELESS, + GL_RGBA8, + nullptr); + return info; + } + } + case GL_RGBA8: + { + static constexpr Format info(GL_RGBA8, + angle::FormatID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_TYPELESS, + GL_RGBA8, + nullptr); + return info; + } + case GL_RGBA8I: + { + static constexpr Format info(GL_RGBA8I, + angle::FormatID::R8G8B8A8_SINT, + DXGI_FORMAT_R8G8B8A8_SINT, + DXGI_FORMAT_R8G8B8A8_SINT, + DXGI_FORMAT_R8G8B8A8_SINT, + DXGI_FORMAT_R8G8B8A8_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_TYPELESS, + GL_RGBA8I, + nullptr); + return info; + } + case GL_RGBA8UI: + { + static constexpr Format info(GL_RGBA8UI, + angle::FormatID::R8G8B8A8_UINT, + DXGI_FORMAT_R8G8B8A8_UINT, + DXGI_FORMAT_R8G8B8A8_UINT, + DXGI_FORMAT_R8G8B8A8_UINT, + DXGI_FORMAT_R8G8B8A8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_TYPELESS, + GL_RGBA8UI, + nullptr); + return info; + } + case GL_RGBA8_SNORM: + { + static constexpr Format info(GL_RGBA8_SNORM, + angle::FormatID::R8G8B8A8_SNORM, + DXGI_FORMAT_R8G8B8A8_SNORM, + DXGI_FORMAT_R8G8B8A8_SNORM, + DXGI_FORMAT_R8G8B8A8_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_TYPELESS, + GL_RGBA8_SNORM, + nullptr); + return info; + } + case GL_RGBX8_ANGLE: + { + if (OnlyFL11_1Plus(deviceCaps)) + { + static constexpr Format info(GL_RGBX8_ANGLE, + angle::FormatID::R8G8B8X8_UNORM, + DXGI_FORMAT_B8G8R8X8_UNORM, + DXGI_FORMAT_B8G8R8X8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B8G8R8X8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B8G8R8X8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBX8_ANGLE, + nullptr); + return info; + } + else + { + static constexpr Format info(GL_RGBX8_ANGLE, + angle::FormatID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_TYPELESS, + GL_RGBA8, + nullptr); + return info; + } + } + case GL_SR8_EXT: + { + static constexpr Format info(GL_SR8_EXT, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_SRG8_EXT: + { + static constexpr Format info(GL_SRG8_EXT, + angle::FormatID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_SRGB8: + { + static constexpr Format info(GL_SRGB8, + angle::FormatID::R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_TYPELESS, + GL_SRGB8_ALPHA8, + Initialize4ComponentData); + return info; + } + case GL_SRGB8_ALPHA8: + { + static constexpr Format info(GL_SRGB8_ALPHA8, + angle::FormatID::R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_TYPELESS, + GL_SRGB8_ALPHA8, + nullptr); + return info; + } + case GL_STENCIL_INDEX8: + { + if (OnlyFL10Plus(deviceCaps)) + { + static constexpr Format info(GL_STENCIL_INDEX8, + angle::FormatID::D24_UNORM_S8_UINT, + DXGI_FORMAT_R24G8_TYPELESS, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS, + DXGI_FORMAT_X24_TYPELESS_G8_UINT, + DXGI_FORMAT_UNKNOWN, + GL_RGBA32F, + nullptr); + return info; + } + else + { + static constexpr Format info(GL_STENCIL_INDEX8, + angle::FormatID::D24_UNORM_S8_UINT, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_RGBA32F, + nullptr); + return info; + } + } + + default: + break; + } + // clang-format on + + UNREACHABLE(); + static constexpr Format defaultInfo; + return defaultInfo; +} + +} // namespace d3d11 + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table_utils.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table_utils.h new file mode 100644 index 0000000000..f46f769182 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table_utils.h @@ -0,0 +1,90 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Helper routines for the D3D11 texture format table. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_TEXTURE_FORMAT_TABLE_UTILS_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_TEXTURE_FORMAT_TABLE_UTILS_H_ + +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" + +namespace rx +{ + +namespace d3d11 +{ + +using FormatSupportFunction = bool (*)(const Renderer11DeviceCaps &); + +inline bool OnlyFL11_1Plus(const Renderer11DeviceCaps &deviceCaps) +{ + return (deviceCaps.featureLevel >= D3D_FEATURE_LEVEL_11_1); +} + +inline bool OnlyFL10Plus(const Renderer11DeviceCaps &deviceCaps) +{ + return (deviceCaps.featureLevel >= D3D_FEATURE_LEVEL_10_0); +} + +inline bool OnlyFL9_3(const Renderer11DeviceCaps &deviceCaps) +{ + return (deviceCaps.featureLevel == D3D_FEATURE_LEVEL_9_3); +} + +inline bool SupportsFormat(DXGI_FORMAT format, const Renderer11DeviceCaps &deviceCaps) +{ + // Must support texture, SRV and RTV support + UINT mustSupport = D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_TEXTURECUBE | + D3D11_FORMAT_SUPPORT_SHADER_SAMPLE | D3D11_FORMAT_SUPPORT_MIP | + D3D11_FORMAT_SUPPORT_RENDER_TARGET; + UINT minimumRequiredSamples = 0; + + if (d3d11_gl::GetMaximumClientVersion(deviceCaps).major > 2) + { + mustSupport |= D3D11_FORMAT_SUPPORT_TEXTURE3D; + + // RGBA4, RGB5A1 and RGB565 are all required multisampled renderbuffer formats in ES3 and + // need to support a minimum of 4 samples. + minimumRequiredSamples = 4; + } + + bool fullSupport = false; + if (format == DXGI_FORMAT_B5G6R5_UNORM) + { + // All hardware that supports DXGI_FORMAT_B5G6R5_UNORM should support autogen mipmaps, but + // check anyway. + mustSupport |= D3D11_FORMAT_SUPPORT_MIP_AUTOGEN; + fullSupport = ((deviceCaps.B5G6R5support & mustSupport) == mustSupport) && + deviceCaps.B5G6R5maxSamples >= minimumRequiredSamples; + } + else if (format == DXGI_FORMAT_B4G4R4A4_UNORM) + { + fullSupport = ((deviceCaps.B4G4R4A4support & mustSupport) == mustSupport) && + deviceCaps.B4G4R4A4maxSamples >= minimumRequiredSamples; + } + else if (format == DXGI_FORMAT_B5G5R5A1_UNORM) + { + fullSupport = ((deviceCaps.B5G5R5A1support & mustSupport) == mustSupport) && + deviceCaps.B5G5R5A1maxSamples >= minimumRequiredSamples; + } + else + { + UNREACHABLE(); + return false; + } + + // This means that ANGLE would like to use the entry in the map if the inputted DXGI format + // *IS* supported. + // e.g. the entry might map GL_RGB5_A1 to DXGI_FORMAT_B5G5R5A1, which should only be used if + // DXGI_FORMAT_B5G5R5A1 is supported. + // In this case, we should only return 'true' if the format *IS* supported. + return fullSupport; +} + +} // namespace d3d11 + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_TEXTURE_FORMAT_TABLE_UTILS_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.cpp new file mode 100644 index 0000000000..722510a482 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.cpp @@ -0,0 +1,218 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// NativeWindow11Win32.cpp: Implementation of NativeWindow11 using win32 window APIs. + +#include "libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" + +#include "common/debug.h" + +// This header must be included before dcomp.h. +#include + +#include + +namespace rx +{ + +NativeWindow11Win32::NativeWindow11Win32(EGLNativeWindowType window, + bool hasAlpha, + bool directComposition) + : NativeWindow11(window), + mDirectComposition(directComposition), + mHasAlpha(hasAlpha), + mDevice(nullptr), + mCompositionTarget(nullptr), + mVisual(nullptr) +{} + +NativeWindow11Win32::~NativeWindow11Win32() +{ + SafeRelease(mCompositionTarget); + SafeRelease(mDevice); + SafeRelease(mVisual); +} + +bool NativeWindow11Win32::initialize() +{ + return true; +} + +bool NativeWindow11Win32::getClientRect(LPRECT rect) const +{ + return GetClientRect(getNativeWindow(), rect) == TRUE; +} + +bool NativeWindow11Win32::isIconic() const +{ + return IsIconic(getNativeWindow()) == TRUE; +} + +HRESULT NativeWindow11Win32::createSwapChain(ID3D11Device *device, + IDXGIFactory *factory, + DXGI_FORMAT format, + UINT width, + UINT height, + UINT samples, + IDXGISwapChain **swapChain) +{ + if (device == nullptr || factory == nullptr || swapChain == nullptr || width == 0 || + height == 0) + { + return E_INVALIDARG; + } + + if (mDirectComposition) + { + HMODULE dcomp = ::GetModuleHandle(TEXT("dcomp.dll")); + if (!dcomp) + { + return E_INVALIDARG; + } + + typedef HRESULT(WINAPI * PFN_DCOMPOSITION_CREATE_DEVICE)( + IDXGIDevice * dxgiDevice, REFIID iid, void **dcompositionDevice); + PFN_DCOMPOSITION_CREATE_DEVICE createDComp = + reinterpret_cast( + GetProcAddress(dcomp, "DCompositionCreateDevice")); + if (!createDComp) + { + return E_INVALIDARG; + } + + if (!mDevice) + { + IDXGIDevice *dxgiDevice = d3d11::DynamicCastComObject(device); + HRESULT result = createDComp(dxgiDevice, __uuidof(IDCompositionDevice), + reinterpret_cast(&mDevice)); + SafeRelease(dxgiDevice); + + if (FAILED(result)) + { + return result; + } + } + + if (!mCompositionTarget) + { + HRESULT result = + mDevice->CreateTargetForHwnd(getNativeWindow(), TRUE, &mCompositionTarget); + if (FAILED(result)) + { + return result; + } + } + + if (!mVisual) + { + HRESULT result = mDevice->CreateVisual(&mVisual); + if (FAILED(result)) + { + return result; + } + } + + IDXGIFactory2 *factory2 = d3d11::DynamicCastComObject(factory); + DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {}; + swapChainDesc.Width = width; + swapChainDesc.Height = height; + swapChainDesc.Format = format; + swapChainDesc.Stereo = FALSE; + swapChainDesc.SampleDesc.Count = 1; + swapChainDesc.SampleDesc.Quality = 0; + swapChainDesc.BufferUsage = + DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER | DXGI_USAGE_SHADER_INPUT; + swapChainDesc.BufferCount = 2; + swapChainDesc.Scaling = DXGI_SCALING_STRETCH; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; + swapChainDesc.AlphaMode = + mHasAlpha ? DXGI_ALPHA_MODE_PREMULTIPLIED : DXGI_ALPHA_MODE_IGNORE; + swapChainDesc.Flags = 0; + IDXGISwapChain1 *swapChain1 = nullptr; + HRESULT result = + factory2->CreateSwapChainForComposition(device, &swapChainDesc, nullptr, &swapChain1); + if (SUCCEEDED(result)) + { + *swapChain = static_cast(swapChain1); + } + mVisual->SetContent(swapChain1); + mCompositionTarget->SetRoot(mVisual); + SafeRelease(factory2); + return result; + } + + // Use IDXGIFactory2::CreateSwapChainForHwnd if DXGI 1.2 is available to create a + // DXGI_SWAP_EFFECT_SEQUENTIAL swap chain. + IDXGIFactory2 *factory2 = d3d11::DynamicCastComObject(factory); + if (factory2 != nullptr) + { + DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {}; + swapChainDesc.Width = width; + swapChainDesc.Height = height; + swapChainDesc.Format = format; + swapChainDesc.Stereo = FALSE; + swapChainDesc.SampleDesc.Count = samples; + swapChainDesc.SampleDesc.Quality = 0; + swapChainDesc.BufferUsage = + DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_BACK_BUFFER; + swapChainDesc.BufferCount = 1; + swapChainDesc.Scaling = DXGI_SCALING_STRETCH; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL; + swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; + swapChainDesc.Flags = 0; + IDXGISwapChain1 *swapChain1 = nullptr; + HRESULT result = factory2->CreateSwapChainForHwnd(device, getNativeWindow(), &swapChainDesc, + nullptr, nullptr, &swapChain1); + if (SUCCEEDED(result)) + { + factory2->MakeWindowAssociation(getNativeWindow(), DXGI_MWA_NO_ALT_ENTER); + *swapChain = static_cast(swapChain1); + } + SafeRelease(factory2); + return result; + } + + DXGI_SWAP_CHAIN_DESC swapChainDesc = {}; + swapChainDesc.BufferCount = 1; + swapChainDesc.BufferDesc.Format = format; + swapChainDesc.BufferDesc.Width = width; + swapChainDesc.BufferDesc.Height = height; + swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; + swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; + swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; + swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; + swapChainDesc.BufferUsage = + DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_BACK_BUFFER; + swapChainDesc.Flags = 0; + swapChainDesc.OutputWindow = getNativeWindow(); + swapChainDesc.SampleDesc.Count = samples; + swapChainDesc.SampleDesc.Quality = 0; + swapChainDesc.Windowed = TRUE; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + + HRESULT result = factory->CreateSwapChain(device, &swapChainDesc, swapChain); + if (SUCCEEDED(result)) + { + factory->MakeWindowAssociation(getNativeWindow(), DXGI_MWA_NO_ALT_ENTER); + } + return result; +} + +void NativeWindow11Win32::commitChange() +{ + if (mDevice) + { + mDevice->Commit(); + } +} + +// static +bool NativeWindow11Win32::IsValidNativeWindow(EGLNativeWindowType window) +{ + return IsWindow(window) == TRUE; +} +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.h new file mode 100644 index 0000000000..f67cfc73a8 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.h @@ -0,0 +1,53 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// NativeWindow11Win32.h: Implementation of NativeWindow11 using win32 window APIs. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_WIN32_NATIVEWINDOW11WIN32_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_WIN32_NATIVEWINDOW11WIN32_H_ + +#include "libANGLE/renderer/d3d/d3d11/NativeWindow11.h" + +typedef interface IDCompositionDevice IDCompositionDevice; +typedef interface IDCompositionTarget IDCompositionTarget; +typedef interface IDCompositionVisual IDCompositionVisual; + +namespace rx +{ + +class NativeWindow11Win32 : public NativeWindow11 +{ + public: + NativeWindow11Win32(EGLNativeWindowType window, bool hasAlpha, bool directComposition); + ~NativeWindow11Win32() override; + + bool initialize() override; + bool getClientRect(LPRECT rect) const override; + bool isIconic() const override; + + HRESULT createSwapChain(ID3D11Device *device, + IDXGIFactory *factory, + DXGI_FORMAT format, + UINT width, + UINT height, + UINT samples, + IDXGISwapChain **swapChain) override; + + void commitChange() override; + + static bool IsValidNativeWindow(EGLNativeWindowType window); + + private: + bool mDirectComposition; + bool mHasAlpha; + IDCompositionDevice *mDevice; + IDCompositionTarget *mCompositionTarget; + IDCompositionVisual *mVisual; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_WIN32_NATIVEWINDOW11WIN32_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp new file mode 100644 index 0000000000..429159b4cb --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp @@ -0,0 +1,760 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Blit9.cpp: Surface copy utility class. + +#include "libANGLE/renderer/d3d/d3d9/Blit9.h" + +#include "libANGLE/Context.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/renderer/d3d/TextureD3D.h" +#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h" +#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" +#include "libANGLE/renderer/d3d/d3d9/TextureStorage9.h" +#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" +#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" + +namespace +{ +// Precompiled shaders +#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskpremultps.h" +#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskps.h" +#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskunmultps.h" +#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/luminancepremultps.h" +#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceps.h" +#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceunmultps.h" +#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/passthroughps.h" +#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/standardvs.h" + +const BYTE *const g_shaderCode[] = { + g_vs20_standardvs, + g_ps20_passthroughps, + g_ps20_luminanceps, + g_ps20_luminancepremultps, + g_ps20_luminanceunmultps, + g_ps20_componentmaskps, + g_ps20_componentmaskpremultps, + g_ps20_componentmaskunmultps, +}; + +const size_t g_shaderSize[] = { + sizeof(g_vs20_standardvs), + sizeof(g_ps20_passthroughps), + sizeof(g_ps20_luminanceps), + sizeof(g_ps20_luminancepremultps), + sizeof(g_ps20_luminanceunmultps), + sizeof(g_ps20_componentmaskps), + sizeof(g_ps20_componentmaskpremultps), + sizeof(g_ps20_componentmaskunmultps), +}; +} // namespace + +namespace rx +{ + +Blit9::Blit9(Renderer9 *renderer) + : mRenderer(renderer), + mGeometryLoaded(false), + mQuadVertexBuffer(nullptr), + mQuadVertexDeclaration(nullptr), + mSavedStateBlock(nullptr), + mSavedRenderTarget(nullptr), + mSavedDepthStencil(nullptr) +{ + memset(mCompiledShaders, 0, sizeof(mCompiledShaders)); +} + +Blit9::~Blit9() +{ + SafeRelease(mSavedStateBlock); + SafeRelease(mQuadVertexBuffer); + SafeRelease(mQuadVertexDeclaration); + + for (int i = 0; i < SHADER_COUNT; i++) + { + SafeRelease(mCompiledShaders[i]); + } +} + +angle::Result Blit9::initialize(Context9 *context9) +{ + if (mGeometryLoaded) + { + return angle::Result::Continue; + } + + static const float quad[] = {-1, -1, -1, 1, 1, -1, 1, 1}; + + IDirect3DDevice9 *device = mRenderer->getDevice(); + + HRESULT result = device->CreateVertexBuffer(sizeof(quad), D3DUSAGE_WRITEONLY, 0, + D3DPOOL_DEFAULT, &mQuadVertexBuffer, nullptr); + + ANGLE_TRY_HR(context9, result, "Failed to create internal blit vertex shader"); + + void *lockPtr = nullptr; + result = mQuadVertexBuffer->Lock(0, 0, &lockPtr, 0); + + ANGLE_TRY_HR(context9, result, "Failed to lock internal blit vertex shader"); + ASSERT(lockPtr); + + memcpy(lockPtr, quad, sizeof(quad)); + mQuadVertexBuffer->Unlock(); + + static const D3DVERTEXELEMENT9 elements[] = { + {0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, D3DDECL_END()}; + + result = device->CreateVertexDeclaration(elements, &mQuadVertexDeclaration); + ANGLE_TRY_HR(context9, result, "Failed to create internal blit vertex shader declaration"); + + mGeometryLoaded = true; + return angle::Result::Continue; +} + +template +angle::Result Blit9::setShader(Context9 *context9, + ShaderId source, + const char *profile, + angle::Result (Renderer9::*createShader)(d3d::Context *, + const DWORD *, + size_t length, + D3DShaderType **outShader), + HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType *)) +{ + IDirect3DDevice9 *device = mRenderer->getDevice(); + + D3DShaderType *shader = nullptr; + + if (mCompiledShaders[source] != nullptr) + { + shader = static_cast(mCompiledShaders[source]); + } + else + { + const BYTE *shaderCode = g_shaderCode[source]; + size_t shaderSize = g_shaderSize[source]; + ANGLE_TRY((mRenderer->*createShader)(context9, reinterpret_cast(shaderCode), + shaderSize, &shader)); + mCompiledShaders[source] = shader; + } + + HRESULT hr = (device->*setShader)(shader); + ANGLE_TRY_HR(context9, hr, "Failed to set shader for blit operation"); + return angle::Result::Continue; +} + +angle::Result Blit9::setVertexShader(Context9 *context9, ShaderId shader) +{ + return setShader(context9, shader, "vs_2_0", + &Renderer9::createVertexShader, + &IDirect3DDevice9::SetVertexShader); +} + +angle::Result Blit9::setPixelShader(Context9 *context9, ShaderId shader) +{ + return setShader(context9, shader, "ps_2_0", + &Renderer9::createPixelShader, + &IDirect3DDevice9::SetPixelShader); +} + +RECT Blit9::getSurfaceRect(IDirect3DSurface9 *surface) const +{ + D3DSURFACE_DESC desc; + surface->GetDesc(&desc); + + RECT rect; + rect.left = 0; + rect.top = 0; + rect.right = desc.Width; + rect.bottom = desc.Height; + + return rect; +} + +gl::Extents Blit9::getSurfaceSize(IDirect3DSurface9 *surface) const +{ + D3DSURFACE_DESC desc; + surface->GetDesc(&desc); + + return gl::Extents(desc.Width, desc.Height, 1); +} + +angle::Result Blit9::boxFilter(Context9 *context9, + IDirect3DSurface9 *source, + IDirect3DSurface9 *dest) +{ + ANGLE_TRY(initialize(context9)); + + angle::ComPtr texture = nullptr; + ANGLE_TRY(copySurfaceToTexture(context9, source, getSurfaceRect(source), &texture)); + + IDirect3DDevice9 *device = mRenderer->getDevice(); + + saveState(); + + device->SetTexture(0, texture.Get()); + device->SetRenderTarget(0, dest); + + ANGLE_TRY(setVertexShader(context9, SHADER_VS_STANDARD)); + ANGLE_TRY(setPixelShader(context9, SHADER_PS_PASSTHROUGH)); + + setCommonBlitState(); + device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + + setViewportAndShaderConstants(getSurfaceRect(source), getSurfaceSize(source), + getSurfaceRect(dest), false); + + render(); + + restoreState(); + + return angle::Result::Continue; +} + +angle::Result Blit9::copy2D(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const RECT &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) +{ + Context9 *context9 = GetImplAs(context); + + ANGLE_TRY(initialize(context9)); + + const gl::FramebufferAttachment *colorbuffer = framebuffer->getColorAttachment(0); + ASSERT(colorbuffer); + + RenderTarget9 *renderTarget9 = nullptr; + ANGLE_TRY(colorbuffer->getRenderTarget(context, 0, &renderTarget9)); + ASSERT(renderTarget9); + + angle::ComPtr source = renderTarget9->getSurface(); + ASSERT(source); + + angle::ComPtr destSurface = nullptr; + TextureStorage9 *storage9 = GetAs(storage); + ANGLE_TRY( + storage9->getSurfaceLevel(context, gl::TextureTarget::_2D, level, true, &destSurface)); + ASSERT(destSurface); + + ANGLE_TRY(copy(context9, source.Get(), nullptr, sourceRect, destFormat, destOffset, + destSurface.Get(), false, false, false)); + return angle::Result::Continue; +} + +angle::Result Blit9::copyCube(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const RECT &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + gl::TextureTarget target, + GLint level) +{ + Context9 *context9 = GetImplAs(context); + + ANGLE_TRY(initialize(context9)); + + const gl::FramebufferAttachment *colorbuffer = framebuffer->getColorAttachment(0); + ASSERT(colorbuffer); + + RenderTarget9 *renderTarget9 = nullptr; + ANGLE_TRY(colorbuffer->getRenderTarget(context, 0, &renderTarget9)); + ASSERT(renderTarget9); + + angle::ComPtr source = renderTarget9->getSurface(); + ASSERT(source); + + angle::ComPtr destSurface = nullptr; + TextureStorage9 *storage9 = GetAs(storage); + ANGLE_TRY(storage9->getSurfaceLevel(context, target, level, true, &destSurface)); + ASSERT(destSurface); + + return copy(context9, source.Get(), nullptr, sourceRect, destFormat, destOffset, + destSurface.Get(), false, false, false); +} + +angle::Result Blit9::copyTexture(const gl::Context *context, + const gl::Texture *source, + GLint sourceLevel, + const RECT &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + gl::TextureTarget destTarget, + GLint destLevel, + bool flipY, + bool premultiplyAlpha, + bool unmultiplyAlpha) +{ + Context9 *context9 = GetImplAs(context); + ANGLE_TRY(initialize(context9)); + + TextureD3D *sourceD3D = GetImplAs(source); + + TextureStorage *sourceStorage = nullptr; + ANGLE_TRY(sourceD3D->getNativeTexture(context, &sourceStorage)); + + TextureStorage9_2D *sourceStorage9 = GetAs(sourceStorage); + ASSERT(sourceStorage9); + + TextureStorage9 *destStorage9 = GetAs(storage); + ASSERT(destStorage9); + + ASSERT(sourceLevel == 0); + IDirect3DBaseTexture9 *sourceTexture = nullptr; + ANGLE_TRY(sourceStorage9->getBaseTexture(context, &sourceTexture)); + + angle::ComPtr sourceSurface = nullptr; + ANGLE_TRY(sourceStorage9->getSurfaceLevel(context, gl::TextureTarget::_2D, sourceLevel, true, + &sourceSurface)); + + angle::ComPtr destSurface = nullptr; + ANGLE_TRY(destStorage9->getSurfaceLevel(context, destTarget, destLevel, true, &destSurface)); + + return copy(context9, sourceSurface.Get(), sourceTexture, sourceRect, destFormat, destOffset, + destSurface.Get(), flipY, premultiplyAlpha, unmultiplyAlpha); +} + +angle::Result Blit9::copy(Context9 *context9, + IDirect3DSurface9 *source, + IDirect3DBaseTexture9 *sourceTexture, + const RECT &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + IDirect3DSurface9 *dest, + bool flipY, + bool premultiplyAlpha, + bool unmultiplyAlpha) +{ + ASSERT(source != nullptr && dest != nullptr); + + IDirect3DDevice9 *device = mRenderer->getDevice(); + + D3DSURFACE_DESC sourceDesc; + D3DSURFACE_DESC destDesc; + source->GetDesc(&sourceDesc); + dest->GetDesc(&destDesc); + + // Check if it's possible to use StetchRect + if (sourceDesc.Format == destDesc.Format && (destDesc.Usage & D3DUSAGE_RENDERTARGET) && + d3d9_gl::IsFormatChannelEquivalent(destDesc.Format, destFormat) && !flipY && + premultiplyAlpha == unmultiplyAlpha) + { + RECT destRect = {destOffset.x, destOffset.y, + destOffset.x + (sourceRect.right - sourceRect.left), + destOffset.y + (sourceRect.bottom - sourceRect.top)}; + HRESULT result = device->StretchRect(source, &sourceRect, dest, &destRect, D3DTEXF_POINT); + ANGLE_TRY_HR(context9, result, "StretchRect failed to blit between textures"); + return angle::Result::Continue; + } + + angle::ComPtr texture = sourceTexture; + RECT adjustedSourceRect = sourceRect; + gl::Extents sourceSize(sourceDesc.Width, sourceDesc.Height, 1); + + if (texture == nullptr) + { + ANGLE_TRY(copySurfaceToTexture(context9, source, sourceRect, &texture)); + + // copySurfaceToTexture only copies in the sourceRect area of the source surface. + // Adjust sourceRect so that it is now covering the entire source texture + adjustedSourceRect.left = 0; + adjustedSourceRect.right = sourceRect.right - sourceRect.left; + adjustedSourceRect.top = 0; + adjustedSourceRect.bottom = sourceRect.bottom - sourceRect.top; + + sourceSize.width = sourceRect.right - sourceRect.left; + sourceSize.height = sourceRect.bottom - sourceRect.top; + } + + ANGLE_TRY(formatConvert(context9, texture.Get(), adjustedSourceRect, sourceSize, destFormat, + destOffset, dest, flipY, premultiplyAlpha, unmultiplyAlpha)); + return angle::Result::Continue; +} + +angle::Result Blit9::formatConvert(Context9 *context9, + IDirect3DBaseTexture9 *source, + const RECT &sourceRect, + const gl::Extents &sourceSize, + GLenum destFormat, + const gl::Offset &destOffset, + IDirect3DSurface9 *dest, + bool flipY, + bool premultiplyAlpha, + bool unmultiplyAlpha) +{ + ANGLE_TRY(initialize(context9)); + + IDirect3DDevice9 *device = mRenderer->getDevice(); + + saveState(); + + device->SetTexture(0, source); + device->SetRenderTarget(0, dest); + + RECT destRect; + destRect.left = destOffset.x; + destRect.right = destOffset.x + (sourceRect.right - sourceRect.left); + destRect.top = destOffset.y; + destRect.bottom = destOffset.y + (sourceRect.bottom - sourceRect.top); + + setViewportAndShaderConstants(sourceRect, sourceSize, destRect, flipY); + + setCommonBlitState(); + + angle::Result result = + setFormatConvertShaders(context9, destFormat, flipY, premultiplyAlpha, unmultiplyAlpha); + if (result == angle::Result::Continue) + { + render(); + } + + restoreState(); + + return result; +} + +angle::Result Blit9::setFormatConvertShaders(Context9 *context9, + GLenum destFormat, + bool flipY, + bool premultiplyAlpha, + bool unmultiplyAlpha) +{ + ANGLE_TRY(setVertexShader(context9, SHADER_VS_STANDARD)); + + switch (destFormat) + { + case GL_RGBA: + case GL_BGRA_EXT: + case GL_RGB: + case GL_RG_EXT: + case GL_RED_EXT: + case GL_ALPHA: + if (premultiplyAlpha == unmultiplyAlpha) + { + ANGLE_TRY(setPixelShader(context9, SHADER_PS_COMPONENTMASK)); + } + else if (premultiplyAlpha) + { + ANGLE_TRY(setPixelShader(context9, SHADER_PS_COMPONENTMASK_PREMULTIPLY_ALPHA)); + } + else + { + ASSERT(unmultiplyAlpha); + ANGLE_TRY(setPixelShader(context9, SHADER_PS_COMPONENTMASK_UNMULTIPLY_ALPHA)); + } + break; + + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + if (premultiplyAlpha == unmultiplyAlpha) + { + ANGLE_TRY(setPixelShader(context9, SHADER_PS_LUMINANCE)); + } + else if (premultiplyAlpha) + { + ANGLE_TRY(setPixelShader(context9, SHADER_PS_LUMINANCE_PREMULTIPLY_ALPHA)); + } + else + { + ASSERT(unmultiplyAlpha); + ANGLE_TRY(setPixelShader(context9, SHADER_PS_LUMINANCE_UNMULTIPLY_ALPHA)); + } + break; + + default: + UNREACHABLE(); + } + + enum + { + X = 0, + Y = 1, + Z = 2, + W = 3 + }; + + // The meaning of this constant depends on the shader that was selected. + // See the shader assembly code above for details. + // Allocate one array for both registers and split it into two float4's. + float psConst[8] = {0}; + float *multConst = &psConst[0]; + float *addConst = &psConst[4]; + + switch (destFormat) + { + case GL_RGBA: + case GL_BGRA_EXT: + multConst[X] = 1; + multConst[Y] = 1; + multConst[Z] = 1; + multConst[W] = 1; + addConst[X] = 0; + addConst[Y] = 0; + addConst[Z] = 0; + addConst[W] = 0; + break; + + case GL_RGB: + multConst[X] = 1; + multConst[Y] = 1; + multConst[Z] = 1; + multConst[W] = 0; + addConst[X] = 0; + addConst[Y] = 0; + addConst[Z] = 0; + addConst[W] = 1; + break; + + case GL_RG_EXT: + multConst[X] = 1; + multConst[Y] = 1; + multConst[Z] = 0; + multConst[W] = 0; + addConst[X] = 0; + addConst[Y] = 0; + addConst[Z] = 0; + addConst[W] = 1; + break; + + case GL_RED_EXT: + multConst[X] = 1; + multConst[Y] = 0; + multConst[Z] = 0; + multConst[W] = 0; + addConst[X] = 0; + addConst[Y] = 0; + addConst[Z] = 0; + addConst[W] = 1; + break; + + case GL_ALPHA: + multConst[X] = 0; + multConst[Y] = 0; + multConst[Z] = 0; + multConst[W] = 1; + addConst[X] = 0; + addConst[Y] = 0; + addConst[Z] = 0; + addConst[W] = 0; + break; + + case GL_LUMINANCE: + multConst[X] = 1; + multConst[Y] = 0; + multConst[Z] = 0; + multConst[W] = 0; + addConst[X] = 0; + addConst[Y] = 0; + addConst[Z] = 0; + addConst[W] = 1; + break; + + case GL_LUMINANCE_ALPHA: + multConst[X] = 1; + multConst[Y] = 0; + multConst[Z] = 0; + multConst[W] = 1; + addConst[X] = 0; + addConst[Y] = 0; + addConst[Z] = 0; + addConst[W] = 0; + break; + + default: + UNREACHABLE(); + } + + mRenderer->getDevice()->SetPixelShaderConstantF(0, psConst, 2); + + return angle::Result::Continue; +} + +angle::Result Blit9::copySurfaceToTexture(Context9 *context9, + IDirect3DSurface9 *surface, + const RECT &sourceRect, + angle::ComPtr *outTexture) +{ + ASSERT(surface); + + IDirect3DDevice9 *device = mRenderer->getDevice(); + + D3DSURFACE_DESC sourceDesc; + surface->GetDesc(&sourceDesc); + + // Copy the render target into a texture + angle::ComPtr texture; + HRESULT result = device->CreateTexture( + sourceRect.right - sourceRect.left, sourceRect.bottom - sourceRect.top, 1, + D3DUSAGE_RENDERTARGET, sourceDesc.Format, D3DPOOL_DEFAULT, &texture, nullptr); + ANGLE_TRY_HR(context9, result, "Failed to allocate internal texture for blit"); + + angle::ComPtr textureSurface; + result = texture->GetSurfaceLevel(0, &textureSurface); + ANGLE_TRY_HR(context9, result, "Failed to query surface of internal blit texture"); + + mRenderer->endScene(); + result = device->StretchRect(surface, &sourceRect, textureSurface.Get(), nullptr, D3DTEXF_NONE); + ANGLE_TRY_HR(context9, result, "Failed to copy between internal blit textures"); + *outTexture = texture; + + return angle::Result::Continue; +} + +void Blit9::setViewportAndShaderConstants(const RECT &sourceRect, + const gl::Extents &sourceSize, + const RECT &destRect, + bool flipY) +{ + IDirect3DDevice9 *device = mRenderer->getDevice(); + + D3DVIEWPORT9 vp; + vp.X = destRect.left; + vp.Y = destRect.top; + vp.Width = destRect.right - destRect.left; + vp.Height = destRect.bottom - destRect.top; + vp.MinZ = 0.0f; + vp.MaxZ = 1.0f; + device->SetViewport(&vp); + + float vertexConstants[8] = { + // halfPixelAdjust + -1.0f / vp.Width, + 1.0f / vp.Height, + 0, + 0, + // texcoordOffset + static_cast(sourceRect.left) / sourceSize.width, + static_cast(flipY ? sourceRect.bottom : sourceRect.top) / sourceSize.height, + static_cast(sourceRect.right - sourceRect.left) / sourceSize.width, + static_cast(flipY ? sourceRect.top - sourceRect.bottom + : sourceRect.bottom - sourceRect.top) / + sourceSize.height, + }; + + device->SetVertexShaderConstantF(0, vertexConstants, 2); +} + +void Blit9::setCommonBlitState() +{ + IDirect3DDevice9 *device = mRenderer->getDevice(); + + device->SetDepthStencilSurface(nullptr); + + device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); + device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); + device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0); + device->SetRenderState(D3DRS_COLORWRITEENABLE, + D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | + D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED); + device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE); + device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); + + device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); + device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); + device->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, FALSE); + device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); + device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); + + RECT scissorRect = {}; // Scissoring is disabled for flipping, but we need this to capture and + // restore the old rectangle + device->SetScissorRect(&scissorRect); + + for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + { + device->SetStreamSourceFreq(i, 1); + } +} + +void Blit9::render() +{ + IDirect3DDevice9 *device = mRenderer->getDevice(); + + device->SetStreamSource(0, mQuadVertexBuffer, 0, 2 * sizeof(float)); + device->SetVertexDeclaration(mQuadVertexDeclaration); + + mRenderer->startScene(); + device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); +} + +void Blit9::saveState() +{ + IDirect3DDevice9 *device = mRenderer->getDevice(); + + HRESULT hr; + + device->GetDepthStencilSurface(&mSavedDepthStencil); + device->GetRenderTarget(0, &mSavedRenderTarget); + + if (mSavedStateBlock == nullptr) + { + hr = device->BeginStateBlock(); + ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); + + setCommonBlitState(); + + static const float mockConst[8] = {0}; + + device->SetVertexShader(nullptr); + device->SetVertexShaderConstantF(0, mockConst, 2); + device->SetPixelShader(nullptr); + device->SetPixelShaderConstantF(0, mockConst, 2); + + D3DVIEWPORT9 mockVp; + mockVp.X = 0; + mockVp.Y = 0; + mockVp.Width = 1; + mockVp.Height = 1; + mockVp.MinZ = 0; + mockVp.MaxZ = 1; + + device->SetViewport(&mockVp); + + device->SetTexture(0, nullptr); + + device->SetStreamSource(0, mQuadVertexBuffer, 0, 0); + + device->SetVertexDeclaration(mQuadVertexDeclaration); + + hr = device->EndStateBlock(&mSavedStateBlock); + ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); + } + + ASSERT(mSavedStateBlock != nullptr); + + if (mSavedStateBlock != nullptr) + { + hr = mSavedStateBlock->Capture(); + ASSERT(SUCCEEDED(hr)); + } +} + +void Blit9::restoreState() +{ + IDirect3DDevice9 *device = mRenderer->getDevice(); + + device->SetDepthStencilSurface(mSavedDepthStencil); + SafeRelease(mSavedDepthStencil); + + device->SetRenderTarget(0, mSavedRenderTarget); + SafeRelease(mSavedRenderTarget); + + ASSERT(mSavedStateBlock != nullptr); + + if (mSavedStateBlock != nullptr) + { + mSavedStateBlock->Apply(); + } +} +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Blit9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Blit9.h new file mode 100644 index 0000000000..1c99413ecd --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Blit9.h @@ -0,0 +1,166 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Blit9.cpp: Surface copy utility class. + +#ifndef LIBANGLE_RENDERER_D3D_D3D9_BLIT9_H_ +#define LIBANGLE_RENDERER_D3D_D3D9_BLIT9_H_ + +#include "common/PackedEnums.h" +#include "common/angleutils.h" +#include "libANGLE/Error.h" + +namespace gl +{ +class Context; +class Framebuffer; +class Texture; +struct Extents; +struct Offset; +} // namespace gl + +namespace rx +{ +class Context9; +class Renderer9; +class TextureStorage; + +namespace d3d +{ +class Context; +} // namespace d3d + +class Blit9 : angle::NonCopyable +{ + public: + explicit Blit9(Renderer9 *renderer); + ~Blit9(); + + angle::Result initialize(Context9 *context9); + + // Copy from source surface to dest surface. + // sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left) + angle::Result copy2D(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const RECT &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level); + angle::Result copyCube(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const RECT &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + gl::TextureTarget target, + GLint level); + angle::Result copyTexture(const gl::Context *context, + const gl::Texture *source, + GLint sourceLevel, + const RECT &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + gl::TextureTarget destTarget, + GLint destLevel, + bool flipY, + bool premultiplyAlpha, + bool unmultiplyAlpha); + + // 2x2 box filter sample from source to dest. + // Requires that source is RGB(A) and dest has the same format as source. + angle::Result boxFilter(Context9 *context9, IDirect3DSurface9 *source, IDirect3DSurface9 *dest); + + private: + Renderer9 *mRenderer; + + bool mGeometryLoaded; + IDirect3DVertexBuffer9 *mQuadVertexBuffer; + IDirect3DVertexDeclaration9 *mQuadVertexDeclaration; + + // Copy from source texture to dest surface. + // sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left) + // source is interpreted as RGBA and destFormat specifies the desired result format. For + // example, if destFormat = GL_RGB, the alpha channel will be forced to 0. + angle::Result formatConvert(Context9 *context9, + IDirect3DBaseTexture9 *source, + const RECT &sourceRect, + const gl::Extents &sourceSize, + GLenum destFormat, + const gl::Offset &destOffset, + IDirect3DSurface9 *dest, + bool flipY, + bool premultiplyAlpha, + bool unmultiplyAlpha); + angle::Result setFormatConvertShaders(Context9 *context9, + GLenum destFormat, + bool flipY, + bool premultiplyAlpha, + bool unmultiplyAlpha); + + angle::Result copy(Context9 *context9, + IDirect3DSurface9 *source, + IDirect3DBaseTexture9 *sourceTexture, + const RECT &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + IDirect3DSurface9 *dest, + bool flipY, + bool premultiplyAlpha, + bool unmultiplyAlpha); + angle::Result copySurfaceToTexture(Context9 *context9, + IDirect3DSurface9 *surface, + const RECT &sourceRect, + angle::ComPtr *outTexture); + void setViewportAndShaderConstants(const RECT &sourceRect, + const gl::Extents &sourceSize, + const RECT &destRect, + bool flipY); + void setCommonBlitState(); + RECT getSurfaceRect(IDirect3DSurface9 *surface) const; + gl::Extents getSurfaceSize(IDirect3DSurface9 *surface) const; + + // This enum is used to index mCompiledShaders and mShaderSource. + enum ShaderId + { + SHADER_VS_STANDARD, + SHADER_PS_PASSTHROUGH, + SHADER_PS_LUMINANCE, + SHADER_PS_LUMINANCE_PREMULTIPLY_ALPHA, + SHADER_PS_LUMINANCE_UNMULTIPLY_ALPHA, + SHADER_PS_COMPONENTMASK, + SHADER_PS_COMPONENTMASK_PREMULTIPLY_ALPHA, + SHADER_PS_COMPONENTMASK_UNMULTIPLY_ALPHA, + SHADER_COUNT, + }; + + // This actually contains IDirect3DVertexShader9 or IDirect3DPixelShader9 casted to IUnknown. + IUnknown *mCompiledShaders[SHADER_COUNT]; + + template + angle::Result setShader(Context9 *, + ShaderId source, + const char *profile, + angle::Result (Renderer9::*createShader)(d3d::Context *context, + const DWORD *, + size_t length, + D3DShaderType **outShader), + HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType *)); + + angle::Result setVertexShader(Context9 *context9, ShaderId shader); + angle::Result setPixelShader(Context9 *context9, ShaderId shader); + void render(); + + void saveState(); + void restoreState(); + IDirect3DStateBlock9 *mSavedStateBlock; + IDirect3DSurface9 *mSavedRenderTarget; + IDirect3DSurface9 *mSavedDepthStencil; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D9_BLIT9_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp new file mode 100644 index 0000000000..dbf875134b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp @@ -0,0 +1,141 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Buffer9.cpp Defines the Buffer9 class. + +#include "libANGLE/renderer/d3d/d3d9/Buffer9.h" + +#include "libANGLE/Context.h" +#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" + +namespace rx +{ + +Buffer9::Buffer9(const gl::BufferState &state, Renderer9 *renderer) + : BufferD3D(state, renderer), mSize(0) +{} + +Buffer9::~Buffer9() +{ + mSize = 0; +} + +size_t Buffer9::getSize() const +{ + return mSize; +} + +bool Buffer9::supportsDirectBinding() const +{ + return false; +} + +angle::Result Buffer9::setData(const gl::Context *context, + gl::BufferBinding target, + const void *data, + size_t size, + gl::BufferUsage usage) +{ + if (size > mMemory.size()) + { + ANGLE_CHECK_GL_ALLOC(GetImplAs(context), mMemory.resize(size)); + } + + mSize = size; + if (data && size > 0) + { + memcpy(mMemory.data(), data, size); + } + + updateD3DBufferUsage(context, usage); + + invalidateStaticData(context); + + return angle::Result::Continue; +} + +angle::Result Buffer9::getData(const gl::Context *context, const uint8_t **outData) +{ + if (mMemory.empty()) + { + *outData = nullptr; + } + else + { + *outData = mMemory.data(); + } + return angle::Result::Continue; +} + +angle::Result Buffer9::setSubData(const gl::Context *context, + gl::BufferBinding target, + const void *data, + size_t size, + size_t offset) +{ + if (offset + size > mMemory.size()) + { + ANGLE_CHECK_GL_ALLOC(GetImplAs(context), mMemory.resize(size + offset)); + } + + mSize = std::max(mSize, offset + size); + if (data && size > 0) + { + memcpy(mMemory.data() + offset, data, size); + } + + invalidateStaticData(context); + + return angle::Result::Continue; +} + +angle::Result Buffer9::copySubData(const gl::Context *context, + BufferImpl *source, + GLintptr sourceOffset, + GLintptr destOffset, + GLsizeiptr size) +{ + // Note: this method is currently unreachable + Buffer9 *sourceBuffer = GetAs(source); + ASSERT(sourceBuffer); + + memcpy(mMemory.data() + destOffset, sourceBuffer->mMemory.data() + sourceOffset, size); + + invalidateStaticData(context); + + return angle::Result::Continue; +} + +// We do not support buffer mapping in D3D9 +angle::Result Buffer9::map(const gl::Context *context, GLenum access, void **mapPtr) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result Buffer9::mapRange(const gl::Context *context, + size_t offset, + size_t length, + GLbitfield access, + void **mapPtr) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result Buffer9::unmap(const gl::Context *context, GLboolean *result) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result Buffer9::markTransformFeedbackUsage(const gl::Context *context) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Buffer9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Buffer9.h new file mode 100644 index 0000000000..dad120d75b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Buffer9.h @@ -0,0 +1,63 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Buffer9.h: Defines the rx::Buffer9 class which implements rx::BufferImpl via rx::BufferD3D. + +#ifndef LIBANGLE_RENDERER_D3D_D3D9_BUFFER9_H_ +#define LIBANGLE_RENDERER_D3D_D3D9_BUFFER9_H_ + +#include "common/MemoryBuffer.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/renderer/d3d/BufferD3D.h" + +namespace rx +{ +class Renderer9; + +class Buffer9 : public BufferD3D +{ + public: + Buffer9(const gl::BufferState &state, Renderer9 *renderer); + ~Buffer9() override; + + // BufferD3D implementation + size_t getSize() const override; + bool supportsDirectBinding() const override; + angle::Result getData(const gl::Context *context, const uint8_t **outData) override; + + // BufferImpl implementation + angle::Result setData(const gl::Context *context, + gl::BufferBinding target, + const void *data, + size_t size, + gl::BufferUsage usage) override; + angle::Result setSubData(const gl::Context *context, + gl::BufferBinding target, + const void *data, + size_t size, + size_t offset) override; + angle::Result copySubData(const gl::Context *context, + BufferImpl *source, + GLintptr sourceOffset, + GLintptr destOffset, + GLsizeiptr size) override; + angle::Result map(const gl::Context *context, GLenum access, void **mapPtr) override; + angle::Result mapRange(const gl::Context *context, + size_t offset, + size_t length, + GLbitfield access, + void **mapPtr) override; + angle::Result unmap(const gl::Context *context, GLboolean *result) override; + angle::Result markTransformFeedbackUsage(const gl::Context *context) override; + + private: + angle::MemoryBuffer mMemory; + size_t mSize; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D9_BUFFER9_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Context9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Context9.cpp new file mode 100644 index 0000000000..b879d9c93b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Context9.cpp @@ -0,0 +1,529 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Context9: +// D3D9-specific functionality associated with a GL Context. +// + +#include "libANGLE/renderer/d3d/d3d9/Context9.h" + +#include "common/entry_points_enum_autogen.h" +#include "common/string_utils.h" +#include "libANGLE/renderer/OverlayImpl.h" +#include "libANGLE/renderer/d3d/CompilerD3D.h" +#include "libANGLE/renderer/d3d/ProgramD3D.h" +#include "libANGLE/renderer/d3d/RenderbufferD3D.h" +#include "libANGLE/renderer/d3d/SamplerD3D.h" +#include "libANGLE/renderer/d3d/ShaderD3D.h" +#include "libANGLE/renderer/d3d/TextureD3D.h" +#include "libANGLE/renderer/d3d/d3d9/Buffer9.h" +#include "libANGLE/renderer/d3d/d3d9/Fence9.h" +#include "libANGLE/renderer/d3d/d3d9/Framebuffer9.h" +#include "libANGLE/renderer/d3d/d3d9/Query9.h" +#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" +#include "libANGLE/renderer/d3d/d3d9/StateManager9.h" +#include "libANGLE/renderer/d3d/d3d9/VertexArray9.h" + +namespace rx +{ + +Context9::Context9(const gl::State &state, gl::ErrorSet *errorSet, Renderer9 *renderer) + : ContextD3D(state, errorSet), mRenderer(renderer) +{} + +Context9::~Context9() {} + +angle::Result Context9::initialize() +{ + return angle::Result::Continue; +} + +void Context9::onDestroy(const gl::Context *context) +{ + mIncompleteTextures.onDestroy(context); +} + +CompilerImpl *Context9::createCompiler() +{ + return new CompilerD3D(SH_HLSL_3_0_OUTPUT); +} + +ShaderImpl *Context9::createShader(const gl::ShaderState &data) +{ + return new ShaderD3D(data, mRenderer); +} + +ProgramImpl *Context9::createProgram(const gl::ProgramState &data) +{ + return new ProgramD3D(data, mRenderer); +} + +FramebufferImpl *Context9::createFramebuffer(const gl::FramebufferState &data) +{ + return new Framebuffer9(data, mRenderer); +} + +TextureImpl *Context9::createTexture(const gl::TextureState &state) +{ + switch (state.getType()) + { + case gl::TextureType::_2D: + // GL_TEXTURE_VIDEO_IMAGE_WEBGL maps to 2D texture on Windows platform. + case gl::TextureType::VideoImage: + return new TextureD3D_2D(state, mRenderer); + case gl::TextureType::CubeMap: + return new TextureD3D_Cube(state, mRenderer); + case gl::TextureType::External: + return new TextureD3D_External(state, mRenderer); + default: + UNREACHABLE(); + } + return nullptr; +} + +RenderbufferImpl *Context9::createRenderbuffer(const gl::RenderbufferState &state) +{ + return new RenderbufferD3D(state, mRenderer); +} + +BufferImpl *Context9::createBuffer(const gl::BufferState &state) +{ + return new Buffer9(state, mRenderer); +} + +VertexArrayImpl *Context9::createVertexArray(const gl::VertexArrayState &data) +{ + return new VertexArray9(data); +} + +QueryImpl *Context9::createQuery(gl::QueryType type) +{ + return new Query9(mRenderer, type); +} + +FenceNVImpl *Context9::createFenceNV() +{ + return new FenceNV9(mRenderer); +} + +SyncImpl *Context9::createSync() +{ + // D3D9 doesn't support ES 3.0 and its sync objects. + UNREACHABLE(); + return nullptr; +} + +TransformFeedbackImpl *Context9::createTransformFeedback(const gl::TransformFeedbackState &state) +{ + UNREACHABLE(); + return nullptr; +} + +SamplerImpl *Context9::createSampler(const gl::SamplerState &state) +{ + return new SamplerD3D(state); +} + +ProgramPipelineImpl *Context9::createProgramPipeline(const gl::ProgramPipelineState &data) +{ + UNREACHABLE(); + return nullptr; +} + +MemoryObjectImpl *Context9::createMemoryObject() +{ + UNREACHABLE(); + return nullptr; +} + +SemaphoreImpl *Context9::createSemaphore() +{ + UNREACHABLE(); + return nullptr; +} + +OverlayImpl *Context9::createOverlay(const gl::OverlayState &state) +{ + // Not implemented. + return new OverlayImpl(state); +} + +angle::Result Context9::flush(const gl::Context *context) +{ + return mRenderer->flush(context); +} + +angle::Result Context9::finish(const gl::Context *context) +{ + return mRenderer->finish(context); +} + +angle::Result Context9::drawArrays(const gl::Context *context, + gl::PrimitiveMode mode, + GLint first, + GLsizei count) +{ + return mRenderer->genericDrawArrays(context, mode, first, count, 0); +} + +angle::Result Context9::drawArraysInstanced(const gl::Context *context, + gl::PrimitiveMode mode, + GLint first, + GLsizei count, + GLsizei instanceCount) +{ + return mRenderer->genericDrawArrays(context, mode, first, count, instanceCount); +} + +angle::Result Context9::drawArraysInstancedBaseInstance(const gl::Context *context, + gl::PrimitiveMode mode, + GLint first, + GLsizei count, + GLsizei instanceCount, + GLuint baseInstance) +{ + ANGLE_HR_UNREACHABLE(this); + return angle::Result::Continue; +} + +angle::Result Context9::drawElements(const gl::Context *context, + gl::PrimitiveMode mode, + GLsizei count, + gl::DrawElementsType type, + const void *indices) +{ + return mRenderer->genericDrawElements(context, mode, count, type, indices, 0); +} + +angle::Result Context9::drawElementsBaseVertex(const gl::Context *context, + gl::PrimitiveMode mode, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + GLint baseVertex) +{ + ANGLE_HR_UNREACHABLE(this); + return angle::Result::Continue; +} + +angle::Result Context9::drawElementsInstanced(const gl::Context *context, + gl::PrimitiveMode mode, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + GLsizei instances) +{ + return mRenderer->genericDrawElements(context, mode, count, type, indices, instances); +} + +angle::Result Context9::drawElementsInstancedBaseVertex(const gl::Context *context, + gl::PrimitiveMode mode, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + GLsizei instances, + GLint baseVertex) +{ + ANGLE_HR_UNREACHABLE(this); + return angle::Result::Continue; +} + +angle::Result Context9::drawElementsInstancedBaseVertexBaseInstance(const gl::Context *context, + gl::PrimitiveMode mode, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + GLsizei instances, + GLint baseVertex, + GLuint baseInstance) +{ + ANGLE_HR_UNREACHABLE(this); + return angle::Result::Continue; +} + +angle::Result Context9::drawRangeElements(const gl::Context *context, + gl::PrimitiveMode mode, + GLuint start, + GLuint end, + GLsizei count, + gl::DrawElementsType type, + const void *indices) +{ + return mRenderer->genericDrawElements(context, mode, count, type, indices, 0); +} + +angle::Result Context9::drawRangeElementsBaseVertex(const gl::Context *context, + gl::PrimitiveMode mode, + GLuint start, + GLuint end, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + GLint baseVertex) +{ + ANGLE_HR_UNREACHABLE(this); + return angle::Result::Continue; +} + +angle::Result Context9::drawArraysIndirect(const gl::Context *context, + gl::PrimitiveMode mode, + const void *indirect) +{ + ANGLE_HR_UNREACHABLE(this); + return angle::Result::Stop; +} + +angle::Result Context9::drawElementsIndirect(const gl::Context *context, + gl::PrimitiveMode mode, + gl::DrawElementsType type, + const void *indirect) +{ + ANGLE_HR_UNREACHABLE(this); + return angle::Result::Stop; +} + +angle::Result Context9::multiDrawArrays(const gl::Context *context, + gl::PrimitiveMode mode, + const GLint *firsts, + const GLsizei *counts, + GLsizei drawcount) +{ + return rx::MultiDrawArraysGeneral(this, context, mode, firsts, counts, drawcount); +} + +angle::Result Context9::multiDrawArraysInstanced(const gl::Context *context, + gl::PrimitiveMode mode, + const GLint *firsts, + const GLsizei *counts, + const GLsizei *instanceCounts, + GLsizei drawcount) +{ + return rx::MultiDrawArraysInstancedGeneral(this, context, mode, firsts, counts, instanceCounts, + drawcount); +} + +angle::Result Context9::multiDrawArraysIndirect(const gl::Context *context, + gl::PrimitiveMode mode, + const void *indirect, + GLsizei drawcount, + GLsizei stride) +{ + UNREACHABLE(); + return angle::Result::Stop; +} + +angle::Result Context9::multiDrawElements(const gl::Context *context, + gl::PrimitiveMode mode, + const GLsizei *counts, + gl::DrawElementsType type, + const GLvoid *const *indices, + GLsizei drawcount) +{ + return rx::MultiDrawElementsGeneral(this, context, mode, counts, type, indices, drawcount); +} + +angle::Result Context9::multiDrawElementsInstanced(const gl::Context *context, + gl::PrimitiveMode mode, + const GLsizei *counts, + gl::DrawElementsType type, + const GLvoid *const *indices, + const GLsizei *instanceCounts, + GLsizei drawcount) +{ + return rx::MultiDrawElementsInstancedGeneral(this, context, mode, counts, type, indices, + instanceCounts, drawcount); +} + +angle::Result Context9::multiDrawElementsIndirect(const gl::Context *context, + gl::PrimitiveMode mode, + gl::DrawElementsType type, + const void *indirect, + GLsizei drawcount, + GLsizei stride) +{ + UNREACHABLE(); + return angle::Result::Stop; +} + +angle::Result Context9::multiDrawArraysInstancedBaseInstance(const gl::Context *context, + gl::PrimitiveMode mode, + const GLint *firsts, + const GLsizei *counts, + const GLsizei *instanceCounts, + const GLuint *baseInstances, + GLsizei drawcount) +{ + ANGLE_HR_UNREACHABLE(this); + return angle::Result::Stop; +} + +angle::Result Context9::multiDrawElementsInstancedBaseVertexBaseInstance( + const gl::Context *context, + gl::PrimitiveMode mode, + const GLsizei *counts, + gl::DrawElementsType type, + const GLvoid *const *indices, + const GLsizei *instanceCounts, + const GLint *baseVertices, + const GLuint *baseInstances, + GLsizei drawcount) +{ + ANGLE_HR_UNREACHABLE(this); + return angle::Result::Stop; +} + +gl::GraphicsResetStatus Context9::getResetStatus() +{ + return mRenderer->getResetStatus(); +} + +angle::Result Context9::insertEventMarker(GLsizei length, const char *marker) +{ + mRenderer->getAnnotator()->setMarker(/*context=*/nullptr, marker); + return angle::Result::Continue; +} + +angle::Result Context9::pushGroupMarker(GLsizei length, const char *marker) +{ + mRenderer->getAnnotator()->beginEvent(nullptr, angle::EntryPoint::GLPushGroupMarkerEXT, marker, + marker); + mMarkerStack.push(std::string(marker)); + return angle::Result::Continue; +} + +angle::Result Context9::popGroupMarker() +{ + const char *marker = nullptr; + if (!mMarkerStack.empty()) + { + marker = mMarkerStack.top().c_str(); + mMarkerStack.pop(); + mRenderer->getAnnotator()->endEvent(nullptr, marker, + angle::EntryPoint::GLPopGroupMarkerEXT); + } + return angle::Result::Continue; +} + +angle::Result Context9::pushDebugGroup(const gl::Context *context, + GLenum source, + GLuint id, + const std::string &message) +{ + // Fall through to the EXT_debug_marker functions + return pushGroupMarker(static_cast(message.size()), message.c_str()); +} + +angle::Result Context9::popDebugGroup(const gl::Context *context) +{ + // Fall through to the EXT_debug_marker functions + return popGroupMarker(); +} + +angle::Result Context9::syncState(const gl::Context *context, + const gl::State::DirtyBits &dirtyBits, + const gl::State::DirtyBits &bitMask, + gl::Command command) +{ + mRenderer->getStateManager()->syncState(mState, dirtyBits); + return angle::Result::Continue; +} + +GLint Context9::getGPUDisjoint() +{ + return mRenderer->getGPUDisjoint(); +} + +GLint64 Context9::getTimestamp() +{ + return mRenderer->getTimestamp(); +} + +angle::Result Context9::onMakeCurrent(const gl::Context *context) +{ + mRenderer->getStateManager()->setAllDirtyBits(); + return mRenderer->ensureVertexDataManagerInitialized(context); +} + +gl::Caps Context9::getNativeCaps() const +{ + return mRenderer->getNativeCaps(); +} + +const gl::TextureCapsMap &Context9::getNativeTextureCaps() const +{ + return mRenderer->getNativeTextureCaps(); +} + +const gl::Extensions &Context9::getNativeExtensions() const +{ + return mRenderer->getNativeExtensions(); +} + +const gl::Limitations &Context9::getNativeLimitations() const +{ + return mRenderer->getNativeLimitations(); +} + +ShPixelLocalStorageType Context9::getNativePixelLocalStorageType() const +{ + return mRenderer->getNativePixelLocalStorageType(); +} + +angle::Result Context9::dispatchCompute(const gl::Context *context, + GLuint numGroupsX, + GLuint numGroupsY, + GLuint numGroupsZ) +{ + ANGLE_HR_UNREACHABLE(this); + return angle::Result::Stop; +} + +angle::Result Context9::dispatchComputeIndirect(const gl::Context *context, GLintptr indirect) +{ + ANGLE_HR_UNREACHABLE(this); + return angle::Result::Stop; +} + +angle::Result Context9::memoryBarrier(const gl::Context *context, GLbitfield barriers) +{ + ANGLE_HR_UNREACHABLE(this); + return angle::Result::Stop; +} + +angle::Result Context9::memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers) +{ + ANGLE_HR_UNREACHABLE(this); + return angle::Result::Stop; +} + +angle::Result Context9::getIncompleteTexture(const gl::Context *context, + gl::TextureType type, + gl::Texture **textureOut) +{ + return mIncompleteTextures.getIncompleteTexture(context, type, gl::SamplerFormat::Float, + nullptr, textureOut); +} + +void Context9::handleResult(HRESULT hr, + const char *message, + const char *file, + const char *function, + unsigned int line) +{ + ASSERT(FAILED(hr)); + + if (d3d9::isDeviceLostError(hr)) + { + mRenderer->notifyDeviceLost(); + } + + GLenum glErrorCode = DefaultGLErrorCode(hr); + + std::stringstream errorStream; + errorStream << "Internal D3D9 error: " << gl::FmtHR(hr) << ": " << message; + + mErrors->handleError(glErrorCode, errorStream.str().c_str(), file, function, line); +} +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Context9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Context9.h new file mode 100644 index 0000000000..ce3e930295 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Context9.h @@ -0,0 +1,265 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Context9: +// D3D9-specific functionality associated with a GL Context. +// + +#ifndef LIBANGLE_RENDERER_D3D_D3D9_CONTEXT9_H_ +#define LIBANGLE_RENDERER_D3D_D3D9_CONTEXT9_H_ + +#include +#include "libANGLE/renderer/d3d/ContextD3D.h" + +namespace rx +{ +class Renderer9; + +class Context9 : public ContextD3D +{ + public: + Context9(const gl::State &state, gl::ErrorSet *errorSet, Renderer9 *renderer); + ~Context9() override; + + angle::Result initialize() override; + void onDestroy(const gl::Context *context) override; + + // Shader creation + CompilerImpl *createCompiler() override; + ShaderImpl *createShader(const gl::ShaderState &data) override; + ProgramImpl *createProgram(const gl::ProgramState &data) override; + + // Framebuffer creation + FramebufferImpl *createFramebuffer(const gl::FramebufferState &data) override; + + // Texture creation + TextureImpl *createTexture(const gl::TextureState &state) override; + + // Renderbuffer creation + RenderbufferImpl *createRenderbuffer(const gl::RenderbufferState &state) override; + + // Buffer creation + BufferImpl *createBuffer(const gl::BufferState &state) override; + + // Vertex Array creation + VertexArrayImpl *createVertexArray(const gl::VertexArrayState &data) override; + + // Query and Fence creation + QueryImpl *createQuery(gl::QueryType type) override; + FenceNVImpl *createFenceNV() override; + SyncImpl *createSync() override; + + // Transform Feedback creation + TransformFeedbackImpl *createTransformFeedback( + const gl::TransformFeedbackState &state) override; + + // Sampler object creation + SamplerImpl *createSampler(const gl::SamplerState &state) override; + + // Program Pipeline object creation + ProgramPipelineImpl *createProgramPipeline(const gl::ProgramPipelineState &data) override; + + // Memory object creation. + MemoryObjectImpl *createMemoryObject() override; + + // Semaphore creation. + SemaphoreImpl *createSemaphore() override; + + // Overlay creation. + OverlayImpl *createOverlay(const gl::OverlayState &state) override; + + // Flush and finish. + angle::Result flush(const gl::Context *context) override; + angle::Result finish(const gl::Context *context) override; + + // Drawing methods. + angle::Result drawArrays(const gl::Context *context, + gl::PrimitiveMode mode, + GLint first, + GLsizei count) override; + angle::Result drawArraysInstanced(const gl::Context *context, + gl::PrimitiveMode mode, + GLint first, + GLsizei count, + GLsizei instanceCount) override; + angle::Result drawArraysInstancedBaseInstance(const gl::Context *context, + gl::PrimitiveMode mode, + GLint first, + GLsizei count, + GLsizei instanceCount, + GLuint baseInstance) override; + + angle::Result drawElements(const gl::Context *context, + gl::PrimitiveMode mode, + GLsizei count, + gl::DrawElementsType type, + const void *indices) override; + angle::Result drawElementsBaseVertex(const gl::Context *context, + gl::PrimitiveMode mode, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + GLint baseVertex) override; + angle::Result drawElementsInstanced(const gl::Context *context, + gl::PrimitiveMode mode, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + GLsizei instances) override; + angle::Result drawElementsInstancedBaseVertex(const gl::Context *context, + gl::PrimitiveMode mode, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + GLsizei instances, + GLint baseVertex) override; + angle::Result drawElementsInstancedBaseVertexBaseInstance(const gl::Context *context, + gl::PrimitiveMode mode, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + GLsizei instances, + GLint baseVertex, + GLuint baseInstance) override; + angle::Result drawRangeElements(const gl::Context *context, + gl::PrimitiveMode mode, + GLuint start, + GLuint end, + GLsizei count, + gl::DrawElementsType type, + const void *indices) override; + angle::Result drawRangeElementsBaseVertex(const gl::Context *context, + gl::PrimitiveMode mode, + GLuint start, + GLuint end, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + GLint baseVertex) override; + angle::Result drawArraysIndirect(const gl::Context *context, + gl::PrimitiveMode mode, + const void *indirect) override; + angle::Result drawElementsIndirect(const gl::Context *context, + gl::PrimitiveMode mode, + gl::DrawElementsType type, + const void *indirect) override; + + angle::Result multiDrawArrays(const gl::Context *context, + gl::PrimitiveMode mode, + const GLint *firsts, + const GLsizei *counts, + GLsizei drawcount) override; + angle::Result multiDrawArraysInstanced(const gl::Context *context, + gl::PrimitiveMode mode, + const GLint *firsts, + const GLsizei *counts, + const GLsizei *instanceCounts, + GLsizei drawcount) override; + angle::Result multiDrawArraysIndirect(const gl::Context *context, + gl::PrimitiveMode mode, + const void *indirect, + GLsizei drawcount, + GLsizei stride) override; + angle::Result multiDrawElements(const gl::Context *context, + gl::PrimitiveMode mode, + const GLsizei *counts, + gl::DrawElementsType type, + const GLvoid *const *indices, + GLsizei drawcount) override; + angle::Result multiDrawElementsInstanced(const gl::Context *context, + gl::PrimitiveMode mode, + const GLsizei *counts, + gl::DrawElementsType type, + const GLvoid *const *indices, + const GLsizei *instanceCounts, + GLsizei drawcount) override; + angle::Result multiDrawElementsIndirect(const gl::Context *context, + gl::PrimitiveMode mode, + gl::DrawElementsType type, + const void *indirect, + GLsizei drawcount, + GLsizei stride) override; + angle::Result multiDrawArraysInstancedBaseInstance(const gl::Context *context, + gl::PrimitiveMode mode, + const GLint *firsts, + const GLsizei *counts, + const GLsizei *instanceCounts, + const GLuint *baseInstances, + GLsizei drawcount) override; + angle::Result multiDrawElementsInstancedBaseVertexBaseInstance(const gl::Context *context, + gl::PrimitiveMode mode, + const GLsizei *counts, + gl::DrawElementsType type, + const GLvoid *const *indices, + const GLsizei *instanceCounts, + const GLint *baseVertices, + const GLuint *baseInstances, + GLsizei drawcount) override; + + // Device loss + gl::GraphicsResetStatus getResetStatus() override; + + // EXT_debug_marker + angle::Result insertEventMarker(GLsizei length, const char *marker) override; + angle::Result pushGroupMarker(GLsizei length, const char *marker) override; + angle::Result popGroupMarker() override; + + // KHR_debug + angle::Result pushDebugGroup(const gl::Context *context, + GLenum source, + GLuint id, + const std::string &message) override; + angle::Result popDebugGroup(const gl::Context *context) override; + + // State sync with dirty bits. + angle::Result syncState(const gl::Context *context, + const gl::State::DirtyBits &dirtyBits, + const gl::State::DirtyBits &bitMask, + gl::Command command) override; + + // Disjoint timer queries + GLint getGPUDisjoint() override; + GLint64 getTimestamp() override; + + // Context switching + angle::Result onMakeCurrent(const gl::Context *context) override; + + // Caps queries + gl::Caps getNativeCaps() const override; + const gl::TextureCapsMap &getNativeTextureCaps() const override; + const gl::Extensions &getNativeExtensions() const override; + const gl::Limitations &getNativeLimitations() const override; + ShPixelLocalStorageType getNativePixelLocalStorageType() const override; + + angle::Result dispatchCompute(const gl::Context *context, + GLuint numGroupsX, + GLuint numGroupsY, + GLuint numGroupsZ) override; + angle::Result dispatchComputeIndirect(const gl::Context *context, GLintptr indirect) override; + + angle::Result memoryBarrier(const gl::Context *context, GLbitfield barriers) override; + angle::Result memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers) override; + + Renderer9 *getRenderer() const { return mRenderer; } + + angle::Result getIncompleteTexture(const gl::Context *context, + gl::TextureType type, + gl::Texture **textureOut); + + void handleResult(HRESULT hr, + const char *message, + const char *file, + const char *function, + unsigned int line) override; + + private: + Renderer9 *mRenderer; + IncompleteTextureSet mIncompleteTextures; + std::stack mMarkerStack; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D9_CONTEXT9_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.cpp new file mode 100644 index 0000000000..7e597e564b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.cpp @@ -0,0 +1,48 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// DebugAnnotator9.h: D3D9 helpers for adding trace annotations. +// + +#include "libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h" + +#include "common/platform.h" + +namespace rx +{ + +void DebugAnnotator9::beginEvent(gl::Context *context, + angle::EntryPoint entryPoint, + const char *eventName, + const char *eventMessage) +{ + angle::LoggingAnnotator::beginEvent(context, entryPoint, eventName, eventMessage); + std::mbstate_t state = std::mbstate_t(); + std::mbsrtowcs(mWCharMessage, &eventMessage, kMaxMessageLength, &state); + D3DPERF_BeginEvent(0, mWCharMessage); +} + +void DebugAnnotator9::endEvent(gl::Context *context, + const char *eventName, + angle::EntryPoint entryPoint) +{ + angle::LoggingAnnotator::endEvent(context, eventName, entryPoint); + D3DPERF_EndEvent(); +} + +void DebugAnnotator9::setMarker(gl::Context *context, const char *markerName) +{ + angle::LoggingAnnotator::setMarker(context, markerName); + std::mbstate_t state = std::mbstate_t(); + std::mbsrtowcs(mWCharMessage, &markerName, kMaxMessageLength, &state); + D3DPERF_SetMarker(0, mWCharMessage); +} + +bool DebugAnnotator9::getStatus(const gl::Context *context) +{ + return !!D3DPERF_GetStatus(); +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h new file mode 100644 index 0000000000..40f8189bea --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h @@ -0,0 +1,38 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// DebugAnnotator9.h: D3D9 helpers for adding trace annotations. +// + +#ifndef LIBANGLE_RENDERER_D3D_D3D9_DEBUGANNOTATOR9_H_ +#define LIBANGLE_RENDERER_D3D_D3D9_DEBUGANNOTATOR9_H_ + +#include "libANGLE/LoggingAnnotator.h" + +namespace rx +{ + +class DebugAnnotator9 : public angle::LoggingAnnotator +{ + public: + DebugAnnotator9() {} + void beginEvent(gl::Context *context, + angle::EntryPoint entryPoint, + const char *eventName, + const char *eventMessage) override; + void endEvent(gl::Context *context, + const char *eventName, + angle::EntryPoint entryPoint) override; + void setMarker(gl::Context *context, const char *markerName) override; + bool getStatus(const gl::Context *context) override; + + private: + static constexpr size_t kMaxMessageLength = 256; + wchar_t mWCharMessage[kMaxMessageLength]; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D9_DEBUGANNOTATOR9_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Fence9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Fence9.cpp new file mode 100644 index 0000000000..e844a9ae70 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Fence9.cpp @@ -0,0 +1,73 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Fence9.cpp: Defines the rx::FenceNV9 class. + +#include "libANGLE/renderer/d3d/d3d9/Fence9.h" + +#include "libANGLE/Context.h" +#include "libANGLE/renderer/d3d/d3d9/Context9.h" +#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" +#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" + +namespace rx +{ + +FenceNV9::FenceNV9(Renderer9 *renderer) : FenceNVImpl(), mRenderer(renderer), mQuery(nullptr) {} + +FenceNV9::~FenceNV9() +{ + SafeRelease(mQuery); +} + +angle::Result FenceNV9::set(const gl::Context *context, GLenum condition) +{ + if (!mQuery) + { + ANGLE_TRY(mRenderer->allocateEventQuery(context, &mQuery)); + } + + HRESULT result = mQuery->Issue(D3DISSUE_END); + if (FAILED(result)) + { + SafeRelease(mQuery); + } + ANGLE_TRY_HR(GetImplAs(context), result, "Failed to end event query"); + return angle::Result::Continue; +} + +angle::Result FenceNV9::test(const gl::Context *context, GLboolean *outFinished) +{ + return testHelper(GetImplAs(context), true, outFinished); +} + +angle::Result FenceNV9::finish(const gl::Context *context) +{ + GLboolean finished = GL_FALSE; + while (finished != GL_TRUE) + { + ANGLE_TRY(testHelper(GetImplAs(context), true, &finished)); + Sleep(0); + } + + return angle::Result::Continue; +} + +angle::Result FenceNV9::testHelper(Context9 *context9, + bool flushCommandBuffer, + GLboolean *outFinished) +{ + ASSERT(mQuery); + + DWORD getDataFlags = (flushCommandBuffer ? D3DGETDATA_FLUSH : 0); + HRESULT result = mQuery->GetData(nullptr, 0, getDataFlags); + ANGLE_TRY_HR(context9, result, "Failed to get query data"); + ASSERT(result == S_OK || result == S_FALSE); + *outFinished = ((result == S_OK) ? GL_TRUE : GL_FALSE); + return angle::Result::Continue; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Fence9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Fence9.h new file mode 100644 index 0000000000..c46671c102 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Fence9.h @@ -0,0 +1,39 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Fence9.h: Defines the rx::FenceNV9 class which implements rx::FenceNVImpl. + +#ifndef LIBANGLE_RENDERER_D3D_D3D9_FENCE9_H_ +#define LIBANGLE_RENDERER_D3D_D3D9_FENCE9_H_ + +#include "libANGLE/renderer/FenceNVImpl.h" +#include "libANGLE/renderer/SyncImpl.h" + +namespace rx +{ +class Context9; +class Renderer9; + +class FenceNV9 : public FenceNVImpl +{ + public: + explicit FenceNV9(Renderer9 *renderer); + ~FenceNV9() override; + + void onDestroy(const gl::Context *context) override {} + angle::Result set(const gl::Context *context, GLenum condition) override; + angle::Result test(const gl::Context *context, GLboolean *outFinished) override; + angle::Result finish(const gl::Context *context) override; + + private: + angle::Result testHelper(Context9 *context9, bool flushCommandBuffer, GLboolean *outFinished); + + Renderer9 *mRenderer; + IDirect3DQuery9 *mQuery; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D9_FENCE9_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp new file mode 100644 index 0000000000..f90fefac20 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp @@ -0,0 +1,416 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Framebuffer9.cpp: Implements the Framebuffer9 class. + +#include "libANGLE/renderer/d3d/d3d9/Framebuffer9.h" + +#include "libANGLE/Context.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/Texture.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/ContextImpl.h" +#include "libANGLE/renderer/d3d/TextureD3D.h" +#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h" +#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" +#include "libANGLE/renderer/d3d/d3d9/TextureStorage9.h" +#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" +#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" +#include "libANGLE/renderer/renderer_utils.h" + +namespace rx +{ +Framebuffer9::Framebuffer9(const gl::FramebufferState &data, Renderer9 *renderer) + : FramebufferD3D(data, renderer), mRenderer(renderer) +{ + ASSERT(mRenderer != nullptr); +} + +Framebuffer9::~Framebuffer9() {} + +angle::Result Framebuffer9::discard(const gl::Context *context, + size_t count, + const GLenum *attachments) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result Framebuffer9::invalidate(const gl::Context *context, + size_t count, + const GLenum *attachments) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result Framebuffer9::invalidateSub(const gl::Context *context, + size_t count, + const GLenum *attachments, + const gl::Rectangle &area) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result Framebuffer9::clearImpl(const gl::Context *context, + const ClearParameters &clearParams) +{ + ANGLE_TRY(mRenderer->applyRenderTarget(context, mRenderTargetCache.getColors()[0], + mRenderTargetCache.getDepthStencil())); + + const gl::State &glState = context->getState(); + float nearZ = glState.getNearPlane(); + float farZ = glState.getFarPlane(); + mRenderer->setViewport(glState.getViewport(), nearZ, farZ, gl::PrimitiveMode::Triangles, + glState.getRasterizerState().frontFace, true); + + mRenderer->setScissorRectangle(glState.getScissor(), glState.isScissorTestEnabled()); + + mRenderer->clear(clearParams, mRenderTargetCache.getColors()[0], + mRenderTargetCache.getDepthStencil()); + return angle::Result::Continue; +} + +angle::Result Framebuffer9::readPixelsImpl(const gl::Context *context, + const gl::Rectangle &area, + GLenum format, + GLenum type, + size_t outputPitch, + const gl::PixelPackState &pack, + gl::Buffer *packBuffer, + uint8_t *pixels) +{ + const gl::FramebufferAttachment *colorbuffer = mState.getColorAttachment(0); + ASSERT(colorbuffer); + + RenderTarget9 *renderTarget = nullptr; + ANGLE_TRY(colorbuffer->getRenderTarget(context, 0, &renderTarget)); + ASSERT(renderTarget); + + IDirect3DSurface9 *surface = renderTarget->getSurface(); + ASSERT(surface); + + D3DSURFACE_DESC desc; + surface->GetDesc(&desc); + + Context9 *context9 = GetImplAs(context); + + if (desc.MultiSampleType != D3DMULTISAMPLE_NONE) + { + UNIMPLEMENTED(); // FIXME: Requires resolve using StretchRect into non-multisampled render + // target + SafeRelease(surface); + ANGLE_TRY_HR(context9, E_OUTOFMEMORY, + "ReadPixels is unimplemented for multisampled framebuffer attachments."); + } + + IDirect3DDevice9 *device = mRenderer->getDevice(); + ASSERT(device); + + HRESULT result; + IDirect3DSurface9 *systemSurface = nullptr; + bool directToPixels = + !pack.reverseRowOrder && pack.alignment <= 4 && mRenderer->getShareHandleSupport() && + area.x == 0 && area.y == 0 && static_cast(area.width) == desc.Width && + static_cast(area.height) == desc.Height && desc.Format == D3DFMT_A8R8G8B8 && + format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE; + if (directToPixels) + { + // Use the pixels ptr as a shared handle to write directly into client's memory + result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, + D3DPOOL_SYSTEMMEM, &systemSurface, + reinterpret_cast(&pixels)); + if (FAILED(result)) + { + // Try again without the shared handle + directToPixels = false; + } + } + + if (!directToPixels) + { + result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, + D3DPOOL_SYSTEMMEM, &systemSurface, nullptr); + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + SafeRelease(surface); + ANGLE_TRY_HR(context9, E_OUTOFMEMORY, + "Failed to allocate internal texture for ReadPixels."); + } + } + + result = device->GetRenderTargetData(surface, systemSurface); + SafeRelease(surface); + + if (FAILED(result)) + { + SafeRelease(systemSurface); + + // It turns out that D3D will sometimes produce more error + // codes than those documented. + if (d3d9::isDeviceLostError(result)) + { + mRenderer->notifyDeviceLost(); + } + else + { + UNREACHABLE(); + } + + ANGLE_TRY_HR(context9, E_OUTOFMEMORY, "Failed to read internal render target data."); + } + + if (directToPixels) + { + SafeRelease(systemSurface); + return angle::Result::Continue; + } + + RECT rect; + rect.left = gl::clamp(area.x, 0L, static_cast(desc.Width)); + rect.top = gl::clamp(area.y, 0L, static_cast(desc.Height)); + rect.right = gl::clamp(area.x + area.width, 0L, static_cast(desc.Width)); + rect.bottom = gl::clamp(area.y + area.height, 0L, static_cast(desc.Height)); + + D3DLOCKED_RECT lock; + result = systemSurface->LockRect(&lock, &rect, D3DLOCK_READONLY); + + if (FAILED(result)) + { + UNREACHABLE(); + SafeRelease(systemSurface); + + ANGLE_TRY_HR(context9, E_OUTOFMEMORY, "Failed to lock internal render target."); + } + + uint8_t *source = static_cast(lock.pBits); + int inputPitch = lock.Pitch; + + const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format); + + gl::FormatType formatType(format, type); + + PackPixelsParams packParams; + packParams.area.x = rect.left; + packParams.area.y = rect.top; + packParams.area.width = rect.right - rect.left; + packParams.area.height = rect.bottom - rect.top; + packParams.destFormat = &GetFormatFromFormatType(format, type); + packParams.outputPitch = static_cast(outputPitch); + packParams.reverseRowOrder = pack.reverseRowOrder; + + PackPixels(packParams, d3dFormatInfo.info(), inputPitch, source, pixels); + + systemSurface->UnlockRect(); + SafeRelease(systemSurface); + + return angle::Result::Continue; +} + +angle::Result Framebuffer9::blitImpl(const gl::Context *context, + const gl::Rectangle &sourceArea, + const gl::Rectangle &destArea, + const gl::Rectangle *scissor, + bool blitRenderTarget, + bool blitDepth, + bool blitStencil, + GLenum filter, + const gl::Framebuffer *sourceFramebuffer) +{ + ASSERT(filter == GL_NEAREST); + + IDirect3DDevice9 *device = mRenderer->getDevice(); + ASSERT(device); + + mRenderer->endScene(); + + Context9 *context9 = GetImplAs(context); + + if (blitRenderTarget) + { + const gl::FramebufferAttachment *readBuffer = sourceFramebuffer->getColorAttachment(0); + ASSERT(readBuffer); + + RenderTarget9 *readRenderTarget = nullptr; + ANGLE_TRY(readBuffer->getRenderTarget(context, 0, &readRenderTarget)); + ASSERT(readRenderTarget); + + const gl::FramebufferAttachment *drawBuffer = mState.getColorAttachment(0); + ASSERT(drawBuffer); + + RenderTarget9 *drawRenderTarget = nullptr; + ANGLE_TRY( + drawBuffer->getRenderTarget(context, drawBuffer->getSamples(), &drawRenderTarget)); + ASSERT(drawRenderTarget); + + // The getSurface calls do an AddRef so save them until after no errors are possible + IDirect3DSurface9 *readSurface = readRenderTarget->getSurface(); + ASSERT(readSurface); + + IDirect3DSurface9 *drawSurface = drawRenderTarget->getSurface(); + ASSERT(drawSurface); + + gl::Extents srcSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1); + gl::Extents dstSize(drawRenderTarget->getWidth(), drawRenderTarget->getHeight(), 1); + + RECT srcRect; + srcRect.left = sourceArea.x; + srcRect.right = sourceArea.x + sourceArea.width; + srcRect.top = sourceArea.y; + srcRect.bottom = sourceArea.y + sourceArea.height; + + RECT dstRect; + dstRect.left = destArea.x; + dstRect.right = destArea.x + destArea.width; + dstRect.top = destArea.y; + dstRect.bottom = destArea.y + destArea.height; + + // Clip the rectangles to the scissor rectangle + if (scissor) + { + if (dstRect.left < scissor->x) + { + srcRect.left += (scissor->x - dstRect.left); + dstRect.left = scissor->x; + } + if (dstRect.top < scissor->y) + { + srcRect.top += (scissor->y - dstRect.top); + dstRect.top = scissor->y; + } + if (dstRect.right > scissor->x + scissor->width) + { + srcRect.right -= (dstRect.right - (scissor->x + scissor->width)); + dstRect.right = scissor->x + scissor->width; + } + if (dstRect.bottom > scissor->y + scissor->height) + { + srcRect.bottom -= (dstRect.bottom - (scissor->y + scissor->height)); + dstRect.bottom = scissor->y + scissor->height; + } + } + + // Clip the rectangles to the destination size + if (dstRect.left < 0) + { + srcRect.left += -dstRect.left; + dstRect.left = 0; + } + if (dstRect.right > dstSize.width) + { + srcRect.right -= (dstRect.right - dstSize.width); + dstRect.right = dstSize.width; + } + if (dstRect.top < 0) + { + srcRect.top += -dstRect.top; + dstRect.top = 0; + } + if (dstRect.bottom > dstSize.height) + { + srcRect.bottom -= (dstRect.bottom - dstSize.height); + dstRect.bottom = dstSize.height; + } + + // Clip the rectangles to the source size + if (srcRect.left < 0) + { + dstRect.left += -srcRect.left; + srcRect.left = 0; + } + if (srcRect.right > srcSize.width) + { + dstRect.right -= (srcRect.right - srcSize.width); + srcRect.right = srcSize.width; + } + if (srcRect.top < 0) + { + dstRect.top += -srcRect.top; + srcRect.top = 0; + } + if (srcRect.bottom > srcSize.height) + { + dstRect.bottom -= (srcRect.bottom - srcSize.height); + srcRect.bottom = srcSize.height; + } + + HRESULT result = + device->StretchRect(readSurface, &srcRect, drawSurface, &dstRect, D3DTEXF_NONE); + + SafeRelease(readSurface); + SafeRelease(drawSurface); + + ANGLE_TRY_HR(context9, result, "Internal blit failed."); + } + + if (blitDepth || blitStencil) + { + const gl::FramebufferAttachment *readBuffer = + sourceFramebuffer->getDepthOrStencilAttachment(); + ASSERT(readBuffer); + + RenderTarget9 *readDepthStencil = nullptr; + ANGLE_TRY(readBuffer->getRenderTarget(context, 0, &readDepthStencil)); + ASSERT(readDepthStencil); + + const gl::FramebufferAttachment *drawBuffer = mState.getDepthOrStencilAttachment(); + ASSERT(drawBuffer); + + RenderTarget9 *drawDepthStencil = nullptr; + ANGLE_TRY( + drawBuffer->getRenderTarget(context, drawBuffer->getSamples(), &drawDepthStencil)); + ASSERT(drawDepthStencil); + + // The getSurface calls do an AddRef so save them until after no errors are possible + IDirect3DSurface9 *readSurface = readDepthStencil->getSurface(); + ASSERT(readDepthStencil); + + IDirect3DSurface9 *drawSurface = drawDepthStencil->getSurface(); + ASSERT(drawDepthStencil); + + HRESULT result = + device->StretchRect(readSurface, nullptr, drawSurface, nullptr, D3DTEXF_NONE); + + SafeRelease(readSurface); + SafeRelease(drawSurface); + + ANGLE_TRY_HR(context9, result, "Internal blit failed."); + } + + return angle::Result::Continue; +} + +const gl::InternalFormat &Framebuffer9::getImplementationColorReadFormat( + const gl::Context *context) const +{ + GLenum sizedFormat = mState.getReadAttachment()->getFormat().info->sizedInternalFormat; + const d3d9::TextureFormat &textureFormat = d3d9::GetTextureFormatInfo(sizedFormat); + const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(textureFormat.renderFormat); + const angle::Format &angleFormat = angle::Format::Get(d3dFormatInfo.formatID); + return gl::GetSizedInternalFormatInfo(angleFormat.fboImplementationInternalFormat); +} + +angle::Result Framebuffer9::getSamplePosition(const gl::Context *context, + size_t index, + GLfloat *xy) const +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result Framebuffer9::syncState(const gl::Context *context, + GLenum binding, + const gl::Framebuffer::DirtyBits &dirtyBits, + gl::Command command) +{ + ANGLE_TRY(FramebufferD3D::syncState(context, binding, dirtyBits, command)); + ANGLE_TRY(mRenderTargetCache.update(context, mState, dirtyBits)); + return angle::Result::Continue; +} +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h new file mode 100644 index 0000000000..a44118ff34 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h @@ -0,0 +1,89 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Framebuffer9.h: Defines the Framebuffer9 class. + +#ifndef LIBANGLE_RENDERER_D3D_D3D9_FRAMBUFFER9_H_ +#define LIBANGLE_RENDERER_D3D_D3D9_FRAMBUFFER9_H_ + +#include "libANGLE/renderer/RenderTargetCache.h" +#include "libANGLE/renderer/d3d/FramebufferD3D.h" +#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" + +namespace rx +{ +class Renderer9; + +class Framebuffer9 : public FramebufferD3D +{ + public: + Framebuffer9(const gl::FramebufferState &data, Renderer9 *renderer); + ~Framebuffer9() override; + + angle::Result discard(const gl::Context *context, + size_t count, + const GLenum *attachments) override; + angle::Result invalidate(const gl::Context *context, + size_t count, + const GLenum *attachments) override; + angle::Result invalidateSub(const gl::Context *context, + size_t count, + const GLenum *attachments, + const gl::Rectangle &area) override; + + angle::Result getSamplePosition(const gl::Context *context, + size_t index, + GLfloat *xy) const override; + + angle::Result syncState(const gl::Context *context, + GLenum binding, + const gl::Framebuffer::DirtyBits &dirtyBits, + gl::Command command) override; + + const gl::AttachmentArray &getCachedColorRenderTargets() const + { + return mRenderTargetCache.getColors(); + } + + const RenderTarget9 *getCachedDepthStencilRenderTarget() const + { + return mRenderTargetCache.getDepthStencil(); + } + + const gl::InternalFormat &getImplementationColorReadFormat( + const gl::Context *context) const override; + + private: + angle::Result clearImpl(const gl::Context *context, + const ClearParameters &clearParams) override; + + angle::Result readPixelsImpl(const gl::Context *context, + const gl::Rectangle &area, + GLenum format, + GLenum type, + size_t outputPitch, + const gl::PixelPackState &pack, + gl::Buffer *packPixels, + uint8_t *pixels) override; + + angle::Result blitImpl(const gl::Context *context, + const gl::Rectangle &sourceArea, + const gl::Rectangle &destArea, + const gl::Rectangle *scissor, + bool blitRenderTarget, + bool blitDepth, + bool blitStencil, + GLenum filter, + const gl::Framebuffer *sourceFramebuffer) override; + + Renderer9 *const mRenderer; + + RenderTargetCache mRenderTargetCache; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D9_FRAMBUFFER9_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Image9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Image9.cpp new file mode 100644 index 0000000000..229d54ced9 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Image9.cpp @@ -0,0 +1,907 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Image9.cpp: Implements the rx::Image9 class, which acts as the interface to +// the actual underlying surfaces of a Texture. + +#include "libANGLE/renderer/d3d/d3d9/Image9.h" + +#include "common/utilities.h" +#include "libANGLE/Context.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/Renderbuffer.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/copyvertex.h" +#include "libANGLE/renderer/d3d/d3d9/Context9.h" +#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h" +#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" +#include "libANGLE/renderer/d3d/d3d9/TextureStorage9.h" +#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" +#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" + +namespace rx +{ + +Image9::Image9(Renderer9 *renderer) +{ + mSurface = nullptr; + mRenderer = nullptr; + + mD3DPool = D3DPOOL_SYSTEMMEM; + mD3DFormat = D3DFMT_UNKNOWN; + + mRenderer = renderer; +} + +Image9::~Image9() +{ + SafeRelease(mSurface); +} + +// static +angle::Result Image9::GenerateMip(Context9 *context9, + IDirect3DSurface9 *destSurface, + IDirect3DSurface9 *sourceSurface) +{ + D3DSURFACE_DESC destDesc; + HRESULT result = destSurface->GetDesc(&destDesc); + ASSERT(SUCCEEDED(result)); + ANGLE_TRY_HR(context9, result, + "Failed to query the source surface description for mipmap generation"); + + D3DSURFACE_DESC sourceDesc; + result = sourceSurface->GetDesc(&sourceDesc); + ASSERT(SUCCEEDED(result)); + ANGLE_TRY_HR(context9, result, + "Failed to query the destination surface description for mipmap generation"); + + ASSERT(sourceDesc.Format == destDesc.Format); + ASSERT(sourceDesc.Width == 1 || sourceDesc.Width / 2 == destDesc.Width); + ASSERT(sourceDesc.Height == 1 || sourceDesc.Height / 2 == destDesc.Height); + + const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(sourceDesc.Format); + ASSERT(d3dFormatInfo.info().mipGenerationFunction != nullptr); + + D3DLOCKED_RECT sourceLocked = {}; + result = sourceSurface->LockRect(&sourceLocked, nullptr, D3DLOCK_READONLY); + ASSERT(SUCCEEDED(result)); + ANGLE_TRY_HR(context9, result, "Failed to lock the source surface for mipmap generation"); + + D3DLOCKED_RECT destLocked = {}; + result = destSurface->LockRect(&destLocked, nullptr, 0); + ASSERT(SUCCEEDED(result)); + ANGLE_TRY_HR(context9, result, "Failed to lock the destination surface for mipmap generation"); + + const uint8_t *sourceData = static_cast(sourceLocked.pBits); + uint8_t *destData = static_cast(destLocked.pBits); + + ASSERT(sourceData && destData); + + d3dFormatInfo.info().mipGenerationFunction(sourceDesc.Width, sourceDesc.Height, 1, sourceData, + sourceLocked.Pitch, 0, destData, destLocked.Pitch, + 0); + + destSurface->UnlockRect(); + sourceSurface->UnlockRect(); + + return angle::Result::Continue; +} + +// static +angle::Result Image9::GenerateMipmap(Context9 *context9, Image9 *dest, Image9 *source) +{ + IDirect3DSurface9 *sourceSurface = nullptr; + ANGLE_TRY(source->getSurface(context9, &sourceSurface)); + + IDirect3DSurface9 *destSurface = nullptr; + ANGLE_TRY(dest->getSurface(context9, &destSurface)); + + ANGLE_TRY(GenerateMip(context9, destSurface, sourceSurface)); + + dest->markDirty(); + + return angle::Result::Continue; +} + +// static +angle::Result Image9::CopyLockableSurfaces(Context9 *context9, + IDirect3DSurface9 *dest, + IDirect3DSurface9 *source) +{ + D3DLOCKED_RECT sourceLock = {}; + D3DLOCKED_RECT destLock = {}; + + HRESULT result; + + result = source->LockRect(&sourceLock, nullptr, 0); + ANGLE_TRY_HR(context9, result, "Failed to lock source surface for copy"); + + result = dest->LockRect(&destLock, nullptr, 0); + if (FAILED(result)) + { + source->UnlockRect(); + } + ANGLE_TRY_HR(context9, result, "Failed to lock destination surface for copy"); + + ASSERT(sourceLock.pBits && destLock.pBits); + + D3DSURFACE_DESC desc; + source->GetDesc(&desc); + + const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format); + unsigned int rows = desc.Height / d3dFormatInfo.blockHeight; + + unsigned int bytes = d3d9::ComputeBlockSize(desc.Format, desc.Width, d3dFormatInfo.blockHeight); + ASSERT(bytes <= static_cast(sourceLock.Pitch) && + bytes <= static_cast(destLock.Pitch)); + + for (unsigned int i = 0; i < rows; i++) + { + memcpy((char *)destLock.pBits + destLock.Pitch * i, + (char *)sourceLock.pBits + sourceLock.Pitch * i, bytes); + } + + source->UnlockRect(); + dest->UnlockRect(); + + return angle::Result::Continue; +} + +// static +angle::Result Image9::CopyImage(const gl::Context *context, + Image9 *dest, + Image9 *source, + const gl::Rectangle &sourceRect, + const gl::Offset &destOffset, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) +{ + Context9 *context9 = GetImplAs(context); + + IDirect3DSurface9 *sourceSurface = nullptr; + ANGLE_TRY(source->getSurface(context9, &sourceSurface)); + + IDirect3DSurface9 *destSurface = nullptr; + ANGLE_TRY(dest->getSurface(context9, &destSurface)); + + D3DSURFACE_DESC destDesc; + HRESULT result = destSurface->GetDesc(&destDesc); + ASSERT(SUCCEEDED(result)); + ANGLE_TRY_HR(context9, result, "Failed to query the source surface description for CopyImage"); + const d3d9::D3DFormat &destD3DFormatInfo = d3d9::GetD3DFormatInfo(destDesc.Format); + + D3DSURFACE_DESC sourceDesc; + result = sourceSurface->GetDesc(&sourceDesc); + ASSERT(SUCCEEDED(result)); + ANGLE_TRY_HR(context9, result, + "Failed to query the destination surface description for CopyImage"); + const d3d9::D3DFormat &sourceD3DFormatInfo = d3d9::GetD3DFormatInfo(sourceDesc.Format); + + D3DLOCKED_RECT sourceLocked = {}; + result = sourceSurface->LockRect(&sourceLocked, nullptr, D3DLOCK_READONLY); + ASSERT(SUCCEEDED(result)); + ANGLE_TRY_HR(context9, result, "Failed to lock the source surface for CopyImage"); + + D3DLOCKED_RECT destLocked = {}; + result = destSurface->LockRect(&destLocked, nullptr, 0); + ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + sourceSurface->UnlockRect(); + } + ANGLE_TRY_HR(context9, result, "Failed to lock the destination surface for CopyImage"); + + const uint8_t *sourceData = static_cast(sourceLocked.pBits) + + sourceRect.x * sourceD3DFormatInfo.pixelBytes + + sourceRect.y * sourceLocked.Pitch; + uint8_t *destData = static_cast(destLocked.pBits) + + destOffset.x * destD3DFormatInfo.pixelBytes + + destOffset.y * destLocked.Pitch; + ASSERT(sourceData && destData); + + CopyImageCHROMIUM(sourceData, sourceLocked.Pitch, sourceD3DFormatInfo.pixelBytes, 0, + sourceD3DFormatInfo.info().pixelReadFunction, destData, destLocked.Pitch, + destD3DFormatInfo.pixelBytes, 0, destD3DFormatInfo.info().pixelWriteFunction, + gl::GetUnsizedFormat(dest->getInternalFormat()), + destD3DFormatInfo.info().componentType, sourceRect.width, sourceRect.height, + 1, unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha); + + dest->markDirty(); + + destSurface->UnlockRect(); + sourceSurface->UnlockRect(); + + return angle::Result::Continue; +} + +bool Image9::redefine(gl::TextureType type, + GLenum internalformat, + const gl::Extents &size, + bool forceRelease) +{ + // 3D textures are not supported by the D3D9 backend. + ASSERT(size.depth <= 1); + + // Only 2D and cube texture are supported by the D3D9 backend. + ASSERT(type == gl::TextureType::_2D || type == gl::TextureType::CubeMap); + + if (mWidth != size.width || mHeight != size.height || mDepth != size.depth || + mInternalFormat != internalformat || forceRelease) + { + mWidth = size.width; + mHeight = size.height; + mDepth = size.depth; + mType = type; + mInternalFormat = internalformat; + + // compute the d3d format that will be used + const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(internalformat); + mD3DFormat = d3d9FormatInfo.texFormat; + mRenderable = (d3d9FormatInfo.renderFormat != D3DFMT_UNKNOWN); + + SafeRelease(mSurface); + mDirty = (d3d9FormatInfo.dataInitializerFunction != nullptr); + + return true; + } + + return false; +} + +angle::Result Image9::createSurface(Context9 *context9) +{ + if (mSurface) + { + return angle::Result::Continue; + } + + IDirect3DTexture9 *newTexture = nullptr; + IDirect3DSurface9 *newSurface = nullptr; + const D3DPOOL poolToUse = D3DPOOL_SYSTEMMEM; + const D3DFORMAT d3dFormat = getD3DFormat(); + + if (mWidth != 0 && mHeight != 0) + { + int levelToFetch = 0; + GLsizei requestWidth = mWidth; + GLsizei requestHeight = mHeight; + d3d9::MakeValidSize(true, d3dFormat, &requestWidth, &requestHeight, &levelToFetch); + + IDirect3DDevice9 *device = mRenderer->getDevice(); + + HRESULT result = device->CreateTexture(requestWidth, requestHeight, levelToFetch + 1, 0, + d3dFormat, poolToUse, &newTexture, nullptr); + + ANGLE_TRY_HR(context9, result, "Failed to create image surface"); + + newTexture->GetSurfaceLevel(levelToFetch, &newSurface); + SafeRelease(newTexture); + + const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat); + if (d3dFormatInfo.dataInitializerFunction != nullptr) + { + RECT entireRect; + entireRect.left = 0; + entireRect.right = mWidth; + entireRect.top = 0; + entireRect.bottom = mHeight; + + D3DLOCKED_RECT lockedRect; + result = newSurface->LockRect(&lockedRect, &entireRect, 0); + ASSERT(SUCCEEDED(result)); + ANGLE_TRY_HR(context9, result, "Failed to lock image surface"); + + d3dFormatInfo.dataInitializerFunction( + mWidth, mHeight, 1, static_cast(lockedRect.pBits), lockedRect.Pitch, 0); + + result = newSurface->UnlockRect(); + ASSERT(SUCCEEDED(result)); + ANGLE_TRY_HR(context9, result, "Failed to unlock image surface"); + } + } + + mSurface = newSurface; + mDirty = false; + mD3DPool = poolToUse; + + return angle::Result::Continue; +} + +angle::Result Image9::lock(Context9 *context9, D3DLOCKED_RECT *lockedRect, const RECT &rect) +{ + ANGLE_TRY(createSurface(context9)); + + if (mSurface) + { + HRESULT result = mSurface->LockRect(lockedRect, &rect, 0); + ASSERT(SUCCEEDED(result)); + ANGLE_TRY_HR(context9, result, "Failed to lock image surface"); + mDirty = true; + } + + return angle::Result::Continue; +} + +void Image9::unlock() +{ + if (mSurface) + { + HRESULT result = mSurface->UnlockRect(); + ASSERT(SUCCEEDED(result)); + } +} + +D3DFORMAT Image9::getD3DFormat() const +{ + // this should only happen if the image hasn't been redefined first + // which would be a bug by the caller + ASSERT(mD3DFormat != D3DFMT_UNKNOWN); + + return mD3DFormat; +} + +bool Image9::isDirty() const +{ + // Make sure to that this image is marked as dirty even if the staging texture hasn't been + // created yet if initialization is required before use. + return (mSurface || + d3d9::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != nullptr) && + mDirty; +} + +angle::Result Image9::getSurface(Context9 *context9, IDirect3DSurface9 **outSurface) +{ + ANGLE_TRY(createSurface(context9)); + *outSurface = mSurface; + return angle::Result::Continue; +} + +angle::Result Image9::setManagedSurface2D(const gl::Context *context, + TextureStorage *storage, + int level) +{ + IDirect3DSurface9 *surface = nullptr; + TextureStorage9 *storage9 = GetAs(storage); + ANGLE_TRY(storage9->getSurfaceLevel(context, gl::TextureTarget::_2D, level, false, &surface)); + return setManagedSurface(GetImplAs(context), surface); +} + +angle::Result Image9::setManagedSurfaceCube(const gl::Context *context, + TextureStorage *storage, + int face, + int level) +{ + IDirect3DSurface9 *surface = nullptr; + TextureStorage9 *storage9 = GetAs(storage); + ANGLE_TRY(storage9->getSurfaceLevel(context, gl::CubeFaceIndexToTextureTarget(face), level, + false, &surface)); + return setManagedSurface(GetImplAs(context), surface); +} + +angle::Result Image9::setManagedSurface(Context9 *context9, IDirect3DSurface9 *surface) +{ + D3DSURFACE_DESC desc; + surface->GetDesc(&desc); + ASSERT(desc.Pool == D3DPOOL_MANAGED); + + if ((GLsizei)desc.Width == mWidth && (GLsizei)desc.Height == mHeight) + { + if (mSurface) + { + angle::Result result = CopyLockableSurfaces(context9, surface, mSurface); + SafeRelease(mSurface); + ANGLE_TRY(result); + } + + mSurface = surface; + mD3DPool = desc.Pool; + } + + return angle::Result::Continue; +} + +angle::Result Image9::copyToStorage(const gl::Context *context, + TextureStorage *storage, + const gl::ImageIndex &index, + const gl::Box ®ion) +{ + ANGLE_TRY(createSurface(GetImplAs(context))); + + TextureStorage9 *storage9 = GetAs(storage); + IDirect3DSurface9 *destSurface = nullptr; + ANGLE_TRY(storage9->getSurfaceLevel(context, index.getTarget(), index.getLevelIndex(), true, + &destSurface)); + + angle::Result result = copyToSurface(GetImplAs(context), destSurface, region); + SafeRelease(destSurface); + return result; +} + +angle::Result Image9::copyToSurface(Context9 *context9, + IDirect3DSurface9 *destSurface, + const gl::Box &area) +{ + ASSERT(area.width > 0 && area.height > 0 && area.depth == 1); + ASSERT(destSurface); + + IDirect3DSurface9 *sourceSurface = nullptr; + ANGLE_TRY(getSurface(context9, &sourceSurface)); + + ASSERT(sourceSurface && sourceSurface != destSurface); + + RECT rect; + rect.left = area.x; + rect.top = area.y; + rect.right = area.x + area.width; + rect.bottom = area.y + area.height; + + POINT point = {rect.left, rect.top}; + + IDirect3DDevice9 *device = mRenderer->getDevice(); + + if (mD3DPool == D3DPOOL_MANAGED) + { + D3DSURFACE_DESC desc; + sourceSurface->GetDesc(&desc); + + IDirect3DSurface9 *surf = 0; + HRESULT result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, + D3DPOOL_SYSTEMMEM, &surf, nullptr); + ANGLE_TRY_HR(context9, result, "Internal CreateOffscreenPlainSurface call failed"); + + auto err = CopyLockableSurfaces(context9, surf, sourceSurface); + result = device->UpdateSurface(surf, &rect, destSurface, &point); + SafeRelease(surf); + ANGLE_TRY(err); + ASSERT(SUCCEEDED(result)); + ANGLE_TRY_HR(context9, result, "Internal UpdateSurface call failed"); + } + else + { + // UpdateSurface: source must be SYSTEMMEM, dest must be DEFAULT pools + HRESULT result = device->UpdateSurface(sourceSurface, &rect, destSurface, &point); + ASSERT(SUCCEEDED(result)); + ANGLE_TRY_HR(context9, result, "Internal UpdateSurface call failed"); + } + + return angle::Result::Continue; +} + +// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as +// format/type at input into the target pixel rectangle. +angle::Result Image9::loadData(const gl::Context *context, + const gl::Box &area, + const gl::PixelUnpackState &unpack, + GLenum type, + const void *input, + bool applySkipImages) +{ + // 3D textures are not supported by the D3D9 backend. + ASSERT(area.z == 0 && area.depth == 1); + + Context9 *context9 = GetImplAs(context); + + const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(mInternalFormat); + GLuint inputRowPitch = 0; + ANGLE_CHECK_GL_MATH(context9, formatInfo.computeRowPitch(type, area.width, unpack.alignment, + unpack.rowLength, &inputRowPitch)); + ASSERT(!applySkipImages); + ASSERT(unpack.skipPixels == 0); + ASSERT(unpack.skipRows == 0); + + const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat); + ASSERT(d3dFormatInfo.loadFunction != nullptr); + + RECT lockRect = {area.x, area.y, area.x + area.width, area.y + area.height}; + + D3DLOCKED_RECT locked; + ANGLE_TRY(lock(GetImplAs(context), &locked, lockRect)); + + d3dFormatInfo.loadFunction(area.width, area.height, area.depth, + static_cast(input), inputRowPitch, 0, + static_cast(locked.pBits), locked.Pitch, 0); + + unlock(); + + return angle::Result::Continue; +} + +angle::Result Image9::loadCompressedData(const gl::Context *context, + const gl::Box &area, + const void *input) +{ + // 3D textures are not supported by the D3D9 backend. + ASSERT(area.z == 0 && area.depth == 1); + + Context9 *context9 = GetImplAs(context); + + const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(mInternalFormat); + GLuint inputRowPitch = 0; + ANGLE_CHECK_GL_MATH( + context9, formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, area.width, 1, 0, &inputRowPitch)); + + GLuint inputDepthPitch = 0; + ANGLE_CHECK_GL_MATH( + context9, formatInfo.computeDepthPitch(area.height, 0, inputRowPitch, &inputDepthPitch)); + + const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat); + + ASSERT(area.x % d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat).blockWidth == 0); + ASSERT(area.y % d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat).blockHeight == 0); + + ASSERT(d3d9FormatInfo.loadFunction != nullptr); + + RECT lockRect = {area.x, area.y, area.x + area.width, area.y + area.height}; + + D3DLOCKED_RECT locked; + ANGLE_TRY(lock(GetImplAs(context), &locked, lockRect)); + + d3d9FormatInfo.loadFunction(area.width, area.height, area.depth, + static_cast(input), inputRowPitch, inputDepthPitch, + static_cast(locked.pBits), locked.Pitch, 0); + + unlock(); + + return angle::Result::Continue; +} + +// This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats and incomplete +// textures +angle::Result Image9::copyFromRTInternal(Context9 *context9, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + RenderTargetD3D *source) +{ + ASSERT(source); + + // ES3.0 only behaviour to copy into a 3d texture + ASSERT(destOffset.z == 0); + + RenderTarget9 *renderTarget = GetAs(source); + + angle::ComPtr surface = renderTarget->getSurface(); + ASSERT(surface); + + IDirect3DDevice9 *device = mRenderer->getDevice(); + + angle::ComPtr renderTargetData = nullptr; + D3DSURFACE_DESC description; + surface->GetDesc(&description); + + HRESULT hr = device->CreateOffscreenPlainSurface(description.Width, description.Height, + description.Format, D3DPOOL_SYSTEMMEM, + &renderTargetData, nullptr); + + ANGLE_TRY_HR(context9, hr, "Could not create matching destination surface"); + + hr = device->GetRenderTargetData(surface.Get(), renderTargetData.Get()); + + ANGLE_TRY_HR(context9, hr, "GetRenderTargetData unexpectedly failed"); + + int width = sourceArea.width; + int height = sourceArea.height; + + RECT sourceRect = {sourceArea.x, sourceArea.y, sourceArea.x + width, sourceArea.y + height}; + RECT destRect = {destOffset.x, destOffset.y, destOffset.x + width, destOffset.y + height}; + + D3DLOCKED_RECT sourceLock = {}; + hr = renderTargetData->LockRect(&sourceLock, &sourceRect, 0); + + ANGLE_TRY_HR(context9, hr, "Failed to lock the source surface (rectangle might be invalid)"); + + D3DLOCKED_RECT destLock = {}; + angle::Result result = lock(context9, &destLock, destRect); + if (result == angle::Result::Stop) + { + renderTargetData->UnlockRect(); + } + ANGLE_TRY(result); + + ASSERT(destLock.pBits && sourceLock.pBits); + + unsigned char *sourcePixels = (unsigned char *)sourceLock.pBits; + unsigned char *destPixels = (unsigned char *)destLock.pBits; + + switch (description.Format) + { + case D3DFMT_X8R8G8B8: + case D3DFMT_A8R8G8B8: + switch (getD3DFormat()) + { + case D3DFMT_X8R8G8B8: + case D3DFMT_A8R8G8B8: + for (int y = 0; y < height; y++) + { + memcpy(destPixels, sourcePixels, 4 * width); + sourcePixels += sourceLock.Pitch; + destPixels += destLock.Pitch; + } + break; + case D3DFMT_L8: + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + destPixels[x] = sourcePixels[x * 4 + 2]; + } + sourcePixels += sourceLock.Pitch; + destPixels += destLock.Pitch; + } + break; + case D3DFMT_A8L8: + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + destPixels[x * 2 + 0] = sourcePixels[x * 4 + 2]; + destPixels[x * 2 + 1] = sourcePixels[x * 4 + 3]; + } + sourcePixels += sourceLock.Pitch; + destPixels += destLock.Pitch; + } + break; + default: + UNREACHABLE(); + } + break; + case D3DFMT_R5G6B5: + switch (getD3DFormat()) + { + case D3DFMT_X8R8G8B8: + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + unsigned short rgb = ((unsigned short *)sourcePixels)[x]; + unsigned char red = static_cast((rgb & 0xF800) >> 8); + unsigned char green = static_cast((rgb & 0x07E0) >> 3); + unsigned char blue = static_cast((rgb & 0x001F) << 3); + destPixels[x + 0] = blue | (blue >> 5); + destPixels[x + 1] = green | (green >> 6); + destPixels[x + 2] = red | (red >> 5); + destPixels[x + 3] = 0xFF; + } + sourcePixels += sourceLock.Pitch; + destPixels += destLock.Pitch; + } + break; + case D3DFMT_L8: + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + unsigned char red = sourcePixels[x * 2 + 1] & 0xF8; + destPixels[x] = red | (red >> 5); + } + sourcePixels += sourceLock.Pitch; + destPixels += destLock.Pitch; + } + break; + default: + UNREACHABLE(); + } + break; + case D3DFMT_A1R5G5B5: + switch (getD3DFormat()) + { + case D3DFMT_X8R8G8B8: + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + unsigned short argb = ((unsigned short *)sourcePixels)[x]; + unsigned char red = static_cast((argb & 0x7C00) >> 7); + unsigned char green = static_cast((argb & 0x03E0) >> 2); + unsigned char blue = static_cast((argb & 0x001F) << 3); + destPixels[x + 0] = blue | (blue >> 5); + destPixels[x + 1] = green | (green >> 5); + destPixels[x + 2] = red | (red >> 5); + destPixels[x + 3] = 0xFF; + } + sourcePixels += sourceLock.Pitch; + destPixels += destLock.Pitch; + } + break; + case D3DFMT_A8R8G8B8: + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + unsigned short argb = ((unsigned short *)sourcePixels)[x]; + unsigned char red = static_cast((argb & 0x7C00) >> 7); + unsigned char green = static_cast((argb & 0x03E0) >> 2); + unsigned char blue = static_cast((argb & 0x001F) << 3); + unsigned char alpha = (signed short)argb >> 15; + destPixels[x + 0] = blue | (blue >> 5); + destPixels[x + 1] = green | (green >> 5); + destPixels[x + 2] = red | (red >> 5); + destPixels[x + 3] = alpha; + } + sourcePixels += sourceLock.Pitch; + destPixels += destLock.Pitch; + } + break; + case D3DFMT_L8: + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + unsigned char red = sourcePixels[x * 2 + 1] & 0x7C; + destPixels[x] = (red << 1) | (red >> 4); + } + sourcePixels += sourceLock.Pitch; + destPixels += destLock.Pitch; + } + break; + case D3DFMT_A8L8: + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + unsigned char red = sourcePixels[x * 2 + 1] & 0x7C; + destPixels[x * 2 + 0] = (red << 1) | (red >> 4); + destPixels[x * 2 + 1] = (signed char)sourcePixels[x * 2 + 1] >> 7; + } + sourcePixels += sourceLock.Pitch; + destPixels += destLock.Pitch; + } + break; + default: + UNREACHABLE(); + } + break; + case D3DFMT_A16B16G16R16F: + switch (getD3DFormat()) + { + case D3DFMT_X8R8G8B8: + case D3DFMT_A8R8G8B8: + for (int y = 0; y < height; y++) + { + const uint16_t *sourcePixels16F = + reinterpret_cast(sourcePixels); + for (int x = 0; x < width; x++) + { + float r = gl::float16ToFloat32(sourcePixels16F[x * 4 + 0]); + float g = gl::float16ToFloat32(sourcePixels16F[x * 4 + 1]); + float b = gl::float16ToFloat32(sourcePixels16F[x * 4 + 2]); + float a = gl::float16ToFloat32(sourcePixels16F[x * 4 + 3]); + destPixels[x * 4 + 0] = gl::floatToNormalized(b); + destPixels[x * 4 + 1] = gl::floatToNormalized(g); + destPixels[x * 4 + 2] = gl::floatToNormalized(r); + destPixels[x * 4 + 3] = gl::floatToNormalized(a); + } + sourcePixels += sourceLock.Pitch; + destPixels += destLock.Pitch; + } + break; + case D3DFMT_L8: + for (int y = 0; y < height; y++) + { + const uint16_t *sourcePixels16F = + reinterpret_cast(sourcePixels); + for (int x = 0; x < width; x++) + { + float r = gl::float16ToFloat32(sourcePixels16F[x * 4]); + destPixels[x] = gl::floatToNormalized(r); + } + sourcePixels += sourceLock.Pitch; + destPixels += destLock.Pitch; + } + break; + case D3DFMT_A8L8: + for (int y = 0; y < height; y++) + { + const uint16_t *sourcePixels16F = + reinterpret_cast(sourcePixels); + for (int x = 0; x < width; x++) + { + float r = gl::float16ToFloat32(sourcePixels16F[x * 4 + 0]); + float a = gl::float16ToFloat32(sourcePixels16F[x * 4 + 3]); + destPixels[x * 2 + 0] = gl::floatToNormalized(r); + destPixels[x * 2 + 1] = gl::floatToNormalized(a); + } + sourcePixels += sourceLock.Pitch; + destPixels += destLock.Pitch; + } + break; + default: + UNREACHABLE(); + } + break; + case D3DFMT_A32B32G32R32F: + switch (getD3DFormat()) + { + case D3DFMT_X8R8G8B8: + case D3DFMT_A8R8G8B8: + for (int y = 0; y < height; y++) + { + const float *sourcePixels32F = reinterpret_cast(sourcePixels); + for (int x = 0; x < width; x++) + { + float r = sourcePixels32F[x * 4 + 0]; + float g = sourcePixels32F[x * 4 + 1]; + float b = sourcePixels32F[x * 4 + 2]; + float a = sourcePixels32F[x * 4 + 3]; + destPixels[x * 4 + 0] = gl::floatToNormalized(b); + destPixels[x * 4 + 1] = gl::floatToNormalized(g); + destPixels[x * 4 + 2] = gl::floatToNormalized(r); + destPixels[x * 4 + 3] = gl::floatToNormalized(a); + } + sourcePixels += sourceLock.Pitch; + destPixels += destLock.Pitch; + } + break; + case D3DFMT_L8: + for (int y = 0; y < height; y++) + { + const float *sourcePixels32F = reinterpret_cast(sourcePixels); + for (int x = 0; x < width; x++) + { + float r = sourcePixels32F[x * 4]; + destPixels[x] = gl::floatToNormalized(r); + } + sourcePixels += sourceLock.Pitch; + destPixels += destLock.Pitch; + } + break; + case D3DFMT_A8L8: + for (int y = 0; y < height; y++) + { + const float *sourcePixels32F = reinterpret_cast(sourcePixels); + for (int x = 0; x < width; x++) + { + float r = sourcePixels32F[x * 4 + 0]; + float a = sourcePixels32F[x * 4 + 3]; + destPixels[x * 2 + 0] = gl::floatToNormalized(r); + destPixels[x * 2 + 1] = gl::floatToNormalized(a); + } + sourcePixels += sourceLock.Pitch; + destPixels += destLock.Pitch; + } + break; + default: + UNREACHABLE(); + } + break; + default: + UNREACHABLE(); + } + + unlock(); + renderTargetData->UnlockRect(); + + mDirty = true; + return angle::Result::Continue; +} + +angle::Result Image9::copyFromTexStorage(const gl::Context *context, + const gl::ImageIndex &imageIndex, + TextureStorage *source) +{ + RenderTargetD3D *renderTarget = nullptr; + ANGLE_TRY(source->getRenderTarget(context, imageIndex, 0, &renderTarget)); + + gl::Rectangle sourceArea(0, 0, mWidth, mHeight); + return copyFromRTInternal(GetImplAs(context), gl::Offset(), sourceArea, renderTarget); +} + +angle::Result Image9::copyFromFramebuffer(const gl::Context *context, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + const gl::Framebuffer *source) +{ + const gl::FramebufferAttachment *srcAttachment = source->getReadColorAttachment(); + ASSERT(srcAttachment); + + RenderTargetD3D *renderTarget = nullptr; + ANGLE_TRY(srcAttachment->getRenderTarget(context, 0, &renderTarget)); + ASSERT(renderTarget); + return copyFromRTInternal(GetImplAs(context), destOffset, sourceArea, renderTarget); +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Image9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Image9.h new file mode 100644 index 0000000000..80064aa24b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Image9.h @@ -0,0 +1,112 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Image9.h: Defines the rx::Image9 class, which acts as the interface to +// the actual underlying surfaces of a Texture. + +#ifndef LIBANGLE_RENDERER_D3D_D3D9_IMAGE9_H_ +#define LIBANGLE_RENDERER_D3D_D3D9_IMAGE9_H_ + +#include "common/debug.h" +#include "libANGLE/renderer/d3d/ImageD3D.h" + +namespace gl +{ +class Framebuffer; +} + +namespace rx +{ +class Context9; +class Renderer9; + +class Image9 : public ImageD3D +{ + public: + Image9(Renderer9 *renderer); + ~Image9() override; + + static angle::Result GenerateMipmap(Context9 *context9, Image9 *dest, Image9 *source); + static angle::Result GenerateMip(Context9 *context9, + IDirect3DSurface9 *destSurface, + IDirect3DSurface9 *sourceSurface); + static angle::Result CopyLockableSurfaces(Context9 *context9, + IDirect3DSurface9 *dest, + IDirect3DSurface9 *source); + static angle::Result CopyImage(const gl::Context *context, + Image9 *dest, + Image9 *source, + const gl::Rectangle &sourceRect, + const gl::Offset &destOffset, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha); + + bool redefine(gl::TextureType type, + GLenum internalformat, + const gl::Extents &size, + bool forceRelease) override; + + D3DFORMAT getD3DFormat() const; + + bool isDirty() const override; + + angle::Result setManagedSurface2D(const gl::Context *context, + TextureStorage *storage, + int level) override; + angle::Result setManagedSurfaceCube(const gl::Context *context, + TextureStorage *storage, + int face, + int level) override; + angle::Result copyToStorage(const gl::Context *context, + TextureStorage *storage, + const gl::ImageIndex &index, + const gl::Box ®ion) override; + + angle::Result loadData(const gl::Context *context, + const gl::Box &area, + const gl::PixelUnpackState &unpack, + GLenum type, + const void *input, + bool applySkipImages) override; + angle::Result loadCompressedData(const gl::Context *context, + const gl::Box &area, + const void *input) override; + + angle::Result copyFromTexStorage(const gl::Context *context, + const gl::ImageIndex &imageIndex, + TextureStorage *source) override; + angle::Result copyFromFramebuffer(const gl::Context *context, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + const gl::Framebuffer *source) override; + + private: + angle::Result getSurface(Context9 *context9, IDirect3DSurface9 **outSurface); + + angle::Result createSurface(Context9 *context9); + angle::Result setManagedSurface(Context9 *context9, IDirect3DSurface9 *surface); + angle::Result copyToSurface(Context9 *context9, IDirect3DSurface9 *dest, const gl::Box &area); + + angle::Result lock(Context9 *context9, D3DLOCKED_RECT *lockedRect, const RECT &rect); + void unlock(); + + angle::Result copyFromRTInternal(Context9 *context9, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + RenderTargetD3D *source); + + Renderer9 *mRenderer; + + D3DPOOL mD3DPool; // can only be D3DPOOL_SYSTEMMEM or D3DPOOL_MANAGED since it needs to be + // lockable. + D3DFORMAT mD3DFormat; + + IDirect3DSurface9 *mSurface; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D9_IMAGE9_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp new file mode 100644 index 0000000000..26bae3bdb8 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp @@ -0,0 +1,161 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Indexffer9.cpp: Defines the D3D9 IndexBuffer implementation. + +#include "libANGLE/renderer/d3d/d3d9/IndexBuffer9.h" + +#include "libANGLE/Context.h" +#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" + +namespace rx +{ + +IndexBuffer9::IndexBuffer9(Renderer9 *const renderer) : mRenderer(renderer) +{ + mIndexBuffer = nullptr; + mBufferSize = 0; + mIndexType = gl::DrawElementsType::InvalidEnum; + mDynamic = false; +} + +IndexBuffer9::~IndexBuffer9() +{ + SafeRelease(mIndexBuffer); +} + +angle::Result IndexBuffer9::initialize(const gl::Context *context, + unsigned int bufferSize, + gl::DrawElementsType indexType, + bool dynamic) +{ + SafeRelease(mIndexBuffer); + + updateSerial(); + + if (bufferSize > 0) + { + D3DFORMAT format = D3DFMT_UNKNOWN; + if (indexType == gl::DrawElementsType::UnsignedShort || + indexType == gl::DrawElementsType::UnsignedByte) + { + format = D3DFMT_INDEX16; + } + else if (indexType == gl::DrawElementsType::UnsignedInt) + { + ASSERT(mRenderer->getNativeExtensions().elementIndexUintOES); + format = D3DFMT_INDEX32; + } + else + UNREACHABLE(); + + DWORD usageFlags = D3DUSAGE_WRITEONLY; + if (dynamic) + { + usageFlags |= D3DUSAGE_DYNAMIC; + } + + HRESULT result = + mRenderer->createIndexBuffer(bufferSize, usageFlags, format, &mIndexBuffer); + ANGLE_TRY_HR(GetImplAs(context), result, + "Failed to allocate internal index buffer"); + } + + mBufferSize = bufferSize; + mIndexType = indexType; + mDynamic = dynamic; + + return angle::Result::Continue; +} + +angle::Result IndexBuffer9::mapBuffer(const gl::Context *context, + unsigned int offset, + unsigned int size, + void **outMappedMemory) +{ + ASSERT(mIndexBuffer); + + DWORD lockFlags = mDynamic ? D3DLOCK_NOOVERWRITE : 0; + + void *mapPtr = nullptr; + HRESULT result = mIndexBuffer->Lock(offset, size, &mapPtr, lockFlags); + ANGLE_TRY_HR(GetImplAs(context), result, "Failed to lock internal index buffer"); + + *outMappedMemory = mapPtr; + return angle::Result::Continue; +} + +angle::Result IndexBuffer9::unmapBuffer(const gl::Context *context) +{ + ASSERT(mIndexBuffer); + HRESULT result = mIndexBuffer->Unlock(); + ANGLE_TRY_HR(GetImplAs(context), result, "Failed to unlock internal index buffer"); + + return angle::Result::Continue; +} + +gl::DrawElementsType IndexBuffer9::getIndexType() const +{ + return mIndexType; +} + +unsigned int IndexBuffer9::getBufferSize() const +{ + return mBufferSize; +} + +angle::Result IndexBuffer9::setSize(const gl::Context *context, + unsigned int bufferSize, + gl::DrawElementsType indexType) +{ + if (bufferSize > mBufferSize || indexType != mIndexType) + { + return initialize(context, bufferSize, indexType, mDynamic); + } + + return angle::Result::Continue; +} + +angle::Result IndexBuffer9::discard(const gl::Context *context) +{ + ASSERT(mIndexBuffer); + + void *mock; + HRESULT result; + + Context9 *context9 = GetImplAs(context); + + result = mIndexBuffer->Lock(0, 1, &mock, D3DLOCK_DISCARD); + ANGLE_TRY_HR(context9, result, "Failed to lock internal index buffer"); + + result = mIndexBuffer->Unlock(); + ANGLE_TRY_HR(context9, result, "Failed to unlock internal index buffer"); + + return angle::Result::Continue; +} + +D3DFORMAT IndexBuffer9::getIndexFormat() const +{ + switch (mIndexType) + { + case gl::DrawElementsType::UnsignedByte: + return D3DFMT_INDEX16; + case gl::DrawElementsType::UnsignedShort: + return D3DFMT_INDEX16; + case gl::DrawElementsType::UnsignedInt: + return D3DFMT_INDEX32; + default: + UNREACHABLE(); + return D3DFMT_UNKNOWN; + } +} + +IDirect3DIndexBuffer9 *IndexBuffer9::getBuffer() const +{ + return mIndexBuffer; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.h new file mode 100644 index 0000000000..9493a1ebbe --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.h @@ -0,0 +1,57 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Indexffer9.h: Defines the D3D9 IndexBuffer implementation. + +#ifndef LIBANGLE_RENDERER_D3D_D3D9_INDEXBUFFER9_H_ +#define LIBANGLE_RENDERER_D3D_D3D9_INDEXBUFFER9_H_ + +#include "libANGLE/renderer/d3d/IndexBuffer.h" + +namespace rx +{ +class Renderer9; + +class IndexBuffer9 : public IndexBuffer +{ + public: + explicit IndexBuffer9(Renderer9 *const renderer); + ~IndexBuffer9() override; + + angle::Result initialize(const gl::Context *context, + unsigned int bufferSize, + gl::DrawElementsType indexType, + bool dynamic) override; + + angle::Result mapBuffer(const gl::Context *context, + unsigned int offset, + unsigned int size, + void **outMappedMemory) override; + angle::Result unmapBuffer(const gl::Context *context) override; + + gl::DrawElementsType getIndexType() const override; + unsigned int getBufferSize() const override; + angle::Result setSize(const gl::Context *context, + unsigned int bufferSize, + gl::DrawElementsType indexType) override; + + angle::Result discard(const gl::Context *context) override; + + D3DFORMAT getIndexFormat() const; + IDirect3DIndexBuffer9 *getBuffer() const; + + private: + Renderer9 *const mRenderer; + + IDirect3DIndexBuffer9 *mIndexBuffer; + unsigned int mBufferSize; + gl::DrawElementsType mIndexType; + bool mDynamic; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D9_INDEXBUFFER9_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.cpp new file mode 100644 index 0000000000..e4834b44eb --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.cpp @@ -0,0 +1,37 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// NativeWindow9.cpp: Defines NativeWindow9, a class for managing and +// performing operations on an EGLNativeWindowType for the D3D9 renderer. + +#include "libANGLE/renderer/d3d/d3d9/NativeWindow9.h" + +namespace rx +{ +NativeWindow9::NativeWindow9(EGLNativeWindowType window) : NativeWindowD3D(window) {} + +bool NativeWindow9::initialize() +{ + return true; +} + +bool NativeWindow9::getClientRect(LPRECT rect) const +{ + return GetClientRect(getNativeWindow(), rect) == TRUE; +} + +bool NativeWindow9::isIconic() const +{ + return IsIconic(getNativeWindow()) == TRUE; +} + +// static +bool NativeWindow9::IsValidNativeWindow(EGLNativeWindowType window) +{ + return IsWindow(window) == TRUE; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.h new file mode 100644 index 0000000000..aae9e13cc0 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.h @@ -0,0 +1,35 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// NativeWindow9.h: Defines NativeWindow9, a class for managing and +// performing operations on an EGLNativeWindowType for the D3D9 renderer. + +#ifndef LIBANGLE_RENDERER_D3D_D3D9_NATIVEWINDOW9_H_ +#define LIBANGLE_RENDERER_D3D_D3D9_NATIVEWINDOW9_H_ + +#include "common/debug.h" +#include "common/platform.h" + +#include "libANGLE/renderer/d3d/NativeWindowD3D.h" + +namespace rx +{ + +class NativeWindow9 : public NativeWindowD3D +{ + public: + explicit NativeWindow9(EGLNativeWindowType window); + + bool initialize() override; + bool getClientRect(LPRECT rect) const override; + bool isIconic() const override; + + static bool IsValidNativeWindow(EGLNativeWindowType window); +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D9_NATIVEWINDOW9_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Query9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Query9.cpp new file mode 100644 index 0000000000..aeefd6a29f --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Query9.cpp @@ -0,0 +1,176 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Query9.cpp: Defines the rx::Query9 class which implements rx::QueryImpl. + +#include "libANGLE/renderer/d3d/d3d9/Query9.h" + +#include "libANGLE/Context.h" +#include "libANGLE/renderer/d3d/d3d9/Context9.h" +#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" +#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" + +#include + +namespace rx +{ +Query9::Query9(Renderer9 *renderer, gl::QueryType type) + : QueryImpl(type), + mGetDataAttemptCount(0), + mResult(GL_FALSE), + mQueryFinished(false), + mRenderer(renderer), + mQuery(nullptr) +{} + +Query9::~Query9() +{ + SafeRelease(mQuery); +} + +angle::Result Query9::begin(const gl::Context *context) +{ + Context9 *context9 = GetImplAs(context); + + D3DQUERYTYPE d3dQueryType = gl_d3d9::ConvertQueryType(getType()); + if (mQuery == nullptr) + { + HRESULT result = mRenderer->getDevice()->CreateQuery(d3dQueryType, &mQuery); + ANGLE_TRY_HR(context9, result, "Internal query creation failed"); + } + + if (d3dQueryType != D3DQUERYTYPE_EVENT) + { + HRESULT result = mQuery->Issue(D3DISSUE_BEGIN); + ASSERT(SUCCEEDED(result)); + ANGLE_TRY_HR(context9, result, "Failed to begin internal query"); + } + + return angle::Result::Continue; +} + +angle::Result Query9::end(const gl::Context *context) +{ + Context9 *context9 = GetImplAs(context); + ASSERT(mQuery); + + HRESULT result = mQuery->Issue(D3DISSUE_END); + ASSERT(SUCCEEDED(result)); + ANGLE_TRY_HR(context9, result, "Failed to end internal query"); + mQueryFinished = false; + mResult = GL_FALSE; + + return angle::Result::Continue; +} + +angle::Result Query9::queryCounter(const gl::Context *context) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); +} + +template +angle::Result Query9::getResultBase(Context9 *context9, T *params) +{ + while (!mQueryFinished) + { + ANGLE_TRY(testQuery(context9)); + + if (!mQueryFinished) + { + Sleep(0); + } + } + + ASSERT(mQueryFinished); + *params = static_cast(mResult); + return angle::Result::Continue; +} + +angle::Result Query9::getResult(const gl::Context *context, GLint *params) +{ + return getResultBase(GetImplAs(context), params); +} + +angle::Result Query9::getResult(const gl::Context *context, GLuint *params) +{ + return getResultBase(GetImplAs(context), params); +} + +angle::Result Query9::getResult(const gl::Context *context, GLint64 *params) +{ + return getResultBase(GetImplAs(context), params); +} + +angle::Result Query9::getResult(const gl::Context *context, GLuint64 *params) +{ + return getResultBase(GetImplAs(context), params); +} + +angle::Result Query9::isResultAvailable(const gl::Context *context, bool *available) +{ + ANGLE_TRY(testQuery(GetImplAs(context))); + *available = mQueryFinished; + return angle::Result::Continue; +} + +angle::Result Query9::testQuery(Context9 *context9) +{ + if (!mQueryFinished) + { + ASSERT(mQuery); + + HRESULT result = S_OK; + switch (getType()) + { + case gl::QueryType::AnySamples: + case gl::QueryType::AnySamplesConservative: + { + DWORD numPixels = 0; + result = mQuery->GetData(&numPixels, sizeof(numPixels), D3DGETDATA_FLUSH); + if (result == S_OK) + { + mQueryFinished = true; + mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE; + } + break; + } + + case gl::QueryType::CommandsCompleted: + { + BOOL completed = FALSE; + result = mQuery->GetData(&completed, sizeof(completed), D3DGETDATA_FLUSH); + if (result == S_OK) + { + mQueryFinished = true; + mResult = (completed == TRUE) ? GL_TRUE : GL_FALSE; + } + break; + } + + default: + UNREACHABLE(); + break; + } + + if (!mQueryFinished) + { + ANGLE_TRY_HR(context9, result, "Failed to test get query result"); + + mGetDataAttemptCount++; + bool checkDeviceLost = + (mGetDataAttemptCount % kPollingD3DDeviceLostCheckFrequency) == 0; + if (checkDeviceLost && mRenderer->testDeviceLost()) + { + ANGLE_TRY_HR(context9, D3DERR_DEVICELOST, + "Failed to test get query result, device is lost"); + } + } + } + + return angle::Result::Continue; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Query9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Query9.h new file mode 100644 index 0000000000..df10ded225 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Query9.h @@ -0,0 +1,50 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Query9.h: Defines the rx::Query9 class which implements rx::QueryImpl. + +#ifndef LIBANGLE_RENDERER_D3D_D3D9_QUERY9_H_ +#define LIBANGLE_RENDERER_D3D_D3D9_QUERY9_H_ + +#include "libANGLE/renderer/QueryImpl.h" + +namespace rx +{ +class Context9; +class Renderer9; + +class Query9 : public QueryImpl +{ + public: + Query9(Renderer9 *renderer, gl::QueryType type); + ~Query9() override; + + angle::Result begin(const gl::Context *context) override; + angle::Result end(const gl::Context *context) override; + angle::Result queryCounter(const gl::Context *context) override; + angle::Result getResult(const gl::Context *context, GLint *params) override; + angle::Result getResult(const gl::Context *context, GLuint *params) override; + angle::Result getResult(const gl::Context *context, GLint64 *params) override; + angle::Result getResult(const gl::Context *context, GLuint64 *params) override; + angle::Result isResultAvailable(const gl::Context *context, bool *available) override; + + private: + angle::Result testQuery(Context9 *context9); + + template + angle::Result getResultBase(Context9 *context9, T *params); + + unsigned int mGetDataAttemptCount; + GLuint64 mResult; + bool mQueryFinished; + + Renderer9 *mRenderer; + IDirect3DQuery9 *mQuery; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D9_QUERY9_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp new file mode 100644 index 0000000000..54c3291799 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp @@ -0,0 +1,160 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// RenderTarget9.cpp: Implements a D3D9-specific wrapper for IDirect3DSurface9 +// pointers retained by renderbuffers. + +#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h" +#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" +#include "libANGLE/renderer/d3d/d3d9/SwapChain9.h" +#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" +#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" + +namespace rx +{ + +// TODO: AddRef the incoming surface to take ownership instead of expecting that its ref is being +// given. +TextureRenderTarget9::TextureRenderTarget9(IDirect3DBaseTexture9 *texture, + size_t textureLevel, + IDirect3DSurface9 *surface, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLsizei samples) + : mWidth(width), + mHeight(height), + mDepth(depth), + mInternalFormat(internalFormat), + mD3DFormat(D3DFMT_UNKNOWN), + mSamples(samples), + mTexture(texture), + mTextureLevel(textureLevel), + mRenderTarget(surface) +{ + ASSERT(mDepth == 1); + + if (mRenderTarget) + { + D3DSURFACE_DESC description; + mRenderTarget->GetDesc(&description); + mD3DFormat = description.Format; + } +} + +TextureRenderTarget9::~TextureRenderTarget9() +{ + SafeRelease(mTexture); + SafeRelease(mRenderTarget); +} + +GLsizei TextureRenderTarget9::getWidth() const +{ + return mWidth; +} + +GLsizei TextureRenderTarget9::getHeight() const +{ + return mHeight; +} + +GLsizei TextureRenderTarget9::getDepth() const +{ + return mDepth; +} + +GLenum TextureRenderTarget9::getInternalFormat() const +{ + return mInternalFormat; +} + +GLsizei TextureRenderTarget9::getSamples() const +{ + return mSamples; +} + +IDirect3DBaseTexture9 *TextureRenderTarget9::getTexture() const +{ + return mTexture; +} + +size_t TextureRenderTarget9::getTextureLevel() const +{ + return mTextureLevel; +} + +IDirect3DSurface9 *TextureRenderTarget9::getSurface() const +{ + // Caller is responsible for releasing the returned surface reference. + // TODO: remove the AddRef to match RenderTarget11 + if (mRenderTarget) + { + mRenderTarget->AddRef(); + } + + return mRenderTarget; +} + +D3DFORMAT TextureRenderTarget9::getD3DFormat() const +{ + return mD3DFormat; +} + +SurfaceRenderTarget9::SurfaceRenderTarget9(SwapChain9 *swapChain, bool depth) + : mSwapChain(swapChain), mDepth(depth) +{} + +SurfaceRenderTarget9::~SurfaceRenderTarget9() {} + +GLsizei SurfaceRenderTarget9::getWidth() const +{ + return mSwapChain->getWidth(); +} + +GLsizei SurfaceRenderTarget9::getHeight() const +{ + return mSwapChain->getHeight(); +} + +GLsizei SurfaceRenderTarget9::getDepth() const +{ + return 1; +} + +GLenum SurfaceRenderTarget9::getInternalFormat() const +{ + return (mDepth ? mSwapChain->getDepthBufferInternalFormat() + : mSwapChain->getRenderTargetInternalFormat()); +} + +GLsizei SurfaceRenderTarget9::getSamples() const +{ + // Our EGL surfaces do not support multisampling. + return 0; +} + +IDirect3DSurface9 *SurfaceRenderTarget9::getSurface() const +{ + return (mDepth ? mSwapChain->getDepthStencil() : mSwapChain->getRenderTarget()); +} + +IDirect3DBaseTexture9 *SurfaceRenderTarget9::getTexture() const +{ + return (mDepth ? nullptr : mSwapChain->getOffscreenTexture()); +} + +size_t SurfaceRenderTarget9::getTextureLevel() const +{ + return 0; +} + +D3DFORMAT SurfaceRenderTarget9::getD3DFormat() const +{ + return d3d9::GetTextureFormatInfo(getInternalFormat()).texFormat; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h new file mode 100644 index 0000000000..010955eb41 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h @@ -0,0 +1,98 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// RenderTarget9.h: Defines a D3D9-specific wrapper for IDirect3DSurface9 pointers +// retained by Renderbuffers. + +#ifndef LIBANGLE_RENDERER_D3D_D3D9_RENDERTARGET9_H_ +#define LIBANGLE_RENDERER_D3D_D3D9_RENDERTARGET9_H_ + +#include "libANGLE/renderer/d3d/RenderTargetD3D.h" + +namespace rx +{ +class Renderer9; +class SwapChain9; + +class RenderTarget9 : public RenderTargetD3D +{ + public: + RenderTarget9() {} + ~RenderTarget9() override {} + // Retrieve the texture that backs this render target, may be null for swap chain render + // targets. + virtual IDirect3DBaseTexture9 *getTexture() const = 0; + virtual size_t getTextureLevel() const = 0; + + virtual IDirect3DSurface9 *getSurface() const = 0; + + virtual D3DFORMAT getD3DFormat() const = 0; +}; + +class TextureRenderTarget9 : public RenderTarget9 +{ + public: + TextureRenderTarget9(IDirect3DBaseTexture9 *texture, + size_t textureLevel, + IDirect3DSurface9 *surface, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLsizei samples); + ~TextureRenderTarget9() override; + + GLsizei getWidth() const override; + GLsizei getHeight() const override; + GLsizei getDepth() const override; + GLenum getInternalFormat() const override; + GLsizei getSamples() const override; + + IDirect3DBaseTexture9 *getTexture() const override; + size_t getTextureLevel() const override; + IDirect3DSurface9 *getSurface() const override; + + D3DFORMAT getD3DFormat() const override; + + private: + GLsizei mWidth; + GLsizei mHeight; + GLsizei mDepth; + GLenum mInternalFormat; + D3DFORMAT mD3DFormat; + GLsizei mSamples; + + IDirect3DBaseTexture9 *mTexture; + size_t mTextureLevel; + IDirect3DSurface9 *mRenderTarget; +}; + +class SurfaceRenderTarget9 : public RenderTarget9 +{ + public: + SurfaceRenderTarget9(SwapChain9 *swapChain, bool depth); + ~SurfaceRenderTarget9() override; + + GLsizei getWidth() const override; + GLsizei getHeight() const override; + GLsizei getDepth() const override; + GLenum getInternalFormat() const override; + GLsizei getSamples() const override; + + IDirect3DBaseTexture9 *getTexture() const override; + size_t getTextureLevel() const override; + IDirect3DSurface9 *getSurface() const override; + + D3DFORMAT getD3DFormat() const override; + + private: + SwapChain9 *mSwapChain; + bool mDepth; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D9_RENDERTARGET9_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp new file mode 100644 index 0000000000..d80997392d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp @@ -0,0 +1,3338 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Renderer9.cpp: Implements a back-end specific class for the D3D9 renderer. + +#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" + +#include +#include + +#include "common/utilities.h" +#include "libANGLE/Buffer.h" +#include "libANGLE/Context.h" +#include "libANGLE/Display.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/Program.h" +#include "libANGLE/Renderbuffer.h" +#include "libANGLE/State.h" +#include "libANGLE/Surface.h" +#include "libANGLE/Texture.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/features.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/CompilerD3D.h" +#include "libANGLE/renderer/d3d/DeviceD3D.h" +#include "libANGLE/renderer/d3d/DisplayD3D.h" +#include "libANGLE/renderer/d3d/FramebufferD3D.h" +#include "libANGLE/renderer/d3d/IndexDataManager.h" +#include "libANGLE/renderer/d3d/ProgramD3D.h" +#include "libANGLE/renderer/d3d/RenderbufferD3D.h" +#include "libANGLE/renderer/d3d/ShaderD3D.h" +#include "libANGLE/renderer/d3d/SurfaceD3D.h" +#include "libANGLE/renderer/d3d/TextureD3D.h" +#include "libANGLE/renderer/d3d/d3d9/Blit9.h" +#include "libANGLE/renderer/d3d/d3d9/Buffer9.h" +#include "libANGLE/renderer/d3d/d3d9/Context9.h" +#include "libANGLE/renderer/d3d/d3d9/Fence9.h" +#include "libANGLE/renderer/d3d/d3d9/Framebuffer9.h" +#include "libANGLE/renderer/d3d/d3d9/Image9.h" +#include "libANGLE/renderer/d3d/d3d9/IndexBuffer9.h" +#include "libANGLE/renderer/d3d/d3d9/NativeWindow9.h" +#include "libANGLE/renderer/d3d/d3d9/Query9.h" +#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h" +#include "libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h" +#include "libANGLE/renderer/d3d/d3d9/SwapChain9.h" +#include "libANGLE/renderer/d3d/d3d9/TextureStorage9.h" +#include "libANGLE/renderer/d3d/d3d9/VertexArray9.h" +#include "libANGLE/renderer/d3d/d3d9/VertexBuffer9.h" +#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" +#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" +#include "libANGLE/renderer/d3d/driver_utils_d3d.h" +#include "libANGLE/renderer/driver_utils.h" +#include "libANGLE/trace.h" + +#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL) +# define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3 +#endif + +// Enable ANGLE_SUPPORT_SHADER_MODEL_2 if you wish devices with only shader model 2. +// Such a device would not be conformant. +#ifndef ANGLE_SUPPORT_SHADER_MODEL_2 +# define ANGLE_SUPPORT_SHADER_MODEL_2 0 +#endif + +namespace rx +{ + +namespace +{ +enum +{ + MAX_VERTEX_CONSTANT_VECTORS_D3D9 = 256, + MAX_PIXEL_CONSTANT_VECTORS_SM2 = 32, + MAX_PIXEL_CONSTANT_VECTORS_SM3 = 224, + MAX_VARYING_VECTORS_SM2 = 8, + MAX_VARYING_VECTORS_SM3 = 10, + + MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 = 4 +}; + +template +static void DrawPoints(IDirect3DDevice9 *device, GLsizei count, const void *indices, int minIndex) +{ + for (int i = 0; i < count; i++) + { + unsigned int indexValue = + static_cast(static_cast(indices)[i]) - minIndex; + device->DrawPrimitive(D3DPT_POINTLIST, indexValue, 1); + } +} + +// A hard limit on buffer size. This works around a problem in the NVIDIA drivers where buffer sizes +// close to MAX_UINT would give undefined results. The limit of MAX_UINT/2 should be generous enough +// for almost any demanding application. +constexpr UINT kMaximumBufferSizeHardLimit = std::numeric_limits::max() >> 1; +} // anonymous namespace + +Renderer9::Renderer9(egl::Display *display) : RendererD3D(display), mStateManager(this) +{ + mD3d9Module = nullptr; + + mD3d9 = nullptr; + mD3d9Ex = nullptr; + mDevice = nullptr; + mDeviceEx = nullptr; + mDeviceWindow = nullptr; + mBlit = nullptr; + + mAdapter = D3DADAPTER_DEFAULT; + + const egl::AttributeMap &attributes = display->getAttributeMap(); + EGLint requestedDeviceType = static_cast(attributes.get( + EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE)); + switch (requestedDeviceType) + { + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE: + mDeviceType = D3DDEVTYPE_HAL; + break; + + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE: + mDeviceType = D3DDEVTYPE_REF; + break; + + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE: + mDeviceType = D3DDEVTYPE_NULLREF; + break; + + default: + UNREACHABLE(); + } + + mMaskedClearSavedState = nullptr; + + mVertexDataManager = nullptr; + mIndexDataManager = nullptr; + mLineLoopIB = nullptr; + mCountingIB = nullptr; + + mMaxNullColorbufferLRU = 0; + for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++) + { + mNullRenderTargetCache[i].lruCount = 0; + mNullRenderTargetCache[i].width = 0; + mNullRenderTargetCache[i].height = 0; + mNullRenderTargetCache[i].renderTarget = nullptr; + } + + mAppliedVertexShader = nullptr; + mAppliedPixelShader = nullptr; + mAppliedProgramSerial = 0; + + gl::InitializeDebugAnnotations(&mAnnotator); +} + +void Renderer9::setGlobalDebugAnnotator() +{ + gl::InitializeDebugAnnotations(&mAnnotator); +} + +Renderer9::~Renderer9() +{ + if (mDevice) + { + // If the device is lost, reset it first to prevent leaving the driver in an unstable state + if (testDeviceLost()) + { + resetDevice(); + } + } + + release(); +} + +void Renderer9::release() +{ + gl::UninitializeDebugAnnotations(); + + mTranslatedAttribCache.clear(); + + releaseDeviceResources(); + + SafeRelease(mDevice); + SafeRelease(mDeviceEx); + SafeRelease(mD3d9); + SafeRelease(mD3d9Ex); + + mCompiler.release(); + + if (mDeviceWindow) + { + DestroyWindow(mDeviceWindow); + mDeviceWindow = nullptr; + } + + mD3d9Module = nullptr; +} + +egl::Error Renderer9::initialize() +{ + ANGLE_TRACE_EVENT0("gpu.angle", "GetModuleHandle_d3d9"); + mD3d9Module = ::LoadLibrary(TEXT("d3d9.dll")); + + if (mD3d9Module == nullptr) + { + return egl::EglNotInitialized(D3D9_INIT_MISSING_DEP) << "No D3D9 module found."; + } + + typedef HRESULT(WINAPI * Direct3DCreate9ExFunc)(UINT, IDirect3D9Ex **); + Direct3DCreate9ExFunc Direct3DCreate9ExPtr = + reinterpret_cast(GetProcAddress(mD3d9Module, "Direct3DCreate9Ex")); + + // Use Direct3D9Ex if available. Among other things, this version is less + // inclined to report a lost context, for example when the user switches + // desktop. Direct3D9Ex is available in Windows Vista and later if suitable drivers are + // available. + if (ANGLE_D3D9EX == ANGLE_ENABLED && Direct3DCreate9ExPtr && + SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex))) + { + ANGLE_TRACE_EVENT0("gpu.angle", "D3d9Ex_QueryInterface"); + ASSERT(mD3d9Ex); + mD3d9Ex->QueryInterface(__uuidof(IDirect3D9), reinterpret_cast(&mD3d9)); + ASSERT(mD3d9); + } + else + { + ANGLE_TRACE_EVENT0("gpu.angle", "Direct3DCreate9"); + mD3d9 = Direct3DCreate9(D3D_SDK_VERSION); + } + + if (!mD3d9) + { + return egl::EglNotInitialized(D3D9_INIT_MISSING_DEP) << "Could not create D3D9 device."; + } + + if (mDisplay->getNativeDisplayId() != nullptr) + { + // UNIMPLEMENTED(); // FIXME: Determine which adapter index the device context + // corresponds to + } + + HRESULT result; + + // Give up on getting device caps after about one second. + { + ANGLE_TRACE_EVENT0("gpu.angle", "GetDeviceCaps"); + for (int i = 0; i < 10; ++i) + { + result = mD3d9->GetDeviceCaps(mAdapter, mDeviceType, &mDeviceCaps); + if (SUCCEEDED(result)) + { + break; + } + else if (result == D3DERR_NOTAVAILABLE) + { + Sleep(100); // Give the driver some time to initialize/recover + } + else if (FAILED(result)) // D3DERR_OUTOFVIDEOMEMORY, E_OUTOFMEMORY, + // D3DERR_INVALIDDEVICE, or another error we can't recover + // from + { + return egl::EglNotInitialized(D3D9_INIT_OTHER_ERROR) + << "Failed to get device caps, " << gl::FmtHR(result); + } + } + } + +#if ANGLE_SUPPORT_SHADER_MODEL_2 + size_t minShaderModel = 2; +#else + size_t minShaderModel = 3; +#endif + + if (mDeviceCaps.PixelShaderVersion < D3DPS_VERSION(minShaderModel, 0)) + { + return egl::EglNotInitialized(D3D9_INIT_UNSUPPORTED_VERSION) + << "Renderer does not support PS " << minShaderModel << ".0, aborting!"; + } + + // When DirectX9 is running with an older DirectX8 driver, a StretchRect from a regular texture + // to a render target texture is not supported. This is required by + // Texture2D::ensureRenderTarget. + if ((mDeviceCaps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES) == 0) + { + return egl::EglNotInitialized(D3D9_INIT_UNSUPPORTED_STRETCHRECT) + << "Renderer does not support StretctRect from textures."; + } + + { + ANGLE_TRACE_EVENT0("gpu.angle", "GetAdapterIdentifier"); + mD3d9->GetAdapterIdentifier(mAdapter, 0, &mAdapterIdentifier); + } + + static const TCHAR windowName[] = TEXT("AngleHiddenWindow"); + static const TCHAR className[] = TEXT("STATIC"); + + { + ANGLE_TRACE_EVENT0("gpu.angle", "CreateWindowEx"); + mDeviceWindow = + CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, + 1, HWND_MESSAGE, nullptr, GetModuleHandle(nullptr), nullptr); + } + + D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters(); + DWORD behaviorFlags = + D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES | D3DCREATE_MULTITHREADED; + + { + ANGLE_TRACE_EVENT0("gpu.angle", "D3d9_CreateDevice"); + result = mD3d9->CreateDevice( + mAdapter, mDeviceType, mDeviceWindow, + behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, + &presentParameters, &mDevice); + + if (FAILED(result)) + { + ERR() << "CreateDevice1 failed: (" << gl::FmtHR(result) << ")"; + } + } + if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DEVICELOST) + { + return egl::EglBadAlloc(D3D9_INIT_OUT_OF_MEMORY) + << "CreateDevice failed: device lost or out of memory (" << gl::FmtHR(result) << ")"; + } + + if (FAILED(result)) + { + ANGLE_TRACE_EVENT0("gpu.angle", "D3d9_CreateDevice2"); + result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, + behaviorFlags | D3DCREATE_SOFTWARE_VERTEXPROCESSING, + &presentParameters, &mDevice); + + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || + result == D3DERR_NOTAVAILABLE || result == D3DERR_DEVICELOST); + return egl::EglBadAlloc(D3D9_INIT_OUT_OF_MEMORY) + << "CreateDevice2 failed: device lost, not available, or of out of memory (" + << gl::FmtHR(result) << ")"; + } + } + + if (mD3d9Ex) + { + ANGLE_TRACE_EVENT0("gpu.angle", "mDevice_QueryInterface"); + result = mDevice->QueryInterface(__uuidof(IDirect3DDevice9Ex), (void **)&mDeviceEx); + ASSERT(SUCCEEDED(result)); + } + + { + ANGLE_TRACE_EVENT0("gpu.angle", "ShaderCache initialize"); + mVertexShaderCache.initialize(mDevice); + mPixelShaderCache.initialize(mDevice); + } + + D3DDISPLAYMODE currentDisplayMode; + mD3d9->GetAdapterDisplayMode(mAdapter, ¤tDisplayMode); + + // Check vertex texture support + // Only Direct3D 10 ready devices support all the necessary vertex texture formats. + // We test this using D3D9 by checking support for the R16F format. + mVertexTextureSupport = mDeviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && + SUCCEEDED(mD3d9->CheckDeviceFormat( + mAdapter, mDeviceType, currentDisplayMode.Format, + D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, D3DFMT_R16F)); + + ANGLE_TRY(initializeDevice()); + + return egl::NoError(); +} + +// do any one-time device initialization +// NOTE: this is also needed after a device lost/reset +// to reset the scene status and ensure the default states are reset. +egl::Error Renderer9::initializeDevice() +{ + // Permanent non-default states + mDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE); + mDevice->SetRenderState(D3DRS_LASTPIXEL, FALSE); + + if (mDeviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) + { + mDevice->SetRenderState(D3DRS_POINTSIZE_MAX, (DWORD &)mDeviceCaps.MaxPointSize); + } + else + { + mDevice->SetRenderState(D3DRS_POINTSIZE_MAX, 0x3F800000); // 1.0f + } + + const gl::Caps &rendererCaps = getNativeCaps(); + + mCurVertexSamplerStates.resize(rendererCaps.maxShaderTextureImageUnits[gl::ShaderType::Vertex]); + mCurPixelSamplerStates.resize( + rendererCaps.maxShaderTextureImageUnits[gl::ShaderType::Fragment]); + + mCurVertexTextures.resize(rendererCaps.maxShaderTextureImageUnits[gl::ShaderType::Vertex]); + mCurPixelTextures.resize(rendererCaps.maxShaderTextureImageUnits[gl::ShaderType::Fragment]); + + markAllStateDirty(); + + mSceneStarted = false; + + ASSERT(!mBlit); + mBlit = new Blit9(this); + + ASSERT(!mVertexDataManager && !mIndexDataManager); + mIndexDataManager = new IndexDataManager(this); + + mTranslatedAttribCache.resize(getNativeCaps().maxVertexAttributes); + + mStateManager.initialize(); + + return egl::NoError(); +} + +D3DPRESENT_PARAMETERS Renderer9::getDefaultPresentParameters() +{ + D3DPRESENT_PARAMETERS presentParameters = {}; + + // The default swap chain is never actually used. Surface will create a new swap chain with the + // proper parameters. + presentParameters.AutoDepthStencilFormat = D3DFMT_UNKNOWN; + presentParameters.BackBufferCount = 1; + presentParameters.BackBufferFormat = D3DFMT_UNKNOWN; + presentParameters.BackBufferWidth = 1; + presentParameters.BackBufferHeight = 1; + presentParameters.EnableAutoDepthStencil = FALSE; + presentParameters.Flags = 0; + presentParameters.hDeviceWindow = mDeviceWindow; + presentParameters.MultiSampleQuality = 0; + presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; + presentParameters.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; + presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD; + presentParameters.Windowed = TRUE; + + return presentParameters; +} + +egl::ConfigSet Renderer9::generateConfigs() +{ + static const GLenum colorBufferFormats[] = { + GL_BGR5_A1_ANGLEX, + GL_BGRA8_EXT, + GL_RGB565, + + }; + + static const GLenum depthStencilBufferFormats[] = { + GL_NONE, + GL_DEPTH_COMPONENT32_OES, + GL_DEPTH24_STENCIL8_OES, + GL_DEPTH_COMPONENT24_OES, + GL_DEPTH_COMPONENT16, + }; + + const gl::Caps &rendererCaps = getNativeCaps(); + const gl::TextureCapsMap &rendererTextureCaps = getNativeTextureCaps(); + + D3DDISPLAYMODE currentDisplayMode; + mD3d9->GetAdapterDisplayMode(mAdapter, ¤tDisplayMode); + + // Determine the min and max swap intervals + int minSwapInterval = 4; + int maxSwapInterval = 0; + + if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE) + { + minSwapInterval = std::min(minSwapInterval, 0); + maxSwapInterval = std::max(maxSwapInterval, 0); + } + if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_ONE) + { + minSwapInterval = std::min(minSwapInterval, 1); + maxSwapInterval = std::max(maxSwapInterval, 1); + } + if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO) + { + minSwapInterval = std::min(minSwapInterval, 2); + maxSwapInterval = std::max(maxSwapInterval, 2); + } + if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_THREE) + { + minSwapInterval = std::min(minSwapInterval, 3); + maxSwapInterval = std::max(maxSwapInterval, 3); + } + if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_FOUR) + { + minSwapInterval = std::min(minSwapInterval, 4); + maxSwapInterval = std::max(maxSwapInterval, 4); + } + + egl::ConfigSet configs; + for (size_t formatIndex = 0; formatIndex < ArraySize(colorBufferFormats); formatIndex++) + { + GLenum colorBufferInternalFormat = colorBufferFormats[formatIndex]; + const gl::TextureCaps &colorBufferFormatCaps = + rendererTextureCaps.get(colorBufferInternalFormat); + if (colorBufferFormatCaps.renderbuffer) + { + ASSERT(colorBufferFormatCaps.textureAttachment); + for (size_t depthStencilIndex = 0; + depthStencilIndex < ArraySize(depthStencilBufferFormats); depthStencilIndex++) + { + GLenum depthStencilBufferInternalFormat = + depthStencilBufferFormats[depthStencilIndex]; + const gl::TextureCaps &depthStencilBufferFormatCaps = + rendererTextureCaps.get(depthStencilBufferInternalFormat); + if (depthStencilBufferFormatCaps.renderbuffer || + depthStencilBufferInternalFormat == GL_NONE) + { + ASSERT(depthStencilBufferFormatCaps.textureAttachment || + depthStencilBufferInternalFormat == GL_NONE); + const gl::InternalFormat &colorBufferFormatInfo = + gl::GetSizedInternalFormatInfo(colorBufferInternalFormat); + const gl::InternalFormat &depthStencilBufferFormatInfo = + gl::GetSizedInternalFormatInfo(depthStencilBufferInternalFormat); + const d3d9::TextureFormat &d3d9ColorBufferFormatInfo = + d3d9::GetTextureFormatInfo(colorBufferInternalFormat); + + egl::Config config; + config.renderTargetFormat = colorBufferInternalFormat; + config.depthStencilFormat = depthStencilBufferInternalFormat; + config.bufferSize = colorBufferFormatInfo.pixelBytes * 8; + config.redSize = colorBufferFormatInfo.redBits; + config.greenSize = colorBufferFormatInfo.greenBits; + config.blueSize = colorBufferFormatInfo.blueBits; + config.luminanceSize = colorBufferFormatInfo.luminanceBits; + config.alphaSize = colorBufferFormatInfo.alphaBits; + config.alphaMaskSize = 0; + config.bindToTextureRGB = (colorBufferFormatInfo.format == GL_RGB); + config.bindToTextureRGBA = (colorBufferFormatInfo.format == GL_RGBA || + colorBufferFormatInfo.format == GL_BGRA_EXT); + config.colorBufferType = EGL_RGB_BUFFER; + // Mark as slow if blits to the back-buffer won't be straight forward + config.configCaveat = + (currentDisplayMode.Format == d3d9ColorBufferFormatInfo.renderFormat) + ? EGL_NONE + : EGL_SLOW_CONFIG; + config.configID = static_cast(configs.size() + 1); + config.conformant = EGL_OPENGL_ES2_BIT; + config.depthSize = depthStencilBufferFormatInfo.depthBits; + config.level = 0; + config.matchNativePixmap = EGL_NONE; + config.maxPBufferWidth = rendererCaps.max2DTextureSize; + config.maxPBufferHeight = rendererCaps.max2DTextureSize; + config.maxPBufferPixels = + rendererCaps.max2DTextureSize * rendererCaps.max2DTextureSize; + config.maxSwapInterval = maxSwapInterval; + config.minSwapInterval = minSwapInterval; + config.nativeRenderable = EGL_FALSE; + config.nativeVisualID = 0; + config.nativeVisualType = EGL_NONE; + config.renderableType = EGL_OPENGL_ES2_BIT; + config.sampleBuffers = 0; // FIXME: enumerate multi-sampling + config.samples = 0; + config.stencilSize = depthStencilBufferFormatInfo.stencilBits; + config.surfaceType = + EGL_PBUFFER_BIT | EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT; + config.transparentType = EGL_NONE; + config.transparentRedValue = 0; + config.transparentGreenValue = 0; + config.transparentBlueValue = 0; + config.colorComponentType = gl_egl::GLComponentTypeToEGLColorComponentType( + colorBufferFormatInfo.componentType); + + configs.add(config); + } + } + } + } + + ASSERT(configs.size() > 0); + return configs; +} + +void Renderer9::generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const +{ + outExtensions->createContextRobustness = true; + + if (getShareHandleSupport()) + { + outExtensions->d3dShareHandleClientBuffer = true; + outExtensions->surfaceD3DTexture2DShareHandle = true; + } + outExtensions->d3dTextureClientBuffer = true; + + outExtensions->querySurfacePointer = true; + outExtensions->windowFixedSize = true; + outExtensions->postSubBuffer = true; + + outExtensions->image = true; + outExtensions->imageBase = true; + outExtensions->glTexture2DImage = true; + outExtensions->glRenderbufferImage = true; + + outExtensions->noConfigContext = true; + + // Contexts are virtualized so textures and semaphores can be shared globally + outExtensions->displayTextureShareGroup = true; + outExtensions->displaySemaphoreShareGroup = true; + + // D3D9 can be used without an output surface + outExtensions->surfacelessContext = true; + + outExtensions->robustResourceInitializationANGLE = true; +} + +void Renderer9::startScene() +{ + if (!mSceneStarted) + { + long result = mDevice->BeginScene(); + if (SUCCEEDED(result)) + { + // This is defensive checking against the device being + // lost at unexpected times. + mSceneStarted = true; + } + } +} + +void Renderer9::endScene() +{ + if (mSceneStarted) + { + // EndScene can fail if the device was lost, for example due + // to a TDR during a draw call. + mDevice->EndScene(); + mSceneStarted = false; + } +} + +angle::Result Renderer9::flush(const gl::Context *context) +{ + IDirect3DQuery9 *query = nullptr; + ANGLE_TRY(allocateEventQuery(context, &query)); + + Context9 *context9 = GetImplAs(context); + + HRESULT result = query->Issue(D3DISSUE_END); + ANGLE_TRY_HR(context9, result, "Failed to issue event query"); + + // Grab the query data once + result = query->GetData(nullptr, 0, D3DGETDATA_FLUSH); + freeEventQuery(query); + ANGLE_TRY_HR(context9, result, "Failed to get event query data"); + + return angle::Result::Continue; +} + +angle::Result Renderer9::finish(const gl::Context *context) +{ + IDirect3DQuery9 *query = nullptr; + ANGLE_TRY(allocateEventQuery(context, &query)); + + Context9 *context9 = GetImplAs(context); + + HRESULT result = query->Issue(D3DISSUE_END); + ANGLE_TRY_HR(context9, result, "Failed to issue event query"); + + // Grab the query data once + result = query->GetData(nullptr, 0, D3DGETDATA_FLUSH); + if (FAILED(result)) + { + freeEventQuery(query); + } + ANGLE_TRY_HR(context9, result, "Failed to get event query data"); + + // Loop until the query completes + unsigned int attempt = 0; + while (result == S_FALSE) + { + // Keep polling, but allow other threads to do something useful first + ScheduleYield(); + + result = query->GetData(nullptr, 0, D3DGETDATA_FLUSH); + attempt++; + + if (result == S_FALSE) + { + // explicitly check for device loss + // some drivers seem to return S_FALSE even if the device is lost + // instead of D3DERR_DEVICELOST like they should + bool checkDeviceLost = (attempt % kPollingD3DDeviceLostCheckFrequency) == 0; + if (checkDeviceLost && testDeviceLost()) + { + result = D3DERR_DEVICELOST; + } + } + + if (FAILED(result)) + { + freeEventQuery(query); + } + ANGLE_TRY_HR(context9, result, "Failed to get event query data"); + } + + freeEventQuery(query); + + return angle::Result::Continue; +} + +bool Renderer9::isValidNativeWindow(EGLNativeWindowType window) const +{ + return NativeWindow9::IsValidNativeWindow(window); +} + +NativeWindowD3D *Renderer9::createNativeWindow(EGLNativeWindowType window, + const egl::Config *, + const egl::AttributeMap &) const +{ + return new NativeWindow9(window); +} + +SwapChainD3D *Renderer9::createSwapChain(NativeWindowD3D *nativeWindow, + HANDLE shareHandle, + IUnknown *d3dTexture, + GLenum backBufferFormat, + GLenum depthBufferFormat, + EGLint orientation, + EGLint samples) +{ + return new SwapChain9(this, GetAs(nativeWindow), shareHandle, d3dTexture, + backBufferFormat, depthBufferFormat, orientation); +} + +egl::Error Renderer9::getD3DTextureInfo(const egl::Config *configuration, + IUnknown *d3dTexture, + const egl::AttributeMap &attribs, + EGLint *width, + EGLint *height, + GLsizei *samples, + gl::Format *glFormat, + const angle::Format **angleFormat, + UINT *arraySlice) const +{ + IDirect3DTexture9 *texture = nullptr; + if (FAILED(d3dTexture->QueryInterface(&texture))) + { + return egl::EglBadParameter() << "Client buffer is not a IDirect3DTexture9"; + } + + IDirect3DDevice9 *textureDevice = nullptr; + texture->GetDevice(&textureDevice); + if (textureDevice != mDevice) + { + SafeRelease(texture); + return egl::EglBadParameter() << "Texture's device does not match."; + } + SafeRelease(textureDevice); + + D3DSURFACE_DESC desc; + texture->GetLevelDesc(0, &desc); + SafeRelease(texture); + + if (width) + { + *width = static_cast(desc.Width); + } + if (height) + { + *height = static_cast(desc.Height); + } + + // GetSamplesCount() returns 0 when multisampling isn't used. + GLsizei sampleCount = d3d9_gl::GetSamplesCount(desc.MultiSampleType); + if ((configuration && configuration->samples > 1) || sampleCount != 0) + { + return egl::EglBadParameter() << "Multisampling not supported for client buffer texture"; + } + if (samples) + { + *samples = static_cast(sampleCount); + } + + // From table egl.restrictions in EGL_ANGLE_d3d_texture_client_buffer. + switch (desc.Format) + { + case D3DFMT_R8G8B8: + case D3DFMT_A8R8G8B8: + case D3DFMT_A16B16G16R16F: + case D3DFMT_A32B32G32R32F: + break; + + default: + return egl::EglBadParameter() + << "Unknown client buffer texture format: " << desc.Format; + } + + const auto &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format); + ASSERT(d3dFormatInfo.info().id != angle::FormatID::NONE); + + if (glFormat) + { + *glFormat = gl::Format(d3dFormatInfo.info().glInternalFormat); + } + + if (angleFormat) + { + + *angleFormat = &d3dFormatInfo.info(); + } + + if (arraySlice) + { + *arraySlice = 0; + } + + return egl::NoError(); +} + +egl::Error Renderer9::validateShareHandle(const egl::Config *config, + HANDLE shareHandle, + const egl::AttributeMap &attribs) const +{ + if (shareHandle == nullptr) + { + return egl::EglBadParameter() << "NULL share handle."; + } + + EGLint width = attribs.getAsInt(EGL_WIDTH, 0); + EGLint height = attribs.getAsInt(EGL_HEIGHT, 0); + ASSERT(width != 0 && height != 0); + + const d3d9::TextureFormat &backBufferd3dFormatInfo = + d3d9::GetTextureFormatInfo(config->renderTargetFormat); + + IDirect3DTexture9 *texture = nullptr; + HRESULT result = mDevice->CreateTexture(width, height, 1, D3DUSAGE_RENDERTARGET, + backBufferd3dFormatInfo.texFormat, D3DPOOL_DEFAULT, + &texture, &shareHandle); + if (FAILED(result)) + { + return egl::EglBadParameter() << "Failed to open share handle, " << gl::FmtHR(result); + } + + DWORD levelCount = texture->GetLevelCount(); + + D3DSURFACE_DESC desc; + texture->GetLevelDesc(0, &desc); + SafeRelease(texture); + + if (levelCount != 1 || desc.Width != static_cast(width) || + desc.Height != static_cast(height) || + desc.Format != backBufferd3dFormatInfo.texFormat) + { + return egl::EglBadParameter() << "Invalid texture parameters in share handle texture."; + } + + return egl::NoError(); +} + +ContextImpl *Renderer9::createContext(const gl::State &state, gl::ErrorSet *errorSet) +{ + return new Context9(state, errorSet, this); +} + +void *Renderer9::getD3DDevice() +{ + return mDevice; +} + +angle::Result Renderer9::allocateEventQuery(const gl::Context *context, IDirect3DQuery9 **outQuery) +{ + if (mEventQueryPool.empty()) + { + HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, outQuery); + ANGLE_TRY_HR(GetImplAs(context), result, "Failed to allocate event query"); + } + else + { + *outQuery = mEventQueryPool.back(); + mEventQueryPool.pop_back(); + } + + return angle::Result::Continue; +} + +void Renderer9::freeEventQuery(IDirect3DQuery9 *query) +{ + if (mEventQueryPool.size() > 1000) + { + SafeRelease(query); + } + else + { + mEventQueryPool.push_back(query); + } +} + +angle::Result Renderer9::createVertexShader(d3d::Context *context, + const DWORD *function, + size_t length, + IDirect3DVertexShader9 **outShader) +{ + return mVertexShaderCache.create(context, function, length, outShader); +} + +angle::Result Renderer9::createPixelShader(d3d::Context *context, + const DWORD *function, + size_t length, + IDirect3DPixelShader9 **outShader) +{ + return mPixelShaderCache.create(context, function, length, outShader); +} + +HRESULT Renderer9::createVertexBuffer(UINT Length, + DWORD Usage, + IDirect3DVertexBuffer9 **ppVertexBuffer) +{ + // Force buffers to be limited to a fixed max size. + if (Length > kMaximumBufferSizeHardLimit) + { + return E_OUTOFMEMORY; + } + + D3DPOOL Pool = getBufferPool(Usage); + return mDevice->CreateVertexBuffer(Length, Usage, 0, Pool, ppVertexBuffer, nullptr); +} + +VertexBuffer *Renderer9::createVertexBuffer() +{ + return new VertexBuffer9(this); +} + +HRESULT Renderer9::createIndexBuffer(UINT Length, + DWORD Usage, + D3DFORMAT Format, + IDirect3DIndexBuffer9 **ppIndexBuffer) +{ + // Force buffers to be limited to a fixed max size. + if (Length > kMaximumBufferSizeHardLimit) + { + return E_OUTOFMEMORY; + } + + D3DPOOL Pool = getBufferPool(Usage); + return mDevice->CreateIndexBuffer(Length, Usage, Format, Pool, ppIndexBuffer, nullptr); +} + +IndexBuffer *Renderer9::createIndexBuffer() +{ + return new IndexBuffer9(this); +} + +StreamProducerImpl *Renderer9::createStreamProducerD3DTexture( + egl::Stream::ConsumerType consumerType, + const egl::AttributeMap &attribs) +{ + // Streams are not supported under D3D9 + UNREACHABLE(); + return nullptr; +} + +bool Renderer9::supportsFastCopyBufferToTexture(GLenum internalFormat) const +{ + // Pixel buffer objects are not supported in D3D9, since D3D9 is ES2-only and PBOs are ES3. + return false; +} + +angle::Result Renderer9::fastCopyBufferToTexture(const gl::Context *context, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + unsigned int offset, + RenderTargetD3D *destRenderTarget, + GLenum destinationFormat, + GLenum sourcePixelsType, + const gl::Box &destArea) +{ + // Pixel buffer objects are not supported in D3D9, since D3D9 is ES2-only and PBOs are ES3. + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result Renderer9::setSamplerState(const gl::Context *context, + gl::ShaderType type, + int index, + gl::Texture *texture, + const gl::SamplerState &samplerState) +{ + CurSamplerState &appliedSampler = (type == gl::ShaderType::Fragment) + ? mCurPixelSamplerStates[index] + : mCurVertexSamplerStates[index]; + + // Make sure to add the level offset for our tiny compressed texture workaround + TextureD3D *textureD3D = GetImplAs(texture); + + TextureStorage *storage = nullptr; + ANGLE_TRY(textureD3D->getNativeTexture(context, &storage)); + + // Storage should exist, texture should be complete + ASSERT(storage); + + DWORD baseLevel = texture->getBaseLevel() + storage->getTopLevel(); + + if (appliedSampler.forceSet || appliedSampler.baseLevel != baseLevel || + memcmp(&samplerState, &appliedSampler, sizeof(gl::SamplerState)) != 0) + { + int d3dSamplerOffset = (type == gl::ShaderType::Fragment) ? 0 : D3DVERTEXTEXTURESAMPLER0; + int d3dSampler = index + d3dSamplerOffset; + + mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSU, + gl_d3d9::ConvertTextureWrap(samplerState.getWrapS())); + mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSV, + gl_d3d9::ConvertTextureWrap(samplerState.getWrapT())); + + mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAGFILTER, + gl_d3d9::ConvertMagFilter(samplerState.getMagFilter(), + samplerState.getMaxAnisotropy())); + + D3DTEXTUREFILTERTYPE d3dMinFilter, d3dMipFilter; + float lodBias; + gl_d3d9::ConvertMinFilter(samplerState.getMinFilter(), &d3dMinFilter, &d3dMipFilter, + &lodBias, samplerState.getMaxAnisotropy(), baseLevel); + mDevice->SetSamplerState(d3dSampler, D3DSAMP_MINFILTER, d3dMinFilter); + mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter); + mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXMIPLEVEL, baseLevel); + mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPMAPLODBIAS, static_cast(lodBias)); + if (getNativeExtensions().textureFilterAnisotropicEXT) + { + DWORD maxAnisotropy = std::min(mDeviceCaps.MaxAnisotropy, + static_cast(samplerState.getMaxAnisotropy())); + mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXANISOTROPY, maxAnisotropy); + } + + const bool isSrgb = gl::GetSizedInternalFormatInfo(textureD3D->getBaseLevelInternalFormat()) + .colorEncoding == GL_SRGB; + mDevice->SetSamplerState(d3dSampler, D3DSAMP_SRGBTEXTURE, isSrgb); + + ASSERT(texture->getBorderColor().type == angle::ColorGeneric::Type::Float); + mDevice->SetSamplerState(d3dSampler, D3DSAMP_BORDERCOLOR, + gl_d3d9::ConvertColor(texture->getBorderColor().colorF)); + } + + appliedSampler.forceSet = false; + appliedSampler.samplerState = samplerState; + appliedSampler.baseLevel = baseLevel; + + return angle::Result::Continue; +} + +angle::Result Renderer9::setTexture(const gl::Context *context, + gl::ShaderType type, + int index, + gl::Texture *texture) +{ + int d3dSamplerOffset = (type == gl::ShaderType::Fragment) ? 0 : D3DVERTEXTEXTURESAMPLER0; + int d3dSampler = index + d3dSamplerOffset; + IDirect3DBaseTexture9 *d3dTexture = nullptr; + bool forceSetTexture = false; + + std::vector &appliedTextures = + (type == gl::ShaderType::Fragment) ? mCurPixelTextures : mCurVertexTextures; + + if (texture) + { + TextureD3D *textureImpl = GetImplAs(texture); + + TextureStorage *texStorage = nullptr; + ANGLE_TRY(textureImpl->getNativeTexture(context, &texStorage)); + + // Texture should be complete and have a storage + ASSERT(texStorage); + + TextureStorage9 *storage9 = GetAs(texStorage); + ANGLE_TRY(storage9->getBaseTexture(context, &d3dTexture)); + + // If we get NULL back from getBaseTexture here, something went wrong + // in the texture class and we're unexpectedly missing the d3d texture + ASSERT(d3dTexture != nullptr); + + forceSetTexture = textureImpl->hasDirtyImages(); + textureImpl->resetDirty(); + } + + if (forceSetTexture || appliedTextures[index] != reinterpret_cast(d3dTexture)) + { + mDevice->SetTexture(d3dSampler, d3dTexture); + } + + appliedTextures[index] = reinterpret_cast(d3dTexture); + + return angle::Result::Continue; +} + +angle::Result Renderer9::updateState(const gl::Context *context, gl::PrimitiveMode drawMode) +{ + const auto &glState = context->getState(); + + // Applies the render target surface, depth stencil surface, viewport rectangle and + // scissor rectangle to the renderer + gl::Framebuffer *framebuffer = glState.getDrawFramebuffer(); + ASSERT(framebuffer && !framebuffer->hasAnyDirtyBit()); + + Framebuffer9 *framebuffer9 = GetImplAs(framebuffer); + + ANGLE_TRY(applyRenderTarget(context, framebuffer9->getCachedColorRenderTargets()[0], + framebuffer9->getCachedDepthStencilRenderTarget())); + + // Setting viewport state + setViewport(glState.getViewport(), glState.getNearPlane(), glState.getFarPlane(), drawMode, + glState.getRasterizerState().frontFace, false); + + // Setting scissors state + setScissorRectangle(glState.getScissor(), glState.isScissorTestEnabled()); + + // Setting blend, depth stencil, and rasterizer states + // Since framebuffer->getSamples will return the original samples which may be different with + // the sample counts that we set in render target view, here we use renderTarget->getSamples to + // get the actual samples. + GLsizei samples = 0; + const gl::FramebufferAttachment *firstColorAttachment = framebuffer->getFirstColorAttachment(); + if (firstColorAttachment) + { + ASSERT(firstColorAttachment->isAttached()); + RenderTarget9 *renderTarget = nullptr; + ANGLE_TRY(firstColorAttachment->getRenderTarget(context, firstColorAttachment->getSamples(), + &renderTarget)); + samples = renderTarget->getSamples(); + + mDevice->SetRenderState(D3DRS_SRGBWRITEENABLE, + renderTarget->getInternalFormat() == GL_SRGB8_ALPHA8); + } + gl::RasterizerState rasterizer = glState.getRasterizerState(); + rasterizer.pointDrawMode = (drawMode == gl::PrimitiveMode::Points); + rasterizer.multiSample = (samples != 0); + + ANGLE_TRY(setBlendDepthRasterStates(context, drawMode)); + + mStateManager.resetDirtyBits(); + + return angle::Result::Continue; +} + +void Renderer9::setScissorRectangle(const gl::Rectangle &scissor, bool enabled) +{ + mStateManager.setScissorState(scissor, enabled); +} + +angle::Result Renderer9::setBlendDepthRasterStates(const gl::Context *context, + gl::PrimitiveMode drawMode) +{ + const auto &glState = context->getState(); + gl::Framebuffer *drawFramebuffer = glState.getDrawFramebuffer(); + ASSERT(!drawFramebuffer->hasAnyDirtyBit()); + // Since framebuffer->getSamples will return the original samples which may be different with + // the sample counts that we set in render target view, here we use renderTarget->getSamples to + // get the actual samples. + GLsizei samples = 0; + const gl::FramebufferAttachment *firstColorAttachment = + drawFramebuffer->getFirstColorAttachment(); + if (firstColorAttachment) + { + ASSERT(firstColorAttachment->isAttached()); + RenderTarget9 *renderTarget = nullptr; + ANGLE_TRY(firstColorAttachment->getRenderTarget(context, firstColorAttachment->getSamples(), + &renderTarget)); + samples = renderTarget->getSamples(); + } + gl::RasterizerState rasterizer = glState.getRasterizerState(); + rasterizer.pointDrawMode = (drawMode == gl::PrimitiveMode::Points); + rasterizer.multiSample = (samples != 0); + + unsigned int mask = GetBlendSampleMask(glState, samples); + mStateManager.setBlendDepthRasterStates(glState, mask); + return angle::Result::Continue; +} + +void Renderer9::setViewport(const gl::Rectangle &viewport, + float zNear, + float zFar, + gl::PrimitiveMode drawMode, + GLenum frontFace, + bool ignoreViewport) +{ + mStateManager.setViewportState(viewport, zNear, zFar, drawMode, frontFace, ignoreViewport); +} + +bool Renderer9::applyPrimitiveType(gl::PrimitiveMode mode, GLsizei count, bool usesPointSize) +{ + switch (mode) + { + case gl::PrimitiveMode::Points: + mPrimitiveType = D3DPT_POINTLIST; + mPrimitiveCount = count; + break; + case gl::PrimitiveMode::Lines: + mPrimitiveType = D3DPT_LINELIST; + mPrimitiveCount = count / 2; + break; + case gl::PrimitiveMode::LineLoop: + mPrimitiveType = D3DPT_LINESTRIP; + mPrimitiveCount = + count - 1; // D3D doesn't support line loops, so we draw the last line separately + break; + case gl::PrimitiveMode::LineStrip: + mPrimitiveType = D3DPT_LINESTRIP; + mPrimitiveCount = count - 1; + break; + case gl::PrimitiveMode::Triangles: + mPrimitiveType = D3DPT_TRIANGLELIST; + mPrimitiveCount = count / 3; + break; + case gl::PrimitiveMode::TriangleStrip: + mPrimitiveType = D3DPT_TRIANGLESTRIP; + mPrimitiveCount = count - 2; + break; + case gl::PrimitiveMode::TriangleFan: + mPrimitiveType = D3DPT_TRIANGLEFAN; + mPrimitiveCount = count - 2; + break; + default: + UNREACHABLE(); + return false; + } + + return mPrimitiveCount > 0; +} + +angle::Result Renderer9::getNullColorRenderTarget(const gl::Context *context, + const RenderTarget9 *depthRenderTarget, + const RenderTarget9 **outColorRenderTarget) +{ + ASSERT(depthRenderTarget); + + const gl::Extents &size = depthRenderTarget->getExtents(); + + // search cached nullcolorbuffers + for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++) + { + if (mNullRenderTargetCache[i].renderTarget != nullptr && + mNullRenderTargetCache[i].width == size.width && + mNullRenderTargetCache[i].height == size.height) + { + mNullRenderTargetCache[i].lruCount = ++mMaxNullColorbufferLRU; + *outColorRenderTarget = mNullRenderTargetCache[i].renderTarget; + return angle::Result::Continue; + } + } + + RenderTargetD3D *nullRenderTarget = nullptr; + ANGLE_TRY(createRenderTarget(context, size.width, size.height, GL_NONE, 0, &nullRenderTarget)); + + // add nullbuffer to the cache + NullRenderTargetCacheEntry *oldest = &mNullRenderTargetCache[0]; + for (int i = 1; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++) + { + if (mNullRenderTargetCache[i].lruCount < oldest->lruCount) + { + oldest = &mNullRenderTargetCache[i]; + } + } + + SafeDelete(oldest->renderTarget); + oldest->renderTarget = GetAs(nullRenderTarget); + oldest->lruCount = ++mMaxNullColorbufferLRU; + oldest->width = size.width; + oldest->height = size.height; + + *outColorRenderTarget = oldest->renderTarget; + return angle::Result::Continue; +} + +angle::Result Renderer9::applyRenderTarget(const gl::Context *context, + const RenderTarget9 *colorRenderTargetIn, + const RenderTarget9 *depthStencilRenderTarget) +{ + // if there is no color attachment we must synthesize a NULL colorattachment + // to keep the D3D runtime happy. This should only be possible if depth texturing. + const RenderTarget9 *colorRenderTarget = colorRenderTargetIn; + if (colorRenderTarget == nullptr) + { + ANGLE_TRY(getNullColorRenderTarget(context, depthStencilRenderTarget, &colorRenderTarget)); + } + ASSERT(colorRenderTarget != nullptr); + + size_t renderTargetWidth = 0; + size_t renderTargetHeight = 0; + + bool renderTargetChanged = false; + unsigned int renderTargetSerial = colorRenderTarget->getSerial(); + if (renderTargetSerial != mAppliedRenderTargetSerial) + { + // Apply the render target on the device + IDirect3DSurface9 *renderTargetSurface = colorRenderTarget->getSurface(); + ASSERT(renderTargetSurface); + + mDevice->SetRenderTarget(0, renderTargetSurface); + SafeRelease(renderTargetSurface); + + renderTargetWidth = colorRenderTarget->getWidth(); + renderTargetHeight = colorRenderTarget->getHeight(); + + mAppliedRenderTargetSerial = renderTargetSerial; + renderTargetChanged = true; + } + + unsigned int depthStencilSerial = 0; + if (depthStencilRenderTarget != nullptr) + { + depthStencilSerial = depthStencilRenderTarget->getSerial(); + } + + if (depthStencilSerial != mAppliedDepthStencilSerial || !mDepthStencilInitialized) + { + unsigned int depthSize = 0; + unsigned int stencilSize = 0; + + // Apply the depth stencil on the device + if (depthStencilRenderTarget) + { + IDirect3DSurface9 *depthStencilSurface = depthStencilRenderTarget->getSurface(); + ASSERT(depthStencilSurface); + + mDevice->SetDepthStencilSurface(depthStencilSurface); + SafeRelease(depthStencilSurface); + + const gl::InternalFormat &format = + gl::GetSizedInternalFormatInfo(depthStencilRenderTarget->getInternalFormat()); + + depthSize = format.depthBits; + stencilSize = format.stencilBits; + } + else + { + mDevice->SetDepthStencilSurface(nullptr); + } + + mStateManager.updateDepthSizeIfChanged(mDepthStencilInitialized, depthSize); + mStateManager.updateStencilSizeIfChanged(mDepthStencilInitialized, stencilSize); + + mAppliedDepthStencilSerial = depthStencilSerial; + mDepthStencilInitialized = true; + } + + if (renderTargetChanged || !mRenderTargetDescInitialized) + { + mStateManager.forceSetBlendState(); + mStateManager.forceSetScissorState(); + mStateManager.setRenderTargetBounds(renderTargetWidth, renderTargetHeight); + mRenderTargetDescInitialized = true; + } + + return angle::Result::Continue; +} + +angle::Result Renderer9::applyVertexBuffer(const gl::Context *context, + gl::PrimitiveMode mode, + GLint first, + GLsizei count, + GLsizei instances, + TranslatedIndexData * /*indexInfo*/) +{ + const gl::State &state = context->getState(); + ANGLE_TRY(mVertexDataManager->prepareVertexData(context, first, count, &mTranslatedAttribCache, + instances)); + + return mVertexDeclarationCache.applyDeclaration(context, mDevice, mTranslatedAttribCache, + state.getProgram(), first, instances, + &mRepeatDraw); +} + +// Applies the indices and element array bindings to the Direct3D 9 device +angle::Result Renderer9::applyIndexBuffer(const gl::Context *context, + const void *indices, + GLsizei count, + gl::PrimitiveMode mode, + gl::DrawElementsType type, + TranslatedIndexData *indexInfo) +{ + gl::VertexArray *vao = context->getState().getVertexArray(); + gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer(); + + gl::DrawElementsType dstType = gl::DrawElementsType::InvalidEnum; + ANGLE_TRY(GetIndexTranslationDestType(context, count, type, indices, false, &dstType)); + + ANGLE_TRY(mIndexDataManager->prepareIndexData(context, type, dstType, count, elementArrayBuffer, + indices, indexInfo)); + + // Directly binding the storage buffer is not supported for d3d9 + ASSERT(indexInfo->storage == nullptr); + + if (indexInfo->serial != mAppliedIBSerial) + { + IndexBuffer9 *indexBuffer = GetAs(indexInfo->indexBuffer); + + mDevice->SetIndices(indexBuffer->getBuffer()); + mAppliedIBSerial = indexInfo->serial; + } + + return angle::Result::Continue; +} + +angle::Result Renderer9::drawArraysImpl(const gl::Context *context, + gl::PrimitiveMode mode, + GLint startVertex, + GLsizei count, + GLsizei instances) +{ + ASSERT(!context->getState().isTransformFeedbackActiveUnpaused()); + + startScene(); + + if (mode == gl::PrimitiveMode::LineLoop) + { + return drawLineLoop(context, count, gl::DrawElementsType::InvalidEnum, nullptr, 0, nullptr); + } + + if (instances > 0) + { + StaticIndexBufferInterface *countingIB = nullptr; + ANGLE_TRY(getCountingIB(context, count, &countingIB)); + + if (mAppliedIBSerial != countingIB->getSerial()) + { + IndexBuffer9 *indexBuffer = GetAs(countingIB->getIndexBuffer()); + + mDevice->SetIndices(indexBuffer->getBuffer()); + mAppliedIBSerial = countingIB->getSerial(); + } + + for (int i = 0; i < mRepeatDraw; i++) + { + mDevice->DrawIndexedPrimitive(mPrimitiveType, 0, 0, count, 0, mPrimitiveCount); + } + + return angle::Result::Continue; + } + + // Regular case + mDevice->DrawPrimitive(mPrimitiveType, 0, mPrimitiveCount); + return angle::Result::Continue; +} + +angle::Result Renderer9::drawElementsImpl(const gl::Context *context, + gl::PrimitiveMode mode, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + GLsizei instances) +{ + TranslatedIndexData indexInfo; + + ANGLE_TRY(applyIndexBuffer(context, indices, count, mode, type, &indexInfo)); + + gl::IndexRange indexRange; + ANGLE_TRY(context->getState().getVertexArray()->getIndexRange(context, type, count, indices, + &indexRange)); + + size_t vertexCount = indexRange.vertexCount(); + ANGLE_TRY(applyVertexBuffer(context, mode, static_cast(indexRange.start), + static_cast(vertexCount), instances, &indexInfo)); + + startScene(); + + int minIndex = static_cast(indexRange.start); + + gl::VertexArray *vao = context->getState().getVertexArray(); + gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer(); + + if (mode == gl::PrimitiveMode::Points) + { + return drawIndexedPoints(context, count, type, indices, minIndex, elementArrayBuffer); + } + + if (mode == gl::PrimitiveMode::LineLoop) + { + return drawLineLoop(context, count, type, indices, minIndex, elementArrayBuffer); + } + + for (int i = 0; i < mRepeatDraw; i++) + { + mDevice->DrawIndexedPrimitive(mPrimitiveType, -minIndex, minIndex, + static_cast(vertexCount), indexInfo.startIndex, + mPrimitiveCount); + } + return angle::Result::Continue; +} + +angle::Result Renderer9::drawLineLoop(const gl::Context *context, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + int minIndex, + gl::Buffer *elementArrayBuffer) +{ + // Get the raw indices for an indexed draw + if (type != gl::DrawElementsType::InvalidEnum && elementArrayBuffer) + { + BufferD3D *storage = GetImplAs(elementArrayBuffer); + intptr_t offset = reinterpret_cast(indices); + const uint8_t *bufferData = nullptr; + ANGLE_TRY(storage->getData(context, &bufferData)); + indices = bufferData + offset; + } + + unsigned int startIndex = 0; + Context9 *context9 = GetImplAs(context); + + if (getNativeExtensions().elementIndexUintOES) + { + if (!mLineLoopIB) + { + mLineLoopIB = new StreamingIndexBufferInterface(this); + ANGLE_TRY(mLineLoopIB->reserveBufferSpace(context, INITIAL_INDEX_BUFFER_SIZE, + gl::DrawElementsType::UnsignedInt)); + } + + // Checked by Renderer9::applyPrimitiveType + ASSERT(count >= 0); + + ANGLE_CHECK(context9, + static_cast(count) + 1 <= + (std::numeric_limits::max() / sizeof(unsigned int)), + "Failed to create a 32-bit looping index buffer for " + "GL_LINE_LOOP, too many indices required.", + GL_OUT_OF_MEMORY); + + const unsigned int spaceNeeded = + (static_cast(count) + 1) * sizeof(unsigned int); + ANGLE_TRY(mLineLoopIB->reserveBufferSpace(context, spaceNeeded, + gl::DrawElementsType::UnsignedInt)); + + void *mappedMemory = nullptr; + unsigned int offset = 0; + ANGLE_TRY(mLineLoopIB->mapBuffer(context, spaceNeeded, &mappedMemory, &offset)); + + startIndex = static_cast(offset) / 4; + unsigned int *data = static_cast(mappedMemory); + + switch (type) + { + case gl::DrawElementsType::InvalidEnum: // Non-indexed draw + for (int i = 0; i < count; i++) + { + data[i] = i; + } + data[count] = 0; + break; + case gl::DrawElementsType::UnsignedByte: + for (int i = 0; i < count; i++) + { + data[i] = static_cast(indices)[i]; + } + data[count] = static_cast(indices)[0]; + break; + case gl::DrawElementsType::UnsignedShort: + for (int i = 0; i < count; i++) + { + data[i] = static_cast(indices)[i]; + } + data[count] = static_cast(indices)[0]; + break; + case gl::DrawElementsType::UnsignedInt: + for (int i = 0; i < count; i++) + { + data[i] = static_cast(indices)[i]; + } + data[count] = static_cast(indices)[0]; + break; + default: + UNREACHABLE(); + } + + ANGLE_TRY(mLineLoopIB->unmapBuffer(context)); + } + else + { + if (!mLineLoopIB) + { + mLineLoopIB = new StreamingIndexBufferInterface(this); + ANGLE_TRY(mLineLoopIB->reserveBufferSpace(context, INITIAL_INDEX_BUFFER_SIZE, + gl::DrawElementsType::UnsignedShort)); + } + + // Checked by Renderer9::applyPrimitiveType + ASSERT(count >= 0); + + ANGLE_CHECK(context9, + static_cast(count) + 1 <= + (std::numeric_limits::max() / sizeof(unsigned short)), + "Failed to create a 16-bit looping index buffer for " + "GL_LINE_LOOP, too many indices required.", + GL_OUT_OF_MEMORY); + + const unsigned int spaceNeeded = + (static_cast(count) + 1) * sizeof(unsigned short); + ANGLE_TRY(mLineLoopIB->reserveBufferSpace(context, spaceNeeded, + gl::DrawElementsType::UnsignedShort)); + + void *mappedMemory = nullptr; + unsigned int offset; + ANGLE_TRY(mLineLoopIB->mapBuffer(context, spaceNeeded, &mappedMemory, &offset)); + + startIndex = static_cast(offset) / 2; + unsigned short *data = static_cast(mappedMemory); + + switch (type) + { + case gl::DrawElementsType::InvalidEnum: // Non-indexed draw + for (int i = 0; i < count; i++) + { + data[i] = static_cast(i); + } + data[count] = 0; + break; + case gl::DrawElementsType::UnsignedByte: + for (int i = 0; i < count; i++) + { + data[i] = static_cast(indices)[i]; + } + data[count] = static_cast(indices)[0]; + break; + case gl::DrawElementsType::UnsignedShort: + for (int i = 0; i < count; i++) + { + data[i] = static_cast(indices)[i]; + } + data[count] = static_cast(indices)[0]; + break; + case gl::DrawElementsType::UnsignedInt: + for (int i = 0; i < count; i++) + { + data[i] = static_cast(static_cast(indices)[i]); + } + data[count] = static_cast(static_cast(indices)[0]); + break; + default: + UNREACHABLE(); + } + + ANGLE_TRY(mLineLoopIB->unmapBuffer(context)); + } + + if (mAppliedIBSerial != mLineLoopIB->getSerial()) + { + IndexBuffer9 *indexBuffer = GetAs(mLineLoopIB->getIndexBuffer()); + + mDevice->SetIndices(indexBuffer->getBuffer()); + mAppliedIBSerial = mLineLoopIB->getSerial(); + } + + mDevice->DrawIndexedPrimitive(D3DPT_LINESTRIP, -minIndex, minIndex, count, startIndex, count); + + return angle::Result::Continue; +} + +angle::Result Renderer9::drawIndexedPoints(const gl::Context *context, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + int minIndex, + gl::Buffer *elementArrayBuffer) +{ + // Drawing index point lists is unsupported in d3d9, fall back to a regular DrawPrimitive call + // for each individual point. This call is not expected to happen often. + + if (elementArrayBuffer) + { + BufferD3D *storage = GetImplAs(elementArrayBuffer); + intptr_t offset = reinterpret_cast(indices); + + const uint8_t *bufferData = nullptr; + ANGLE_TRY(storage->getData(context, &bufferData)); + indices = bufferData + offset; + } + + switch (type) + { + case gl::DrawElementsType::UnsignedByte: + DrawPoints(mDevice, count, indices, minIndex); + return angle::Result::Continue; + case gl::DrawElementsType::UnsignedShort: + DrawPoints(mDevice, count, indices, minIndex); + return angle::Result::Continue; + case gl::DrawElementsType::UnsignedInt: + DrawPoints(mDevice, count, indices, minIndex); + return angle::Result::Continue; + default: + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + } +} + +angle::Result Renderer9::getCountingIB(const gl::Context *context, + size_t count, + StaticIndexBufferInterface **outIB) +{ + // Update the counting index buffer if it is not large enough or has not been created yet. + if (count <= 65536) // 16-bit indices + { + const unsigned int spaceNeeded = static_cast(count) * sizeof(unsigned short); + + if (!mCountingIB || mCountingIB->getBufferSize() < spaceNeeded) + { + SafeDelete(mCountingIB); + mCountingIB = new StaticIndexBufferInterface(this); + ANGLE_TRY(mCountingIB->reserveBufferSpace(context, spaceNeeded, + gl::DrawElementsType::UnsignedShort)); + + void *mappedMemory = nullptr; + ANGLE_TRY(mCountingIB->mapBuffer(context, spaceNeeded, &mappedMemory, nullptr)); + + unsigned short *data = static_cast(mappedMemory); + for (size_t i = 0; i < count; i++) + { + data[i] = static_cast(i); + } + + ANGLE_TRY(mCountingIB->unmapBuffer(context)); + } + } + else if (getNativeExtensions().elementIndexUintOES) + { + const unsigned int spaceNeeded = static_cast(count) * sizeof(unsigned int); + + if (!mCountingIB || mCountingIB->getBufferSize() < spaceNeeded) + { + SafeDelete(mCountingIB); + mCountingIB = new StaticIndexBufferInterface(this); + ANGLE_TRY(mCountingIB->reserveBufferSpace(context, spaceNeeded, + gl::DrawElementsType::UnsignedInt)); + + void *mappedMemory = nullptr; + ANGLE_TRY(mCountingIB->mapBuffer(context, spaceNeeded, &mappedMemory, nullptr)); + + unsigned int *data = static_cast(mappedMemory); + for (unsigned int i = 0; i < count; i++) + { + data[i] = i; + } + + ANGLE_TRY(mCountingIB->unmapBuffer(context)); + } + } + else + { + ANGLE_TRY_HR(GetImplAs(context), E_OUTOFMEMORY, + "Could not create a counting index buffer for glDrawArraysInstanced."); + } + + *outIB = mCountingIB; + return angle::Result::Continue; +} + +angle::Result Renderer9::applyShaders(const gl::Context *context, gl::PrimitiveMode drawMode) +{ + const gl::State &state = context->getState(); + d3d::Context *contextD3D = GetImplAs(context); + + // This method is called single-threaded. + ANGLE_TRY(ensureHLSLCompilerInitialized(contextD3D)); + + ProgramD3D *programD3D = GetImplAs(state.getProgram()); + VertexArray9 *vao = GetImplAs(state.getVertexArray()); + programD3D->updateCachedInputLayout(vao->getCurrentStateSerial(), state); + + ShaderExecutableD3D *vertexExe = nullptr; + ANGLE_TRY(programD3D->getVertexExecutableForCachedInputLayout(contextD3D, &vertexExe, nullptr)); + + const gl::Framebuffer *drawFramebuffer = state.getDrawFramebuffer(); + programD3D->updateCachedOutputLayout(context, drawFramebuffer); + + ShaderExecutableD3D *pixelExe = nullptr; + ANGLE_TRY(programD3D->getPixelExecutableForCachedOutputLayout(contextD3D, &pixelExe, nullptr)); + + IDirect3DVertexShader9 *vertexShader = + (vertexExe ? GetAs(vertexExe)->getVertexShader() : nullptr); + IDirect3DPixelShader9 *pixelShader = + (pixelExe ? GetAs(pixelExe)->getPixelShader() : nullptr); + + if (vertexShader != mAppliedVertexShader) + { + mDevice->SetVertexShader(vertexShader); + mAppliedVertexShader = vertexShader; + } + + if (pixelShader != mAppliedPixelShader) + { + mDevice->SetPixelShader(pixelShader); + mAppliedPixelShader = pixelShader; + } + + // D3D9 has a quirk where creating multiple shaders with the same content + // can return the same shader pointer. Because GL programs store different data + // per-program, checking the program serial guarantees we upload fresh + // uniform data even if our shader pointers are the same. + // https://code.google.com/p/angleproject/issues/detail?id=661 + unsigned int programSerial = programD3D->getSerial(); + if (programSerial != mAppliedProgramSerial) + { + programD3D->dirtyAllUniforms(); + mStateManager.forceSetDXUniformsState(); + mAppliedProgramSerial = programSerial; + } + + applyUniforms(programD3D); + + // Driver uniforms + mStateManager.setShaderConstants(); + + return angle::Result::Continue; +} + +void Renderer9::applyUniforms(ProgramD3D *programD3D) +{ + // Skip updates if we're not dirty. Note that D3D9 cannot have compute or geometry. + if (!programD3D->anyShaderUniformsDirty()) + { + return; + } + + const auto &uniformArray = programD3D->getD3DUniforms(); + + for (const D3DUniform *targetUniform : uniformArray) + { + // Built-in uniforms must be skipped. + if (!targetUniform->isReferencedByShader(gl::ShaderType::Vertex) && + !targetUniform->isReferencedByShader(gl::ShaderType::Fragment)) + continue; + + const GLfloat *f = reinterpret_cast(targetUniform->firstNonNullData()); + const GLint *i = reinterpret_cast(targetUniform->firstNonNullData()); + + switch (targetUniform->typeInfo.type) + { + case GL_SAMPLER_2D: + case GL_SAMPLER_CUBE: + case GL_SAMPLER_EXTERNAL_OES: + case GL_SAMPLER_VIDEO_IMAGE_WEBGL: + break; + case GL_BOOL: + case GL_BOOL_VEC2: + case GL_BOOL_VEC3: + case GL_BOOL_VEC4: + applyUniformnbv(targetUniform, i); + break; + case GL_FLOAT: + case GL_FLOAT_VEC2: + case GL_FLOAT_VEC3: + case GL_FLOAT_VEC4: + case GL_FLOAT_MAT2: + case GL_FLOAT_MAT3: + case GL_FLOAT_MAT4: + applyUniformnfv(targetUniform, f); + break; + case GL_INT: + case GL_INT_VEC2: + case GL_INT_VEC3: + case GL_INT_VEC4: + applyUniformniv(targetUniform, i); + break; + default: + UNREACHABLE(); + } + } + + programD3D->markUniformsClean(); +} + +void Renderer9::applyUniformnfv(const D3DUniform *targetUniform, const GLfloat *v) +{ + if (targetUniform->isReferencedByShader(gl::ShaderType::Fragment)) + { + mDevice->SetPixelShaderConstantF( + targetUniform->mShaderRegisterIndexes[gl::ShaderType::Fragment], v, + targetUniform->registerCount); + } + + if (targetUniform->isReferencedByShader(gl::ShaderType::Vertex)) + { + mDevice->SetVertexShaderConstantF( + targetUniform->mShaderRegisterIndexes[gl::ShaderType::Vertex], v, + targetUniform->registerCount); + } +} + +void Renderer9::applyUniformniv(const D3DUniform *targetUniform, const GLint *v) +{ + ASSERT(targetUniform->registerCount <= MAX_VERTEX_CONSTANT_VECTORS_D3D9); + GLfloat vector[MAX_VERTEX_CONSTANT_VECTORS_D3D9][4]; + + for (unsigned int i = 0; i < targetUniform->registerCount; i++) + { + vector[i][0] = (GLfloat)v[4 * i + 0]; + vector[i][1] = (GLfloat)v[4 * i + 1]; + vector[i][2] = (GLfloat)v[4 * i + 2]; + vector[i][3] = (GLfloat)v[4 * i + 3]; + } + + applyUniformnfv(targetUniform, (GLfloat *)vector); +} + +void Renderer9::applyUniformnbv(const D3DUniform *targetUniform, const GLint *v) +{ + ASSERT(targetUniform->registerCount <= MAX_VERTEX_CONSTANT_VECTORS_D3D9); + GLfloat vector[MAX_VERTEX_CONSTANT_VECTORS_D3D9][4]; + + for (unsigned int i = 0; i < targetUniform->registerCount; i++) + { + vector[i][0] = (v[4 * i + 0] == GL_FALSE) ? 0.0f : 1.0f; + vector[i][1] = (v[4 * i + 1] == GL_FALSE) ? 0.0f : 1.0f; + vector[i][2] = (v[4 * i + 2] == GL_FALSE) ? 0.0f : 1.0f; + vector[i][3] = (v[4 * i + 3] == GL_FALSE) ? 0.0f : 1.0f; + } + + applyUniformnfv(targetUniform, (GLfloat *)vector); +} + +void Renderer9::clear(const ClearParameters &clearParams, + const RenderTarget9 *colorRenderTarget, + const RenderTarget9 *depthStencilRenderTarget) +{ + // Clearing buffers with non-float values is not supported by Renderer9 and ES 2.0 + ASSERT(clearParams.colorType == GL_FLOAT); + + // Clearing individual buffers other than buffer zero is not supported by Renderer9 and ES 2.0 + bool clearColor = clearParams.clearColor[0]; + for (unsigned int i = 0; i < clearParams.clearColor.size(); i++) + { + ASSERT(clearParams.clearColor[i] == clearColor); + } + + float depth = gl::clamp01(clearParams.depthValue); + DWORD stencil = clearParams.stencilValue & 0x000000FF; + + unsigned int stencilUnmasked = 0x0; + if (clearParams.clearStencil && depthStencilRenderTarget) + { + const gl::InternalFormat &depthStencilFormat = + gl::GetSizedInternalFormatInfo(depthStencilRenderTarget->getInternalFormat()); + if (depthStencilFormat.stencilBits > 0) + { + const d3d9::D3DFormat &d3dFormatInfo = + d3d9::GetD3DFormatInfo(depthStencilRenderTarget->getD3DFormat()); + stencilUnmasked = (0x1 << d3dFormatInfo.stencilBits) - 1; + } + } + + const bool needMaskedStencilClear = + clearParams.clearStencil && + (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked; + + bool needMaskedColorClear = false; + D3DCOLOR color = D3DCOLOR_ARGB(255, 0, 0, 0); + if (clearColor) + { + ASSERT(colorRenderTarget != nullptr); + + const gl::InternalFormat &formatInfo = + gl::GetSizedInternalFormatInfo(colorRenderTarget->getInternalFormat()); + const d3d9::D3DFormat &d3dFormatInfo = + d3d9::GetD3DFormatInfo(colorRenderTarget->getD3DFormat()); + + color = + D3DCOLOR_ARGB(gl::unorm<8>((formatInfo.alphaBits == 0 && d3dFormatInfo.alphaBits > 0) + ? 1.0f + : clearParams.colorF.alpha), + gl::unorm<8>((formatInfo.redBits == 0 && d3dFormatInfo.redBits > 0) + ? 0.0f + : clearParams.colorF.red), + gl::unorm<8>((formatInfo.greenBits == 0 && d3dFormatInfo.greenBits > 0) + ? 0.0f + : clearParams.colorF.green), + gl::unorm<8>((formatInfo.blueBits == 0 && d3dFormatInfo.blueBits > 0) + ? 0.0f + : clearParams.colorF.blue)); + + const uint8_t colorMask = + gl::BlendStateExt::ColorMaskStorage::GetValueIndexed(0, clearParams.colorMask); + bool r, g, b, a; + gl::BlendStateExt::UnpackColorMask(colorMask, &r, &g, &b, &a); + if ((formatInfo.redBits > 0 && !r) || (formatInfo.greenBits > 0 && !g) || + (formatInfo.blueBits > 0 && !b) || (formatInfo.alphaBits > 0 && !a)) + { + needMaskedColorClear = true; + } + } + + if (needMaskedColorClear || needMaskedStencilClear) + { + // State which is altered in all paths from this point to the clear call is saved. + // State which is altered in only some paths will be flagged dirty in the case that + // that path is taken. + HRESULT hr; + if (mMaskedClearSavedState == nullptr) + { + hr = mDevice->BeginStateBlock(); + ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); + + mDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + mDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); + mDevice->SetRenderState(D3DRS_ZENABLE, FALSE); + mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + mDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); + mDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); + mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + mDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, 0); + mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0); + mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); + mDevice->SetPixelShader(nullptr); + mDevice->SetVertexShader(nullptr); + mDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE); + mDevice->SetStreamSource(0, nullptr, 0, 0); + mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE); + mDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + mDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); + mDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + mDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR); + mDevice->SetRenderState(D3DRS_TEXTUREFACTOR, color); + mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF); + + for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + { + mDevice->SetStreamSourceFreq(i, 1); + } + + hr = mDevice->EndStateBlock(&mMaskedClearSavedState); + ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); + } + + ASSERT(mMaskedClearSavedState != nullptr); + + if (mMaskedClearSavedState != nullptr) + { + hr = mMaskedClearSavedState->Capture(); + ASSERT(SUCCEEDED(hr)); + } + + mDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + mDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); + mDevice->SetRenderState(D3DRS_ZENABLE, FALSE); + mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + mDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); + mDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); + mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + mDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, 0); + + if (clearColor) + { + // clearParams.colorMask follows the same packing scheme as + // D3DCOLORWRITEENABLE_RED/GREEN/BLUE/ALPHA + mDevice->SetRenderState( + D3DRS_COLORWRITEENABLE, + gl::BlendStateExt::ColorMaskStorage::GetValueIndexed(0, clearParams.colorMask)); + } + else + { + mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0); + } + + if (stencilUnmasked != 0x0 && clearParams.clearStencil) + { + mDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE); + mDevice->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE); + mDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); + mDevice->SetRenderState(D3DRS_STENCILREF, stencil); + mDevice->SetRenderState(D3DRS_STENCILWRITEMASK, clearParams.stencilWriteMask); + mDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_REPLACE); + mDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_REPLACE); + mDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE); + } + else + { + mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); + } + + mDevice->SetPixelShader(nullptr); + mDevice->SetVertexShader(nullptr); + mDevice->SetFVF(D3DFVF_XYZRHW); + mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE); + mDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + mDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); + mDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + mDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR); + mDevice->SetRenderState(D3DRS_TEXTUREFACTOR, color); + mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF); + + for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + { + mDevice->SetStreamSourceFreq(i, 1); + } + + int renderTargetWidth = mStateManager.getRenderTargetWidth(); + int renderTargetHeight = mStateManager.getRenderTargetHeight(); + + float quad[4][4]; // A quadrilateral covering the target, aligned to match the edges + quad[0][0] = -0.5f; + quad[0][1] = renderTargetHeight - 0.5f; + quad[0][2] = 0.0f; + quad[0][3] = 1.0f; + + quad[1][0] = renderTargetWidth - 0.5f; + quad[1][1] = renderTargetHeight - 0.5f; + quad[1][2] = 0.0f; + quad[1][3] = 1.0f; + + quad[2][0] = -0.5f; + quad[2][1] = -0.5f; + quad[2][2] = 0.0f; + quad[2][3] = 1.0f; + + quad[3][0] = renderTargetWidth - 0.5f; + quad[3][1] = -0.5f; + quad[3][2] = 0.0f; + quad[3][3] = 1.0f; + + startScene(); + mDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float[4])); + + if (clearParams.clearDepth) + { + mDevice->SetRenderState(D3DRS_ZENABLE, TRUE); + mDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); + mDevice->Clear(0, nullptr, D3DCLEAR_ZBUFFER, color, depth, stencil); + } + + if (mMaskedClearSavedState != nullptr) + { + mMaskedClearSavedState->Apply(); + } + } + else if (clearColor || clearParams.clearDepth || clearParams.clearStencil) + { + DWORD dxClearFlags = 0; + if (clearColor) + { + dxClearFlags |= D3DCLEAR_TARGET; + } + if (clearParams.clearDepth) + { + dxClearFlags |= D3DCLEAR_ZBUFFER; + } + if (clearParams.clearStencil) + { + dxClearFlags |= D3DCLEAR_STENCIL; + } + + mDevice->Clear(0, nullptr, dxClearFlags, color, depth, stencil); + } +} + +void Renderer9::markAllStateDirty() +{ + mAppliedRenderTargetSerial = 0; + mAppliedDepthStencilSerial = 0; + mDepthStencilInitialized = false; + mRenderTargetDescInitialized = false; + + mStateManager.forceSetRasterState(); + mStateManager.forceSetDepthStencilState(); + mStateManager.forceSetBlendState(); + mStateManager.forceSetScissorState(); + mStateManager.forceSetViewportState(); + + ASSERT(mCurVertexSamplerStates.size() == mCurVertexTextures.size()); + for (unsigned int i = 0; i < mCurVertexTextures.size(); i++) + { + mCurVertexSamplerStates[i].forceSet = true; + mCurVertexTextures[i] = angle::DirtyPointer; + } + + ASSERT(mCurPixelSamplerStates.size() == mCurPixelTextures.size()); + for (unsigned int i = 0; i < mCurPixelSamplerStates.size(); i++) + { + mCurPixelSamplerStates[i].forceSet = true; + mCurPixelTextures[i] = angle::DirtyPointer; + } + + mAppliedIBSerial = 0; + mAppliedVertexShader = nullptr; + mAppliedPixelShader = nullptr; + mAppliedProgramSerial = 0; + mStateManager.forceSetDXUniformsState(); + + mVertexDeclarationCache.markStateDirty(); +} + +void Renderer9::releaseDeviceResources() +{ + for (size_t i = 0; i < mEventQueryPool.size(); i++) + { + SafeRelease(mEventQueryPool[i]); + } + mEventQueryPool.clear(); + + SafeRelease(mMaskedClearSavedState); + + mVertexShaderCache.clear(); + mPixelShaderCache.clear(); + + SafeDelete(mBlit); + SafeDelete(mVertexDataManager); + SafeDelete(mIndexDataManager); + SafeDelete(mLineLoopIB); + SafeDelete(mCountingIB); + + for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++) + { + SafeDelete(mNullRenderTargetCache[i].renderTarget); + } +} + +// set notify to true to broadcast a message to all contexts of the device loss +bool Renderer9::testDeviceLost() +{ + HRESULT status = getDeviceStatusCode(); + return FAILED(status); +} + +HRESULT Renderer9::getDeviceStatusCode() +{ + HRESULT status = D3D_OK; + + if (mDeviceEx) + { + status = mDeviceEx->CheckDeviceState(nullptr); + } + else if (mDevice) + { + status = mDevice->TestCooperativeLevel(); + } + + return status; +} + +bool Renderer9::testDeviceResettable() +{ + // On D3D9Ex, DEVICELOST represents a hung device that needs to be restarted + // DEVICEREMOVED indicates the device has been stopped and must be recreated + switch (getDeviceStatusCode()) + { + case D3DERR_DEVICENOTRESET: + case D3DERR_DEVICEHUNG: + return true; + case D3DERR_DEVICELOST: + return (mDeviceEx != nullptr); + case D3DERR_DEVICEREMOVED: + ASSERT(mDeviceEx != nullptr); + return isRemovedDeviceResettable(); + default: + return false; + } +} + +bool Renderer9::resetDevice() +{ + releaseDeviceResources(); + + D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters(); + + HRESULT result = D3D_OK; + bool lost = testDeviceLost(); + bool removedDevice = (getDeviceStatusCode() == D3DERR_DEVICEREMOVED); + + // Device Removed is a feature which is only present with D3D9Ex + ASSERT(mDeviceEx != nullptr || !removedDevice); + + for (int attempts = 3; lost && attempts > 0; attempts--) + { + if (removedDevice) + { + // Device removed, which may trigger on driver reinstallation, + // may cause a longer wait other reset attempts before the + // system is ready to handle creating a new device. + Sleep(800); + lost = !resetRemovedDevice(); + } + else if (mDeviceEx) + { + Sleep(500); // Give the graphics driver some CPU time + result = mDeviceEx->ResetEx(&presentParameters, nullptr); + lost = testDeviceLost(); + } + else + { + result = mDevice->TestCooperativeLevel(); + while (result == D3DERR_DEVICELOST) + { + Sleep(100); // Give the graphics driver some CPU time + result = mDevice->TestCooperativeLevel(); + } + + if (result == D3DERR_DEVICENOTRESET) + { + result = mDevice->Reset(&presentParameters); + } + lost = testDeviceLost(); + } + } + + if (FAILED(result)) + { + ERR() << "Reset/ResetEx failed multiple times, " << gl::FmtHR(result); + return false; + } + + if (removedDevice && lost) + { + ERR() << "Device lost reset failed multiple times"; + return false; + } + + // If the device was removed, we already finished re-initialization in resetRemovedDevice + if (!removedDevice) + { + // reset device defaults + if (initializeDevice().isError()) + { + return false; + } + } + + return true; +} + +bool Renderer9::isRemovedDeviceResettable() const +{ + bool success = false; + +#if ANGLE_D3D9EX == ANGLE_ENABLED + IDirect3D9Ex *d3d9Ex = nullptr; + typedef HRESULT(WINAPI * Direct3DCreate9ExFunc)(UINT, IDirect3D9Ex **); + Direct3DCreate9ExFunc Direct3DCreate9ExPtr = + reinterpret_cast(GetProcAddress(mD3d9Module, "Direct3DCreate9Ex")); + + if (Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &d3d9Ex))) + { + D3DCAPS9 deviceCaps; + HRESULT result = d3d9Ex->GetDeviceCaps(mAdapter, mDeviceType, &deviceCaps); + success = SUCCEEDED(result); + } + + SafeRelease(d3d9Ex); +#else + UNREACHABLE(); +#endif + + return success; +} + +bool Renderer9::resetRemovedDevice() +{ + // From http://msdn.microsoft.com/en-us/library/windows/desktop/bb172554(v=vs.85).aspx: + // The hardware adapter has been removed. Application must destroy the device, do enumeration of + // adapters and create another Direct3D device. If application continues rendering without + // calling Reset, the rendering calls will succeed. Applies to Direct3D 9Ex only. + release(); + return !initialize().isError(); +} + +VendorID Renderer9::getVendorId() const +{ + return static_cast(mAdapterIdentifier.VendorId); +} + +std::string Renderer9::getRendererDescription() const +{ + std::ostringstream rendererString; + + rendererString << mAdapterIdentifier.Description; + if (getShareHandleSupport()) + { + rendererString << " Direct3D9Ex"; + } + else + { + rendererString << " Direct3D9"; + } + + rendererString << " vs_" << D3DSHADER_VERSION_MAJOR(mDeviceCaps.VertexShaderVersion) << "_" + << D3DSHADER_VERSION_MINOR(mDeviceCaps.VertexShaderVersion); + rendererString << " ps_" << D3DSHADER_VERSION_MAJOR(mDeviceCaps.PixelShaderVersion) << "_" + << D3DSHADER_VERSION_MINOR(mDeviceCaps.PixelShaderVersion); + + return rendererString.str(); +} + +DeviceIdentifier Renderer9::getAdapterIdentifier() const +{ + DeviceIdentifier deviceIdentifier = {}; + deviceIdentifier.VendorId = static_cast(mAdapterIdentifier.VendorId); + deviceIdentifier.DeviceId = static_cast(mAdapterIdentifier.DeviceId); + deviceIdentifier.SubSysId = static_cast(mAdapterIdentifier.SubSysId); + deviceIdentifier.Revision = static_cast(mAdapterIdentifier.Revision); + deviceIdentifier.FeatureLevel = 0; + + return deviceIdentifier; +} + +unsigned int Renderer9::getReservedVertexUniformVectors() const +{ + return d3d9_gl::GetReservedVertexUniformVectors(); +} + +unsigned int Renderer9::getReservedFragmentUniformVectors() const +{ + return d3d9_gl::GetReservedFragmentUniformVectors(); +} + +bool Renderer9::getShareHandleSupport() const +{ + // PIX doesn't seem to support using share handles, so disable them. + return (mD3d9Ex != nullptr) && !gl::DebugAnnotationsActive(/*context=*/nullptr); +} + +int Renderer9::getMajorShaderModel() const +{ + return D3DSHADER_VERSION_MAJOR(mDeviceCaps.PixelShaderVersion); +} + +int Renderer9::getMinorShaderModel() const +{ + return D3DSHADER_VERSION_MINOR(mDeviceCaps.PixelShaderVersion); +} + +std::string Renderer9::getShaderModelSuffix() const +{ + return ""; +} + +DWORD Renderer9::getCapsDeclTypes() const +{ + return mDeviceCaps.DeclTypes; +} + +D3DPOOL Renderer9::getBufferPool(DWORD usage) const +{ + if (mD3d9Ex != nullptr) + { + return D3DPOOL_DEFAULT; + } + else + { + if (!(usage & D3DUSAGE_DYNAMIC)) + { + return D3DPOOL_MANAGED; + } + } + + return D3DPOOL_DEFAULT; +} + +angle::Result Renderer9::copyImage2D(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) +{ + RECT rect; + rect.left = sourceRect.x; + rect.top = sourceRect.y; + rect.right = sourceRect.x + sourceRect.width; + rect.bottom = sourceRect.y + sourceRect.height; + + return mBlit->copy2D(context, framebuffer, rect, destFormat, destOffset, storage, level); +} + +angle::Result Renderer9::copyImageCube(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + gl::TextureTarget target, + GLint level) +{ + RECT rect; + rect.left = sourceRect.x; + rect.top = sourceRect.y; + rect.right = sourceRect.x + sourceRect.width; + rect.bottom = sourceRect.y + sourceRect.height; + + return mBlit->copyCube(context, framebuffer, rect, destFormat, destOffset, storage, target, + level); +} + +angle::Result Renderer9::copyImage3D(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) +{ + // 3D textures are not available in the D3D9 backend. + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result Renderer9::copyImage2DArray(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) +{ + // 2D array textures are not available in the D3D9 backend. + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result Renderer9::copyTexture(const gl::Context *context, + const gl::Texture *source, + GLint sourceLevel, + gl::TextureTarget srcTarget, + const gl::Box &sourceBox, + GLenum destFormat, + GLenum destType, + const gl::Offset &destOffset, + TextureStorage *storage, + gl::TextureTarget destTarget, + GLint destLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) +{ + RECT rect; + rect.left = sourceBox.x; + rect.top = sourceBox.y; + rect.right = sourceBox.x + sourceBox.width; + rect.bottom = sourceBox.y + sourceBox.height; + + return mBlit->copyTexture(context, source, sourceLevel, rect, destFormat, destOffset, storage, + destTarget, destLevel, unpackFlipY, unpackPremultiplyAlpha, + unpackUnmultiplyAlpha); +} + +angle::Result Renderer9::copyCompressedTexture(const gl::Context *context, + const gl::Texture *source, + GLint sourceLevel, + TextureStorage *storage, + GLint destLevel) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result Renderer9::createRenderTarget(const gl::Context *context, + int width, + int height, + GLenum format, + GLsizei samples, + RenderTargetD3D **outRT) +{ + const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(format); + + const gl::TextureCaps &textureCaps = getNativeTextureCaps().get(format); + GLuint supportedSamples = textureCaps.getNearestSamples(samples); + + IDirect3DTexture9 *texture = nullptr; + IDirect3DSurface9 *renderTarget = nullptr; + if (width > 0 && height > 0) + { + bool requiresInitialization = false; + HRESULT result = D3DERR_INVALIDCALL; + + const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(format); + if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0) + { + result = mDevice->CreateDepthStencilSurface( + width, height, d3d9FormatInfo.renderFormat, + gl_d3d9::GetMultisampleType(supportedSamples), 0, FALSE, &renderTarget, nullptr); + } + else + { + requiresInitialization = (d3d9FormatInfo.dataInitializerFunction != nullptr); + if (supportedSamples > 0) + { + result = mDevice->CreateRenderTarget(width, height, d3d9FormatInfo.renderFormat, + gl_d3d9::GetMultisampleType(supportedSamples), + 0, FALSE, &renderTarget, nullptr); + } + else + { + result = mDevice->CreateTexture( + width, height, 1, D3DUSAGE_RENDERTARGET, d3d9FormatInfo.texFormat, + getTexturePool(D3DUSAGE_RENDERTARGET), &texture, nullptr); + if (!FAILED(result)) + { + result = texture->GetSurfaceLevel(0, &renderTarget); + } + } + } + + ANGLE_TRY_HR(GetImplAs(context), result, "Failed to create render target"); + + if (requiresInitialization) + { + // This format requires that the data be initialized before the render target can be + // used Unfortunately this requires a Get call on the d3d device but it is far better + // than having to mark the render target as lockable and copy data to the gpu. + IDirect3DSurface9 *prevRenderTarget = nullptr; + mDevice->GetRenderTarget(0, &prevRenderTarget); + mDevice->SetRenderTarget(0, renderTarget); + mDevice->Clear(0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 255), 0.0f, 0); + mDevice->SetRenderTarget(0, prevRenderTarget); + } + } + + *outRT = new TextureRenderTarget9(texture, 0, renderTarget, format, width, height, 1, + supportedSamples); + return angle::Result::Continue; +} + +angle::Result Renderer9::createRenderTargetCopy(const gl::Context *context, + RenderTargetD3D *source, + RenderTargetD3D **outRT) +{ + ASSERT(source != nullptr); + + RenderTargetD3D *newRT = nullptr; + ANGLE_TRY(createRenderTarget(context, source->getWidth(), source->getHeight(), + source->getInternalFormat(), source->getSamples(), &newRT)); + + RenderTarget9 *source9 = GetAs(source); + RenderTarget9 *dest9 = GetAs(newRT); + + HRESULT result = mDevice->StretchRect(source9->getSurface(), nullptr, dest9->getSurface(), + nullptr, D3DTEXF_NONE); + ANGLE_TRY_HR(GetImplAs(context), result, "Failed to copy render target"); + + *outRT = newRT; + return angle::Result::Continue; +} + +angle::Result Renderer9::loadExecutable(d3d::Context *context, + const uint8_t *function, + size_t length, + gl::ShaderType type, + const std::vector &streamOutVaryings, + bool separatedOutputBuffers, + ShaderExecutableD3D **outExecutable) +{ + // Transform feedback is not supported in ES2 or D3D9 + ASSERT(streamOutVaryings.empty()); + + switch (type) + { + case gl::ShaderType::Vertex: + { + IDirect3DVertexShader9 *vshader = nullptr; + ANGLE_TRY(createVertexShader(context, (DWORD *)function, length, &vshader)); + *outExecutable = new ShaderExecutable9(function, length, vshader); + } + break; + case gl::ShaderType::Fragment: + { + IDirect3DPixelShader9 *pshader = nullptr; + ANGLE_TRY(createPixelShader(context, (DWORD *)function, length, &pshader)); + *outExecutable = new ShaderExecutable9(function, length, pshader); + } + break; + default: + ANGLE_HR_UNREACHABLE(context); + } + + return angle::Result::Continue; +} + +angle::Result Renderer9::compileToExecutable(d3d::Context *context, + gl::InfoLog &infoLog, + const std::string &shaderHLSL, + gl::ShaderType type, + const std::vector &streamOutVaryings, + bool separatedOutputBuffers, + const CompilerWorkaroundsD3D &workarounds, + ShaderExecutableD3D **outExectuable) +{ + // Transform feedback is not supported in ES2 or D3D9 + ASSERT(streamOutVaryings.empty()); + + std::stringstream profileStream; + + switch (type) + { + case gl::ShaderType::Vertex: + profileStream << "vs"; + break; + case gl::ShaderType::Fragment: + profileStream << "ps"; + break; + default: + ANGLE_HR_UNREACHABLE(context); + } + + profileStream << "_" << ((getMajorShaderModel() >= 3) ? 3 : 2); + profileStream << "_" + << "0"; + + std::string profile = profileStream.str(); + + UINT flags = ANGLE_COMPILE_OPTIMIZATION_LEVEL; + + if (workarounds.skipOptimization) + { + flags = D3DCOMPILE_SKIP_OPTIMIZATION; + } + else if (workarounds.useMaxOptimization) + { + flags = D3DCOMPILE_OPTIMIZATION_LEVEL3; + } + + if (gl::DebugAnnotationsActive(/*context=*/nullptr)) + { +#ifndef NDEBUG + flags = D3DCOMPILE_SKIP_OPTIMIZATION; +#endif + + flags |= D3DCOMPILE_DEBUG; + } + + // Sometimes D3DCompile will fail with the default compilation flags for complicated shaders + // when it would otherwise pass with alternative options. Try the default flags first and if + // compilation fails, try some alternatives. + std::vector configs; + configs.push_back(CompileConfig(flags, "default")); + configs.push_back(CompileConfig(flags | D3DCOMPILE_AVOID_FLOW_CONTROL, "avoid flow control")); + configs.push_back(CompileConfig(flags | D3DCOMPILE_PREFER_FLOW_CONTROL, "prefer flow control")); + + ID3DBlob *binary = nullptr; + std::string debugInfo; + angle::Result error = mCompiler.compileToBinary(context, infoLog, shaderHLSL, profile, configs, + nullptr, &binary, &debugInfo); + ANGLE_TRY(error); + + // It's possible that binary is NULL if the compiler failed in all configurations. Set the + // executable to NULL and return GL_NO_ERROR to signify that there was a link error but the + // internal state is still OK. + if (!binary) + { + *outExectuable = nullptr; + return angle::Result::Continue; + } + + error = loadExecutable(context, reinterpret_cast(binary->GetBufferPointer()), + binary->GetBufferSize(), type, streamOutVaryings, separatedOutputBuffers, + outExectuable); + + SafeRelease(binary); + ANGLE_TRY(error); + + if (!debugInfo.empty()) + { + (*outExectuable)->appendDebugInfo(debugInfo); + } + + return angle::Result::Continue; +} + +angle::Result Renderer9::ensureHLSLCompilerInitialized(d3d::Context *context) +{ + return mCompiler.ensureInitialized(context); +} + +UniformStorageD3D *Renderer9::createUniformStorage(size_t storageSize) +{ + return new UniformStorageD3D(storageSize); +} + +angle::Result Renderer9::boxFilter(Context9 *context9, + IDirect3DSurface9 *source, + IDirect3DSurface9 *dest) +{ + return mBlit->boxFilter(context9, source, dest); +} + +D3DPOOL Renderer9::getTexturePool(DWORD usage) const +{ + if (mD3d9Ex != nullptr) + { + return D3DPOOL_DEFAULT; + } + else + { + if (!(usage & (D3DUSAGE_DEPTHSTENCIL | D3DUSAGE_RENDERTARGET))) + { + return D3DPOOL_MANAGED; + } + } + + return D3DPOOL_DEFAULT; +} + +angle::Result Renderer9::copyToRenderTarget(const gl::Context *context, + IDirect3DSurface9 *dest, + IDirect3DSurface9 *source, + bool fromManaged) +{ + ASSERT(source && dest); + + Context9 *context9 = GetImplAs(context); + + HRESULT result = D3DERR_OUTOFVIDEOMEMORY; + + if (fromManaged) + { + D3DSURFACE_DESC desc; + source->GetDesc(&desc); + + IDirect3DSurface9 *surf = 0; + result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, + D3DPOOL_SYSTEMMEM, &surf, nullptr); + + if (SUCCEEDED(result)) + { + ANGLE_TRY(Image9::CopyLockableSurfaces(context9, surf, source)); + result = mDevice->UpdateSurface(surf, nullptr, dest, nullptr); + SafeRelease(surf); + } + } + else + { + endScene(); + result = mDevice->StretchRect(source, nullptr, dest, nullptr, D3DTEXF_NONE); + } + + ANGLE_TRY_HR(context9, result, "Failed to blit internal texture"); + return angle::Result::Continue; +} + +RendererClass Renderer9::getRendererClass() const +{ + return RENDERER_D3D9; +} + +ImageD3D *Renderer9::createImage() +{ + return new Image9(this); +} + +ExternalImageSiblingImpl *Renderer9::createExternalImageSibling(const gl::Context *context, + EGLenum target, + EGLClientBuffer buffer, + const egl::AttributeMap &attribs) +{ + UNREACHABLE(); + return nullptr; +} + +angle::Result Renderer9::generateMipmap(const gl::Context *context, ImageD3D *dest, ImageD3D *src) +{ + Image9 *src9 = GetAs(src); + Image9 *dst9 = GetAs(dest); + return Image9::GenerateMipmap(GetImplAs(context), dst9, src9); +} + +angle::Result Renderer9::generateMipmapUsingD3D(const gl::Context *context, + TextureStorage *storage, + const gl::TextureState &textureState) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result Renderer9::copyImage(const gl::Context *context, + ImageD3D *dest, + ImageD3D *source, + const gl::Box &sourceBox, + const gl::Offset &destOffset, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) +{ + Image9 *dest9 = GetAs(dest); + Image9 *src9 = GetAs(source); + return Image9::CopyImage(context, dest9, src9, sourceBox.toRect(), destOffset, unpackFlipY, + unpackPremultiplyAlpha, unpackUnmultiplyAlpha); +} + +TextureStorage *Renderer9::createTextureStorage2D(SwapChainD3D *swapChain, const std::string &label) +{ + SwapChain9 *swapChain9 = GetAs(swapChain); + return new TextureStorage9_2D(this, swapChain9, label); +} + +TextureStorage *Renderer9::createTextureStorageEGLImage(EGLImageD3D *eglImage, + RenderTargetD3D *renderTargetD3D, + const std::string &label) +{ + return new TextureStorage9_EGLImage(this, eglImage, GetAs(renderTargetD3D), + label); +} + +TextureStorage *Renderer9::createTextureStorageBuffer( + const gl::OffsetBindingPointer &buffer, + GLenum internalFormat, + const std::string &label) +{ + UNREACHABLE(); + return nullptr; +} + +TextureStorage *Renderer9::createTextureStorageExternal( + egl::Stream *stream, + const egl::Stream::GLTextureDescription &desc, + const std::string &label) +{ + UNIMPLEMENTED(); + return nullptr; +} + +TextureStorage *Renderer9::createTextureStorage2D(GLenum internalformat, + BindFlags bindFlags, + GLsizei width, + GLsizei height, + int levels, + const std::string &label, + bool hintLevelZeroOnly) +{ + return new TextureStorage9_2D(this, internalformat, bindFlags.renderTarget, width, height, + levels, label); +} + +TextureStorage *Renderer9::createTextureStorageCube(GLenum internalformat, + BindFlags bindFlags, + int size, + int levels, + bool hintLevelZeroOnly, + const std::string &label) +{ + return new TextureStorage9_Cube(this, internalformat, bindFlags.renderTarget, size, levels, + hintLevelZeroOnly, label); +} + +TextureStorage *Renderer9::createTextureStorage3D(GLenum internalformat, + BindFlags bindFlags, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels, + const std::string &label) +{ + // 3D textures are not supported by the D3D9 backend. + UNREACHABLE(); + + return nullptr; +} + +TextureStorage *Renderer9::createTextureStorage2DArray(GLenum internalformat, + BindFlags bindFlags, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels, + const std::string &label) +{ + // 2D array textures are not supported by the D3D9 backend. + UNREACHABLE(); + + return nullptr; +} + +TextureStorage *Renderer9::createTextureStorage2DMultisample(GLenum internalformat, + GLsizei width, + GLsizei height, + int levels, + int samples, + bool fixedSampleLocations, + const std::string &label) +{ + // 2D multisampled textures are not supported by the D3D9 backend. + UNREACHABLE(); + + return nullptr; +} + +TextureStorage *Renderer9::createTextureStorage2DMultisampleArray(GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels, + int samples, + bool fixedSampleLocations, + const std::string &label) +{ + // 2D multisampled textures are not supported by the D3D9 backend. + UNREACHABLE(); + + return nullptr; +} + +bool Renderer9::getLUID(LUID *adapterLuid) const +{ + adapterLuid->HighPart = 0; + adapterLuid->LowPart = 0; + + if (mD3d9Ex) + { + mD3d9Ex->GetAdapterLUID(mAdapter, adapterLuid); + return true; + } + + return false; +} + +VertexConversionType Renderer9::getVertexConversionType(angle::FormatID vertexFormatID) const +{ + return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormatID).conversionType; +} + +GLenum Renderer9::getVertexComponentType(angle::FormatID vertexFormatID) const +{ + return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormatID).componentType; +} + +angle::Result Renderer9::getVertexSpaceRequired(const gl::Context *context, + const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + size_t count, + GLsizei instances, + GLuint baseInstance, + unsigned int *bytesRequiredOut) const +{ + if (!attrib.enabled) + { + *bytesRequiredOut = 16u; + return angle::Result::Continue; + } + + angle::FormatID vertexFormatID = gl::GetVertexFormatID(attrib, gl::VertexAttribType::Float); + const d3d9::VertexFormat &d3d9VertexInfo = + d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormatID); + + unsigned int elementCount = 0; + const unsigned int divisor = binding.getDivisor(); + if (instances == 0 || divisor == 0) + { + elementCount = static_cast(count); + } + else + { + // Round up to divisor, if possible + elementCount = UnsignedCeilDivide(static_cast(instances), divisor); + } + + bool check = (d3d9VertexInfo.outputElementSize > + std::numeric_limits::max() / elementCount); + ANGLE_CHECK(GetImplAs(context), !check, + "New vertex buffer size would result in an overflow.", GL_OUT_OF_MEMORY); + + *bytesRequiredOut = static_cast(d3d9VertexInfo.outputElementSize) * elementCount; + return angle::Result::Continue; +} + +void Renderer9::generateCaps(gl::Caps *outCaps, + gl::TextureCapsMap *outTextureCaps, + gl::Extensions *outExtensions, + gl::Limitations *outLimitations) const +{ + d3d9_gl::GenerateCaps(mD3d9, mDevice, mDeviceType, mAdapter, outCaps, outTextureCaps, + outExtensions, outLimitations); +} + +void Renderer9::initializeFeatures(angle::FeaturesD3D *features) const +{ + if (!mDisplay->getState().featuresAllDisabled) + { + d3d9::InitializeFeatures(features); + } + ApplyFeatureOverrides(features, mDisplay->getState()); +} + +void Renderer9::initializeFrontendFeatures(angle::FrontendFeatures *features) const {} + +DeviceImpl *Renderer9::createEGLDevice() +{ + return new DeviceD3D(EGL_D3D9_DEVICE_ANGLE, mDevice); +} + +Renderer9::CurSamplerState::CurSamplerState() + : forceSet(true), baseLevel(std::numeric_limits::max()), samplerState() +{} + +angle::Result Renderer9::genericDrawElements(const gl::Context *context, + gl::PrimitiveMode mode, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + GLsizei instances) +{ + const gl::State &state = context->getState(); + gl::Program *program = context->getState().getProgram(); + ASSERT(program != nullptr); + ProgramD3D *programD3D = GetImplAs(program); + bool usesPointSize = programD3D->usesPointSize(); + + programD3D->updateSamplerMapping(); + + if (!applyPrimitiveType(mode, count, usesPointSize)) + { + return angle::Result::Continue; + } + + ANGLE_TRY(updateState(context, mode)); + ANGLE_TRY(applyTextures(context)); + ANGLE_TRY(applyShaders(context, mode)); + + if (!skipDraw(state, mode)) + { + ANGLE_TRY(drawElementsImpl(context, mode, count, type, indices, instances)); + } + + return angle::Result::Continue; +} + +angle::Result Renderer9::genericDrawArrays(const gl::Context *context, + gl::PrimitiveMode mode, + GLint first, + GLsizei count, + GLsizei instances) +{ + gl::Program *program = context->getState().getProgram(); + ASSERT(program != nullptr); + ProgramD3D *programD3D = GetImplAs(program); + bool usesPointSize = programD3D->usesPointSize(); + + programD3D->updateSamplerMapping(); + + if (!applyPrimitiveType(mode, count, usesPointSize)) + { + return angle::Result::Continue; + } + + ANGLE_TRY(updateState(context, mode)); + ANGLE_TRY(applyVertexBuffer(context, mode, first, count, instances, nullptr)); + ANGLE_TRY(applyTextures(context)); + ANGLE_TRY(applyShaders(context, mode)); + + if (!skipDraw(context->getState(), mode)) + { + ANGLE_TRY(drawArraysImpl(context, mode, first, count, instances)); + } + + return angle::Result::Continue; +} + +FramebufferImpl *Renderer9::createDefaultFramebuffer(const gl::FramebufferState &state) +{ + return new Framebuffer9(state, this); +} + +gl::Version Renderer9::getMaxSupportedESVersion() const +{ + return gl::Version(2, 0); +} + +gl::Version Renderer9::getMaxConformantESVersion() const +{ + return gl::Version(2, 0); +} + +angle::Result Renderer9::clearRenderTarget(const gl::Context *context, + RenderTargetD3D *renderTarget, + const gl::ColorF &clearColorValue, + const float clearDepthValue, + const unsigned int clearStencilValue) +{ + D3DCOLOR color = + D3DCOLOR_ARGB(gl::unorm<8>(clearColorValue.alpha), gl::unorm<8>(clearColorValue.red), + gl::unorm<8>(clearColorValue.green), gl::unorm<8>(clearColorValue.blue)); + float depth = clearDepthValue; + DWORD stencil = clearStencilValue & 0x000000FF; + + unsigned int renderTargetSerial = renderTarget->getSerial(); + RenderTarget9 *renderTarget9 = GetAs(renderTarget); + IDirect3DSurface9 *renderTargetSurface = renderTarget9->getSurface(); + ASSERT(renderTargetSurface); + + DWORD dxClearFlags = 0; + + const gl::InternalFormat &internalFormatInfo = + gl::GetSizedInternalFormatInfo(renderTarget->getInternalFormat()); + if (internalFormatInfo.depthBits > 0 || internalFormatInfo.stencilBits > 0) + { + dxClearFlags = D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL; + if (mAppliedDepthStencilSerial != renderTargetSerial) + { + mDevice->SetDepthStencilSurface(renderTargetSurface); + } + } + else + { + dxClearFlags = D3DCLEAR_TARGET; + if (mAppliedRenderTargetSerial != renderTargetSerial) + { + mDevice->SetRenderTarget(0, renderTargetSurface); + } + } + SafeRelease(renderTargetSurface); + + D3DVIEWPORT9 viewport; + viewport.X = 0; + viewport.Y = 0; + viewport.Width = renderTarget->getWidth(); + viewport.Height = renderTarget->getHeight(); + mDevice->SetViewport(&viewport); + + mDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); + + mDevice->Clear(0, nullptr, dxClearFlags, color, depth, stencil); + + markAllStateDirty(); + + return angle::Result::Continue; +} + +bool Renderer9::canSelectViewInVertexShader() const +{ + return false; +} + +// For each Direct3D sampler of either the pixel or vertex stage, +// looks up the corresponding OpenGL texture image unit and texture type, +// and sets the texture and its addressing/filtering state (or NULL when inactive). +// Sampler mapping needs to be up-to-date on the program object before this is called. +angle::Result Renderer9::applyTextures(const gl::Context *context, gl::ShaderType shaderType) +{ + const auto &glState = context->getState(); + const auto &caps = context->getCaps(); + ProgramD3D *programD3D = GetImplAs(glState.getProgram()); + + ASSERT(!programD3D->isSamplerMappingDirty()); + + // TODO(jmadill): Use the Program's sampler bindings. + const gl::ActiveTexturesCache &activeTextures = glState.getActiveTexturesCache(); + + const gl::RangeUI samplerRange = programD3D->getUsedSamplerRange(shaderType); + for (unsigned int samplerIndex = samplerRange.low(); samplerIndex < samplerRange.high(); + samplerIndex++) + { + GLint textureUnit = programD3D->getSamplerMapping(shaderType, samplerIndex, caps); + ASSERT(textureUnit != -1); + gl::Texture *texture = activeTextures[textureUnit]; + + // A nullptr texture indicates incomplete. + if (texture) + { + gl::Sampler *samplerObject = glState.getSampler(textureUnit); + + const gl::SamplerState &samplerState = + samplerObject ? samplerObject->getSamplerState() : texture->getSamplerState(); + + ANGLE_TRY(setSamplerState(context, shaderType, samplerIndex, texture, samplerState)); + ANGLE_TRY(setTexture(context, shaderType, samplerIndex, texture)); + } + else + { + gl::TextureType textureType = + programD3D->getSamplerTextureType(shaderType, samplerIndex); + + // Texture is not sampler complete or it is in use by the framebuffer. Bind the + // incomplete texture. + gl::Texture *incompleteTexture = nullptr; + ANGLE_TRY(getIncompleteTexture(context, textureType, &incompleteTexture)); + ANGLE_TRY(setSamplerState(context, shaderType, samplerIndex, incompleteTexture, + incompleteTexture->getSamplerState())); + ANGLE_TRY(setTexture(context, shaderType, samplerIndex, incompleteTexture)); + } + } + + // Set all the remaining textures to NULL + int samplerCount = (shaderType == gl::ShaderType::Fragment) + ? caps.maxShaderTextureImageUnits[gl::ShaderType::Fragment] + : caps.maxShaderTextureImageUnits[gl::ShaderType::Vertex]; + + // TODO(jmadill): faster way? + for (int samplerIndex = samplerRange.high(); samplerIndex < samplerCount; samplerIndex++) + { + ANGLE_TRY(setTexture(context, shaderType, samplerIndex, nullptr)); + } + + return angle::Result::Continue; +} + +angle::Result Renderer9::applyTextures(const gl::Context *context) +{ + ANGLE_TRY(applyTextures(context, gl::ShaderType::Vertex)); + ANGLE_TRY(applyTextures(context, gl::ShaderType::Fragment)); + return angle::Result::Continue; +} + +angle::Result Renderer9::getIncompleteTexture(const gl::Context *context, + gl::TextureType type, + gl::Texture **textureOut) +{ + return GetImplAs(context)->getIncompleteTexture(context, type, textureOut); +} + +angle::Result Renderer9::ensureVertexDataManagerInitialized(const gl::Context *context) +{ + if (!mVertexDataManager) + { + mVertexDataManager = new VertexDataManager(this); + ANGLE_TRY(mVertexDataManager->initialize(context)); + } + + return angle::Result::Continue; +} + +std::string Renderer9::getVendorString() const +{ + return GetVendorString(getVendorId()); +} + +std::string Renderer9::getVersionString(bool includeFullVersion) const +{ + std::ostringstream versionString; + std::string driverName(mAdapterIdentifier.Driver); + if (!driverName.empty()) + { + versionString << mAdapterIdentifier.Driver; + } + else + { + versionString << "D3D9"; + } + + if (includeFullVersion) + { + versionString << " -"; + versionString << GetDriverVersionString(mAdapterIdentifier.DriverVersion); + } + + return versionString.str(); +} + +RendererD3D *CreateRenderer9(egl::Display *display) +{ + return new Renderer9(display); +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Renderer9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Renderer9.h new file mode 100644 index 0000000000..67a20f56ba --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Renderer9.h @@ -0,0 +1,586 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Renderer9.h: Defines a back-end specific class for the D3D9 renderer. + +#ifndef LIBANGLE_RENDERER_D3D_D3D9_RENDERER9_H_ +#define LIBANGLE_RENDERER_D3D_D3D9_RENDERER9_H_ + +#include "common/angleutils.h" +#include "common/mathutil.h" +#include "libANGLE/renderer/d3d/HLSLCompiler.h" +#include "libANGLE/renderer/d3d/RenderTargetD3D.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" +#include "libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h" +#include "libANGLE/renderer/d3d/d3d9/ShaderCache.h" +#include "libANGLE/renderer/d3d/d3d9/StateManager9.h" +#include "libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h" +#include "libANGLE/renderer/driver_utils.h" + +namespace gl +{ +class FramebufferAttachment; +} + +namespace egl +{ +class AttributeMap; +} + +namespace rx +{ +class Blit9; +class Context9; +class IndexDataManager; +class ProgramD3D; +class RenderTarget9; +class StreamingIndexBufferInterface; +class StaticIndexBufferInterface; +class VertexDataManager; +struct ClearParameters; +struct D3DUniform; +struct TranslatedAttribute; + +class Renderer9 : public RendererD3D +{ + public: + explicit Renderer9(egl::Display *display); + ~Renderer9() override; + + egl::Error initialize() override; + bool resetDevice() override; + + egl::ConfigSet generateConfigs() override; + void generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const override; + + void startScene(); + void endScene(); + + angle::Result flush(const gl::Context *context); + angle::Result finish(const gl::Context *context); + + bool isValidNativeWindow(EGLNativeWindowType window) const override; + NativeWindowD3D *createNativeWindow(EGLNativeWindowType window, + const egl::Config *config, + const egl::AttributeMap &attribs) const override; + + SwapChainD3D *createSwapChain(NativeWindowD3D *nativeWindow, + HANDLE shareHandle, + IUnknown *d3dTexture, + GLenum backBufferFormat, + GLenum depthBufferFormat, + EGLint orientation, + EGLint samples) override; + egl::Error getD3DTextureInfo(const egl::Config *configuration, + IUnknown *d3dTexture, + const egl::AttributeMap &attribs, + EGLint *width, + EGLint *height, + GLsizei *samples, + gl::Format *glFormat, + const angle::Format **angleFormat, + UINT *arraySlice) const override; + egl::Error validateShareHandle(const egl::Config *config, + HANDLE shareHandle, + const egl::AttributeMap &attribs) const override; + + ContextImpl *createContext(const gl::State &state, gl::ErrorSet *errorSet) override; + + angle::Result allocateEventQuery(const gl::Context *context, IDirect3DQuery9 **outQuery); + void freeEventQuery(IDirect3DQuery9 *query); + + // resource creation + angle::Result createVertexShader(d3d::Context *context, + const DWORD *function, + size_t length, + IDirect3DVertexShader9 **outShader); + angle::Result createPixelShader(d3d::Context *context, + const DWORD *function, + size_t length, + IDirect3DPixelShader9 **outShader); + HRESULT createVertexBuffer(UINT Length, DWORD Usage, IDirect3DVertexBuffer9 **ppVertexBuffer); + HRESULT createIndexBuffer(UINT Length, + DWORD Usage, + D3DFORMAT Format, + IDirect3DIndexBuffer9 **ppIndexBuffer); + angle::Result setSamplerState(const gl::Context *context, + gl::ShaderType type, + int index, + gl::Texture *texture, + const gl::SamplerState &sampler); + angle::Result setTexture(const gl::Context *context, + gl::ShaderType type, + int index, + gl::Texture *texture); + + angle::Result updateState(const gl::Context *context, gl::PrimitiveMode drawMode); + + void setScissorRectangle(const gl::Rectangle &scissor, bool enabled); + void setViewport(const gl::Rectangle &viewport, + float zNear, + float zFar, + gl::PrimitiveMode drawMode, + GLenum frontFace, + bool ignoreViewport); + + angle::Result applyRenderTarget(const gl::Context *context, + const RenderTarget9 *colorRenderTarget, + const RenderTarget9 *depthStencilRenderTarget); + void applyUniforms(ProgramD3D *programD3D); + bool applyPrimitiveType(gl::PrimitiveMode primitiveType, + GLsizei elementCount, + bool usesPointSize); + angle::Result applyVertexBuffer(const gl::Context *context, + gl::PrimitiveMode mode, + GLint first, + GLsizei count, + GLsizei instances, + TranslatedIndexData *indexInfo); + angle::Result applyIndexBuffer(const gl::Context *context, + const void *indices, + GLsizei count, + gl::PrimitiveMode mode, + gl::DrawElementsType type, + TranslatedIndexData *indexInfo); + + void clear(const ClearParameters &clearParams, + const RenderTarget9 *colorRenderTarget, + const RenderTarget9 *depthStencilRenderTarget); + + void markAllStateDirty(); + + // lost device + bool testDeviceLost() override; + bool testDeviceResettable() override; + + VendorID getVendorId() const; + DeviceIdentifier getAdapterIdentifier() const override; + + IDirect3DDevice9 *getDevice() { return mDevice; } + void *getD3DDevice() override; + + unsigned int getReservedVertexUniformVectors() const; + unsigned int getReservedFragmentUniformVectors() const; + + bool getShareHandleSupport() const; + + int getMajorShaderModel() const override; + int getMinorShaderModel() const override; + std::string getShaderModelSuffix() const override; + + DWORD getCapsDeclTypes() const; + + // Pixel operations + angle::Result copyImage2D(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) override; + angle::Result copyImageCube(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + gl::TextureTarget target, + GLint level) override; + angle::Result copyImage3D(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) override; + angle::Result copyImage2DArray(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) override; + + angle::Result copyTexture(const gl::Context *context, + const gl::Texture *source, + GLint sourceLevel, + gl::TextureTarget srcTarget, + const gl::Box &sourceBox, + GLenum destFormat, + GLenum destType, + const gl::Offset &destOffset, + TextureStorage *storage, + gl::TextureTarget destTarget, + GLint destLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) override; + angle::Result copyCompressedTexture(const gl::Context *context, + const gl::Texture *source, + GLint sourceLevel, + TextureStorage *storage, + GLint destLevel) override; + + // RenderTarget creation + angle::Result createRenderTarget(const gl::Context *context, + int width, + int height, + GLenum format, + GLsizei samples, + RenderTargetD3D **outRT) override; + angle::Result createRenderTargetCopy(const gl::Context *context, + RenderTargetD3D *source, + RenderTargetD3D **outRT) override; + + // Shader operations + angle::Result loadExecutable(d3d::Context *context, + const uint8_t *function, + size_t length, + gl::ShaderType type, + const std::vector &streamOutVaryings, + bool separatedOutputBuffers, + ShaderExecutableD3D **outExecutable) override; + angle::Result compileToExecutable(d3d::Context *context, + gl::InfoLog &infoLog, + const std::string &shaderHLSL, + gl::ShaderType type, + const std::vector &streamOutVaryings, + bool separatedOutputBuffers, + const CompilerWorkaroundsD3D &workarounds, + ShaderExecutableD3D **outExectuable) override; + angle::Result ensureHLSLCompilerInitialized(d3d::Context *context) override; + + UniformStorageD3D *createUniformStorage(size_t storageSize) override; + + // Image operations + ImageD3D *createImage() override; + ExternalImageSiblingImpl *createExternalImageSibling(const gl::Context *context, + EGLenum target, + EGLClientBuffer buffer, + const egl::AttributeMap &attribs) override; + angle::Result generateMipmap(const gl::Context *context, + ImageD3D *dest, + ImageD3D *source) override; + angle::Result generateMipmapUsingD3D(const gl::Context *context, + TextureStorage *storage, + const gl::TextureState &textureState) override; + angle::Result copyImage(const gl::Context *context, + ImageD3D *dest, + ImageD3D *source, + const gl::Box &sourceBox, + const gl::Offset &destOffset, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) override; + TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain, + const std::string &label) override; + TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage, + RenderTargetD3D *renderTargetD3D, + const std::string &label) override; + + TextureStorage *createTextureStorageBuffer(const gl::OffsetBindingPointer &buffer, + GLenum internalFormat, + const std::string &label) override; + + TextureStorage *createTextureStorageExternal(egl::Stream *stream, + const egl::Stream::GLTextureDescription &desc, + const std::string &label) override; + + TextureStorage *createTextureStorage2D(GLenum internalformat, + BindFlags bindFlags, + GLsizei width, + GLsizei height, + int levels, + const std::string &label, + bool hintLevelZeroOnly) override; + TextureStorage *createTextureStorageCube(GLenum internalformat, + BindFlags bindFlags, + int size, + int levels, + bool hintLevelZeroOnly, + const std::string &label) override; + TextureStorage *createTextureStorage3D(GLenum internalformat, + BindFlags bindFlags, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels, + const std::string &label) override; + TextureStorage *createTextureStorage2DArray(GLenum internalformat, + BindFlags bindFlags, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels, + const std::string &label) override; + + TextureStorage *createTextureStorage2DMultisample(GLenum internalformat, + GLsizei width, + GLsizei height, + int levels, + int samples, + bool fixedSampleLocations, + const std::string &label) override; + TextureStorage *createTextureStorage2DMultisampleArray(GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels, + int samples, + bool fixedSampleLocations, + const std::string &label) override; + + // Buffer creation + VertexBuffer *createVertexBuffer() override; + IndexBuffer *createIndexBuffer() override; + + // Stream Creation + StreamProducerImpl *createStreamProducerD3DTexture(egl::Stream::ConsumerType consumerType, + const egl::AttributeMap &attribs) override; + + // Buffer-to-texture and Texture-to-buffer copies + bool supportsFastCopyBufferToTexture(GLenum internalFormat) const override; + angle::Result fastCopyBufferToTexture(const gl::Context *context, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + unsigned int offset, + RenderTargetD3D *destRenderTarget, + GLenum destinationFormat, + GLenum sourcePixelsType, + const gl::Box &destArea) override; + + // D3D9-renderer specific methods + angle::Result boxFilter(Context9 *context9, IDirect3DSurface9 *source, IDirect3DSurface9 *dest); + + D3DPOOL getTexturePool(DWORD usage) const; + + bool getLUID(LUID *adapterLuid) const override; + VertexConversionType getVertexConversionType(angle::FormatID vertexFormatID) const override; + GLenum getVertexComponentType(angle::FormatID vertexFormatID) const override; + + // Warning: you should ensure binding really matches attrib.bindingIndex before using this + // function. + angle::Result getVertexSpaceRequired(const gl::Context *context, + const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + size_t count, + GLsizei instances, + GLuint baseInstance, + unsigned int *bytesRequiredOut) const override; + + angle::Result copyToRenderTarget(const gl::Context *context, + IDirect3DSurface9 *dest, + IDirect3DSurface9 *source, + bool fromManaged); + + RendererClass getRendererClass() const override; + + D3DDEVTYPE getD3D9DeviceType() const { return mDeviceType; } + + DeviceImpl *createEGLDevice() override; + + StateManager9 *getStateManager() { return &mStateManager; } + + angle::Result genericDrawArrays(const gl::Context *context, + gl::PrimitiveMode mode, + GLint first, + GLsizei count, + GLsizei instances); + + angle::Result genericDrawElements(const gl::Context *context, + gl::PrimitiveMode mode, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + GLsizei instances); + + // Necessary hack for default framebuffers in D3D. + FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) override; + + DebugAnnotator9 *getAnnotator() { return &mAnnotator; } + + gl::Version getMaxSupportedESVersion() const override; + gl::Version getMaxConformantESVersion() const override; + + angle::Result clearRenderTarget(const gl::Context *context, + RenderTargetD3D *renderTarget, + const gl::ColorF &clearColorValue, + const float clearDepthValue, + const unsigned int clearStencilValue) override; + + bool canSelectViewInVertexShader() const override; + + angle::Result getIncompleteTexture(const gl::Context *context, + gl::TextureType type, + gl::Texture **textureOut) override; + + angle::Result ensureVertexDataManagerInitialized(const gl::Context *context); + + void setGlobalDebugAnnotator() override; + + std::string getRendererDescription() const override; + std::string getVendorString() const override; + std::string getVersionString(bool includeFullVersion) const override; + + private: + angle::Result drawArraysImpl(const gl::Context *context, + gl::PrimitiveMode mode, + GLint startVertex, + GLsizei count, + GLsizei instances); + angle::Result drawElementsImpl(const gl::Context *context, + gl::PrimitiveMode mode, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + GLsizei instances); + + angle::Result applyShaders(const gl::Context *context, gl::PrimitiveMode drawMode); + + angle::Result applyTextures(const gl::Context *context); + angle::Result applyTextures(const gl::Context *context, gl::ShaderType shaderType); + + void generateCaps(gl::Caps *outCaps, + gl::TextureCapsMap *outTextureCaps, + gl::Extensions *outExtensions, + gl::Limitations *outLimitations) const override; + + void initializeFeatures(angle::FeaturesD3D *features) const override; + + void initializeFrontendFeatures(angle::FrontendFeatures *features) const override; + + angle::Result setBlendDepthRasterStates(const gl::Context *context, gl::PrimitiveMode drawMode); + + void release(); + + void applyUniformnfv(const D3DUniform *targetUniform, const GLfloat *v); + void applyUniformniv(const D3DUniform *targetUniform, const GLint *v); + void applyUniformnbv(const D3DUniform *targetUniform, const GLint *v); + + angle::Result drawLineLoop(const gl::Context *context, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + int minIndex, + gl::Buffer *elementArrayBuffer); + angle::Result drawIndexedPoints(const gl::Context *context, + GLsizei count, + gl::DrawElementsType type, + const void *indices, + int minIndex, + gl::Buffer *elementArrayBuffer); + + angle::Result getCountingIB(const gl::Context *context, + size_t count, + StaticIndexBufferInterface **outIB); + + angle::Result getNullColorRenderTarget(const gl::Context *context, + const RenderTarget9 *depthRenderTarget, + const RenderTarget9 **outColorRenderTarget); + + D3DPOOL getBufferPool(DWORD usage) const; + + HMODULE mD3d9Module; + + egl::Error initializeDevice(); + D3DPRESENT_PARAMETERS getDefaultPresentParameters(); + void releaseDeviceResources(); + + HRESULT getDeviceStatusCode(); + bool isRemovedDeviceResettable() const; + bool resetRemovedDevice(); + + UINT mAdapter; + D3DDEVTYPE mDeviceType; + IDirect3D9 *mD3d9; // Always valid after successful initialization. + IDirect3D9Ex *mD3d9Ex; // Might be null if D3D9Ex is not supported. + IDirect3DDevice9 *mDevice; + IDirect3DDevice9Ex *mDeviceEx; // Might be null if D3D9Ex is not supported. + + HLSLCompiler mCompiler; + + Blit9 *mBlit; + + HWND mDeviceWindow; + + D3DCAPS9 mDeviceCaps; + D3DADAPTER_IDENTIFIER9 mAdapterIdentifier; + + D3DPRIMITIVETYPE mPrimitiveType; + int mPrimitiveCount; + GLsizei mRepeatDraw; + + bool mSceneStarted; + + bool mVertexTextureSupport; + + // current render target states + unsigned int mAppliedRenderTargetSerial; + unsigned int mAppliedDepthStencilSerial; + bool mDepthStencilInitialized; + bool mRenderTargetDescInitialized; + + IDirect3DStateBlock9 *mMaskedClearSavedState; + + StateManager9 mStateManager; + + // Currently applied sampler states + struct CurSamplerState + { + CurSamplerState(); + + bool forceSet; + size_t baseLevel; + gl::SamplerState samplerState; + }; + std::vector mCurVertexSamplerStates; + std::vector mCurPixelSamplerStates; + + // Currently applied textures + std::vector mCurVertexTextures; + std::vector mCurPixelTextures; + + unsigned int mAppliedIBSerial; + IDirect3DVertexShader9 *mAppliedVertexShader; + IDirect3DPixelShader9 *mAppliedPixelShader; + unsigned int mAppliedProgramSerial; + + // A pool of event queries that are currently unused. + std::vector mEventQueryPool; + VertexShaderCache mVertexShaderCache; + PixelShaderCache mPixelShaderCache; + + VertexDataManager *mVertexDataManager; + VertexDeclarationCache mVertexDeclarationCache; + + IndexDataManager *mIndexDataManager; + StreamingIndexBufferInterface *mLineLoopIB; + StaticIndexBufferInterface *mCountingIB; + + enum + { + NUM_NULL_COLORBUFFER_CACHE_ENTRIES = 12 + }; + struct NullRenderTargetCacheEntry + { + UINT lruCount; + int width; + int height; + RenderTarget9 *renderTarget; + }; + + std::array + mNullRenderTargetCache; + UINT mMaxNullColorbufferLRU; + + std::vector mTranslatedAttribCache; + + DebugAnnotator9 mAnnotator; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D9_RENDERER9_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/ShaderCache.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/ShaderCache.h new file mode 100644 index 0000000000..bd1a4cf269 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/ShaderCache.h @@ -0,0 +1,110 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ShaderCache: Defines rx::ShaderCache, a cache of Direct3D shader objects +// keyed by their byte code. + +#ifndef LIBANGLE_RENDERER_D3D_D3D9_SHADERCACHE_H_ +#define LIBANGLE_RENDERER_D3D_D3D9_SHADERCACHE_H_ + +#include "libANGLE/Error.h" + +#include "common/debug.h" +#include "libANGLE/renderer/d3d/d3d9/Context9.h" + +#include +#include +#include +#include + +namespace rx +{ +template +class ShaderCache : angle::NonCopyable +{ + public: + ShaderCache() : mDevice(nullptr) {} + + ~ShaderCache() + { + // Call clear while the device is still valid. + ASSERT(mMap.empty()); + } + + void initialize(IDirect3DDevice9 *device) { mDevice = device; } + + angle::Result create(d3d::Context *context, + const DWORD *function, + size_t length, + ShaderObject **outShaderObject) + { + std::lock_guard lock(mMutex); + + std::string key(reinterpret_cast(function), length); + typename Map::iterator it = mMap.find(key); + if (it != mMap.end()) + { + it->second->AddRef(); + *outShaderObject = it->second; + return angle::Result::Continue; + } + + ShaderObject *shader; + HRESULT result = createShader(function, &shader); + ANGLE_TRY_HR(context, result, "Failed to create shader"); + + // Random eviction policy. + if (mMap.size() >= kMaxMapSize) + { + SafeRelease(mMap.begin()->second); + mMap.erase(mMap.begin()); + } + + shader->AddRef(); + mMap[key] = shader; + + *outShaderObject = shader; + return angle::Result::Continue; + } + + void clear() + { + std::lock_guard lock(mMutex); + + for (typename Map::iterator it = mMap.begin(); it != mMap.end(); ++it) + { + SafeRelease(it->second); + } + + mMap.clear(); + } + + private: + const static size_t kMaxMapSize = 100; + + HRESULT createShader(const DWORD *function, IDirect3DVertexShader9 **shader) + { + return mDevice->CreateVertexShader(function, shader); + } + + HRESULT createShader(const DWORD *function, IDirect3DPixelShader9 **shader) + { + return mDevice->CreatePixelShader(function, shader); + } + + typedef angle::HashMap Map; + Map mMap; + std::mutex mMutex; + + IDirect3DDevice9 *mDevice; +}; + +typedef ShaderCache VertexShaderCache; +typedef ShaderCache PixelShaderCache; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D9_SHADERCACHE_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp new file mode 100644 index 0000000000..b5c237f9a7 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp @@ -0,0 +1,51 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ShaderExecutable9.cpp: Implements a D3D9-specific class to contain shader +// executable implementation details. + +#include "libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h" + +#include "common/debug.h" + +namespace rx +{ + +ShaderExecutable9::ShaderExecutable9(const void *function, + size_t length, + IDirect3DPixelShader9 *executable) + : ShaderExecutableD3D(function, length) +{ + mPixelExecutable = executable; + mVertexExecutable = nullptr; +} + +ShaderExecutable9::ShaderExecutable9(const void *function, + size_t length, + IDirect3DVertexShader9 *executable) + : ShaderExecutableD3D(function, length) +{ + mVertexExecutable = executable; + mPixelExecutable = nullptr; +} + +ShaderExecutable9::~ShaderExecutable9() +{ + SafeRelease(mVertexExecutable); + SafeRelease(mPixelExecutable); +} + +IDirect3DVertexShader9 *ShaderExecutable9::getVertexShader() const +{ + return mVertexExecutable; +} + +IDirect3DPixelShader9 *ShaderExecutable9::getPixelShader() const +{ + return mPixelExecutable; +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h new file mode 100644 index 0000000000..0c8c595ef0 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h @@ -0,0 +1,35 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ShaderExecutable9.h: Defines a D3D9-specific class to contain shader +// executable implementation details. + +#ifndef LIBANGLE_RENDERER_D3D_D3D9_SHADEREXECUTABLE9_H_ +#define LIBANGLE_RENDERER_D3D_D3D9_SHADEREXECUTABLE9_H_ + +#include "libANGLE/renderer/d3d/ShaderExecutableD3D.h" + +namespace rx +{ + +class ShaderExecutable9 : public ShaderExecutableD3D +{ + public: + ShaderExecutable9(const void *function, size_t length, IDirect3DPixelShader9 *executable); + ShaderExecutable9(const void *function, size_t length, IDirect3DVertexShader9 *executable); + ~ShaderExecutable9() override; + + IDirect3DPixelShader9 *getPixelShader() const; + IDirect3DVertexShader9 *getVertexShader() const; + + private: + IDirect3DPixelShader9 *mPixelExecutable; + IDirect3DVertexShader9 *mVertexExecutable; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D9_SHADEREXECUTABLE9_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp new file mode 100644 index 0000000000..cad011b25a --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp @@ -0,0 +1,888 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// StateManager9.cpp: Defines a class for caching D3D9 state +#include "libANGLE/renderer/d3d/d3d9/StateManager9.h" + +#include "common/bitset_utils.h" +#include "common/utilities.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/d3d9/Framebuffer9.h" +#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" +#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" + +namespace rx +{ + +StateManager9::StateManager9(Renderer9 *renderer9) + : mUsingZeroColorMaskWorkaround(false), + mCurSampleAlphaToCoverage(false), + mCurBlendState(), + mCurBlendColor(0, 0, 0, 0), + mCurSampleMask(0), + mCurRasterState(), + mCurDepthSize(0), + mCurDepthStencilState(), + mCurStencilRef(0), + mCurStencilBackRef(0), + mCurFrontFaceCCW(0), + mCurStencilSize(0), + mCurScissorRect(), + mCurScissorEnabled(false), + mCurViewport(), + mCurNear(0.0f), + mCurFar(0.0f), + mCurDepthFront(0.0f), + mCurIgnoreViewport(false), + mRenderer9(renderer9), + mDirtyBits() +{ + mBlendStateDirtyBits.set(DIRTY_BIT_BLEND_ENABLED); + mBlendStateDirtyBits.set(DIRTY_BIT_BLEND_COLOR); + mBlendStateDirtyBits.set(DIRTY_BIT_BLEND_FUNCS_EQUATIONS); + mBlendStateDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE); + mBlendStateDirtyBits.set(DIRTY_BIT_COLOR_MASK); + mBlendStateDirtyBits.set(DIRTY_BIT_DITHER); + mBlendStateDirtyBits.set(DIRTY_BIT_SAMPLE_MASK); + + mRasterizerStateDirtyBits.set(DIRTY_BIT_CULL_MODE); + mRasterizerStateDirtyBits.set(DIRTY_BIT_DEPTH_BIAS); + + mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_DEPTH_MASK); + mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_DEPTH_FUNC); + mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED); + mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT); + mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK); + mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT); + mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK); + mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT); + mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK); + + mScissorStateDirtyBits.set(DIRTY_BIT_SCISSOR_ENABLED); + mScissorStateDirtyBits.set(DIRTY_BIT_SCISSOR_RECT); +} + +StateManager9::~StateManager9() {} + +void StateManager9::initialize() +{ + mUsingZeroColorMaskWorkaround = IsAMD(mRenderer9->getVendorId()); +} + +void StateManager9::forceSetBlendState() +{ + mDirtyBits |= mBlendStateDirtyBits; +} + +void StateManager9::forceSetRasterState() +{ + mDirtyBits |= mRasterizerStateDirtyBits; +} + +void StateManager9::forceSetDepthStencilState() +{ + mDirtyBits |= mDepthStencilStateDirtyBits; +} + +void StateManager9::forceSetScissorState() +{ + mDirtyBits |= mScissorStateDirtyBits; +} + +void StateManager9::forceSetViewportState() +{ + mForceSetViewport = true; +} + +void StateManager9::forceSetDXUniformsState() +{ + mDxUniformsDirty = true; +} + +void StateManager9::updateStencilSizeIfChanged(bool depthStencilInitialized, + unsigned int stencilSize) +{ + if (!depthStencilInitialized || stencilSize != mCurStencilSize) + { + mCurStencilSize = stencilSize; + forceSetDepthStencilState(); + } +} + +void StateManager9::syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits) +{ + if (!dirtyBits.any()) + { + return; + } + + for (auto dirtyBit : dirtyBits) + { + switch (dirtyBit) + { + case gl::State::DIRTY_BIT_BLEND_ENABLED: + if (state.getBlendState().blend != mCurBlendState.blend) + { + mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED); + // BlendColor and funcs and equations has to be set if blend is enabled + mDirtyBits.set(DIRTY_BIT_BLEND_COLOR); + mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS_EQUATIONS); + + // The color mask may have to be updated if the blend state changes + if (mUsingZeroColorMaskWorkaround) + { + mDirtyBits.set(DIRTY_BIT_COLOR_MASK); + } + } + break; + case gl::State::DIRTY_BIT_BLEND_FUNCS: + { + const gl::BlendState &blendState = state.getBlendState(); + if (blendState.sourceBlendRGB != mCurBlendState.sourceBlendRGB || + blendState.destBlendRGB != mCurBlendState.destBlendRGB || + blendState.sourceBlendAlpha != mCurBlendState.sourceBlendAlpha || + blendState.destBlendAlpha != mCurBlendState.destBlendAlpha) + { + mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS_EQUATIONS); + // BlendColor depends on the values of blend funcs + mDirtyBits.set(DIRTY_BIT_BLEND_COLOR); + + // The color mask may have to be updated if the blend funcs change + if (mUsingZeroColorMaskWorkaround) + { + mDirtyBits.set(DIRTY_BIT_COLOR_MASK); + } + } + break; + } + case gl::State::DIRTY_BIT_BLEND_EQUATIONS: + { + const gl::BlendState &blendState = state.getBlendState(); + if (blendState.blendEquationRGB != mCurBlendState.blendEquationRGB || + blendState.blendEquationAlpha != mCurBlendState.blendEquationAlpha) + { + mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS_EQUATIONS); + + // The color mask may have to be updated if the blend funcs change + if (mUsingZeroColorMaskWorkaround) + { + mDirtyBits.set(DIRTY_BIT_COLOR_MASK); + } + } + break; + } + case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED: + if (state.isSampleAlphaToCoverageEnabled() != mCurSampleAlphaToCoverage) + { + mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE); + } + break; + case gl::State::DIRTY_BIT_COLOR_MASK: + { + const gl::BlendState &blendState = state.getBlendState(); + if (blendState.colorMaskRed != mCurBlendState.colorMaskRed || + blendState.colorMaskGreen != mCurBlendState.colorMaskGreen || + blendState.colorMaskBlue != mCurBlendState.colorMaskBlue || + blendState.colorMaskAlpha != mCurBlendState.colorMaskAlpha) + { + mDirtyBits.set(DIRTY_BIT_COLOR_MASK); + + // The color mask can cause the blend state to get out of sync when using the + // zero color mask workaround + if (mUsingZeroColorMaskWorkaround) + { + mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED); + mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS_EQUATIONS); + } + } + break; + } + case gl::State::DIRTY_BIT_DITHER_ENABLED: + if (state.getRasterizerState().dither != mCurRasterState.dither) + { + mDirtyBits.set(DIRTY_BIT_DITHER); + } + break; + case gl::State::DIRTY_BIT_BLEND_COLOR: + if (state.getBlendColor() != mCurBlendColor) + { + mDirtyBits.set(DIRTY_BIT_BLEND_COLOR); + } + break; + case gl::State::DIRTY_BIT_CULL_FACE_ENABLED: + if (state.getRasterizerState().cullFace != mCurRasterState.cullFace) + { + mDirtyBits.set(DIRTY_BIT_CULL_MODE); + } + break; + case gl::State::DIRTY_BIT_CULL_FACE: + if (state.getRasterizerState().cullMode != mCurRasterState.cullMode) + { + mDirtyBits.set(DIRTY_BIT_CULL_MODE); + } + break; + case gl::State::DIRTY_BIT_FRONT_FACE: + if (state.getRasterizerState().frontFace != mCurRasterState.frontFace) + { + mDirtyBits.set(DIRTY_BIT_CULL_MODE); + + // Viewport state depends on rasterizer.frontface + mDirtyBits.set(DIRTY_BIT_VIEWPORT); + } + break; + case gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED: + if (state.getRasterizerState().polygonOffsetFill != + mCurRasterState.polygonOffsetFill) + { + mDirtyBits.set(DIRTY_BIT_DEPTH_BIAS); + } + break; + case gl::State::DIRTY_BIT_POLYGON_OFFSET: + { + const gl::RasterizerState &rasterizerState = state.getRasterizerState(); + if (rasterizerState.polygonOffsetFactor != mCurRasterState.polygonOffsetFactor || + rasterizerState.polygonOffsetUnits != mCurRasterState.polygonOffsetUnits) + { + mDirtyBits.set(DIRTY_BIT_DEPTH_BIAS); + } + break; + } + // Depth and stencil redundant state changes are guarded in the + // frontend so for related cases here just set the dirty bit. + case gl::State::DIRTY_BIT_DEPTH_MASK: + if (state.getDepthStencilState().depthMask != mCurDepthStencilState.depthMask) + { + mDirtyBits.set(DIRTY_BIT_STENCIL_DEPTH_MASK); + } + break; + case gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED: + mDirtyBits.set(DIRTY_BIT_STENCIL_DEPTH_FUNC); + break; + case gl::State::DIRTY_BIT_DEPTH_FUNC: + mDirtyBits.set(DIRTY_BIT_STENCIL_DEPTH_FUNC); + break; + case gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED: + mDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED); + // If we enable the stencil test, all of these must be set + mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK); + mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT); + mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT); + mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK); + mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT); + mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK); + break; + case gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT: + mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT); + break; + case gl::State::DIRTY_BIT_STENCIL_FUNCS_BACK: + mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK); + break; + case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT: + mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT); + break; + case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK: + mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK); + break; + case gl::State::DIRTY_BIT_STENCIL_OPS_FRONT: + mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT); + break; + case gl::State::DIRTY_BIT_STENCIL_OPS_BACK: + mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK); + break; + case gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED: + if (state.isScissorTestEnabled() != mCurScissorEnabled) + { + mDirtyBits.set(DIRTY_BIT_SCISSOR_ENABLED); + // If scissor is enabled, we have to set the scissor rect + mDirtyBits.set(DIRTY_BIT_SCISSOR_RECT); + } + break; + case gl::State::DIRTY_BIT_SCISSOR: + if (state.getScissor() != mCurScissorRect) + { + mDirtyBits.set(DIRTY_BIT_SCISSOR_RECT); + } + break; + case gl::State::DIRTY_BIT_DEPTH_RANGE: + mDirtyBits.set(DIRTY_BIT_VIEWPORT); + break; + case gl::State::DIRTY_BIT_VIEWPORT: + if (state.getViewport() != mCurViewport) + { + mDirtyBits.set(DIRTY_BIT_VIEWPORT); + } + break; + default: + break; + } + } +} + +void StateManager9::setBlendDepthRasterStates(const gl::State &glState, unsigned int sampleMask) +{ + const gl::Framebuffer *framebuffer = glState.getDrawFramebuffer(); + + const gl::BlendState &blendState = glState.getBlendState(); + const gl::ColorF &blendColor = glState.getBlendColor(); + const gl::RasterizerState &rasterState = glState.getRasterizerState(); + + const auto &depthStencilState = glState.getDepthStencilState(); + bool frontFaceCCW = (glState.getRasterizerState().frontFace == GL_CCW); + unsigned int maxStencil = (1 << mCurStencilSize) - 1; + + // All the depth stencil states depends on the front face ccw variable + if (frontFaceCCW != mCurFrontFaceCCW) + { + forceSetDepthStencilState(); + mCurFrontFaceCCW = frontFaceCCW; + } + + for (auto dirtyBit : mDirtyBits) + { + switch (dirtyBit) + { + case DIRTY_BIT_BLEND_ENABLED: + setBlendEnabled(blendState.blend); + break; + case DIRTY_BIT_BLEND_COLOR: + setBlendColor(blendState, blendColor); + break; + case DIRTY_BIT_BLEND_FUNCS_EQUATIONS: + setBlendFuncsEquations(blendState); + break; + case DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE: + setSampleAlphaToCoverage(glState.isSampleAlphaToCoverageEnabled()); + break; + case DIRTY_BIT_COLOR_MASK: + setColorMask(framebuffer, blendState.colorMaskRed, blendState.colorMaskBlue, + blendState.colorMaskGreen, blendState.colorMaskAlpha); + break; + case DIRTY_BIT_DITHER: + setDither(rasterState.dither); + break; + case DIRTY_BIT_CULL_MODE: + setCullMode(rasterState.cullFace, rasterState.cullMode, rasterState.frontFace); + break; + case DIRTY_BIT_DEPTH_BIAS: + setDepthBias(rasterState.polygonOffsetFill, rasterState.polygonOffsetFactor, + rasterState.polygonOffsetUnits); + break; + case DIRTY_BIT_STENCIL_DEPTH_MASK: + setDepthMask(depthStencilState.depthMask); + break; + case DIRTY_BIT_STENCIL_DEPTH_FUNC: + setDepthFunc(depthStencilState.depthTest, depthStencilState.depthFunc); + break; + case DIRTY_BIT_STENCIL_TEST_ENABLED: + setStencilTestEnabled(depthStencilState.stencilTest); + break; + case DIRTY_BIT_STENCIL_FUNCS_FRONT: + setStencilFuncsFront(depthStencilState.stencilFunc, depthStencilState.stencilMask, + glState.getStencilRef(), frontFaceCCW, maxStencil); + break; + case DIRTY_BIT_STENCIL_FUNCS_BACK: + setStencilFuncsBack(depthStencilState.stencilBackFunc, + depthStencilState.stencilBackMask, glState.getStencilBackRef(), + frontFaceCCW, maxStencil); + break; + case DIRTY_BIT_STENCIL_WRITEMASK_FRONT: + setStencilWriteMask(depthStencilState.stencilWritemask, frontFaceCCW); + break; + case DIRTY_BIT_STENCIL_WRITEMASK_BACK: + setStencilBackWriteMask(depthStencilState.stencilBackWritemask, frontFaceCCW); + break; + case DIRTY_BIT_STENCIL_OPS_FRONT: + setStencilOpsFront(depthStencilState.stencilFail, + depthStencilState.stencilPassDepthFail, + depthStencilState.stencilPassDepthPass, frontFaceCCW); + break; + case DIRTY_BIT_STENCIL_OPS_BACK: + setStencilOpsBack(depthStencilState.stencilBackFail, + depthStencilState.stencilBackPassDepthFail, + depthStencilState.stencilBackPassDepthPass, frontFaceCCW); + break; + default: + break; + } + } + + if (sampleMask != mCurSampleMask) + { + setSampleMask(sampleMask); + } +} + +void StateManager9::setViewportState(const gl::Rectangle &viewport, + float zNear, + float zFar, + gl::PrimitiveMode drawMode, + GLenum frontFace, + bool ignoreViewport) +{ + if (!mDirtyBits.test(DIRTY_BIT_VIEWPORT) && mCurIgnoreViewport == ignoreViewport) + return; + + gl::Rectangle actualViewport = viewport; + float actualZNear = gl::clamp01(zNear); + float actualZFar = gl::clamp01(zFar); + + if (ignoreViewport) + { + actualViewport.x = 0; + actualViewport.y = 0; + actualViewport.width = static_cast(mRenderTargetBounds.width); + actualViewport.height = static_cast(mRenderTargetBounds.height); + actualZNear = 0.0f; + actualZFar = 1.0f; + } + + D3DVIEWPORT9 dxViewport; + dxViewport.X = gl::clamp(actualViewport.x, 0, static_cast(mRenderTargetBounds.width)); + dxViewport.Y = gl::clamp(actualViewport.y, 0, static_cast(mRenderTargetBounds.height)); + dxViewport.Width = + gl::clamp(actualViewport.width, 0, + static_cast(mRenderTargetBounds.width) - static_cast(dxViewport.X)); + dxViewport.Height = + gl::clamp(actualViewport.height, 0, + static_cast(mRenderTargetBounds.height) - static_cast(dxViewport.Y)); + dxViewport.MinZ = actualZNear; + dxViewport.MaxZ = actualZFar; + + float depthFront = !gl::IsTriangleMode(drawMode) ? 0.0f : (frontFace == GL_CCW ? 1.0f : -1.0f); + + mRenderer9->getDevice()->SetViewport(&dxViewport); + + mCurViewport = actualViewport; + mCurNear = actualZNear; + mCurFar = actualZFar; + mCurDepthFront = depthFront; + mCurIgnoreViewport = ignoreViewport; + + // Setting shader constants + dx_VertexConstants9 vc = {}; + dx_PixelConstants9 pc = {}; + + vc.viewAdjust[0] = + static_cast((actualViewport.width - static_cast(dxViewport.Width)) + + 2 * (actualViewport.x - static_cast(dxViewport.X)) - 1) / + dxViewport.Width; + vc.viewAdjust[1] = + static_cast((actualViewport.height - static_cast(dxViewport.Height)) + + 2 * (actualViewport.y - static_cast(dxViewport.Y)) - 1) / + dxViewport.Height; + vc.viewAdjust[2] = static_cast(actualViewport.width) / dxViewport.Width; + vc.viewAdjust[3] = static_cast(actualViewport.height) / dxViewport.Height; + + pc.viewCoords[0] = actualViewport.width * 0.5f; + pc.viewCoords[1] = actualViewport.height * 0.5f; + pc.viewCoords[2] = actualViewport.x + (actualViewport.width * 0.5f); + pc.viewCoords[3] = actualViewport.y + (actualViewport.height * 0.5f); + + pc.depthFront[0] = (actualZFar - actualZNear) * 0.5f; + pc.depthFront[1] = (actualZNear + actualZFar) * 0.5f; + pc.depthFront[2] = depthFront; + + vc.depthRange[0] = actualZNear; + vc.depthRange[1] = actualZFar; + vc.depthRange[2] = actualZFar - actualZNear; + + pc.depthRange[0] = actualZNear; + pc.depthRange[1] = actualZFar; + pc.depthRange[2] = actualZFar - actualZNear; + + if (memcmp(&vc, &mVertexConstants, sizeof(dx_VertexConstants9)) != 0) + { + mVertexConstants = vc; + mDxUniformsDirty = true; + } + + if (memcmp(&pc, &mPixelConstants, sizeof(dx_PixelConstants9)) != 0) + { + mPixelConstants = pc; + mDxUniformsDirty = true; + } + + mForceSetViewport = false; +} + +void StateManager9::setShaderConstants() +{ + if (!mDxUniformsDirty) + return; + + IDirect3DDevice9 *device = mRenderer9->getDevice(); + device->SetVertexShaderConstantF(0, reinterpret_cast(&mVertexConstants), + sizeof(dx_VertexConstants9) / sizeof(float[4])); + device->SetPixelShaderConstantF(0, reinterpret_cast(&mPixelConstants), + sizeof(dx_PixelConstants9) / sizeof(float[4])); + mDxUniformsDirty = false; +} + +// This is separate from the main state loop because other functions +// outside call only setScissorState to update scissor state +void StateManager9::setScissorState(const gl::Rectangle &scissor, bool enabled) +{ + if (mDirtyBits.test(DIRTY_BIT_SCISSOR_ENABLED)) + setScissorEnabled(enabled); + + if (mDirtyBits.test(DIRTY_BIT_SCISSOR_RECT)) + setScissorRect(scissor, enabled); +} + +void StateManager9::setRenderTargetBounds(size_t width, size_t height) +{ + mRenderTargetBounds.width = (int)width; + mRenderTargetBounds.height = (int)height; + forceSetViewportState(); +} + +void StateManager9::setScissorEnabled(bool scissorEnabled) +{ + mRenderer9->getDevice()->SetRenderState(D3DRS_SCISSORTESTENABLE, scissorEnabled ? TRUE : FALSE); + mCurScissorEnabled = scissorEnabled; +} + +void StateManager9::setScissorRect(const gl::Rectangle &scissor, bool enabled) +{ + if (!enabled) + return; + + RECT rect; + rect.left = gl::clamp(scissor.x, 0, static_cast(mRenderTargetBounds.width)); + rect.top = gl::clamp(scissor.y, 0, static_cast(mRenderTargetBounds.height)); + rect.right = + gl::clamp(scissor.x + scissor.width, 0, static_cast(mRenderTargetBounds.width)); + rect.bottom = + gl::clamp(scissor.y + scissor.height, 0, static_cast(mRenderTargetBounds.height)); + mRenderer9->getDevice()->SetScissorRect(&rect); +} + +void StateManager9::setDepthFunc(bool depthTest, GLenum depthFunc) +{ + if (depthTest) + { + IDirect3DDevice9 *device = mRenderer9->getDevice(); + device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE); + device->SetRenderState(D3DRS_ZFUNC, gl_d3d9::ConvertComparison(depthFunc)); + } + else + { + mRenderer9->getDevice()->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); + } + + mCurDepthStencilState.depthTest = depthTest; + mCurDepthStencilState.depthFunc = depthFunc; +} + +void StateManager9::setStencilOpsFront(GLenum stencilFail, + GLenum stencilPassDepthFail, + GLenum stencilPassDepthPass, + bool frontFaceCCW) +{ + // TODO(dianx) It may be slightly more efficient todo these and other similar areas + // with separate dirty bits. + IDirect3DDevice9 *device = mRenderer9->getDevice(); + device->SetRenderState(frontFaceCCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, + gl_d3d9::ConvertStencilOp(stencilFail)); + device->SetRenderState(frontFaceCCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, + gl_d3d9::ConvertStencilOp(stencilPassDepthFail)); + device->SetRenderState(frontFaceCCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, + gl_d3d9::ConvertStencilOp(stencilPassDepthPass)); + + mCurDepthStencilState.stencilFail = stencilFail; + mCurDepthStencilState.stencilPassDepthFail = stencilPassDepthFail; + mCurDepthStencilState.stencilPassDepthPass = stencilPassDepthPass; +} + +void StateManager9::setStencilOpsBack(GLenum stencilBackFail, + GLenum stencilBackPassDepthFail, + GLenum stencilBackPassDepthPass, + bool frontFaceCCW) +{ + IDirect3DDevice9 *device = mRenderer9->getDevice(); + device->SetRenderState(!frontFaceCCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, + gl_d3d9::ConvertStencilOp(stencilBackFail)); + device->SetRenderState(!frontFaceCCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, + gl_d3d9::ConvertStencilOp(stencilBackPassDepthFail)); + device->SetRenderState(!frontFaceCCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, + gl_d3d9::ConvertStencilOp(stencilBackPassDepthPass)); + + mCurDepthStencilState.stencilBackFail = stencilBackFail; + mCurDepthStencilState.stencilBackPassDepthFail = stencilBackPassDepthFail; + mCurDepthStencilState.stencilBackPassDepthPass = stencilBackPassDepthPass; +} + +void StateManager9::setStencilBackWriteMask(GLuint stencilBackWriteMask, bool frontFaceCCW) +{ + mRenderer9->getDevice()->SetRenderState( + !frontFaceCCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, stencilBackWriteMask); + + mCurDepthStencilState.stencilBackWritemask = stencilBackWriteMask; +} + +void StateManager9::setStencilFuncsBack(GLenum stencilBackFunc, + GLuint stencilBackMask, + GLint stencilBackRef, + bool frontFaceCCW, + unsigned int maxStencil) +{ + IDirect3DDevice9 *device = mRenderer9->getDevice(); + device->SetRenderState(!frontFaceCCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, + gl_d3d9::ConvertComparison(stencilBackFunc)); + device->SetRenderState(!frontFaceCCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, + (stencilBackRef < (int)maxStencil) ? stencilBackRef : maxStencil); + device->SetRenderState(!frontFaceCCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, + stencilBackMask); + + mCurDepthStencilState.stencilBackFunc = stencilBackFunc; + mCurStencilBackRef = stencilBackRef; + mCurDepthStencilState.stencilBackMask = stencilBackMask; +} + +void StateManager9::setStencilWriteMask(GLuint stencilWriteMask, bool frontFaceCCW) +{ + mRenderer9->getDevice()->SetRenderState( + frontFaceCCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, stencilWriteMask); + mCurDepthStencilState.stencilWritemask = stencilWriteMask; +} + +void StateManager9::setStencilFuncsFront(GLenum stencilFunc, + GLuint stencilMask, + GLint stencilRef, + bool frontFaceCCW, + unsigned int maxStencil) +{ + IDirect3DDevice9 *device = mRenderer9->getDevice(); + device->SetRenderState(frontFaceCCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, + gl_d3d9::ConvertComparison(stencilFunc)); + device->SetRenderState(frontFaceCCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, + (stencilRef < static_cast(maxStencil)) ? stencilRef : maxStencil); + device->SetRenderState(frontFaceCCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, stencilMask); + + mCurDepthStencilState.stencilFunc = stencilFunc; + mCurStencilRef = stencilRef; + mCurDepthStencilState.stencilMask = stencilMask; +} +void StateManager9::setStencilTestEnabled(bool stencilTestEnabled) +{ + if (stencilTestEnabled && mCurStencilSize > 0) + { + mRenderer9->getDevice()->SetRenderState(D3DRS_STENCILENABLE, TRUE); + mRenderer9->getDevice()->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, TRUE); + } + else + { + mRenderer9->getDevice()->SetRenderState(D3DRS_STENCILENABLE, FALSE); + } + + mCurDepthStencilState.stencilTest = stencilTestEnabled; +} + +void StateManager9::setDepthMask(bool depthMask) +{ + mRenderer9->getDevice()->SetRenderState(D3DRS_ZWRITEENABLE, depthMask ? TRUE : FALSE); + mCurDepthStencilState.depthMask = depthMask; +} + +// TODO(dianx) one bit for sampleAlphaToCoverage +void StateManager9::setSampleAlphaToCoverage(bool enabled) +{ + if (enabled) + { + // D3D9 support for alpha-to-coverage is vendor-specific. + UNIMPLEMENTED(); + } +} + +void StateManager9::setBlendColor(const gl::BlendState &blendState, const gl::ColorF &blendColor) +{ + if (!blendState.blend) + return; + + if (blendState.sourceBlendRGB != GL_CONSTANT_ALPHA && + blendState.sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA && + blendState.destBlendRGB != GL_CONSTANT_ALPHA && + blendState.destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA) + { + mRenderer9->getDevice()->SetRenderState(D3DRS_BLENDFACTOR, + gl_d3d9::ConvertColor(blendColor)); + } + else + { + mRenderer9->getDevice()->SetRenderState( + D3DRS_BLENDFACTOR, + D3DCOLOR_RGBA(gl::unorm<8>(blendColor.alpha), gl::unorm<8>(blendColor.alpha), + gl::unorm<8>(blendColor.alpha), gl::unorm<8>(blendColor.alpha))); + } + mCurBlendColor = blendColor; +} + +void StateManager9::setBlendFuncsEquations(const gl::BlendState &blendState) +{ + if (!blendState.blend) + return; + + IDirect3DDevice9 *device = mRenderer9->getDevice(); + + device->SetRenderState(D3DRS_SRCBLEND, gl_d3d9::ConvertBlendFunc(blendState.sourceBlendRGB)); + device->SetRenderState(D3DRS_DESTBLEND, gl_d3d9::ConvertBlendFunc(blendState.destBlendRGB)); + device->SetRenderState(D3DRS_BLENDOP, gl_d3d9::ConvertBlendOp(blendState.blendEquationRGB)); + + if (blendState.sourceBlendRGB != blendState.sourceBlendAlpha || + blendState.destBlendRGB != blendState.destBlendAlpha || + blendState.blendEquationRGB != blendState.blendEquationAlpha) + { + device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE); + + device->SetRenderState(D3DRS_SRCBLENDALPHA, + gl_d3d9::ConvertBlendFunc(blendState.sourceBlendAlpha)); + device->SetRenderState(D3DRS_DESTBLENDALPHA, + gl_d3d9::ConvertBlendFunc(blendState.destBlendAlpha)); + device->SetRenderState(D3DRS_BLENDOPALPHA, + gl_d3d9::ConvertBlendOp(blendState.blendEquationAlpha)); + } + else + { + device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE); + } + + mCurBlendState.sourceBlendRGB = blendState.sourceBlendRGB; + mCurBlendState.destBlendRGB = blendState.destBlendRGB; + mCurBlendState.blendEquationRGB = blendState.blendEquationRGB; + mCurBlendState.blendEquationAlpha = blendState.blendEquationAlpha; +} + +void StateManager9::setBlendEnabled(bool enabled) +{ + mRenderer9->getDevice()->SetRenderState(D3DRS_ALPHABLENDENABLE, enabled ? TRUE : FALSE); + mCurBlendState.blend = enabled; +} + +void StateManager9::setDither(bool dither) +{ + mRenderer9->getDevice()->SetRenderState(D3DRS_DITHERENABLE, dither ? TRUE : FALSE); + mCurRasterState.dither = dither; +} + +// TODO(dianx) one bit for color mask +void StateManager9::setColorMask(const gl::Framebuffer *framebuffer, + bool red, + bool blue, + bool green, + bool alpha) +{ + // Set the color mask + + const auto *attachment = framebuffer->getFirstColorAttachment(); + const auto &format = attachment ? attachment->getFormat() : gl::Format::Invalid(); + + DWORD colorMask = gl_d3d9::ConvertColorMask( + format.info->redBits > 0 && red, format.info->greenBits > 0 && green, + format.info->blueBits > 0 && blue, format.info->alphaBits > 0 && alpha); + + // Apparently some ATI cards have a bug where a draw with a zero color write mask can cause + // later draws to have incorrect results. Instead, set a nonzero color write mask but modify the + // blend state so that no drawing is done. + // http://anglebug.com/169 + if (colorMask == 0 && mUsingZeroColorMaskWorkaround) + { + IDirect3DDevice9 *device = mRenderer9->getDevice(); + // Enable green channel, but set blending so nothing will be drawn. + device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_GREEN); + + device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + + device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO); + device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); + device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); + + mCurBlendState.colorMaskRed = false; + mCurBlendState.colorMaskGreen = true; + mCurBlendState.colorMaskBlue = false; + mCurBlendState.colorMaskAlpha = false; + + mCurBlendState.blend = true; + mCurBlendState.sourceBlendRGB = GL_ZERO; + mCurBlendState.sourceBlendAlpha = GL_ZERO; + mCurBlendState.destBlendRGB = GL_ONE; + mCurBlendState.destBlendAlpha = GL_ONE; + mCurBlendState.blendEquationRGB = GL_FUNC_ADD; + mCurBlendState.blendEquationAlpha = GL_FUNC_ADD; + } + else + { + mRenderer9->getDevice()->SetRenderState(D3DRS_COLORWRITEENABLE, colorMask); + + mCurBlendState.colorMaskRed = red; + mCurBlendState.colorMaskGreen = green; + mCurBlendState.colorMaskBlue = blue; + mCurBlendState.colorMaskAlpha = alpha; + } +} + +void StateManager9::setSampleMask(unsigned int sampleMask) +{ + IDirect3DDevice9 *device = mRenderer9->getDevice(); + // Set the multisample mask + device->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE); + device->SetRenderState(D3DRS_MULTISAMPLEMASK, static_cast(sampleMask)); + + mCurSampleMask = sampleMask; +} + +void StateManager9::setCullMode(bool cullFace, gl::CullFaceMode cullMode, GLenum frontFace) +{ + if (cullFace) + { + mRenderer9->getDevice()->SetRenderState(D3DRS_CULLMODE, + gl_d3d9::ConvertCullMode(cullMode, frontFace)); + } + else + { + mRenderer9->getDevice()->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + } + + mCurRasterState.cullFace = cullFace; + mCurRasterState.cullMode = cullMode; + mCurRasterState.frontFace = frontFace; +} + +void StateManager9::setDepthBias(bool polygonOffsetFill, + GLfloat polygonOffsetFactor, + GLfloat polygonOffsetUnits) +{ + if (polygonOffsetFill) + { + if (mCurDepthSize > 0) + { + IDirect3DDevice9 *device = mRenderer9->getDevice(); + device->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, *(DWORD *)&polygonOffsetFactor); + + float depthBias = ldexp(polygonOffsetUnits, -static_cast(mCurDepthSize)); + device->SetRenderState(D3DRS_DEPTHBIAS, *(DWORD *)&depthBias); + } + } + else + { + IDirect3DDevice9 *device = mRenderer9->getDevice(); + device->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, 0); + device->SetRenderState(D3DRS_DEPTHBIAS, 0); + } + + mCurRasterState.polygonOffsetFill = polygonOffsetFill; + mCurRasterState.polygonOffsetFactor = polygonOffsetFactor; + mCurRasterState.polygonOffsetUnits = polygonOffsetUnits; +} + +void StateManager9::updateDepthSizeIfChanged(bool depthStencilInitialized, unsigned int depthSize) +{ + if (!depthStencilInitialized || depthSize != mCurDepthSize) + { + mCurDepthSize = depthSize; + forceSetRasterState(); + } +} +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/StateManager9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/StateManager9.h new file mode 100644 index 0000000000..b047b69cdd --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/StateManager9.h @@ -0,0 +1,211 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// StateManager9.h: Defines a class for caching D3D9 state + +#ifndef LIBANGLE_RENDERER_D3D9_STATEMANAGER9_H_ +#define LIBANGLE_RENDERER_D3D9_STATEMANAGER9_H_ + +#include "libANGLE/State.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" + +namespace rx +{ + +class Renderer9; + +struct dx_VertexConstants9 +{ + float depthRange[4]; + float viewAdjust[4]; + float viewCoords[4]; +}; + +struct dx_PixelConstants9 +{ + float depthRange[4]; + float viewCoords[4]; + float depthFront[4]; +}; + +class StateManager9 final : angle::NonCopyable +{ + public: + StateManager9(Renderer9 *renderer9); + ~StateManager9(); + + void initialize(); + + void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits); + + void setBlendDepthRasterStates(const gl::State &glState, unsigned int sampleMask); + void setScissorState(const gl::Rectangle &scissor, bool enabled); + void setViewportState(const gl::Rectangle &viewport, + float zNear, + float zFar, + gl::PrimitiveMode drawMode, + GLenum frontFace, + bool ignoreViewport); + + void setShaderConstants(); + + void forceSetBlendState(); + void forceSetRasterState(); + void forceSetDepthStencilState(); + void forceSetScissorState(); + void forceSetViewportState(); + void forceSetDXUniformsState(); + + void updateDepthSizeIfChanged(bool depthStencilInitialized, unsigned int depthSize); + void updateStencilSizeIfChanged(bool depthStencilInitialized, unsigned int stencilSize); + + void setRenderTargetBounds(size_t width, size_t height); + + int getRenderTargetWidth() const { return mRenderTargetBounds.width; } + int getRenderTargetHeight() const { return mRenderTargetBounds.height; } + + void setAllDirtyBits() { mDirtyBits.set(); } + void resetDirtyBits() { mDirtyBits.reset(); } + + private: + // Blend state functions + void setBlendEnabled(bool enabled); + void setBlendColor(const gl::BlendState &blendState, const gl::ColorF &blendColor); + void setBlendFuncsEquations(const gl::BlendState &blendState); + void setColorMask(const gl::Framebuffer *framebuffer, + bool red, + bool blue, + bool green, + bool alpha); + void setSampleAlphaToCoverage(bool enabled); + void setDither(bool dither); + void setSampleMask(unsigned int sampleMask); + + // Current raster state functions + void setCullMode(bool cullFace, gl::CullFaceMode cullMode, GLenum frontFace); + void setDepthBias(bool polygonOffsetFill, + GLfloat polygonOffsetFactor, + GLfloat polygonOffsetUnits); + + // Depth stencil state functions + void setStencilOpsFront(GLenum stencilFail, + GLenum stencilPassDepthFail, + GLenum stencilPassDepthPass, + bool frontFaceCCW); + void setStencilOpsBack(GLenum stencilBackFail, + GLenum stencilBackPassDepthFail, + GLenum stencilBackPassDepthPass, + bool frontFaceCCW); + void setStencilBackWriteMask(GLuint stencilBackWriteMask, bool frontFaceCCW); + void setDepthFunc(bool depthTest, GLenum depthFunc); + void setStencilTestEnabled(bool enabled); + void setDepthMask(bool depthMask); + void setStencilFuncsFront(GLenum stencilFunc, + GLuint stencilMask, + GLint stencilRef, + bool frontFaceCCW, + unsigned int maxStencil); + void setStencilFuncsBack(GLenum stencilBackFunc, + GLuint stencilBackMask, + GLint stencilBackRef, + bool frontFaceCCW, + unsigned int maxStencil); + void setStencilWriteMask(GLuint stencilWriteMask, bool frontFaceCCW); + + void setScissorEnabled(bool scissorEnabled); + void setScissorRect(const gl::Rectangle &scissor, bool enabled); + + enum DirtyBitType + { + // Blend dirty bits + DIRTY_BIT_BLEND_ENABLED, + DIRTY_BIT_BLEND_COLOR, + DIRTY_BIT_BLEND_FUNCS_EQUATIONS, + DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE, + DIRTY_BIT_COLOR_MASK, + DIRTY_BIT_DITHER, + DIRTY_BIT_SAMPLE_MASK, + + // Rasterizer dirty bits + DIRTY_BIT_CULL_MODE, + DIRTY_BIT_DEPTH_BIAS, + + // Depth stencil dirty bits + DIRTY_BIT_STENCIL_DEPTH_MASK, + DIRTY_BIT_STENCIL_DEPTH_FUNC, + DIRTY_BIT_STENCIL_TEST_ENABLED, + DIRTY_BIT_STENCIL_FUNCS_FRONT, + DIRTY_BIT_STENCIL_FUNCS_BACK, + DIRTY_BIT_STENCIL_WRITEMASK_FRONT, + DIRTY_BIT_STENCIL_WRITEMASK_BACK, + DIRTY_BIT_STENCIL_OPS_FRONT, + DIRTY_BIT_STENCIL_OPS_BACK, + + // Scissor dirty bits + DIRTY_BIT_SCISSOR_ENABLED, + DIRTY_BIT_SCISSOR_RECT, + + // Viewport dirty bits + DIRTY_BIT_VIEWPORT, + + DIRTY_BIT_MAX + }; + + using DirtyBits = angle::BitSet; + + bool mUsingZeroColorMaskWorkaround; + + bool mCurSampleAlphaToCoverage; + + // Currently applied blend state + gl::BlendState mCurBlendState; + gl::ColorF mCurBlendColor; + unsigned int mCurSampleMask; + DirtyBits mBlendStateDirtyBits; + + // Currently applied raster state + gl::RasterizerState mCurRasterState; + unsigned int mCurDepthSize; + DirtyBits mRasterizerStateDirtyBits; + + // Currently applied depth stencil state + gl::DepthStencilState mCurDepthStencilState; + int mCurStencilRef; + int mCurStencilBackRef; + bool mCurFrontFaceCCW; + unsigned int mCurStencilSize; + DirtyBits mDepthStencilStateDirtyBits; + + // Currently applied scissor states + gl::Rectangle mCurScissorRect; + bool mCurScissorEnabled; + gl::Extents mRenderTargetBounds; + DirtyBits mScissorStateDirtyBits; + + // Currently applied viewport states + bool mForceSetViewport; + gl::Rectangle mCurViewport; + float mCurNear; + float mCurFar; + float mCurDepthFront; + bool mCurIgnoreViewport; + + dx_VertexConstants9 mVertexConstants; + dx_PixelConstants9 mPixelConstants; + bool mDxUniformsDirty; + + // FIXME: Unsupported by D3D9 + static const D3DRENDERSTATETYPE D3DRS_CCW_STENCILREF = D3DRS_STENCILREF; + static const D3DRENDERSTATETYPE D3DRS_CCW_STENCILMASK = D3DRS_STENCILMASK; + static const D3DRENDERSTATETYPE D3DRS_CCW_STENCILWRITEMASK = D3DRS_STENCILWRITEMASK; + + Renderer9 *mRenderer9; + DirtyBits mDirtyBits; +}; + +} // namespace rx +#endif // LIBANGLE_RENDERER_D3D9_STATEMANAGER9_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp new file mode 100644 index 0000000000..c8abac7a57 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp @@ -0,0 +1,472 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// SwapChain9.cpp: Implements a back-end specific class for the D3D9 swap chain. + +#include "libANGLE/renderer/d3d/d3d9/SwapChain9.h" + +#include "libANGLE/features.h" +#include "libANGLE/renderer/d3d/d3d9/NativeWindow9.h" +#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" +#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" +#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" + +namespace rx +{ + +SwapChain9::SwapChain9(Renderer9 *renderer, + NativeWindow9 *nativeWindow, + HANDLE shareHandle, + IUnknown *d3dTexture, + GLenum backBufferFormat, + GLenum depthBufferFormat, + EGLint orientation) + : SwapChainD3D(shareHandle, d3dTexture, backBufferFormat, depthBufferFormat), + mRenderer(renderer), + mWidth(-1), + mHeight(-1), + mSwapInterval(-1), + mNativeWindow(nativeWindow), + mSwapChain(nullptr), + mBackBuffer(nullptr), + mRenderTarget(nullptr), + mDepthStencil(nullptr), + mOffscreenTexture(nullptr), + mColorRenderTarget(this, false), + mDepthStencilRenderTarget(this, true) +{ + ASSERT(orientation == 0); +} + +SwapChain9::~SwapChain9() +{ + release(); +} + +void SwapChain9::release() +{ + SafeRelease(mSwapChain); + SafeRelease(mBackBuffer); + SafeRelease(mDepthStencil); + SafeRelease(mRenderTarget); + SafeRelease(mOffscreenTexture); + + if (mNativeWindow->getNativeWindow()) + { + mShareHandle = nullptr; + } +} + +static DWORD convertInterval(EGLint interval) +{ +#if ANGLE_VSYNC == ANGLE_DISABLED + return D3DPRESENT_INTERVAL_IMMEDIATE; +#else + switch (interval) + { + case 0: + return D3DPRESENT_INTERVAL_IMMEDIATE; + case 1: + return D3DPRESENT_INTERVAL_ONE; + case 2: + return D3DPRESENT_INTERVAL_TWO; + case 3: + return D3DPRESENT_INTERVAL_THREE; + case 4: + return D3DPRESENT_INTERVAL_FOUR; + default: + UNREACHABLE(); + } + + return D3DPRESENT_INTERVAL_DEFAULT; +#endif +} + +EGLint SwapChain9::resize(DisplayD3D *displayD3D, int backbufferWidth, int backbufferHeight) +{ + // D3D9 does not support resizing swap chains without recreating them + return reset(displayD3D, backbufferWidth, backbufferHeight, mSwapInterval); +} + +EGLint SwapChain9::reset(DisplayD3D *displayD3D, + int backbufferWidth, + int backbufferHeight, + EGLint swapInterval) +{ + IDirect3DDevice9 *device = mRenderer->getDevice(); + + if (device == nullptr) + { + return EGL_BAD_ACCESS; + } + + // Evict all non-render target textures to system memory and release all resources + // before reallocating them to free up as much video memory as possible. + device->EvictManagedResources(); + + HRESULT result; + + // Release specific resources to free up memory for the new render target, while the + // old render target still exists for the purpose of preserving its contents. + SafeRelease(mSwapChain); + SafeRelease(mBackBuffer); + SafeRelease(mOffscreenTexture); + SafeRelease(mDepthStencil); + + const d3d9::TextureFormat &backBufferd3dFormatInfo = + d3d9::GetTextureFormatInfo(mOffscreenRenderTargetFormat); + if (mD3DTexture != nullptr) + { + result = mD3DTexture->QueryInterface(&mOffscreenTexture); + ASSERT(SUCCEEDED(result)); + } + else + { + HANDLE *pShareHandle = nullptr; + if (!mNativeWindow->getNativeWindow() && mRenderer->getShareHandleSupport()) + { + pShareHandle = &mShareHandle; + } + + result = device->CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET, + backBufferd3dFormatInfo.texFormat, D3DPOOL_DEFAULT, + &mOffscreenTexture, pShareHandle); + if (FAILED(result)) + { + ERR() << "Could not create offscreen texture, " << gl::FmtHR(result); + release(); + + if (d3d9::isDeviceLostError(result)) + { + return EGL_CONTEXT_LOST; + } + else + { + return EGL_BAD_ALLOC; + } + } + } + + IDirect3DSurface9 *oldRenderTarget = mRenderTarget; + + result = mOffscreenTexture->GetSurfaceLevel(0, &mRenderTarget); + ASSERT(SUCCEEDED(result)); + + if (oldRenderTarget) + { + RECT rect = {0, 0, mWidth, mHeight}; + + if (rect.right > static_cast(backbufferWidth)) + { + rect.right = backbufferWidth; + } + + if (rect.bottom > static_cast(backbufferHeight)) + { + rect.bottom = backbufferHeight; + } + + mRenderer->endScene(); + + result = device->StretchRect(oldRenderTarget, &rect, mRenderTarget, &rect, D3DTEXF_NONE); + ASSERT(SUCCEEDED(result)); + + SafeRelease(oldRenderTarget); + } + + const d3d9::TextureFormat &depthBufferd3dFormatInfo = + d3d9::GetTextureFormatInfo(mDepthBufferFormat); + + // Don't create a swapchain for NULLREF devices + D3DDEVTYPE deviceType = mRenderer->getD3D9DeviceType(); + EGLNativeWindowType window = mNativeWindow->getNativeWindow(); + if (window && deviceType != D3DDEVTYPE_NULLREF) + { + D3DPRESENT_PARAMETERS presentParameters = {}; + presentParameters.AutoDepthStencilFormat = depthBufferd3dFormatInfo.renderFormat; + presentParameters.BackBufferCount = 1; + presentParameters.BackBufferFormat = backBufferd3dFormatInfo.renderFormat; + presentParameters.EnableAutoDepthStencil = FALSE; + presentParameters.Flags = 0; + presentParameters.hDeviceWindow = window; + presentParameters.MultiSampleQuality = 0; // FIXME: Unimplemented + presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // FIXME: Unimplemented + presentParameters.PresentationInterval = convertInterval(swapInterval); + presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD; + presentParameters.Windowed = TRUE; + presentParameters.BackBufferWidth = backbufferWidth; + presentParameters.BackBufferHeight = backbufferHeight; + + // http://crbug.com/140239 + // http://crbug.com/143434 + // + // Some AMD/Intel switchable systems / drivers appear to round swap chain surfaces to a + // multiple of 64 pixels in width when using the integrated Intel. This rounds the width up + // rather than down. + // + // Some non-switchable AMD GPUs / drivers do not respect the source rectangle to Present. + // Therefore, when the vendor ID is not Intel, the back buffer width must be exactly the + // same width as the window or horizontal scaling will occur. + if (IsIntel(mRenderer->getVendorId())) + { + presentParameters.BackBufferWidth = (presentParameters.BackBufferWidth + 63) / 64 * 64; + } + + result = device->CreateAdditionalSwapChain(&presentParameters, &mSwapChain); + + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || + result == D3DERR_INVALIDCALL || result == D3DERR_DEVICELOST); + + ERR() << "Could not create additional swap chains or offscreen surfaces, " + << gl::FmtHR(result); + release(); + + if (d3d9::isDeviceLostError(result)) + { + return EGL_CONTEXT_LOST; + } + else + { + return EGL_BAD_ALLOC; + } + } + + result = mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer); + ASSERT(SUCCEEDED(result)); + InvalidateRect(window, nullptr, FALSE); + } + + if (mDepthBufferFormat != GL_NONE) + { + result = device->CreateDepthStencilSurface( + backbufferWidth, backbufferHeight, depthBufferd3dFormatInfo.renderFormat, + D3DMULTISAMPLE_NONE, 0, FALSE, &mDepthStencil, nullptr); + + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || + result == D3DERR_INVALIDCALL); + + ERR() << "Could not create depthstencil surface for new swap chain, " + << gl::FmtHR(result); + release(); + + if (d3d9::isDeviceLostError(result)) + { + return EGL_CONTEXT_LOST; + } + else + { + return EGL_BAD_ALLOC; + } + } + } + + mWidth = backbufferWidth; + mHeight = backbufferHeight; + mSwapInterval = swapInterval; + + return EGL_SUCCESS; +} + +// parameters should be validated/clamped by caller +EGLint SwapChain9::swapRect(DisplayD3D *displayD3D, EGLint x, EGLint y, EGLint width, EGLint height) +{ + if (!mSwapChain) + { + return EGL_SUCCESS; + } + + IDirect3DDevice9 *device = mRenderer->getDevice(); + + // Disable all pipeline operations + device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); + device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); + device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); + device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + device->SetRenderState(D3DRS_STENCILENABLE, FALSE); + device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0); + device->SetRenderState(D3DRS_COLORWRITEENABLE, + D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | + D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED); + device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE); + device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); + device->SetPixelShader(nullptr); + device->SetVertexShader(nullptr); + + device->SetRenderTarget(0, mBackBuffer); + device->SetDepthStencilSurface(nullptr); + + device->SetTexture(0, mOffscreenTexture); + device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); + device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); + device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); + device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); + device->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1); + + for (UINT streamIndex = 0; streamIndex < gl::MAX_VERTEX_ATTRIBS; streamIndex++) + { + device->SetStreamSourceFreq(streamIndex, 1); + } + + D3DVIEWPORT9 viewport = {0, 0, static_cast(mWidth), static_cast(mHeight), + 0.0f, 1.0f}; + device->SetViewport(&viewport); + + float x1 = x - 0.5f; + float y1 = (mHeight - y - height) - 0.5f; + float x2 = (x + width) - 0.5f; + float y2 = (mHeight - y) - 0.5f; + + float u1 = x / float(mWidth); + float v1 = y / float(mHeight); + float u2 = (x + width) / float(mWidth); + float v2 = (y + height) / float(mHeight); + + float quad[4][6] = {{x1, y1, 0.0f, 1.0f, u1, v2}, + {x2, y1, 0.0f, 1.0f, u2, v2}, + {x2, y2, 0.0f, 1.0f, u2, v1}, + {x1, y2, 0.0f, 1.0f, u1, v1}}; // x, y, z, rhw, u, v + + mRenderer->startScene(); + device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, quad, 6 * sizeof(float)); + mRenderer->endScene(); + + device->SetTexture(0, nullptr); + + RECT rect = {static_cast(x), static_cast(mHeight - y - height), + static_cast(x + width), static_cast(mHeight - y)}; + + HRESULT result = mSwapChain->Present(&rect, &rect, nullptr, nullptr, 0); + + mRenderer->markAllStateDirty(); + + if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || + result == D3DERR_DRIVERINTERNALERROR) + { + return EGL_BAD_ALLOC; + } + + // On Windows 8 systems, IDirect3DSwapChain9::Present sometimes returns 0x88760873 when the + // windows is in the process of entering/exiting fullscreen. This code doesn't seem to have any + // documentation. The device appears to be ok after emitting this error so simply return a + // failure to swap. + if (result == static_cast(0x88760873) || result == static_cast(0x88760872)) + { + return EGL_BAD_MATCH; + } + + // http://crbug.com/313210 + // If our swap failed, trigger a device lost event. Resetting will work around an AMD-specific + // device removed bug with lost contexts when reinstalling drivers. + if (FAILED(result)) + { + mRenderer->notifyDeviceLost(); + return EGL_CONTEXT_LOST; + } + + return EGL_SUCCESS; +} + +// Increments refcount on surface. +// caller must Release() the returned surface +// TODO: remove the AddRef to match SwapChain11 +IDirect3DSurface9 *SwapChain9::getRenderTarget() +{ + if (mRenderTarget) + { + mRenderTarget->AddRef(); + } + + return mRenderTarget; +} + +// Increments refcount on surface. +// caller must Release() the returned surface +// TODO: remove the AddRef to match SwapChain11 +IDirect3DSurface9 *SwapChain9::getDepthStencil() +{ + if (mDepthStencil) + { + mDepthStencil->AddRef(); + } + + return mDepthStencil; +} + +// Increments refcount on texture. +// caller must Release() the returned texture +// TODO: remove the AddRef to match SwapChain11 +IDirect3DTexture9 *SwapChain9::getOffscreenTexture() +{ + if (mOffscreenTexture) + { + mOffscreenTexture->AddRef(); + } + + return mOffscreenTexture; +} + +void *SwapChain9::getKeyedMutex() +{ + UNREACHABLE(); + return nullptr; +} + +egl::Error SwapChain9::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) +{ + UNREACHABLE(); + return egl::EglBadSurface(); +} + +void SwapChain9::recreate() +{ + if (!mSwapChain) + { + return; + } + + IDirect3DDevice9 *device = mRenderer->getDevice(); + if (device == nullptr) + { + return; + } + + D3DPRESENT_PARAMETERS presentParameters; + HRESULT result = mSwapChain->GetPresentParameters(&presentParameters); + ASSERT(SUCCEEDED(result)); + + IDirect3DSwapChain9 *newSwapChain = nullptr; + result = device->CreateAdditionalSwapChain(&presentParameters, &newSwapChain); + if (FAILED(result)) + { + return; + } + + SafeRelease(mSwapChain); + mSwapChain = newSwapChain; + + SafeRelease(mBackBuffer); + result = mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer); + ASSERT(SUCCEEDED(result)); +} + +RenderTargetD3D *SwapChain9::getColorRenderTarget() +{ + return &mColorRenderTarget; +} + +RenderTargetD3D *SwapChain9::getDepthStencilRenderTarget() +{ + return &mDepthStencilRenderTarget; +} +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h new file mode 100644 index 0000000000..2b3176967d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h @@ -0,0 +1,80 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// SwapChain9.h: Defines a back-end specific class for the D3D9 swap chain. + +#ifndef LIBANGLE_RENDERER_D3D_D3D9_SWAPCHAIN9_H_ +#define LIBANGLE_RENDERER_D3D_D3D9_SWAPCHAIN9_H_ + +#include "common/angleutils.h" +#include "libANGLE/renderer/d3d/SwapChainD3D.h" +#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h" + +namespace rx +{ +class NativeWindow9; +class Renderer9; + +class SwapChain9 : public SwapChainD3D +{ + public: + SwapChain9(Renderer9 *renderer, + NativeWindow9 *nativeWindow, + HANDLE shareHandle, + IUnknown *d3dTexture, + GLenum backBufferFormat, + GLenum depthBufferFormat, + EGLint orientation); + ~SwapChain9() override; + + EGLint resize(DisplayD3D *displayD3D, EGLint backbufferWidth, EGLint backbufferHeight) override; + EGLint reset(DisplayD3D *displayD3D, + EGLint backbufferWidth, + EGLint backbufferHeight, + EGLint swapInterval) override; + EGLint swapRect(DisplayD3D *displayD3D, + EGLint x, + EGLint y, + EGLint width, + EGLint height) override; + void recreate() override; + + RenderTargetD3D *getColorRenderTarget() override; + RenderTargetD3D *getDepthStencilRenderTarget() override; + + virtual IDirect3DSurface9 *getRenderTarget(); + virtual IDirect3DSurface9 *getDepthStencil(); + virtual IDirect3DTexture9 *getOffscreenTexture(); + + EGLint getWidth() const { return mWidth; } + EGLint getHeight() const { return mHeight; } + + void *getKeyedMutex() override; + + egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) override; + + private: + void release(); + + Renderer9 *mRenderer; + EGLint mWidth; + EGLint mHeight; + EGLint mSwapInterval; + + NativeWindow9 *mNativeWindow; + + IDirect3DSwapChain9 *mSwapChain; + IDirect3DSurface9 *mBackBuffer; + IDirect3DSurface9 *mRenderTarget; + IDirect3DSurface9 *mDepthStencil; + IDirect3DTexture9 *mOffscreenTexture; + + SurfaceRenderTarget9 mColorRenderTarget; + SurfaceRenderTarget9 mDepthStencilRenderTarget; +}; + +} // namespace rx +#endif // LIBANGLE_RENDERER_D3D_D3D9_SWAPCHAIN9_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp new file mode 100644 index 0000000000..b2fea07fd5 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp @@ -0,0 +1,575 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// TextureStorage9.cpp: Implements the abstract rx::TextureStorage9 class and its concrete derived +// classes TextureStorage9_2D and TextureStorage9_Cube, which act as the interface to the +// D3D9 texture. + +#include "libANGLE/renderer/d3d/d3d9/TextureStorage9.h" + +#include "common/utilities.h" +#include "libANGLE/Context.h" +#include "libANGLE/Texture.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/EGLImageD3D.h" +#include "libANGLE/renderer/d3d/TextureD3D.h" +#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h" +#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" +#include "libANGLE/renderer/d3d/d3d9/SwapChain9.h" +#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" +#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" + +namespace rx +{ +TextureStorage9::TextureStorage9(Renderer9 *renderer, DWORD usage, const std::string &label) + : TextureStorage(label), + mTopLevel(0), + mMipLevels(0), + mTextureWidth(0), + mTextureHeight(0), + mInternalFormat(GL_NONE), + mTextureFormat(D3DFMT_UNKNOWN), + mRenderer(renderer), + mD3DUsage(usage), + mD3DPool(mRenderer->getTexturePool(usage)) +{} + +TextureStorage9::~TextureStorage9() {} + +DWORD TextureStorage9::GetTextureUsage(GLenum internalformat, bool renderTarget) +{ + DWORD d3dusage = 0; + + const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat); + const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat); + if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0) + { + d3dusage |= D3DUSAGE_DEPTHSTENCIL; + } + else if (renderTarget && (d3dFormatInfo.renderFormat != D3DFMT_UNKNOWN)) + { + d3dusage |= D3DUSAGE_RENDERTARGET; + } + + return d3dusage; +} + +bool TextureStorage9::isRenderTarget() const +{ + return (mD3DUsage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)) != 0; +} + +bool TextureStorage9::isManaged() const +{ + return (mD3DPool == D3DPOOL_MANAGED); +} + +bool TextureStorage9::supportsNativeMipmapFunction() const +{ + return false; +} + +D3DPOOL TextureStorage9::getPool() const +{ + return mD3DPool; +} + +DWORD TextureStorage9::getUsage() const +{ + return mD3DUsage; +} + +int TextureStorage9::getTopLevel() const +{ + return mTopLevel; +} + +int TextureStorage9::getLevelCount() const +{ + return static_cast(mMipLevels) - mTopLevel; +} + +angle::Result TextureStorage9::setData(const gl::Context *context, + const gl::ImageIndex &index, + ImageD3D *image, + const gl::Box *destBox, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixelData) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer, + SwapChain9 *swapchain, + const std::string &label) + : TextureStorage9(renderer, D3DUSAGE_RENDERTARGET, label) +{ + IDirect3DTexture9 *surfaceTexture = swapchain->getOffscreenTexture(); + mTexture = surfaceTexture; + mMipLevels = surfaceTexture->GetLevelCount(); + + mInternalFormat = swapchain->getRenderTargetInternalFormat(); + + D3DSURFACE_DESC surfaceDesc; + surfaceTexture->GetLevelDesc(0, &surfaceDesc); + mTextureWidth = surfaceDesc.Width; + mTextureHeight = surfaceDesc.Height; + mTextureFormat = surfaceDesc.Format; + + mRenderTargets.resize(mMipLevels, nullptr); +} + +TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer, + GLenum internalformat, + bool renderTarget, + GLsizei width, + GLsizei height, + int levels, + const std::string &label) + : TextureStorage9(renderer, GetTextureUsage(internalformat, renderTarget), label) +{ + mTexture = nullptr; + + mInternalFormat = internalformat; + + const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat); + mTextureFormat = d3dFormatInfo.texFormat; + + d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &width, &height, &mTopLevel); + mTextureWidth = width; + mTextureHeight = height; + mMipLevels = mTopLevel + levels; + + mRenderTargets.resize(levels, nullptr); +} + +TextureStorage9_2D::~TextureStorage9_2D() +{ + SafeRelease(mTexture); + for (RenderTargetD3D *renderTarget : mRenderTargets) + { + SafeDelete(renderTarget); + } +} + +// Increments refcount on surface. +// caller must Release() the returned surface +angle::Result TextureStorage9_2D::getSurfaceLevel(const gl::Context *context, + gl::TextureTarget target, + int level, + bool dirty, + IDirect3DSurface9 **outSurface) +{ + ASSERT(target == gl::TextureTarget::_2D); + + IDirect3DBaseTexture9 *baseTexture = nullptr; + ANGLE_TRY(getBaseTexture(context, &baseTexture)); + + IDirect3DTexture9 *texture = static_cast(baseTexture); + + HRESULT result = texture->GetSurfaceLevel(level + mTopLevel, outSurface); + ANGLE_TRY_HR(GetImplAs(context), result, "Failed to get the surface from a texture"); + + // With managed textures the driver needs to be informed of updates to the lower mipmap levels + if (level + mTopLevel != 0 && isManaged() && dirty) + { + texture->AddDirtyRect(nullptr); + } + + return angle::Result::Continue; +} + +angle::Result TextureStorage9_2D::findRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) const +{ + ASSERT(index.getLevelIndex() < getLevelCount()); + + ASSERT(outRT); + *outRT = mRenderTargets[index.getLevelIndex()]; + return angle::Result::Continue; +} + +angle::Result TextureStorage9_2D::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) +{ + ASSERT(index.getLevelIndex() < getLevelCount()); + + if (!mRenderTargets[index.getLevelIndex()] && isRenderTarget()) + { + IDirect3DBaseTexture9 *baseTexture = nullptr; + ANGLE_TRY(getBaseTexture(context, &baseTexture)); + + IDirect3DSurface9 *surface = nullptr; + ANGLE_TRY(getSurfaceLevel(context, gl::TextureTarget::_2D, index.getLevelIndex(), false, + &surface)); + + size_t textureMipLevel = mTopLevel + index.getLevelIndex(); + size_t mipWidth = std::max(mTextureWidth >> textureMipLevel, 1u); + size_t mipHeight = std::max(mTextureHeight >> textureMipLevel, 1u); + + baseTexture->AddRef(); + mRenderTargets[index.getLevelIndex()] = new TextureRenderTarget9( + baseTexture, textureMipLevel, surface, mInternalFormat, static_cast(mipWidth), + static_cast(mipHeight), 1, 0); + } + + ASSERT(outRT); + *outRT = mRenderTargets[index.getLevelIndex()]; + return angle::Result::Continue; +} + +angle::Result TextureStorage9_2D::generateMipmap(const gl::Context *context, + const gl::ImageIndex &sourceIndex, + const gl::ImageIndex &destIndex) +{ + angle::ComPtr upper = nullptr; + ANGLE_TRY(getSurfaceLevel(context, gl::TextureTarget::_2D, sourceIndex.getLevelIndex(), false, + &upper)); + + angle::ComPtr lower = nullptr; + ANGLE_TRY( + getSurfaceLevel(context, gl::TextureTarget::_2D, destIndex.getLevelIndex(), true, &lower)); + + ASSERT(upper && lower); + return mRenderer->boxFilter(GetImplAs(context), upper.Get(), lower.Get()); +} + +angle::Result TextureStorage9_2D::getBaseTexture(const gl::Context *context, + IDirect3DBaseTexture9 **outTexture) +{ + // if the width or height is not positive this should be treated as an incomplete texture + // we handle that here by skipping the d3d texture creation + if (mTexture == nullptr && mTextureWidth > 0 && mTextureHeight > 0) + { + ASSERT(mMipLevels > 0); + + IDirect3DDevice9 *device = mRenderer->getDevice(); + HRESULT result = device->CreateTexture(static_cast(mTextureWidth), + static_cast(mTextureHeight), + static_cast(mMipLevels), getUsage(), + mTextureFormat, getPool(), &mTexture, nullptr); + ANGLE_TRY_HR(GetImplAs(context), result, "Failed to create 2D storage texture"); + } + + *outTexture = mTexture; + return angle::Result::Continue; +} + +angle::Result TextureStorage9_2D::copyToStorage(const gl::Context *context, + TextureStorage *destStorage) +{ + ASSERT(destStorage); + + TextureStorage9_2D *dest9 = GetAs(destStorage); + + int levels = getLevelCount(); + for (int i = 0; i < levels; ++i) + { + angle::ComPtr srcSurf = nullptr; + ANGLE_TRY(getSurfaceLevel(context, gl::TextureTarget::_2D, i, false, &srcSurf)); + + angle::ComPtr dstSurf = nullptr; + ANGLE_TRY(dest9->getSurfaceLevel(context, gl::TextureTarget::_2D, i, true, &dstSurf)); + + ANGLE_TRY( + mRenderer->copyToRenderTarget(context, dstSurf.Get(), srcSurf.Get(), isManaged())); + } + + return angle::Result::Continue; +} + +TextureStorage9_EGLImage::TextureStorage9_EGLImage(Renderer9 *renderer, + EGLImageD3D *image, + RenderTarget9 *renderTarget9, + const std::string &label) + : TextureStorage9(renderer, D3DUSAGE_RENDERTARGET, label), mImage(image) +{ + + mInternalFormat = renderTarget9->getInternalFormat(); + mTextureFormat = renderTarget9->getD3DFormat(); + mTextureWidth = renderTarget9->getWidth(); + mTextureHeight = renderTarget9->getHeight(); + mTopLevel = static_cast(renderTarget9->getTextureLevel()); + mMipLevels = mTopLevel + 1; +} + +TextureStorage9_EGLImage::~TextureStorage9_EGLImage() {} + +angle::Result TextureStorage9_EGLImage::getSurfaceLevel(const gl::Context *context, + gl::TextureTarget target, + int level, + bool, + IDirect3DSurface9 **outSurface) +{ + ASSERT(target == gl::TextureTarget::_2D); + ASSERT(level == 0); + + RenderTargetD3D *renderTargetD3D = nullptr; + ANGLE_TRY(mImage->getRenderTarget(context, &renderTargetD3D)); + + RenderTarget9 *renderTarget9 = GetAs(renderTargetD3D); + + *outSurface = renderTarget9->getSurface(); + return angle::Result::Continue; +} + +angle::Result TextureStorage9_EGLImage::findRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) const +{ + // Since the render target of a EGL image will be updated when orphaning, trying to find a cache + // of it can be rarely useful. + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result TextureStorage9_EGLImage::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) +{ + ASSERT(!index.hasLayer()); + ASSERT(index.getLevelIndex() == 0); + ASSERT(samples == 0); + + return mImage->getRenderTarget(context, outRT); +} + +angle::Result TextureStorage9_EGLImage::getBaseTexture(const gl::Context *context, + IDirect3DBaseTexture9 **outTexture) +{ + RenderTargetD3D *renderTargetD3D = nullptr; + ANGLE_TRY(mImage->getRenderTarget(context, &renderTargetD3D)); + + RenderTarget9 *renderTarget9 = GetAs(renderTargetD3D); + *outTexture = renderTarget9->getTexture(); + ASSERT(*outTexture != nullptr); + + return angle::Result::Continue; +} + +angle::Result TextureStorage9_EGLImage::generateMipmap(const gl::Context *context, + const gl::ImageIndex &, + const gl::ImageIndex &) +{ + ANGLE_HR_UNREACHABLE(GetImplAs(context)); + return angle::Result::Stop; +} + +angle::Result TextureStorage9_EGLImage::copyToStorage(const gl::Context *context, + TextureStorage *destStorage) +{ + ASSERT(destStorage); + ASSERT(getLevelCount() == 1); + + TextureStorage9 *dest9 = GetAs(destStorage); + + IDirect3DBaseTexture9 *destBaseTexture9 = nullptr; + ANGLE_TRY(dest9->getBaseTexture(context, &destBaseTexture9)); + + IDirect3DTexture9 *destTexture9 = static_cast(destBaseTexture9); + + angle::ComPtr destSurface = nullptr; + HRESULT result = destTexture9->GetSurfaceLevel(destStorage->getTopLevel(), &destSurface); + ANGLE_TRY_HR(GetImplAs(context), result, "Failed to get the surface from a texture"); + + RenderTargetD3D *sourceRenderTarget = nullptr; + ANGLE_TRY(mImage->getRenderTarget(context, &sourceRenderTarget)); + + RenderTarget9 *sourceRenderTarget9 = GetAs(sourceRenderTarget); + ANGLE_TRY(mRenderer->copyToRenderTarget(context, destSurface.Get(), + sourceRenderTarget9->getSurface(), isManaged())); + + if (destStorage->getTopLevel() != 0) + { + destTexture9->AddDirtyRect(nullptr); + } + + return angle::Result::Continue; +} + +TextureStorage9_Cube::TextureStorage9_Cube(Renderer9 *renderer, + GLenum internalformat, + bool renderTarget, + int size, + int levels, + bool hintLevelZeroOnly, + const std::string &label) + : TextureStorage9(renderer, GetTextureUsage(internalformat, renderTarget), label) +{ + mTexture = nullptr; + for (size_t i = 0; i < gl::kCubeFaceCount; ++i) + { + mRenderTarget[i] = nullptr; + } + + mInternalFormat = internalformat; + + const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat); + mTextureFormat = d3dFormatInfo.texFormat; + + int height = size; + d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &size, &height, &mTopLevel); + mTextureWidth = size; + mTextureHeight = size; + mMipLevels = mTopLevel + levels; +} + +TextureStorage9_Cube::~TextureStorage9_Cube() +{ + SafeRelease(mTexture); + + for (size_t i = 0; i < gl::kCubeFaceCount; ++i) + { + SafeDelete(mRenderTarget[i]); + } +} + +// Increments refcount on surface. +// caller must Release() the returned surface +angle::Result TextureStorage9_Cube::getSurfaceLevel(const gl::Context *context, + gl::TextureTarget target, + int level, + bool dirty, + IDirect3DSurface9 **outSurface) +{ + IDirect3DBaseTexture9 *baseTexture = nullptr; + ANGLE_TRY(getBaseTexture(context, &baseTexture)); + + IDirect3DCubeTexture9 *texture = static_cast(baseTexture); + + D3DCUBEMAP_FACES face = gl_d3d9::ConvertCubeFace(target); + HRESULT result = texture->GetCubeMapSurface(face, level, outSurface); + ANGLE_TRY_HR(GetImplAs(context), result, "Failed to get the surface from a texture"); + + // With managed textures the driver needs to be informed of updates to the lower mipmap levels + if (level != 0 && isManaged() && dirty) + { + texture->AddDirtyRect(face, nullptr); + } + + return angle::Result::Continue; +} + +angle::Result TextureStorage9_Cube::findRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) const +{ + ASSERT(outRT); + ASSERT(index.getLevelIndex() == 0); + ASSERT(samples == 0); + + ASSERT(index.getType() == gl::TextureType::CubeMap && + gl::IsCubeMapFaceTarget(index.getTarget())); + const size_t renderTargetIndex = index.cubeMapFaceIndex(); + + *outRT = mRenderTarget[renderTargetIndex]; + return angle::Result::Continue; +} + +angle::Result TextureStorage9_Cube::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) +{ + ASSERT(outRT); + ASSERT(index.getLevelIndex() == 0); + ASSERT(samples == 0); + + ASSERT(index.getType() == gl::TextureType::CubeMap && + gl::IsCubeMapFaceTarget(index.getTarget())); + const size_t renderTargetIndex = index.cubeMapFaceIndex(); + + if (mRenderTarget[renderTargetIndex] == nullptr && isRenderTarget()) + { + IDirect3DBaseTexture9 *baseTexture = nullptr; + ANGLE_TRY(getBaseTexture(context, &baseTexture)); + + IDirect3DSurface9 *surface = nullptr; + ANGLE_TRY(getSurfaceLevel(context, index.getTarget(), mTopLevel + index.getLevelIndex(), + false, &surface)); + + baseTexture->AddRef(); + mRenderTarget[renderTargetIndex] = new TextureRenderTarget9( + baseTexture, mTopLevel + index.getLevelIndex(), surface, mInternalFormat, + static_cast(mTextureWidth), static_cast(mTextureHeight), 1, 0); + } + + *outRT = mRenderTarget[renderTargetIndex]; + return angle::Result::Continue; +} + +angle::Result TextureStorage9_Cube::generateMipmap(const gl::Context *context, + const gl::ImageIndex &sourceIndex, + const gl::ImageIndex &destIndex) +{ + angle::ComPtr upper = nullptr; + ANGLE_TRY(getSurfaceLevel(context, sourceIndex.getTarget(), sourceIndex.getLevelIndex(), false, + &upper)); + + angle::ComPtr lower = nullptr; + ANGLE_TRY( + getSurfaceLevel(context, destIndex.getTarget(), destIndex.getLevelIndex(), true, &lower)); + + ASSERT(upper && lower); + return mRenderer->boxFilter(GetImplAs(context), upper.Get(), lower.Get()); +} + +angle::Result TextureStorage9_Cube::getBaseTexture(const gl::Context *context, + IDirect3DBaseTexture9 **outTexture) +{ + // if the size is not positive this should be treated as an incomplete texture + // we handle that here by skipping the d3d texture creation + if (mTexture == nullptr && mTextureWidth > 0 && mTextureHeight > 0) + { + ASSERT(mMipLevels > 0); + ASSERT(mTextureWidth == mTextureHeight); + + IDirect3DDevice9 *device = mRenderer->getDevice(); + HRESULT result = device->CreateCubeTexture( + static_cast(mTextureWidth), static_cast(mMipLevels), + getUsage(), mTextureFormat, getPool(), &mTexture, nullptr); + ANGLE_TRY_HR(GetImplAs(context), result, "Failed to create cube storage texture"); + } + + *outTexture = mTexture; + return angle::Result::Continue; +} + +angle::Result TextureStorage9_Cube::copyToStorage(const gl::Context *context, + TextureStorage *destStorage) +{ + ASSERT(destStorage); + + TextureStorage9_Cube *dest9 = GetAs(destStorage); + + int levels = getLevelCount(); + for (gl::TextureTarget face : gl::AllCubeFaceTextureTargets()) + { + for (int i = 0; i < levels; i++) + { + angle::ComPtr srcSurf = nullptr; + ANGLE_TRY(getSurfaceLevel(context, face, i, false, &srcSurf)); + + angle::ComPtr dstSurf = nullptr; + ANGLE_TRY(dest9->getSurfaceLevel(context, face, i, true, &dstSurf)); + + ANGLE_TRY( + mRenderer->copyToRenderTarget(context, dstSurf.Get(), srcSurf.Get(), isManaged())); + } + } + + return angle::Result::Continue; +} +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h new file mode 100644 index 0000000000..9882c341f9 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h @@ -0,0 +1,186 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// TextureStorage9.h: Defines the abstract rx::TextureStorage9 class and its concrete derived +// classes TextureStorage9_2D and TextureStorage9_Cube, which act as the interface to the +// D3D9 texture. + +#ifndef LIBANGLE_RENDERER_D3D_D3D9_TEXTURESTORAGE9_H_ +#define LIBANGLE_RENDERER_D3D_D3D9_TEXTURESTORAGE9_H_ + +#include "common/debug.h" +#include "libANGLE/renderer/d3d/TextureStorage.h" + +namespace rx +{ +class EGLImageD3D; +class Renderer9; +class SwapChain9; +class RenderTargetD3D; +class RenderTarget9; + +class TextureStorage9 : public TextureStorage +{ + public: + ~TextureStorage9() override; + + static DWORD GetTextureUsage(GLenum internalformat, bool renderTarget); + + D3DPOOL getPool() const; + DWORD getUsage() const; + + virtual angle::Result getSurfaceLevel(const gl::Context *context, + gl::TextureTarget target, + int level, + bool dirty, + IDirect3DSurface9 **outSurface) = 0; + virtual angle::Result getBaseTexture(const gl::Context *context, + IDirect3DBaseTexture9 **outTexture) = 0; + + int getTopLevel() const override; + bool isRenderTarget() const override; + bool isUnorderedAccess() const override { return false; } + bool isManaged() const override; + bool supportsNativeMipmapFunction() const override; + int getLevelCount() const override; + + angle::Result setData(const gl::Context *context, + const gl::ImageIndex &index, + ImageD3D *image, + const gl::Box *destBox, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixelData) override; + + protected: + int mTopLevel; + size_t mMipLevels; + size_t mTextureWidth; + size_t mTextureHeight; + GLenum mInternalFormat; + D3DFORMAT mTextureFormat; + + Renderer9 *mRenderer; + + TextureStorage9(Renderer9 *renderer, DWORD usage, const std::string &label); + + private: + const DWORD mD3DUsage; + const D3DPOOL mD3DPool; +}; + +class TextureStorage9_2D : public TextureStorage9 +{ + public: + TextureStorage9_2D(Renderer9 *renderer, SwapChain9 *swapchain, const std::string &label); + TextureStorage9_2D(Renderer9 *renderer, + GLenum internalformat, + bool renderTarget, + GLsizei width, + GLsizei height, + int levels, + const std::string &label); + ~TextureStorage9_2D() override; + + angle::Result getSurfaceLevel(const gl::Context *context, + gl::TextureTarget target, + int level, + bool dirty, + IDirect3DSurface9 **outSurface) override; + angle::Result findRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) const override; + angle::Result getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) override; + angle::Result getBaseTexture(const gl::Context *context, + IDirect3DBaseTexture9 **outTexture) override; + angle::Result generateMipmap(const gl::Context *context, + const gl::ImageIndex &sourceIndex, + const gl::ImageIndex &destIndex) override; + angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override; + + private: + IDirect3DTexture9 *mTexture; + std::vector mRenderTargets; +}; + +class TextureStorage9_EGLImage final : public TextureStorage9 +{ + public: + TextureStorage9_EGLImage(Renderer9 *renderer, + EGLImageD3D *image, + RenderTarget9 *renderTarget9, + const std::string &label); + ~TextureStorage9_EGLImage() override; + + angle::Result getSurfaceLevel(const gl::Context *context, + gl::TextureTarget target, + int level, + bool dirty, + IDirect3DSurface9 **outSurface) override; + angle::Result findRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) const override; + angle::Result getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) override; + angle::Result getBaseTexture(const gl::Context *context, + IDirect3DBaseTexture9 **outTexture) override; + angle::Result generateMipmap(const gl::Context *context, + const gl::ImageIndex &sourceIndex, + const gl::ImageIndex &destIndex) override; + angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override; + + private: + EGLImageD3D *mImage; +}; + +class TextureStorage9_Cube : public TextureStorage9 +{ + public: + TextureStorage9_Cube(Renderer9 *renderer, + GLenum internalformat, + bool renderTarget, + int size, + int levels, + bool hintLevelZeroOnly, + const std::string &label); + + ~TextureStorage9_Cube() override; + + angle::Result getSurfaceLevel(const gl::Context *context, + gl::TextureTarget target, + int level, + bool dirty, + IDirect3DSurface9 **outSurface) override; + angle::Result findRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) const override; + angle::Result getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + GLsizei samples, + RenderTargetD3D **outRT) override; + angle::Result getBaseTexture(const gl::Context *context, + IDirect3DBaseTexture9 **outTexture) override; + angle::Result generateMipmap(const gl::Context *context, + const gl::ImageIndex &sourceIndex, + const gl::ImageIndex &destIndex) override; + angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override; + + private: + IDirect3DCubeTexture9 *mTexture; + RenderTarget9 *mRenderTarget[gl::kCubeFaceCount]; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D9_TEXTURESTORAGE9_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h new file mode 100644 index 0000000000..a9c1ee7d4b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h @@ -0,0 +1,57 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// VertexArray9.h: Defines the rx::VertexArray9 class which implements rx::VertexArrayImpl. + +#ifndef LIBANGLE_RENDERER_D3D_D3D9_VERTEXARRAY9_H_ +#define LIBANGLE_RENDERER_D3D_D3D9_VERTEXARRAY9_H_ + +#include "libANGLE/Context.h" +#include "libANGLE/renderer/VertexArrayImpl.h" +#include "libANGLE/renderer/d3d/d3d9/Context9.h" +#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" + +namespace rx +{ +class Renderer9; + +class VertexArray9 : public VertexArrayImpl +{ + public: + VertexArray9(const gl::VertexArrayState &data) : VertexArrayImpl(data) {} + + angle::Result syncState(const gl::Context *context, + const gl::VertexArray::DirtyBits &dirtyBits, + gl::VertexArray::DirtyAttribBitsArray *attribBits, + gl::VertexArray::DirtyBindingBitsArray *bindingBits) override; + + ~VertexArray9() override {} + + Serial getCurrentStateSerial() const { return mCurrentStateSerial; } + + private: + Serial mCurrentStateSerial; +}; + +inline angle::Result VertexArray9::syncState(const gl::Context *context, + const gl::VertexArray::DirtyBits &dirtyBits, + gl::VertexArray::DirtyAttribBitsArray *attribBits, + gl::VertexArray::DirtyBindingBitsArray *bindingBits) +{ + + ASSERT(dirtyBits.any()); + Renderer9 *renderer = GetImplAs(context)->getRenderer(); + mCurrentStateSerial = renderer->generateSerial(); + + // Clear the dirty bits in the back-end here. + memset(attribBits, 0, sizeof(gl::VertexArray::DirtyAttribBitsArray)); + memset(bindingBits, 0, sizeof(gl::VertexArray::DirtyBindingBitsArray)); + + return angle::Result::Continue; +} +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D9_VERTEXARRAY9_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp new file mode 100644 index 0000000000..915928686a --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp @@ -0,0 +1,153 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// VertexBuffer9.cpp: Defines the D3D9 VertexBuffer implementation. + +#include "libANGLE/renderer/d3d/d3d9/VertexBuffer9.h" + +#include "libANGLE/Buffer.h" +#include "libANGLE/Context.h" +#include "libANGLE/VertexAttribute.h" +#include "libANGLE/renderer/d3d/BufferD3D.h" +#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" +#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" +#include "libANGLE/renderer/d3d/d3d9/vertexconversion.h" + +namespace rx +{ + +VertexBuffer9::VertexBuffer9(Renderer9 *renderer) : mRenderer(renderer) +{ + mVertexBuffer = nullptr; + mBufferSize = 0; + mDynamicUsage = false; +} + +VertexBuffer9::~VertexBuffer9() +{ + SafeRelease(mVertexBuffer); +} + +angle::Result VertexBuffer9::initialize(const gl::Context *context, + unsigned int size, + bool dynamicUsage) +{ + SafeRelease(mVertexBuffer); + + updateSerial(); + + if (size > 0) + { + DWORD flags = D3DUSAGE_WRITEONLY; + if (dynamicUsage) + { + flags |= D3DUSAGE_DYNAMIC; + } + + HRESULT result = mRenderer->createVertexBuffer(size, flags, &mVertexBuffer); + ANGLE_TRY_HR(GetImplAs(context), result, + "Failed to allocate internal vertex buffer"); + } + + mBufferSize = size; + mDynamicUsage = dynamicUsage; + return angle::Result::Continue; +} + +angle::Result VertexBuffer9::storeVertexAttributes(const gl::Context *context, + const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + gl::VertexAttribType currentValueType, + GLint start, + size_t count, + GLsizei instances, + unsigned int offset, + const uint8_t *sourceData) +{ + ASSERT(mVertexBuffer); + + size_t inputStride = gl::ComputeVertexAttributeStride(attrib, binding); + size_t elementSize = gl::ComputeVertexAttributeTypeSize(attrib); + + DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0; + + uint8_t *mapPtr = nullptr; + + unsigned int mapSize = 0; + ANGLE_TRY( + mRenderer->getVertexSpaceRequired(context, attrib, binding, count, instances, 0, &mapSize)); + + HRESULT result = + mVertexBuffer->Lock(offset, mapSize, reinterpret_cast(&mapPtr), lockFlags); + ANGLE_TRY_HR(GetImplAs(context), result, "Failed to lock internal vertex buffer"); + + const uint8_t *input = sourceData; + + if (instances == 0 || binding.getDivisor() == 0) + { + input += inputStride * start; + } + + angle::FormatID vertexFormatID = gl::GetVertexFormatID(attrib, currentValueType); + const d3d9::VertexFormat &d3dVertexInfo = + d3d9::GetVertexFormatInfo(mRenderer->getCapsDeclTypes(), vertexFormatID); + bool needsConversion = (d3dVertexInfo.conversionType & VERTEX_CONVERT_CPU) > 0; + + if (!needsConversion && inputStride == elementSize) + { + size_t copySize = count * inputStride; + memcpy(mapPtr, input, copySize); + } + else + { + d3dVertexInfo.copyFunction(input, inputStride, count, mapPtr); + } + + mVertexBuffer->Unlock(); + + return angle::Result::Continue; +} + +unsigned int VertexBuffer9::getBufferSize() const +{ + return mBufferSize; +} + +angle::Result VertexBuffer9::setBufferSize(const gl::Context *context, unsigned int size) +{ + if (size > mBufferSize) + { + return initialize(context, size, mDynamicUsage); + } + else + { + return angle::Result::Continue; + } +} + +angle::Result VertexBuffer9::discard(const gl::Context *context) +{ + ASSERT(mVertexBuffer); + + void *mock; + HRESULT result; + + Context9 *context9 = GetImplAs(context); + + result = mVertexBuffer->Lock(0, 1, &mock, D3DLOCK_DISCARD); + ANGLE_TRY_HR(context9, result, "Failed to lock internal vertex buffer for discarding"); + + result = mVertexBuffer->Unlock(); + ANGLE_TRY_HR(context9, result, "Failed to unlock internal vertex buffer for discarding"); + + return angle::Result::Continue; +} + +IDirect3DVertexBuffer9 *VertexBuffer9::getBuffer() const +{ + return mVertexBuffer; +} +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h new file mode 100644 index 0000000000..d5c156e5f5 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h @@ -0,0 +1,56 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// VertexBuffer9.h: Defines the D3D9 VertexBuffer implementation. + +#ifndef LIBANGLE_RENDERER_D3D_D3D9_VERTEXBUFFER9_H_ +#define LIBANGLE_RENDERER_D3D_D3D9_VERTEXBUFFER9_H_ + +#include "libANGLE/renderer/d3d/VertexBuffer.h" + +namespace rx +{ +class Renderer9; + +class VertexBuffer9 : public VertexBuffer +{ + public: + explicit VertexBuffer9(Renderer9 *renderer); + + angle::Result initialize(const gl::Context *context, + unsigned int size, + bool dynamicUsage) override; + + // Warning: you should ensure binding really matches attrib.bindingIndex before using this + // function. + angle::Result storeVertexAttributes(const gl::Context *context, + const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + gl::VertexAttribType currentValueType, + GLint start, + size_t count, + GLsizei instances, + unsigned int offset, + const uint8_t *sourceData) override; + + unsigned int getBufferSize() const override; + angle::Result setBufferSize(const gl::Context *context, unsigned int size) override; + angle::Result discard(const gl::Context *context) override; + + IDirect3DVertexBuffer9 *getBuffer() const; + + private: + ~VertexBuffer9() override; + Renderer9 *mRenderer; + + IDirect3DVertexBuffer9 *mVertexBuffer; + unsigned int mBufferSize; + bool mDynamicUsage; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D9_VERTEXBUFFER9_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp new file mode 100644 index 0000000000..e129ae9786 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp @@ -0,0 +1,262 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// VertexDeclarationCache.cpp: Implements a helper class to construct and cache vertex declarations. + +#include "libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h" + +#include "libANGLE/Context.h" +#include "libANGLE/VertexAttribute.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/ProgramD3D.h" +#include "libANGLE/renderer/d3d/d3d9/Context9.h" +#include "libANGLE/renderer/d3d/d3d9/VertexBuffer9.h" +#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" + +namespace rx +{ + +VertexDeclarationCache::VertexDeclarationCache() : mMaxLru(0) +{ + for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++) + { + mVertexDeclCache[i].vertexDeclaration = nullptr; + mVertexDeclCache[i].lruCount = 0; + } + + for (VBData &vb : mAppliedVBs) + { + vb.serial = 0; + } + + mLastSetVDecl = nullptr; + mInstancingEnabled = true; +} + +VertexDeclarationCache::~VertexDeclarationCache() +{ + for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++) + { + SafeRelease(mVertexDeclCache[i].vertexDeclaration); + } +} + +angle::Result VertexDeclarationCache::applyDeclaration( + const gl::Context *context, + IDirect3DDevice9 *device, + const std::vector &attributes, + gl::Program *program, + GLint start, + GLsizei instances, + GLsizei *repeatDraw) +{ + ASSERT(gl::MAX_VERTEX_ATTRIBS >= attributes.size()); + + *repeatDraw = 1; + + const size_t invalidAttribIndex = attributes.size(); + size_t indexedAttribute = invalidAttribIndex; + size_t instancedAttribute = invalidAttribIndex; + + if (instances == 0) + { + for (size_t i = 0; i < attributes.size(); ++i) + { + if (attributes[i].divisor != 0) + { + // If a divisor is set, it still applies even if an instanced draw was not used, so + // treat as a single-instance draw. + instances = 1; + break; + } + } + } + + if (instances > 0) + { + // Find an indexed attribute to be mapped to D3D stream 0 + for (size_t i = 0; i < attributes.size(); i++) + { + if (attributes[i].active) + { + if (indexedAttribute == invalidAttribIndex && attributes[i].divisor == 0) + { + indexedAttribute = i; + } + else if (instancedAttribute == invalidAttribIndex && attributes[i].divisor != 0) + { + instancedAttribute = i; + } + if (indexedAttribute != invalidAttribIndex && + instancedAttribute != invalidAttribIndex) + break; // Found both an indexed and instanced attribute + } + } + + // The validation layer checks that there is at least one active attribute with a zero + // divisor as per the GL_ANGLE_instanced_arrays spec. + ASSERT(indexedAttribute != invalidAttribIndex); + } + + D3DCAPS9 caps; + device->GetDeviceCaps(&caps); + + D3DVERTEXELEMENT9 elements[gl::MAX_VERTEX_ATTRIBS + 1]; + D3DVERTEXELEMENT9 *element = &elements[0]; + + ProgramD3D *programD3D = GetImplAs(program); + const auto &semanticIndexes = programD3D->getAttribLocationToD3DSemantics(); + + for (size_t i = 0; i < attributes.size(); i++) + { + if (attributes[i].active) + { + // Directly binding the storage buffer is not supported for d3d9 + ASSERT(attributes[i].storage == nullptr); + + int stream = static_cast(i); + + if (instances > 0) + { + // Due to a bug on ATI cards we can't enable instancing when none of the attributes + // are instanced. + if (instancedAttribute == invalidAttribIndex) + { + *repeatDraw = instances; + } + else + { + if (i == indexedAttribute) + { + stream = 0; + } + else if (i == 0) + { + stream = static_cast(indexedAttribute); + } + + UINT frequency = 1; + + if (attributes[i].divisor == 0) + { + frequency = D3DSTREAMSOURCE_INDEXEDDATA | instances; + } + else + { + frequency = D3DSTREAMSOURCE_INSTANCEDATA | attributes[i].divisor; + } + + device->SetStreamSourceFreq(stream, frequency); + mInstancingEnabled = true; + } + } + + VertexBuffer9 *vertexBuffer = GetAs(attributes[i].vertexBuffer.get()); + + unsigned int offset = 0; + ANGLE_TRY(attributes[i].computeOffset(context, start, &offset)); + + if (mAppliedVBs[stream].serial != attributes[i].serial || + mAppliedVBs[stream].stride != attributes[i].stride || + mAppliedVBs[stream].offset != offset) + { + device->SetStreamSource(stream, vertexBuffer->getBuffer(), offset, + attributes[i].stride); + mAppliedVBs[stream].serial = attributes[i].serial; + mAppliedVBs[stream].stride = attributes[i].stride; + mAppliedVBs[stream].offset = offset; + } + + angle::FormatID vertexformatID = + gl::GetVertexFormatID(*attributes[i].attribute, gl::VertexAttribType::Float); + const d3d9::VertexFormat &d3d9VertexInfo = + d3d9::GetVertexFormatInfo(caps.DeclTypes, vertexformatID); + + element->Stream = static_cast(stream); + element->Offset = 0; + element->Type = static_cast(d3d9VertexInfo.nativeFormat); + element->Method = D3DDECLMETHOD_DEFAULT; + element->Usage = D3DDECLUSAGE_TEXCOORD; + element->UsageIndex = static_cast(semanticIndexes[i]); + element++; + } + } + + if (instances == 0 || instancedAttribute == invalidAttribIndex) + { + if (mInstancingEnabled) + { + for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + { + device->SetStreamSourceFreq(i, 1); + } + + mInstancingEnabled = false; + } + } + + static const D3DVERTEXELEMENT9 end = D3DDECL_END(); + *(element++) = end; + + for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++) + { + VertexDeclCacheEntry *entry = &mVertexDeclCache[i]; + if (memcmp(entry->cachedElements, elements, + (element - elements) * sizeof(D3DVERTEXELEMENT9)) == 0 && + entry->vertexDeclaration) + { + entry->lruCount = ++mMaxLru; + if (entry->vertexDeclaration != mLastSetVDecl) + { + device->SetVertexDeclaration(entry->vertexDeclaration); + mLastSetVDecl = entry->vertexDeclaration; + } + + return angle::Result::Continue; + } + } + + VertexDeclCacheEntry *lastCache = mVertexDeclCache; + + for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++) + { + if (mVertexDeclCache[i].lruCount < lastCache->lruCount) + { + lastCache = &mVertexDeclCache[i]; + } + } + + if (lastCache->vertexDeclaration != nullptr) + { + SafeRelease(lastCache->vertexDeclaration); + // mLastSetVDecl is set to the replacement, so we don't have to worry + // about it. + } + + memcpy(lastCache->cachedElements, elements, (element - elements) * sizeof(D3DVERTEXELEMENT9)); + HRESULT result = device->CreateVertexDeclaration(elements, &lastCache->vertexDeclaration); + ANGLE_TRY_HR(GetImplAs(context), result, + "Failed to create internal vertex declaration"); + + device->SetVertexDeclaration(lastCache->vertexDeclaration); + mLastSetVDecl = lastCache->vertexDeclaration; + lastCache->lruCount = ++mMaxLru; + + return angle::Result::Continue; +} + +void VertexDeclarationCache::markStateDirty() +{ + for (VBData &vb : mAppliedVBs) + { + vb.serial = 0; + } + + mLastSetVDecl = nullptr; + mInstancingEnabled = true; // Forces it to be disabled when not used +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h new file mode 100644 index 0000000000..22e677d800 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h @@ -0,0 +1,68 @@ +// +// Copyright 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// VertexDeclarationCache.h: Defines a helper class to construct and cache vertex declarations. + +#ifndef LIBANGLE_RENDERER_D3D_D3D9_VERTEXDECLARATIONCACHE_H_ +#define LIBANGLE_RENDERER_D3D_D3D9_VERTEXDECLARATIONCACHE_H_ + +#include "libANGLE/Error.h" +#include "libANGLE/renderer/d3d/VertexDataManager.h" + +namespace gl +{ +class VertexDataManager; +class Program; +} // namespace gl + +namespace rx +{ +class VertexDeclarationCache +{ + public: + VertexDeclarationCache(); + ~VertexDeclarationCache(); + + angle::Result applyDeclaration(const gl::Context *context, + IDirect3DDevice9 *device, + const std::vector &attributes, + gl::Program *program, + GLint start, + GLsizei instances, + GLsizei *repeatDraw); + + void markStateDirty(); + + private: + UINT mMaxLru; + + enum + { + NUM_VERTEX_DECL_CACHE_ENTRIES = 32 + }; + + struct VBData + { + unsigned int serial; + unsigned int stride; + unsigned int offset; + }; + + VBData mAppliedVBs[gl::MAX_VERTEX_ATTRIBS]; + IDirect3DVertexDeclaration9 *mLastSetVDecl; + bool mInstancingEnabled; + + struct VertexDeclCacheEntry + { + D3DVERTEXELEMENT9 cachedElements[gl::MAX_VERTEX_ATTRIBS + 1]; + UINT lruCount; + IDirect3DVertexDeclaration9 *vertexDeclaration; + } mVertexDeclCache[NUM_VERTEX_DECL_CACHE_ENTRIES]; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D9_VERTEXDECLARATIONCACHE_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp new file mode 100644 index 0000000000..19a10b9cfb --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp @@ -0,0 +1,695 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// formatutils9.cpp: Queries for GL image formats and their translations to D3D9 +// formats. + +#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" + +#include "image_util/copyimage.h" +#include "image_util/generatemip.h" +#include "image_util/loadimage.h" + +#include "anglebase/no_destructor.h" +#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" +#include "libANGLE/renderer/d3d/d3d9/vertexconversion.h" + +using namespace angle; + +namespace rx +{ + +namespace d3d9 +{ + +constexpr D3DFORMAT D3DFMT_INTZ = ((D3DFORMAT)(MAKEFOURCC('I', 'N', 'T', 'Z'))); +constexpr D3DFORMAT D3DFMT_NULL = ((D3DFORMAT)(MAKEFOURCC('N', 'U', 'L', 'L'))); + +// A map to determine the pixel size and mip generation function of a given D3D format +typedef std::map D3D9FormatInfoMap; + +typedef std::pair InternalFormatInitialzerPair; +typedef std::map InternalFormatInitialzerMap; + +static InternalFormatInitialzerMap BuildInternalFormatInitialzerMap() +{ + using namespace angle; // For image initialization functions + + InternalFormatInitialzerMap map; + + map.insert(InternalFormatInitialzerPair( + GL_RGB16F, Initialize4ComponentData)); + map.insert(InternalFormatInitialzerPair( + GL_RGB32F, + Initialize4ComponentData)); + + return map; +} + +static void UnreachableLoad(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + UNREACHABLE(); +} + +typedef std::pair D3D9FormatPair; +typedef std::map D3D9FormatMap; + +TextureFormat::TextureFormat() + : texFormat(D3DFMT_UNKNOWN), + renderFormat(D3DFMT_UNKNOWN), + dataInitializerFunction(nullptr), + loadFunction(UnreachableLoad) +{} + +static inline void InsertD3D9FormatInfo(D3D9FormatMap *map, + GLenum internalFormat, + D3DFORMAT texFormat, + D3DFORMAT renderFormat, + LoadImageFunction loadFunction) +{ + TextureFormat info; + info.texFormat = texFormat; + info.renderFormat = renderFormat; + + static const angle::base::NoDestructor dataInitializationMap( + BuildInternalFormatInitialzerMap()); + InternalFormatInitialzerMap::const_iterator dataInitIter = + dataInitializationMap->find(internalFormat); + info.dataInitializerFunction = + (dataInitIter != dataInitializationMap->end()) ? dataInitIter->second : nullptr; + + info.loadFunction = loadFunction; + + map->insert(std::make_pair(internalFormat, info)); +} + +static D3D9FormatMap BuildD3D9FormatMap() +{ + using namespace angle; // For image loading functions + + D3D9FormatMap map; + + // clang-format off + // | Internal format | Texture format | Render format | Load function | + InsertD3D9FormatInfo(&map, GL_NONE, D3DFMT_NULL, D3DFMT_NULL, UnreachableLoad ); + + // We choose to downsample the GL_DEPTH_COMPONENT32_OES format to a 24-bit format because D3DFMT_D32 is not widely + // supported. We're allowed to do this because: + // - The ES spec 2.0.25 sec 3.7.1 states that we're allowed to store texture formats with internal format + // resolutions of our own choosing. + // - OES_depth_texture states that downsampling of the depth formats is allowed. + // - ANGLE_depth_texture does not state minimum required resolutions of the depth texture formats it + // introduces. + // In ES3 however, there are minimum resolutions for the texture formats and this would not be allowed. + + InsertD3D9FormatInfo(&map, GL_DEPTH_COMPONENT16, D3DFMT_INTZ, D3DFMT_D24S8, UnreachableLoad ); + InsertD3D9FormatInfo(&map, GL_DEPTH_COMPONENT32_OES, D3DFMT_INTZ, D3DFMT_D24X8, UnreachableLoad ); + InsertD3D9FormatInfo(&map, GL_DEPTH24_STENCIL8_OES, D3DFMT_INTZ, D3DFMT_D24S8, UnreachableLoad ); + InsertD3D9FormatInfo(&map, GL_STENCIL_INDEX8, D3DFMT_UNKNOWN, D3DFMT_D24S8, UnreachableLoad ); // TODO: What's the texture format? + + InsertD3D9FormatInfo(&map, GL_RGBA32F_EXT, D3DFMT_A32B32G32R32F, D3DFMT_A32B32G32R32F, LoadToNative ); + InsertD3D9FormatInfo(&map, GL_RGB32F_EXT, D3DFMT_A32B32G32R32F, D3DFMT_A32B32G32R32F, LoadToNative3To4); + InsertD3D9FormatInfo(&map, GL_RG32F_EXT, D3DFMT_G32R32F, D3DFMT_G32R32F, LoadToNative ); + InsertD3D9FormatInfo(&map, GL_R32F_EXT, D3DFMT_R32F, D3DFMT_R32F, LoadToNative ); + InsertD3D9FormatInfo(&map, GL_ALPHA32F_EXT, D3DFMT_A32B32G32R32F, D3DFMT_UNKNOWN, LoadA32FToRGBA32F ); + InsertD3D9FormatInfo(&map, GL_LUMINANCE32F_EXT, D3DFMT_A32B32G32R32F, D3DFMT_UNKNOWN, LoadL32FToRGBA32F ); + InsertD3D9FormatInfo(&map, GL_LUMINANCE_ALPHA32F_EXT, D3DFMT_A32B32G32R32F, D3DFMT_UNKNOWN, LoadLA32FToRGBA32F ); + + InsertD3D9FormatInfo(&map, GL_RGBA16F_EXT, D3DFMT_A16B16G16R16F, D3DFMT_A16B16G16R16F, LoadToNative ); + InsertD3D9FormatInfo(&map, GL_RGB16F_EXT, D3DFMT_A16B16G16R16F, D3DFMT_A16B16G16R16F, LoadToNative3To4 ); + InsertD3D9FormatInfo(&map, GL_RG16F_EXT, D3DFMT_G16R16F, D3DFMT_G16R16F, LoadToNative ); + InsertD3D9FormatInfo(&map, GL_R16F_EXT, D3DFMT_R16F, D3DFMT_R16F, LoadToNative ); + InsertD3D9FormatInfo(&map, GL_ALPHA16F_EXT, D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN, LoadA16FToRGBA16F ); + InsertD3D9FormatInfo(&map, GL_LUMINANCE16F_EXT, D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN, LoadL16FToRGBA16F ); + InsertD3D9FormatInfo(&map, GL_LUMINANCE_ALPHA16F_EXT, D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN, LoadLA16FToRGBA16F ); + + InsertD3D9FormatInfo(&map, GL_ALPHA8_EXT, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadA8ToBGRA8 ); + + InsertD3D9FormatInfo(&map, GL_RGB8_OES, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadRGB8ToBGRX8 ); + InsertD3D9FormatInfo(&map, GL_RGB565, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadR5G6B5ToBGRA8 ); + InsertD3D9FormatInfo(&map, GL_RGBA8_OES, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadRGBA8ToBGRA8 ); + InsertD3D9FormatInfo(&map, GL_RGBA4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadRGBA4ToBGRA8 ); + InsertD3D9FormatInfo(&map, GL_RGB5_A1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadRGB5A1ToBGRA8 ); + InsertD3D9FormatInfo(&map, GL_R8_EXT, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadR8ToBGRX8 ); + InsertD3D9FormatInfo(&map, GL_RG8_EXT, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadRG8ToBGRX8 ); + + InsertD3D9FormatInfo(&map, GL_SRGB8, D3DFMT_X8R8G8B8, D3DFMT_UNKNOWN, LoadRGB8ToBGRX8 ); + InsertD3D9FormatInfo(&map, GL_SRGB8_ALPHA8_EXT, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadRGBA8ToBGRA8 ); + + InsertD3D9FormatInfo(&map, GL_BGRA8_EXT, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadToNative ); + InsertD3D9FormatInfo(&map, GL_BGRA4_ANGLEX, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadBGRA4ToBGRA8 ); + InsertD3D9FormatInfo(&map, GL_BGR5_A1_ANGLEX, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadBGR5A1ToBGRA8 ); + + InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, D3DFMT_DXT1, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 1, 8> ); + InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, D3DFMT_DXT1, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 1, 8> ); + InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, D3DFMT_DXT3, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 1, 16> ); + InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, D3DFMT_DXT5, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 1, 16> ); + + InsertD3D9FormatInfo(&map, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, D3DFMT_DXT1, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 1, 8> ); + InsertD3D9FormatInfo(&map, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, D3DFMT_DXT1, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 1, 8> ); + InsertD3D9FormatInfo(&map, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, D3DFMT_DXT3, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 1, 16> ); + InsertD3D9FormatInfo(&map, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, D3DFMT_DXT5, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 1, 16> ); + + // These formats require checking if the renderer supports D3DFMT_L8 or D3DFMT_A8L8 and + // then changing the format and loading function appropriately. + InsertD3D9FormatInfo(&map, GL_LUMINANCE8_EXT, D3DFMT_L8, D3DFMT_UNKNOWN, LoadToNative ); + InsertD3D9FormatInfo(&map, GL_LUMINANCE8_ALPHA8_EXT, D3DFMT_A8L8, D3DFMT_UNKNOWN, LoadToNative ); + // clang-format on + + return map; +} + +const TextureFormat &GetTextureFormatInfo(GLenum internalFormat) +{ + static const angle::base::NoDestructor formatMap(BuildD3D9FormatMap()); + D3D9FormatMap::const_iterator iter = formatMap->find(internalFormat); + if (iter != formatMap->end()) + { + return iter->second; + } + else + { + static const TextureFormat defaultInfo; + return defaultInfo; + } +} + +static GLenum GetDeclTypeComponentType(D3DDECLTYPE declType) +{ + switch (declType) + { + case D3DDECLTYPE_FLOAT1: + return GL_FLOAT; + case D3DDECLTYPE_FLOAT2: + return GL_FLOAT; + case D3DDECLTYPE_FLOAT3: + return GL_FLOAT; + case D3DDECLTYPE_FLOAT4: + return GL_FLOAT; + case D3DDECLTYPE_UBYTE4: + return GL_UNSIGNED_INT; + case D3DDECLTYPE_SHORT2: + return GL_INT; + case D3DDECLTYPE_SHORT4: + return GL_INT; + case D3DDECLTYPE_UBYTE4N: + return GL_UNSIGNED_NORMALIZED; + case D3DDECLTYPE_SHORT4N: + return GL_SIGNED_NORMALIZED; + case D3DDECLTYPE_USHORT4N: + return GL_UNSIGNED_NORMALIZED; + case D3DDECLTYPE_SHORT2N: + return GL_SIGNED_NORMALIZED; + case D3DDECLTYPE_USHORT2N: + return GL_UNSIGNED_NORMALIZED; + default: + UNREACHABLE(); + return GL_NONE; + } +} + +// Attribute format conversion +enum +{ + NUM_GL_VERTEX_ATTRIB_TYPES = 6 +}; + +struct TranslationDescription +{ + DWORD capsFlag; + VertexFormat preferredConversion; + VertexFormat fallbackConversion; +}; + +// Mapping from OpenGL-ES vertex attrib type to D3D decl type: +// +// BYTE SHORT (Cast) +// BYTE-norm FLOAT (Normalize) (can't be exactly represented as SHORT-norm) +// UNSIGNED_BYTE UBYTE4 (Identity) or SHORT (Cast) +// UNSIGNED_BYTE-norm UBYTE4N (Identity) or FLOAT (Normalize) +// SHORT SHORT (Identity) +// SHORT-norm SHORT-norm (Identity) or FLOAT (Normalize) +// UNSIGNED_SHORT FLOAT (Cast) +// UNSIGNED_SHORT-norm USHORT-norm (Identity) or FLOAT (Normalize) +// FIXED (not in WebGL) FLOAT (FixedToFloat) +// FLOAT FLOAT (Identity) + +// GLToCType maps from GL type (as GLenum) to the C typedef. +template +struct GLToCType +{}; + +template <> +struct GLToCType +{ + typedef GLbyte type; +}; +template <> +struct GLToCType +{ + typedef GLubyte type; +}; +template <> +struct GLToCType +{ + typedef GLshort type; +}; +template <> +struct GLToCType +{ + typedef GLushort type; +}; +template <> +struct GLToCType +{ + typedef GLuint type; +}; +template <> +struct GLToCType +{ + typedef GLfloat type; +}; + +// This differs from D3DDECLTYPE in that it is unsized. (Size expansion is applied last.) +enum D3DVertexType +{ + D3DVT_FLOAT, + D3DVT_SHORT, + D3DVT_SHORT_NORM, + D3DVT_UBYTE, + D3DVT_UBYTE_NORM, + D3DVT_USHORT_NORM +}; + +// D3DToCType maps from D3D vertex type (as enum D3DVertexType) to the corresponding C type. +template +struct D3DToCType +{}; + +template <> +struct D3DToCType +{ + typedef float type; +}; +template <> +struct D3DToCType +{ + typedef short type; +}; +template <> +struct D3DToCType +{ + typedef short type; +}; +template <> +struct D3DToCType +{ + typedef unsigned char type; +}; +template <> +struct D3DToCType +{ + typedef unsigned char type; +}; +template <> +struct D3DToCType +{ + typedef unsigned short type; +}; + +// Encode the type/size combinations that D3D permits. For each type/size it expands to a widener +// that will provide the appropriate final size. +template +struct WidenRule +{}; + +template +struct WidenRule : NoWiden +{}; +template +struct WidenRule : WidenToEven +{}; +template +struct WidenRule : WidenToEven +{}; +template +struct WidenRule : WidenToFour +{}; +template +struct WidenRule : WidenToFour +{}; +template +struct WidenRule : WidenToEven +{}; + +// VertexTypeFlags encodes the D3DCAPS9::DeclType flag and vertex declaration flag for each D3D +// vertex type & size combination. +template +struct VertexTypeFlags +{}; + +template +struct VertexTypeFlagsHelper +{ + enum + { + capflag = _capflag + }; + enum + { + declflag = _declflag + }; +}; + +template <> +struct VertexTypeFlags : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT1> +{}; +template <> +struct VertexTypeFlags : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT2> +{}; +template <> +struct VertexTypeFlags : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT3> +{}; +template <> +struct VertexTypeFlags : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT4> +{}; +template <> +struct VertexTypeFlags : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT2> +{}; +template <> +struct VertexTypeFlags : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT4> +{}; +template <> +struct VertexTypeFlags + : VertexTypeFlagsHelper +{}; +template <> +struct VertexTypeFlags + : VertexTypeFlagsHelper +{}; +template <> +struct VertexTypeFlags : VertexTypeFlagsHelper +{}; +template <> +struct VertexTypeFlags + : VertexTypeFlagsHelper +{}; +template <> +struct VertexTypeFlags + : VertexTypeFlagsHelper +{}; +template <> +struct VertexTypeFlags + : VertexTypeFlagsHelper +{}; + +// VertexTypeMapping maps GL type & normalized flag to preferred and fallback D3D vertex types (as +// D3DVertexType enums). +template +struct VertexTypeMapping +{}; + +template +struct VertexTypeMappingBase +{ + enum + { + preferred = Preferred + }; + enum + { + fallback = Fallback + }; +}; + +template <> +struct VertexTypeMapping : VertexTypeMappingBase +{}; // Cast +template <> +struct VertexTypeMapping : VertexTypeMappingBase +{}; // Normalize +template <> +struct VertexTypeMapping : VertexTypeMappingBase +{}; // Identity, Cast +template <> +struct VertexTypeMapping + : VertexTypeMappingBase +{}; // Identity, Normalize +template <> +struct VertexTypeMapping : VertexTypeMappingBase +{}; // Identity +template <> +struct VertexTypeMapping : VertexTypeMappingBase +{}; // Cast, Normalize +template <> +struct VertexTypeMapping : VertexTypeMappingBase +{}; // Cast +template <> +struct VertexTypeMapping + : VertexTypeMappingBase +{}; // Cast, Normalize +template +struct VertexTypeMapping : VertexTypeMappingBase +{}; // FixedToFloat +template +struct VertexTypeMapping : VertexTypeMappingBase +{}; // Identity + +// Given a GL type & norm flag and a D3D type, ConversionRule provides the type conversion rule +// (Cast, Normalize, Identity, FixedToFloat). The conversion rules themselves are defined in +// vertexconversion.h. + +// Almost all cases are covered by Cast (including those that are actually Identity since Cast +// knows it's an identity mapping). +template +struct ConversionRule : Cast::type, typename D3DToCType::type> +{}; + +// All conversions from normalized types to float use the Normalize operator. +template +struct ConversionRule : Normalize::type> +{}; + +// Use a full specialization for this so that it preferentially matches ahead of the generic +// normalize-to-float rules. +template <> +struct ConversionRule : FixedToFloat +{}; +template <> +struct ConversionRule : FixedToFloat +{}; + +// A 2-stage construction is used for DefaultVertexValues because float must use SimpleDefaultValues +// (i.e. 0/1) whether it is normalized or not. +template +struct DefaultVertexValuesStage2 +{}; + +template +struct DefaultVertexValuesStage2 : NormalizedDefaultValues +{}; +template +struct DefaultVertexValuesStage2 : SimpleDefaultValues +{}; + +// Work out the default value rule for a D3D type (expressed as the C type) and +template +struct DefaultVertexValues : DefaultVertexValuesStage2 +{}; +template +struct DefaultVertexValues : SimpleDefaultValues +{}; + +// Policy rules for use with Converter, to choose whether to use the preferred or fallback +// conversion. The fallback conversion produces an output that all D3D9 devices must support. +template +struct UsePreferred +{ + enum + { + type = T::preferred + }; +}; +template +struct UseFallback +{ + enum + { + type = T::fallback + }; +}; + +// Converter ties it all together. Given an OpenGL type/norm/size and choice of preferred/fallback +// conversion, it provides all the members of the appropriate VertexDataConverter, the +// D3DCAPS9::DeclTypes flag in cap flag and the D3DDECLTYPE member needed for the vertex declaration +// in declflag. +template class PreferenceRule> +struct Converter + : VertexDataConverter< + typename GLToCType::type, + WidenRule>::type, size>, + ConversionRule>::type>, + DefaultVertexValues>::type>::type, + normalized>> +{ + private: + enum + { + d3dtype = PreferenceRule>::type + }; + enum + { + d3dsize = WidenRule::finalWidth + }; + + public: + enum + { + capflag = VertexTypeFlags::capflag + }; + enum + { + declflag = VertexTypeFlags::declflag + }; +}; + +VertexFormat::VertexFormat() + : conversionType(VERTEX_CONVERT_NONE), + outputElementSize(0), + copyFunction(nullptr), + nativeFormat(D3DDECLTYPE_UNUSED), + componentType(GL_NONE) +{} + +// Initialize a TranslationInfo +VertexFormat CreateVertexFormatInfo(bool identity, + size_t elementSize, + VertexCopyFunction copyFunc, + D3DDECLTYPE nativeFormat) +{ + VertexFormat formatInfo; + formatInfo.conversionType = identity ? VERTEX_CONVERT_NONE : VERTEX_CONVERT_CPU; + formatInfo.outputElementSize = elementSize; + formatInfo.copyFunction = copyFunc; + formatInfo.nativeFormat = nativeFormat; + formatInfo.componentType = GetDeclTypeComponentType(nativeFormat); + return formatInfo; +} + +#define TRANSLATION(type, norm, size, preferred) \ + CreateVertexFormatInfo( \ + Converter::identity, \ + Converter::finalSize, \ + Converter::convertArray, \ + static_cast(Converter::declflag)) + +#define TRANSLATION_FOR_TYPE_NORM_SIZE(type, norm, size) \ + { \ + Converter::capflag, \ + TRANSLATION(type, norm, size, UsePreferred), \ + TRANSLATION(type, norm, size, UseFallback) \ + } + +#define TRANSLATIONS_FOR_TYPE(type) \ + { \ + {TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), \ + TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), \ + TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), \ + TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4)}, \ + {TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 1), \ + TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 2), \ + TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 3), \ + TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 4)}, \ + } + +#define TRANSLATIONS_FOR_TYPE_NO_NORM(type) \ + { \ + {TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), \ + TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), \ + TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), \ + TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4)}, \ + {TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), \ + TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), \ + TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), \ + TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4)}, \ + } + +static inline unsigned int ComputeTypeIndex(GLenum type) +{ + switch (type) + { + case GL_BYTE: + return 0; + case GL_UNSIGNED_BYTE: + return 1; + case GL_SHORT: + return 2; + case GL_UNSIGNED_SHORT: + return 3; + case GL_FIXED: + return 4; + case GL_FLOAT: + return 5; + + default: + UNREACHABLE(); + return 5; + } +} + +const VertexFormat &GetVertexFormatInfo(DWORD supportedDeclTypes, angle::FormatID vertexFormatID) +{ + static DWORD initializedDeclTypes = 0; + static VertexFormat formatConverters[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; + if (initializedDeclTypes != supportedDeclTypes) + { + const TranslationDescription + translations[NUM_GL_VERTEX_ATTRIB_TYPES][2] + [4] = // [GL types as enumerated by typeIndex()][normalized][size-1] + {TRANSLATIONS_FOR_TYPE(GL_BYTE), TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_BYTE), + TRANSLATIONS_FOR_TYPE(GL_SHORT), TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_SHORT), + TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FIXED), TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FLOAT)}; + for (unsigned int i = 0; i < NUM_GL_VERTEX_ATTRIB_TYPES; i++) + { + for (unsigned int j = 0; j < 2; j++) + { + for (unsigned int k = 0; k < 4; k++) + { + if (translations[i][j][k].capsFlag == 0 || + (supportedDeclTypes & translations[i][j][k].capsFlag) != 0) + { + formatConverters[i][j][k] = translations[i][j][k].preferredConversion; + } + else + { + formatConverters[i][j][k] = translations[i][j][k].fallbackConversion; + } + } + } + } + initializedDeclTypes = supportedDeclTypes; + } + + const gl::VertexFormat &vertexFormat = gl::GetVertexFormatFromID(vertexFormatID); + + // Pure integer attributes only supported in ES3.0 + ASSERT(!vertexFormat.pureInteger); + return formatConverters[ComputeTypeIndex(vertexFormat.type)][vertexFormat.normalized] + [vertexFormat.components - 1]; +} +} // namespace d3d9 +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/formatutils9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/formatutils9.h new file mode 100644 index 0000000000..c3997ec0e9 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/formatutils9.h @@ -0,0 +1,59 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// formatutils9.h: Queries for GL image formats and their translations to D3D9 +// formats. + +#ifndef LIBANGLE_RENDERER_D3D_D3D9_FORMATUTILS9_H_ +#define LIBANGLE_RENDERER_D3D_D3D9_FORMATUTILS9_H_ + +#include + +#include "common/platform.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/Format.h" +#include "libANGLE/renderer/copyvertex.h" +#include "libANGLE/renderer/d3d/formatutilsD3D.h" +#include "libANGLE/renderer/d3d_format.h" +#include "libANGLE/renderer/renderer_utils.h" + +namespace rx +{ + +class Renderer9; + +namespace d3d9 +{ + +struct VertexFormat +{ + VertexFormat(); + + VertexConversionType conversionType; + size_t outputElementSize; + VertexCopyFunction copyFunction; + D3DDECLTYPE nativeFormat; + GLenum componentType; +}; +const VertexFormat &GetVertexFormatInfo(DWORD supportedDeclTypes, angle::FormatID vertexFormatID); + +struct TextureFormat +{ + TextureFormat(); + + D3DFORMAT texFormat; + D3DFORMAT renderFormat; + + InitializeTextureDataFunction dataInitializerFunction; + + LoadImageFunction loadFunction; +}; +const TextureFormat &GetTextureFormatInfo(GLenum internalFormat); +} // namespace d3d9 +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D9_FORMATUTILS9_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp new file mode 100644 index 0000000000..79e5c9cb06 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp @@ -0,0 +1,845 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// renderer9_utils.cpp: Conversion functions and other utility routines +// specific to the D3D9 renderer. + +#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" + +#include "common/debug.h" +#include "common/mathutil.h" + +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h" +#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" +#include "libANGLE/renderer/driver_utils.h" +#include "platform/FeaturesD3D_autogen.h" +#include "platform/PlatformMethods.h" + +#include "third_party/systeminfo/SystemInfo.h" + +namespace rx +{ + +namespace gl_d3d9 +{ + +D3DCMPFUNC ConvertComparison(GLenum comparison) +{ + D3DCMPFUNC d3dComp = D3DCMP_ALWAYS; + switch (comparison) + { + case GL_NEVER: + d3dComp = D3DCMP_NEVER; + break; + case GL_ALWAYS: + d3dComp = D3DCMP_ALWAYS; + break; + case GL_LESS: + d3dComp = D3DCMP_LESS; + break; + case GL_LEQUAL: + d3dComp = D3DCMP_LESSEQUAL; + break; + case GL_EQUAL: + d3dComp = D3DCMP_EQUAL; + break; + case GL_GREATER: + d3dComp = D3DCMP_GREATER; + break; + case GL_GEQUAL: + d3dComp = D3DCMP_GREATEREQUAL; + break; + case GL_NOTEQUAL: + d3dComp = D3DCMP_NOTEQUAL; + break; + default: + UNREACHABLE(); + } + + return d3dComp; +} + +D3DCOLOR ConvertColor(gl::ColorF color) +{ + return D3DCOLOR_RGBA(gl::unorm<8>(color.red), gl::unorm<8>(color.green), + gl::unorm<8>(color.blue), gl::unorm<8>(color.alpha)); +} + +D3DBLEND ConvertBlendFunc(GLenum blend) +{ + D3DBLEND d3dBlend = D3DBLEND_ZERO; + + switch (blend) + { + case GL_ZERO: + d3dBlend = D3DBLEND_ZERO; + break; + case GL_ONE: + d3dBlend = D3DBLEND_ONE; + break; + case GL_SRC_COLOR: + d3dBlend = D3DBLEND_SRCCOLOR; + break; + case GL_ONE_MINUS_SRC_COLOR: + d3dBlend = D3DBLEND_INVSRCCOLOR; + break; + case GL_DST_COLOR: + d3dBlend = D3DBLEND_DESTCOLOR; + break; + case GL_ONE_MINUS_DST_COLOR: + d3dBlend = D3DBLEND_INVDESTCOLOR; + break; + case GL_SRC_ALPHA: + d3dBlend = D3DBLEND_SRCALPHA; + break; + case GL_ONE_MINUS_SRC_ALPHA: + d3dBlend = D3DBLEND_INVSRCALPHA; + break; + case GL_DST_ALPHA: + d3dBlend = D3DBLEND_DESTALPHA; + break; + case GL_ONE_MINUS_DST_ALPHA: + d3dBlend = D3DBLEND_INVDESTALPHA; + break; + case GL_CONSTANT_COLOR: + d3dBlend = D3DBLEND_BLENDFACTOR; + break; + case GL_ONE_MINUS_CONSTANT_COLOR: + d3dBlend = D3DBLEND_INVBLENDFACTOR; + break; + case GL_CONSTANT_ALPHA: + d3dBlend = D3DBLEND_BLENDFACTOR; + break; + case GL_ONE_MINUS_CONSTANT_ALPHA: + d3dBlend = D3DBLEND_INVBLENDFACTOR; + break; + case GL_SRC_ALPHA_SATURATE: + d3dBlend = D3DBLEND_SRCALPHASAT; + break; + default: + UNREACHABLE(); + } + + return d3dBlend; +} + +D3DBLENDOP ConvertBlendOp(GLenum blendOp) +{ + D3DBLENDOP d3dBlendOp = D3DBLENDOP_ADD; + + switch (blendOp) + { + case GL_FUNC_ADD: + d3dBlendOp = D3DBLENDOP_ADD; + break; + case GL_FUNC_SUBTRACT: + d3dBlendOp = D3DBLENDOP_SUBTRACT; + break; + case GL_FUNC_REVERSE_SUBTRACT: + d3dBlendOp = D3DBLENDOP_REVSUBTRACT; + break; + case GL_MIN_EXT: + d3dBlendOp = D3DBLENDOP_MIN; + break; + case GL_MAX_EXT: + d3dBlendOp = D3DBLENDOP_MAX; + break; + default: + UNREACHABLE(); + } + + return d3dBlendOp; +} + +D3DSTENCILOP ConvertStencilOp(GLenum stencilOp) +{ + D3DSTENCILOP d3dStencilOp = D3DSTENCILOP_KEEP; + + switch (stencilOp) + { + case GL_ZERO: + d3dStencilOp = D3DSTENCILOP_ZERO; + break; + case GL_KEEP: + d3dStencilOp = D3DSTENCILOP_KEEP; + break; + case GL_REPLACE: + d3dStencilOp = D3DSTENCILOP_REPLACE; + break; + case GL_INCR: + d3dStencilOp = D3DSTENCILOP_INCRSAT; + break; + case GL_DECR: + d3dStencilOp = D3DSTENCILOP_DECRSAT; + break; + case GL_INVERT: + d3dStencilOp = D3DSTENCILOP_INVERT; + break; + case GL_INCR_WRAP: + d3dStencilOp = D3DSTENCILOP_INCR; + break; + case GL_DECR_WRAP: + d3dStencilOp = D3DSTENCILOP_DECR; + break; + default: + UNREACHABLE(); + } + + return d3dStencilOp; +} + +D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap) +{ + D3DTEXTUREADDRESS d3dWrap = D3DTADDRESS_WRAP; + + switch (wrap) + { + case GL_REPEAT: + d3dWrap = D3DTADDRESS_WRAP; + break; + case GL_CLAMP_TO_EDGE: + d3dWrap = D3DTADDRESS_CLAMP; + break; + case GL_CLAMP_TO_BORDER: + d3dWrap = D3DTADDRESS_BORDER; + break; + case GL_MIRRORED_REPEAT: + d3dWrap = D3DTADDRESS_MIRROR; + break; + default: + UNREACHABLE(); + } + + return d3dWrap; +} + +D3DCULL ConvertCullMode(gl::CullFaceMode cullFace, GLenum frontFace) +{ + D3DCULL cull = D3DCULL_CCW; + switch (cullFace) + { + case gl::CullFaceMode::Front: + cull = (frontFace == GL_CCW ? D3DCULL_CW : D3DCULL_CCW); + break; + case gl::CullFaceMode::Back: + cull = (frontFace == GL_CCW ? D3DCULL_CCW : D3DCULL_CW); + break; + case gl::CullFaceMode::FrontAndBack: + cull = D3DCULL_NONE; // culling will be handled during draw + break; + default: + UNREACHABLE(); + } + + return cull; +} + +D3DCUBEMAP_FACES ConvertCubeFace(gl::TextureTarget cubeFace) +{ + D3DCUBEMAP_FACES face = D3DCUBEMAP_FACE_POSITIVE_X; + + switch (cubeFace) + { + case gl::TextureTarget::CubeMapPositiveX: + face = D3DCUBEMAP_FACE_POSITIVE_X; + break; + case gl::TextureTarget::CubeMapNegativeX: + face = D3DCUBEMAP_FACE_NEGATIVE_X; + break; + case gl::TextureTarget::CubeMapPositiveY: + face = D3DCUBEMAP_FACE_POSITIVE_Y; + break; + case gl::TextureTarget::CubeMapNegativeY: + face = D3DCUBEMAP_FACE_NEGATIVE_Y; + break; + case gl::TextureTarget::CubeMapPositiveZ: + face = D3DCUBEMAP_FACE_POSITIVE_Z; + break; + case gl::TextureTarget::CubeMapNegativeZ: + face = D3DCUBEMAP_FACE_NEGATIVE_Z; + break; + default: + UNREACHABLE(); + } + + return face; +} + +DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha) +{ + return (red ? D3DCOLORWRITEENABLE_RED : 0) | (green ? D3DCOLORWRITEENABLE_GREEN : 0) | + (blue ? D3DCOLORWRITEENABLE_BLUE : 0) | (alpha ? D3DCOLORWRITEENABLE_ALPHA : 0); +} + +D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy) +{ + if (maxAnisotropy > 1.0f) + { + return D3DTEXF_ANISOTROPIC; + } + + D3DTEXTUREFILTERTYPE d3dMagFilter = D3DTEXF_POINT; + switch (magFilter) + { + case GL_NEAREST: + d3dMagFilter = D3DTEXF_POINT; + break; + case GL_LINEAR: + d3dMagFilter = D3DTEXF_LINEAR; + break; + default: + UNREACHABLE(); + } + + return d3dMagFilter; +} + +void ConvertMinFilter(GLenum minFilter, + D3DTEXTUREFILTERTYPE *d3dMinFilter, + D3DTEXTUREFILTERTYPE *d3dMipFilter, + float *d3dLodBias, + float maxAnisotropy, + size_t baseLevel) +{ + switch (minFilter) + { + case GL_NEAREST: + *d3dMinFilter = D3DTEXF_POINT; + *d3dMipFilter = D3DTEXF_NONE; + break; + case GL_LINEAR: + *d3dMinFilter = D3DTEXF_LINEAR; + *d3dMipFilter = D3DTEXF_NONE; + break; + case GL_NEAREST_MIPMAP_NEAREST: + *d3dMinFilter = D3DTEXF_POINT; + *d3dMipFilter = D3DTEXF_POINT; + break; + case GL_LINEAR_MIPMAP_NEAREST: + *d3dMinFilter = D3DTEXF_LINEAR; + *d3dMipFilter = D3DTEXF_POINT; + break; + case GL_NEAREST_MIPMAP_LINEAR: + *d3dMinFilter = D3DTEXF_POINT; + *d3dMipFilter = D3DTEXF_LINEAR; + break; + case GL_LINEAR_MIPMAP_LINEAR: + *d3dMinFilter = D3DTEXF_LINEAR; + *d3dMipFilter = D3DTEXF_LINEAR; + break; + default: + *d3dMinFilter = D3DTEXF_POINT; + *d3dMipFilter = D3DTEXF_NONE; + UNREACHABLE(); + } + + // Disabling mipmapping will always sample from level 0 of the texture. It is possible to work + // around this by modifying D3DSAMP_MAXMIPLEVEL to force a specific mip level to become the + // lowest sampled mip level and using a large negative value for D3DSAMP_MIPMAPLODBIAS to + // ensure that only the base mip level is sampled. + if (baseLevel > 0 && *d3dMipFilter == D3DTEXF_NONE) + { + *d3dMipFilter = D3DTEXF_POINT; + *d3dLodBias = -static_cast(gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + } + else + { + *d3dLodBias = 0.0f; + } + + if (maxAnisotropy > 1.0f) + { + *d3dMinFilter = D3DTEXF_ANISOTROPIC; + } +} + +D3DQUERYTYPE ConvertQueryType(gl::QueryType type) +{ + switch (type) + { + case gl::QueryType::AnySamples: + case gl::QueryType::AnySamplesConservative: + return D3DQUERYTYPE_OCCLUSION; + case gl::QueryType::CommandsCompleted: + return D3DQUERYTYPE_EVENT; + default: + UNREACHABLE(); + return static_cast(0); + } +} + +D3DMULTISAMPLE_TYPE GetMultisampleType(GLuint samples) +{ + return (samples > 1) ? static_cast(samples) : D3DMULTISAMPLE_NONE; +} + +} // namespace gl_d3d9 + +namespace d3d9_gl +{ + +unsigned int GetReservedVaryingVectors() +{ + // We reserve two registers for "dx_Position" and "gl_Position". The spec says they + // don't count towards the varying limit, so we must make space for them. We also + // reserve the last register since it can only pass a PSIZE, and not any arbitrary + // varying. + return 3; +} + +unsigned int GetReservedVertexUniformVectors() +{ + return 3; // dx_ViewCoords, dx_ViewAdjust and dx_DepthRange. +} + +unsigned int GetReservedFragmentUniformVectors() +{ + return 4; // dx_ViewCoords, dx_DepthFront, dx_DepthRange, dx_FragCoordoffset. +} + +GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type) +{ + return (type != D3DMULTISAMPLE_NONMASKABLE) ? type : 0; +} + +bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format) +{ + GLenum internalFormat = d3d9::GetD3DFormatInfo(d3dformat).info().glInternalFormat; + GLenum convertedFormat = gl::GetSizedInternalFormatInfo(internalFormat).format; + return convertedFormat == format; +} + +static gl::TextureCaps GenerateTextureFormatCaps(GLenum internalFormat, + IDirect3D9 *d3d9, + D3DDEVTYPE deviceType, + UINT adapter, + D3DFORMAT adapterFormat) +{ + gl::TextureCaps textureCaps; + + const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalFormat); + const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalFormat); + + if (d3dFormatInfo.texFormat != D3DFMT_UNKNOWN) + { + if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0) + { + textureCaps.texturable = SUCCEEDED(d3d9->CheckDeviceFormat( + adapter, deviceType, adapterFormat, 0, D3DRTYPE_TEXTURE, d3dFormatInfo.texFormat)); + } + else + { + textureCaps.texturable = + SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, + D3DRTYPE_TEXTURE, d3dFormatInfo.texFormat)) && + SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, + D3DRTYPE_CUBETEXTURE, d3dFormatInfo.texFormat)); + if (textureCaps.texturable && (formatInfo.colorEncoding == GL_SRGB)) + { + textureCaps.texturable = + SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, + D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE, + d3dFormatInfo.texFormat)) && + SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, + D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_CUBETEXTURE, + d3dFormatInfo.texFormat)); + } + } + + textureCaps.filterable = SUCCEEDED( + d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_QUERY_FILTER, + D3DRTYPE_TEXTURE, d3dFormatInfo.texFormat)); + } + + if (d3dFormatInfo.renderFormat != D3DFMT_UNKNOWN) + { + textureCaps.textureAttachment = SUCCEEDED( + d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_RENDERTARGET, + D3DRTYPE_TEXTURE, d3dFormatInfo.renderFormat)); + if (textureCaps.textureAttachment && (formatInfo.colorEncoding == GL_SRGB)) + { + textureCaps.textureAttachment = SUCCEEDED(d3d9->CheckDeviceFormat( + adapter, deviceType, adapterFormat, D3DUSAGE_QUERY_SRGBWRITE, D3DRTYPE_TEXTURE, + d3dFormatInfo.renderFormat)); + } + + if ((formatInfo.depthBits > 0 || formatInfo.stencilBits > 0) && + !textureCaps.textureAttachment) + { + textureCaps.textureAttachment = SUCCEEDED( + d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_TEXTURE, d3dFormatInfo.renderFormat)); + } + textureCaps.renderbuffer = textureCaps.textureAttachment; + textureCaps.blendable = textureCaps.renderbuffer; + + textureCaps.sampleCounts.insert(1); + for (unsigned int i = D3DMULTISAMPLE_2_SAMPLES; i <= D3DMULTISAMPLE_16_SAMPLES; i++) + { + D3DMULTISAMPLE_TYPE multisampleType = D3DMULTISAMPLE_TYPE(i); + + HRESULT result = d3d9->CheckDeviceMultiSampleType( + adapter, deviceType, d3dFormatInfo.renderFormat, TRUE, multisampleType, nullptr); + if (SUCCEEDED(result)) + { + textureCaps.sampleCounts.insert(i); + } + } + } + + return textureCaps; +} + +void GenerateCaps(IDirect3D9 *d3d9, + IDirect3DDevice9 *device, + D3DDEVTYPE deviceType, + UINT adapter, + gl::Caps *caps, + gl::TextureCapsMap *textureCapsMap, + gl::Extensions *extensions, + gl::Limitations *limitations) +{ + D3DCAPS9 deviceCaps; + if (FAILED(d3d9->GetDeviceCaps(adapter, deviceType, &deviceCaps))) + { + // Can't continue with out device caps + return; + } + + D3DDISPLAYMODE currentDisplayMode; + d3d9->GetAdapterDisplayMode(adapter, ¤tDisplayMode); + + GLuint maxSamples = 0; + for (GLenum internalFormat : gl::GetAllSizedInternalFormats()) + { + gl::TextureCaps textureCaps = GenerateTextureFormatCaps(internalFormat, d3d9, deviceType, + adapter, currentDisplayMode.Format); + textureCapsMap->insert(internalFormat, textureCaps); + + maxSamples = std::max(maxSamples, textureCaps.getMaxSamples()); + } + + // GL core feature limits + caps->maxElementIndex = static_cast(std::numeric_limits::max()); + + // 3D textures are unimplemented in D3D9 + caps->max3DTextureSize = 1; + + // Only one limit in GL, use the minimum dimension + caps->max2DTextureSize = std::min(deviceCaps.MaxTextureWidth, deviceCaps.MaxTextureHeight); + + // D3D treats cube maps as a special case of 2D textures + caps->maxCubeMapTextureSize = caps->max2DTextureSize; + + // Array textures are not available in D3D9 + caps->maxArrayTextureLayers = 1; + + // ES3-only feature + caps->maxLODBias = 0.0f; + + // No specific limits on render target size, maximum 2D texture size is equivalent + caps->maxRenderbufferSize = caps->max2DTextureSize; + + // Draw buffers are not supported in D3D9 + caps->maxDrawBuffers = 1; + caps->maxColorAttachments = 1; + + // No specific limits on viewport size, maximum 2D texture size is equivalent + caps->maxViewportWidth = caps->max2DTextureSize; + caps->maxViewportHeight = caps->maxViewportWidth; + + // Point size is clamped to 1.0f when the shader model is less than 3 + caps->minAliasedPointSize = 1.0f; + caps->maxAliasedPointSize = + ((D3DSHADER_VERSION_MAJOR(deviceCaps.PixelShaderVersion) >= 3) ? deviceCaps.MaxPointSize + : 1.0f); + + // Wide lines not supported + caps->minAliasedLineWidth = 1.0f; + caps->maxAliasedLineWidth = 1.0f; + + // Primitive count limits (unused in ES2) + caps->maxElementsIndices = 0; + caps->maxElementsVertices = 0; + + // Program and shader binary formats (no supported shader binary formats) + caps->programBinaryFormats.push_back(GL_PROGRAM_BINARY_ANGLE); + + caps->vertexHighpFloat.setIEEEFloat(); + caps->vertexMediumpFloat.setIEEEFloat(); + caps->vertexLowpFloat.setIEEEFloat(); + caps->fragmentHighpFloat.setIEEEFloat(); + caps->fragmentMediumpFloat.setIEEEFloat(); + caps->fragmentLowpFloat.setIEEEFloat(); + + // Some (most) hardware only supports single-precision floating-point numbers, + // which can accurately represent integers up to +/-16777216 + caps->vertexHighpInt.setSimulatedInt(24); + caps->vertexMediumpInt.setSimulatedInt(24); + caps->vertexLowpInt.setSimulatedInt(24); + caps->fragmentHighpInt.setSimulatedInt(24); + caps->fragmentMediumpInt.setSimulatedInt(24); + caps->fragmentLowpInt.setSimulatedInt(24); + + // WaitSync is ES3-only, set to zero + caps->maxServerWaitTimeout = 0; + + // Vertex shader limits + caps->maxVertexAttributes = 16; + // Vertex Attrib Binding not supported. + caps->maxVertexAttribBindings = caps->maxVertexAttributes; + + const size_t MAX_VERTEX_CONSTANT_VECTORS_D3D9 = 256; + caps->maxVertexUniformVectors = + MAX_VERTEX_CONSTANT_VECTORS_D3D9 - GetReservedVertexUniformVectors(); + caps->maxShaderUniformComponents[gl::ShaderType::Vertex] = caps->maxVertexUniformVectors * 4; + + caps->maxShaderUniformBlocks[gl::ShaderType::Vertex] = 0; + + // SM3 only supports 12 output variables, but the special 12th register is only for PSIZE. + const unsigned int MAX_VERTEX_OUTPUT_VECTORS_SM3 = 12 - GetReservedVaryingVectors(); + const unsigned int MAX_VERTEX_OUTPUT_VECTORS_SM2 = 10 - GetReservedVaryingVectors(); + caps->maxVertexOutputComponents = + ((deviceCaps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) ? MAX_VERTEX_OUTPUT_VECTORS_SM3 + : MAX_VERTEX_OUTPUT_VECTORS_SM2) * + 4; + + // Only Direct3D 10 ready devices support all the necessary vertex texture formats. + // We test this using D3D9 by checking support for the R16F format. + if (deviceCaps.VertexShaderVersion >= D3DVS_VERSION(3, 0) && + SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, currentDisplayMode.Format, + D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, + D3DFMT_R16F))) + { + const size_t MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 = 4; + caps->maxShaderTextureImageUnits[gl::ShaderType::Vertex] = MAX_TEXTURE_IMAGE_UNITS_VTF_SM3; + } + else + { + caps->maxShaderTextureImageUnits[gl::ShaderType::Vertex] = 0; + } + + // Fragment shader limits + const size_t MAX_PIXEL_CONSTANT_VECTORS_SM3 = 224; + const size_t MAX_PIXEL_CONSTANT_VECTORS_SM2 = 32; + caps->maxFragmentUniformVectors = + ((deviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) ? MAX_PIXEL_CONSTANT_VECTORS_SM3 + : MAX_PIXEL_CONSTANT_VECTORS_SM2) - + GetReservedFragmentUniformVectors(); + caps->maxShaderUniformComponents[gl::ShaderType::Fragment] = + caps->maxFragmentUniformVectors * 4; + caps->maxShaderUniformBlocks[gl::ShaderType::Fragment] = 0; + caps->maxFragmentInputComponents = caps->maxVertexOutputComponents; + caps->maxShaderTextureImageUnits[gl::ShaderType::Fragment] = 16; + caps->minProgramTexelOffset = 0; + caps->maxProgramTexelOffset = 0; + + // Aggregate shader limits (unused in ES2) + caps->maxUniformBufferBindings = 0; + caps->maxUniformBlockSize = 0; + caps->uniformBufferOffsetAlignment = 0; + caps->maxCombinedUniformBlocks = 0; + caps->maxCombinedShaderUniformComponents[gl::ShaderType::Vertex] = 0; + caps->maxCombinedShaderUniformComponents[gl::ShaderType::Fragment] = 0; + caps->maxVaryingComponents = 0; + + // Aggregate shader limits + caps->maxVaryingVectors = caps->maxVertexOutputComponents / 4; + caps->maxCombinedTextureImageUnits = caps->maxShaderTextureImageUnits[gl::ShaderType::Vertex] + + caps->maxShaderTextureImageUnits[gl::ShaderType::Fragment]; + + // Transform feedback limits + caps->maxTransformFeedbackInterleavedComponents = 0; + caps->maxTransformFeedbackSeparateAttributes = 0; + caps->maxTransformFeedbackSeparateComponents = 0; + + // Multisample limits + caps->maxSamples = maxSamples; + + // GL extension support + extensions->setTextureExtensionSupport(*textureCapsMap); + extensions->elementIndexUintOES = deviceCaps.MaxVertexIndex >= (1 << 16); + extensions->getProgramBinaryOES = true; + extensions->rgb8Rgba8OES = true; + extensions->readFormatBgraEXT = true; + extensions->pixelBufferObjectNV = false; + extensions->mapbufferOES = false; + extensions->mapBufferRangeEXT = false; + + // D3D does not allow depth textures to have more than one mipmap level OES_depth_texture + // allows for that so we can't implement full support with the D3D9 back end. + extensions->depthTextureOES = false; + + // textureRgEXT is emulated and not performant. + extensions->textureRgEXT = false; + + // GL_KHR_parallel_shader_compile + extensions->parallelShaderCompileKHR = true; + + D3DADAPTER_IDENTIFIER9 adapterId = {}; + if (SUCCEEDED(d3d9->GetAdapterIdentifier(adapter, 0, &adapterId))) + { + // ATI cards on XP have problems with non-power-of-two textures. + extensions->textureNpotOES = + !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_POW2) && + !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) && + !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) && + !(!isWindowsVistaOrGreater() && IsAMD(adapterId.VendorId)); + + // Disable depth texture support on AMD cards (See ANGLE issue 839) + if (IsAMD(adapterId.VendorId)) + { + extensions->depthTextureANGLE = false; + extensions->depthTextureOES = false; + } + } + else + { + extensions->textureNpotOES = false; + } + + extensions->drawBuffersEXT = false; + extensions->textureStorageEXT = true; + + // Must support a minimum of 2:1 anisotropy for max anisotropy to be considered supported, per + // the spec + extensions->textureFilterAnisotropicEXT = + (deviceCaps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) != 0 && deviceCaps.MaxAnisotropy >= 2; + caps->maxTextureAnisotropy = static_cast(deviceCaps.MaxAnisotropy); + + // Check occlusion query support by trying to create one + IDirect3DQuery9 *occlusionQuery = nullptr; + extensions->occlusionQueryBooleanEXT = + SUCCEEDED(device->CreateQuery(D3DQUERYTYPE_OCCLUSION, &occlusionQuery)) && occlusionQuery; + SafeRelease(occlusionQuery); + + // Check event query support by trying to create one + IDirect3DQuery9 *eventQuery = nullptr; + extensions->fenceNV = + SUCCEEDED(device->CreateQuery(D3DQUERYTYPE_EVENT, &eventQuery)) && eventQuery; + SafeRelease(eventQuery); + + extensions->disjointTimerQueryEXT = false; + extensions->robustnessEXT = true; + // It seems that only DirectX 10 and higher enforce the well-defined behavior of always + // returning zero values when out-of-bounds reads. See + // https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_robustness.txt + extensions->robustBufferAccessBehaviorKHR = false; + extensions->blendMinmaxEXT = true; + // Although according to + // https://docs.microsoft.com/en-us/windows/desktop/direct3ddxgi/format-support-for-direct3d-feature-level-9-1-hardware + // D3D9 doesn't have full blending capability for RGBA32F. But turns out it could provide + // correct blending result in reality. As a result of some regression reports by client app, we + // decided to turn floatBlendEXT on for D3D9 + extensions->floatBlendEXT = true; + extensions->framebufferBlitANGLE = true; + extensions->framebufferMultisampleANGLE = true; + extensions->instancedArraysANGLE = deviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0); + // D3D9 requires at least one attribute that has a divisor of 0, which isn't required by the EXT + // extension + extensions->instancedArraysEXT = false; + extensions->packReverseRowOrderANGLE = true; + extensions->standardDerivativesOES = + (deviceCaps.PS20Caps.Caps & D3DPS20CAPS_GRADIENTINSTRUCTIONS) != 0; + extensions->shaderTextureLodEXT = true; + extensions->fragDepthEXT = true; + extensions->textureUsageANGLE = true; + extensions->translatedShaderSourceANGLE = true; + extensions->fboRenderMipmapOES = true; + extensions->discardFramebufferEXT = false; // It would be valid to set this to true, since + // glDiscardFramebufferEXT is just a hint + extensions->colorBufferFloatEXT = false; + extensions->debugMarkerEXT = true; + extensions->EGLImageOES = true; + extensions->EGLImageExternalOES = true; + extensions->unpackSubimageEXT = true; + extensions->packSubimageNV = true; + extensions->syncQueryCHROMIUM = extensions->fenceNV; + extensions->copyTextureCHROMIUM = true; + extensions->textureBorderClampOES = true; + extensions->videoTextureWEBGL = true; + + // D3D9 has no concept of separate masks and refs for front and back faces in the depth stencil + // state. + limitations->noSeparateStencilRefsAndMasks = true; + + // D3D9 shader models have limited support for looping, so the Appendix A + // index/loop limitations are necessary. Workarounds that are needed to + // support dynamic indexing of vectors on HLSL also don't work on D3D9. + limitations->shadersRequireIndexedLoopValidation = true; + + // D3D9 cannot support constant color and alpha blend funcs together + limitations->noSimultaneousConstantColorAndAlphaBlendFunc = true; + + // D3D9 cannot support unclamped constant blend color + limitations->noUnclampedBlendColor = true; + + // D3D9 cannot support packing more than one variable to a single varying. + // TODO(jmadill): Implement more sophisticated component packing in D3D9. + limitations->noFlexibleVaryingPacking = true; + + // D3D9 does not support vertex attribute aliasing + limitations->noVertexAttributeAliasing = true; + + // D3D9 does not support compressed textures where the base mip level is not a multiple of 4 + limitations->compressedBaseMipLevelMultipleOfFour = true; +} + +} // namespace d3d9_gl + +namespace d3d9 +{ + +GLuint ComputeBlockSize(D3DFORMAT format, GLuint width, GLuint height) +{ + const D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(format); + GLuint numBlocksWide = (width + d3dFormatInfo.blockWidth - 1) / d3dFormatInfo.blockWidth; + GLuint numBlocksHight = (height + d3dFormatInfo.blockHeight - 1) / d3dFormatInfo.blockHeight; + return (d3dFormatInfo.pixelBytes * numBlocksWide * numBlocksHight); +} + +void MakeValidSize(bool isImage, + D3DFORMAT format, + GLsizei *requestWidth, + GLsizei *requestHeight, + int *levelOffset) +{ + const D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(format); + + int upsampleCount = 0; + // Don't expand the size of full textures that are at least (blockWidth x blockHeight) already. + if (isImage || *requestWidth < static_cast(d3dFormatInfo.blockWidth) || + *requestHeight < static_cast(d3dFormatInfo.blockHeight)) + { + while (*requestWidth % d3dFormatInfo.blockWidth != 0 || + *requestHeight % d3dFormatInfo.blockHeight != 0) + { + *requestWidth <<= 1; + *requestHeight <<= 1; + upsampleCount++; + } + } + *levelOffset = upsampleCount; +} + +void InitializeFeatures(angle::FeaturesD3D *features) +{ + ANGLE_FEATURE_CONDITION(features, mrtPerfWorkaround, true); + ANGLE_FEATURE_CONDITION(features, setDataFasterThanImageUpload, false); + ANGLE_FEATURE_CONDITION(features, setDataFasterThanImageUploadOn128bitFormats, false); + ANGLE_FEATURE_CONDITION(features, useInstancedPointSpriteEmulation, false); + + // TODO(jmadill): Disable workaround when we have a fixed compiler DLL. + ANGLE_FEATURE_CONDITION(features, expandIntegerPowExpressions, true); + + // crbug.com/1011627 Turn this on for D3D9. + ANGLE_FEATURE_CONDITION(features, allowClearForRobustResourceInit, true); +} + +} // namespace d3d9 + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h new file mode 100644 index 0000000000..b900e9c44c --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h @@ -0,0 +1,105 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// renderer9_utils.h: Conversion functions and other utility routines +// specific to the D3D9 renderer + +#ifndef LIBANGLE_RENDERER_D3D_D3D9_RENDERER9UTILS_H_ +#define LIBANGLE_RENDERER_D3D_D3D9_RENDERER9UTILS_H_ + +#include "common/Color.h" +#include "libANGLE/Caps.h" +#include "libANGLE/Error.h" +#include "platform/FeaturesD3D_autogen.h" + +namespace gl +{ +class FramebufferAttachment; +} + +namespace rx +{ +class RenderTarget9; + +namespace gl_d3d9 +{ + +D3DCMPFUNC ConvertComparison(GLenum comparison); +D3DCOLOR ConvertColor(gl::ColorF color); +D3DBLEND ConvertBlendFunc(GLenum blend); +D3DBLENDOP ConvertBlendOp(GLenum blendOp); +D3DSTENCILOP ConvertStencilOp(GLenum stencilOp); +D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap); +D3DCULL ConvertCullMode(gl::CullFaceMode cullFace, GLenum frontFace); +D3DCUBEMAP_FACES ConvertCubeFace(gl::TextureTarget cubeFace); +DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha); +D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy); +void ConvertMinFilter(GLenum minFilter, + D3DTEXTUREFILTERTYPE *d3dMinFilter, + D3DTEXTUREFILTERTYPE *d3dMipFilter, + float *d3dLodBias, + float maxAnisotropy, + size_t baseLevel); +D3DQUERYTYPE ConvertQueryType(gl::QueryType type); + +D3DMULTISAMPLE_TYPE GetMultisampleType(GLuint samples); + +} // namespace gl_d3d9 + +namespace d3d9_gl +{ + +unsigned int GetReservedVaryingVectors(); + +unsigned int GetReservedVertexUniformVectors(); + +unsigned int GetReservedFragmentUniformVectors(); + +GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type); + +bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format); + +void GenerateCaps(IDirect3D9 *d3d9, + IDirect3DDevice9 *device, + D3DDEVTYPE deviceType, + UINT adapter, + gl::Caps *caps, + gl::TextureCapsMap *textureCapsMap, + gl::Extensions *extensions, + gl::Limitations *limitations); +} // namespace d3d9_gl + +namespace d3d9 +{ + +GLuint ComputeBlockSize(D3DFORMAT format, GLuint width, GLuint height); + +void MakeValidSize(bool isImage, + D3DFORMAT format, + GLsizei *requestWidth, + GLsizei *requestHeight, + int *levelOffset); + +inline bool isDeviceLostError(HRESULT errorCode) +{ + switch (errorCode) + { + case D3DERR_DRIVERINTERNALERROR: + case D3DERR_DEVICELOST: + case D3DERR_DEVICEHUNG: + case D3DERR_DEVICEREMOVED: + return true; + default: + return false; + } +} + +void InitializeFeatures(angle::FeaturesD3D *features); +} // namespace d3d9 + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D9_RENDERER9UTILS_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskpremultps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskpremultps.h new file mode 100644 index 0000000000..04868aeb9c --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskpremultps.h @@ -0,0 +1,50 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// Parameters: +// +// float4 add; +// float4 mult; +// sampler2D tex; +// +// +// Registers: +// +// Name Reg Size +// ------------ ----- ---- +// mult c0 1 +// add c1 1 +// tex s0 1 +// + + ps_2_0 + dcl t0.xy + dcl_2d s0 + texld r0, t0, s0 + mul r0.xyz, r0.w, r0 + mov r1, c0 + mad r0, r0, r1, c1 + mov oC0, r0 + +// approximately 5 instruction slots used (1 texture, 4 arithmetic) +#endif + +const BYTE g_ps20_componentmaskpremultps[] = { + 0, 2, 255, 255, 254, 255, 50, 0, 67, 84, 65, 66, 28, 0, 0, 0, 143, 0, 0, + 0, 0, 2, 255, 255, 3, 0, 0, 0, 28, 0, 0, 0, 0, 1, 0, 0, 136, 0, + 0, 0, 88, 0, 0, 0, 2, 0, 1, 0, 1, 0, 0, 0, 92, 0, 0, 0, 0, + 0, 0, 0, 108, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0, + 0, 0, 0, 0, 113, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 120, 0, 0, + 0, 0, 0, 0, 0, 97, 100, 100, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 109, 117, 108, 116, 0, 116, 101, 120, 0, 171, 171, 171, 4, + 0, 12, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 112, 115, 95, 50, + 95, 48, 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, 171, 31, + 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 144, + 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, + 160, 5, 0, 0, 3, 0, 0, 7, 128, 0, 0, 255, 128, 0, 0, 228, 128, 1, 0, + 0, 2, 1, 0, 15, 128, 0, 0, 228, 160, 4, 0, 0, 4, 0, 0, 15, 128, 0, + 0, 228, 128, 1, 0, 228, 128, 1, 0, 228, 160, 1, 0, 0, 2, 0, 8, 15, 128, + 0, 0, 228, 128, 255, 255, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskps.h new file mode 100644 index 0000000000..06673ae5f7 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskps.h @@ -0,0 +1,48 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// Parameters: +// +// float4 add; +// float4 mult; +// sampler2D tex; +// +// +// Registers: +// +// Name Reg Size +// ------------ ----- ---- +// mult c0 1 +// add c1 1 +// tex s0 1 +// + + ps_2_0 + dcl t0.xy + dcl_2d s0 + texld r0, t0, s0 + mov r1, c0 + mad r0, r0, r1, c1 + mov oC0, r0 + +// approximately 4 instruction slots used (1 texture, 3 arithmetic) +#endif + +const BYTE g_ps20_componentmaskps[] = { + 0, 2, 255, 255, 254, 255, 50, 0, 67, 84, 65, 66, 28, 0, 0, 0, 143, 0, 0, + 0, 0, 2, 255, 255, 3, 0, 0, 0, 28, 0, 0, 0, 0, 1, 0, 0, 136, 0, + 0, 0, 88, 0, 0, 0, 2, 0, 1, 0, 1, 0, 0, 0, 92, 0, 0, 0, 0, + 0, 0, 0, 108, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0, + 0, 0, 0, 0, 113, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 120, 0, 0, + 0, 0, 0, 0, 0, 97, 100, 100, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 109, 117, 108, 116, 0, 116, 101, 120, 0, 171, 171, 171, 4, + 0, 12, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 112, 115, 95, 50, + 95, 48, 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, 171, 31, + 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 144, + 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, + 160, 1, 0, 0, 2, 1, 0, 15, 128, 0, 0, 228, 160, 4, 0, 0, 4, 0, 0, + 15, 128, 0, 0, 228, 128, 1, 0, 228, 128, 1, 0, 228, 160, 1, 0, 0, 2, 0, + 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskunmultps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskunmultps.h new file mode 100644 index 0000000000..ad15364bb8 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskunmultps.h @@ -0,0 +1,54 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// Parameters: +// +// float4 add; +// float4 mult; +// sampler2D tex; +// +// +// Registers: +// +// Name Reg Size +// ------------ ----- ---- +// mult c0 1 +// add c1 1 +// tex s0 1 +// + + ps_2_0 + dcl t0.xy + dcl_2d s0 + texld r0, t0, s0 + rcp r1.w, r0.w + mul r1.xyz, r0, r1.w + cmp r0.xyz, -r0.w, r0, r1 + mov r1, c0 + mad r0, r0, r1, c1 + mov oC0, r0 + +// approximately 7 instruction slots used (1 texture, 6 arithmetic) +#endif + +const BYTE g_ps20_componentmaskunmultps[] = { + 0, 2, 255, 255, 254, 255, 50, 0, 67, 84, 65, 66, 28, 0, 0, 0, 143, 0, 0, + 0, 0, 2, 255, 255, 3, 0, 0, 0, 28, 0, 0, 0, 0, 1, 0, 0, 136, 0, + 0, 0, 88, 0, 0, 0, 2, 0, 1, 0, 1, 0, 0, 0, 92, 0, 0, 0, 0, + 0, 0, 0, 108, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0, + 0, 0, 0, 0, 113, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 120, 0, 0, + 0, 0, 0, 0, 0, 97, 100, 100, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 109, 117, 108, 116, 0, 116, 101, 120, 0, 171, 171, 171, 4, + 0, 12, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 112, 115, 95, 50, + 95, 48, 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, 171, 31, + 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 144, + 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, + 160, 6, 0, 0, 2, 1, 0, 8, 128, 0, 0, 255, 128, 5, 0, 0, 3, 1, 0, + 7, 128, 0, 0, 228, 128, 1, 0, 255, 128, 88, 0, 0, 4, 0, 0, 7, 128, 0, + 0, 255, 129, 0, 0, 228, 128, 1, 0, 228, 128, 1, 0, 0, 2, 1, 0, 15, 128, + 0, 0, 228, 160, 4, 0, 0, 4, 0, 0, 15, 128, 0, 0, 228, 128, 1, 0, 228, + 128, 1, 0, 228, 160, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, + 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminancepremultps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminancepremultps.h new file mode 100644 index 0000000000..274a7824f9 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminancepremultps.h @@ -0,0 +1,50 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// Parameters: +// +// float4 add; +// float4 mult; +// sampler2D tex; +// +// +// Registers: +// +// Name Reg Size +// ------------ ----- ---- +// mult c0 1 +// add c1 1 +// tex s0 1 +// + + ps_2_0 + dcl t0.xy + dcl_2d s0 + texld r0, t0, s0 + mul r0.xyz, r0.w, r0.x + mov r1, c0 + mad r0, r0, r1, c1 + mov oC0, r0 + +// approximately 5 instruction slots used (1 texture, 4 arithmetic) +#endif + +const BYTE g_ps20_luminancepremultps[] = { + 0, 2, 255, 255, 254, 255, 50, 0, 67, 84, 65, 66, 28, 0, 0, 0, 143, 0, 0, + 0, 0, 2, 255, 255, 3, 0, 0, 0, 28, 0, 0, 0, 0, 1, 0, 0, 136, 0, + 0, 0, 88, 0, 0, 0, 2, 0, 1, 0, 1, 0, 0, 0, 92, 0, 0, 0, 0, + 0, 0, 0, 108, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0, + 0, 0, 0, 0, 113, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 120, 0, 0, + 0, 0, 0, 0, 0, 97, 100, 100, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 109, 117, 108, 116, 0, 116, 101, 120, 0, 171, 171, 171, 4, + 0, 12, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 112, 115, 95, 50, + 95, 48, 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, 171, 31, + 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 144, + 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, + 160, 5, 0, 0, 3, 0, 0, 7, 128, 0, 0, 255, 128, 0, 0, 0, 128, 1, 0, + 0, 2, 1, 0, 15, 128, 0, 0, 228, 160, 4, 0, 0, 4, 0, 0, 15, 128, 0, + 0, 228, 128, 1, 0, 228, 128, 1, 0, 228, 160, 1, 0, 0, 2, 0, 8, 15, 128, + 0, 0, 228, 128, 255, 255, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceps.h new file mode 100644 index 0000000000..0be665c525 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceps.h @@ -0,0 +1,53 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// Parameters: +// +// float4 add; +// float4 mult; +// sampler2D tex; +// +// +// Registers: +// +// Name Reg Size +// ------------ ----- ---- +// mult c0 1 +// add c1 1 +// tex s0 1 +// + + ps_2_0 + dcl t0.xy + dcl_2d s0 + texld r0, t0, s0 + mov r1.xw, c0 + mad r0.x, r0.x, r1.x, c1.x + mad r0.y, r0.w, r1.w, c1.w + mov r1.xyz, r0.x + mov r1.w, r0.y + mov oC0, r1 + +// approximately 7 instruction slots used (1 texture, 6 arithmetic) +#endif + +const BYTE g_ps20_luminanceps[] = { + 0, 2, 255, 255, 254, 255, 50, 0, 67, 84, 65, 66, 28, 0, 0, 0, 143, 0, 0, + 0, 0, 2, 255, 255, 3, 0, 0, 0, 28, 0, 0, 0, 0, 1, 0, 0, 136, 0, + 0, 0, 88, 0, 0, 0, 2, 0, 1, 0, 1, 0, 0, 0, 92, 0, 0, 0, 0, + 0, 0, 0, 108, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0, + 0, 0, 0, 0, 113, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 120, 0, 0, + 0, 0, 0, 0, 0, 97, 100, 100, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 109, 117, 108, 116, 0, 116, 101, 120, 0, 171, 171, 171, 4, + 0, 12, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 112, 115, 95, 50, + 95, 48, 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, 171, 31, + 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 144, + 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, + 160, 1, 0, 0, 2, 1, 0, 9, 128, 0, 0, 228, 160, 4, 0, 0, 4, 0, 0, + 1, 128, 0, 0, 0, 128, 1, 0, 0, 128, 1, 0, 0, 160, 4, 0, 0, 4, 0, + 0, 2, 128, 0, 0, 255, 128, 1, 0, 255, 128, 1, 0, 255, 160, 1, 0, 0, 2, + 1, 0, 7, 128, 0, 0, 0, 128, 1, 0, 0, 2, 1, 0, 8, 128, 0, 0, 85, + 128, 1, 0, 0, 2, 0, 8, 15, 128, 1, 0, 228, 128, 255, 255, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceunmultps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceunmultps.h new file mode 100644 index 0000000000..1100d0b088 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceunmultps.h @@ -0,0 +1,54 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// Parameters: +// +// float4 add; +// float4 mult; +// sampler2D tex; +// +// +// Registers: +// +// Name Reg Size +// ------------ ----- ---- +// mult c0 1 +// add c1 1 +// tex s0 1 +// + + ps_2_0 + dcl t0.xy + dcl_2d s0 + texld r0, t0, s0 + rcp r1.w, r0.w + mul r1.x, r0.x, r1.w + cmp r0.xyz, -r0.w, r0.x, r1.x + mov r1, c0 + mad r0, r0, r1, c1 + mov oC0, r0 + +// approximately 7 instruction slots used (1 texture, 6 arithmetic) +#endif + +const BYTE g_ps20_luminanceunmultps[] = { + 0, 2, 255, 255, 254, 255, 50, 0, 67, 84, 65, 66, 28, 0, 0, 0, 143, 0, 0, + 0, 0, 2, 255, 255, 3, 0, 0, 0, 28, 0, 0, 0, 0, 1, 0, 0, 136, 0, + 0, 0, 88, 0, 0, 0, 2, 0, 1, 0, 1, 0, 0, 0, 92, 0, 0, 0, 0, + 0, 0, 0, 108, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0, + 0, 0, 0, 0, 113, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 120, 0, 0, + 0, 0, 0, 0, 0, 97, 100, 100, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 109, 117, 108, 116, 0, 116, 101, 120, 0, 171, 171, 171, 4, + 0, 12, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 112, 115, 95, 50, + 95, 48, 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, 171, 31, + 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 144, + 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, + 160, 6, 0, 0, 2, 1, 0, 8, 128, 0, 0, 255, 128, 5, 0, 0, 3, 1, 0, + 1, 128, 0, 0, 0, 128, 1, 0, 255, 128, 88, 0, 0, 4, 0, 0, 7, 128, 0, + 0, 255, 129, 0, 0, 0, 128, 1, 0, 0, 128, 1, 0, 0, 2, 1, 0, 15, 128, + 0, 0, 228, 160, 4, 0, 0, 4, 0, 0, 15, 128, 0, 0, 228, 128, 1, 0, 228, + 128, 1, 0, 228, 160, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, + 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/passthroughps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/passthroughps.h new file mode 100644 index 0000000000..0c17739e17 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/passthroughps.h @@ -0,0 +1,37 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// Parameters: +// +// sampler2D tex; +// +// +// Registers: +// +// Name Reg Size +// ------------ ----- ---- +// tex s0 1 +// + + ps_2_0 + dcl t0.xy + dcl_2d s0 + texld r0, t0, s0 + mov oC0, r0 + +// approximately 2 instruction slots used (1 texture, 1 arithmetic) +#endif + +const BYTE g_ps20_passthroughps[] = { + 0, 2, 255, 255, 254, 255, 33, 0, 67, 84, 65, 66, 28, 0, 0, 0, 75, 0, + 0, 0, 0, 2, 255, 255, 1, 0, 0, 0, 28, 0, 0, 0, 0, 1, 0, 0, + 68, 0, 0, 0, 48, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 52, 0, + 0, 0, 0, 0, 0, 0, 116, 101, 120, 0, 4, 0, 12, 0, 1, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 112, 115, 95, 50, 95, 48, 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, 171, 31, 0, 0, 2, + 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, + 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, + 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/standardvs.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/standardvs.h new file mode 100644 index 0000000000..e4d7e0e1a8 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/standardvs.h @@ -0,0 +1,46 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// Parameters: +// +// float4 halfPixelSize; +// float4 texcoordOffset; +// +// +// Registers: +// +// Name Reg Size +// -------------- ----- ---- +// halfPixelSize c0 1 +// texcoordOffset c1 1 +// + + vs_2_0 + def c2, 0.5, -0.5, 1, 0 + dcl_position v0 + add oPos, v0, c0 + mad r0, v0, c2.xyzz, c2.xxww + mov oT0.zw, r0 + mad oT0.xy, r0, c1.zwzw, c1 + +// approximately 4 instruction slots used +#endif + +const BYTE g_vs20_standardvs[] = { + 0, 2, 254, 255, 254, 255, 44, 0, 67, 84, 65, 66, 28, 0, 0, 0, 122, 0, 0, + 0, 0, 2, 254, 255, 2, 0, 0, 0, 28, 0, 0, 0, 0, 1, 0, 0, 115, 0, + 0, 0, 68, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 0, + 0, 0, 0, 100, 0, 0, 0, 2, 0, 1, 0, 1, 0, 0, 0, 84, 0, 0, 0, + 0, 0, 0, 0, 104, 97, 108, 102, 80, 105, 120, 101, 108, 83, 105, 122, 101, 0, 171, + 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 116, 101, + 120, 99, 111, 111, 114, 100, 79, 102, 102, 115, 101, 116, 0, 118, 115, 95, 50, 95, 48, + 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, 81, 0, 0, 5, 2, 0, + 15, 160, 0, 0, 0, 63, 0, 0, 0, 191, 0, 0, 128, 63, 0, 0, 0, 0, 31, + 0, 0, 2, 0, 0, 0, 128, 0, 0, 15, 144, 2, 0, 0, 3, 0, 0, 15, 192, + 0, 0, 228, 144, 0, 0, 228, 160, 4, 0, 0, 4, 0, 0, 15, 128, 0, 0, 228, + 144, 2, 0, 164, 160, 2, 0, 240, 160, 1, 0, 0, 2, 0, 0, 12, 224, 0, 0, + 228, 128, 4, 0, 0, 4, 0, 0, 3, 224, 0, 0, 228, 128, 1, 0, 238, 160, 1, + 0, 228, 160, 255, 255, 0, 0}; diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/vertexconversion.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/vertexconversion.h new file mode 100644 index 0000000000..fb172448d1 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/vertexconversion.h @@ -0,0 +1,197 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// vertexconversion.h: A library of vertex conversion classes that can be used to build +// the FormatConverter objects used by the buffer conversion system. + +#ifndef LIBANGLE_RENDERER_D3D_D3D9_VERTEXCONVERSION_H_ +#define LIBANGLE_RENDERER_D3D_D3D9_VERTEXCONVERSION_H_ + +#include +#include +#include + +namespace rx +{ + +// Conversion types: +// static const bool identity: true if this is an identity transform, false otherwise +// static U convert(T): convert a single element from the input type to the output type +// typedef ... OutputType: the type produced by this conversion + +template +struct Identity +{ + static const bool identity = true; + + typedef T OutputType; + + static T convert(T x) { return x; } +}; + +template +struct Cast +{ + static const bool identity = false; + + typedef ToT OutputType; + + static ToT convert(FromT x) { return static_cast(x); } +}; + +template +struct Cast +{ + static const bool identity = true; + + typedef T OutputType; + + static T convert(T x) { return static_cast(x); } +}; + +template +struct Normalize +{ + static const bool identity = false; + + typedef float OutputType; + + static float convert(T x) + { + typedef std::numeric_limits NL; + float f = static_cast(x); + + if (NL::is_signed) + { + // const float => VC2008 computes it at compile time + // static const float => VC2008 computes it the first time we get here, stores it to + // memory with static guard and all that. + const float divisor = 1.0f / (2 * static_cast(NL::max()) + 1); + return (2 * f + 1) * divisor; + } + else + { + return f / NL::max(); + } + } +}; + +template +struct FixedToFloat +{ + static const bool identity = false; + + typedef float OutputType; + + static float convert(FromType x) + { + const float divisor = 1.0f / static_cast(static_cast(1) << ScaleBits); + return static_cast(x) * divisor; + } +}; + +// Widen types: +// static const unsigned int initialWidth: number of components before conversion +// static const unsigned int finalWidth: number of components after conversion + +// Float is supported at any size. +template +struct NoWiden +{ + static const std::size_t initialWidth = N; + static const std::size_t finalWidth = N; +}; + +// SHORT, norm-SHORT, norm-UNSIGNED_SHORT are supported but only with 2 or 4 components +template +struct WidenToEven +{ + static const std::size_t initialWidth = N; + static const std::size_t finalWidth = N + (N & 1); +}; + +template +struct WidenToFour +{ + static const std::size_t initialWidth = N; + static const std::size_t finalWidth = 4; +}; + +// Most types have 0 and 1 that are just that. +template +struct SimpleDefaultValues +{ + static T zero() { return static_cast(0); } + static T one() { return static_cast(1); } +}; + +// But normalised types only store [0,1] or [-1,1] so 1.0 is represented by the max value. +template +struct NormalizedDefaultValues +{ + static T zero() { return static_cast(0); } + static T one() { return std::numeric_limits::max(); } +}; + +// Converter: +// static const bool identity: true if this is an identity transform (with no widening) +// static const std::size_t finalSize: number of bytes per output vertex +// static void convertArray(const void *in, std::size_t stride, std::size_t n, void *out): convert +// an array of vertices. Input may be strided, but output will be unstrided. + +template > +struct VertexDataConverter +{ + typedef typename Converter::OutputType OutputType; + typedef InT InputType; + + static const bool identity = + (WidenRule::initialWidth == WidenRule::finalWidth) && Converter::identity; + static const std::size_t finalSize = WidenRule::finalWidth * sizeof(OutputType); + + static void convertArray(const uint8_t *input, size_t stride, size_t n, uint8_t *output) + { + OutputType *out = reinterpret_cast(output); + + for (std::size_t i = 0; i < n; i++) + { + const InputType *ein = reinterpret_cast(input + i * stride); + + copyComponent(out, ein, 0, static_cast(DefaultValueRule::zero())); + copyComponent(out, ein, 1, static_cast(DefaultValueRule::zero())); + copyComponent(out, ein, 2, static_cast(DefaultValueRule::zero())); + copyComponent(out, ein, 3, static_cast(DefaultValueRule::one())); + + out += WidenRule::finalWidth; + } + } + + private: + static void copyComponent(OutputType *out, + const InputType *in, + std::size_t elementindex, + OutputType defaultvalue) + { + if (WidenRule::finalWidth > elementindex) + { + if (WidenRule::initialWidth > elementindex) + { + out[elementindex] = Converter::convert(in[elementindex]); + } + else + { + out[elementindex] = defaultvalue; + } + } + } +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D9_VERTEXCONVERSION_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/driver_utils_d3d.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/driver_utils_d3d.cpp new file mode 100644 index 0000000000..1709f82868 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/driver_utils_d3d.cpp @@ -0,0 +1,26 @@ +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// driver_utils_d3d.cpp: Information specific to the D3D driver + +#include "libANGLE/renderer/d3d/driver_utils_d3d.h" + +namespace rx +{ + +std::string GetDriverVersionString(LARGE_INTEGER driverVersion) +{ + std::stringstream versionString; + uint64_t intVersion = driverVersion.QuadPart; + constexpr uint64_t kMask16 = std::numeric_limits::max(); + versionString << ((intVersion >> 48) & kMask16) << "."; + versionString << ((intVersion >> 32) & kMask16) << "."; + versionString << ((intVersion >> 16) & kMask16) << "."; + versionString << (intVersion & kMask16); + return versionString.str(); +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/driver_utils_d3d.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/driver_utils_d3d.h new file mode 100644 index 0000000000..3b217838f9 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/driver_utils_d3d.h @@ -0,0 +1,21 @@ +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// driver_utils_d3d.h: Information specific to the D3D driver + +#ifndef LIBANGLE_RENDERER_D3D_DRIVER_UTILS_D3D_H_ +#define LIBANGLE_RENDERER_D3D_DRIVER_UTILS_D3D_H_ + +#include "libANGLE/angletypes.h" + +namespace rx +{ + +std::string GetDriverVersionString(LARGE_INTEGER driverVersion); + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_DRIVER_UTILS_D3D_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/formatutilsD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/formatutilsD3D.h new file mode 100644 index 0000000000..f0e876d49d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/formatutilsD3D.h @@ -0,0 +1,24 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// formatutils9.h: Queries for GL image formats and their translations to D3D +// formats. + +#ifndef LIBANGLE_RENDERER_D3D_FORMATUTILSD3D_H_ +#define LIBANGLE_RENDERER_D3D_FORMATUTILSD3D_H_ + +namespace rx +{ +enum VertexConversionType +{ + VERTEX_CONVERT_NONE = 0, + VERTEX_CONVERT_CPU = 1, + VERTEX_CONVERT_GPU = 2, + VERTEX_CONVERT_BOTH = 3 +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_FORMATUTILSD3D_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d_format.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d_format.cpp new file mode 100644 index 0000000000..0823b37a5d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d_format.cpp @@ -0,0 +1,206 @@ +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// d3d_format: Describes a D3D9 format. Used by the D3D9 and GL back-ends. + +#include "libANGLE/renderer/d3d_format.h" + +using namespace angle; + +namespace rx +{ +namespace d3d9 +{ +namespace +{ +constexpr D3DFORMAT D3DFMT_INTZ = ((D3DFORMAT)(MAKEFOURCC('I', 'N', 'T', 'Z'))); +constexpr D3DFORMAT D3DFMT_NULL = ((D3DFORMAT)(MAKEFOURCC('N', 'U', 'L', 'L'))); +} // anonymous namespace + +D3DFormat::D3DFormat() + : pixelBytes(0), + blockWidth(0), + blockHeight(0), + redBits(0), + greenBits(0), + blueBits(0), + alphaBits(0), + luminanceBits(0), + depthBits(0), + stencilBits(0), + formatID(angle::FormatID::NONE) +{} + +D3DFormat::D3DFormat(GLuint bits, + GLuint blockWidth, + GLuint blockHeight, + GLuint redBits, + GLuint greenBits, + GLuint blueBits, + GLuint alphaBits, + GLuint lumBits, + GLuint depthBits, + GLuint stencilBits, + FormatID formatID) + : pixelBytes(bits / 8), + blockWidth(blockWidth), + blockHeight(blockHeight), + redBits(redBits), + greenBits(greenBits), + blueBits(blueBits), + alphaBits(alphaBits), + luminanceBits(lumBits), + depthBits(depthBits), + stencilBits(stencilBits), + formatID(formatID) +{} + +const D3DFormat &GetD3DFormatInfo(D3DFORMAT format) +{ + if (format == D3DFMT_NULL) + { + static const D3DFormat info(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FormatID::NONE); + return info; + } + + if (format == D3DFMT_INTZ) + { + static const D3DFormat info(32, 1, 1, 0, 0, 0, 0, 0, 24, 8, FormatID::D24_UNORM_S8_UINT); + return info; + } + + switch (format) + { + case D3DFMT_UNKNOWN: + { + static const D3DFormat info(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FormatID::NONE); + return info; + } + + case D3DFMT_L8: + { + static const D3DFormat info(8, 1, 1, 0, 0, 0, 0, 8, 0, 0, FormatID::L8_UNORM); + return info; + } + case D3DFMT_A8: + { + static const D3DFormat info(8, 1, 1, 0, 0, 0, 8, 0, 0, 0, FormatID::A8_UNORM); + return info; + } + case D3DFMT_A8L8: + { + static const D3DFormat info(16, 1, 1, 0, 0, 0, 8, 8, 0, 0, FormatID::L8A8_UNORM); + return info; + } + + case D3DFMT_A4R4G4B4: + { + static const D3DFormat info(16, 1, 1, 4, 4, 4, 4, 0, 0, 0, FormatID::B4G4R4A4_UNORM); + return info; + } + case D3DFMT_A1R5G5B5: + { + static const D3DFormat info(16, 1, 1, 5, 5, 5, 1, 0, 0, 0, FormatID::B5G5R5A1_UNORM); + return info; + } + case D3DFMT_R5G6B5: + { + static const D3DFormat info(16, 1, 1, 5, 6, 5, 0, 0, 0, 0, FormatID::R5G6B5_UNORM); + return info; + } + case D3DFMT_X8R8G8B8: + { + static const D3DFormat info(32, 1, 1, 8, 8, 8, 0, 0, 0, 0, FormatID::B8G8R8X8_UNORM); + return info; + } + case D3DFMT_A8R8G8B8: + { + static const D3DFormat info(32, 1, 1, 8, 8, 8, 8, 0, 0, 0, FormatID::B8G8R8A8_UNORM); + return info; + } + + case D3DFMT_R16F: + { + static const D3DFormat info(16, 1, 1, 16, 0, 0, 0, 0, 0, 0, FormatID::R16_FLOAT); + return info; + } + case D3DFMT_G16R16F: + { + static const D3DFormat info(32, 1, 1, 16, 16, 0, 0, 0, 0, 0, FormatID::R16G16_FLOAT); + return info; + } + case D3DFMT_A16B16G16R16F: + { + static const D3DFormat info(64, 1, 1, 16, 16, 16, 16, 0, 0, 0, + FormatID::R16G16B16A16_FLOAT); + return info; + } + case D3DFMT_R32F: + { + static const D3DFormat info(32, 1, 1, 32, 0, 0, 0, 0, 0, 0, FormatID::R32_FLOAT); + return info; + } + case D3DFMT_G32R32F: + { + static const D3DFormat info(64, 1, 1, 32, 32, 0, 0, 0, 0, 0, FormatID::R32G32_FLOAT); + return info; + } + case D3DFMT_A32B32G32R32F: + { + static const D3DFormat info(128, 1, 1, 32, 32, 32, 32, 0, 0, 0, + FormatID::R32G32B32A32_FLOAT); + return info; + } + + case D3DFMT_D16: + { + static const D3DFormat info(16, 1, 1, 0, 0, 0, 0, 0, 16, 0, FormatID::D16_UNORM); + return info; + } + case D3DFMT_D24S8: + { + static const D3DFormat info(32, 1, 1, 0, 0, 0, 0, 0, 24, 8, + FormatID::D24_UNORM_S8_UINT); + return info; + } + case D3DFMT_D24X8: + { + static const D3DFormat info(32, 1, 1, 0, 0, 0, 0, 0, 24, 0, FormatID::D16_UNORM); + return info; + } + case D3DFMT_D32: + { + static const D3DFormat info(32, 1, 1, 0, 0, 0, 0, 0, 32, 0, FormatID::D32_UNORM); + return info; + } + + case D3DFMT_DXT1: + { + static const D3DFormat info(64, 4, 4, 0, 0, 0, 0, 0, 0, 0, + FormatID::BC1_RGBA_UNORM_BLOCK); + return info; + } + case D3DFMT_DXT3: + { + static const D3DFormat info(128, 4, 4, 0, 0, 0, 0, 0, 0, 0, + FormatID::BC2_RGBA_UNORM_BLOCK); + return info; + } + case D3DFMT_DXT5: + { + static const D3DFormat info(128, 4, 4, 0, 0, 0, 0, 0, 0, 0, + FormatID::BC3_RGBA_UNORM_BLOCK); + return info; + } + + default: + { + static const D3DFormat defaultInfo; + return defaultInfo; + } + } +} +} // namespace d3d9 +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d_format.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d_format.h new file mode 100644 index 0000000000..4554f11460 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d_format.h @@ -0,0 +1,58 @@ +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// d3d_format: Describes a D3D9 format. Used by the D3D9 and GL back-ends. + +#ifndef LIBANGLE_RENDERER_D3D_FORMAT_H_ +#define LIBANGLE_RENDERER_D3D_FORMAT_H_ + +#include "libANGLE/renderer/Format.h" + +// We forcibly include the D3D9 header here because this file can be used from 3 different backends. +#include + +namespace rx +{ +namespace d3d9 +{ +struct D3DFormat +{ + D3DFormat(); + D3DFormat(GLuint pixelBytes, + GLuint blockWidth, + GLuint blockHeight, + GLuint redBits, + GLuint greenBits, + GLuint blueBits, + GLuint alphaBits, + GLuint luminanceBits, + GLuint depthBits, + GLuint stencilBits, + angle::FormatID formatID); + + const angle::Format &info() const { return angle::Format::Get(formatID); } + + GLuint pixelBytes; + GLuint blockWidth; + GLuint blockHeight; + + GLuint redBits; + GLuint greenBits; + GLuint blueBits; + GLuint alphaBits; + GLuint luminanceBits; + + GLuint depthBits; + GLuint stencilBits; + + angle::FormatID formatID; +}; + +const D3DFormat &GetD3DFormatInfo(D3DFORMAT format); + +} // namespace d3d9 +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_FORMAT_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/driver_utils.cpp b/gfx/angle/checkout/src/libANGLE/renderer/driver_utils.cpp new file mode 100644 index 0000000000..360a0dd9a2 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/driver_utils.cpp @@ -0,0 +1,438 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// driver_utils.h : provides more information about current driver. + +#include + +#include "libANGLE/renderer/driver_utils.h" + +#include "common/platform.h" +#include "common/system_utils.h" + +#if defined(ANGLE_PLATFORM_ANDROID) +# include +#endif + +#if defined(ANGLE_PLATFORM_LINUX) +# include +#endif + +#if defined(ANGLE_PLATFORM_WINDOWS) +# include +#endif + +namespace rx +{ +// Intel +// Referenced from +// https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/include/pci_ids/crocus_pci_ids.h +// https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/include/pci_ids/iris_pci_ids.h +namespace +{ +// gen6 +const uint16_t SandyBridge[] = { + 0x0102, 0x0106, 0x010A, // snb_gt1 + 0x0112, 0x0122, 0x0116, 0x0126 // snb_gt2 +}; + +// gen7 +const uint16_t IvyBridge[] = { + 0x0152, 0x0156, 0x015A, // ivb_gt1 + 0x0162, 0x0166, 0x016A // ivb_gt2 +}; + +// gen 7.5 +const uint16_t Haswell[] = { + 0x0402, 0x0406, 0x040A, 0x040B, 0x040E, 0x0C02, 0x0C06, 0x0C0A, 0x0C0B, 0x0C0E, + 0x0A02, 0x0A06, 0x0A0A, 0x0A0B, 0x0A0E, 0x0D02, 0x0D06, 0x0D0A, 0x0D0B, 0x0D0E, // hsw_gt1 + 0x0412, 0x0416, 0x041A, 0x041B, 0x041E, 0x0C12, 0x0C16, 0x0C1A, 0x0C1B, 0x0C1E, + 0x0A12, 0x0A16, 0x0A1A, 0x0A1B, 0x0A1E, 0x0D12, 0x0D16, 0x0D1A, 0x0D1B, 0x0D1E, // hsw_gt2 + 0x0422, 0x0426, 0x042A, 0x042B, 0x042E, 0x0C22, 0x0C26, 0x0C2A, 0x0C2B, 0x0C2E, + 0x0A22, 0x0A26, 0x0A2A, 0x0A2B, 0x0A2E, 0x0D22, 0x0D26, 0x0D2A, 0x0D2B, 0x0D2E // hsw_gt3 +}; + +// gen8 +const uint16_t Broadwell[] = { + 0x1602, 0x1606, 0x160A, 0x160B, 0x160D, 0x160E, // bdw_gt1 + 0x1612, 0x1616, 0x161A, 0x161B, 0x161D, 0x161E, // bdw_gt2 + 0x1622, 0x1626, 0x162A, 0x162B, 0x162D, 0x162E // bdw_gt3 +}; + +const uint16_t CherryView[] = {0x22B0, 0x22B1, 0x22B2, 0x22B3}; + +// gen9 +const uint16_t Skylake[] = { + 0x1902, 0x1906, 0x190A, 0x190B, 0x190E, // skl_gt1 + 0x1912, 0x1913, 0x1915, 0x1916, 0x1917, 0x191A, 0x191B, 0x191D, 0x191E, 0x1921, // skl_gt2 + 0x1923, 0x1926, 0x1927, 0x192B, 0x192D, // skl_gt3 + 0x192A, 0x1932, 0x193A, 0x193B, 0x193D // skl_gt4 +}; + +// gen9lp +const uint16_t Broxton[] = {0x0A84, 0x1A84, 0x1A85, 0x5A84, 0x5A85}; + +const uint16_t GeminiLake[] = {0x3184, 0x3185}; + +// gen9p5 +const uint16_t KabyLake[] = { + // Kaby Lake + 0x5902, 0x5906, 0x5908, 0x590A, 0x590B, 0x590E, // kbl_gt1 + 0x5913, 0x5915, // kbl_gt1_5 + 0x5912, 0x5916, 0x5917, 0x591A, 0x591B, 0x591D, 0x591E, 0x5921, // kbl_gt2 + 0x5923, 0x5926, 0x5927, // kbl_gt3 + 0x593B, // kbl_gt4 + // Amber Lake + 0x591C, 0x87C0 // kbl_gt2 +}; + +const uint16_t CoffeeLake[] = { + // Amber Lake + 0x87CA, // cfl_gt2 + + // Coffee Lake + 0x3E90, 0x3E93, 0x3E99, 0x3E9C, // cfl_gt1 + 0x3E91, 0x3E92, 0x3E94, 0x3E96, 0x3E98, 0x3E9A, 0x3E9B, 0x3EA9, // cfl_gt2 + 0x3EA5, 0x3EA6, 0x3EA7, 0x3EA8, // cfl_gt3 + + // Whisky Lake + 0x3EA1, 0x3EA4, // cfl_gt1 + 0x3EA0, 0x3EA3, // cfl_gt2 + 0x3EA2, // cfl_gt3 + + // Comet Lake + 0x9B21, 0x9BA0, 0x9BA2, 0x9BA4, 0x9BA5, 0x9BA8, 0x9BAA, 0x9BAB, 0x9BAC, // cfl_gt1 + 0x9B41, 0x9BC0, 0x9BC2, 0x9BC4, 0x9BC5, 0x9BC6, 0x9BC8, 0x9BCA, 0x9BCB, 0x9BCC, // cfl_gt2 + 0x9BE6, 0x9BF6 // cfl_gt2 +}; + +const uint16_t IntelGen11[] = { + // Ice Lake + 0x8A71, // icl_gt0_5 + 0x8A56, 0x8A58, 0x8A5B, 0x8A5D, // icl_gt1 + 0x8A54, 0x8A57, 0x8A59, 0x8A5A, 0x8A5C, // icl_gt1_5 + 0x8A50, 0x8A51, 0x8A52, 0x8A53, // icl_gt2 + + // Elkhart Lake + 0x4500, 0x4541, 0x4551, 0x4555, 0x4557, 0x4571, + + // Jasper Lake + 0x4E51, 0x4E55, 0x4E57, 0x4E61, 0x4E71}; + +const uint16_t IntelGen12[] = { + // Rocket Lake + 0x4C8C, // rkl_gt05 + 0x4C8A, 0x4C8B, 0x4C90, 0x4C9A, // rkl_gt1 + + // Alder Lake + 0x4683, 0x4693, // adl_gt05 + 0x4680, 0x4681, 0x4682, 0x4688, 0x4689, 0x4690, 0x4691, 0x4692, // adl_gt1 + 0x4626, 0x4628, 0x462A, 0x46A0, 0x46A1, 0x46A2, 0x46A3, 0x46A6, 0x46A8, // adl_gt2 + 0x46AA, 0x46B0, 0x46B1, 0x46B2, 0x46B3, 0x46C0, 0x46C1, 0x46C2, 0x46C3, // adl_gt2 + 0x46D0, 0x46D1, 0x46D2, // adl_n + + // Tiger Lake + 0x9A60, 0x9A68, 0x9A70, // tgl_gt1 + 0x9A40, 0x9A49, 0x9A59, 0x9A78, 0x9AC0, 0x9AC9, 0x9AD9, 0x9AF8, // tgl_gt2 + + // Raptop Lake + 0xA780, 0xA781, 0xA782, 0xA783, 0xA788, 0xA789, // rpl + 0xA720, 0xA721, 0xA7A0, 0xA7A1, 0xA7A8, 0xA7A9, // rpl_p + + // DG1 + 0x4905, 0x4906, 0x4907, 0x4908, 0x4909}; + +} // anonymous namespace + +IntelDriverVersion::IntelDriverVersion(uint32_t buildNumber) : mBuildNumber(buildNumber) {} + +bool IntelDriverVersion::operator==(const IntelDriverVersion &version) +{ + return mBuildNumber == version.mBuildNumber; +} + +bool IntelDriverVersion::operator!=(const IntelDriverVersion &version) +{ + return !(*this == version); +} + +bool IntelDriverVersion::operator<(const IntelDriverVersion &version) +{ + return mBuildNumber < version.mBuildNumber; +} + +bool IntelDriverVersion::operator>=(const IntelDriverVersion &version) +{ + return !(*this < version); +} + +bool IsSandyBridge(uint32_t DeviceId) +{ + return std::find(std::begin(SandyBridge), std::end(SandyBridge), DeviceId) != + std::end(SandyBridge); +} + +bool IsIvyBridge(uint32_t DeviceId) +{ + return std::find(std::begin(IvyBridge), std::end(IvyBridge), DeviceId) != std::end(IvyBridge); +} + +bool IsHaswell(uint32_t DeviceId) +{ + return std::find(std::begin(Haswell), std::end(Haswell), DeviceId) != std::end(Haswell); +} + +bool IsBroadwell(uint32_t DeviceId) +{ + return std::find(std::begin(Broadwell), std::end(Broadwell), DeviceId) != std::end(Broadwell); +} + +bool IsCherryView(uint32_t DeviceId) +{ + return std::find(std::begin(CherryView), std::end(CherryView), DeviceId) != + std::end(CherryView); +} + +bool IsSkylake(uint32_t DeviceId) +{ + return std::find(std::begin(Skylake), std::end(Skylake), DeviceId) != std::end(Skylake); +} + +bool IsBroxton(uint32_t DeviceId) +{ + return std::find(std::begin(Broxton), std::end(Broxton), DeviceId) != std::end(Broxton); +} + +bool IsKabyLake(uint32_t DeviceId) +{ + return std::find(std::begin(KabyLake), std::end(KabyLake), DeviceId) != std::end(KabyLake); +} + +bool IsGeminiLake(uint32_t DeviceId) +{ + return std::find(std::begin(GeminiLake), std::end(GeminiLake), DeviceId) != + std::end(GeminiLake); +} + +bool IsCoffeeLake(uint32_t DeviceId) +{ + return std::find(std::begin(CoffeeLake), std::end(CoffeeLake), DeviceId) != + std::end(CoffeeLake); +} + +bool Is9thGenIntel(uint32_t DeviceId) +{ + return IsSkylake(DeviceId) || IsBroxton(DeviceId) || IsKabyLake(DeviceId); +} + +bool Is11thGenIntel(uint32_t DeviceId) +{ + return std::find(std::begin(IntelGen11), std::end(IntelGen11), DeviceId) != + std::end(IntelGen11); +} + +bool Is12thGenIntel(uint32_t DeviceId) +{ + return std::find(std::begin(IntelGen12), std::end(IntelGen12), DeviceId) != + std::end(IntelGen12); +} + +const char *GetVendorString(uint32_t vendorId) +{ + switch (vendorId) + { + case VENDOR_ID_AMD: + return "AMD"; + case VENDOR_ID_ARM: + return "ARM"; + case VENDOR_ID_APPLE: + return "Apple"; + case VENDOR_ID_BROADCOM: + return "Broadcom"; + case VENDOR_ID_GOOGLE: + return "Google"; + case VENDOR_ID_INTEL: + return "Intel"; + case VENDOR_ID_MESA: + return "Mesa"; + case VENDOR_ID_MICROSOFT: + return "Microsoft"; + case VENDOR_ID_NVIDIA: + return "NVIDIA"; + case VENDOR_ID_POWERVR: + return "Imagination Technologies"; + case VENDOR_ID_QUALCOMM: + return "Qualcomm"; + case VENDOR_ID_SAMSUNG: + return "Samsung Electronics Co., Ltd."; + case VENDOR_ID_VIVANTE: + return "Vivante"; + case VENDOR_ID_VMWARE: + return "VMware"; + case 0xba5eba11: // Mock vendor ID used for tests. + return "Test"; + case 0: + return "NULL"; + default: + // TODO(jmadill): More vendor IDs. + UNIMPLEMENTED(); + return "Unknown"; + } +} + +MajorMinorPatchVersion::MajorMinorPatchVersion() {} +MajorMinorPatchVersion::MajorMinorPatchVersion(int major, int minor, int patch) + : majorVersion(major), minorVersion(minor), patchVersion(patch) +{} + +bool operator==(const MajorMinorPatchVersion &a, const MajorMinorPatchVersion &b) +{ + return std::tie(a.majorVersion, a.minorVersion, a.patchVersion) == + std::tie(b.majorVersion, b.minorVersion, b.patchVersion); +} +bool operator!=(const MajorMinorPatchVersion &a, const MajorMinorPatchVersion &b) +{ + return std::tie(a.majorVersion, a.minorVersion, a.patchVersion) != + std::tie(b.majorVersion, b.minorVersion, b.patchVersion); +} +bool operator<(const MajorMinorPatchVersion &a, const MajorMinorPatchVersion &b) +{ + return std::tie(a.majorVersion, a.minorVersion, a.patchVersion) < + std::tie(b.majorVersion, b.minorVersion, b.patchVersion); +} +bool operator>=(const MajorMinorPatchVersion &a, const MajorMinorPatchVersion &b) +{ + return std::tie(a.majorVersion, a.minorVersion, a.patchVersion) >= + std::tie(b.majorVersion, b.minorVersion, b.patchVersion); +} + +ARMDriverVersion ParseARMDriverVersion(uint32_t driverVersion) +{ + // ARM driver versions are built with the following macro: + // ((((uint32_t)(major)) << 22) | (((uint32_t)(minor)) << 12) | ((uint32_t)(patch))) + constexpr uint32_t kMinorVersionMask = angle::BitMask(10); + constexpr uint32_t kPatchMask = angle::BitMask(12); + return ARMDriverVersion(driverVersion >> 22, (driverVersion >> 12) & kMinorVersionMask, + driverVersion & kPatchMask); +} + +int GetAndroidSDKVersion() +{ +#if defined(ANGLE_PLATFORM_ANDROID) + char apiVersion[PROP_VALUE_MAX]; + int length = __system_property_get("ro.build.version.sdk", apiVersion); + if (length == 0) + { + return 0; + } + return atoi(apiVersion); +#else + return 0; +#endif +} +#if !defined(ANGLE_PLATFORM_MACOS) +OSVersion GetMacOSVersion() +{ + // Return a default version + return OSVersion(0, 0, 0); +} +#endif + +#if !defined(ANGLE_PLATFORM_IOS) +OSVersion GetiOSVersion() +{ + // Return a default version + return OSVersion(0, 0, 0); +} +#endif + +#if defined(ANGLE_PLATFORM_LINUX) +bool ParseLinuxOSVersion(const char *version, int *major, int *minor, int *patch) +{ + errno = 0; // reset global error flag. + char *next; + *major = static_cast(strtol(version, &next, 10)); + if (next == nullptr || *next != '.' || errno != 0) + { + return false; + } + + *minor = static_cast(strtol(next + 1, &next, 10)); + if (next == nullptr || *next != '.' || errno != 0) + { + return false; + } + + *patch = static_cast(strtol(next + 1, &next, 10)); + if (errno != 0) + { + return false; + } + + return true; +} +#endif + +OSVersion GetLinuxOSVersion() +{ +#if defined(ANGLE_PLATFORM_LINUX) + struct utsname uname_info; + if (uname(&uname_info) != 0) + { + return OSVersion(0, 0, 0); + } + + int majorVersion = 0, minorVersion = 0, patchVersion = 0; + if (ParseLinuxOSVersion(uname_info.release, &majorVersion, &minorVersion, &patchVersion)) + { + return OSVersion(majorVersion, minorVersion, patchVersion); + } +#endif + + return OSVersion(0, 0, 0); +} + +// There are multiple environment variables that may or may not be set during Wayland +// sessions, including WAYLAND_DISPLAY, XDG_SESSION_TYPE, and DESKTOP_SESSION +bool IsWayland() +{ + static bool checked = false; + static bool isWayland = false; + if (!checked) + { + if (IsLinux()) + { + if (!angle::GetEnvironmentVar("WAYLAND_DISPLAY").empty()) + { + isWayland = true; + } + else if (angle::GetEnvironmentVar("XDG_SESSION_TYPE") == "wayland") + { + isWayland = true; + } + else if (angle::GetEnvironmentVar("DESKTOP_SESSION").find("wayland") != + std::string::npos) + { + isWayland = true; + } + } + checked = true; + } + return isWayland; +} + +bool IsWin10OrGreater() +{ +#if defined(ANGLE_ENABLE_WINDOWS_UWP) + return true; +#elif defined(ANGLE_PLATFORM_WINDOWS) + return IsWindows10OrGreater(); +#else + return false; +#endif +} + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/driver_utils.h b/gfx/angle/checkout/src/libANGLE/renderer/driver_utils.h new file mode 100644 index 0000000000..3addc07ffd --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/driver_utils.h @@ -0,0 +1,278 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// driver_utils.h : provides more information about current driver. + +#ifndef LIBANGLE_RENDERER_DRIVER_UTILS_H_ +#define LIBANGLE_RENDERER_DRIVER_UTILS_H_ + +#include "common/platform.h" +#include "libANGLE/angletypes.h" + +namespace rx +{ + +enum VendorID : uint32_t +{ + VENDOR_ID_UNKNOWN = 0x0, + VENDOR_ID_AMD = 0x1002, + VENDOR_ID_APPLE = 0x106B, + VENDOR_ID_ARM = 0x13B5, + // Broadcom devices won't use PCI, but this is their Vulkan vendor id. + VENDOR_ID_BROADCOM = 0x14E4, + VENDOR_ID_GOOGLE = 0x1AE0, + VENDOR_ID_INTEL = 0x8086, + VENDOR_ID_MESA = 0x10005, + VENDOR_ID_MICROSOFT = 0x1414, + VENDOR_ID_NVIDIA = 0x10DE, + VENDOR_ID_POWERVR = 0x1010, + // This is Qualcomm PCI Vendor ID. + // Android doesn't have a PCI bus, but all we need is a unique id. + VENDOR_ID_QUALCOMM = 0x5143, + VENDOR_ID_SAMSUNG = 0x144D, + VENDOR_ID_VIVANTE = 0x9999, + VENDOR_ID_VMWARE = 0x15AD, +}; + +enum AndroidDeviceID : uint32_t +{ + ANDROID_DEVICE_ID_UNKNOWN = 0x0, + ANDROID_DEVICE_ID_NEXUS5X = 0x4010800, + ANDROID_DEVICE_ID_PIXEL2 = 0x5040001, + ANDROID_DEVICE_ID_PIXEL1XL = 0x5030004, + ANDROID_DEVICE_ID_PIXEL4 = 0x6040001, + ANDROID_DEVICE_ID_SWIFTSHADER = 0xC0DE, +}; + +inline bool IsAMD(uint32_t vendorId) +{ + return vendorId == VENDOR_ID_AMD; +} + +inline bool IsApple(uint32_t vendorId) +{ + return vendorId == VENDOR_ID_APPLE; +} + +inline bool IsARM(uint32_t vendorId) +{ + return vendorId == VENDOR_ID_ARM; +} + +inline bool IsBroadcom(uint32_t vendorId) +{ + return vendorId == VENDOR_ID_BROADCOM; +} + +inline bool IsIntel(uint32_t vendorId) +{ + return vendorId == VENDOR_ID_INTEL; +} + +inline bool IsGoogle(uint32_t vendorId) +{ + return vendorId == VENDOR_ID_GOOGLE; +} + +inline bool IsMicrosoft(uint32_t vendorId) +{ + return vendorId == VENDOR_ID_MICROSOFT; +} + +inline bool IsNvidia(uint32_t vendorId) +{ + return vendorId == VENDOR_ID_NVIDIA; +} + +inline bool IsPowerVR(uint32_t vendorId) +{ + return vendorId == VENDOR_ID_POWERVR; +} + +inline bool IsQualcomm(uint32_t vendorId) +{ + return vendorId == VENDOR_ID_QUALCOMM; +} + +inline bool IsSamsung(uint32_t vendorId) +{ + return vendorId == VENDOR_ID_SAMSUNG; +} + +inline bool IsVivante(uint32_t vendorId) +{ + return vendorId == VENDOR_ID_VIVANTE; +} + +inline bool IsVMWare(uint32_t vendorId) +{ + return vendorId == VENDOR_ID_VMWARE; +} + +inline bool IsNexus5X(uint32_t vendorId, uint32_t deviceId) +{ + return IsQualcomm(vendorId) && deviceId == ANDROID_DEVICE_ID_NEXUS5X; +} + +inline bool IsPixel1XL(uint32_t vendorId, uint32_t deviceId) +{ + return IsQualcomm(vendorId) && deviceId == ANDROID_DEVICE_ID_PIXEL1XL; +} + +inline bool IsPixel2(uint32_t vendorId, uint32_t deviceId) +{ + return IsQualcomm(vendorId) && deviceId == ANDROID_DEVICE_ID_PIXEL2; +} + +inline bool IsPixel4(uint32_t vendorId, uint32_t deviceId) +{ + return IsQualcomm(vendorId) && deviceId == ANDROID_DEVICE_ID_PIXEL4; +} + +inline bool IsSwiftshader(uint32_t vendorId, uint32_t deviceId) +{ + return IsGoogle(vendorId) && deviceId == ANDROID_DEVICE_ID_SWIFTSHADER; +} + +const char *GetVendorString(uint32_t vendorId); + +// For Linux, Intel graphics driver version is the Mesa version. The version number has three +// fields: major revision, minor revision and release number. +// For Windows, The version number includes 3rd and 4th fields. Please refer the details at +// http://www.intel.com/content/www/us/en/support/graphics-drivers/000005654.html. +// Current implementation only supports Windows. +class IntelDriverVersion +{ + public: + IntelDriverVersion(uint32_t buildNumber); + bool operator==(const IntelDriverVersion &); + bool operator!=(const IntelDriverVersion &); + bool operator<(const IntelDriverVersion &); + bool operator>=(const IntelDriverVersion &); + + private: + uint32_t mBuildNumber; +}; + +bool IsSandyBridge(uint32_t DeviceId); +bool IsIvyBridge(uint32_t DeviceId); +bool IsHaswell(uint32_t DeviceId); +bool IsBroadwell(uint32_t DeviceId); +bool IsCherryView(uint32_t DeviceId); +bool IsSkylake(uint32_t DeviceId); +bool IsBroxton(uint32_t DeviceId); +bool IsKabyLake(uint32_t DeviceId); +bool IsGeminiLake(uint32_t DeviceId); +bool IsCoffeeLake(uint32_t DeviceId); +bool Is9thGenIntel(uint32_t DeviceId); +bool Is11thGenIntel(uint32_t DeviceId); +bool Is12thGenIntel(uint32_t DeviceId); + +struct MajorMinorPatchVersion +{ + MajorMinorPatchVersion(); + MajorMinorPatchVersion(int major, int minor, int patch); + + int majorVersion = 0; + int minorVersion = 0; + int patchVersion = 0; +}; +bool operator==(const MajorMinorPatchVersion &a, const MajorMinorPatchVersion &b); +bool operator!=(const MajorMinorPatchVersion &a, const MajorMinorPatchVersion &b); +bool operator<(const MajorMinorPatchVersion &a, const MajorMinorPatchVersion &b); +bool operator>=(const MajorMinorPatchVersion &a, const MajorMinorPatchVersion &b); + +using ARMDriverVersion = MajorMinorPatchVersion; +ARMDriverVersion ParseARMDriverVersion(uint32_t driverVersion); + +// Platform helpers +inline bool IsWindows() +{ +#if defined(ANGLE_PLATFORM_WINDOWS) + return true; +#else + return false; +#endif +} + +inline bool IsLinux() +{ +#if defined(ANGLE_PLATFORM_LINUX) + return true; +#else + return false; +#endif +} + +inline bool IsChromeOS() +{ +#if defined(ANGLE_PLATFORM_CHROMEOS) + return true; +#else + return false; +#endif +} + +inline bool IsApple() +{ +#if defined(ANGLE_PLATFORM_APPLE) + return true; +#else + return false; +#endif +} + +inline bool IsMac() +{ +#if defined(ANGLE_PLATFORM_APPLE) && defined(ANGLE_PLATFORM_MACOS) + return true; +#else + return false; +#endif +} + +inline bool IsFuchsia() +{ +#if defined(ANGLE_PLATFORM_FUCHSIA) + return true; +#else + return false; +#endif +} + +inline bool IsIOS() +{ +#if defined(ANGLE_PLATFORM_IOS) + return true; +#else + return false; +#endif +} + +bool IsWayland(); +bool IsWin10OrGreater(); + +using OSVersion = MajorMinorPatchVersion; + +OSVersion GetMacOSVersion(); + +OSVersion GetiOSVersion(); + +OSVersion GetLinuxOSVersion(); + +inline bool IsAndroid() +{ +#if defined(ANGLE_PLATFORM_ANDROID) + return true; +#else + return false; +#endif +} + +int GetAndroidSDKVersion(); + +} // namespace rx +#endif // LIBANGLE_RENDERER_DRIVER_UTILS_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/dxgi_format_map.h b/gfx/angle/checkout/src/libANGLE/renderer/dxgi_format_map.h new file mode 100644 index 0000000000..711d0d0a0b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/dxgi_format_map.h @@ -0,0 +1,27 @@ +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// DXGI format info: +// Determining metadata about a DXGI format. + +#ifndef LIBANGLE_RENDERER_DXGI_FORMAT_MAP_H_ +#define LIBANGLE_RENDERER_DXGI_FORMAT_MAP_H_ + +#include "common/platform.h" + +namespace rx +{ +namespace d3d11 +{ +GLenum GetComponentType(DXGI_FORMAT dxgiFormat); +} // namespace d3d11 + +namespace d3d11_angle +{ +const angle::Format &GetFormat(DXGI_FORMAT dxgiFormat); +} // namespace d3d11_angle +} // namespace rx + +#endif // LIBANGLE_RENDERER_DXGI_FORMAT_MAP_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/dxgi_format_map_autogen.cpp b/gfx/angle/checkout/src/libANGLE/renderer/dxgi_format_map_autogen.cpp new file mode 100644 index 0000000000..a46567ae0d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/dxgi_format_map_autogen.cpp @@ -0,0 +1,516 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_dxgi_format_table.py using data from dxgi_format_data.json. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// DXGI format info: +// Determining metadata about a DXGI format. + +#include "libANGLE/renderer/Format.h" + +using namespace angle; + +namespace rx +{ + +namespace d3d11 +{ + +GLenum GetComponentType(DXGI_FORMAT dxgiFormat) +{ + switch (dxgiFormat) + { + case DXGI_FORMAT_420_OPAQUE: + break; + case DXGI_FORMAT_A8P8: + break; + case DXGI_FORMAT_A8_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_AI44: + break; + case DXGI_FORMAT_AYUV: + break; + case DXGI_FORMAT_B4G4R4A4_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_B5G5R5A1_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_B5G6R5_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + break; + case DXGI_FORMAT_B8G8R8A8_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + break; + case DXGI_FORMAT_B8G8R8X8_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_BC1_TYPELESS: + break; + case DXGI_FORMAT_BC1_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_BC1_UNORM_SRGB: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_BC2_TYPELESS: + break; + case DXGI_FORMAT_BC2_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_BC2_UNORM_SRGB: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_BC3_TYPELESS: + break; + case DXGI_FORMAT_BC3_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_BC3_UNORM_SRGB: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_BC4_SNORM: + return GL_SIGNED_NORMALIZED; + case DXGI_FORMAT_BC4_TYPELESS: + break; + case DXGI_FORMAT_BC4_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_BC5_SNORM: + return GL_SIGNED_NORMALIZED; + case DXGI_FORMAT_BC5_TYPELESS: + break; + case DXGI_FORMAT_BC5_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_BC6H_SF16: + break; + case DXGI_FORMAT_BC6H_TYPELESS: + break; + case DXGI_FORMAT_BC6H_UF16: + break; + case DXGI_FORMAT_BC7_TYPELESS: + break; + case DXGI_FORMAT_BC7_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_BC7_UNORM_SRGB: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_D16_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_D24_UNORM_S8_UINT: + break; + case DXGI_FORMAT_D32_FLOAT: + return GL_FLOAT; + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + break; + case DXGI_FORMAT_G8R8_G8B8_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_IA44: + break; + case DXGI_FORMAT_NV11: + break; + case DXGI_FORMAT_NV12: + break; + case DXGI_FORMAT_P010: + break; + case DXGI_FORMAT_P016: + break; + case DXGI_FORMAT_P8: + break; + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + break; + case DXGI_FORMAT_R10G10B10A2_UINT: + return GL_UNSIGNED_INT; + case DXGI_FORMAT_R10G10B10A2_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_R11G11B10_FLOAT: + return GL_FLOAT; + case DXGI_FORMAT_R16G16B16A16_FLOAT: + return GL_FLOAT; + case DXGI_FORMAT_R16G16B16A16_SINT: + return GL_INT; + case DXGI_FORMAT_R16G16B16A16_SNORM: + return GL_SIGNED_NORMALIZED; + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + break; + case DXGI_FORMAT_R16G16B16A16_UINT: + return GL_UNSIGNED_INT; + case DXGI_FORMAT_R16G16B16A16_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_R16G16_FLOAT: + return GL_FLOAT; + case DXGI_FORMAT_R16G16_SINT: + return GL_INT; + case DXGI_FORMAT_R16G16_SNORM: + return GL_SIGNED_NORMALIZED; + case DXGI_FORMAT_R16G16_TYPELESS: + break; + case DXGI_FORMAT_R16G16_UINT: + return GL_UNSIGNED_INT; + case DXGI_FORMAT_R16G16_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_R16_FLOAT: + return GL_FLOAT; + case DXGI_FORMAT_R16_SINT: + return GL_INT; + case DXGI_FORMAT_R16_SNORM: + return GL_SIGNED_NORMALIZED; + case DXGI_FORMAT_R16_TYPELESS: + break; + case DXGI_FORMAT_R16_UINT: + return GL_UNSIGNED_INT; + case DXGI_FORMAT_R16_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_R1_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_R24G8_TYPELESS: + break; + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_R32G32B32A32_FLOAT: + return GL_FLOAT; + case DXGI_FORMAT_R32G32B32A32_SINT: + return GL_INT; + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + break; + case DXGI_FORMAT_R32G32B32A32_UINT: + return GL_UNSIGNED_INT; + case DXGI_FORMAT_R32G32B32_FLOAT: + return GL_FLOAT; + case DXGI_FORMAT_R32G32B32_SINT: + return GL_INT; + case DXGI_FORMAT_R32G32B32_TYPELESS: + break; + case DXGI_FORMAT_R32G32B32_UINT: + return GL_UNSIGNED_INT; + case DXGI_FORMAT_R32G32_FLOAT: + return GL_FLOAT; + case DXGI_FORMAT_R32G32_SINT: + return GL_INT; + case DXGI_FORMAT_R32G32_TYPELESS: + break; + case DXGI_FORMAT_R32G32_UINT: + return GL_UNSIGNED_INT; + case DXGI_FORMAT_R32G8X24_TYPELESS: + break; + case DXGI_FORMAT_R32_FLOAT: + return GL_FLOAT; + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + return GL_FLOAT; + case DXGI_FORMAT_R32_SINT: + return GL_INT; + case DXGI_FORMAT_R32_TYPELESS: + break; + case DXGI_FORMAT_R32_UINT: + return GL_UNSIGNED_INT; + case DXGI_FORMAT_R8G8B8A8_SINT: + return GL_INT; + case DXGI_FORMAT_R8G8B8A8_SNORM: + return GL_SIGNED_NORMALIZED; + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + break; + case DXGI_FORMAT_R8G8B8A8_UINT: + return GL_UNSIGNED_INT; + case DXGI_FORMAT_R8G8B8A8_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_R8G8_B8G8_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_R8G8_SINT: + return GL_INT; + case DXGI_FORMAT_R8G8_SNORM: + return GL_SIGNED_NORMALIZED; + case DXGI_FORMAT_R8G8_TYPELESS: + break; + case DXGI_FORMAT_R8G8_UINT: + return GL_UNSIGNED_INT; + case DXGI_FORMAT_R8G8_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_R8_SINT: + return GL_INT; + case DXGI_FORMAT_R8_SNORM: + return GL_SIGNED_NORMALIZED; + case DXGI_FORMAT_R8_TYPELESS: + break; + case DXGI_FORMAT_R8_UINT: + return GL_UNSIGNED_INT; + case DXGI_FORMAT_R8_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + return GL_FLOAT; + case DXGI_FORMAT_UNKNOWN: + break; + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + return GL_UNSIGNED_INT; + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + return GL_UNSIGNED_INT; + case DXGI_FORMAT_Y210: + break; + case DXGI_FORMAT_Y216: + break; + case DXGI_FORMAT_Y410: + break; + case DXGI_FORMAT_Y416: + break; + case DXGI_FORMAT_YUY2: + break; + default: + break; + } + + UNREACHABLE(); + return GL_NONE; +} + +} // namespace d3d11 + +namespace d3d11_angle +{ + +const Format &GetFormat(DXGI_FORMAT dxgiFormat) +{ + switch (dxgiFormat) + { + case DXGI_FORMAT_420_OPAQUE: + break; + case DXGI_FORMAT_A8P8: + break; + case DXGI_FORMAT_A8_UNORM: + return Format::Get(FormatID::A8_UNORM); + case DXGI_FORMAT_AI44: + break; + case DXGI_FORMAT_AYUV: + break; + case DXGI_FORMAT_B4G4R4A4_UNORM: + return Format::Get(FormatID::B4G4R4A4_UNORM); + case DXGI_FORMAT_B5G5R5A1_UNORM: + return Format::Get(FormatID::B5G5R5A1_UNORM); + case DXGI_FORMAT_B5G6R5_UNORM: + return Format::Get(FormatID::B5G6R5_UNORM); + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + return Format::Get(FormatID::B8G8R8A8_TYPELESS); + case DXGI_FORMAT_B8G8R8A8_UNORM: + return Format::Get(FormatID::B8G8R8A8_UNORM); + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + return Format::Get(FormatID::B8G8R8A8_UNORM_SRGB); + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + break; + case DXGI_FORMAT_B8G8R8X8_UNORM: + return Format::Get(FormatID::B8G8R8X8_UNORM); + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: + break; + case DXGI_FORMAT_BC1_TYPELESS: + break; + case DXGI_FORMAT_BC1_UNORM: + return Format::Get(FormatID::BC1_RGBA_UNORM_BLOCK); + case DXGI_FORMAT_BC1_UNORM_SRGB: + return Format::Get(FormatID::BC1_RGBA_UNORM_SRGB_BLOCK); + case DXGI_FORMAT_BC2_TYPELESS: + break; + case DXGI_FORMAT_BC2_UNORM: + return Format::Get(FormatID::BC2_RGBA_UNORM_BLOCK); + case DXGI_FORMAT_BC2_UNORM_SRGB: + return Format::Get(FormatID::BC2_RGBA_UNORM_SRGB_BLOCK); + case DXGI_FORMAT_BC3_TYPELESS: + break; + case DXGI_FORMAT_BC3_UNORM: + return Format::Get(FormatID::BC3_RGBA_UNORM_BLOCK); + case DXGI_FORMAT_BC3_UNORM_SRGB: + return Format::Get(FormatID::BC3_RGBA_UNORM_SRGB_BLOCK); + case DXGI_FORMAT_BC4_SNORM: + return Format::Get(FormatID::BC4_RED_SNORM_BLOCK); + case DXGI_FORMAT_BC4_TYPELESS: + break; + case DXGI_FORMAT_BC4_UNORM: + return Format::Get(FormatID::BC4_RED_UNORM_BLOCK); + case DXGI_FORMAT_BC5_SNORM: + return Format::Get(FormatID::BC5_RG_SNORM_BLOCK); + case DXGI_FORMAT_BC5_TYPELESS: + break; + case DXGI_FORMAT_BC5_UNORM: + return Format::Get(FormatID::BC5_RG_UNORM_BLOCK); + case DXGI_FORMAT_BC6H_SF16: + break; + case DXGI_FORMAT_BC6H_TYPELESS: + break; + case DXGI_FORMAT_BC6H_UF16: + break; + case DXGI_FORMAT_BC7_TYPELESS: + break; + case DXGI_FORMAT_BC7_UNORM: + break; + case DXGI_FORMAT_BC7_UNORM_SRGB: + break; + case DXGI_FORMAT_D16_UNORM: + return Format::Get(FormatID::D16_UNORM); + case DXGI_FORMAT_D24_UNORM_S8_UINT: + return Format::Get(FormatID::D24_UNORM_S8_UINT); + case DXGI_FORMAT_D32_FLOAT: + return Format::Get(FormatID::D32_FLOAT); + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + return Format::Get(FormatID::D32_FLOAT_S8X24_UINT); + case DXGI_FORMAT_G8R8_G8B8_UNORM: + break; + case DXGI_FORMAT_IA44: + break; + case DXGI_FORMAT_NV11: + break; + case DXGI_FORMAT_NV12: + break; + case DXGI_FORMAT_P010: + break; + case DXGI_FORMAT_P016: + break; + case DXGI_FORMAT_P8: + break; + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + break; + case DXGI_FORMAT_R10G10B10A2_UINT: + return Format::Get(FormatID::R10G10B10A2_UINT); + case DXGI_FORMAT_R10G10B10A2_UNORM: + return Format::Get(FormatID::R10G10B10A2_UNORM); + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: + break; + case DXGI_FORMAT_R11G11B10_FLOAT: + return Format::Get(FormatID::R11G11B10_FLOAT); + case DXGI_FORMAT_R16G16B16A16_FLOAT: + return Format::Get(FormatID::R16G16B16A16_FLOAT); + case DXGI_FORMAT_R16G16B16A16_SINT: + return Format::Get(FormatID::R16G16B16A16_SINT); + case DXGI_FORMAT_R16G16B16A16_SNORM: + return Format::Get(FormatID::R16G16B16A16_SNORM); + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + break; + case DXGI_FORMAT_R16G16B16A16_UINT: + return Format::Get(FormatID::R16G16B16A16_UINT); + case DXGI_FORMAT_R16G16B16A16_UNORM: + return Format::Get(FormatID::R16G16B16A16_UNORM); + case DXGI_FORMAT_R16G16_FLOAT: + return Format::Get(FormatID::R16G16_FLOAT); + case DXGI_FORMAT_R16G16_SINT: + return Format::Get(FormatID::R16G16_SINT); + case DXGI_FORMAT_R16G16_SNORM: + return Format::Get(FormatID::R16G16_SNORM); + case DXGI_FORMAT_R16G16_TYPELESS: + break; + case DXGI_FORMAT_R16G16_UINT: + return Format::Get(FormatID::R16G16_UINT); + case DXGI_FORMAT_R16G16_UNORM: + return Format::Get(FormatID::R16G16_UNORM); + case DXGI_FORMAT_R16_FLOAT: + return Format::Get(FormatID::R16_FLOAT); + case DXGI_FORMAT_R16_SINT: + return Format::Get(FormatID::R16_SINT); + case DXGI_FORMAT_R16_SNORM: + return Format::Get(FormatID::R16_SNORM); + case DXGI_FORMAT_R16_TYPELESS: + break; + case DXGI_FORMAT_R16_UINT: + return Format::Get(FormatID::R16_UINT); + case DXGI_FORMAT_R16_UNORM: + return Format::Get(FormatID::R16_UNORM); + case DXGI_FORMAT_R1_UNORM: + break; + case DXGI_FORMAT_R24G8_TYPELESS: + break; + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + break; + case DXGI_FORMAT_R32G32B32A32_FLOAT: + return Format::Get(FormatID::R32G32B32A32_FLOAT); + case DXGI_FORMAT_R32G32B32A32_SINT: + return Format::Get(FormatID::R32G32B32A32_SINT); + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + break; + case DXGI_FORMAT_R32G32B32A32_UINT: + return Format::Get(FormatID::R32G32B32A32_UINT); + case DXGI_FORMAT_R32G32B32_FLOAT: + return Format::Get(FormatID::R32G32B32_FLOAT); + case DXGI_FORMAT_R32G32B32_SINT: + return Format::Get(FormatID::R32G32B32_SINT); + case DXGI_FORMAT_R32G32B32_TYPELESS: + break; + case DXGI_FORMAT_R32G32B32_UINT: + return Format::Get(FormatID::R32G32B32_UINT); + case DXGI_FORMAT_R32G32_FLOAT: + return Format::Get(FormatID::R32G32_FLOAT); + case DXGI_FORMAT_R32G32_SINT: + return Format::Get(FormatID::R32G32_SINT); + case DXGI_FORMAT_R32G32_TYPELESS: + break; + case DXGI_FORMAT_R32G32_UINT: + return Format::Get(FormatID::R32G32_UINT); + case DXGI_FORMAT_R32G8X24_TYPELESS: + break; + case DXGI_FORMAT_R32_FLOAT: + return Format::Get(FormatID::R32_FLOAT); + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + break; + case DXGI_FORMAT_R32_SINT: + return Format::Get(FormatID::R32_SINT); + case DXGI_FORMAT_R32_TYPELESS: + break; + case DXGI_FORMAT_R32_UINT: + return Format::Get(FormatID::R32_UINT); + case DXGI_FORMAT_R8G8B8A8_SINT: + return Format::Get(FormatID::R8G8B8A8_SINT); + case DXGI_FORMAT_R8G8B8A8_SNORM: + return Format::Get(FormatID::R8G8B8A8_SNORM); + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + return Format::Get(FormatID::R8G8B8A8_TYPELESS); + case DXGI_FORMAT_R8G8B8A8_UINT: + return Format::Get(FormatID::R8G8B8A8_UINT); + case DXGI_FORMAT_R8G8B8A8_UNORM: + return Format::Get(FormatID::R8G8B8A8_UNORM); + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + return Format::Get(FormatID::R8G8B8A8_UNORM_SRGB); + case DXGI_FORMAT_R8G8_B8G8_UNORM: + break; + case DXGI_FORMAT_R8G8_SINT: + return Format::Get(FormatID::R8G8_SINT); + case DXGI_FORMAT_R8G8_SNORM: + return Format::Get(FormatID::R8G8_SNORM); + case DXGI_FORMAT_R8G8_TYPELESS: + break; + case DXGI_FORMAT_R8G8_UINT: + return Format::Get(FormatID::R8G8_UINT); + case DXGI_FORMAT_R8G8_UNORM: + return Format::Get(FormatID::R8G8_UNORM); + case DXGI_FORMAT_R8_SINT: + return Format::Get(FormatID::R8_SINT); + case DXGI_FORMAT_R8_SNORM: + return Format::Get(FormatID::R8_SNORM); + case DXGI_FORMAT_R8_TYPELESS: + break; + case DXGI_FORMAT_R8_UINT: + return Format::Get(FormatID::R8_UINT); + case DXGI_FORMAT_R8_UNORM: + return Format::Get(FormatID::R8_UNORM); + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + return Format::Get(FormatID::R9G9B9E5_SHAREDEXP); + case DXGI_FORMAT_UNKNOWN: + return Format::Get(FormatID::NONE); + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + break; + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + break; + case DXGI_FORMAT_Y210: + break; + case DXGI_FORMAT_Y216: + break; + case DXGI_FORMAT_Y410: + break; + case DXGI_FORMAT_Y416: + break; + case DXGI_FORMAT_YUY2: + break; + default: + break; + } + + UNREACHABLE(); + return Format::Get(FormatID::NONE); +} + +} // namespace d3d11_angle + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/dxgi_support_table.h b/gfx/angle/checkout/src/libANGLE/renderer/dxgi_support_table.h new file mode 100644 index 0000000000..fef57d0a1b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/dxgi_support_table.h @@ -0,0 +1,43 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// dxgi_support_table: +// Queries for DXGI support of various texture formats. Depends on DXGI +// version, D3D feature level, and is sometimes guaranteed or optional. +// + +#ifndef LIBANGLE_RENDERER_DXGI_SUPPORT_TABLE_H_ +#define LIBANGLE_RENDERER_DXGI_SUPPORT_TABLE_H_ + +#include "common/platform.h" + +namespace rx +{ + +namespace d3d11 +{ + +struct DXGISupport +{ + DXGISupport() : alwaysSupportedFlags(0), neverSupportedFlags(0), optionallySupportedFlags(0) {} + + DXGISupport(UINT alwaysSupportedIn, UINT neverSupportedIn, UINT optionallySupportedIn) + : alwaysSupportedFlags(alwaysSupportedIn), + neverSupportedFlags(neverSupportedIn), + optionallySupportedFlags(optionallySupportedIn) + {} + + UINT alwaysSupportedFlags; + UINT neverSupportedFlags; + UINT optionallySupportedFlags; +}; + +const DXGISupport &GetDXGISupport(DXGI_FORMAT dxgiFormat, D3D_FEATURE_LEVEL featureLevel); + +} // namespace d3d11 + +} // namespace rx + +#endif // LIBANGLE_RENDERER_DXGI_SUPPORT_TABLE_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/dxgi_support_table_autogen.cpp b/gfx/angle/checkout/src/libANGLE/renderer/dxgi_support_table_autogen.cpp new file mode 100644 index 0000000000..56bbaed0db --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/dxgi_support_table_autogen.cpp @@ -0,0 +1,3042 @@ +// GENERATED FILE - DO NOT EDIT. See dxgi_support_data.json. +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// dxgi_support_table: +// Queries for DXGI support of various texture formats. Depends on DXGI +// version, D3D feature level, and is sometimes guaranteed or optional. +// + +#include "libANGLE/renderer/dxgi_support_table.h" + +#include "common/debug.h" + +namespace rx +{ + +namespace d3d11 +{ + +#define F_2D D3D11_FORMAT_SUPPORT_TEXTURE2D +#define F_3D D3D11_FORMAT_SUPPORT_TEXTURE3D +#define F_CUBE D3D11_FORMAT_SUPPORT_TEXTURECUBE +#define F_SAMPLE D3D11_FORMAT_SUPPORT_SHADER_SAMPLE +#define F_RT D3D11_FORMAT_SUPPORT_RENDER_TARGET +#define F_MS D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET +#define F_DS D3D11_FORMAT_SUPPORT_DEPTH_STENCIL +#define F_MIPGEN D3D11_FORMAT_SUPPORT_MIP_AUTOGEN + +namespace +{ + +const DXGISupport &GetDefaultSupport() +{ + static UINT AllSupportFlags = + D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_TEXTURE3D | + D3D11_FORMAT_SUPPORT_TEXTURECUBE | D3D11_FORMAT_SUPPORT_SHADER_SAMPLE | + D3D11_FORMAT_SUPPORT_RENDER_TARGET | D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET | + D3D11_FORMAT_SUPPORT_DEPTH_STENCIL | D3D11_FORMAT_SUPPORT_MIP_AUTOGEN; + static const DXGISupport defaultSupport(0, 0, AllSupportFlags); + return defaultSupport; +} + +const DXGISupport &GetDXGISupport_9_3(DXGI_FORMAT dxgiFormat) +{ + // clang-format off + switch (dxgiFormat) + { + case DXGI_FORMAT_420_OPAQUE: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_A8P8: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_A8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_AI44: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_AYUV: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_B4G4R4A4_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_SAMPLE, F_DS, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_B5G5R5A1_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_SAMPLE, F_DS, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_B5G6R5_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE); + return info; + } + case DXGI_FORMAT_B8G8R8A8_UNORM: + { + static const DXGISupport info(F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_2D | F_3D | F_CUBE | F_MS); + return info; + } + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + { + static const DXGISupport info(F_MIPGEN | F_RT, F_DS, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE); + return info; + } + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE); + return info; + } + case DXGI_FORMAT_B8G8R8X8_UNORM: + { + static const DXGISupport info(0, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS); + return info; + } + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: + { + static const DXGISupport info(0, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS); + return info; + } + case DXGI_FORMAT_BC1_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC1_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC1_UNORM_SRGB: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC2_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC2_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC2_UNORM_SRGB: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC3_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC3_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC3_UNORM_SRGB: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC4_SNORM: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC4_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC4_UNORM: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC5_SNORM: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC5_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC5_UNORM: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC6H_SF16: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC6H_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC6H_UF16: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC7_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC7_UNORM: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC7_UNORM_SRGB: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_D16_UNORM: + { + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_D24_UNORM_S8_UINT: + { + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_D32_FLOAT: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_G8R8_G8B8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_IA44: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_NV11: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_NV12: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_P010: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_P016: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_P8: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R10G10B10A2_UINT: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R10G10B10A2_UNORM: + { + static const DXGISupport info(0, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: + { + static const DXGISupport info(0, F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D); + return info; + } + case DXGI_FORMAT_R11G11B10_FLOAT: + { + static const DXGISupport info(0, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT, F_DS, F_MS | F_SAMPLE); + return info; + } + case DXGI_FORMAT_R16G16B16A16_SINT: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_SNORM: + { + static const DXGISupport info(0, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R16G16B16A16_UINT: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_SINT: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R16G16_UINT: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16_FLOAT: + { + static const DXGISupport info(0, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16_SINT: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16_SNORM: + { + static const DXGISupport info(0, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R16_UINT: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R1_UNORM: + { + static const DXGISupport info(F_2D, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R24G8_TYPELESS: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_R32G32B32A32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R32G32B32A32_SINT: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32G32B32A32_UINT: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G32B32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_R32G32B32_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_SAMPLE, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_R32G32B32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32G32B32_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_SAMPLE, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_R32G32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R32G32_SINT: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32G32_UINT: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G8X24_TYPELESS: + { + static const DXGISupport info(0, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_R32_SINT: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32_UINT: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_SINT: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R8G8B8A8_UINT: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_B8G8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_R8G8_SINT: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_SNORM: + { + static const DXGISupport info(F_2D | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R8G8_UINT: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_UNORM: + { + static const DXGISupport info(0, F_DS, F_MS | F_RT | F_SAMPLE); + return info; + } + case DXGI_FORMAT_R8_SINT: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8_SNORM: + { + static const DXGISupport info(0, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R8_UINT: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_UNKNOWN: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_Y210: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_Y216: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_Y410: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_Y416: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_YUY2: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + + default: + UNREACHABLE(); + return GetDefaultSupport(); + } + // clang-format on +} + +const DXGISupport &GetDXGISupport_10_0(DXGI_FORMAT dxgiFormat) +{ + // clang-format off + switch (dxgiFormat) + { + case DXGI_FORMAT_420_OPAQUE: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_A8P8: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_A8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_AI44: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_AYUV: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_B4G4R4A4_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_SAMPLE, F_DS, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_B5G5R5A1_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_SAMPLE, F_DS, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_B5G6R5_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE); + return info; + } + case DXGI_FORMAT_B8G8R8A8_UNORM: + { + static const DXGISupport info(F_MIPGEN, F_DS, F_2D | F_3D | F_CUBE | F_MS | F_RT | F_SAMPLE); + return info; + } + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + { + static const DXGISupport info(F_MIPGEN | F_RT, F_DS, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE); + return info; + } + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE); + return info; + } + case DXGI_FORMAT_B8G8R8X8_UNORM: + { + static const DXGISupport info(0, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE); + return info; + } + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: + { + static const DXGISupport info(0, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE); + return info; + } + case DXGI_FORMAT_BC1_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC1_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC1_UNORM_SRGB: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC2_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC2_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC2_UNORM_SRGB: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC3_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC3_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC3_UNORM_SRGB: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC4_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC4_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC4_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC5_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC5_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC5_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC6H_SF16: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC6H_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC6H_UF16: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC7_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC7_UNORM: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC7_UNORM_SRGB: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_D16_UNORM: + { + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_D24_UNORM_S8_UINT: + { + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_D32_FLOAT: + { + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + { + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_G8R8_G8B8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_IA44: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_NV11: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_NV12: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_P010: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_P016: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_P8: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R10G10B10A2_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R10G10B10A2_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: + { + static const DXGISupport info(0, F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D); + return info; + } + case DXGI_FORMAT_R11G11B10_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R16G16B16A16_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R16G16_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R16_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R1_UNORM: + { + static const DXGISupport info(F_2D, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R24G8_TYPELESS: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT, F_SAMPLE); + return info; + } + case DXGI_FORMAT_R32G32B32A32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT, F_DS, F_MS | F_SAMPLE); + return info; + } + case DXGI_FORMAT_R32G32B32A32_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32G32B32A32_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G32B32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_R32G32B32_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_SAMPLE, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_R32G32B32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32G32B32_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_SAMPLE, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_R32G32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT, F_DS, F_MS | F_SAMPLE); + return info; + } + case DXGI_FORMAT_R32G32_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32G32_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G8X24_TYPELESS: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT, F_DS, F_MS | F_SAMPLE); + return info; + } + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT, F_SAMPLE); + return info; + } + case DXGI_FORMAT_R32_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R8G8B8A8_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_B8G8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_R8G8_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R8G8_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R8_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_UNKNOWN: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_Y210: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_Y216: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_Y410: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_Y416: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_YUY2: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + + default: + UNREACHABLE(); + return GetDefaultSupport(); + } + // clang-format on +} + +const DXGISupport &GetDXGISupport_10_1(DXGI_FORMAT dxgiFormat) +{ + // clang-format off + switch (dxgiFormat) + { + case DXGI_FORMAT_420_OPAQUE: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_A8P8: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_A8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_AI44: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_AYUV: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_B4G4R4A4_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_SAMPLE, F_DS, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_B5G5R5A1_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_SAMPLE, F_DS, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_B5G6R5_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE); + return info; + } + case DXGI_FORMAT_B8G8R8A8_UNORM: + { + static const DXGISupport info(F_MIPGEN, F_DS, F_2D | F_3D | F_CUBE | F_MS | F_RT | F_SAMPLE); + return info; + } + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + { + static const DXGISupport info(F_MIPGEN | F_RT, F_DS, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE); + return info; + } + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE); + return info; + } + case DXGI_FORMAT_B8G8R8X8_UNORM: + { + static const DXGISupport info(0, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE); + return info; + } + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: + { + static const DXGISupport info(0, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE); + return info; + } + case DXGI_FORMAT_BC1_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC1_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC1_UNORM_SRGB: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC2_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC2_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC2_UNORM_SRGB: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC3_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC3_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC3_UNORM_SRGB: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC4_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC4_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC4_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC5_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC5_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC5_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC6H_SF16: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC6H_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC6H_UF16: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC7_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC7_UNORM: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC7_UNORM_SRGB: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_D16_UNORM: + { + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_D24_UNORM_S8_UINT: + { + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_D32_FLOAT: + { + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + { + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_G8R8_G8B8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_IA44: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_NV11: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_NV12: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_P010: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_P016: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_P8: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R10G10B10A2_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R10G10B10A2_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: + { + static const DXGISupport info(0, F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D); + return info; + } + case DXGI_FORMAT_R11G11B10_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R16G16B16A16_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R16G16_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R16_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R1_UNORM: + { + static const DXGISupport info(F_2D, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R24G8_TYPELESS: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + { + static const DXGISupport info(F_2D | F_CUBE | F_SAMPLE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_R32G32B32A32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R32G32B32A32_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32G32B32A32_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G32B32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_R32G32B32_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_SAMPLE, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_R32G32B32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32G32B32_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_SAMPLE, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_R32G32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R32G32_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32G32_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G8X24_TYPELESS: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + { + static const DXGISupport info(F_2D | F_CUBE | F_SAMPLE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_R32_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R8G8B8A8_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_B8G8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_R8G8_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R8G8_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R8_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_UNKNOWN: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_Y210: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_Y216: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_Y410: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_Y416: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_YUY2: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + + default: + UNREACHABLE(); + return GetDefaultSupport(); + } + // clang-format on +} + +const DXGISupport &GetDXGISupport_11_0(DXGI_FORMAT dxgiFormat) +{ + // clang-format off + switch (dxgiFormat) + { + case DXGI_FORMAT_420_OPAQUE: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_A8P8: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_A8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_AI44: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_AYUV: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_B4G4R4A4_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_SAMPLE, F_DS, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_B5G5R5A1_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_SAMPLE, F_DS, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_B5G6R5_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE); + return info; + } + case DXGI_FORMAT_B8G8R8A8_UNORM: + { + static const DXGISupport info(F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_2D | F_3D | F_CUBE | F_MS); + return info; + } + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + { + static const DXGISupport info(F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_2D | F_3D | F_CUBE | F_MS); + return info; + } + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE); + return info; + } + case DXGI_FORMAT_B8G8R8X8_UNORM: + { + static const DXGISupport info(F_RT | F_SAMPLE, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS); + return info; + } + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: + { + static const DXGISupport info(F_RT | F_SAMPLE, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS); + return info; + } + case DXGI_FORMAT_BC1_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC1_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC1_UNORM_SRGB: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC2_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC2_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC2_UNORM_SRGB: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC3_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC3_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC3_UNORM_SRGB: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC4_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC4_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC4_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC5_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC5_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC5_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC6H_SF16: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC6H_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC6H_UF16: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC7_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC7_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC7_UNORM_SRGB: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_D16_UNORM: + { + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_D24_UNORM_S8_UINT: + { + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_D32_FLOAT: + { + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + { + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_G8R8_G8B8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_IA44: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_NV11: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_NV12: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_P010: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_P016: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_P8: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R10G10B10A2_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R10G10B10A2_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: + { + static const DXGISupport info(0, F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D); + return info; + } + case DXGI_FORMAT_R11G11B10_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R16G16B16A16_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R16G16_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R16_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R1_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R24G8_TYPELESS: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + { + static const DXGISupport info(F_2D | F_CUBE | F_SAMPLE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_R32G32B32A32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R32G32B32A32_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32G32B32A32_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G32B32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_R32G32B32_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_SAMPLE, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_R32G32B32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32G32B32_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_SAMPLE, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_R32G32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R32G32_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32G32_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G8X24_TYPELESS: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + { + static const DXGISupport info(F_2D | F_CUBE | F_SAMPLE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_R32_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R8G8B8A8_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_B8G8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_R8G8_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R8G8_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R8_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_UNKNOWN: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_Y210: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_Y216: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_Y410: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_Y416: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_YUY2: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + + default: + UNREACHABLE(); + return GetDefaultSupport(); + } + // clang-format on +} + +const DXGISupport &GetDXGISupport_11_1(DXGI_FORMAT dxgiFormat) +{ + // clang-format off + switch (dxgiFormat) + { + case DXGI_FORMAT_420_OPAQUE: + { + static const DXGISupport info(F_2D, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_A8P8: + { + static const DXGISupport info(F_2D, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_A8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_AI44: + { + static const DXGISupport info(F_2D, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_AYUV: + { + static const DXGISupport info(F_2D | F_RT | F_SAMPLE, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_B4G4R4A4_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_SAMPLE, F_DS, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_B5G5R5A1_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_SAMPLE, F_DS, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_B5G6R5_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE); + return info; + } + case DXGI_FORMAT_B8G8R8A8_UNORM: + { + static const DXGISupport info(F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_2D | F_3D | F_CUBE | F_MS); + return info; + } + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + { + static const DXGISupport info(F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_2D | F_3D | F_CUBE | F_MS); + return info; + } + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE); + return info; + } + case DXGI_FORMAT_B8G8R8X8_UNORM: + { + static const DXGISupport info(F_RT | F_SAMPLE, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS); + return info; + } + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: + { + static const DXGISupport info(F_RT | F_SAMPLE, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS); + return info; + } + case DXGI_FORMAT_BC1_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC1_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC1_UNORM_SRGB: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC2_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC2_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC2_UNORM_SRGB: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC3_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC3_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC3_UNORM_SRGB: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC4_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC4_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC4_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC5_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC5_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC5_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC6H_SF16: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC6H_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC6H_UF16: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC7_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC7_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC7_UNORM_SRGB: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_D16_UNORM: + { + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_D24_UNORM_S8_UINT: + { + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_D32_FLOAT: + { + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + { + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_G8R8_G8B8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_IA44: + { + static const DXGISupport info(F_2D, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_NV11: + { + static const DXGISupport info(F_2D | F_RT | F_SAMPLE, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_NV12: + { + static const DXGISupport info(F_2D | F_RT | F_SAMPLE, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_P010: + { + static const DXGISupport info(F_2D | F_RT | F_SAMPLE, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_P016: + { + static const DXGISupport info(F_2D | F_RT | F_SAMPLE, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_P8: + { + static const DXGISupport info(F_2D, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R10G10B10A2_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R10G10B10A2_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: + { + static const DXGISupport info(0, F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D); + return info; + } + case DXGI_FORMAT_R11G11B10_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R16G16B16A16_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R16G16_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R16_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R1_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R24G8_TYPELESS: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + { + static const DXGISupport info(F_2D | F_CUBE | F_SAMPLE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_R32G32B32A32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R32G32B32A32_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32G32B32A32_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G32B32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_R32G32B32_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_SAMPLE, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_R32G32B32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32G32B32_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_SAMPLE, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_R32G32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R32G32_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32G32_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G8X24_TYPELESS: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + { + static const DXGISupport info(F_2D | F_CUBE | F_SAMPLE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_R32_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R8G8B8A8_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_B8G8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_R8G8_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R8G8_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R8_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_UNKNOWN: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_Y210: + { + static const DXGISupport info(F_2D | F_SAMPLE, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_Y216: + { + static const DXGISupport info(F_2D | F_SAMPLE, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_Y410: + { + static const DXGISupport info(F_2D | F_SAMPLE, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_Y416: + { + static const DXGISupport info(F_2D | F_SAMPLE, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_YUY2: + { + static const DXGISupport info(F_2D | F_SAMPLE, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + + default: + UNREACHABLE(); + return GetDefaultSupport(); + } + // clang-format on +} + +} // namespace + +#undef F_2D +#undef F_3D +#undef F_CUBE +#undef F_SAMPLE +#undef F_RT +#undef F_MS +#undef F_DS +#undef F_MIPGEN + +const DXGISupport &GetDXGISupport(DXGI_FORMAT dxgiFormat, D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_9_3: + return GetDXGISupport_9_3(dxgiFormat); + case D3D_FEATURE_LEVEL_10_0: + return GetDXGISupport_10_0(dxgiFormat); + case D3D_FEATURE_LEVEL_10_1: + return GetDXGISupport_10_1(dxgiFormat); + case D3D_FEATURE_LEVEL_11_0: + return GetDXGISupport_11_0(dxgiFormat); + case D3D_FEATURE_LEVEL_11_1: + return GetDXGISupport_11_1(dxgiFormat); + default: + return GetDefaultSupport(); + } +} + +} // namespace d3d11 + +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/gl/functionsgl_enums.h b/gfx/angle/checkout/src/libANGLE/renderer/gl/functionsgl_enums.h new file mode 100644 index 0000000000..667436e915 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/gl/functionsgl_enums.h @@ -0,0 +1,1376 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// functionsgl_enums.h: OpenGL enums for versions 1.0 through 4.5. + +#ifndef LIBANGLE_RENDERER_GL_FUNCTIONSGLENUMS_H_ +#define LIBANGLE_RENDERER_GL_FUNCTIONSGLENUMS_H_ + +// 1.0 +#define GL_ALPHA 0x1906 +#define GL_ALWAYS 0x0207 +#define GL_AND 0x1501 +#define GL_AND_INVERTED 0x1504 +#define GL_AND_REVERSE 0x1502 +#define GL_BACK 0x0405 +#define GL_BACK_LEFT 0x0402 +#define GL_BACK_RIGHT 0x0403 +#define GL_BLEND 0x0BE2 +#define GL_BLEND_DST 0x0BE0 +#define GL_BLEND_SRC 0x0BE1 +#define GL_BLUE 0x1905 +#define GL_BYTE 0x1400 +#define GL_CCW 0x0901 +#define GL_CLEAR 0x1500 +#define GL_COLOR 0x1800 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_LOGIC_OP 0x0BF2 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_COPY 0x1503 +#define GL_COPY_INVERTED 0x150C +#define GL_CULL_FACE 0x0B44 +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_CW 0x0900 +#define GL_DECR 0x1E03 +#define GL_DEPTH 0x1801 +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_TEST 0x0B71 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DITHER 0x0BD0 +#define GL_DONT_CARE 0x1100 +#define GL_DOUBLE 0x140A +#define GL_DOUBLEBUFFER 0x0C32 +#define GL_DRAW_BUFFER 0x0C01 +#define GL_DST_ALPHA 0x0304 +#define GL_DST_COLOR 0x0306 +#define GL_EQUAL 0x0202 +#define GL_EQUIV 0x1509 +#define GL_EXTENSIONS 0x1F03 +#define GL_FALSE 0 +#define GL_FASTEST 0x1101 +#define GL_FILL 0x1B02 +#define GL_FLOAT 0x1406 +#define GL_FRONT 0x0404 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_FRONT_FACE 0x0B46 +#define GL_FRONT_LEFT 0x0400 +#define GL_FRONT_RIGHT 0x0401 +#define GL_GEQUAL 0x0206 +#define GL_GREATER 0x0204 +#define GL_GREEN 0x1904 +#define GL_INCR 0x1E02 +#define GL_INT 0x1404 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_OPERATION 0x0502 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVERT 0x150A +#define GL_KEEP 0x1E00 +#define GL_LEFT 0x0406 +#define GL_LEQUAL 0x0203 +#define GL_LESS 0x0201 +#define GL_LINE 0x1B01 +#define GL_LINEAR 0x2601 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_SMOOTH 0x0B20 +#define GL_LINE_SMOOTH_HINT 0x0C52 +#define GL_LINE_STRIP 0x0003 +#define GL_LINE_WIDTH 0x0B21 +#define GL_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_LINE_WIDTH_RANGE 0x0B22 +#define GL_LOGIC_OP_MODE 0x0BF0 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_NAND 0x150E +#define GL_NEAREST 0x2600 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_NEVER 0x0200 +#define GL_NICEST 0x1102 +#define GL_NONE 0 +#define GL_NOOP 0x1505 +#define GL_NOR 0x1508 +#define GL_NOTEQUAL 0x0205 +#define GL_NO_ERROR 0 +#define GL_ONE 1 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_OR 0x1507 +#define GL_OR_INVERTED 0x150D +#define GL_OR_REVERSE 0x150B +#define GL_OUT_OF_MEMORY 0x0505 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_PACK_LSB_FIRST 0x0D01 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PACK_SWAP_BYTES 0x0D00 +#define GL_POINT 0x1B00 +#define GL_POINTS 0x0000 +#define GL_POINT_SIZE 0x0B11 +#define GL_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_POINT_SIZE_RANGE 0x0B12 +#define GL_POLYGON_MODE 0x0B40 +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_POLYGON_OFFSET_LINE 0x2A02 +#define GL_POLYGON_OFFSET_POINT 0x2A01 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_SMOOTH 0x0B41 +#define GL_POLYGON_SMOOTH_HINT 0x0C53 +#define GL_PROXY_TEXTURE_1D 0x8063 +#define GL_PROXY_TEXTURE_2D 0x8064 +#define GL_QUADS 0x0007 +#define GL_R3_G3_B2 0x2A10 +#define GL_READ_BUFFER 0x0C02 +#define GL_RED 0x1903 +#define GL_RENDERER 0x1F01 +#define GL_REPEAT 0x2901 +#define GL_REPLACE 0x1E01 +#define GL_RGB 0x1907 +#define GL_RGB10 0x8052 +#define GL_RGB10_A2 0x8059 +#define GL_RGB12 0x8053 +#define GL_RGB16 0x8054 +#define GL_RGB4 0x804F +#define GL_RGB5 0x8050 +#define GL_RGB5_A1 0x8057 +#define GL_RGB8 0x8051 +#define GL_RGBA 0x1908 +#define GL_RGBA12 0x805A +#define GL_RGBA16 0x805B +#define GL_RGBA2 0x8055 +#define GL_RGBA4 0x8056 +#define GL_RGBA8 0x8058 +#define GL_RIGHT 0x0407 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_SET 0x150F +#define GL_SHORT 0x1402 +#define GL_SRC_ALPHA 0x0302 +#define GL_SRC_ALPHA_SATURATE 0x0308 +#define GL_SRC_COLOR 0x0300 +#define GL_STENCIL 0x1802 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_INDEX 0x1901 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_TEST 0x0B90 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_STEREO 0x0C33 +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_TEXTURE 0x1702 +#define GL_TEXTURE_1D 0x0DE0 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_TEXTURE_ALPHA_SIZE 0x805F +#define GL_TEXTURE_BINDING_1D 0x8068 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_TEXTURE_BLUE_SIZE 0x805E +#define GL_TEXTURE_BORDER_COLOR 0x1004 +#define GL_TEXTURE_GREEN_SIZE 0x805D +#define GL_TEXTURE_HEIGHT 0x1001 +#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_RED_SIZE 0x805C +#define GL_TEXTURE_WIDTH 0x1000 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_FAN 0x0006 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRUE 1 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_UNPACK_LSB_FIRST 0x0CF1 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SWAP_BYTES 0x0CF0 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_UNSIGNED_INT 0x1405 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_VENDOR 0x1F00 +#define GL_VERSION 0x1F02 +#define GL_VIEWPORT 0x0BA2 +#define GL_XOR 0x1506 +#define GL_ZERO 0 + +// 1.2 +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_TEXTURE_3D 0x806F +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 + +// 1.2 Extensions +#define GL_ALL_COMPLETED_NV 0x84F2 +#define GL_FENCE_STATUS_NV 0x84F3 +#define GL_FENCE_CONDITION_NV 0x84F4 + +// 1.3 +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_CLAMP_TO_BORDER 0x812D +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_MULTISAMPLE 0x809D +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 + +// 1.5 +#define GL_BLEND_COLOR 0x8005 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_EQUATION 0x8009 +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_CONSTANT_COLOR 0x8001 +#define GL_DECR_WRAP 0x8508 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_DEPTH_COMPONENT32 0x81A7 +#define GL_FUNC_ADD 0x8006 +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_FUNC_SUBTRACT 0x800A +#define GL_INCR_WRAP 0x8507 +#define GL_MAX 0x8008 +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_MIN 0x8007 +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_TEXTURE_LOD_BIAS 0x8501 + +// 1.5 +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_BUFFER_ACCESS 0x88BB +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_CURRENT_QUERY 0x8865 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_QUERY_COUNTER_BITS 0x8864 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_READ_ONLY 0x88B8 +#define GL_READ_WRITE 0x88BA +#define GL_SAMPLES_PASSED 0x8914 +#define GL_SRC1_ALPHA 0x8589 +#define GL_STATIC_COPY 0x88E6 +#define GL_STATIC_DRAW 0x88E4 +#define GL_STATIC_READ 0x88E5 +#define GL_STREAM_COPY 0x88E2 +#define GL_STREAM_DRAW 0x88E0 +#define GL_STREAM_READ 0x88E1 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_WRITE_ONLY 0x88B9 + +// 2.0 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_BLEND_EQUATION_RGB 0x8009 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_DELETE_STATUS 0x8B80 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_LINK_STATUS 0x8B82 +#define GL_LOWER_LEFT 0x8CA1 +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_MAX_VARYING_FLOATS 0x8B4B +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_POINT_SPRITE 0x8861 +#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 +#define GL_SAMPLER_1D 0x8B5D +#define GL_SAMPLER_1D_SHADOW 0x8B61 +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_SHADER_TYPE 0x8B4F +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#define GL_UPPER_LEFT 0x8CA2 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 +#define GL_VERTEX_SHADER 0x8B31 + +// 2.1 +#define GL_COMPRESSED_SRGB 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#define GL_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_SRGB_ALPHA 0x8C42 + +// 3.0 +#define GL_BGRA_INTEGER 0x8D9B +#define GL_BGR_INTEGER 0x8D9A +#define GL_BLUE_INTEGER 0x8D96 +#define GL_BUFFER_ACCESS_FLAGS 0x911F +#define GL_BUFFER_MAP_LENGTH 0x9120 +#define GL_BUFFER_MAP_OFFSET 0x9121 +#define GL_CLAMP_READ_COLOR 0x891C +#define GL_CLIP_DISTANCE0 0x3000 +#define GL_CLIP_DISTANCE1 0x3001 +#define GL_CLIP_DISTANCE2 0x3002 +#define GL_CLIP_DISTANCE3 0x3003 +#define GL_CLIP_DISTANCE4 0x3004 +#define GL_CLIP_DISTANCE5 0x3005 +#define GL_CLIP_DISTANCE6 0x3006 +#define GL_CLIP_DISTANCE7 0x3007 +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT10 0x8CEA +#define GL_COLOR_ATTACHMENT11 0x8CEB +#define GL_COLOR_ATTACHMENT12 0x8CEC +#define GL_COLOR_ATTACHMENT13 0x8CED +#define GL_COLOR_ATTACHMENT14 0x8CEE +#define GL_COLOR_ATTACHMENT15 0x8CEF +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#define GL_COLOR_ATTACHMENT8 0x8CE8 +#define GL_COLOR_ATTACHMENT9 0x8CE9 +#define GL_COMPARE_REF_TO_TEXTURE 0x884E +#define GL_COMPRESSED_RED 0x8225 +#define GL_COMPRESSED_RED_RGTC1 0x8DBB +#define GL_COMPRESSED_RG 0x8226 +#define GL_COMPRESSED_RG_RGTC2 0x8DBD +#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC +#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE +#define GL_CONTEXT_FLAGS 0x821E +#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001 +#define GL_DEPTH24_STENCIL8 0x88F0 +#define GL_DEPTH32F_STENCIL8 0x8CAD +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH_STENCIL 0x84F9 +#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_FIXED_ONLY 0x891D +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD +#define GL_FRAMEBUFFER 0x8D40 +#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 +#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 +#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 +#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_DEFAULT 0x8218 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC +#define GL_FRAMEBUFFER_SRGB 0x8DB9 +#define GL_FRAMEBUFFER_UNDEFINED 0x8219 +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_GREEN_INTEGER 0x8D95 +#define GL_HALF_FLOAT 0x140B +#define GL_INTERLEAVED_ATTRIBS 0x8C8C +#define GL_INT_SAMPLER_1D 0x8DC9 +#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE +#define GL_INT_SAMPLER_2D 0x8DCA +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_CUBE 0x8DCC +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 +#define GL_MAJOR_VERSION 0x821B +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF +#define GL_MAX_CLIP_DISTANCES 0x0D32 +#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF +#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_MAX_SAMPLES 0x8D57 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 +#define GL_MAX_VARYING_COMPONENTS 0x8B4B +#define GL_MINOR_VERSION 0x821C +#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 +#define GL_NUM_EXTENSIONS 0x821D +#define GL_PRIMITIVES_GENERATED 0x8C87 +#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 +#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B +#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 +#define GL_QUERY_BY_REGION_WAIT 0x8E15 +#define GL_QUERY_NO_WAIT 0x8E14 +#define GL_QUERY_WAIT 0x8E13 +#define GL_R11F_G11F_B10F 0x8C3A +#define GL_R16 0x822A +#define GL_R16F 0x822D +#define GL_R16I 0x8233 +#define GL_R16UI 0x8234 +#define GL_R32F 0x822E +#define GL_R32I 0x8235 +#define GL_R32UI 0x8236 +#define GL_R8 0x8229 +#define GL_R8I 0x8231 +#define GL_R8UI 0x8232 +#define GL_RASTERIZER_DISCARD 0x8C89 +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA +#define GL_RED_INTEGER 0x8D94 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_SAMPLES 0x8CAB +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RG 0x8227 +#define GL_RG16 0x822C +#define GL_RG16F 0x822F +#define GL_RG16I 0x8239 +#define GL_RG16UI 0x823A +#define GL_RG32F 0x8230 +#define GL_RG32I 0x823B +#define GL_RG32UI 0x823C +#define GL_RG8 0x822B +#define GL_RG8I 0x8237 +#define GL_RG8UI 0x8238 +#define GL_RGB16F 0x881B +#define GL_RGB16I 0x8D89 +#define GL_RGB16UI 0x8D77 +#define GL_RGB32F 0x8815 +#define GL_RGB32I 0x8D83 +#define GL_RGB32UI 0x8D71 +#define GL_RGB8I 0x8D8F +#define GL_RGB8UI 0x8D7D +#define GL_RGB9_E5 0x8C3D +#define GL_RGBA16F 0x881A +#define GL_RGBA16I 0x8D88 +#define GL_RGBA16UI 0x8D76 +#define GL_RGBA32F 0x8814 +#define GL_RGBA32I 0x8D82 +#define GL_RGBA32UI 0x8D70 +#define GL_RGBA8I 0x8D8E +#define GL_RGBA8UI 0x8D7C +#define GL_RGBA_INTEGER 0x8D99 +#define GL_RGB_INTEGER 0x8D98 +#define GL_RG_INTEGER 0x8228 +#define GL_SAMPLER_1D_ARRAY 0x8DC0 +#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#define GL_SEPARATE_ATTRIBS 0x8C8D +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_STENCIL_INDEX1 0x8D46 +#define GL_STENCIL_INDEX16 0x8D49 +#define GL_STENCIL_INDEX4 0x8D47 +#define GL_STENCIL_INDEX8 0x8D48 +#define GL_TEXTURE_1D_ARRAY 0x8C18 +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_TEXTURE_ALPHA_TYPE 0x8C13 +#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C +#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_TEXTURE_BLUE_TYPE 0x8C12 +#define GL_TEXTURE_DEPTH_TYPE 0x8C16 +#define GL_TEXTURE_GREEN_TYPE 0x8C11 +#define GL_TEXTURE_RED_TYPE 0x8C10 +#define GL_TEXTURE_SHARED_SIZE 0x8C3F +#define GL_TEXTURE_STENCIL_SIZE 0x88F1 +#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 +#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B +#define GL_UNSIGNED_INT_24_8 0x84FA +#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E +#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 +#define GL_UNSIGNED_INT_VEC2 0x8DC6 +#define GL_UNSIGNED_INT_VEC3 0x8DC7 +#define GL_UNSIGNED_INT_VEC4 0x8DC8 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_VERTEX_ARRAY_BINDING 0x85B5 +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD + +// 3.1 +#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 +#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 +#define GL_COPY_READ_BUFFER 0x8F36 +#define GL_COPY_WRITE_BUFFER 0x8F37 +#define GL_INT_SAMPLER_2D_RECT 0x8DCD +#define GL_INT_SAMPLER_BUFFER 0x8DD0 +#define GL_INVALID_INDEX 0xFFFFFFFFu +#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 +#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E +#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 +#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D +#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 +#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B +#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 +#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F +#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B +#define GL_PRIMITIVE_RESTART 0x8F9D +#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E +#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 +#define GL_R16_SNORM 0x8F98 +#define GL_R8_SNORM 0x8F94 +#define GL_RG16_SNORM 0x8F99 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB16_SNORM 0x8F9A +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGBA16_SNORM 0x8F9B +#define GL_RGBA8_SNORM 0x8F97 +#define GL_SAMPLER_2D_RECT 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 +#define GL_SAMPLER_BUFFER 0x8DC2 +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_TEXTURE_BINDING_BUFFER 0x8C2C +#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 +#define GL_TEXTURE_BUFFER 0x8C2A +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D +#define GL_TEXTURE_RECTANGLE 0x84F5 +#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 +#define GL_UNIFORM_BLOCK_BINDING 0x8A3F +#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 +#define GL_UNIFORM_BLOCK_INDEX 0x8A3A +#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 +#define GL_UNIFORM_BUFFER 0x8A11 +#define GL_UNIFORM_BUFFER_BINDING 0x8A28 +#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 +#define GL_UNIFORM_BUFFER_SIZE 0x8A2A +#define GL_UNIFORM_BUFFER_START 0x8A29 +#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E +#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D +#define GL_UNIFORM_NAME_LENGTH 0x8A39 +#define GL_UNIFORM_OFFSET 0x8A3B +#define GL_UNIFORM_SIZE 0x8A38 +#define GL_UNIFORM_TYPE 0x8A37 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 + +// 3.2 +#define GL_ALREADY_SIGNALED 0x911A +#define GL_CONDITION_SATISFIED 0x911C +#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 +#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 +#define GL_CONTEXT_PROFILE_MASK 0x9126 +#define GL_DEPTH_CLAMP 0x864F +#define GL_FIRST_VERTEX_CONVENTION 0x8E4D +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 +#define GL_GEOMETRY_INPUT_TYPE 0x8917 +#define GL_GEOMETRY_OUTPUT_TYPE 0x8918 +#define GL_GEOMETRY_SHADER 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT 0x8916 +#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 +#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C +#define GL_LAST_VERTEX_CONVENTION 0x8E4E +#define GL_LINES_ADJACENCY 0x000A +#define GL_LINE_STRIP_ADJACENCY 0x000B +#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E +#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F +#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 +#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 +#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF +#define GL_MAX_INTEGER_SAMPLES 0x9110 +#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 +#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 +#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 +#define GL_OBJECT_TYPE 0x9112 +#define GL_PROGRAM_POINT_SIZE 0x8642 +#define GL_PROVOKING_VERTEX 0x8E4F +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 +#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C +#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 +#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B +#define GL_SAMPLE_MASK 0x8E51 +#define GL_SAMPLE_MASK_VALUE 0x8E52 +#define GL_SAMPLE_POSITION 0x8E50 +#define GL_SIGNALED 0x9119 +#define GL_SYNC_CONDITION 0x9113 +#define GL_SYNC_FENCE 0x9116 +#define GL_SYNC_FLAGS 0x9115 +#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 +#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 +#define GL_SYNC_STATUS 0x9114 +#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 +#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F +#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 +#define GL_TEXTURE_SAMPLES 0x9106 +#define GL_TIMEOUT_EXPIRED 0x911B +#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull +#define GL_TRIANGLES_ADJACENCY 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D +#define GL_UNSIGNALED 0x9118 +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D +#define GL_WAIT_FAILED 0x911D + +// 3.3 +#define GL_ANY_SAMPLES_PASSED 0x8C2F +#define GL_INT_2_10_10_10_REV 0x8D9F +#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC +#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB +#define GL_ONE_MINUS_SRC1_COLOR 0x88FA +#define GL_RGB10_A2UI 0x906F +#define GL_SAMPLER_BINDING 0x8919 +#define GL_SRC1_COLOR 0x88F9 +#define GL_TEXTURE_SWIZZLE_A 0x8E45 +#define GL_TEXTURE_SWIZZLE_B 0x8E44 +#define GL_TEXTURE_SWIZZLE_G 0x8E43 +#define GL_TEXTURE_SWIZZLE_R 0x8E42 +#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 +#define GL_TIMESTAMP 0x8E28 +#define GL_TIME_ELAPSED 0x88BF +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE + +// 4.0 +#define GL_ACTIVE_SUBROUTINES 0x8DE5 +#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48 +#define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49 +#define GL_COMPATIBLE_SUBROUTINES 0x8E4B +#define GL_DOUBLE_MAT2 0x8F46 +#define GL_DOUBLE_MAT2x3 0x8F49 +#define GL_DOUBLE_MAT2x4 0x8F4A +#define GL_DOUBLE_MAT3 0x8F47 +#define GL_DOUBLE_MAT3x2 0x8F4B +#define GL_DOUBLE_MAT3x4 0x8F4C +#define GL_DOUBLE_MAT4 0x8F48 +#define GL_DOUBLE_MAT4x2 0x8F4D +#define GL_DOUBLE_MAT4x3 0x8F4E +#define GL_DOUBLE_VEC2 0x8FFC +#define GL_DOUBLE_VEC3 0x8FFD +#define GL_DOUBLE_VEC4 0x8FFE +#define GL_DRAW_INDIRECT_BUFFER 0x8F3F +#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43 +#define GL_FRACTIONAL_EVEN 0x8E7C +#define GL_FRACTIONAL_ODD 0x8E7B +#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D +#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E +#define GL_ISOLINES 0x8E7A +#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E +#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F +#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C +#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A +#define GL_MAX_PATCH_VERTICES 0x8E7D +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F +#define GL_MAX_SUBROUTINES 0x8DE7 +#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8 +#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C +#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83 +#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81 +#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85 +#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89 +#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F +#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D +#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86 +#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82 +#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A +#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80 +#define GL_MAX_TESS_GEN_LEVEL 0x8E7E +#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84 +#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70 +#define GL_MAX_VERTEX_STREAMS 0x8E71 +#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E +#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37 +#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A +#define GL_PATCHES 0x000E +#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73 +#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74 +#define GL_PATCH_VERTICES 0x8E72 +#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B +#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D +#define GL_SAMPLE_SHADING 0x8C36 +#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75 +#define GL_TESS_CONTROL_SHADER 0x8E88 +#define GL_TESS_EVALUATION_SHADER 0x8E87 +#define GL_TESS_GEN_MODE 0x8E76 +#define GL_TESS_GEN_POINT_MODE 0x8E79 +#define GL_TESS_GEN_SPACING 0x8E77 +#define GL_TESS_GEN_VERTEX_ORDER 0x8E78 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A +#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 +#define GL_TRANSFORM_FEEDBACK 0x8E22 +#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 +#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1 +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F + +// 4.1 +#define GL_ACTIVE_PROGRAM 0x8259 +#define GL_ALL_SHADER_BITS 0xFFFFFFFF +#define GL_FIXED 0x140C +#define GL_FRAGMENT_SHADER_BIT 0x00000002 +#define GL_GEOMETRY_SHADER_BIT 0x00000004 +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_HIGH_INT 0x8DF5 +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_LAYER_PROVOKING_VERTEX 0x825E +#define GL_LOW_FLOAT 0x8DF0 +#define GL_LOW_INT 0x8DF3 +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VIEWPORTS 0x825B +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 +#define GL_PROGRAM_BINARY_FORMATS 0x87FF +#define GL_PROGRAM_BINARY_LENGTH 0x8741 +#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 +#define GL_PROGRAM_PIPELINE_BINDING 0x825A +#define GL_PROGRAM_SEPARABLE 0x8258 +#define GL_RGB565 0x8D62 +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_SHADER_COMPILER 0x8DFA +#define GL_TESS_CONTROL_SHADER_BIT 0x00000008 +#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010 +#define GL_UNDEFINED_VERTEX 0x8260 +#define GL_VERTEX_SHADER_BIT 0x00000001 +#define GL_VIEWPORT_BOUNDS_RANGE 0x825D +#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F +#define GL_VIEWPORT_SUBPIXEL_BITS 0x825C + +// 4.2 +#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9 +#define GL_ALL_BARRIER_BITS 0xFFFFFFFF +#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 +#define GL_ATOMIC_COUNTER_BUFFER 0x92C0 +#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5 +#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6 +#define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1 +#define GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7 +#define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3 +#define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2 +#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 +#define GL_COMMAND_BARRIER_BIT 0x00000040 +#define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D +#define GL_COPY_READ_BUFFER_BINDING 0x8F36 +#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 +#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 +#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 +#define GL_IMAGE_1D 0x904C +#define GL_IMAGE_1D_ARRAY 0x9052 +#define GL_IMAGE_2D 0x904D +#define GL_IMAGE_2D_ARRAY 0x9053 +#define GL_IMAGE_2D_MULTISAMPLE 0x9055 +#define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056 +#define GL_IMAGE_2D_RECT 0x904F +#define GL_IMAGE_3D 0x904E +#define GL_IMAGE_BINDING_ACCESS 0x8F3E +#define GL_IMAGE_BINDING_FORMAT 0x906E +#define GL_IMAGE_BINDING_LAYER 0x8F3D +#define GL_IMAGE_BINDING_LAYERED 0x8F3C +#define GL_IMAGE_BINDING_LEVEL 0x8F3B +#define GL_IMAGE_BINDING_NAME 0x8F3A +#define GL_IMAGE_BUFFER 0x9051 +#define GL_IMAGE_CUBE 0x9050 +#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054 +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9 +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8 +#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7 +#define GL_INT_IMAGE_1D 0x9057 +#define GL_INT_IMAGE_1D_ARRAY 0x905D +#define GL_INT_IMAGE_2D 0x9058 +#define GL_INT_IMAGE_2D_ARRAY 0x905E +#define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060 +#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061 +#define GL_INT_IMAGE_2D_RECT 0x905A +#define GL_INT_IMAGE_3D 0x9059 +#define GL_INT_IMAGE_BUFFER 0x905C +#define GL_INT_IMAGE_CUBE 0x905B +#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F +#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC +#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8 +#define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7 +#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1 +#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF +#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39 +#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6 +#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0 +#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE +#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS 0x92D5 +#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF +#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS 0x90CD +#define GL_MAX_IMAGE_SAMPLES 0x906D +#define GL_MAX_IMAGE_UNITS 0x8F38 +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3 +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD +#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4 +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE +#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC +#define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2 +#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC +#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA +#define GL_MIN_MAP_BUFFER_ALIGNMENT 0x90BC +#define GL_NUM_SAMPLE_COUNTS 0x9380 +#define GL_PACK_COMPRESSED_BLOCK_DEPTH 0x912D +#define GL_PACK_COMPRESSED_BLOCK_HEIGHT 0x912C +#define GL_PACK_COMPRESSED_BLOCK_SIZE 0x912E +#define GL_PACK_COMPRESSED_BLOCK_WIDTH 0x912B +#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 +#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 +#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 +#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F +#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 +#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 +#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 +#define GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA +#define GL_UNIFORM_BARRIER_BIT 0x00000004 +#define GL_UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129 +#define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128 +#define GL_UNPACK_COMPRESSED_BLOCK_SIZE 0x912A +#define GL_UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127 +#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB +#define GL_UNSIGNED_INT_IMAGE_1D 0x9062 +#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068 +#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 +#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069 +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C +#define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065 +#define GL_UNSIGNED_INT_IMAGE_3D 0x9064 +#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067 +#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066 +#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A +#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 + +// 4.3 +#define GL_ACTIVE_RESOURCES 0x92F5 +#define GL_ACTIVE_VARIABLES 0x9305 +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A +#define GL_ARRAY_SIZE 0x92FB +#define GL_ARRAY_STRIDE 0x92FE +#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED +#define GL_AUTO_GENERATE_MIPMAP 0x8295 +#define GL_BLOCK_INDEX 0x92FD +#define GL_BUFFER 0x82E0 +#define GL_BUFFER_BINDING 0x9302 +#define GL_BUFFER_DATA_SIZE 0x9303 +#define GL_BUFFER_VARIABLE 0x92E5 +#define GL_CAVEAT_SUPPORT 0x82B8 +#define GL_CLEAR_BUFFER 0x82B4 +#define GL_COLOR_COMPONENTS 0x8283 +#define GL_COLOR_ENCODING 0x8296 +#define GL_COLOR_RENDERABLE 0x8286 +#define GL_COMPRESSED_R11_EAC 0x9270 +#define GL_COMPRESSED_RG11_EAC 0x9272 +#define GL_COMPRESSED_RGB8_ETC2 0x9274 +#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 +#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 +#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 +#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 +#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 +#define GL_COMPRESSED_SRGB8_ETC2 0x9275 +#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 +#define GL_COMPUTE_SHADER 0x91B9 +#define GL_COMPUTE_SHADER_BIT 0x00000020 +#define GL_COMPUTE_SUBROUTINE 0x92ED +#define GL_COMPUTE_SUBROUTINE_UNIFORM 0x92F3 +#define GL_COMPUTE_TEXTURE 0x82A0 +#define GL_COMPUTE_WORK_GROUP_SIZE 0x8267 +#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 +#define GL_DEBUG_CALLBACK_FUNCTION 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245 +#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D +#define GL_DEBUG_LOGGED_MESSAGES 0x9145 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243 +#define GL_DEBUG_OUTPUT 0x92E0 +#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 +#define GL_DEBUG_SEVERITY_HIGH 0x9146 +#define GL_DEBUG_SEVERITY_LOW 0x9148 +#define GL_DEBUG_SEVERITY_MEDIUM 0x9147 +#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B +#define GL_DEBUG_SOURCE_API 0x8246 +#define GL_DEBUG_SOURCE_APPLICATION 0x824A +#define GL_DEBUG_SOURCE_OTHER 0x824B +#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247 +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D +#define GL_DEBUG_TYPE_ERROR 0x824C +#define GL_DEBUG_TYPE_MARKER 0x8268 +#define GL_DEBUG_TYPE_OTHER 0x8251 +#define GL_DEBUG_TYPE_PERFORMANCE 0x8250 +#define GL_DEBUG_TYPE_POP_GROUP 0x826A +#define GL_DEBUG_TYPE_PORTABILITY 0x824F +#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269 +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E +#define GL_DEPTH_COMPONENTS 0x8284 +#define GL_DEPTH_RENDERABLE 0x8287 +#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA +#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE +#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF +#define GL_FILTER 0x829A +#define GL_FRAGMENT_SUBROUTINE 0x92EC +#define GL_FRAGMENT_SUBROUTINE_UNIFORM 0x92F2 +#define GL_FRAGMENT_TEXTURE 0x829F +#define GL_FRAMEBUFFER_BLEND 0x828B +#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314 +#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311 +#define GL_FRAMEBUFFER_DEFAULT_LAYERS 0x9312 +#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313 +#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310 +#define GL_FRAMEBUFFER_RENDERABLE 0x8289 +#define GL_FRAMEBUFFER_RENDERABLE_LAYERED 0x828A +#define GL_FULL_SUPPORT 0x82B7 +#define GL_GEOMETRY_SUBROUTINE 0x92EB +#define GL_GEOMETRY_SUBROUTINE_UNIFORM 0x92F1 +#define GL_GEOMETRY_TEXTURE 0x829E +#define GL_GET_TEXTURE_IMAGE_FORMAT 0x8291 +#define GL_GET_TEXTURE_IMAGE_TYPE 0x8292 +#define GL_IMAGE_CLASS_10_10_10_2 0x82C3 +#define GL_IMAGE_CLASS_11_11_10 0x82C2 +#define GL_IMAGE_CLASS_1_X_16 0x82BE +#define GL_IMAGE_CLASS_1_X_32 0x82BB +#define GL_IMAGE_CLASS_1_X_8 0x82C1 +#define GL_IMAGE_CLASS_2_X_16 0x82BD +#define GL_IMAGE_CLASS_2_X_32 0x82BA +#define GL_IMAGE_CLASS_2_X_8 0x82C0 +#define GL_IMAGE_CLASS_4_X_16 0x82BC +#define GL_IMAGE_CLASS_4_X_32 0x82B9 +#define GL_IMAGE_CLASS_4_X_8 0x82BF +#define GL_IMAGE_COMPATIBILITY_CLASS 0x82A8 +#define GL_IMAGE_PIXEL_FORMAT 0x82A9 +#define GL_IMAGE_PIXEL_TYPE 0x82AA +#define GL_IMAGE_TEXEL_SIZE 0x82A7 +#define GL_INTERNALFORMAT_ALPHA_SIZE 0x8274 +#define GL_INTERNALFORMAT_ALPHA_TYPE 0x827B +#define GL_INTERNALFORMAT_BLUE_SIZE 0x8273 +#define GL_INTERNALFORMAT_BLUE_TYPE 0x827A +#define GL_INTERNALFORMAT_DEPTH_SIZE 0x8275 +#define GL_INTERNALFORMAT_DEPTH_TYPE 0x827C +#define GL_INTERNALFORMAT_GREEN_SIZE 0x8272 +#define GL_INTERNALFORMAT_GREEN_TYPE 0x8279 +#define GL_INTERNALFORMAT_PREFERRED 0x8270 +#define GL_INTERNALFORMAT_RED_SIZE 0x8271 +#define GL_INTERNALFORMAT_RED_TYPE 0x8278 +#define GL_INTERNALFORMAT_SHARED_SIZE 0x8277 +#define GL_INTERNALFORMAT_STENCIL_SIZE 0x8276 +#define GL_INTERNALFORMAT_STENCIL_TYPE 0x827D +#define GL_INTERNALFORMAT_SUPPORTED 0x826F +#define GL_IS_PER_PATCH 0x92E7 +#define GL_IS_ROW_MAJOR 0x9300 +#define GL_LOCATION 0x930E +#define GL_LOCATION_INDEX 0x930F +#define GL_MANUAL_GENERATE_MIPMAP 0x8294 +#define GL_MATRIX_STRIDE 0x92FF +#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266 +#define GL_MAX_COMBINED_DIMENSIONS 0x8282 +#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39 +#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC +#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265 +#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264 +#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD +#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB +#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262 +#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC +#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB +#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263 +#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE +#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB +#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF +#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C +#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144 +#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143 +#define GL_MAX_DEPTH 0x8280 +#define GL_MAX_ELEMENT_INDEX 0x8D6B +#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA +#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316 +#define GL_MAX_FRAMEBUFFER_LAYERS 0x9317 +#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318 +#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315 +#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7 +#define GL_MAX_HEIGHT 0x827F +#define GL_MAX_LABEL_LENGTH 0x82E8 +#define GL_MAX_LAYERS 0x8281 +#define GL_MAX_NAME_LENGTH 0x92F6 +#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7 +#define GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8 +#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE +#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD +#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8 +#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9 +#define GL_MAX_UNIFORM_LOCATIONS 0x826E +#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA +#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9 +#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6 +#define GL_MAX_WIDTH 0x827E +#define GL_MIPMAP 0x8293 +#define GL_NAME_LENGTH 0x92F9 +#define GL_NUM_ACTIVE_VARIABLES 0x9304 +#define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9 +#define GL_OFFSET 0x92FC +#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 +#define GL_PROGRAM 0x82E2 +#define GL_PROGRAM_INPUT 0x92E3 +#define GL_PROGRAM_OUTPUT 0x92E4 +#define GL_PROGRAM_PIPELINE 0x82E4 +#define GL_QUERY 0x82E3 +#define GL_READ_PIXELS 0x828C +#define GL_READ_PIXELS_FORMAT 0x828D +#define GL_READ_PIXELS_TYPE 0x828E +#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B +#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A +#define GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309 +#define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307 +#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308 +#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306 +#define GL_SAMPLER 0x82E6 +#define GL_SHADER 0x82E1 +#define GL_SHADER_IMAGE_ATOMIC 0x82A6 +#define GL_SHADER_IMAGE_LOAD 0x82A4 +#define GL_SHADER_IMAGE_STORE 0x82A5 +#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000 +#define GL_SHADER_STORAGE_BLOCK 0x92E6 +#define GL_SHADER_STORAGE_BUFFER 0x90D2 +#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3 +#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF +#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5 +#define GL_SHADER_STORAGE_BUFFER_START 0x90D4 +#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST 0x82AC +#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE 0x82AE +#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST 0x82AD +#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE 0x82AF +#define GL_SRGB_READ 0x8297 +#define GL_SRGB_WRITE 0x8298 +#define GL_STENCIL_COMPONENTS 0x8285 +#define GL_STENCIL_RENDERABLE 0x8288 +#define GL_TESS_CONTROL_SUBROUTINE 0x92E9 +#define GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF +#define GL_TESS_CONTROL_TEXTURE 0x829C +#define GL_TESS_EVALUATION_SUBROUTINE 0x92EA +#define GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0 +#define GL_TESS_EVALUATION_TEXTURE 0x829D +#define GL_TEXTURE_BUFFER_OFFSET 0x919D +#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F +#define GL_TEXTURE_BUFFER_SIZE 0x919E +#define GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT 0x82B2 +#define GL_TEXTURE_COMPRESSED_BLOCK_SIZE 0x82B3 +#define GL_TEXTURE_COMPRESSED_BLOCK_WIDTH 0x82B1 +#define GL_TEXTURE_GATHER 0x82A2 +#define GL_TEXTURE_GATHER_SHADOW 0x82A3 +#define GL_TEXTURE_IMAGE_FORMAT 0x828F +#define GL_TEXTURE_IMAGE_TYPE 0x8290 +#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF +#define GL_TEXTURE_SHADOW 0x82A1 +#define GL_TEXTURE_VIEW 0x82B5 +#define GL_TEXTURE_VIEW_MIN_LAYER 0x82DD +#define GL_TEXTURE_VIEW_MIN_LEVEL 0x82DB +#define GL_TEXTURE_VIEW_NUM_LAYERS 0x82DE +#define GL_TEXTURE_VIEW_NUM_LEVELS 0x82DC +#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C +#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D +#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4 +#define GL_TYPE 0x92FA +#define GL_UNIFORM 0x92E1 +#define GL_UNIFORM_BLOCK 0x92E2 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC +#define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E +#define GL_VERTEX_ATTRIB_BINDING 0x82D4 +#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5 +#define GL_VERTEX_BINDING_BUFFER 0x8F4F +#define GL_VERTEX_BINDING_DIVISOR 0x82D6 +#define GL_VERTEX_BINDING_OFFSET 0x82D7 +#define GL_VERTEX_BINDING_STRIDE 0x82D8 +#define GL_VERTEX_SUBROUTINE 0x92E8 +#define GL_VERTEX_SUBROUTINE_UNIFORM 0x92EE +#define GL_VERTEX_TEXTURE 0x829B +#define GL_VIEW_CLASS_128_BITS 0x82C4 +#define GL_VIEW_CLASS_16_BITS 0x82CA +#define GL_VIEW_CLASS_24_BITS 0x82C9 +#define GL_VIEW_CLASS_32_BITS 0x82C8 +#define GL_VIEW_CLASS_48_BITS 0x82C7 +#define GL_VIEW_CLASS_64_BITS 0x82C6 +#define GL_VIEW_CLASS_8_BITS 0x82CB +#define GL_VIEW_CLASS_96_BITS 0x82C5 +#define GL_VIEW_CLASS_BPTC_FLOAT 0x82D3 +#define GL_VIEW_CLASS_BPTC_UNORM 0x82D2 +#define GL_VIEW_CLASS_RGTC1_RED 0x82D0 +#define GL_VIEW_CLASS_RGTC2_RG 0x82D1 +#define GL_VIEW_CLASS_S3TC_DXT1_RGB 0x82CC +#define GL_VIEW_CLASS_S3TC_DXT1_RGBA 0x82CD +#define GL_VIEW_CLASS_S3TC_DXT3_RGBA 0x82CE +#define GL_VIEW_CLASS_S3TC_DXT5_RGBA 0x82CF +#define GL_VIEW_COMPATIBILITY_CLASS 0x82B6 + +// 4.4 +#define GL_BUFFER_IMMUTABLE_STORAGE 0x821F +#define GL_BUFFER_STORAGE_FLAGS 0x8220 +#define GL_CLEAR_TEXTURE 0x9365 +#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT 0x00004000 +#define GL_CLIENT_STORAGE_BIT 0x0200 +#define GL_DYNAMIC_STORAGE_BIT 0x0100 +#define GL_LOCATION_COMPONENT 0x934A +#define GL_MAP_COHERENT_BIT 0x0080 +#define GL_MAP_PERSISTENT_BIT 0x0040 +#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5 +#define GL_MIRROR_CLAMP_TO_EDGE 0x8743 +#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221 +#define GL_QUERY_BUFFER 0x9192 +#define GL_QUERY_BUFFER_BARRIER_BIT 0x00008000 +#define GL_QUERY_BUFFER_BINDING 0x9193 +#define GL_QUERY_RESULT_NO_WAIT 0x9194 +#define GL_TEXTURE_BUFFER_BINDING 0x8C2A +#define GL_TRANSFORM_FEEDBACK_BUFFER_INDEX 0x934B +#define GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE 0x934C + +// 4.5 +#define GL_CLIP_DEPTH_MODE 0x935D +#define GL_CLIP_ORIGIN 0x935C +#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT 0x00000004 +#define GL_CONTEXT_LOST 0x0507 +#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82FB +#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82FC +#define GL_GUILTY_CONTEXT_RESET 0x8253 +#define GL_INNOCENT_CONTEXT_RESET 0x8254 +#define GL_LOSE_CONTEXT_ON_RESET 0x8252 +#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES 0x82FA +#define GL_MAX_CULL_DISTANCES 0x82F9 +#define GL_NEGATIVE_ONE_TO_ONE 0x935E +#define GL_NO_RESET_NOTIFICATION 0x8261 +#define GL_QUERY_BY_REGION_NO_WAIT_INVERTED 0x8E1A +#define GL_QUERY_BY_REGION_WAIT_INVERTED 0x8E19 +#define GL_QUERY_NO_WAIT_INVERTED 0x8E18 +#define GL_QUERY_TARGET 0x82EA +#define GL_QUERY_WAIT_INVERTED 0x8E17 +#define GL_RESET_NOTIFICATION_STRATEGY 0x8256 +#define GL_TEXTURE_TARGET 0x1006 +#define GL_UNKNOWN_CONTEXT_RESET 0x8255 +#define GL_ZERO_TO_ONE 0x935F +#define GL_COMPLETION_STATUS 0x91B1 + +#endif // LIBANGLE_RENDERER_GL_FUNCTIONSGLENUMS_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/load_functions_table.h b/gfx/angle/checkout/src/libANGLE/renderer/load_functions_table.h new file mode 100644 index 0000000000..27eaebc8e7 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/load_functions_table.h @@ -0,0 +1,20 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// load_functions_table: +// Contains load functions table depending on internal format and ANGLE format. +// + +#ifndef LIBANGLE_RENDERER_LOADFUNCTIONSTABLE_H_ +#define LIBANGLE_RENDERER_LOADFUNCTIONSTABLE_H_ + +#include "libANGLE/renderer/Format.h" + +namespace angle +{ +rx::LoadFunctionMap GetLoadFunctionsMap(GLenum internalFormat, FormatID angleFormat); +} // namespace angle + +#endif // LIBANGLE_RENDERER_LOADFUNCTIONSTABLE_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/load_functions_table_autogen.cpp b/gfx/angle/checkout/src/libANGLE/renderer/load_functions_table_autogen.cpp new file mode 100644 index 0000000000..11fe60fe0d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/load_functions_table_autogen.cpp @@ -0,0 +1,5465 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_load_functions_table.py using data from load_functions_data.json +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// load_functions_table: +// Contains the GetLoadFunctionsMap for texture_format_util.h +// + +#include "libANGLE/renderer/load_functions_table.h" + +#include "image_util/copyimage.h" +#include "image_util/generatemip.h" +#include "image_util/loadimage.h" + +using namespace rx; + +namespace angle +{ + +namespace +{ + +// ES3 image loading functions vary based on: +// - the GL internal format (supplied to glTex*Image*D) +// - the GL data type given (supplied to glTex*Image*D) +// - the target DXGI_FORMAT that the image will be loaded into (which is chosen based on the D3D +// device's capabilities) +// This map type determines which loading function to use, based on these three parameters. +// Source formats and types are taken from Tables 3.2 and 3.3 of the ES 3 spec. +void UnimplementedLoadFunction(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + UNIMPLEMENTED(); +} + +void UnreachableLoadFunction(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + UNREACHABLE(); +} + +LoadImageFunctionInfo A1RGB5_ANGLEX_to_A1R5G5B5_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadRGB5A1ToRGBA8, true); + case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo ALPHA_to_R16G16B16A16_FLOAT(GLenum type) +{ + switch (type) + { + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadA16FToRGBA16F, true); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadA16FToRGBA16F, true); + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo ALPHA_to_R32G32B32A32_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadA32FToRGBA32F, true); + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo ALPHA_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo ALPHA16F_EXT_to_R16_FLOAT(GLenum type) +{ + switch (type) + { + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadToNative, false); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo ALPHA16F_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadA16FToRGBA16F, true); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadA16FToRGBA16F, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo ALPHA32F_EXT_to_R32_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo ALPHA32F_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadA32FToRGBA32F, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo ALPHA8_EXT_to_A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo ALPHA8_EXT_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadA8ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo ALPHA8_EXT_to_R8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo BGR10_A2_ANGLEX_to_B10G10R10A2_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT_2_10_10_10_REV: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo BGR565_ANGLEX_to_B5G6R5_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadRGB8ToBGR565, true); + case GL_UNSIGNED_SHORT_5_6_5: + return LoadImageFunctionInfo(LoadRGB565ToBGR565, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo BGR5_A1_ANGLEX_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadRGB5A1ToRGBA8, true); + case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo BGRA4_ANGLEX_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: + return LoadImageFunctionInfo(LoadRGBA4ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo BGRA8_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo BGRA8_SRGB_ANGLEX_to_B8G8R8A8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo BGRA_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo BGRX8_ANGLEX_to_B8G8R8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo BGRX8_ANGLEX_to_B8G8R8X8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_R11_EAC_to_EAC_R11_UNORM_BLOCK(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 8>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_R11_EAC_to_R16_FLOAT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadEACR11ToR16F, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_R11_EAC_to_R16_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadEACR11ToR16, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RED_GREEN_RGTC2_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RED_RGTC1_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 8>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RG11_EAC_to_EAC_R11G11_UNORM_BLOCK(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RG11_EAC_to_R16G16_FLOAT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadEACRG11ToRG16F, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RG11_EAC_to_R16G16_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadEACRG11ToRG16, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGB8_ETC2_to_ETC2_R8G8B8_UNORM_BLOCK(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 8>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGB8_ETC2_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC2RGB8ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE_to_BC1_RGB_UNORM_BLOCK(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC2RGB8ToBC1, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_to_ETC2_R8G8B8A1_UNORM_BLOCK( + GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 8>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC2RGB8A1ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo +COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE_to_BC1_RGBA_UNORM_BLOCK(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC2RGB8A1ToBC1, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA8_ETC2_EAC_to_ETC2_R8G8B8A8_UNORM_BLOCK(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA8_ETC2_EAC_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC2RGBA8ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_10x10_KHR_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadASTCToRGBA8<10, 10>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_10x10_KHR_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<10, 10, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_10x5_KHR_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadASTCToRGBA8<10, 5>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_10x5_KHR_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<10, 5, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_10x6_KHR_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadASTCToRGBA8<10, 6>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_10x6_KHR_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<10, 6, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_10x8_KHR_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadASTCToRGBA8<10, 8>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_10x8_KHR_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<10, 8, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_12x10_KHR_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadASTCToRGBA8<12, 10>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_12x10_KHR_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<12, 10, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_12x12_KHR_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadASTCToRGBA8<12, 12>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_12x12_KHR_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<12, 12, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_3x3x3_OES_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<3, 3, 3, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_4x3x3_OES_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 3, 3, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_4x4_KHR_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadASTCToRGBA8<4, 4>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_4x4_KHR_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_4x4x3_OES_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 3, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_4x4x4_OES_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 4, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_5x4_KHR_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadASTCToRGBA8<5, 4>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_5x4_KHR_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<5, 4, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_5x4x4_OES_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<5, 4, 4, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_5x5_KHR_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadASTCToRGBA8<5, 5>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_5x5_KHR_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<5, 5, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_5x5x4_OES_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<5, 5, 4, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_5x5x5_OES_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<5, 5, 5, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_6x5_KHR_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadASTCToRGBA8<6, 5>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_6x5_KHR_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<6, 5, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_6x5x5_OES_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<6, 5, 5, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_6x6_KHR_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadASTCToRGBA8<6, 6>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_6x6_KHR_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<6, 6, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_6x6x5_OES_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<6, 6, 5, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_6x6x6_OES_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<6, 6, 6, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_8x5_KHR_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadASTCToRGBA8<8, 5>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_8x5_KHR_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<8, 5, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_8x6_KHR_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadASTCToRGBA8<8, 6>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_8x6_KHR_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<8, 6, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_8x8_KHR_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadASTCToRGBA8<8, 8>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_8x8_KHR_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<8, 8, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_BPTC_UNORM_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_S3TC_DXT1_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 8>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_S3TC_DXT3_ANGLE_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_S3TC_DXT5_ANGLE_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGB_S3TC_DXT1_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 8>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SIGNED_R11_EAC_to_EAC_R11_SNORM_BLOCK(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 8>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SIGNED_R11_EAC_to_R16_FLOAT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadEACR11SToR16F, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SIGNED_R11_EAC_to_R16_SNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadEACR11SToR16, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SIGNED_RED_RGTC1_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 8>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SIGNED_RG11_EAC_to_EAC_R11G11_SNORM_BLOCK(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SIGNED_RG11_EAC_to_R16G16_FLOAT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadEACRG11SToRG16F, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SIGNED_RG11_EAC_to_R16G16_SNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadEACRG11SToRG16, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR_to_R8G8B8A8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadASTCToRGBA8<10, 10>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<10, 10, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR_to_R8G8B8A8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadASTCToRGBA8<10, 5>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<10, 5, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR_to_R8G8B8A8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadASTCToRGBA8<10, 6>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<10, 6, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR_to_R8G8B8A8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadASTCToRGBA8<10, 8>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<10, 8, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR_to_R8G8B8A8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadASTCToRGBA8<12, 10>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<12, 10, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR_to_R8G8B8A8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadASTCToRGBA8<12, 12>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<12, 12, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<3, 3, 3, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 3, 3, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR_to_R8G8B8A8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadASTCToRGBA8<4, 4>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 3, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 4, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR_to_R8G8B8A8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadASTCToRGBA8<5, 4>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<5, 4, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<5, 4, 4, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR_to_R8G8B8A8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadASTCToRGBA8<5, 5>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<5, 5, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<5, 5, 4, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<5, 5, 5, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR_to_R8G8B8A8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadASTCToRGBA8<6, 5>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<6, 5, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<6, 5, 5, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR_to_R8G8B8A8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadASTCToRGBA8<6, 6>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<6, 6, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<6, 6, 5, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<6, 6, 6, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR_to_R8G8B8A8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadASTCToRGBA8<8, 5>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<8, 5, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR_to_R8G8B8A8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadASTCToRGBA8<8, 6>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<8, 6, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR_to_R8G8B8A8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadASTCToRGBA8<8, 8>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<8, 8, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_to_ETC2_R8G8B8A8_SRGB_BLOCK(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_to_R8G8B8A8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC2SRGBA8ToSRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ETC2_to_ETC2_R8G8B8_SRGB_BLOCK(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 8>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ETC2_to_R8G8B8A8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC2SRGB8ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE_to_BC1_RGB_UNORM_SRGB_BLOCK( + GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC2SRGB8ToBC1, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_to_ETC2_R8G8B8A1_SRGB_BLOCK( + GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 8>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_to_R8G8B8A8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC2SRGB8A1ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo +COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE_to_BC1_RGBA_UNORM_SRGB_BLOCK( + GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC2SRGB8A1ToBC1, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 8>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB_S3TC_DXT1_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 8>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo DEPTH24_STENCIL8_to_D24_UNORM_S8_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT_24_8: + return LoadImageFunctionInfo(LoadR32ToR24G8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo DEPTH24_STENCIL8_to_D32_FLOAT_S8X24_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT_24_8: + return LoadImageFunctionInfo(LoadD24S8ToD32FS8X24, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo DEPTH32F_STENCIL8_to_D24_UNORM_S8_UINT(GLenum type) +{ + switch (type) + { + case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: + return LoadImageFunctionInfo(LoadD32FS8X24ToD24S8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo DEPTH32F_STENCIL8_to_D32_FLOAT_S8X24_UINT(GLenum type) +{ + switch (type) + { + case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: + return LoadImageFunctionInfo(LoadD32FS8X24ToD32FS8X24, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo DEPTH_COMPONENT16_to_D16_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT: + return LoadImageFunctionInfo(LoadR32ToR16, true); + case GL_UNSIGNED_SHORT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo DEPTH_COMPONENT16_to_D32_FLOAT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT: + return LoadImageFunctionInfo(LoadUNorm32To32F, true); + case GL_UNSIGNED_SHORT: + return LoadImageFunctionInfo(LoadUNorm16To32F, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo DEPTH_COMPONENT24_to_D24_UNORM_S8_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT: + return LoadImageFunctionInfo(LoadR32ToR24G8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo DEPTH_COMPONENT24_to_D24_UNORM_X8_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT: + return LoadImageFunctionInfo(LoadR32ToR24G8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo DEPTH_COMPONENT24_to_D32_FLOAT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT: + return LoadImageFunctionInfo(LoadD24S8ToD32F, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo DEPTH_COMPONENT24_to_D32_FLOAT_S8X24_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT: + return LoadImageFunctionInfo(LoadD32ToD32FX32, true); + case GL_UNSIGNED_INT_24_8: + return LoadImageFunctionInfo(LoadD24S8ToD32FS8X24, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo DEPTH_COMPONENT32F_to_D32_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadD32FToD32F, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo DEPTH_COMPONENT32_OES_to_D32_FLOAT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT: + return LoadImageFunctionInfo(LoadD32ToD32F, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo DEPTH_COMPONENT32_OES_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT: + return LoadImageFunctionInfo(LoadR32ToR24G8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo ETC1_RGB8_LOSSY_DECODE_ANGLE_to_BC1_RGB_UNORM_BLOCK(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC1RGB8ToBC1, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo ETC1_RGB8_OES_to_ETC1_R8G8B8_UNORM_BLOCK(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 8>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo ETC1_RGB8_OES_to_ETC2_R8G8B8_UNORM_BLOCK(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 8>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo ETC1_RGB8_OES_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC1RGB8ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo G8_B8R8_2PLANE_420_UNORM_ANGLE_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadYuvToNative, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo G8_B8_R8_3PLANE_420_UNORM_ANGLE_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnimplementedLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE_to_R16G16B16A16_FLOAT(GLenum type) +{ + switch (type) + { + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadL16FToRGBA16F, true); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadL16FToRGBA16F, true); + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE_to_R32G32B32A32_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadL32FToRGBA32F, true); + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE16F_EXT_to_R16_FLOAT(GLenum type) +{ + switch (type) + { + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadToNative, false); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE16F_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadL16FToRGBA16F, true); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadL16FToRGBA16F, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE32F_EXT_to_R32_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE32F_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadL32FToRGBA32F, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE8_ALPHA8_EXT_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadLA8ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE8_ALPHA8_EXT_to_R8G8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE8_EXT_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadL8ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE8_EXT_to_R8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE_ALPHA_to_R16G16B16A16_FLOAT(GLenum type) +{ + switch (type) + { + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadLA16FToRGBA16F, true); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadLA16FToRGBA16F, true); + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE_ALPHA_to_R32G32B32A32_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadLA32FToRGBA32F, true); + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE_ALPHA_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE_ALPHA16F_EXT_to_R16G16_FLOAT(GLenum type) +{ + switch (type) + { + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadToNative, false); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE_ALPHA16F_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadLA16FToRGBA16F, true); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadLA16FToRGBA16F, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE_ALPHA32F_EXT_to_R32G32_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE_ALPHA32F_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadLA32FToRGBA32F, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo PALETTE4_R5_G6_B5_OES_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadPalettedToRGBA8<4, 5, 6, 0>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo PALETTE4_RGB5_A1_OES_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadPalettedToRGBA8<4, 5, 5, 1>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo PALETTE4_RGB8_OES_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadPalettedToRGBA8<4, 8, 8, 0>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo PALETTE4_RGBA4_OES_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadPalettedToRGBA8<4, 4, 4, 4>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo PALETTE4_RGBA8_OES_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadPalettedToRGBA8<4, 8, 8, 8>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo PALETTE8_R5_G6_B5_OES_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadPalettedToRGBA8<8, 5, 6, 0>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo PALETTE8_RGB5_A1_OES_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadPalettedToRGBA8<8, 5, 5, 1>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo PALETTE8_RGB8_OES_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadPalettedToRGBA8<8, 8, 8, 0>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo PALETTE8_RGBA4_OES_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadPalettedToRGBA8<8, 4, 4, 4>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo PALETTE8_RGBA8_OES_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadPalettedToRGBA8<8, 8, 8, 8>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R11F_G11F_B10F_to_R11G11B10_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadRGB32FToRG11B10F, true); + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadRGB16FToRG11B10F, true); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadRGB16FToRG11B10F, true); + case GL_UNSIGNED_INT_10F_11F_11F_REV: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R16F_to_R16_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(Load32FTo16F<1>, true); + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadToNative, false); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R16I_to_R16_SINT(GLenum type) +{ + switch (type) + { + case GL_SHORT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R16UI_to_R16_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_SHORT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R16_EXT_to_R16_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_SHORT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R16_SNORM_EXT_to_R16_SNORM(GLenum type) +{ + switch (type) + { + case GL_SHORT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R16_SSCALED_ANGLEX_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R16_USCALED_ANGLEX_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R32F_to_R32_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R32I_to_R32_SINT(GLenum type) +{ + switch (type) + { + case GL_INT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R32UI_to_R32_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R8_to_R8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R8I_to_R8_SINT(GLenum type) +{ + switch (type) + { + case GL_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R8UI_to_R8_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R8_SNORM_to_R8_SNORM(GLenum type) +{ + switch (type) + { + case GL_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R8_SSCALED_ANGLEX_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R8_USCALED_ANGLEX_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG16F_to_R16G16_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(Load32FTo16F<2>, true); + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadToNative, false); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG16I_to_R16G16_SINT(GLenum type) +{ + switch (type) + { + case GL_SHORT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG16UI_to_R16G16_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_SHORT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG16_EXT_to_R16G16_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_SHORT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG16_SNORM_EXT_to_R16G16_SNORM(GLenum type) +{ + switch (type) + { + case GL_SHORT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG16_SSCALED_ANGLEX_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG16_USCALED_ANGLEX_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG32F_to_R32G32_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG32I_to_R32G32_SINT(GLenum type) +{ + switch (type) + { + case GL_INT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG32UI_to_R32G32_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG8_to_R8G8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG8I_to_R8G8_SINT(GLenum type) +{ + switch (type) + { + case GL_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG8UI_to_R8G8_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG8_SNORM_to_R8G8_SNORM(GLenum type) +{ + switch (type) + { + case GL_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG8_SSCALED_ANGLEX_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG8_USCALED_ANGLEX_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + case GL_UNSIGNED_SHORT_5_6_5: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB10_A2_to_R10G10B10A2_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT_2_10_10_10_REV: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB10_A2UI_to_R10G10B10A2_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT_2_10_10_10_REV: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB10_A2_SINT_ANGLEX_to_R10G10B10A2_SINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadRGB10A2ToRGBA8, true); + case GL_UNSIGNED_INT_2_10_10_10_REV: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB10_A2_SNORM_ANGLEX_to_R10G10B10A2_SNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadRGB10A2ToRGBA8, true); + case GL_UNSIGNED_INT_2_10_10_10_REV: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB10_A2_SSCALED_ANGLEX_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB10_A2_USCALED_ANGLEX_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB10_UNORM_ANGLEX_to_R10G10B10A2_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT_2_10_10_10_REV: + return LoadImageFunctionInfo(LoadRGB10A2ToRGB10X2, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB10_UNORM_ANGLEX_to_R10G10B10X2_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT_2_10_10_10_REV: + return LoadImageFunctionInfo(LoadRGB10A2ToRGB10X2, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB16F_to_R16G16B16A16_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadRGB32FToRGBA16F, true); + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadToNative3To4, true); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadToNative3To4, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB16F_to_R16G16B16_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadRGB32FToRGB16F, true); + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadToNative, false); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB16I_to_R16G16B16A16_SINT(GLenum type) +{ + switch (type) + { + case GL_SHORT: + return LoadImageFunctionInfo(LoadToNative3To4, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB16I_to_R16G16B16_SINT(GLenum type) +{ + switch (type) + { + case GL_SHORT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB16UI_to_R16G16B16A16_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_SHORT: + return LoadImageFunctionInfo(LoadToNative3To4, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB16UI_to_R16G16B16_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_SHORT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB16_EXT_to_R16G16B16A16_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_SHORT: + return LoadImageFunctionInfo(LoadToNative3To4, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB16_EXT_to_R16G16B16_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_SHORT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB16_SNORM_EXT_to_R16G16B16A16_SNORM(GLenum type) +{ + switch (type) + { + case GL_SHORT: + return LoadImageFunctionInfo(LoadToNative3To4, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB16_SNORM_EXT_to_R16G16B16_SNORM(GLenum type) +{ + switch (type) + { + case GL_SHORT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB16_SSCALED_ANGLEX_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB16_USCALED_ANGLEX_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB32F_to_R32G32B32A32_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadToNative3To4, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB32F_to_R32G32B32_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB32I_to_R32G32B32A32_SINT(GLenum type) +{ + switch (type) + { + case GL_INT: + return LoadImageFunctionInfo(LoadToNative3To4, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB32I_to_R32G32B32_SINT(GLenum type) +{ + switch (type) + { + case GL_INT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB32UI_to_R32G32B32A32_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT: + return LoadImageFunctionInfo(LoadToNative3To4, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB32UI_to_R32G32B32_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB565_to_B5G6R5_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadRGB8ToBGR565, true); + case GL_UNSIGNED_SHORT_5_6_5: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB565_to_R5G6B5_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadRGB8ToBGR565, true); + case GL_UNSIGNED_SHORT_5_6_5: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB565_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative3To4, true); + case GL_UNSIGNED_SHORT_5_6_5: + return LoadImageFunctionInfo(LoadR5G6B5ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB5_A1_to_A1R5G5B5_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadRGBA8ToBGR5A1, true); + case GL_UNSIGNED_INT_2_10_10_10_REV: + return LoadImageFunctionInfo(LoadRGB10A2ToBGR5A1, true); + case GL_UNSIGNED_SHORT_5_5_5_1: + return LoadImageFunctionInfo(LoadRGB5A1ToA1RGB5, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB5_A1_to_B5G5R5A1_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadRGBA8ToBGR5A1, true); + case GL_UNSIGNED_INT_2_10_10_10_REV: + return LoadImageFunctionInfo(LoadRGB10A2ToBGR5A1, true); + case GL_UNSIGNED_SHORT_5_5_5_1: + return LoadImageFunctionInfo(LoadRGB5A1ToA1RGB5, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB5_A1_to_R5G5B5A1_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadRGBA8ToRGB5A1, true); + case GL_UNSIGNED_INT_2_10_10_10_REV: + return LoadImageFunctionInfo(LoadRGB10A2ToRGB5A1, true); + case GL_UNSIGNED_SHORT_5_5_5_1: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB5_A1_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + case GL_UNSIGNED_INT_2_10_10_10_REV: + return LoadImageFunctionInfo(LoadRGB10A2ToRGBA8, true); + case GL_UNSIGNED_SHORT_5_5_5_1: + return LoadImageFunctionInfo(LoadRGB5A1ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB8_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative3To4, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB8_to_R8G8B8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB8I_to_R8G8B8A8_SINT(GLenum type) +{ + switch (type) + { + case GL_BYTE: + return LoadImageFunctionInfo(LoadToNative3To4, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB8I_to_R8G8B8_SINT(GLenum type) +{ + switch (type) + { + case GL_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB8UI_to_R8G8B8A8_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative3To4, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB8UI_to_R8G8B8_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB8_SNORM_to_R8G8B8A8_SNORM(GLenum type) +{ + switch (type) + { + case GL_BYTE: + return LoadImageFunctionInfo(LoadToNative3To4, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB8_SNORM_to_R8G8B8_SNORM(GLenum type) +{ + switch (type) + { + case GL_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB8_SSCALED_ANGLEX_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB8_USCALED_ANGLEX_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB9_E5_to_R9G9B9E5_SHAREDEXP(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadRGB32FToRGB9E5, true); + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadRGB16FToRGB9E5, true); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadRGB16FToRGB9E5, true); + case GL_UNSIGNED_INT_5_9_9_9_REV: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + case GL_UNSIGNED_SHORT_4_4_4_4: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + case GL_UNSIGNED_SHORT_5_5_5_1: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA16F_to_R16G16B16A16_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(Load32FTo16F<4>, true); + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadToNative, false); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA16I_to_R16G16B16A16_SINT(GLenum type) +{ + switch (type) + { + case GL_SHORT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA16UI_to_R16G16B16A16_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_SHORT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA16_EXT_to_R16G16B16A16_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_SHORT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA16_SNORM_EXT_to_R16G16B16A16_SNORM(GLenum type) +{ + switch (type) + { + case GL_SHORT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA16_SSCALED_ANGLEX_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA16_USCALED_ANGLEX_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA32F_to_R32G32B32A32_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA32I_to_R32G32B32A32_SINT(GLenum type) +{ + switch (type) + { + case GL_INT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA32UI_to_R32G32B32A32_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA4_to_B4G4R4A4_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadRGBA8ToBGRA4, true); + case GL_UNSIGNED_SHORT_4_4_4_4: + return LoadImageFunctionInfo(LoadRGBA4ToARGB4, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA4_to_R4G4B4A4_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadRGBA8ToRGBA4, true); + case GL_UNSIGNED_SHORT_4_4_4_4: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA4_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + case GL_UNSIGNED_SHORT_4_4_4_4: + return LoadImageFunctionInfo(LoadRGBA4ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA8_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA8I_to_R8G8B8A8_SINT(GLenum type) +{ + switch (type) + { + case GL_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA8UI_to_R8G8B8A8_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA8_SNORM_to_R8G8B8A8_SNORM(GLenum type) +{ + switch (type) + { + case GL_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA8_SSCALED_ANGLEX_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA8_USCALED_ANGLEX_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBX8_ANGLE_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative3To4, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBX8_ANGLE_to_R8G8B8X8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative3To4, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo SR8_EXT_to_R8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo SRG8_EXT_to_R8G8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo SRGB8_to_R8G8B8A8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative3To4, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo SRGB8_to_R8G8B8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo SRGB8_ALPHA8_to_R8G8B8A8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo STENCIL_INDEX8_to_S8_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo STENCIL_INDEX8_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnimplementedLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +} // namespace + +LoadFunctionMap GetLoadFunctionsMap(GLenum internalFormat, FormatID angleFormat) +{ + // clang-format off + switch (internalFormat) + { + case GL_A1RGB5_ANGLEX: + { + switch (angleFormat) + { + case FormatID::A1R5G5B5_UNORM: + return A1RGB5_ANGLEX_to_A1R5G5B5_UNORM; + default: + break; + } + break; + } + case GL_ALPHA: + { + switch (angleFormat) + { + case FormatID::R16G16B16A16_FLOAT: + return ALPHA_to_R16G16B16A16_FLOAT; + case FormatID::R32G32B32A32_FLOAT: + return ALPHA_to_R32G32B32A32_FLOAT; + default: + return ALPHA_to_default; + } + } + case GL_ALPHA16F_EXT: + { + switch (angleFormat) + { + case FormatID::R16_FLOAT: + return ALPHA16F_EXT_to_R16_FLOAT; + default: + return ALPHA16F_EXT_to_default; + } + } + case GL_ALPHA32F_EXT: + { + switch (angleFormat) + { + case FormatID::R32_FLOAT: + return ALPHA32F_EXT_to_R32_FLOAT; + default: + return ALPHA32F_EXT_to_default; + } + } + case GL_ALPHA8_EXT: + { + switch (angleFormat) + { + case FormatID::A8_UNORM: + return ALPHA8_EXT_to_A8_UNORM; + case FormatID::R8G8B8A8_UNORM: + return ALPHA8_EXT_to_R8G8B8A8_UNORM; + case FormatID::R8_UNORM: + return ALPHA8_EXT_to_R8_UNORM; + default: + break; + } + break; + } + case GL_BGR10_A2_ANGLEX: + { + switch (angleFormat) + { + case FormatID::B10G10R10A2_UNORM: + return BGR10_A2_ANGLEX_to_B10G10R10A2_UNORM; + default: + break; + } + break; + } + case GL_BGR565_ANGLEX: + { + switch (angleFormat) + { + case FormatID::B5G6R5_UNORM: + return BGR565_ANGLEX_to_B5G6R5_UNORM; + default: + break; + } + break; + } + case GL_BGR5_A1_ANGLEX: + return BGR5_A1_ANGLEX_to_default; + case GL_BGRA4_ANGLEX: + return BGRA4_ANGLEX_to_default; + case GL_BGRA8_EXT: + return BGRA8_EXT_to_default; + case GL_BGRA8_SRGB_ANGLEX: + { + switch (angleFormat) + { + case FormatID::B8G8R8A8_UNORM_SRGB: + return BGRA8_SRGB_ANGLEX_to_B8G8R8A8_UNORM_SRGB; + default: + break; + } + break; + } + case GL_BGRA_EXT: + return BGRA_EXT_to_default; + case GL_BGRX8_ANGLEX: + { + switch (angleFormat) + { + case FormatID::B8G8R8A8_UNORM: + return BGRX8_ANGLEX_to_B8G8R8A8_UNORM; + case FormatID::B8G8R8X8_UNORM: + return BGRX8_ANGLEX_to_B8G8R8X8_UNORM; + default: + break; + } + break; + } + case GL_COMPRESSED_R11_EAC: + { + switch (angleFormat) + { + case FormatID::EAC_R11_UNORM_BLOCK: + return COMPRESSED_R11_EAC_to_EAC_R11_UNORM_BLOCK; + case FormatID::R16_FLOAT: + return COMPRESSED_R11_EAC_to_R16_FLOAT; + case FormatID::R16_UNORM: + return COMPRESSED_R11_EAC_to_R16_UNORM; + default: + break; + } + break; + } + case GL_COMPRESSED_RED_GREEN_RGTC2_EXT: + return COMPRESSED_RED_GREEN_RGTC2_EXT_to_default; + case GL_COMPRESSED_RED_RGTC1_EXT: + return COMPRESSED_RED_RGTC1_EXT_to_default; + case GL_COMPRESSED_RG11_EAC: + { + switch (angleFormat) + { + case FormatID::EAC_R11G11_UNORM_BLOCK: + return COMPRESSED_RG11_EAC_to_EAC_R11G11_UNORM_BLOCK; + case FormatID::R16G16_FLOAT: + return COMPRESSED_RG11_EAC_to_R16G16_FLOAT; + case FormatID::R16G16_UNORM: + return COMPRESSED_RG11_EAC_to_R16G16_UNORM; + default: + break; + } + break; + } + case GL_COMPRESSED_RGB8_ETC2: + { + switch (angleFormat) + { + case FormatID::ETC2_R8G8B8_UNORM_BLOCK: + return COMPRESSED_RGB8_ETC2_to_ETC2_R8G8B8_UNORM_BLOCK; + case FormatID::R8G8B8A8_UNORM: + return COMPRESSED_RGB8_ETC2_to_R8G8B8A8_UNORM; + default: + break; + } + break; + } + case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE: + { + switch (angleFormat) + { + case FormatID::BC1_RGB_UNORM_BLOCK: + return COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE_to_BC1_RGB_UNORM_BLOCK; + default: + break; + } + break; + } + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + { + switch (angleFormat) + { + case FormatID::ETC2_R8G8B8A1_UNORM_BLOCK: + return COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_to_ETC2_R8G8B8A1_UNORM_BLOCK; + case FormatID::R8G8B8A8_UNORM: + return COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_to_R8G8B8A8_UNORM; + default: + break; + } + break; + } + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE: + { + switch (angleFormat) + { + case FormatID::BC1_RGBA_UNORM_BLOCK: + return COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE_to_BC1_RGBA_UNORM_BLOCK; + default: + break; + } + break; + } + case GL_COMPRESSED_RGBA8_ETC2_EAC: + { + switch (angleFormat) + { + case FormatID::ETC2_R8G8B8A8_UNORM_BLOCK: + return COMPRESSED_RGBA8_ETC2_EAC_to_ETC2_R8G8B8A8_UNORM_BLOCK; + case FormatID::R8G8B8A8_UNORM: + return COMPRESSED_RGBA8_ETC2_EAC_to_R8G8B8A8_UNORM; + default: + break; + } + break; + } + case GL_COMPRESSED_RGBA_ASTC_10x10_KHR: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM: + return COMPRESSED_RGBA_ASTC_10x10_KHR_to_R8G8B8A8_UNORM; + default: + return COMPRESSED_RGBA_ASTC_10x10_KHR_to_default; + } + } + case GL_COMPRESSED_RGBA_ASTC_10x5_KHR: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM: + return COMPRESSED_RGBA_ASTC_10x5_KHR_to_R8G8B8A8_UNORM; + default: + return COMPRESSED_RGBA_ASTC_10x5_KHR_to_default; + } + } + case GL_COMPRESSED_RGBA_ASTC_10x6_KHR: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM: + return COMPRESSED_RGBA_ASTC_10x6_KHR_to_R8G8B8A8_UNORM; + default: + return COMPRESSED_RGBA_ASTC_10x6_KHR_to_default; + } + } + case GL_COMPRESSED_RGBA_ASTC_10x8_KHR: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM: + return COMPRESSED_RGBA_ASTC_10x8_KHR_to_R8G8B8A8_UNORM; + default: + return COMPRESSED_RGBA_ASTC_10x8_KHR_to_default; + } + } + case GL_COMPRESSED_RGBA_ASTC_12x10_KHR: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM: + return COMPRESSED_RGBA_ASTC_12x10_KHR_to_R8G8B8A8_UNORM; + default: + return COMPRESSED_RGBA_ASTC_12x10_KHR_to_default; + } + } + case GL_COMPRESSED_RGBA_ASTC_12x12_KHR: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM: + return COMPRESSED_RGBA_ASTC_12x12_KHR_to_R8G8B8A8_UNORM; + default: + return COMPRESSED_RGBA_ASTC_12x12_KHR_to_default; + } + } + case GL_COMPRESSED_RGBA_ASTC_3x3x3_OES: + return COMPRESSED_RGBA_ASTC_3x3x3_OES_to_default; + case GL_COMPRESSED_RGBA_ASTC_4x3x3_OES: + return COMPRESSED_RGBA_ASTC_4x3x3_OES_to_default; + case GL_COMPRESSED_RGBA_ASTC_4x4_KHR: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM: + return COMPRESSED_RGBA_ASTC_4x4_KHR_to_R8G8B8A8_UNORM; + default: + return COMPRESSED_RGBA_ASTC_4x4_KHR_to_default; + } + } + case GL_COMPRESSED_RGBA_ASTC_4x4x3_OES: + return COMPRESSED_RGBA_ASTC_4x4x3_OES_to_default; + case GL_COMPRESSED_RGBA_ASTC_4x4x4_OES: + return COMPRESSED_RGBA_ASTC_4x4x4_OES_to_default; + case GL_COMPRESSED_RGBA_ASTC_5x4_KHR: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM: + return COMPRESSED_RGBA_ASTC_5x4_KHR_to_R8G8B8A8_UNORM; + default: + return COMPRESSED_RGBA_ASTC_5x4_KHR_to_default; + } + } + case GL_COMPRESSED_RGBA_ASTC_5x4x4_OES: + return COMPRESSED_RGBA_ASTC_5x4x4_OES_to_default; + case GL_COMPRESSED_RGBA_ASTC_5x5_KHR: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM: + return COMPRESSED_RGBA_ASTC_5x5_KHR_to_R8G8B8A8_UNORM; + default: + return COMPRESSED_RGBA_ASTC_5x5_KHR_to_default; + } + } + case GL_COMPRESSED_RGBA_ASTC_5x5x4_OES: + return COMPRESSED_RGBA_ASTC_5x5x4_OES_to_default; + case GL_COMPRESSED_RGBA_ASTC_5x5x5_OES: + return COMPRESSED_RGBA_ASTC_5x5x5_OES_to_default; + case GL_COMPRESSED_RGBA_ASTC_6x5_KHR: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM: + return COMPRESSED_RGBA_ASTC_6x5_KHR_to_R8G8B8A8_UNORM; + default: + return COMPRESSED_RGBA_ASTC_6x5_KHR_to_default; + } + } + case GL_COMPRESSED_RGBA_ASTC_6x5x5_OES: + return COMPRESSED_RGBA_ASTC_6x5x5_OES_to_default; + case GL_COMPRESSED_RGBA_ASTC_6x6_KHR: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM: + return COMPRESSED_RGBA_ASTC_6x6_KHR_to_R8G8B8A8_UNORM; + default: + return COMPRESSED_RGBA_ASTC_6x6_KHR_to_default; + } + } + case GL_COMPRESSED_RGBA_ASTC_6x6x5_OES: + return COMPRESSED_RGBA_ASTC_6x6x5_OES_to_default; + case GL_COMPRESSED_RGBA_ASTC_6x6x6_OES: + return COMPRESSED_RGBA_ASTC_6x6x6_OES_to_default; + case GL_COMPRESSED_RGBA_ASTC_8x5_KHR: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM: + return COMPRESSED_RGBA_ASTC_8x5_KHR_to_R8G8B8A8_UNORM; + default: + return COMPRESSED_RGBA_ASTC_8x5_KHR_to_default; + } + } + case GL_COMPRESSED_RGBA_ASTC_8x6_KHR: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM: + return COMPRESSED_RGBA_ASTC_8x6_KHR_to_R8G8B8A8_UNORM; + default: + return COMPRESSED_RGBA_ASTC_8x6_KHR_to_default; + } + } + case GL_COMPRESSED_RGBA_ASTC_8x8_KHR: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM: + return COMPRESSED_RGBA_ASTC_8x8_KHR_to_R8G8B8A8_UNORM; + default: + return COMPRESSED_RGBA_ASTC_8x8_KHR_to_default; + } + } + case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT: + return COMPRESSED_RGBA_BPTC_UNORM_EXT_to_default; + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + return COMPRESSED_RGBA_S3TC_DXT1_EXT_to_default; + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + return COMPRESSED_RGBA_S3TC_DXT3_ANGLE_to_default; + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + return COMPRESSED_RGBA_S3TC_DXT5_ANGLE_to_default; + case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT: + return COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT_to_default; + case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT: + return COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT_to_default; + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + return COMPRESSED_RGB_S3TC_DXT1_EXT_to_default; + case GL_COMPRESSED_SIGNED_R11_EAC: + { + switch (angleFormat) + { + case FormatID::EAC_R11_SNORM_BLOCK: + return COMPRESSED_SIGNED_R11_EAC_to_EAC_R11_SNORM_BLOCK; + case FormatID::R16_FLOAT: + return COMPRESSED_SIGNED_R11_EAC_to_R16_FLOAT; + case FormatID::R16_SNORM: + return COMPRESSED_SIGNED_R11_EAC_to_R16_SNORM; + default: + break; + } + break; + } + case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT: + return COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT_to_default; + case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT: + return COMPRESSED_SIGNED_RED_RGTC1_EXT_to_default; + case GL_COMPRESSED_SIGNED_RG11_EAC: + { + switch (angleFormat) + { + case FormatID::EAC_R11G11_SNORM_BLOCK: + return COMPRESSED_SIGNED_RG11_EAC_to_EAC_R11G11_SNORM_BLOCK; + case FormatID::R16G16_FLOAT: + return COMPRESSED_SIGNED_RG11_EAC_to_R16G16_FLOAT; + case FormatID::R16G16_SNORM: + return COMPRESSED_SIGNED_RG11_EAC_to_R16G16_SNORM; + default: + break; + } + break; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM_SRGB: + return COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR_to_R8G8B8A8_UNORM_SRGB; + default: + return COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR_to_default; + } + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM_SRGB: + return COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR_to_R8G8B8A8_UNORM_SRGB; + default: + return COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR_to_default; + } + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM_SRGB: + return COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR_to_R8G8B8A8_UNORM_SRGB; + default: + return COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR_to_default; + } + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM_SRGB: + return COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR_to_R8G8B8A8_UNORM_SRGB; + default: + return COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR_to_default; + } + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM_SRGB: + return COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR_to_R8G8B8A8_UNORM_SRGB; + default: + return COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR_to_default; + } + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM_SRGB: + return COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR_to_R8G8B8A8_UNORM_SRGB; + default: + return COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR_to_default; + } + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES: + return COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES_to_default; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES: + return COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES_to_default; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM_SRGB: + return COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR_to_R8G8B8A8_UNORM_SRGB; + default: + return COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR_to_default; + } + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES: + return COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES_to_default; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES: + return COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES_to_default; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM_SRGB: + return COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR_to_R8G8B8A8_UNORM_SRGB; + default: + return COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR_to_default; + } + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES: + return COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES_to_default; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM_SRGB: + return COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR_to_R8G8B8A8_UNORM_SRGB; + default: + return COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR_to_default; + } + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES: + return COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES_to_default; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES: + return COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES_to_default; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM_SRGB: + return COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR_to_R8G8B8A8_UNORM_SRGB; + default: + return COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR_to_default; + } + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES: + return COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES_to_default; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM_SRGB: + return COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR_to_R8G8B8A8_UNORM_SRGB; + default: + return COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR_to_default; + } + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES: + return COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES_to_default; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES: + return COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES_to_default; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM_SRGB: + return COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR_to_R8G8B8A8_UNORM_SRGB; + default: + return COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR_to_default; + } + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM_SRGB: + return COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR_to_R8G8B8A8_UNORM_SRGB; + default: + return COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR_to_default; + } + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM_SRGB: + return COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR_to_R8G8B8A8_UNORM_SRGB; + default: + return COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR_to_default; + } + } + case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: + { + switch (angleFormat) + { + case FormatID::ETC2_R8G8B8A8_SRGB_BLOCK: + return COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_to_ETC2_R8G8B8A8_SRGB_BLOCK; + case FormatID::R8G8B8A8_UNORM_SRGB: + return COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_to_R8G8B8A8_UNORM_SRGB; + default: + break; + } + break; + } + case GL_COMPRESSED_SRGB8_ETC2: + { + switch (angleFormat) + { + case FormatID::ETC2_R8G8B8_SRGB_BLOCK: + return COMPRESSED_SRGB8_ETC2_to_ETC2_R8G8B8_SRGB_BLOCK; + case FormatID::R8G8B8A8_UNORM_SRGB: + return COMPRESSED_SRGB8_ETC2_to_R8G8B8A8_UNORM_SRGB; + default: + break; + } + break; + } + case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE: + { + switch (angleFormat) + { + case FormatID::BC1_RGB_UNORM_SRGB_BLOCK: + return COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE_to_BC1_RGB_UNORM_SRGB_BLOCK; + default: + break; + } + break; + } + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + { + switch (angleFormat) + { + case FormatID::ETC2_R8G8B8A1_SRGB_BLOCK: + return COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_to_ETC2_R8G8B8A1_SRGB_BLOCK; + case FormatID::R8G8B8A8_UNORM_SRGB: + return COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_to_R8G8B8A8_UNORM_SRGB; + default: + break; + } + break; + } + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE: + { + switch (angleFormat) + { + case FormatID::BC1_RGBA_UNORM_SRGB_BLOCK: + return COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE_to_BC1_RGBA_UNORM_SRGB_BLOCK; + default: + break; + } + break; + } + case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT: + return COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT_to_default; + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + return COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT_to_default; + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + return COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT_to_default; + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + return COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT_to_default; + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + return COMPRESSED_SRGB_S3TC_DXT1_EXT_to_default; + case GL_DEPTH24_STENCIL8: + { + switch (angleFormat) + { + case FormatID::D24_UNORM_S8_UINT: + return DEPTH24_STENCIL8_to_D24_UNORM_S8_UINT; + case FormatID::D32_FLOAT_S8X24_UINT: + return DEPTH24_STENCIL8_to_D32_FLOAT_S8X24_UINT; + default: + break; + } + break; + } + case GL_DEPTH32F_STENCIL8: + { + switch (angleFormat) + { + case FormatID::D24_UNORM_S8_UINT: + return DEPTH32F_STENCIL8_to_D24_UNORM_S8_UINT; + case FormatID::D32_FLOAT_S8X24_UINT: + return DEPTH32F_STENCIL8_to_D32_FLOAT_S8X24_UINT; + default: + break; + } + break; + } + case GL_DEPTH_COMPONENT16: + { + switch (angleFormat) + { + case FormatID::D16_UNORM: + return DEPTH_COMPONENT16_to_D16_UNORM; + case FormatID::D32_FLOAT: + return DEPTH_COMPONENT16_to_D32_FLOAT; + default: + break; + } + break; + } + case GL_DEPTH_COMPONENT24: + { + switch (angleFormat) + { + case FormatID::D24_UNORM_S8_UINT: + return DEPTH_COMPONENT24_to_D24_UNORM_S8_UINT; + case FormatID::D24_UNORM_X8_UINT: + return DEPTH_COMPONENT24_to_D24_UNORM_X8_UINT; + case FormatID::D32_FLOAT: + return DEPTH_COMPONENT24_to_D32_FLOAT; + case FormatID::D32_FLOAT_S8X24_UINT: + return DEPTH_COMPONENT24_to_D32_FLOAT_S8X24_UINT; + default: + break; + } + break; + } + case GL_DEPTH_COMPONENT32F: + { + switch (angleFormat) + { + case FormatID::D32_FLOAT: + return DEPTH_COMPONENT32F_to_D32_FLOAT; + default: + break; + } + break; + } + case GL_DEPTH_COMPONENT32_OES: + { + switch (angleFormat) + { + case FormatID::D32_FLOAT: + return DEPTH_COMPONENT32_OES_to_D32_FLOAT; + default: + return DEPTH_COMPONENT32_OES_to_default; + } + } + case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE: + { + switch (angleFormat) + { + case FormatID::BC1_RGB_UNORM_BLOCK: + return ETC1_RGB8_LOSSY_DECODE_ANGLE_to_BC1_RGB_UNORM_BLOCK; + default: + break; + } + break; + } + case GL_ETC1_RGB8_OES: + { + switch (angleFormat) + { + case FormatID::ETC1_R8G8B8_UNORM_BLOCK: + return ETC1_RGB8_OES_to_ETC1_R8G8B8_UNORM_BLOCK; + case FormatID::ETC2_R8G8B8_UNORM_BLOCK: + return ETC1_RGB8_OES_to_ETC2_R8G8B8_UNORM_BLOCK; + case FormatID::R8G8B8A8_UNORM: + return ETC1_RGB8_OES_to_R8G8B8A8_UNORM; + default: + break; + } + break; + } + case GL_G8_B8R8_2PLANE_420_UNORM_ANGLE: + return G8_B8R8_2PLANE_420_UNORM_ANGLE_to_default; + case GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE: + return G8_B8_R8_3PLANE_420_UNORM_ANGLE_to_default; + case GL_LUMINANCE: + { + switch (angleFormat) + { + case FormatID::R16G16B16A16_FLOAT: + return LUMINANCE_to_R16G16B16A16_FLOAT; + case FormatID::R32G32B32A32_FLOAT: + return LUMINANCE_to_R32G32B32A32_FLOAT; + default: + return LUMINANCE_to_default; + } + } + case GL_LUMINANCE16F_EXT: + { + switch (angleFormat) + { + case FormatID::R16_FLOAT: + return LUMINANCE16F_EXT_to_R16_FLOAT; + default: + return LUMINANCE16F_EXT_to_default; + } + } + case GL_LUMINANCE32F_EXT: + { + switch (angleFormat) + { + case FormatID::R32_FLOAT: + return LUMINANCE32F_EXT_to_R32_FLOAT; + default: + return LUMINANCE32F_EXT_to_default; + } + } + case GL_LUMINANCE8_ALPHA8_EXT: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM: + return LUMINANCE8_ALPHA8_EXT_to_R8G8B8A8_UNORM; + case FormatID::R8G8_UNORM: + return LUMINANCE8_ALPHA8_EXT_to_R8G8_UNORM; + default: + break; + } + break; + } + case GL_LUMINANCE8_EXT: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM: + return LUMINANCE8_EXT_to_R8G8B8A8_UNORM; + case FormatID::R8_UNORM: + return LUMINANCE8_EXT_to_R8_UNORM; + default: + break; + } + break; + } + case GL_LUMINANCE_ALPHA: + { + switch (angleFormat) + { + case FormatID::R16G16B16A16_FLOAT: + return LUMINANCE_ALPHA_to_R16G16B16A16_FLOAT; + case FormatID::R32G32B32A32_FLOAT: + return LUMINANCE_ALPHA_to_R32G32B32A32_FLOAT; + default: + return LUMINANCE_ALPHA_to_default; + } + } + case GL_LUMINANCE_ALPHA16F_EXT: + { + switch (angleFormat) + { + case FormatID::R16G16_FLOAT: + return LUMINANCE_ALPHA16F_EXT_to_R16G16_FLOAT; + default: + return LUMINANCE_ALPHA16F_EXT_to_default; + } + } + case GL_LUMINANCE_ALPHA32F_EXT: + { + switch (angleFormat) + { + case FormatID::R32G32_FLOAT: + return LUMINANCE_ALPHA32F_EXT_to_R32G32_FLOAT; + default: + return LUMINANCE_ALPHA32F_EXT_to_default; + } + } + case GL_PALETTE4_R5_G6_B5_OES: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM: + return PALETTE4_R5_G6_B5_OES_to_R8G8B8A8_UNORM; + default: + break; + } + break; + } + case GL_PALETTE4_RGB5_A1_OES: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM: + return PALETTE4_RGB5_A1_OES_to_R8G8B8A8_UNORM; + default: + break; + } + break; + } + case GL_PALETTE4_RGB8_OES: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM: + return PALETTE4_RGB8_OES_to_R8G8B8A8_UNORM; + default: + break; + } + break; + } + case GL_PALETTE4_RGBA4_OES: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM: + return PALETTE4_RGBA4_OES_to_R8G8B8A8_UNORM; + default: + break; + } + break; + } + case GL_PALETTE4_RGBA8_OES: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM: + return PALETTE4_RGBA8_OES_to_R8G8B8A8_UNORM; + default: + break; + } + break; + } + case GL_PALETTE8_R5_G6_B5_OES: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM: + return PALETTE8_R5_G6_B5_OES_to_R8G8B8A8_UNORM; + default: + break; + } + break; + } + case GL_PALETTE8_RGB5_A1_OES: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM: + return PALETTE8_RGB5_A1_OES_to_R8G8B8A8_UNORM; + default: + break; + } + break; + } + case GL_PALETTE8_RGB8_OES: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM: + return PALETTE8_RGB8_OES_to_R8G8B8A8_UNORM; + default: + break; + } + break; + } + case GL_PALETTE8_RGBA4_OES: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM: + return PALETTE8_RGBA4_OES_to_R8G8B8A8_UNORM; + default: + break; + } + break; + } + case GL_PALETTE8_RGBA8_OES: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM: + return PALETTE8_RGBA8_OES_to_R8G8B8A8_UNORM; + default: + break; + } + break; + } + case GL_R11F_G11F_B10F: + { + switch (angleFormat) + { + case FormatID::R11G11B10_FLOAT: + return R11F_G11F_B10F_to_R11G11B10_FLOAT; + default: + break; + } + break; + } + case GL_R16F: + { + switch (angleFormat) + { + case FormatID::R16_FLOAT: + return R16F_to_R16_FLOAT; + default: + break; + } + break; + } + case GL_R16I: + { + switch (angleFormat) + { + case FormatID::R16_SINT: + return R16I_to_R16_SINT; + default: + break; + } + break; + } + case GL_R16UI: + { + switch (angleFormat) + { + case FormatID::R16_UINT: + return R16UI_to_R16_UINT; + default: + break; + } + break; + } + case GL_R16_EXT: + { + switch (angleFormat) + { + case FormatID::R16_UNORM: + return R16_EXT_to_R16_UNORM; + default: + break; + } + break; + } + case GL_R16_SNORM_EXT: + { + switch (angleFormat) + { + case FormatID::R16_SNORM: + return R16_SNORM_EXT_to_R16_SNORM; + default: + break; + } + break; + } + case GL_R16_SSCALED_ANGLEX: + return R16_SSCALED_ANGLEX_to_default; + case GL_R16_USCALED_ANGLEX: + return R16_USCALED_ANGLEX_to_default; + case GL_R32F: + { + switch (angleFormat) + { + case FormatID::R32_FLOAT: + return R32F_to_R32_FLOAT; + default: + break; + } + break; + } + case GL_R32I: + { + switch (angleFormat) + { + case FormatID::R32_SINT: + return R32I_to_R32_SINT; + default: + break; + } + break; + } + case GL_R32UI: + { + switch (angleFormat) + { + case FormatID::R32_UINT: + return R32UI_to_R32_UINT; + default: + break; + } + break; + } + case GL_R8: + { + switch (angleFormat) + { + case FormatID::R8_UNORM: + return R8_to_R8_UNORM; + default: + break; + } + break; + } + case GL_R8I: + { + switch (angleFormat) + { + case FormatID::R8_SINT: + return R8I_to_R8_SINT; + default: + break; + } + break; + } + case GL_R8UI: + { + switch (angleFormat) + { + case FormatID::R8_UINT: + return R8UI_to_R8_UINT; + default: + break; + } + break; + } + case GL_R8_SNORM: + { + switch (angleFormat) + { + case FormatID::R8_SNORM: + return R8_SNORM_to_R8_SNORM; + default: + break; + } + break; + } + case GL_R8_SSCALED_ANGLEX: + return R8_SSCALED_ANGLEX_to_default; + case GL_R8_USCALED_ANGLEX: + return R8_USCALED_ANGLEX_to_default; + case GL_RG16F: + { + switch (angleFormat) + { + case FormatID::R16G16_FLOAT: + return RG16F_to_R16G16_FLOAT; + default: + break; + } + break; + } + case GL_RG16I: + { + switch (angleFormat) + { + case FormatID::R16G16_SINT: + return RG16I_to_R16G16_SINT; + default: + break; + } + break; + } + case GL_RG16UI: + { + switch (angleFormat) + { + case FormatID::R16G16_UINT: + return RG16UI_to_R16G16_UINT; + default: + break; + } + break; + } + case GL_RG16_EXT: + { + switch (angleFormat) + { + case FormatID::R16G16_UNORM: + return RG16_EXT_to_R16G16_UNORM; + default: + break; + } + break; + } + case GL_RG16_SNORM_EXT: + { + switch (angleFormat) + { + case FormatID::R16G16_SNORM: + return RG16_SNORM_EXT_to_R16G16_SNORM; + default: + break; + } + break; + } + case GL_RG16_SSCALED_ANGLEX: + return RG16_SSCALED_ANGLEX_to_default; + case GL_RG16_USCALED_ANGLEX: + return RG16_USCALED_ANGLEX_to_default; + case GL_RG32F: + { + switch (angleFormat) + { + case FormatID::R32G32_FLOAT: + return RG32F_to_R32G32_FLOAT; + default: + break; + } + break; + } + case GL_RG32I: + { + switch (angleFormat) + { + case FormatID::R32G32_SINT: + return RG32I_to_R32G32_SINT; + default: + break; + } + break; + } + case GL_RG32UI: + { + switch (angleFormat) + { + case FormatID::R32G32_UINT: + return RG32UI_to_R32G32_UINT; + default: + break; + } + break; + } + case GL_RG8: + { + switch (angleFormat) + { + case FormatID::R8G8_UNORM: + return RG8_to_R8G8_UNORM; + default: + break; + } + break; + } + case GL_RG8I: + { + switch (angleFormat) + { + case FormatID::R8G8_SINT: + return RG8I_to_R8G8_SINT; + default: + break; + } + break; + } + case GL_RG8UI: + { + switch (angleFormat) + { + case FormatID::R8G8_UINT: + return RG8UI_to_R8G8_UINT; + default: + break; + } + break; + } + case GL_RG8_SNORM: + { + switch (angleFormat) + { + case FormatID::R8G8_SNORM: + return RG8_SNORM_to_R8G8_SNORM; + default: + break; + } + break; + } + case GL_RG8_SSCALED_ANGLEX: + return RG8_SSCALED_ANGLEX_to_default; + case GL_RG8_USCALED_ANGLEX: + return RG8_USCALED_ANGLEX_to_default; + case GL_RGB: + return RGB_to_default; + case GL_RGB10_A2: + { + switch (angleFormat) + { + case FormatID::R10G10B10A2_UNORM: + return RGB10_A2_to_R10G10B10A2_UNORM; + default: + break; + } + break; + } + case GL_RGB10_A2UI: + { + switch (angleFormat) + { + case FormatID::R10G10B10A2_UINT: + return RGB10_A2UI_to_R10G10B10A2_UINT; + default: + break; + } + break; + } + case GL_RGB10_A2_SINT_ANGLEX: + { + switch (angleFormat) + { + case FormatID::R10G10B10A2_SINT: + return RGB10_A2_SINT_ANGLEX_to_R10G10B10A2_SINT; + default: + break; + } + break; + } + case GL_RGB10_A2_SNORM_ANGLEX: + { + switch (angleFormat) + { + case FormatID::R10G10B10A2_SNORM: + return RGB10_A2_SNORM_ANGLEX_to_R10G10B10A2_SNORM; + default: + break; + } + break; + } + case GL_RGB10_A2_SSCALED_ANGLEX: + return RGB10_A2_SSCALED_ANGLEX_to_default; + case GL_RGB10_A2_USCALED_ANGLEX: + return RGB10_A2_USCALED_ANGLEX_to_default; + case GL_RGB10_UNORM_ANGLEX: + { + switch (angleFormat) + { + case FormatID::R10G10B10A2_UNORM: + return RGB10_UNORM_ANGLEX_to_R10G10B10A2_UNORM; + case FormatID::R10G10B10X2_UNORM: + return RGB10_UNORM_ANGLEX_to_R10G10B10X2_UNORM; + default: + break; + } + break; + } + case GL_RGB16F: + { + switch (angleFormat) + { + case FormatID::R16G16B16A16_FLOAT: + return RGB16F_to_R16G16B16A16_FLOAT; + case FormatID::R16G16B16_FLOAT: + return RGB16F_to_R16G16B16_FLOAT; + default: + break; + } + break; + } + case GL_RGB16I: + { + switch (angleFormat) + { + case FormatID::R16G16B16A16_SINT: + return RGB16I_to_R16G16B16A16_SINT; + case FormatID::R16G16B16_SINT: + return RGB16I_to_R16G16B16_SINT; + default: + break; + } + break; + } + case GL_RGB16UI: + { + switch (angleFormat) + { + case FormatID::R16G16B16A16_UINT: + return RGB16UI_to_R16G16B16A16_UINT; + case FormatID::R16G16B16_UINT: + return RGB16UI_to_R16G16B16_UINT; + default: + break; + } + break; + } + case GL_RGB16_EXT: + { + switch (angleFormat) + { + case FormatID::R16G16B16A16_UNORM: + return RGB16_EXT_to_R16G16B16A16_UNORM; + case FormatID::R16G16B16_UNORM: + return RGB16_EXT_to_R16G16B16_UNORM; + default: + break; + } + break; + } + case GL_RGB16_SNORM_EXT: + { + switch (angleFormat) + { + case FormatID::R16G16B16A16_SNORM: + return RGB16_SNORM_EXT_to_R16G16B16A16_SNORM; + case FormatID::R16G16B16_SNORM: + return RGB16_SNORM_EXT_to_R16G16B16_SNORM; + default: + break; + } + break; + } + case GL_RGB16_SSCALED_ANGLEX: + return RGB16_SSCALED_ANGLEX_to_default; + case GL_RGB16_USCALED_ANGLEX: + return RGB16_USCALED_ANGLEX_to_default; + case GL_RGB32F: + { + switch (angleFormat) + { + case FormatID::R32G32B32A32_FLOAT: + return RGB32F_to_R32G32B32A32_FLOAT; + case FormatID::R32G32B32_FLOAT: + return RGB32F_to_R32G32B32_FLOAT; + default: + break; + } + break; + } + case GL_RGB32I: + { + switch (angleFormat) + { + case FormatID::R32G32B32A32_SINT: + return RGB32I_to_R32G32B32A32_SINT; + case FormatID::R32G32B32_SINT: + return RGB32I_to_R32G32B32_SINT; + default: + break; + } + break; + } + case GL_RGB32UI: + { + switch (angleFormat) + { + case FormatID::R32G32B32A32_UINT: + return RGB32UI_to_R32G32B32A32_UINT; + case FormatID::R32G32B32_UINT: + return RGB32UI_to_R32G32B32_UINT; + default: + break; + } + break; + } + case GL_RGB565: + { + switch (angleFormat) + { + case FormatID::B5G6R5_UNORM: + return RGB565_to_B5G6R5_UNORM; + case FormatID::R5G6B5_UNORM: + return RGB565_to_R5G6B5_UNORM; + case FormatID::R8G8B8A8_UNORM: + return RGB565_to_R8G8B8A8_UNORM; + default: + break; + } + break; + } + case GL_RGB5_A1: + { + switch (angleFormat) + { + case FormatID::A1R5G5B5_UNORM: + return RGB5_A1_to_A1R5G5B5_UNORM; + case FormatID::B5G5R5A1_UNORM: + return RGB5_A1_to_B5G5R5A1_UNORM; + case FormatID::R5G5B5A1_UNORM: + return RGB5_A1_to_R5G5B5A1_UNORM; + case FormatID::R8G8B8A8_UNORM: + return RGB5_A1_to_R8G8B8A8_UNORM; + default: + break; + } + break; + } + case GL_RGB8: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM: + return RGB8_to_R8G8B8A8_UNORM; + case FormatID::R8G8B8_UNORM: + return RGB8_to_R8G8B8_UNORM; + default: + break; + } + break; + } + case GL_RGB8I: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_SINT: + return RGB8I_to_R8G8B8A8_SINT; + case FormatID::R8G8B8_SINT: + return RGB8I_to_R8G8B8_SINT; + default: + break; + } + break; + } + case GL_RGB8UI: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UINT: + return RGB8UI_to_R8G8B8A8_UINT; + case FormatID::R8G8B8_UINT: + return RGB8UI_to_R8G8B8_UINT; + default: + break; + } + break; + } + case GL_RGB8_SNORM: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_SNORM: + return RGB8_SNORM_to_R8G8B8A8_SNORM; + case FormatID::R8G8B8_SNORM: + return RGB8_SNORM_to_R8G8B8_SNORM; + default: + break; + } + break; + } + case GL_RGB8_SSCALED_ANGLEX: + return RGB8_SSCALED_ANGLEX_to_default; + case GL_RGB8_USCALED_ANGLEX: + return RGB8_USCALED_ANGLEX_to_default; + case GL_RGB9_E5: + { + switch (angleFormat) + { + case FormatID::R9G9B9E5_SHAREDEXP: + return RGB9_E5_to_R9G9B9E5_SHAREDEXP; + default: + break; + } + break; + } + case GL_RGBA: + return RGBA_to_default; + case GL_RGBA16F: + { + switch (angleFormat) + { + case FormatID::R16G16B16A16_FLOAT: + return RGBA16F_to_R16G16B16A16_FLOAT; + default: + break; + } + break; + } + case GL_RGBA16I: + { + switch (angleFormat) + { + case FormatID::R16G16B16A16_SINT: + return RGBA16I_to_R16G16B16A16_SINT; + default: + break; + } + break; + } + case GL_RGBA16UI: + { + switch (angleFormat) + { + case FormatID::R16G16B16A16_UINT: + return RGBA16UI_to_R16G16B16A16_UINT; + default: + break; + } + break; + } + case GL_RGBA16_EXT: + { + switch (angleFormat) + { + case FormatID::R16G16B16A16_UNORM: + return RGBA16_EXT_to_R16G16B16A16_UNORM; + default: + break; + } + break; + } + case GL_RGBA16_SNORM_EXT: + { + switch (angleFormat) + { + case FormatID::R16G16B16A16_SNORM: + return RGBA16_SNORM_EXT_to_R16G16B16A16_SNORM; + default: + break; + } + break; + } + case GL_RGBA16_SSCALED_ANGLEX: + return RGBA16_SSCALED_ANGLEX_to_default; + case GL_RGBA16_USCALED_ANGLEX: + return RGBA16_USCALED_ANGLEX_to_default; + case GL_RGBA32F: + { + switch (angleFormat) + { + case FormatID::R32G32B32A32_FLOAT: + return RGBA32F_to_R32G32B32A32_FLOAT; + default: + break; + } + break; + } + case GL_RGBA32I: + { + switch (angleFormat) + { + case FormatID::R32G32B32A32_SINT: + return RGBA32I_to_R32G32B32A32_SINT; + default: + break; + } + break; + } + case GL_RGBA32UI: + { + switch (angleFormat) + { + case FormatID::R32G32B32A32_UINT: + return RGBA32UI_to_R32G32B32A32_UINT; + default: + break; + } + break; + } + case GL_RGBA4: + { + switch (angleFormat) + { + case FormatID::B4G4R4A4_UNORM: + return RGBA4_to_B4G4R4A4_UNORM; + case FormatID::R4G4B4A4_UNORM: + return RGBA4_to_R4G4B4A4_UNORM; + case FormatID::R8G8B8A8_UNORM: + return RGBA4_to_R8G8B8A8_UNORM; + default: + break; + } + break; + } + case GL_RGBA8: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM: + return RGBA8_to_R8G8B8A8_UNORM; + default: + break; + } + break; + } + case GL_RGBA8I: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_SINT: + return RGBA8I_to_R8G8B8A8_SINT; + default: + break; + } + break; + } + case GL_RGBA8UI: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UINT: + return RGBA8UI_to_R8G8B8A8_UINT; + default: + break; + } + break; + } + case GL_RGBA8_SNORM: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_SNORM: + return RGBA8_SNORM_to_R8G8B8A8_SNORM; + default: + break; + } + break; + } + case GL_RGBA8_SSCALED_ANGLEX: + return RGBA8_SSCALED_ANGLEX_to_default; + case GL_RGBA8_USCALED_ANGLEX: + return RGBA8_USCALED_ANGLEX_to_default; + case GL_RGBX8_ANGLE: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM: + return RGBX8_ANGLE_to_R8G8B8A8_UNORM; + case FormatID::R8G8B8X8_UNORM: + return RGBX8_ANGLE_to_R8G8B8X8_UNORM; + default: + break; + } + break; + } + case GL_SR8_EXT: + { + switch (angleFormat) + { + case FormatID::R8_UNORM_SRGB: + return SR8_EXT_to_R8_UNORM_SRGB; + default: + break; + } + break; + } + case GL_SRG8_EXT: + { + switch (angleFormat) + { + case FormatID::R8G8_UNORM_SRGB: + return SRG8_EXT_to_R8G8_UNORM_SRGB; + default: + break; + } + break; + } + case GL_SRGB8: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM_SRGB: + return SRGB8_to_R8G8B8A8_UNORM_SRGB; + case FormatID::R8G8B8_UNORM_SRGB: + return SRGB8_to_R8G8B8_UNORM_SRGB; + default: + break; + } + break; + } + case GL_SRGB8_ALPHA8: + { + switch (angleFormat) + { + case FormatID::R8G8B8A8_UNORM_SRGB: + return SRGB8_ALPHA8_to_R8G8B8A8_UNORM_SRGB; + default: + break; + } + break; + } + case GL_STENCIL_INDEX8: + { + switch (angleFormat) + { + case FormatID::S8_UINT: + return STENCIL_INDEX8_to_S8_UINT; + default: + return STENCIL_INDEX8_to_default; + } + } + + default: + break; + } + // clang-format on + ASSERT(internalFormat == GL_NONE || angleFormat == angle::FormatID::NONE); + static LoadFunctionMap emptyLoadFunctionsMap; + return emptyLoadFunctionsMap; + +} // GetLoadFunctionsMap + +} // namespace angle diff --git a/gfx/angle/checkout/src/libANGLE/renderer/renderer_utils.cpp b/gfx/angle/checkout/src/libANGLE/renderer/renderer_utils.cpp new file mode 100644 index 0000000000..152de2f25d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/renderer_utils.cpp @@ -0,0 +1,1583 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// renderer_utils: +// Helper methods pertaining to most or all back-ends. +// + +#include "libANGLE/renderer/renderer_utils.h" + +#include "common/string_utils.h" +#include "common/system_utils.h" +#include "common/utilities.h" +#include "image_util/copyimage.h" +#include "image_util/imageformats.h" +#include "libANGLE/AttributeMap.h" +#include "libANGLE/Context.h" +#include "libANGLE/Context.inl.h" +#include "libANGLE/Display.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/ContextImpl.h" +#include "libANGLE/renderer/Format.h" +#include "platform/Feature.h" + +#include +#include + +namespace angle +{ +namespace +{ +// For the sake of feature name matching, underscore is ignored, and the names are matched +// case-insensitive. This allows feature names to be overriden both in snake_case (previously used +// by ANGLE) and camelCase. The second string (user-provided name) can end in `*` for wildcard +// matching. +bool FeatureNameMatch(const std::string &a, const std::string &b) +{ + size_t ai = 0; + size_t bi = 0; + + while (ai < a.size() && bi < b.size()) + { + if (a[ai] == '_') + { + ++ai; + } + if (b[bi] == '_') + { + ++bi; + } + if (b[bi] == '*' && bi + 1 == b.size()) + { + // If selected feature name ends in wildcard, match it. + return true; + } + if (std::tolower(a[ai++]) != std::tolower(b[bi++])) + { + return false; + } + } + + return ai == a.size() && bi == b.size(); +} +} // anonymous namespace + +// FeatureSetBase implementation +void FeatureSetBase::overrideFeatures(const std::vector &featureNames, bool enabled) +{ + for (const std::string &name : featureNames) + { + const bool hasWildcard = name.back() == '*'; + for (auto iter : members) + { + const std::string &featureName = iter.first; + FeatureInfo *feature = iter.second; + + if (!FeatureNameMatch(featureName, name)) + { + continue; + } + + feature->enabled = enabled; + + // If name has a wildcard, try to match it with all features. Otherwise, bail on first + // match, as names are unique. + if (!hasWildcard) + { + break; + } + } + } +} + +void FeatureSetBase::populateFeatureList(FeatureList *features) const +{ + for (FeatureMap::const_iterator it = members.begin(); it != members.end(); it++) + { + features->push_back(it->second); + } +} +} // namespace angle + +namespace rx +{ + +namespace +{ +// Both D3D and Vulkan support the same set of standard sample positions for 1, 2, 4, 8, and 16 +// samples. See: +// +// - https://msdn.microsoft.com/en-us/library/windows/desktop/ff476218.aspx +// +// - +// https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#primsrast-multisampling +using SamplePositionsArray = std::array; +constexpr std::array kSamplePositions = { + {{{0.5f, 0.5f}}, + {{0.75f, 0.75f, 0.25f, 0.25f}}, + {{0.375f, 0.125f, 0.875f, 0.375f, 0.125f, 0.625f, 0.625f, 0.875f}}, + {{0.5625f, 0.3125f, 0.4375f, 0.6875f, 0.8125f, 0.5625f, 0.3125f, 0.1875f, 0.1875f, 0.8125f, + 0.0625f, 0.4375f, 0.6875f, 0.9375f, 0.9375f, 0.0625f}}, + {{0.5625f, 0.5625f, 0.4375f, 0.3125f, 0.3125f, 0.625f, 0.75f, 0.4375f, + 0.1875f, 0.375f, 0.625f, 0.8125f, 0.8125f, 0.6875f, 0.6875f, 0.1875f, + 0.375f, 0.875f, 0.5f, 0.0625f, 0.25f, 0.125f, 0.125f, 0.75f, + 0.0f, 0.5f, 0.9375f, 0.25f, 0.875f, 0.9375f, 0.0625f, 0.0f}}}}; + +struct IncompleteTextureParameters +{ + GLenum sizedInternalFormat; + GLenum format; + GLenum type; + GLubyte clearColor[4]; +}; + +// Note that for gl::SamplerFormat::Shadow, the clearColor datatype needs to be GLushort and as such +// we will reinterpret GLubyte[4] as GLushort[2]. +constexpr angle::PackedEnumMap + kIncompleteTextureParameters = { + {gl::SamplerFormat::Float, {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, {0, 0, 0, 255}}}, + {gl::SamplerFormat::Unsigned, + {GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, {0, 0, 0, 255}}}, + {gl::SamplerFormat::Signed, {GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE, {0, 0, 0, 127}}}, + {gl::SamplerFormat::Shadow, + {GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, {0, 0, 0, 0}}}}; + +void CopyColor(gl::ColorF *color) +{ + // No-op +} + +void PremultiplyAlpha(gl::ColorF *color) +{ + color->red *= color->alpha; + color->green *= color->alpha; + color->blue *= color->alpha; +} + +void UnmultiplyAlpha(gl::ColorF *color) +{ + if (color->alpha != 0.0f) + { + float invAlpha = 1.0f / color->alpha; + color->red *= invAlpha; + color->green *= invAlpha; + color->blue *= invAlpha; + } +} + +void ClipChannelsR(gl::ColorF *color) +{ + color->green = 0.0f; + color->blue = 0.0f; + color->alpha = 1.0f; +} + +void ClipChannelsRG(gl::ColorF *color) +{ + color->blue = 0.0f; + color->alpha = 1.0f; +} + +void ClipChannelsRGB(gl::ColorF *color) +{ + color->alpha = 1.0f; +} + +void ClipChannelsLuminance(gl::ColorF *color) +{ + color->alpha = 1.0f; +} + +void ClipChannelsAlpha(gl::ColorF *color) +{ + color->red = 0.0f; + color->green = 0.0f; + color->blue = 0.0f; +} + +void ClipChannelsNoOp(gl::ColorF *color) {} + +void WriteUintColor(const gl::ColorF &color, + PixelWriteFunction colorWriteFunction, + uint8_t *destPixelData) +{ + gl::ColorUI destColor( + static_cast(color.red * 255), static_cast(color.green * 255), + static_cast(color.blue * 255), static_cast(color.alpha * 255)); + colorWriteFunction(reinterpret_cast(&destColor), destPixelData); +} + +void WriteFloatColor(const gl::ColorF &color, + PixelWriteFunction colorWriteFunction, + uint8_t *destPixelData) +{ + colorWriteFunction(reinterpret_cast(&color), destPixelData); +} + +template +inline int GetFlattenedIndex(int col, int row) +{ + if (IsColumnMajor) + { + return col * rows + row; + } + else + { + return row * cols + col; + } +} + +template +void ExpandMatrix(T *target, const GLfloat *value) +{ + static_assert(colsSrc <= colsDst && rowsSrc <= rowsDst, "Can only expand!"); + + constexpr int kDstFlatSize = colsDst * rowsDst; + T staging[kDstFlatSize] = {0}; + + for (int r = 0; r < rowsSrc; r++) + { + for (int c = 0; c < colsSrc; c++) + { + int srcIndex = GetFlattenedIndex(c, r); + int dstIndex = GetFlattenedIndex(c, r); + + staging[dstIndex] = static_cast(value[srcIndex]); + } + } + + memcpy(target, staging, kDstFlatSize * sizeof(T)); +} + +template +void SetFloatUniformMatrix(unsigned int arrayElementOffset, + unsigned int elementCount, + GLsizei countIn, + const GLfloat *value, + uint8_t *targetData) +{ + unsigned int count = + std::min(elementCount - arrayElementOffset, static_cast(countIn)); + + const unsigned int targetMatrixStride = colsDst * rowsDst; + GLfloat *target = reinterpret_cast( + targetData + arrayElementOffset * sizeof(GLfloat) * targetMatrixStride); + + for (unsigned int i = 0; i < count; i++) + { + ExpandMatrix(target, value); + + target += targetMatrixStride; + value += colsSrc * rowsSrc; + } +} + +void SetFloatUniformMatrixFast(unsigned int arrayElementOffset, + unsigned int elementCount, + GLsizei countIn, + size_t matrixSize, + const GLfloat *value, + uint8_t *targetData) +{ + const unsigned int count = + std::min(elementCount - arrayElementOffset, static_cast(countIn)); + + const uint8_t *valueData = reinterpret_cast(value); + targetData = targetData + arrayElementOffset * matrixSize; + + memcpy(targetData, valueData, matrixSize * count); +} +} // anonymous namespace + +bool IsRotatedAspectRatio(SurfaceRotation rotation) +{ + switch (rotation) + { + case SurfaceRotation::Rotated90Degrees: + case SurfaceRotation::Rotated270Degrees: + case SurfaceRotation::FlippedRotated90Degrees: + case SurfaceRotation::FlippedRotated270Degrees: + return true; + default: + return false; + } +} + +void RotateRectangle(const SurfaceRotation rotation, + const bool flipY, + const int framebufferWidth, + const int framebufferHeight, + const gl::Rectangle &incoming, + gl::Rectangle *outgoing) +{ + // GLES's y-axis points up; Vulkan's points down. + switch (rotation) + { + case SurfaceRotation::Identity: + // Do not rotate gl_Position (surface matches the device's orientation): + outgoing->x = incoming.x; + outgoing->y = flipY ? framebufferHeight - incoming.y - incoming.height : incoming.y; + outgoing->width = incoming.width; + outgoing->height = incoming.height; + break; + case SurfaceRotation::Rotated90Degrees: + // Rotate gl_Position 90 degrees: + outgoing->x = incoming.y; + outgoing->y = flipY ? incoming.x : framebufferWidth - incoming.x - incoming.width; + outgoing->width = incoming.height; + outgoing->height = incoming.width; + break; + case SurfaceRotation::Rotated180Degrees: + // Rotate gl_Position 180 degrees: + outgoing->x = framebufferWidth - incoming.x - incoming.width; + outgoing->y = flipY ? incoming.y : framebufferHeight - incoming.y - incoming.height; + outgoing->width = incoming.width; + outgoing->height = incoming.height; + break; + case SurfaceRotation::Rotated270Degrees: + // Rotate gl_Position 270 degrees: + outgoing->x = framebufferHeight - incoming.y - incoming.height; + outgoing->y = flipY ? framebufferWidth - incoming.x - incoming.width : incoming.x; + outgoing->width = incoming.height; + outgoing->height = incoming.width; + break; + default: + UNREACHABLE(); + break; + } +} + +PackPixelsParams::PackPixelsParams() + : destFormat(nullptr), + outputPitch(0), + packBuffer(nullptr), + offset(0), + rotation(SurfaceRotation::Identity) +{} + +PackPixelsParams::PackPixelsParams(const gl::Rectangle &areaIn, + const angle::Format &destFormat, + GLuint outputPitchIn, + bool reverseRowOrderIn, + gl::Buffer *packBufferIn, + ptrdiff_t offsetIn) + : area(areaIn), + destFormat(&destFormat), + outputPitch(outputPitchIn), + packBuffer(packBufferIn), + reverseRowOrder(reverseRowOrderIn), + offset(offsetIn), + rotation(SurfaceRotation::Identity) +{} + +void PackPixels(const PackPixelsParams ¶ms, + const angle::Format &sourceFormat, + int inputPitchIn, + const uint8_t *sourceIn, + uint8_t *destWithoutOffset) +{ + uint8_t *destWithOffset = destWithoutOffset + params.offset; + + const uint8_t *source = sourceIn; + int inputPitch = inputPitchIn; + int destWidth = params.area.width; + int destHeight = params.area.height; + int xAxisPitch = 0; + int yAxisPitch = 0; + switch (params.rotation) + { + case SurfaceRotation::Identity: + // The source image is not rotated (i.e. matches the device's orientation), and may or + // may not be y-flipped. The image is row-major. Each source row (one step along the + // y-axis for each step in the dest y-axis) is inputPitch past the previous row. Along + // a row, each source pixel (one step along the x-axis for each step in the dest + // x-axis) is sourceFormat.pixelBytes past the previous pixel. + xAxisPitch = sourceFormat.pixelBytes; + if (params.reverseRowOrder) + { + // The source image is y-flipped, which means we start at the last row, and each + // source row is BEFORE the previous row. + source += inputPitchIn * (params.area.height - 1); + inputPitch = -inputPitch; + yAxisPitch = -inputPitchIn; + } + else + { + yAxisPitch = inputPitchIn; + } + break; + case SurfaceRotation::Rotated90Degrees: + // The source image is rotated 90 degrees counter-clockwise. Y-flip is always applied + // to rotated images. The image is column-major. Each source column (one step along + // the source x-axis for each step in the dest y-axis) is inputPitch past the previous + // column. Along a column, each source pixel (one step along the y-axis for each step + // in the dest x-axis) is sourceFormat.pixelBytes past the previous pixel. + xAxisPitch = inputPitchIn; + yAxisPitch = sourceFormat.pixelBytes; + destWidth = params.area.height; + destHeight = params.area.width; + break; + case SurfaceRotation::Rotated180Degrees: + // The source image is rotated 180 degrees. Y-flip is always applied to rotated + // images. The image is row-major, but upside down. Each source row (one step along + // the y-axis for each step in the dest y-axis) is inputPitch after the previous row. + // Along a row, each source pixel (one step along the x-axis for each step in the dest + // x-axis) is sourceFormat.pixelBytes BEFORE the previous pixel. + xAxisPitch = -static_cast(sourceFormat.pixelBytes); + yAxisPitch = inputPitchIn; + source += sourceFormat.pixelBytes * (params.area.width - 1); + break; + case SurfaceRotation::Rotated270Degrees: + // The source image is rotated 270 degrees counter-clockwise (or 90 degrees clockwise). + // Y-flip is always applied to rotated images. The image is column-major, where each + // column (one step in the source x-axis for one step in the dest y-axis) is inputPitch + // BEFORE the previous column. Along a column, each source pixel (one step along the + // y-axis for each step in the dest x-axis) is sourceFormat.pixelBytes BEFORE the + // previous pixel. The first pixel is at the end of the source. + xAxisPitch = -inputPitchIn; + yAxisPitch = -static_cast(sourceFormat.pixelBytes); + destWidth = params.area.height; + destHeight = params.area.width; + source += inputPitch * (params.area.height - 1) + + sourceFormat.pixelBytes * (params.area.width - 1); + break; + default: + UNREACHABLE(); + break; + } + + if (params.rotation == SurfaceRotation::Identity && sourceFormat == *params.destFormat) + { + // Direct copy possible + for (int y = 0; y < params.area.height; ++y) + { + memcpy(destWithOffset + y * params.outputPitch, source + y * inputPitch, + params.area.width * sourceFormat.pixelBytes); + } + return; + } + + FastCopyFunction fastCopyFunc = sourceFormat.fastCopyFunctions.get(params.destFormat->id); + + if (fastCopyFunc) + { + // Fast copy is possible through some special function + fastCopyFunc(source, xAxisPitch, yAxisPitch, destWithOffset, params.destFormat->pixelBytes, + params.outputPitch, destWidth, destHeight); + return; + } + + PixelWriteFunction pixelWriteFunction = params.destFormat->pixelWriteFunction; + ASSERT(pixelWriteFunction != nullptr); + + // Maximum size of any Color type used. + uint8_t temp[16]; + static_assert(sizeof(temp) >= sizeof(gl::ColorF) && sizeof(temp) >= sizeof(gl::ColorUI) && + sizeof(temp) >= sizeof(gl::ColorI) && + sizeof(temp) >= sizeof(angle::DepthStencil), + "Unexpected size of pixel struct."); + + PixelReadFunction pixelReadFunction = sourceFormat.pixelReadFunction; + ASSERT(pixelReadFunction != nullptr); + + for (int y = 0; y < destHeight; ++y) + { + for (int x = 0; x < destWidth; ++x) + { + uint8_t *dest = + destWithOffset + y * params.outputPitch + x * params.destFormat->pixelBytes; + const uint8_t *src = source + y * yAxisPitch + x * xAxisPitch; + + // readFunc and writeFunc will be using the same type of color, CopyTexImage + // will not allow the copy otherwise. + pixelReadFunction(src, temp); + pixelWriteFunction(temp, dest); + } + } +} + +bool FastCopyFunctionMap::has(angle::FormatID formatID) const +{ + return (get(formatID) != nullptr); +} + +namespace +{ + +const FastCopyFunctionMap::Entry *getEntry(const FastCopyFunctionMap::Entry *entry, + size_t numEntries, + angle::FormatID formatID) +{ + const FastCopyFunctionMap::Entry *end = entry + numEntries; + while (entry != end) + { + if (entry->formatID == formatID) + { + return entry; + } + ++entry; + } + + return nullptr; +} + +} // namespace + +FastCopyFunction FastCopyFunctionMap::get(angle::FormatID formatID) const +{ + const FastCopyFunctionMap::Entry *entry = getEntry(mData, mSize, formatID); + return entry ? entry->func : nullptr; +} + +bool ShouldUseDebugLayers(const egl::AttributeMap &attribs) +{ + EGLAttrib debugSetting = + attribs.get(EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE, EGL_DONT_CARE); + + // Prefer to enable debug layers when available. +#if defined(ANGLE_ENABLE_ASSERTS) + return (debugSetting != EGL_FALSE); +#else + return (debugSetting == EGL_TRUE); +#endif // defined(ANGLE_ENABLE_ASSERTS) +} + +void CopyImageCHROMIUM(const uint8_t *sourceData, + size_t sourceRowPitch, + size_t sourcePixelBytes, + size_t sourceDepthPitch, + PixelReadFunction pixelReadFunction, + uint8_t *destData, + size_t destRowPitch, + size_t destPixelBytes, + size_t destDepthPitch, + PixelWriteFunction pixelWriteFunction, + GLenum destUnsizedFormat, + GLenum destComponentType, + size_t width, + size_t height, + size_t depth, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) +{ + using ConversionFunction = void (*)(gl::ColorF *); + ConversionFunction conversionFunction = CopyColor; + if (unpackPremultiplyAlpha != unpackUnmultiplyAlpha) + { + if (unpackPremultiplyAlpha) + { + conversionFunction = PremultiplyAlpha; + } + else + { + conversionFunction = UnmultiplyAlpha; + } + } + + auto clipChannelsFunction = ClipChannelsNoOp; + switch (destUnsizedFormat) + { + case GL_RED: + clipChannelsFunction = ClipChannelsR; + break; + case GL_RG: + clipChannelsFunction = ClipChannelsRG; + break; + case GL_RGB: + clipChannelsFunction = ClipChannelsRGB; + break; + case GL_LUMINANCE: + clipChannelsFunction = ClipChannelsLuminance; + break; + case GL_ALPHA: + clipChannelsFunction = ClipChannelsAlpha; + break; + } + + auto writeFunction = (destComponentType == GL_UNSIGNED_INT) ? WriteUintColor : WriteFloatColor; + + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + for (size_t x = 0; x < width; x++) + { + const uint8_t *sourcePixelData = + sourceData + y * sourceRowPitch + x * sourcePixelBytes + z * sourceDepthPitch; + + gl::ColorF sourceColor; + pixelReadFunction(sourcePixelData, reinterpret_cast(&sourceColor)); + + conversionFunction(&sourceColor); + clipChannelsFunction(&sourceColor); + + size_t destY = 0; + if (unpackFlipY) + { + destY += (height - 1); + destY -= y; + } + else + { + destY += y; + } + + uint8_t *destPixelData = + destData + destY * destRowPitch + x * destPixelBytes + z * destDepthPitch; + writeFunction(sourceColor, pixelWriteFunction, destPixelData); + } + } + } +} + +// IncompleteTextureSet implementation. +IncompleteTextureSet::IncompleteTextureSet() : mIncompleteTextureBufferAttachment(nullptr) {} + +IncompleteTextureSet::~IncompleteTextureSet() {} + +void IncompleteTextureSet::onDestroy(const gl::Context *context) +{ + // Clear incomplete textures. + for (auto &incompleteTextures : mIncompleteTextures) + { + for (auto &incompleteTexture : incompleteTextures) + { + if (incompleteTexture.get() != nullptr) + { + incompleteTexture->onDestroy(context); + incompleteTexture.set(context, nullptr); + } + } + } + if (mIncompleteTextureBufferAttachment != nullptr) + { + mIncompleteTextureBufferAttachment->onDestroy(context); + mIncompleteTextureBufferAttachment = nullptr; + } +} + +angle::Result IncompleteTextureSet::getIncompleteTexture( + const gl::Context *context, + gl::TextureType type, + gl::SamplerFormat format, + MultisampleTextureInitializer *multisampleInitializer, + gl::Texture **textureOut) +{ + *textureOut = mIncompleteTextures[format][type].get(); + if (*textureOut != nullptr) + { + return angle::Result::Continue; + } + + ContextImpl *implFactory = context->getImplementation(); + + gl::Extents colorSize(1, 1, 1); + gl::PixelUnpackState unpack; + unpack.alignment = 1; + gl::Box area(0, 0, 0, 1, 1, 1); + const IncompleteTextureParameters &incompleteTextureParam = + kIncompleteTextureParameters[format]; + + // Cube map arrays are expected to have layer counts that are multiples of 6 + constexpr int kCubeMapArraySize = 6; + if (type == gl::TextureType::CubeMapArray) + { + // From the GLES 3.2 spec: + // 8.18. IMMUTABLE-FORMAT TEXTURE IMAGES + // TexStorage3D Errors + // An INVALID_OPERATION error is generated if any of the following conditions hold: + // * target is TEXTURE_CUBE_MAP_ARRAY and depth is not a multiple of 6 + // Since ANGLE treats incomplete textures as immutable, respect that here. + colorSize.depth = kCubeMapArraySize; + area.depth = kCubeMapArraySize; + } + + // If a texture is external use a 2D texture for the incomplete texture + gl::TextureType createType = (type == gl::TextureType::External) ? gl::TextureType::_2D : type; + + gl::Texture *tex = + new gl::Texture(implFactory, {std::numeric_limits::max()}, createType); + angle::UniqueObjectPointer t(tex, context); + + // This is a bit of a kludge but is necessary to consume the error. + gl::Context *mutableContext = const_cast(context); + + if (createType == gl::TextureType::Buffer) + { + constexpr uint32_t kBufferInitData = 0; + mIncompleteTextureBufferAttachment = + new gl::Buffer(implFactory, {std::numeric_limits::max()}); + ANGLE_TRY(mIncompleteTextureBufferAttachment->bufferData( + mutableContext, gl::BufferBinding::Texture, &kBufferInitData, sizeof(kBufferInitData), + gl::BufferUsage::StaticDraw)); + } + else if (createType == gl::TextureType::_2DMultisample) + { + ANGLE_TRY(t->setStorageMultisample(mutableContext, createType, 1, + incompleteTextureParam.sizedInternalFormat, colorSize, + true)); + } + else + { + ANGLE_TRY(t->setStorage(mutableContext, createType, 1, + incompleteTextureParam.sizedInternalFormat, colorSize)); + } + + if (type == gl::TextureType::CubeMap) + { + for (gl::TextureTarget face : gl::AllCubeFaceTextureTargets()) + { + ANGLE_TRY(t->setSubImage(mutableContext, unpack, nullptr, face, 0, area, + incompleteTextureParam.format, incompleteTextureParam.type, + incompleteTextureParam.clearColor)); + } + } + else if (type == gl::TextureType::CubeMapArray) + { + // We need to provide enough pixel data to fill the array of six faces + GLubyte incompleteCubeArrayPixels[kCubeMapArraySize][4]; + for (int i = 0; i < kCubeMapArraySize; ++i) + { + incompleteCubeArrayPixels[i][0] = incompleteTextureParam.clearColor[0]; + incompleteCubeArrayPixels[i][1] = incompleteTextureParam.clearColor[1]; + incompleteCubeArrayPixels[i][2] = incompleteTextureParam.clearColor[2]; + incompleteCubeArrayPixels[i][3] = incompleteTextureParam.clearColor[3]; + } + + ANGLE_TRY(t->setSubImage(mutableContext, unpack, nullptr, + gl::NonCubeTextureTypeToTarget(createType), 0, area, + incompleteTextureParam.format, incompleteTextureParam.type, + *incompleteCubeArrayPixels)); + } + else if (type == gl::TextureType::_2DMultisample) + { + // Call a specialized clear function to init a multisample texture. + ANGLE_TRY(multisampleInitializer->initializeMultisampleTextureToBlack(context, t.get())); + } + else if (type == gl::TextureType::Buffer) + { + ANGLE_TRY(t->setBuffer(context, mIncompleteTextureBufferAttachment, + incompleteTextureParam.sizedInternalFormat)); + } + else + { + ANGLE_TRY(t->setSubImage(mutableContext, unpack, nullptr, + gl::NonCubeTextureTypeToTarget(createType), 0, area, + incompleteTextureParam.format, incompleteTextureParam.type, + incompleteTextureParam.clearColor)); + } + + if (format == gl::SamplerFormat::Shadow) + { + // To avoid the undefined spec behavior for shadow samplers with a depth texture, we set the + // compare mode to GL_COMPARE_REF_TO_TEXTURE + ASSERT(!t->hasObservers()); + t->setCompareMode(context, GL_COMPARE_REF_TO_TEXTURE); + } + + ANGLE_TRY(t->syncState(context, gl::Command::Other)); + + mIncompleteTextures[format][type].set(context, t.release()); + *textureOut = mIncompleteTextures[format][type].get(); + return angle::Result::Continue; +} + +#define ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(api, cols, rows) \ + template void SetFloatUniformMatrix##api::Run( \ + unsigned int, unsigned int, GLsizei, GLboolean, const GLfloat *, uint8_t *) + +ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(GLSL, 2, 2); +ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(GLSL, 3, 3); +ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(GLSL, 2, 3); +ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(GLSL, 3, 2); +ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(GLSL, 4, 2); +ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(GLSL, 4, 3); + +ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(HLSL, 2, 2); +ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(HLSL, 3, 3); +ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(HLSL, 2, 3); +ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(HLSL, 3, 2); +ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(HLSL, 2, 4); +ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(HLSL, 3, 4); + +#undef ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC + +#define ANGLE_SPECIALIZATION_ROWS_SET_UNIFORM_MATRIX_FUNC(api, cols, rows) \ + template void SetFloatUniformMatrix##api::Run(unsigned int, unsigned int, GLsizei, \ + GLboolean, const GLfloat *, uint8_t *) + +template +struct SetFloatUniformMatrixGLSL +{ + static void Run(unsigned int arrayElementOffset, + unsigned int elementCount, + GLsizei countIn, + GLboolean transpose, + const GLfloat *value, + uint8_t *targetData); +}; + +ANGLE_SPECIALIZATION_ROWS_SET_UNIFORM_MATRIX_FUNC(GLSL, 2, 4); +ANGLE_SPECIALIZATION_ROWS_SET_UNIFORM_MATRIX_FUNC(GLSL, 3, 4); +ANGLE_SPECIALIZATION_ROWS_SET_UNIFORM_MATRIX_FUNC(GLSL, 4, 4); + +#undef ANGLE_SPECIALIZATION_ROWS_SET_UNIFORM_MATRIX_FUNC + +#define ANGLE_SPECIALIZATION_COLS_SET_UNIFORM_MATRIX_FUNC(api, cols, rows) \ + template void SetFloatUniformMatrix##api<4, rows>::Run(unsigned int, unsigned int, GLsizei, \ + GLboolean, const GLfloat *, uint8_t *) + +template +struct SetFloatUniformMatrixHLSL<4, rows> +{ + static void Run(unsigned int arrayElementOffset, + unsigned int elementCount, + GLsizei countIn, + GLboolean transpose, + const GLfloat *value, + uint8_t *targetData); +}; + +ANGLE_SPECIALIZATION_COLS_SET_UNIFORM_MATRIX_FUNC(HLSL, 4, 2); +ANGLE_SPECIALIZATION_COLS_SET_UNIFORM_MATRIX_FUNC(HLSL, 4, 3); +ANGLE_SPECIALIZATION_COLS_SET_UNIFORM_MATRIX_FUNC(HLSL, 4, 4); + +#undef ANGLE_SPECIALIZATION_COLS_SET_UNIFORM_MATRIX_FUNC + +template +void SetFloatUniformMatrixGLSL::Run(unsigned int arrayElementOffset, + unsigned int elementCount, + GLsizei countIn, + GLboolean transpose, + const GLfloat *value, + uint8_t *targetData) +{ + const bool isSrcColumnMajor = !transpose; + if (isSrcColumnMajor) + { + // Both src and dst matrixs are has same layout, + // a single memcpy updates all the matrices + constexpr size_t srcMatrixSize = sizeof(GLfloat) * cols * 4; + SetFloatUniformMatrixFast(arrayElementOffset, elementCount, countIn, srcMatrixSize, value, + targetData); + } + else + { + // fallback to general cases + SetFloatUniformMatrix(arrayElementOffset, elementCount, + countIn, value, targetData); + } +} + +template +void SetFloatUniformMatrixGLSL::Run(unsigned int arrayElementOffset, + unsigned int elementCount, + GLsizei countIn, + GLboolean transpose, + const GLfloat *value, + uint8_t *targetData) +{ + const bool isSrcColumnMajor = !transpose; + // GLSL expects matrix uniforms to be column-major, and each column is padded to 4 rows. + if (isSrcColumnMajor) + { + SetFloatUniformMatrix(arrayElementOffset, elementCount, + countIn, value, targetData); + } + else + { + SetFloatUniformMatrix(arrayElementOffset, elementCount, + countIn, value, targetData); + } +} + +template +void SetFloatUniformMatrixHLSL<4, rows>::Run(unsigned int arrayElementOffset, + unsigned int elementCount, + GLsizei countIn, + GLboolean transpose, + const GLfloat *value, + uint8_t *targetData) +{ + const bool isSrcColumnMajor = !transpose; + if (!isSrcColumnMajor) + { + // Both src and dst matrixs are has same layout, + // a single memcpy updates all the matrices + constexpr size_t srcMatrixSize = sizeof(GLfloat) * 4 * rows; + SetFloatUniformMatrixFast(arrayElementOffset, elementCount, countIn, srcMatrixSize, value, + targetData); + } + else + { + // fallback to general cases + SetFloatUniformMatrix(arrayElementOffset, elementCount, + countIn, value, targetData); + } +} + +template +void SetFloatUniformMatrixHLSL::Run(unsigned int arrayElementOffset, + unsigned int elementCount, + GLsizei countIn, + GLboolean transpose, + const GLfloat *value, + uint8_t *targetData) +{ + const bool isSrcColumnMajor = !transpose; + // Internally store matrices as row-major to accomodate HLSL matrix indexing. Each row is + // padded to 4 columns. + if (!isSrcColumnMajor) + { + SetFloatUniformMatrix(arrayElementOffset, elementCount, + countIn, value, targetData); + } + else + { + SetFloatUniformMatrix(arrayElementOffset, elementCount, + countIn, value, targetData); + } +} + +template void GetMatrixUniform(GLenum, GLint *, const GLint *, bool); +template void GetMatrixUniform(GLenum, GLuint *, const GLuint *, bool); + +void GetMatrixUniform(GLenum type, GLfloat *dataOut, const GLfloat *source, bool transpose) +{ + int columns = gl::VariableColumnCount(type); + int rows = gl::VariableRowCount(type); + for (GLint col = 0; col < columns; ++col) + { + for (GLint row = 0; row < rows; ++row) + { + GLfloat *outptr = dataOut + ((col * rows) + row); + const GLfloat *inptr = + transpose ? source + ((row * 4) + col) : source + ((col * 4) + row); + *outptr = *inptr; + } + } +} + +template +void GetMatrixUniform(GLenum type, NonFloatT *dataOut, const NonFloatT *source, bool transpose) +{ + UNREACHABLE(); +} + +const angle::Format &GetFormatFromFormatType(GLenum format, GLenum type) +{ + GLenum sizedInternalFormat = gl::GetInternalFormatInfo(format, type).sizedInternalFormat; + angle::FormatID angleFormatID = angle::Format::InternalFormatToID(sizedInternalFormat); + return angle::Format::Get(angleFormatID); +} + +angle::Result ComputeStartVertex(ContextImpl *contextImpl, + const gl::IndexRange &indexRange, + GLint baseVertex, + GLint *firstVertexOut) +{ + // The entire index range should be within the limits of a 32-bit uint because the largest + // GL index type is GL_UNSIGNED_INT. + ASSERT(indexRange.start <= std::numeric_limits::max() && + indexRange.end <= std::numeric_limits::max()); + + // The base vertex is only used in DrawElementsIndirect. Given the assertion above and the + // type of mBaseVertex (GLint), adding them both as 64-bit ints is safe. + int64_t startVertexInt64 = + static_cast(baseVertex) + static_cast(indexRange.start); + + // OpenGL ES 3.2 spec section 10.5: "Behavior of DrawElementsOneInstance is undefined if the + // vertex ID is negative for any element" + ANGLE_CHECK_GL_MATH(contextImpl, startVertexInt64 >= 0); + + // OpenGL ES 3.2 spec section 10.5: "If the vertex ID is larger than the maximum value + // representable by type, it should behave as if the calculation were upconverted to 32-bit + // unsigned integers(with wrapping on overflow conditions)." ANGLE does not fully handle + // these rules, an overflow error is returned if the start vertex cannot be stored in a + // 32-bit signed integer. + ANGLE_CHECK_GL_MATH(contextImpl, startVertexInt64 <= std::numeric_limits::max()); + + *firstVertexOut = static_cast(startVertexInt64); + return angle::Result::Continue; +} + +angle::Result GetVertexRangeInfo(const gl::Context *context, + GLint firstVertex, + GLsizei vertexOrIndexCount, + gl::DrawElementsType indexTypeOrInvalid, + const void *indices, + GLint baseVertex, + GLint *startVertexOut, + size_t *vertexCountOut) +{ + if (indexTypeOrInvalid != gl::DrawElementsType::InvalidEnum) + { + gl::IndexRange indexRange; + ANGLE_TRY(context->getState().getVertexArray()->getIndexRange( + context, indexTypeOrInvalid, vertexOrIndexCount, indices, &indexRange)); + ANGLE_TRY(ComputeStartVertex(context->getImplementation(), indexRange, baseVertex, + startVertexOut)); + *vertexCountOut = indexRange.vertexCount(); + } + else + { + *startVertexOut = firstVertex; + *vertexCountOut = vertexOrIndexCount; + } + return angle::Result::Continue; +} + +gl::Rectangle ClipRectToScissor(const gl::State &glState, const gl::Rectangle &rect, bool invertY) +{ + // If the scissor test isn't enabled, assume it has infinite size. Its intersection with the + // rect would be the rect itself. + // + // Note that on Vulkan, returning this (as opposed to a fixed max-int-sized rect) could lead to + // unnecessary pipeline creations if two otherwise identical pipelines are used on framebuffers + // with different sizes. If such usage is observed in an application, we should investigate + // possible optimizations. + if (!glState.isScissorTestEnabled()) + { + return rect; + } + + gl::Rectangle clippedRect; + if (!gl::ClipRectangle(glState.getScissor(), rect, &clippedRect)) + { + return gl::Rectangle(); + } + + if (invertY) + { + clippedRect.y = rect.height - clippedRect.y - clippedRect.height; + } + + return clippedRect; +} + +void LogFeatureStatus(const angle::FeatureSetBase &features, + const std::vector &featureNames, + bool enabled) +{ + for (const std::string &name : featureNames) + { + const bool hasWildcard = name.back() == '*'; + for (auto iter : features.getFeatures()) + { + const std::string &featureName = iter.first; + + if (!angle::FeatureNameMatch(featureName, name)) + { + continue; + } + + INFO() << "Feature: " << featureName << (enabled ? " enabled" : " disabled"); + + if (!hasWildcard) + { + break; + } + } + } +} + +void ApplyFeatureOverrides(angle::FeatureSetBase *features, const egl::DisplayState &state) +{ + features->overrideFeatures(state.featureOverridesEnabled, true); + features->overrideFeatures(state.featureOverridesDisabled, false); + + // Override with environment as well. + constexpr char kAngleFeatureOverridesEnabledEnvName[] = "ANGLE_FEATURE_OVERRIDES_ENABLED"; + constexpr char kAngleFeatureOverridesDisabledEnvName[] = "ANGLE_FEATURE_OVERRIDES_DISABLED"; + constexpr char kAngleFeatureOverridesEnabledPropertyName[] = + "debug.angle.feature_overrides_enabled"; + constexpr char kAngleFeatureOverridesDisabledPropertyName[] = + "debug.angle.feature_overrides_disabled"; + std::vector overridesEnabled = + angle::GetCachedStringsFromEnvironmentVarOrAndroidProperty( + kAngleFeatureOverridesEnabledEnvName, kAngleFeatureOverridesEnabledPropertyName, ":"); + std::vector overridesDisabled = + angle::GetCachedStringsFromEnvironmentVarOrAndroidProperty( + kAngleFeatureOverridesDisabledEnvName, kAngleFeatureOverridesDisabledPropertyName, ":"); + + features->overrideFeatures(overridesEnabled, true); + LogFeatureStatus(*features, overridesEnabled, true); + + features->overrideFeatures(overridesDisabled, false); + LogFeatureStatus(*features, overridesDisabled, false); +} + +void GetSamplePosition(GLsizei sampleCount, size_t index, GLfloat *xy) +{ + ASSERT(gl::isPow2(sampleCount)); + if (sampleCount > 16) + { + // Vulkan (and D3D11) doesn't have standard sample positions for 32 and 64 samples (and no + // drivers are known to support that many samples) + xy[0] = 0.5f; + xy[1] = 0.5f; + } + else + { + size_t indexKey = static_cast(gl::log2(sampleCount)); + ASSERT(indexKey < kSamplePositions.size() && + (2 * index + 1) < kSamplePositions[indexKey].size()); + + xy[0] = kSamplePositions[indexKey][2 * index]; + xy[1] = kSamplePositions[indexKey][2 * index + 1]; + } +} + +// These macros are to avoid code too much duplication for variations of multi draw types +#define DRAW_ARRAYS__ contextImpl->drawArrays(context, mode, firsts[drawID], counts[drawID]) +#define DRAW_ARRAYS_INSTANCED_ \ + contextImpl->drawArraysInstanced(context, mode, firsts[drawID], counts[drawID], \ + instanceCounts[drawID]) +#define DRAW_ELEMENTS__ \ + contextImpl->drawElements(context, mode, counts[drawID], type, indices[drawID]) +#define DRAW_ELEMENTS_INSTANCED_ \ + contextImpl->drawElementsInstanced(context, mode, counts[drawID], type, indices[drawID], \ + instanceCounts[drawID]) +#define DRAW_ARRAYS_INSTANCED_BASE_INSTANCE \ + contextImpl->drawArraysInstancedBaseInstance(context, mode, firsts[drawID], counts[drawID], \ + instanceCounts[drawID], baseInstances[drawID]) +#define DRAW_ELEMENTS_INSTANCED_BASE_VERTEX_BASE_INSTANCE \ + contextImpl->drawElementsInstancedBaseVertexBaseInstance( \ + context, mode, counts[drawID], type, indices[drawID], instanceCounts[drawID], \ + baseVertices[drawID], baseInstances[drawID]) +#define DRAW_CALL(drawType, instanced, bvbi) DRAW_##drawType##instanced##bvbi + +#define MULTI_DRAW_BLOCK(drawType, instanced, bvbi, hasDrawID, hasBaseVertex, hasBaseInstance) \ + for (GLsizei drawID = 0; drawID < drawcount; ++drawID) \ + { \ + if (ANGLE_NOOP_DRAW(instanced)) \ + { \ + ANGLE_TRY(contextImpl->handleNoopDrawEvent()); \ + continue; \ + } \ + ANGLE_SET_DRAW_ID_UNIFORM(hasDrawID)(drawID); \ + ANGLE_SET_BASE_VERTEX_UNIFORM(hasBaseVertex)(baseVertices[drawID]); \ + ANGLE_SET_BASE_INSTANCE_UNIFORM(hasBaseInstance)(baseInstances[drawID]); \ + ANGLE_TRY(DRAW_CALL(drawType, instanced, bvbi)); \ + ANGLE_MARK_TRANSFORM_FEEDBACK_USAGE(instanced); \ + gl::MarkShaderStorageUsage(context); \ + } + +angle::Result MultiDrawArraysGeneral(ContextImpl *contextImpl, + const gl::Context *context, + gl::PrimitiveMode mode, + const GLint *firsts, + const GLsizei *counts, + GLsizei drawcount) +{ + gl::Program *programObject = context->getState().getLinkedProgram(context); + const bool hasDrawID = programObject && programObject->hasDrawIDUniform(); + if (hasDrawID) + { + MULTI_DRAW_BLOCK(ARRAYS, _, _, 1, 0, 0) + } + else + { + MULTI_DRAW_BLOCK(ARRAYS, _, _, 0, 0, 0) + } + + return angle::Result::Continue; +} + +angle::Result MultiDrawArraysIndirectGeneral(ContextImpl *contextImpl, + const gl::Context *context, + gl::PrimitiveMode mode, + const void *indirect, + GLsizei drawcount, + GLsizei stride) +{ + const GLubyte *indirectPtr = static_cast(indirect); + + for (auto count = 0; count < drawcount; count++) + { + ANGLE_TRY(contextImpl->drawArraysIndirect( + context, mode, reinterpret_cast(indirectPtr))); + if (stride == 0) + { + indirectPtr += sizeof(gl::DrawArraysIndirectCommand); + } + else + { + indirectPtr += stride; + } + } + + return angle::Result::Continue; +} + +angle::Result MultiDrawArraysInstancedGeneral(ContextImpl *contextImpl, + const gl::Context *context, + gl::PrimitiveMode mode, + const GLint *firsts, + const GLsizei *counts, + const GLsizei *instanceCounts, + GLsizei drawcount) +{ + gl::Program *programObject = context->getState().getLinkedProgram(context); + const bool hasDrawID = programObject && programObject->hasDrawIDUniform(); + if (hasDrawID) + { + MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _, 1, 0, 0) + } + else + { + MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _, 0, 0, 0) + } + + return angle::Result::Continue; +} + +angle::Result MultiDrawElementsGeneral(ContextImpl *contextImpl, + const gl::Context *context, + gl::PrimitiveMode mode, + const GLsizei *counts, + gl::DrawElementsType type, + const GLvoid *const *indices, + GLsizei drawcount) +{ + gl::Program *programObject = context->getState().getLinkedProgram(context); + const bool hasDrawID = programObject && programObject->hasDrawIDUniform(); + if (hasDrawID) + { + MULTI_DRAW_BLOCK(ELEMENTS, _, _, 1, 0, 0) + } + else + { + MULTI_DRAW_BLOCK(ELEMENTS, _, _, 0, 0, 0) + } + + return angle::Result::Continue; +} + +angle::Result MultiDrawElementsIndirectGeneral(ContextImpl *contextImpl, + const gl::Context *context, + gl::PrimitiveMode mode, + gl::DrawElementsType type, + const void *indirect, + GLsizei drawcount, + GLsizei stride) +{ + const GLubyte *indirectPtr = static_cast(indirect); + + for (auto count = 0; count < drawcount; count++) + { + ANGLE_TRY(contextImpl->drawElementsIndirect( + context, mode, type, + reinterpret_cast(indirectPtr))); + if (stride == 0) + { + indirectPtr += sizeof(gl::DrawElementsIndirectCommand); + } + else + { + indirectPtr += stride; + } + } + + return angle::Result::Continue; +} + +angle::Result MultiDrawElementsInstancedGeneral(ContextImpl *contextImpl, + const gl::Context *context, + gl::PrimitiveMode mode, + const GLsizei *counts, + gl::DrawElementsType type, + const GLvoid *const *indices, + const GLsizei *instanceCounts, + GLsizei drawcount) +{ + gl::Program *programObject = context->getState().getLinkedProgram(context); + const bool hasDrawID = programObject && programObject->hasDrawIDUniform(); + if (hasDrawID) + { + MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _, 1, 0, 0) + } + else + { + MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _, 0, 0, 0) + } + + return angle::Result::Continue; +} + +angle::Result MultiDrawArraysInstancedBaseInstanceGeneral(ContextImpl *contextImpl, + const gl::Context *context, + gl::PrimitiveMode mode, + const GLint *firsts, + const GLsizei *counts, + const GLsizei *instanceCounts, + const GLuint *baseInstances, + GLsizei drawcount) +{ + gl::Program *programObject = context->getState().getLinkedProgram(context); + const bool hasDrawID = programObject && programObject->hasDrawIDUniform(); + const bool hasBaseInstance = programObject && programObject->hasBaseInstanceUniform(); + ResetBaseVertexBaseInstance resetUniforms(programObject, false, hasBaseInstance); + + if (hasDrawID && hasBaseInstance) + { + MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _BASE_INSTANCE, 1, 0, 1) + } + else if (hasDrawID) + { + MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _BASE_INSTANCE, 1, 0, 0) + } + else if (hasBaseInstance) + { + MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _BASE_INSTANCE, 0, 0, 1) + } + else + { + MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _BASE_INSTANCE, 0, 0, 0) + } + + return angle::Result::Continue; +} + +angle::Result MultiDrawElementsInstancedBaseVertexBaseInstanceGeneral(ContextImpl *contextImpl, + const gl::Context *context, + gl::PrimitiveMode mode, + const GLsizei *counts, + gl::DrawElementsType type, + const GLvoid *const *indices, + const GLsizei *instanceCounts, + const GLint *baseVertices, + const GLuint *baseInstances, + GLsizei drawcount) +{ + gl::Program *programObject = context->getState().getLinkedProgram(context); + const bool hasDrawID = programObject && programObject->hasDrawIDUniform(); + const bool hasBaseVertex = programObject && programObject->hasBaseVertexUniform(); + const bool hasBaseInstance = programObject && programObject->hasBaseInstanceUniform(); + ResetBaseVertexBaseInstance resetUniforms(programObject, hasBaseVertex, hasBaseInstance); + + if (hasDrawID) + { + if (hasBaseVertex) + { + if (hasBaseInstance) + { + MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 1, 1, 1) + } + else + { + MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 1, 1, 0) + } + } + else + { + if (hasBaseInstance) + { + MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 1, 0, 1) + } + else + { + MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 1, 0, 0) + } + } + } + else + { + if (hasBaseVertex) + { + if (hasBaseInstance) + { + MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 0, 1, 1) + } + else + { + MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 0, 1, 0) + } + } + else + { + if (hasBaseInstance) + { + MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 0, 0, 1) + } + else + { + MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 0, 0, 0) + } + } + } + + return angle::Result::Continue; +} + +ResetBaseVertexBaseInstance::ResetBaseVertexBaseInstance(gl::Program *programObject, + bool resetBaseVertex, + bool resetBaseInstance) + : mProgramObject(programObject), + mResetBaseVertex(resetBaseVertex), + mResetBaseInstance(resetBaseInstance) +{} + +ResetBaseVertexBaseInstance::~ResetBaseVertexBaseInstance() +{ + if (mProgramObject) + { + // Reset emulated uniforms to zero to avoid affecting other draw calls + if (mResetBaseVertex) + { + mProgramObject->setBaseVertexUniform(0); + } + + if (mResetBaseInstance) + { + mProgramObject->setBaseInstanceUniform(0); + } + } +} + +angle::FormatID ConvertToSRGB(angle::FormatID formatID) +{ + switch (formatID) + { + case angle::FormatID::R8_UNORM: + return angle::FormatID::R8_UNORM_SRGB; + case angle::FormatID::R8G8_UNORM: + return angle::FormatID::R8G8_UNORM_SRGB; + case angle::FormatID::R8G8B8_UNORM: + return angle::FormatID::R8G8B8_UNORM_SRGB; + case angle::FormatID::R8G8B8A8_UNORM: + return angle::FormatID::R8G8B8A8_UNORM_SRGB; + case angle::FormatID::B8G8R8A8_UNORM: + return angle::FormatID::B8G8R8A8_UNORM_SRGB; + case angle::FormatID::BC1_RGB_UNORM_BLOCK: + return angle::FormatID::BC1_RGB_UNORM_SRGB_BLOCK; + case angle::FormatID::BC1_RGBA_UNORM_BLOCK: + return angle::FormatID::BC1_RGBA_UNORM_SRGB_BLOCK; + case angle::FormatID::BC2_RGBA_UNORM_BLOCK: + return angle::FormatID::BC2_RGBA_UNORM_SRGB_BLOCK; + case angle::FormatID::BC3_RGBA_UNORM_BLOCK: + return angle::FormatID::BC3_RGBA_UNORM_SRGB_BLOCK; + case angle::FormatID::BC7_RGBA_UNORM_BLOCK: + return angle::FormatID::BC7_RGBA_UNORM_SRGB_BLOCK; + case angle::FormatID::ETC2_R8G8B8_UNORM_BLOCK: + return angle::FormatID::ETC2_R8G8B8_SRGB_BLOCK; + case angle::FormatID::ETC2_R8G8B8A1_UNORM_BLOCK: + return angle::FormatID::ETC2_R8G8B8A1_SRGB_BLOCK; + case angle::FormatID::ETC2_R8G8B8A8_UNORM_BLOCK: + return angle::FormatID::ETC2_R8G8B8A8_SRGB_BLOCK; + case angle::FormatID::ASTC_4x4_UNORM_BLOCK: + return angle::FormatID::ASTC_4x4_SRGB_BLOCK; + case angle::FormatID::ASTC_5x4_UNORM_BLOCK: + return angle::FormatID::ASTC_5x4_SRGB_BLOCK; + case angle::FormatID::ASTC_5x5_UNORM_BLOCK: + return angle::FormatID::ASTC_5x5_SRGB_BLOCK; + case angle::FormatID::ASTC_6x5_UNORM_BLOCK: + return angle::FormatID::ASTC_6x5_SRGB_BLOCK; + case angle::FormatID::ASTC_6x6_UNORM_BLOCK: + return angle::FormatID::ASTC_6x6_SRGB_BLOCK; + case angle::FormatID::ASTC_8x5_UNORM_BLOCK: + return angle::FormatID::ASTC_8x5_SRGB_BLOCK; + case angle::FormatID::ASTC_8x6_UNORM_BLOCK: + return angle::FormatID::ASTC_8x6_SRGB_BLOCK; + case angle::FormatID::ASTC_8x8_UNORM_BLOCK: + return angle::FormatID::ASTC_8x8_SRGB_BLOCK; + case angle::FormatID::ASTC_10x5_UNORM_BLOCK: + return angle::FormatID::ASTC_10x5_SRGB_BLOCK; + case angle::FormatID::ASTC_10x6_UNORM_BLOCK: + return angle::FormatID::ASTC_10x6_SRGB_BLOCK; + case angle::FormatID::ASTC_10x8_UNORM_BLOCK: + return angle::FormatID::ASTC_10x8_SRGB_BLOCK; + case angle::FormatID::ASTC_10x10_UNORM_BLOCK: + return angle::FormatID::ASTC_10x10_SRGB_BLOCK; + case angle::FormatID::ASTC_12x10_UNORM_BLOCK: + return angle::FormatID::ASTC_12x10_SRGB_BLOCK; + case angle::FormatID::ASTC_12x12_UNORM_BLOCK: + return angle::FormatID::ASTC_12x12_SRGB_BLOCK; + default: + return angle::FormatID::NONE; + } +} + +angle::FormatID ConvertToLinear(angle::FormatID formatID) +{ + switch (formatID) + { + case angle::FormatID::R8_UNORM_SRGB: + return angle::FormatID::R8_UNORM; + case angle::FormatID::R8G8_UNORM_SRGB: + return angle::FormatID::R8G8_UNORM; + case angle::FormatID::R8G8B8_UNORM_SRGB: + return angle::FormatID::R8G8B8_UNORM; + case angle::FormatID::R8G8B8A8_UNORM_SRGB: + return angle::FormatID::R8G8B8A8_UNORM; + case angle::FormatID::B8G8R8A8_UNORM_SRGB: + return angle::FormatID::B8G8R8A8_UNORM; + case angle::FormatID::BC1_RGB_UNORM_SRGB_BLOCK: + return angle::FormatID::BC1_RGB_UNORM_BLOCK; + case angle::FormatID::BC1_RGBA_UNORM_SRGB_BLOCK: + return angle::FormatID::BC1_RGBA_UNORM_BLOCK; + case angle::FormatID::BC2_RGBA_UNORM_SRGB_BLOCK: + return angle::FormatID::BC2_RGBA_UNORM_BLOCK; + case angle::FormatID::BC3_RGBA_UNORM_SRGB_BLOCK: + return angle::FormatID::BC3_RGBA_UNORM_BLOCK; + case angle::FormatID::BC7_RGBA_UNORM_SRGB_BLOCK: + return angle::FormatID::BC7_RGBA_UNORM_BLOCK; + case angle::FormatID::ETC2_R8G8B8_SRGB_BLOCK: + return angle::FormatID::ETC2_R8G8B8_UNORM_BLOCK; + case angle::FormatID::ETC2_R8G8B8A1_SRGB_BLOCK: + return angle::FormatID::ETC2_R8G8B8A1_UNORM_BLOCK; + case angle::FormatID::ETC2_R8G8B8A8_SRGB_BLOCK: + return angle::FormatID::ETC2_R8G8B8A8_UNORM_BLOCK; + case angle::FormatID::ASTC_4x4_SRGB_BLOCK: + return angle::FormatID::ASTC_4x4_UNORM_BLOCK; + case angle::FormatID::ASTC_5x4_SRGB_BLOCK: + return angle::FormatID::ASTC_5x4_UNORM_BLOCK; + case angle::FormatID::ASTC_5x5_SRGB_BLOCK: + return angle::FormatID::ASTC_5x5_UNORM_BLOCK; + case angle::FormatID::ASTC_6x5_SRGB_BLOCK: + return angle::FormatID::ASTC_6x5_UNORM_BLOCK; + case angle::FormatID::ASTC_6x6_SRGB_BLOCK: + return angle::FormatID::ASTC_6x6_UNORM_BLOCK; + case angle::FormatID::ASTC_8x5_SRGB_BLOCK: + return angle::FormatID::ASTC_8x5_UNORM_BLOCK; + case angle::FormatID::ASTC_8x6_SRGB_BLOCK: + return angle::FormatID::ASTC_8x6_UNORM_BLOCK; + case angle::FormatID::ASTC_8x8_SRGB_BLOCK: + return angle::FormatID::ASTC_8x8_UNORM_BLOCK; + case angle::FormatID::ASTC_10x5_SRGB_BLOCK: + return angle::FormatID::ASTC_10x5_UNORM_BLOCK; + case angle::FormatID::ASTC_10x6_SRGB_BLOCK: + return angle::FormatID::ASTC_10x6_UNORM_BLOCK; + case angle::FormatID::ASTC_10x8_SRGB_BLOCK: + return angle::FormatID::ASTC_10x8_UNORM_BLOCK; + case angle::FormatID::ASTC_10x10_SRGB_BLOCK: + return angle::FormatID::ASTC_10x10_UNORM_BLOCK; + case angle::FormatID::ASTC_12x10_SRGB_BLOCK: + return angle::FormatID::ASTC_12x10_UNORM_BLOCK; + case angle::FormatID::ASTC_12x12_SRGB_BLOCK: + return angle::FormatID::ASTC_12x12_UNORM_BLOCK; + default: + return angle::FormatID::NONE; + } +} + +bool IsOverridableLinearFormat(angle::FormatID formatID) +{ + return ConvertToSRGB(formatID) != angle::FormatID::NONE; +} +} // namespace rx diff --git a/gfx/angle/checkout/src/libANGLE/renderer/renderer_utils.h b/gfx/angle/checkout/src/libANGLE/renderer/renderer_utils.h new file mode 100644 index 0000000000..92002db56f --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/renderer_utils.h @@ -0,0 +1,499 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// renderer_utils: +// Helper methods pertaining to most or all back-ends. +// + +#ifndef LIBANGLE_RENDERER_RENDERER_UTILS_H_ +#define LIBANGLE_RENDERER_RENDERER_UTILS_H_ + +#include + +#include +#include + +#include "GLSLANG/ShaderLang.h" +#include "common/angleutils.h" +#include "common/utilities.h" +#include "libANGLE/angletypes.h" + +namespace angle +{ +struct FeatureSetBase; +struct Format; +enum class FormatID; +} // namespace angle + +namespace gl +{ +struct FormatType; +struct InternalFormat; +class State; +} // namespace gl + +namespace egl +{ +class AttributeMap; +struct DisplayState; +} // namespace egl + +namespace rx +{ +class ContextImpl; + +// The possible rotations of the surface/draw framebuffer, particularly for the Vulkan back-end on +// Android. +enum class SurfaceRotation +{ + Identity, + Rotated90Degrees, + Rotated180Degrees, + Rotated270Degrees, + FlippedIdentity, + FlippedRotated90Degrees, + FlippedRotated180Degrees, + FlippedRotated270Degrees, + + InvalidEnum, + EnumCount = InvalidEnum, +}; + +bool IsRotatedAspectRatio(SurfaceRotation rotation); + +using SpecConstUsageBits = angle::PackedEnumBitSet; + +void RotateRectangle(const SurfaceRotation rotation, + const bool flipY, + const int framebufferWidth, + const int framebufferHeight, + const gl::Rectangle &incoming, + gl::Rectangle *outgoing); + +using MipGenerationFunction = void (*)(size_t sourceWidth, + size_t sourceHeight, + size_t sourceDepth, + const uint8_t *sourceData, + size_t sourceRowPitch, + size_t sourceDepthPitch, + uint8_t *destData, + size_t destRowPitch, + size_t destDepthPitch); + +typedef void (*PixelReadFunction)(const uint8_t *source, uint8_t *dest); +typedef void (*PixelWriteFunction)(const uint8_t *source, uint8_t *dest); +typedef void (*FastCopyFunction)(const uint8_t *source, + int srcXAxisPitch, + int srcYAxisPitch, + uint8_t *dest, + int destXAxisPitch, + int destYAxisPitch, + int width, + int height); + +class FastCopyFunctionMap +{ + public: + struct Entry + { + angle::FormatID formatID; + FastCopyFunction func; + }; + + constexpr FastCopyFunctionMap() : FastCopyFunctionMap(nullptr, 0) {} + + constexpr FastCopyFunctionMap(const Entry *data, size_t size) : mSize(size), mData(data) {} + + bool has(angle::FormatID formatID) const; + FastCopyFunction get(angle::FormatID formatID) const; + + private: + size_t mSize; + const Entry *mData; +}; + +struct PackPixelsParams +{ + PackPixelsParams(); + PackPixelsParams(const gl::Rectangle &area, + const angle::Format &destFormat, + GLuint outputPitch, + bool reverseRowOrderIn, + gl::Buffer *packBufferIn, + ptrdiff_t offset); + + gl::Rectangle area; + const angle::Format *destFormat; + GLuint outputPitch; + gl::Buffer *packBuffer; + bool reverseRowOrder; + ptrdiff_t offset; + SurfaceRotation rotation; +}; + +void PackPixels(const PackPixelsParams ¶ms, + const angle::Format &sourceFormat, + int inputPitch, + const uint8_t *source, + uint8_t *destination); + +using InitializeTextureDataFunction = void (*)(size_t width, + size_t height, + size_t depth, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +using LoadImageFunction = void (*)(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +struct LoadImageFunctionInfo +{ + LoadImageFunctionInfo() : loadFunction(nullptr), requiresConversion(false) {} + LoadImageFunctionInfo(LoadImageFunction loadFunction, bool requiresConversion) + : loadFunction(loadFunction), requiresConversion(requiresConversion) + {} + + LoadImageFunction loadFunction; + bool requiresConversion; +}; + +using LoadFunctionMap = LoadImageFunctionInfo (*)(GLenum); + +bool ShouldUseDebugLayers(const egl::AttributeMap &attribs); + +void CopyImageCHROMIUM(const uint8_t *sourceData, + size_t sourceRowPitch, + size_t sourcePixelBytes, + size_t sourceDepthPitch, + PixelReadFunction pixelReadFunction, + uint8_t *destData, + size_t destRowPitch, + size_t destPixelBytes, + size_t destDepthPitch, + PixelWriteFunction pixelWriteFunction, + GLenum destUnsizedFormat, + GLenum destComponentType, + size_t width, + size_t height, + size_t depth, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha); + +// Incomplete textures are 1x1 textures filled with black, used when samplers are incomplete. +// This helper class encapsulates handling incomplete textures. Because the GL back-end +// can take advantage of the driver's incomplete textures, and because clearing multisample +// textures is so difficult, we can keep an instance of this class in the back-end instead +// of moving the logic to the Context front-end. + +// This interface allows us to call-back to init a multisample texture. +class MultisampleTextureInitializer +{ + public: + virtual ~MultisampleTextureInitializer() {} + virtual angle::Result initializeMultisampleTextureToBlack(const gl::Context *context, + gl::Texture *glTexture) = 0; +}; + +class IncompleteTextureSet final : angle::NonCopyable +{ + public: + IncompleteTextureSet(); + ~IncompleteTextureSet(); + + void onDestroy(const gl::Context *context); + + angle::Result getIncompleteTexture(const gl::Context *context, + gl::TextureType type, + gl::SamplerFormat format, + MultisampleTextureInitializer *multisampleInitializer, + gl::Texture **textureOut); + + private: + using TextureMapWithSamplerFormat = angle::PackedEnumMap; + + TextureMapWithSamplerFormat mIncompleteTextures; + gl::Buffer *mIncompleteTextureBufferAttachment; +}; + +// Helpers to set a matrix uniform value based on GLSL or HLSL semantics. +// The return value indicate if the data was updated or not. +template +struct SetFloatUniformMatrixGLSL +{ + static void Run(unsigned int arrayElementOffset, + unsigned int elementCount, + GLsizei countIn, + GLboolean transpose, + const GLfloat *value, + uint8_t *targetData); +}; + +template +struct SetFloatUniformMatrixHLSL +{ + static void Run(unsigned int arrayElementOffset, + unsigned int elementCount, + GLsizei countIn, + GLboolean transpose, + const GLfloat *value, + uint8_t *targetData); +}; + +// Helper method to de-tranpose a matrix uniform for an API query. +void GetMatrixUniform(GLenum type, GLfloat *dataOut, const GLfloat *source, bool transpose); + +template +void GetMatrixUniform(GLenum type, NonFloatT *dataOut, const NonFloatT *source, bool transpose); + +const angle::Format &GetFormatFromFormatType(GLenum format, GLenum type); + +angle::Result ComputeStartVertex(ContextImpl *contextImpl, + const gl::IndexRange &indexRange, + GLint baseVertex, + GLint *firstVertexOut); + +angle::Result GetVertexRangeInfo(const gl::Context *context, + GLint firstVertex, + GLsizei vertexOrIndexCount, + gl::DrawElementsType indexTypeOrInvalid, + const void *indices, + GLint baseVertex, + GLint *startVertexOut, + size_t *vertexCountOut); + +gl::Rectangle ClipRectToScissor(const gl::State &glState, const gl::Rectangle &rect, bool invertY); + +// Helper method to intialize a FeatureSet with overrides from the DisplayState +void ApplyFeatureOverrides(angle::FeatureSetBase *features, const egl::DisplayState &state); + +template +uint32_t LineLoopRestartIndexCountHelper(GLsizei indexCount, const uint8_t *srcPtr) +{ + constexpr In restartIndex = gl::GetPrimitiveRestartIndexFromType(); + const In *inIndices = reinterpret_cast(srcPtr); + uint32_t numIndices = 0; + // See CopyLineLoopIndicesWithRestart() below for more info on how + // numIndices is calculated. + GLsizei loopStartIndex = 0; + for (GLsizei curIndex = 0; curIndex < indexCount; curIndex++) + { + In vertex = inIndices[curIndex]; + if (vertex != restartIndex) + { + numIndices++; + } + else + { + if (curIndex > loopStartIndex) + { + numIndices += 2; + } + loopStartIndex = curIndex + 1; + } + } + if (indexCount > loopStartIndex) + { + numIndices++; + } + return numIndices; +} + +inline uint32_t GetLineLoopWithRestartIndexCount(gl::DrawElementsType glIndexType, + GLsizei indexCount, + const uint8_t *srcPtr) +{ + switch (glIndexType) + { + case gl::DrawElementsType::UnsignedByte: + return LineLoopRestartIndexCountHelper(indexCount, srcPtr); + case gl::DrawElementsType::UnsignedShort: + return LineLoopRestartIndexCountHelper(indexCount, srcPtr); + case gl::DrawElementsType::UnsignedInt: + return LineLoopRestartIndexCountHelper(indexCount, srcPtr); + default: + UNREACHABLE(); + return 0; + } +} + +// Writes the line-strip vertices for a line loop to outPtr, +// where outLimit is calculated as in GetPrimitiveRestartIndexCount. +template +void CopyLineLoopIndicesWithRestart(GLsizei indexCount, const uint8_t *srcPtr, uint8_t *outPtr) +{ + constexpr In restartIndex = gl::GetPrimitiveRestartIndexFromType(); + constexpr Out outRestartIndex = gl::GetPrimitiveRestartIndexFromType(); + const In *inIndices = reinterpret_cast(srcPtr); + Out *outIndices = reinterpret_cast(outPtr); + GLsizei loopStartIndex = 0; + for (GLsizei curIndex = 0; curIndex < indexCount; curIndex++) + { + In vertex = inIndices[curIndex]; + if (vertex != restartIndex) + { + *(outIndices++) = static_cast(vertex); + } + else + { + if (curIndex > loopStartIndex) + { + // Emit an extra vertex only if the loop is not empty. + *(outIndices++) = inIndices[loopStartIndex]; + // Then restart the strip. + *(outIndices++) = outRestartIndex; + } + loopStartIndex = curIndex + 1; + } + } + if (indexCount > loopStartIndex) + { + // Close the last loop if not empty. + *(outIndices++) = inIndices[loopStartIndex]; + } +} + +void GetSamplePosition(GLsizei sampleCount, size_t index, GLfloat *xy); + +angle::Result MultiDrawArraysGeneral(ContextImpl *contextImpl, + const gl::Context *context, + gl::PrimitiveMode mode, + const GLint *firsts, + const GLsizei *counts, + GLsizei drawcount); +angle::Result MultiDrawArraysIndirectGeneral(ContextImpl *contextImpl, + const gl::Context *context, + gl::PrimitiveMode mode, + const void *indirect, + GLsizei drawcount, + GLsizei stride); +angle::Result MultiDrawArraysInstancedGeneral(ContextImpl *contextImpl, + const gl::Context *context, + gl::PrimitiveMode mode, + const GLint *firsts, + const GLsizei *counts, + const GLsizei *instanceCounts, + GLsizei drawcount); +angle::Result MultiDrawElementsGeneral(ContextImpl *contextImpl, + const gl::Context *context, + gl::PrimitiveMode mode, + const GLsizei *counts, + gl::DrawElementsType type, + const GLvoid *const *indices, + GLsizei drawcount); +angle::Result MultiDrawElementsIndirectGeneral(ContextImpl *contextImpl, + const gl::Context *context, + gl::PrimitiveMode mode, + gl::DrawElementsType type, + const void *indirect, + GLsizei drawcount, + GLsizei stride); +angle::Result MultiDrawElementsInstancedGeneral(ContextImpl *contextImpl, + const gl::Context *context, + gl::PrimitiveMode mode, + const GLsizei *counts, + gl::DrawElementsType type, + const GLvoid *const *indices, + const GLsizei *instanceCounts, + GLsizei drawcount); +angle::Result MultiDrawArraysInstancedBaseInstanceGeneral(ContextImpl *contextImpl, + const gl::Context *context, + gl::PrimitiveMode mode, + const GLint *firsts, + const GLsizei *counts, + const GLsizei *instanceCounts, + const GLuint *baseInstances, + GLsizei drawcount); +angle::Result MultiDrawElementsInstancedBaseVertexBaseInstanceGeneral(ContextImpl *contextImpl, + const gl::Context *context, + gl::PrimitiveMode mode, + const GLsizei *counts, + gl::DrawElementsType type, + const GLvoid *const *indices, + const GLsizei *instanceCounts, + const GLint *baseVertices, + const GLuint *baseInstances, + GLsizei drawcount); + +// RAII object making sure reset uniforms is called no matter whether there's an error in draw calls +class ResetBaseVertexBaseInstance : angle::NonCopyable +{ + public: + ResetBaseVertexBaseInstance(gl::Program *programObject, + bool resetBaseVertex, + bool resetBaseInstance); + + ~ResetBaseVertexBaseInstance(); + + private: + gl::Program *mProgramObject; + bool mResetBaseVertex; + bool mResetBaseInstance; +}; + +angle::FormatID ConvertToSRGB(angle::FormatID formatID); +angle::FormatID ConvertToLinear(angle::FormatID formatID); +bool IsOverridableLinearFormat(angle::FormatID formatID); + +enum class PipelineType +{ + Graphics = 0, + Compute = 1, + + InvalidEnum = 2, + EnumCount = 2, +}; +} // namespace rx + +// MultiDraw macro patterns +// These macros are to avoid too much code duplication as we don't want to have if detect for +// hasDrawID/BaseVertex/BaseInstance inside for loop in a multiDrawANGLE call Part of these are put +// in the header as we want to share with specialized context impl on some platforms for multidraw +#define ANGLE_SET_DRAW_ID_UNIFORM_0(drawID) \ + {} +#define ANGLE_SET_DRAW_ID_UNIFORM_1(drawID) programObject->setDrawIDUniform(drawID) +#define ANGLE_SET_DRAW_ID_UNIFORM(cond) ANGLE_SET_DRAW_ID_UNIFORM_##cond + +#define ANGLE_SET_BASE_VERTEX_UNIFORM_0(baseVertex) \ + {} +#define ANGLE_SET_BASE_VERTEX_UNIFORM_1(baseVertex) programObject->setBaseVertexUniform(baseVertex); +#define ANGLE_SET_BASE_VERTEX_UNIFORM(cond) ANGLE_SET_BASE_VERTEX_UNIFORM_##cond + +#define ANGLE_SET_BASE_INSTANCE_UNIFORM_0(baseInstance) \ + {} +#define ANGLE_SET_BASE_INSTANCE_UNIFORM_1(baseInstance) \ + programObject->setBaseInstanceUniform(baseInstance) +#define ANGLE_SET_BASE_INSTANCE_UNIFORM(cond) ANGLE_SET_BASE_INSTANCE_UNIFORM_##cond + +#define ANGLE_NOOP_DRAW_ context->noopDraw(mode, counts[drawID]) +#define ANGLE_NOOP_DRAW_INSTANCED \ + context->noopDrawInstanced(mode, counts[drawID], instanceCounts[drawID]) +#define ANGLE_NOOP_DRAW(_instanced) ANGLE_NOOP_DRAW##_instanced + +#define ANGLE_MARK_TRANSFORM_FEEDBACK_USAGE_ \ + gl::MarkTransformFeedbackBufferUsage(context, counts[drawID], 1) +#define ANGLE_MARK_TRANSFORM_FEEDBACK_USAGE_INSTANCED \ + gl::MarkTransformFeedbackBufferUsage(context, counts[drawID], instanceCounts[drawID]) +#define ANGLE_MARK_TRANSFORM_FEEDBACK_USAGE(instanced) \ + ANGLE_MARK_TRANSFORM_FEEDBACK_USAGE##instanced + +// Helper macro that casts to a bitfield type then verifies no bits were dropped. +#define SetBitField(lhs, rhs) \ + do \ + { \ + auto ANGLE_LOCAL_VAR = rhs; \ + lhs = static_cast::type>(ANGLE_LOCAL_VAR); \ + ASSERT(static_cast(lhs) == ANGLE_LOCAL_VAR); \ + } while (0) + +#endif // LIBANGLE_RENDERER_RENDERER_UTILS_H_ diff --git a/gfx/angle/checkout/src/libANGLE/renderer/serial_utils.h b/gfx/angle/checkout/src/libANGLE/renderer/serial_utils.h new file mode 100644 index 0000000000..49a65c4e26 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/serial_utils.h @@ -0,0 +1,126 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// serial_utils: +// Utilities for generating unique IDs for resources in ANGLE. +// + +#ifndef LIBANGLE_RENDERER_SERIAL_UTILS_H_ +#define LIBANGLE_RENDERER_SERIAL_UTILS_H_ + +#include +#include + +#include "common/angleutils.h" +#include "common/debug.h" + +namespace rx +{ +class ResourceSerial +{ + public: + constexpr ResourceSerial() : mValue(kDirty) {} + explicit constexpr ResourceSerial(uintptr_t value) : mValue(value) {} + constexpr bool operator==(ResourceSerial other) const { return mValue == other.mValue; } + constexpr bool operator!=(ResourceSerial other) const { return mValue != other.mValue; } + + void dirty() { mValue = kDirty; } + void clear() { mValue = kEmpty; } + + constexpr bool valid() const { return mValue != kEmpty && mValue != kDirty; } + constexpr bool empty() const { return mValue == kEmpty; } + + private: + constexpr static uintptr_t kDirty = std::numeric_limits::max(); + constexpr static uintptr_t kEmpty = 0; + + uintptr_t mValue; +}; + +class Serial final +{ + public: + constexpr Serial() : mValue(kInvalid) {} + constexpr Serial(const Serial &other) = default; + Serial &operator=(const Serial &other) = default; + + static constexpr Serial Infinite() { return Serial(std::numeric_limits::max()); } + + constexpr bool operator==(const Serial &other) const + { + return mValue != kInvalid && mValue == other.mValue; + } + constexpr bool operator==(uint32_t value) const + { + return mValue != kInvalid && mValue == static_cast(value); + } + constexpr bool operator!=(const Serial &other) const + { + return mValue == kInvalid || mValue != other.mValue; + } + constexpr bool operator>(const Serial &other) const { return mValue > other.mValue; } + constexpr bool operator>=(const Serial &other) const { return mValue >= other.mValue; } + constexpr bool operator<(const Serial &other) const { return mValue < other.mValue; } + constexpr bool operator<=(const Serial &other) const { return mValue <= other.mValue; } + + constexpr bool operator<(uint32_t value) const { return mValue < static_cast(value); } + + // Useful for serialization. + constexpr uint64_t getValue() const { return mValue; } + constexpr bool valid() const { return mValue != kInvalid; } + + private: + template + friend class SerialFactoryBase; + friend class AtomicQueueSerial; + constexpr explicit Serial(uint64_t value) : mValue(value) {} + uint64_t mValue; + static constexpr uint64_t kInvalid = 0; +}; + +// Defines class to track the queue serial that can be load/store from multiple threads atomically. +class AtomicQueueSerial final +{ + public: + constexpr AtomicQueueSerial() : mValue(kInvalid) { ASSERT(mValue.is_lock_free()); } + AtomicQueueSerial &operator=(const Serial &other) + { + mValue.store(other.mValue, std::memory_order_release); + return *this; + } + Serial getSerial() const { return Serial(mValue.load(std::memory_order_consume)); } + + private: + std::atomic mValue; + static constexpr uint64_t kInvalid = 0; +}; + +// Used as default/initial serial +static constexpr Serial kZeroSerial = Serial(); + +template +class SerialFactoryBase final : angle::NonCopyable +{ + public: + SerialFactoryBase() : mSerial(1) {} + + Serial generate() + { + uint64_t current = mSerial++; + ASSERT(mSerial > current); // Integer overflow + return Serial(current); + } + + private: + SerialBaseType mSerial; +}; + +using SerialFactory = SerialFactoryBase; +using AtomicSerialFactory = SerialFactoryBase>; +using RenderPassSerialFactory = SerialFactoryBase; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_SERIAL_UTILS_H_ diff --git a/gfx/angle/checkout/src/libANGLE/trace.h b/gfx/angle/checkout/src/libANGLE/trace.h new file mode 100644 index 0000000000..fc8d40c646 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/trace.h @@ -0,0 +1,26 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// trace.h: Wrappers for ANGLE trace event functions. +// + +#ifndef LIBANGLE_TRACE_H_ +#define LIBANGLE_TRACE_H_ + +#include +#include "third_party/trace_event/trace_event.h" + +// TODO: Pass platform directly to these methods. http://anglebug.com/1892 +#define ANGLE_TRACE_EVENT_BEGIN0(CATEGORY, EVENT) \ + TRACE_EVENT_BEGIN0(ANGLEPlatformCurrent(), CATEGORY, EVENT) +#define ANGLE_TRACE_EVENT_END0(CATEGORY, EVENT) \ + TRACE_EVENT_END0(ANGLEPlatformCurrent(), CATEGORY, EVENT) +#define ANGLE_TRACE_EVENT_INSTANT0(CATEGORY, EVENT) \ + TRACE_EVENT_INSTANT0(ANGLEPlatformCurrent(), CATEGORY, EVENT) +#define ANGLE_TRACE_EVENT0(CATEGORY, EVENT) TRACE_EVENT0(ANGLEPlatformCurrent(), CATEGORY, EVENT) +#define ANGLE_TRACE_EVENT1(CATEGORY, EVENT, NAME, PARAM) \ + TRACE_EVENT1(ANGLEPlatformCurrent(), CATEGORY, EVENT, NAME, PARAM) + +#endif // LIBANGLE_TRACE_H_ diff --git a/gfx/angle/checkout/src/libANGLE/validationEGL.cpp b/gfx/angle/checkout/src/libANGLE/validationEGL.cpp new file mode 100644 index 0000000000..e73535ab5c --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationEGL.cpp @@ -0,0 +1,6782 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// validationEGL.cpp: Validation functions for generic EGL entry point parameters + +#include "libANGLE/validationEGL_autogen.h" + +#include "common/utilities.h" +#include "libANGLE/Config.h" +#include "libANGLE/Context.h" +#include "libANGLE/Device.h" +#include "libANGLE/Display.h" +#include "libANGLE/EGLSync.h" +#include "libANGLE/Image.h" +#include "libANGLE/Stream.h" +#include "libANGLE/Surface.h" +#include "libANGLE/Texture.h" +#include "libANGLE/Thread.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/DisplayImpl.h" + +#include + +namespace egl +{ +namespace +{ +size_t GetMaximumMipLevel(const gl::Context *context, gl::TextureType type) +{ + const gl::Caps &caps = context->getCaps(); + + int maxDimension = 0; + switch (type) + { + case gl::TextureType::_2D: + case gl::TextureType::_2DArray: + case gl::TextureType::_2DMultisample: + maxDimension = caps.max2DTextureSize; + break; + case gl::TextureType::Rectangle: + maxDimension = caps.maxRectangleTextureSize; + break; + case gl::TextureType::CubeMap: + maxDimension = caps.maxCubeMapTextureSize; + break; + case gl::TextureType::_3D: + maxDimension = caps.max3DTextureSize; + break; + + default: + UNREACHABLE(); + } + + return gl::log2(maxDimension); +} + +bool TextureHasNonZeroMipLevelsSpecified(const gl::Context *context, const gl::Texture *texture) +{ + size_t maxMip = GetMaximumMipLevel(context, texture->getType()); + for (size_t level = 1; level < maxMip; level++) + { + if (texture->getType() == gl::TextureType::CubeMap) + { + for (gl::TextureTarget face : gl::AllCubeFaceTextureTargets()) + { + if (texture->getFormat(face, level).valid()) + { + return true; + } + } + } + else + { + if (texture->getFormat(gl::NonCubeTextureTypeToTarget(texture->getType()), level) + .valid()) + { + return true; + } + } + } + + return false; +} + +bool CubeTextureHasUnspecifiedLevel0Face(const gl::Texture *texture) +{ + ASSERT(texture->getType() == gl::TextureType::CubeMap); + for (gl::TextureTarget face : gl::AllCubeFaceTextureTargets()) + { + if (!texture->getFormat(face, 0).valid()) + { + return true; + } + } + + return false; +} + +bool ValidateStreamAttribute(const ValidationContext *val, + const EGLAttrib attribute, + const EGLAttrib value, + const DisplayExtensions &extensions) +{ + switch (attribute) + { + case EGL_STREAM_STATE_KHR: + case EGL_PRODUCER_FRAME_KHR: + case EGL_CONSUMER_FRAME_KHR: + val->setError(EGL_BAD_ACCESS, "Attempt to initialize readonly parameter"); + return false; + case EGL_CONSUMER_LATENCY_USEC_KHR: + // Technically not in spec but a latency < 0 makes no sense so we check it + if (value < 0) + { + val->setError(EGL_BAD_PARAMETER, "Latency must be positive"); + return false; + } + break; + case EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR: + if (!extensions.streamConsumerGLTexture) + { + val->setError(EGL_BAD_ATTRIBUTE, "Consumer GL extension not enabled"); + return false; + } + // Again not in spec but it should be positive anyways + if (value < 0) + { + val->setError(EGL_BAD_PARAMETER, "Timeout must be positive"); + return false; + } + break; + default: + val->setError(EGL_BAD_ATTRIBUTE, "Invalid stream attribute"); + return false; + } + return true; +} + +bool ValidateCreateImageMipLevelCommon(const ValidationContext *val, + const gl::Context *context, + const gl::Texture *texture, + EGLAttrib level) +{ + // Note that the spec EGL_create_image spec does not explicitly specify an error + // when the level is outside the base/max level range, but it does mention that the + // level "must be a part of the complete texture object ". It can be argued + // that out-of-range levels are not a part of the complete texture. + const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel(); + if (level > 0 && + (!texture->isMipmapComplete() || static_cast(level) < effectiveBaseLevel || + static_cast(level) > texture->getTextureState().getMipmapMaxLevel())) + { + val->setError(EGL_BAD_PARAMETER, "texture must be complete if level is non-zero."); + return false; + } + + if (level == 0 && !texture->isMipmapComplete() && + TextureHasNonZeroMipLevelsSpecified(context, texture)) + { + val->setError(EGL_BAD_PARAMETER, + "if level is zero and the texture is incomplete, it must " + "have no mip levels specified except zero."); + return false; + } + + return true; +} + +bool ValidateConfigAttribute(const ValidationContext *val, + const Display *display, + EGLAttrib attribute) +{ + switch (attribute) + { + case EGL_BUFFER_SIZE: + case EGL_ALPHA_SIZE: + case EGL_BLUE_SIZE: + case EGL_GREEN_SIZE: + case EGL_RED_SIZE: + case EGL_DEPTH_SIZE: + case EGL_STENCIL_SIZE: + case EGL_CONFIG_CAVEAT: + case EGL_CONFIG_ID: + case EGL_LEVEL: + case EGL_NATIVE_RENDERABLE: + case EGL_NATIVE_VISUAL_ID: + case EGL_NATIVE_VISUAL_TYPE: + case EGL_SAMPLES: + case EGL_SAMPLE_BUFFERS: + case EGL_SURFACE_TYPE: + case EGL_TRANSPARENT_TYPE: + case EGL_TRANSPARENT_BLUE_VALUE: + case EGL_TRANSPARENT_GREEN_VALUE: + case EGL_TRANSPARENT_RED_VALUE: + case EGL_BIND_TO_TEXTURE_RGB: + case EGL_BIND_TO_TEXTURE_RGBA: + case EGL_MIN_SWAP_INTERVAL: + case EGL_MAX_SWAP_INTERVAL: + case EGL_LUMINANCE_SIZE: + case EGL_ALPHA_MASK_SIZE: + case EGL_COLOR_BUFFER_TYPE: + case EGL_RENDERABLE_TYPE: + case EGL_MATCH_NATIVE_PIXMAP: + case EGL_CONFORMANT: + case EGL_MAX_PBUFFER_WIDTH: + case EGL_MAX_PBUFFER_HEIGHT: + case EGL_MAX_PBUFFER_PIXELS: + break; + + case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE: + if (!display->getExtensions().surfaceOrientation) + { + val->setError(EGL_BAD_ATTRIBUTE, "EGL_ANGLE_surface_orientation is not enabled."); + return false; + } + break; + + case EGL_COLOR_COMPONENT_TYPE_EXT: + if (!display->getExtensions().pixelFormatFloat) + { + val->setError(EGL_BAD_ATTRIBUTE, "EGL_EXT_pixel_format_float is not enabled."); + return false; + } + break; + + case EGL_RECORDABLE_ANDROID: + if (!display->getExtensions().recordable) + { + val->setError(EGL_BAD_ATTRIBUTE, "EGL_ANDROID_recordable is not enabled."); + return false; + } + break; + + case EGL_FRAMEBUFFER_TARGET_ANDROID: + if (!display->getExtensions().framebufferTargetANDROID) + { + val->setError(EGL_BAD_ATTRIBUTE, "EGL_ANDROID_framebuffer_target is not enabled."); + return false; + } + break; + + case EGL_BIND_TO_TEXTURE_TARGET_ANGLE: + if (!display->getExtensions().iosurfaceClientBuffer) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_ANGLE_iosurface_client_buffer is not enabled."); + return false; + } + break; + + case EGL_Y_INVERTED_NOK: + if (!display->getExtensions().textureFromPixmapNOK) + { + val->setError(EGL_BAD_ATTRIBUTE, "EGL_NOK_texture_from_pixmap is not enabled."); + return false; + } + break; + + case EGL_MATCH_FORMAT_KHR: + if (!display->getExtensions().lockSurface3KHR) + { + val->setError(EGL_BAD_ATTRIBUTE, "EGL_KHR_lock_surface3 is not enabled."); + return false; + } + break; + + default: + val->setError(EGL_BAD_ATTRIBUTE, "Unknown attribute: 0x%04" PRIxPTR "X", attribute); + return false; + } + + return true; +} + +bool ValidateConfigAttributeValue(const ValidationContext *val, + const Display *display, + EGLAttrib attribute, + EGLAttrib value) +{ + switch (attribute) + { + + case EGL_BIND_TO_TEXTURE_RGB: + case EGL_BIND_TO_TEXTURE_RGBA: + switch (value) + { + case EGL_DONT_CARE: + case EGL_TRUE: + case EGL_FALSE: + break; + default: + val->setError(EGL_BAD_ATTRIBUTE, "EGL_bind_to_texture invalid attribute: 0x%X", + static_cast(value)); + return false; + } + break; + + case EGL_COLOR_BUFFER_TYPE: + switch (value) + { + case EGL_RGB_BUFFER: + case EGL_LUMINANCE_BUFFER: + // EGL_DONT_CARE doesn't match the spec, but does match dEQP usage + case EGL_DONT_CARE: + break; + default: + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_color_buffer_type invalid attribute: 0x%X", + static_cast(value)); + return false; + } + break; + + case EGL_NATIVE_RENDERABLE: + switch (value) + { + case EGL_DONT_CARE: + case EGL_TRUE: + case EGL_FALSE: + break; + default: + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_native_renderable invalid attribute: 0x%X", + static_cast(value)); + return false; + } + break; + + case EGL_TRANSPARENT_TYPE: + switch (value) + { + case EGL_NONE: + case EGL_TRANSPARENT_RGB: + // EGL_DONT_CARE doesn't match the spec, but does match dEQP usage + case EGL_DONT_CARE: + break; + default: + val->setError(EGL_BAD_ATTRIBUTE, "EGL_transparent_type invalid attribute: 0x%X", + static_cast(value)); + return false; + } + break; + + case EGL_RECORDABLE_ANDROID: + switch (value) + { + case EGL_TRUE: + case EGL_FALSE: + case EGL_DONT_CARE: + break; + default: + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_RECORDABLE_ANDROID invalid attribute: 0x%X", + static_cast(value)); + return false; + } + break; + + case EGL_COLOR_COMPONENT_TYPE_EXT: + switch (value) + { + case EGL_COLOR_COMPONENT_TYPE_FIXED_EXT: + case EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT: + case EGL_DONT_CARE: + break; + default: + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_COLOR_COMPONENT_TYPE_EXT invalid attribute: 0x%X", + static_cast(value)); + return false; + } + break; + + case EGL_MATCH_FORMAT_KHR: + switch (value) + { + case EGL_FORMAT_RGB_565_KHR: + case EGL_FORMAT_RGBA_8888_KHR: + case EGL_FORMAT_RGB_565_EXACT_KHR: + case EGL_FORMAT_RGBA_8888_EXACT_KHR: + break; + default: + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_KHR_lock_surface3 invalid attribute: 0x%X", + static_cast(value)); + return false; + } + break; + + default: + break; + } + + return true; +} + +bool ValidateConfigAttributes(const ValidationContext *val, + const Display *display, + const AttributeMap &attributes) +{ + ANGLE_VALIDATION_TRY(attributes.validate(val, display, ValidateConfigAttribute)); + + for (const auto &attrib : attributes) + { + EGLAttrib pname = attrib.first; + EGLAttrib value = attrib.second; + ANGLE_VALIDATION_TRY(ValidateConfigAttributeValue(val, display, pname, value)); + } + + return true; +} + +bool ValidateColorspaceAttribute(const ValidationContext *val, + const DisplayExtensions &displayExtensions, + EGLAttrib colorSpace) +{ + switch (colorSpace) + { + case EGL_GL_COLORSPACE_SRGB: + break; + case EGL_GL_COLORSPACE_LINEAR: + break; + case EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT: + if (!displayExtensions.glColorspaceDisplayP3Linear && + !displayExtensions.eglColorspaceAttributePassthroughANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EXT_gl_colorspace_display_p3_linear is not available."); + return false; + } + break; + case EGL_GL_COLORSPACE_DISPLAY_P3_EXT: + if (!displayExtensions.glColorspaceDisplayP3 && + !displayExtensions.eglColorspaceAttributePassthroughANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, "EXT_gl_colorspace_display_p3 is not available."); + return false; + } + break; + case EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT: + if (!displayExtensions.glColorspaceDisplayP3Passthrough && + !displayExtensions.eglColorspaceAttributePassthroughANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_EXT_gl_colorspace_display_p3_passthrough is not available."); + return false; + } + break; + case EGL_GL_COLORSPACE_SCRGB_EXT: + if (!displayExtensions.glColorspaceScrgb && + !displayExtensions.eglColorspaceAttributePassthroughANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, "EXT_gl_colorspace_scrgb is not available."); + return false; + } + break; + case EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT: + if (!displayExtensions.glColorspaceScrgbLinear && + !displayExtensions.eglColorspaceAttributePassthroughANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EXT_gl_colorspace_scrgb_linear is not available."); + return false; + } + break; + default: + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + return true; +} +bool ValidatePlatformType(const ValidationContext *val, + const ClientExtensions &clientExtensions, + EGLAttrib platformType) +{ + switch (platformType) + { + case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE: + break; + + case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE: + case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE: + if (!clientExtensions.platformANGLED3D) + { + val->setError(EGL_BAD_ATTRIBUTE, "Direct3D platform is unsupported."); + return false; + } + break; + + case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE: + case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE: + if (!clientExtensions.platformANGLEOpenGL) + { + val->setError(EGL_BAD_ATTRIBUTE, "OpenGL platform is unsupported."); + return false; + } + break; + + case EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE: + if (!clientExtensions.platformANGLENULL) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Display type EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE " + "requires EGL_ANGLE_platform_angle_null."); + return false; + } + break; + + case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE: + if (!clientExtensions.platformANGLEVulkan) + { + val->setError(EGL_BAD_ATTRIBUTE, "Vulkan platform is unsupported."); + return false; + } + break; + + case EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE: + if (!clientExtensions.platformANGLEMetal) + { + val->setError(EGL_BAD_ATTRIBUTE, "Metal platform is unsupported."); + return false; + } + break; + + default: + val->setError(EGL_BAD_ATTRIBUTE, "Unknown platform type."); + return false; + } + + return true; +} + +bool ValidateGetPlatformDisplayCommon(const ValidationContext *val, + EGLenum platform, + const void *native_display, + const AttributeMap &attribMap) +{ + const ClientExtensions &clientExtensions = Display::GetClientExtensions(); + + switch (platform) + { + case EGL_PLATFORM_ANGLE_ANGLE: + if (!clientExtensions.platformANGLE) + { + val->setError(EGL_BAD_PARAMETER, "Platform ANGLE extension is not active"); + return false; + } + break; + case EGL_PLATFORM_DEVICE_EXT: + if (!clientExtensions.platformDevice) + { + val->setError(EGL_BAD_PARAMETER, "Platform Device extension is not active"); + return false; + } + break; + case EGL_PLATFORM_GBM_KHR: + if (!clientExtensions.platformGbmKHR) + { + val->setError(EGL_BAD_PARAMETER, "Platform GBM extension is not active"); + return false; + } + break; + case EGL_PLATFORM_WAYLAND_EXT: + if (!clientExtensions.platformWaylandEXT) + { + val->setError(EGL_BAD_PARAMETER, "Platform Wayland extension is not active"); + return false; + } + break; + default: + val->setError(EGL_BAD_CONFIG, "Bad platform type."); + return false; + } + + attribMap.initializeWithoutValidation(); + + if (platform != EGL_PLATFORM_DEVICE_EXT) + { + EGLAttrib platformType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE; + bool enableAutoTrimSpecified = false; + bool enableD3D11on12 = false; + bool presentPathSpecified = false; + bool luidSpecified = false; + bool deviceIdSpecified = false; + + Optional majorVersion; + Optional minorVersion; + Optional deviceType; + Optional eglHandle; + + for (const auto &curAttrib : attribMap) + { + const EGLAttrib value = curAttrib.second; + + switch (curAttrib.first) + { + case EGL_PLATFORM_ANGLE_TYPE_ANGLE: + { + ANGLE_VALIDATION_TRY(ValidatePlatformType(val, clientExtensions, value)); + platformType = value; + break; + } + + case EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE: + if (value != EGL_DONT_CARE) + { + majorVersion = value; + } + break; + + case EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE: + if (value != EGL_DONT_CARE) + { + minorVersion = value; + } + break; + + case EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE: + switch (value) + { + case EGL_TRUE: + case EGL_FALSE: + break; + default: + val->setError(EGL_BAD_ATTRIBUTE, "Invalid automatic trim attribute"); + return false; + } + enableAutoTrimSpecified = true; + break; + + case EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE: + if (!clientExtensions.platformANGLED3D || + !clientExtensions.platformANGLED3D11ON12) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE extension not active."); + return false; + } + + switch (value) + { + case EGL_TRUE: + case EGL_FALSE: + break; + default: + val->setError(EGL_BAD_ATTRIBUTE, "Invalid D3D11on12 attribute"); + return false; + } + enableD3D11on12 = true; + break; + + case EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE: + if (!clientExtensions.experimentalPresentPath) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_ANGLE_experimental_present_path extension not active"); + return false; + } + + switch (value) + { + case EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE: + case EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE: + break; + default: + val->setError(EGL_BAD_ATTRIBUTE, + "Invalid value for EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE"); + return false; + } + presentPathSpecified = true; + break; + + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE: + switch (value) + { + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE: + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE: + break; + + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE: + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE: + if (!clientExtensions.platformANGLED3D) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_ANGLE_platform_angle_d3d is not supported"); + return false; + } + break; + + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_EGL_ANGLE: + if (!clientExtensions.platformANGLEDeviceTypeEGLANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_ANGLE_platform_angle_device_type_" + "egl_angle is not supported"); + return false; + } + break; + + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE: + if (!clientExtensions.platformANGLEDeviceTypeSwiftShader) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_ANGLE_platform_angle_device_type_" + "swiftshader is not supported"); + return false; + } + break; + + default: + val->setError(EGL_BAD_ATTRIBUTE, + "Invalid value for " + "EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE " + "attrib"); + return false; + } + deviceType = value; + break; + + case EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE: + if (!clientExtensions.platformANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_ANGLE_platform_angle extension not active"); + return false; + } + if (value != EGL_TRUE && value != EGL_FALSE && value != EGL_DONT_CARE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE " + "must be EGL_TRUE, EGL_FALSE, or " + "EGL_DONT_CARE."); + return false; + } + break; + + case EGL_PLATFORM_ANGLE_EGL_HANDLE_ANGLE: + if (value != EGL_DONT_CARE) + { + eglHandle = value; + } + break; + + case EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE: + case EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE: + luidSpecified = true; + break; + case EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_EAGL_ANGLE: + // The property does not have an effect if it's not active, so do not check + // for non-support. + switch (value) + { + case EGL_FALSE: + case EGL_TRUE: + break; + default: + val->setError(EGL_BAD_ATTRIBUTE, + "Invalid value for " + "EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_" + "EAGL_ANGLE attrib"); + return false; + } + break; + case EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_CGL_ANGLE: + // The property does not have an effect if it's not active, so do not check + // for non-support. + switch (value) + { + case EGL_FALSE: + case EGL_TRUE: + break; + default: + val->setError(EGL_BAD_ATTRIBUTE, + "Invalid value for " + "EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_" + "CGL_ANGLE attrib"); + return false; + } + break; + case EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE: + case EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE: + if (!clientExtensions.platformANGLEDeviceId) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_ANGLE_platform_angle_device_id is not supported"); + return false; + } + deviceIdSpecified = true; + break; + default: + break; + } + } + + if (!majorVersion.valid() && minorVersion.valid()) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Must specify major version if you specify a minor version."); + return false; + } + + if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE && + platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE requires a " + "device type of EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE."); + return false; + } + + if (enableAutoTrimSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE " + "requires a device type of " + "EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE."); + return false; + } + + if (enableD3D11on12) + { + if (platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE " + "requires a platform type of " + "EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE."); + return false; + } + + if (deviceType.valid() && deviceType != EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE && + deviceType != EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE requires a device " + "type of EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE " + "or EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE"); + return false; + } + } + + if (presentPathSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE requires a " + "device type of EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE."); + return false; + } + + if (luidSpecified) + { + if (platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE and " + "EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE " + "require a platform type of " + "EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE."); + return false; + } + + if (attribMap.get(EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE, 0) == 0 && + attribMap.get(EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE, 0) == 0) + { + val->setError(EGL_BAD_ATTRIBUTE, + "If either EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE " + "and/or EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE are " + "specified, at least one must non-zero."); + return false; + } + } + + if (deviceIdSpecified) + { + if (attribMap.get(EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE, 0) == 0 && + attribMap.get(EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE, 0) == 0) + { + val->setError(EGL_BAD_ATTRIBUTE, + "If either EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE " + "and/or EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE are " + "specified, at least one must non-zero."); + return false; + } + } + + if (deviceType.valid()) + { + switch (deviceType.value()) + { + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE: + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE: + if (platformType != EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE && + platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "This device type requires a " + "platform type of EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE or " + "EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE."); + return false; + } + break; + + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE: + if (platformType != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "This device type requires a " + "platform type of EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE."); + return false; + } + break; + + default: + break; + } + } + + if (platformType == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) + { + if ((majorVersion.valid() && majorVersion.value() != 1) || + (minorVersion.valid() && minorVersion.value() != 0)) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE currently " + "only supports Vulkan 1.0."); + return false; + } + } + + if (eglHandle.valid() && platformType != EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE && + platformType != EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_PLATFORM_ANGLE_EGL_HANDLE_ANGLE requires a " + "device type of EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE."); + return false; + } + } + else + { + const Device *eglDevice = static_cast(native_display); + if (eglDevice == nullptr || !Device::IsValidDevice(eglDevice)) + { + val->setError(EGL_BAD_ATTRIBUTE, + "native_display should be a valid EGL device if " + "platform equals EGL_PLATFORM_DEVICE_EXT"); + return false; + } + } + + if (attribMap.contains(EGL_POWER_PREFERENCE_ANGLE)) + { + if (!clientExtensions.displayPowerPreferenceANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Attribute EGL_POWER_PREFERENCE_ANGLE " + "requires EGL_ANGLE_display_power_preference."); + return false; + } + EGLAttrib value = attribMap.get(EGL_POWER_PREFERENCE_ANGLE, 0); + if (value != EGL_LOW_POWER_ANGLE && value != EGL_HIGH_POWER_ANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_POWER_PREFERENCE_ANGLE must be " + "either EGL_LOW_POWER_ANGLE or EGL_HIGH_POWER_ANGLE."); + return false; + } + } + + if (attribMap.contains(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE)) + { + if (!clientExtensions.featureControlANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, "EGL_ANGLE_feature_control is not supported"); + return false; + } + else if (attribMap.get(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE, 0) == 0) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_FEATURE_OVERRIDES_ENABLED_ANGLE must be a valid pointer"); + return false; + } + } + if (attribMap.contains(EGL_FEATURE_OVERRIDES_DISABLED_ANGLE)) + { + if (!clientExtensions.featureControlANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, "EGL_ANGLE_feature_control is not supported"); + return false; + } + else if (attribMap.get(EGL_FEATURE_OVERRIDES_DISABLED_ANGLE, 0) == 0) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_FEATURE_OVERRIDES_DISABLED_ANGLE must be a valid pointer"); + return false; + } + } + + return true; +} + +bool ValidateStream(const ValidationContext *val, const Display *display, const Stream *stream) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + const DisplayExtensions &displayExtensions = display->getExtensions(); + if (!displayExtensions.stream) + { + val->setError(EGL_BAD_ACCESS, "Stream extension not active"); + return false; + } + + if (stream == EGL_NO_STREAM_KHR || !display->isValidStream(stream)) + { + val->setError(EGL_BAD_STREAM_KHR, "Invalid stream"); + return false; + } + + return true; +} + +bool ValidateLabeledObject(const ValidationContext *val, + const Display *display, + ObjectType objectType, + EGLObjectKHR object, + LabeledObject **outLabeledObject) +{ + switch (objectType) + { + case ObjectType::Context: + { + gl::Context *context = static_cast(object); + ANGLE_VALIDATION_TRY(ValidateContext(val, display, context)); + *outLabeledObject = context; + break; + } + + case ObjectType::Display: + { + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + if (display != object) + { + if (val) + { + val->setError(EGL_BAD_PARAMETER, + "when object type is EGL_OBJECT_DISPLAY_KHR, the " + "object must be the same as the display."); + } + return false; + } + + *outLabeledObject = static_cast(object); + break; + } + + case ObjectType::Image: + { + Image *image = static_cast(object); + ANGLE_VALIDATION_TRY(ValidateImage(val, display, image)); + *outLabeledObject = image; + break; + } + + case ObjectType::Stream: + { + Stream *stream = static_cast(object); + ANGLE_VALIDATION_TRY(ValidateStream(val, display, stream)); + *outLabeledObject = stream; + break; + } + + case ObjectType::Surface: + { + Surface *surface = static_cast(object); + ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); + *outLabeledObject = surface; + break; + } + + case ObjectType::Sync: + { + Sync *sync = static_cast(object); + ANGLE_VALIDATION_TRY(ValidateSync(val, display, sync)); + *outLabeledObject = sync; + break; + } + + case ObjectType::Thread: + { + ASSERT(val); + *outLabeledObject = val->eglThread; + break; + } + + default: + if (val) + { + val->setError(EGL_BAD_PARAMETER, "unknown object type."); + } + return false; + } + + return true; +} + +// This is a common sub-check of Display status that's shared by multiple functions +bool ValidateDisplayPointer(const ValidationContext *val, const Display *display) +{ + if (display == EGL_NO_DISPLAY) + { + if (val) + { + val->setError(EGL_BAD_DISPLAY, "display is EGL_NO_DISPLAY."); + } + return false; + } + + if (!Display::isValidDisplay(display)) + { + if (val) + { + val->setError(EGL_BAD_DISPLAY, "display is not a valid display: 0x%p", display); + } + return false; + } + + return true; +} + +bool ValidCompositorTimingName(CompositorTiming name) +{ + switch (name) + { + case CompositorTiming::CompositeDeadline: + case CompositorTiming::CompositInterval: + case CompositorTiming::CompositToPresentLatency: + return true; + + default: + return false; + } +} + +bool ValidTimestampType(Timestamp timestamp) +{ + switch (timestamp) + { + case Timestamp::RequestedPresentTime: + case Timestamp::RenderingCompleteTime: + case Timestamp::CompositionLatchTime: + case Timestamp::FirstCompositionStartTime: + case Timestamp::LastCompositionStartTime: + case Timestamp::FirstCompositionGPUFinishedTime: + case Timestamp::DisplayPresentTime: + case Timestamp::DequeueReadyTime: + case Timestamp::ReadsDoneTime: + return true; + + default: + return false; + } +} + +bool ValidateCompatibleSurface(const ValidationContext *val, + const Display *display, + const gl::Context *context, + const Surface *surface) +{ + const Config *contextConfig = context->getConfig(); + const Config *surfaceConfig = surface->getConfig(); + + if (context->getClientType() != EGL_OPENGL_API) + { + // Surface compatible with client API - only OPENGL_ES supported + switch (context->getClientMajorVersion()) + { + case 1: + if (!(surfaceConfig->renderableType & EGL_OPENGL_ES_BIT)) + { + val->setError(EGL_BAD_MATCH, "Surface not compatible with OpenGL ES 1.x."); + return false; + } + break; + case 2: + if (!(surfaceConfig->renderableType & EGL_OPENGL_ES2_BIT)) + { + val->setError(EGL_BAD_MATCH, "Surface not compatible with OpenGL ES 2.x."); + return false; + } + break; + case 3: + if (!(surfaceConfig->renderableType & (EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT))) + { + val->setError(EGL_BAD_MATCH, "Surface not compatible with OpenGL ES 3.x."); + return false; + } + break; + default: + val->setError(EGL_BAD_MATCH, "Surface not compatible with Context API."); + return false; + } + } + else + { + if (!(surfaceConfig->renderableType & EGL_OPENGL_BIT)) + { + val->setError(EGL_BAD_MATCH, "Surface not compatible with OpenGL Desktop."); + return false; + } + } + + // EGL KHR no config context + if (context->getConfig() == EGL_NO_CONFIG_KHR) + { + const DisplayExtensions &displayExtensions = display->getExtensions(); + if (displayExtensions.noConfigContext) + { + return true; + } + val->setError(EGL_BAD_MATCH, "Context with no config is not supported."); + return false; + } + + // Config compatibility is defined in section 2.2 of the EGL 1.5 spec + + bool colorBufferCompat = surfaceConfig->colorBufferType == contextConfig->colorBufferType; + if (!colorBufferCompat) + { + val->setError(EGL_BAD_MATCH, "Color buffer types are not compatible."); + return false; + } + + bool colorCompat = surfaceConfig->redSize == contextConfig->redSize && + surfaceConfig->greenSize == contextConfig->greenSize && + surfaceConfig->blueSize == contextConfig->blueSize && + surfaceConfig->alphaSize == contextConfig->alphaSize && + surfaceConfig->luminanceSize == contextConfig->luminanceSize; + if (!colorCompat) + { + val->setError(EGL_BAD_MATCH, "Color buffer sizes are not compatible."); + return false; + } + + bool componentTypeCompat = + surfaceConfig->colorComponentType == contextConfig->colorComponentType; + if (!componentTypeCompat) + { + val->setError(EGL_BAD_MATCH, "Color buffer component types are not compatible."); + return false; + } + + bool dsCompat = surfaceConfig->depthSize == contextConfig->depthSize && + surfaceConfig->stencilSize == contextConfig->stencilSize; + if (!dsCompat) + { + val->setError(EGL_BAD_MATCH, "Depth-stencil buffer types are not compatible."); + return false; + } + + bool surfaceTypeCompat = (surfaceConfig->surfaceType & contextConfig->surfaceType) != 0; + if (!surfaceTypeCompat) + { + val->setError(EGL_BAD_MATCH, "Surface type is not compatible."); + return false; + } + + return true; +} + +bool ValidateCreateSyncBase(const ValidationContext *val, + const Display *display, + EGLenum type, + const AttributeMap &attribs, + bool isExt) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + attribs.initializeWithoutValidation(); + + gl::Context *currentContext = val->eglThread->getContext(); + egl::Display *currentDisplay = currentContext ? currentContext->getDisplay() : nullptr; + + switch (type) + { + case EGL_SYNC_FENCE_KHR: + if (!attribs.isEmpty()) + { + val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute"); + return false; + } + + if (!display->getExtensions().fenceSync) + { + val->setError(EGL_BAD_MATCH, "EGL_KHR_fence_sync extension is not available"); + return false; + } + + if (display != currentDisplay) + { + val->setError(EGL_BAD_MATCH, + "CreateSync can only be called on the current display"); + return false; + } + + ANGLE_VALIDATION_TRY(ValidateContext(val, currentDisplay, currentContext)); + + if (!currentContext->getExtensions().EGLSyncOES) + { + val->setError(EGL_BAD_MATCH, + "EGL_SYNC_FENCE_KHR cannot be used without " + "GL_OES_EGL_sync support."); + return false; + } + break; + + case EGL_SYNC_NATIVE_FENCE_ANDROID: + if (!display->getExtensions().fenceSync) + { + val->setError(EGL_BAD_MATCH, "EGL_KHR_fence_sync extension is not available"); + return false; + } + + if (!display->getExtensions().nativeFenceSyncANDROID) + { + val->setError(EGL_BAD_DISPLAY, + "EGL_ANDROID_native_fence_sync extension is not available."); + return false; + } + + if (display != currentDisplay) + { + val->setError(EGL_BAD_MATCH, + "CreateSync can only be called on the current display"); + return false; + } + + ANGLE_VALIDATION_TRY(ValidateContext(val, currentDisplay, currentContext)); + + if (!currentContext->getExtensions().EGLSyncOES) + { + val->setError(EGL_BAD_MATCH, + "EGL_SYNC_FENCE_KHR cannot be used without " + "GL_OES_EGL_sync support."); + return false; + } + + for (const auto &attributeIter : attribs) + { + EGLAttrib attribute = attributeIter.first; + + switch (attribute) + { + case EGL_SYNC_NATIVE_FENCE_FD_ANDROID: + break; + + default: + val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute"); + return false; + } + } + break; + + case EGL_SYNC_REUSABLE_KHR: + if (!attribs.isEmpty()) + { + val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute"); + return false; + } + + if (!display->getExtensions().reusableSyncKHR) + { + val->setError(EGL_BAD_MATCH, "EGL_KHR_reusable_sync extension is not available."); + return false; + } + break; + + case EGL_SYNC_METAL_SHARED_EVENT_ANGLE: + if (!display->getExtensions().fenceSync) + { + val->setError(EGL_BAD_MATCH, "EGL_KHR_fence_sync extension is not available"); + return false; + } + + if (!display->getExtensions().mtlSyncSharedEventANGLE) + { + val->setError(EGL_BAD_DISPLAY, + "EGL_ANGLE_metal_shared_event_sync is not available"); + return false; + } + + if (display != currentDisplay) + { + val->setError(EGL_BAD_MATCH, + "CreateSync can only be called on the current display"); + return false; + } + + ANGLE_VALIDATION_TRY(ValidateContext(val, currentDisplay, currentContext)); + + // This should be implied by exposing EGL_KHR_fence_sync + ASSERT(currentContext->getExtensions().EGLSyncOES); + + for (const auto &attributeIter : attribs) + { + EGLAttrib attribute = attributeIter.first; + EGLAttrib value = attributeIter.second; + + switch (attribute) + { + case EGL_SYNC_METAL_SHARED_EVENT_OBJECT_ANGLE: + if (!value) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_SYNC_METAL_SHARED_EVENT_ANGLE can't be NULL"); + return false; + } + break; + + case EGL_SYNC_METAL_SHARED_EVENT_SIGNAL_VALUE_LO_ANGLE: + case EGL_SYNC_METAL_SHARED_EVENT_SIGNAL_VALUE_HI_ANGLE: + break; + + default: + val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute"); + return false; + } + } + break; + + default: + if (isExt) + { + val->setError(EGL_BAD_ATTRIBUTE, "Invalid type parameter"); + return false; + } + else + { + val->setError(EGL_BAD_PARAMETER, "Invalid type parameter"); + return false; + } + } + + return true; +} + +bool ValidateGetSyncAttribBase(const ValidationContext *val, + const Display *display, + const Sync *sync, + EGLint attribute) +{ + ANGLE_VALIDATION_TRY(ValidateSync(val, display, sync)); + + switch (attribute) + { + case EGL_SYNC_CONDITION_KHR: + switch (sync->getType()) + { + case EGL_SYNC_FENCE_KHR: + case EGL_SYNC_NATIVE_FENCE_ANDROID: + case EGL_SYNC_METAL_SHARED_EVENT_ANGLE: + break; + + default: + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_SYNC_CONDITION_KHR is not valid for this sync type."); + return false; + } + break; + + // The following attributes are accepted by all types + case EGL_SYNC_TYPE_KHR: + case EGL_SYNC_STATUS_KHR: + break; + + default: + val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute"); + return false; + } + + return true; +} + +bool ValidateQueryDisplayAttribBase(const ValidationContext *val, + const Display *display, + const EGLint attribute) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + switch (attribute) + { + case EGL_DEVICE_EXT: + if (!Display::GetClientExtensions().deviceQueryEXT) + { + val->setError(EGL_BAD_DISPLAY, "EGL_EXT_device_query extension is not available."); + return false; + } + break; + + case EGL_FEATURE_COUNT_ANGLE: + if (!Display::GetClientExtensions().featureControlANGLE) + { + val->setError(EGL_BAD_DISPLAY, + "EGL_ANGLE_feature_control extension is not available."); + return false; + } + break; + + default: + val->setError(EGL_BAD_ATTRIBUTE, "attribute is not valid."); + return false; + } + + return true; +} + +bool ValidateCreateContextAttribute(const ValidationContext *val, + const Display *display, + EGLAttrib attribute) +{ + switch (attribute) + { + case EGL_CONTEXT_CLIENT_VERSION: + case EGL_CONTEXT_MINOR_VERSION: + case EGL_CONTEXT_FLAGS_KHR: + case EGL_CONTEXT_OPENGL_DEBUG: + break; + + case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR: + if (val->eglThread->getAPI() != EGL_OPENGL_API) + { + // Only valid for OpenGL (non-ES) contexts + val->setError(EGL_BAD_ATTRIBUTE, "OpenGL profile mask requires an OpenGL context."); + return false; + } + break; + + case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT: + if (!display->getExtensions().createContextRobustness) + { + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + break; + + case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT: + if (!display->getExtensions().createContextRobustness) + { + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + break; + + case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY: + { + // We either need to have - + // 1. EGL 1.5 which added support for this as part of core spec + // 2. EGL_KHR_create_context extension which requires EGL 1.4 + constexpr EGLint kRequiredMajorVersion = 1; + constexpr EGLint kRequiredMinorVersion = 5; + if ((kEglMajorVersion < kRequiredMajorVersion || + kEglMinorVersion < kRequiredMinorVersion) && + !display->getExtensions().createContext) + { + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + break; + } + + case EGL_CONTEXT_OPENGL_NO_ERROR_KHR: + if (!display->getExtensions().createContextNoError) + { + val->setError(EGL_BAD_ATTRIBUTE, "Invalid Context attribute."); + return false; + } + break; + + case EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE: + if (!display->getExtensions().createContextWebGLCompatibility) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Attribute " + "EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE requires " + "EGL_ANGLE_create_context_webgl_compatibility."); + return false; + } + break; + + case EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM: + if (!display->getExtensions().createContextBindGeneratesResource) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Attribute EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM requires " + "EGL_CHROMIUM_create_context_bind_generates_resource."); + return false; + } + break; + + case EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE: + if (!display->getExtensions().displayTextureShareGroup) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Attribute " + "EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE requires " + "EGL_ANGLE_display_texture_share_group."); + return false; + } + break; + + case EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE: + if (!display->getExtensions().displayTextureShareGroup) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Attribute " + "EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE requires " + "EGL_ANGLE_display_semaphore_share_group."); + return false; + } + break; + + case EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE: + if (!display->getExtensions().createContextClientArrays) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Attribute EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE requires " + "EGL_ANGLE_create_context_client_arrays."); + return false; + } + break; + + case EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE: + if (!display->getExtensions().programCacheControlANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Attribute EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE " + "requires EGL_ANGLE_program_cache_control."); + return false; + } + break; + + case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE: + if (!display->getExtensions().robustResourceInitializationANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Attribute EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE " + "requires EGL_ANGLE_robust_resource_initialization."); + return false; + } + break; + + case EGL_EXTENSIONS_ENABLED_ANGLE: + if (!display->getExtensions().createContextExtensionsEnabled) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Attribute EGL_EXTENSIONS_ENABLED_ANGLE " + "requires EGL_ANGLE_create_context_extensions_enabled."); + return false; + } + break; + + case EGL_POWER_PREFERENCE_ANGLE: + if (!display->getExtensions().powerPreference) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Attribute EGL_POWER_PREFERENCE_ANGLE " + "requires EGL_ANGLE_power_preference."); + return false; + } + break; + + case EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE: + if (!display->getExtensions().createContextBackwardsCompatible) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Attribute EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE " + "requires EGL_ANGLE_create_context_backwards_compatible."); + return false; + } + break; + + case EGL_CONTEXT_PRIORITY_LEVEL_IMG: + if (!display->getExtensions().contextPriority) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Attribute EGL_CONTEXT_PRIORITY_LEVEL_IMG requires " + "extension EGL_IMG_context_priority."); + return false; + } + break; + + case EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV: + if (!display->getExtensions().robustnessVideoMemoryPurgeNV) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Attribute EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV requires " + "extension EGL_NV_robustness_video_memory_purge."); + return false; + } + break; + + case EGL_EXTERNAL_CONTEXT_ANGLE: + if (!display->getExtensions().externalContextAndSurface) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Attribute " + "EGL_EXTERNAL_CONTEXT_ANGLE requires " + "EGL_ANGLE_external_context_and_surface."); + return false; + } + break; + case EGL_EXTERNAL_CONTEXT_SAVE_STATE_ANGLE: + if (!display->getExtensions().externalContextAndSurface) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Attribute " + "EGL_EXTERNAL_CONTEXT_SAVE_STATE_ANGLE requires " + "EGL_ANGLE_external_context_and_surface."); + return false; + } + break; + + case EGL_PROTECTED_CONTENT_EXT: + if (!display->getExtensions().protectedContentEXT) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Attribute EGL_PROTECTED_CONTEXT_EXT requires " + "extension EGL_EXT_protected_content."); + return false; + } + break; + + case EGL_CONTEXT_VIRTUALIZATION_GROUP_ANGLE: + if (!display->getExtensions().contextVirtualizationANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Attribute EGL_CONTEXT_VIRTUALIZATION_GROUP_ANGLE requires " + "extension EGL_ANGLE_context_virtualization."); + return false; + } + break; + + case EGL_CONTEXT_METAL_OWNERSHIP_IDENTITY_ANGLE: + if (!display->getExtensions().metalCreateContextOwnershipIdentityANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Attribute EGL_CONTEXT_METAL_OWNERSHIP_IDENTITY_ANGLE requires " + "EGL_ANGLE_metal_create_context_ownership_identity."); + } + break; + + default: + val->setError(EGL_BAD_ATTRIBUTE, "Unknown attribute: 0x%04" PRIxPTR "X", attribute); + return false; + } + + return true; +} + +bool ValidateCreateContextAttributeValue(const ValidationContext *val, + const Display *display, + const gl::Context *shareContext, + EGLAttrib attribute, + EGLAttrib value) +{ + switch (attribute) + { + case EGL_CONTEXT_CLIENT_VERSION: + case EGL_CONTEXT_MINOR_VERSION: + case EGL_CONTEXT_OPENGL_DEBUG: + case EGL_CONTEXT_VIRTUALIZATION_GROUP_ANGLE: + break; + + case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR: + { + constexpr EGLint kValidProfileMaskFlags = + (EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT | + EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT); + if ((value & ~kValidProfileMaskFlags) != 0) + { + val->setError(EGL_BAD_ATTRIBUTE, "Invalid OpenGL profile mask."); + return false; + } + break; + } + + case EGL_CONTEXT_FLAGS_KHR: + { + // Note: EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR does not apply to ES + constexpr EGLint kValidContextFlags = + (EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR | EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR); + if ((value & ~kValidContextFlags) != 0) + { + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + break; + } + + case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT: + if (value != EGL_TRUE && value != EGL_FALSE) + { + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + break; + + case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT: + case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY: + if (value != EGL_LOSE_CONTEXT_ON_RESET_EXT && value != EGL_NO_RESET_NOTIFICATION_EXT) + { + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + + if (shareContext && shareContext->isResetNotificationEnabled() != + (value == EGL_LOSE_CONTEXT_ON_RESET_EXT)) + { + val->setError(EGL_BAD_MATCH); + return false; + } + break; + + case EGL_CONTEXT_OPENGL_NO_ERROR_KHR: + if (value != EGL_TRUE && value != EGL_FALSE) + { + val->setError(EGL_BAD_ATTRIBUTE, "Attribute must be EGL_TRUE or EGL_FALSE."); + return false; + } + break; + + case EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE: + if (value != EGL_TRUE && value != EGL_FALSE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE must be " + "EGL_TRUE or EGL_FALSE."); + return false; + } + break; + + case EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM: + if (value != EGL_TRUE && value != EGL_FALSE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM " + "must be EGL_TRUE or EGL_FALSE."); + return false; + } + break; + + case EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE: + if (value != EGL_TRUE && value != EGL_FALSE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE must be " + "EGL_TRUE or EGL_FALSE."); + return false; + } + if (shareContext && + shareContext->usingDisplayTextureShareGroup() != (value == EGL_TRUE)) + { + val->setError(EGL_BAD_ATTRIBUTE, + "All contexts within a share group must be " + "created with the same value of " + "EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE."); + return false; + } + break; + + case EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE: + if (value != EGL_TRUE && value != EGL_FALSE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE must be " + "EGL_TRUE or EGL_FALSE."); + return false; + } + if (shareContext && + shareContext->usingDisplaySemaphoreShareGroup() != (value == EGL_TRUE)) + { + val->setError(EGL_BAD_ATTRIBUTE, + "All contexts within a share group must be " + "created with the same value of " + "EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE."); + return false; + } + break; + + case EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE: + if (value != EGL_TRUE && value != EGL_FALSE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE must " + "be EGL_TRUE or EGL_FALSE."); + return false; + } + break; + + case EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE: + if (value != EGL_TRUE && value != EGL_FALSE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE must " + "be EGL_TRUE or EGL_FALSE."); + return false; + } + break; + + case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE: + if (value != EGL_TRUE && value != EGL_FALSE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE must be " + "either EGL_TRUE or EGL_FALSE."); + return false; + } + break; + + case EGL_EXTENSIONS_ENABLED_ANGLE: + if (value != EGL_TRUE && value != EGL_FALSE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_EXTENSIONS_ENABLED_ANGLE must be " + "either EGL_TRUE or EGL_FALSE."); + return false; + } + break; + + case EGL_POWER_PREFERENCE_ANGLE: + if (value != EGL_LOW_POWER_ANGLE && value != EGL_HIGH_POWER_ANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_POWER_PREFERENCE_ANGLE must be " + "either EGL_LOW_POWER_ANGLE or EGL_HIGH_POWER_ANGLE."); + return false; + } + break; + + case EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE: + if (value != EGL_TRUE && value != EGL_FALSE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE must be " + "either EGL_TRUE or EGL_FALSE."); + return false; + } + break; + + case EGL_CONTEXT_PRIORITY_LEVEL_IMG: + switch (value) + { + case EGL_CONTEXT_PRIORITY_LOW_IMG: + case EGL_CONTEXT_PRIORITY_MEDIUM_IMG: + case EGL_CONTEXT_PRIORITY_HIGH_IMG: + break; + default: + val->setError(EGL_BAD_ATTRIBUTE, + "Attribute EGL_CONTEXT_PRIORITY_LEVEL_IMG " + "must be one of: EGL_CONTEXT_PRIORITY_LOW_IMG, " + "EGL_CONTEXT_PRIORITY_MEDIUM_IMG, or " + "EGL_CONTEXT_PRIORITY_HIGH_IMG."); + return false; + } + break; + + case EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV: + if (value != EGL_TRUE && value != EGL_FALSE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV must " + "be either EGL_TRUE or EGL_FALSE."); + return false; + } + break; + + case EGL_EXTERNAL_CONTEXT_ANGLE: + if (value != EGL_TRUE && value != EGL_FALSE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_EXTERNAL_CONTEXT_ANGLE must " + "be either EGL_TRUE or EGL_FALSE."); + return false; + } + if (shareContext && (value == EGL_TRUE)) + { + val->setError( + EGL_BAD_ATTRIBUTE, + "EGL_EXTERNAL_CONTEXT_ANGLE doesn't allow creating with sharedContext."); + return false; + } + break; + case EGL_EXTERNAL_CONTEXT_SAVE_STATE_ANGLE: + if (value != EGL_TRUE && value != EGL_FALSE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_EXTERNAL_CONTEXT_SAVE_STATE_ANGLE must " + "be either EGL_TRUE or EGL_FALSE."); + return false; + } + break; + + case EGL_PROTECTED_CONTENT_EXT: + if (value != EGL_TRUE && value != EGL_FALSE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_PROTECTED_CONTENT_EXT must " + "be either EGL_TRUE or EGL_FALSE."); + return false; + } + break; + + case EGL_CONTEXT_METAL_OWNERSHIP_IDENTITY_ANGLE: + if (value == 0) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_CONTEXT_METAL_OWNERSHIP_IDENTITY_ANGLE must" + "be non-zero."); + return false; + } + break; + + default: + UNREACHABLE(); + return false; + } + + return true; +} + +bool ValidateCreatePbufferSurfaceAttribute(const ValidationContext *val, + const Display *display, + EGLAttrib attribute) +{ + const DisplayExtensions &displayExtensions = display->getExtensions(); + + switch (attribute) + { + case EGL_WIDTH: + case EGL_HEIGHT: + case EGL_LARGEST_PBUFFER: + case EGL_TEXTURE_FORMAT: + case EGL_TEXTURE_TARGET: + case EGL_MIPMAP_TEXTURE: + case EGL_VG_COLORSPACE: + case EGL_GL_COLORSPACE: + case EGL_VG_ALPHA_FORMAT: + break; + + case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE: + if (!displayExtensions.robustResourceInitializationANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Attribute EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE " + "requires EGL_ANGLE_robust_resource_initialization."); + return false; + } + break; + + case EGL_PROTECTED_CONTENT_EXT: + if (!displayExtensions.protectedContentEXT) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Attribute EGL_PROTECTED_CONTEXT_EXT requires " + "extension EGL_EXT_protected_content."); + return false; + } + break; + + default: + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + + return true; +} + +bool ValidateCreatePbufferSurfaceAttributeValue(const ValidationContext *val, + const Display *display, + EGLAttrib attribute, + EGLAttrib value) +{ + const DisplayExtensions &displayExtensions = display->getExtensions(); + + switch (attribute) + { + case EGL_WIDTH: + case EGL_HEIGHT: + if (value < 0) + { + val->setError(EGL_BAD_PARAMETER); + return false; + } + break; + + case EGL_LARGEST_PBUFFER: + break; + + case EGL_TEXTURE_FORMAT: + switch (value) + { + case EGL_NO_TEXTURE: + case EGL_TEXTURE_RGB: + case EGL_TEXTURE_RGBA: + break; + default: + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + break; + + case EGL_TEXTURE_TARGET: + switch (value) + { + case EGL_NO_TEXTURE: + case EGL_TEXTURE_2D: + break; + default: + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + break; + + case EGL_MIPMAP_TEXTURE: + break; + + case EGL_VG_COLORSPACE: + break; + + case EGL_GL_COLORSPACE: + ANGLE_VALIDATION_TRY(ValidateColorspaceAttribute(val, displayExtensions, value)); + break; + + case EGL_VG_ALPHA_FORMAT: + break; + + case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE: + ASSERT(displayExtensions.robustResourceInitializationANGLE); + if (value != EGL_TRUE && value != EGL_FALSE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE must be " + "either EGL_TRUE or EGL_FALSE."); + return false; + } + break; + + case EGL_PROTECTED_CONTENT_EXT: + ASSERT(displayExtensions.protectedContentEXT); + if (value != EGL_TRUE && value != EGL_FALSE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_PROTECTED_CONTENT_EXT must " + "be either EGL_TRUE or EGL_FALSE."); + return false; + } + break; + + default: + UNREACHABLE(); + return false; + } + + return true; +} +} // anonymous namespace + +void ValidationContext::setError(EGLint error) const +{ + eglThread->setError(error, entryPoint, labeledObject, nullptr); +} + +void ValidationContext::setError(EGLint error, const char *message...) const +{ + ASSERT(message); + + constexpr uint32_t kBufferSize = 1000; + char buffer[kBufferSize]; + + va_list args; + va_start(args, message); + vsnprintf(buffer, kBufferSize, message, args); + + eglThread->setError(error, entryPoint, labeledObject, buffer); +} + +bool ValidateDisplay(const ValidationContext *val, const Display *display) +{ + ANGLE_VALIDATION_TRY(ValidateDisplayPointer(val, display)); + + if (!display->isInitialized()) + { + if (val) + { + val->setError(EGL_NOT_INITIALIZED, "display is not initialized."); + } + return false; + } + + if (display->isDeviceLost()) + { + if (val) + { + val->setError(EGL_CONTEXT_LOST, "display had a context loss"); + } + return false; + } + + return true; +} + +bool ValidateSurface(const ValidationContext *val, const Display *display, const Surface *surface) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + if (!display->isValidSurface(surface)) + { + if (val) + { + val->setError(EGL_BAD_SURFACE); + } + return false; + } + + return true; +} + +bool ValidateConfig(const ValidationContext *val, const Display *display, const Config *config) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + if (!display->isValidConfig(config)) + { + if (val) + { + val->setError(EGL_BAD_CONFIG); + } + return false; + } + + return true; +} + +bool ValidateContext(const ValidationContext *val, + const Display *display, + const gl::Context *context) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + if (!display->isValidContext(context)) + { + if (val) + { + val->setError(EGL_BAD_CONTEXT); + } + return false; + } + + return true; +} + +bool ValidateImage(const ValidationContext *val, const Display *display, const Image *image) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + if (!display->isValidImage(image)) + { + if (val) + { + val->setError(EGL_BAD_PARAMETER, "image is not valid."); + } + return false; + } + + return true; +} + +bool ValidateDevice(const ValidationContext *val, const Device *device) +{ + if (device == EGL_NO_DEVICE_EXT) + { + if (val) + { + val->setError(EGL_BAD_ACCESS, "device is EGL_NO_DEVICE."); + } + return false; + } + + if (!Device::IsValidDevice(device)) + { + if (val) + { + val->setError(EGL_BAD_ACCESS, "device is not valid."); + } + return false; + } + + return true; +} + +bool ValidateSync(const ValidationContext *val, const Display *display, const Sync *sync) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + if (!display->isValidSync(sync)) + { + if (val) + { + val->setError(EGL_BAD_PARAMETER, "sync object is not valid."); + } + return false; + } + + return true; +} + +const Thread *GetThreadIfValid(const Thread *thread) +{ + // Threads should always be valid + return thread; +} + +const Display *GetDisplayIfValid(const Display *display) +{ + return ValidateDisplay(nullptr, display) ? display : nullptr; +} + +const Surface *GetSurfaceIfValid(const Display *display, const Surface *surface) +{ + return ValidateSurface(nullptr, display, surface) ? surface : nullptr; +} + +const Image *GetImageIfValid(const Display *display, const Image *image) +{ + return ValidateImage(nullptr, display, image) ? image : nullptr; +} + +const Stream *GetStreamIfValid(const Display *display, const Stream *stream) +{ + return ValidateStream(nullptr, display, stream) ? stream : nullptr; +} + +const gl::Context *GetContextIfValid(const Display *display, const gl::Context *context) +{ + return ValidateContext(nullptr, display, context) ? context : nullptr; +} + +const Device *GetDeviceIfValid(const Device *device) +{ + return ValidateDevice(nullptr, device) ? device : nullptr; +} + +const Sync *GetSyncIfValid(const Display *display, const Sync *sync) +{ + return ValidateSync(nullptr, display, sync) ? sync : nullptr; +} + +LabeledObject *GetLabeledObjectIfValid(Thread *thread, + const Display *display, + ObjectType objectType, + EGLObjectKHR object) +{ + if (objectType == ObjectType::Thread) + { + return thread; + } + + LabeledObject *labeledObject = nullptr; + if (ValidateLabeledObject(nullptr, display, objectType, object, &labeledObject)) + { + return labeledObject; + } + + return nullptr; +} + +bool ValidateInitialize(const ValidationContext *val, + const Display *display, + const EGLint *major, + const EGLint *minor) +{ + return ValidateDisplayPointer(val, display); +} + +bool ValidateTerminate(const ValidationContext *val, const Display *display) +{ + return ValidateDisplayPointer(val, display); +} + +bool ValidateCreateContext(const ValidationContext *val, + const Display *display, + const Config *configuration, + const gl::Context *shareContext, + const AttributeMap &attributes) +{ + if (configuration) + { + ANGLE_VALIDATION_TRY(ValidateConfig(val, display, configuration)); + } + else + { + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + const DisplayExtensions &displayExtensions = display->getExtensions(); + if (!displayExtensions.noConfigContext) + { + val->setError(EGL_BAD_CONFIG); + return false; + } + } + + ANGLE_VALIDATION_TRY(attributes.validate(val, display, ValidateCreateContextAttribute)); + + for (const auto &attributePair : attributes) + { + EGLAttrib attribute = attributePair.first; + EGLAttrib value = attributePair.second; + ANGLE_VALIDATION_TRY( + ValidateCreateContextAttributeValue(val, display, shareContext, attribute, value)); + } + + // Get the requested client version (default is 1) and check it is 2 or 3. + EGLAttrib clientMajorVersion = attributes.get(EGL_CONTEXT_CLIENT_VERSION, 1); + EGLAttrib clientMinorVersion = attributes.get(EGL_CONTEXT_MINOR_VERSION, 0); + EGLenum api = val->eglThread->getAPI(); + + switch (api) + { + case EGL_OPENGL_ES_API: + switch (clientMajorVersion) + { + case 1: + if (clientMinorVersion != 0 && clientMinorVersion != 1) + { + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + if (configuration == EGL_NO_CONFIG_KHR) + { + val->setError(EGL_BAD_MATCH); + return false; + } + if ((configuration != EGL_NO_CONFIG_KHR) && + !(configuration->renderableType & EGL_OPENGL_ES_BIT)) + { + val->setError(EGL_BAD_MATCH); + return false; + } + break; + + case 2: + if (clientMinorVersion != 0) + { + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + if ((configuration != EGL_NO_CONFIG_KHR) && + !(configuration->renderableType & EGL_OPENGL_ES2_BIT)) + { + val->setError(EGL_BAD_MATCH); + return false; + } + break; + case 3: + if (clientMinorVersion < 0 || clientMinorVersion > 2) + { + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + if ((configuration != EGL_NO_CONFIG_KHR) && + !(configuration->renderableType & EGL_OPENGL_ES3_BIT)) + { + val->setError(EGL_BAD_MATCH); + return false; + } + if (display->getMaxSupportedESVersion() < + gl::Version(static_cast(clientMajorVersion), + static_cast(clientMinorVersion))) + { + gl::Version max = display->getMaxSupportedESVersion(); + val->setError(EGL_BAD_ATTRIBUTE, + "Requested GLES version (%" PRIxPTR ".%" PRIxPTR + ") is greater than " + "max supported (%d, %d).", + clientMajorVersion, clientMinorVersion, max.major, max.minor); + return false; + } + if ((attributes.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == + EGL_TRUE) && + (clientMinorVersion > 1)) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Requested GLES version (%" PRIxPTR ".%" PRIxPTR + ") is greater than " + "max supported 3.1 for WebGL.", + clientMajorVersion, clientMinorVersion); + return false; + } + break; + default: + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + break; + + case EGL_OPENGL_API: + // The requested configuration must use EGL_OPENGL_BIT if EGL_OPENGL_BIT is the + // currently bound API. + if ((configuration != EGL_NO_CONFIG_KHR) && + !(configuration->renderableType & EGL_OPENGL_BIT)) + { + val->setError(EGL_BAD_CONFIG); + return false; + } + // TODO(http://anglebug.com/7533): validate desktop OpenGL versions and profile mask + break; + + default: + val->setError(EGL_BAD_MATCH, "Unsupported API."); + return false; + } + + if (shareContext) + { + // Shared context is invalid or is owned by another display + if (!display->isValidContext(shareContext)) + { + val->setError(EGL_BAD_MATCH); + return false; + } + } + + return true; +} + +bool ValidateCreateWindowSurface(const ValidationContext *val, + const Display *display, + const Config *config, + EGLNativeWindowType window, + const AttributeMap &attributes) +{ + ANGLE_VALIDATION_TRY(ValidateConfig(val, display, config)); + + if (!display->isValidNativeWindow(window)) + { + val->setError(EGL_BAD_NATIVE_WINDOW); + return false; + } + + const DisplayExtensions &displayExtensions = display->getExtensions(); + + attributes.initializeWithoutValidation(); + + for (const auto &attributeIter : attributes) + { + EGLAttrib attribute = attributeIter.first; + EGLAttrib value = attributeIter.second; + + switch (attribute) + { + case EGL_RENDER_BUFFER: + switch (value) + { + case EGL_BACK_BUFFER: + break; + case EGL_SINGLE_BUFFER: + break; + default: + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + break; + + case EGL_POST_SUB_BUFFER_SUPPORTED_NV: + if (!displayExtensions.postSubBuffer) + { + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + break; + + case EGL_WIDTH: + case EGL_HEIGHT: + if (!displayExtensions.windowFixedSize) + { + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + if (value < 0) + { + val->setError(EGL_BAD_PARAMETER); + return false; + } + break; + + case EGL_FIXED_SIZE_ANGLE: + if (!displayExtensions.windowFixedSize) + { + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + break; + + case EGL_SURFACE_ORIENTATION_ANGLE: + if (!displayExtensions.surfaceOrientation) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_ANGLE_surface_orientation is not enabled."); + return false; + } + break; + + case EGL_VG_COLORSPACE: + if (value != EGL_VG_COLORSPACE_sRGB) + { + val->setError(EGL_BAD_MATCH); + return false; + } + break; + + case EGL_GL_COLORSPACE: + ANGLE_VALIDATION_TRY(ValidateColorspaceAttribute(val, displayExtensions, value)); + break; + + case EGL_VG_ALPHA_FORMAT: + val->setError(EGL_BAD_MATCH); + return false; + + case EGL_DIRECT_COMPOSITION_ANGLE: + if (!displayExtensions.directComposition) + { + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + break; + + case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE: + if (!display->getExtensions().robustResourceInitializationANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Attribute EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE " + "requires EGL_ANGLE_robust_resource_initialization."); + return false; + } + if (value != EGL_TRUE && value != EGL_FALSE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE must be " + "either EGL_TRUE or EGL_FALSE."); + return false; + } + break; + + case EGL_GGP_STREAM_DESCRIPTOR_ANGLE: + if (!display->getExtensions().ggpStreamDescriptor) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_GGP_STREAM_DESCRIPTOR_ANGLE requires " + "EGL_ANGLE_ggp_stream_descriptor."); + return false; + } + break; + + case EGL_PROTECTED_CONTENT_EXT: + if (!displayExtensions.protectedContentEXT) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Attribute EGL_PROTECTED_CONTEXT_EXT requires " + "extension EGL_EXT_protected_content."); + return false; + } + if (value != EGL_TRUE && value != EGL_FALSE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_PROTECTED_CONTENT_EXT must " + "be either EGL_TRUE or EGL_FALSE."); + return false; + } + break; + + case EGL_SWAP_INTERVAL_ANGLE: + if (!displayExtensions.createSurfaceSwapIntervalANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Attribute EGL_SWAP_INTERVAL_ANGLE requires " + "extension EGL_ANGLE_create_surface_swap_interval."); + return false; + } + if (value < config->minSwapInterval || value > config->maxSwapInterval) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_SWAP_INTERVAL_ANGLE must " + "be within the EGLConfig min and max swap intervals."); + return false; + } + break; + + default: + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + } + + if (Display::hasExistingWindowSurface(window)) + { + val->setError(EGL_BAD_ALLOC); + return false; + } + + return true; +} + +bool ValidateCreatePbufferSurface(const ValidationContext *val, + const Display *display, + const Config *config, + const AttributeMap &attributes) +{ + ANGLE_VALIDATION_TRY(ValidateConfig(val, display, config)); + ANGLE_VALIDATION_TRY(attributes.validate(val, display, ValidateCreatePbufferSurfaceAttribute)); + + for (const auto &attributeIter : attributes) + { + EGLAttrib attribute = attributeIter.first; + EGLAttrib value = attributeIter.second; + + ANGLE_VALIDATION_TRY( + ValidateCreatePbufferSurfaceAttributeValue(val, display, attribute, value)); + } + + if ((config->surfaceType & EGL_PBUFFER_BIT) == 0) + { + val->setError(EGL_BAD_MATCH); + return false; + } + + const Caps &caps = display->getCaps(); + + EGLAttrib textureFormat = attributes.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE); + EGLAttrib textureTarget = attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE); + + if ((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) || + (textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE)) + { + val->setError(EGL_BAD_MATCH); + return false; + } + + if ((textureFormat == EGL_TEXTURE_RGB && config->bindToTextureRGB != EGL_TRUE) || + (textureFormat == EGL_TEXTURE_RGBA && config->bindToTextureRGBA != EGL_TRUE)) + { + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + + EGLint width = static_cast(attributes.get(EGL_WIDTH, 0)); + EGLint height = static_cast(attributes.get(EGL_HEIGHT, 0)); + if (textureFormat != EGL_NO_TEXTURE && !caps.textureNPOT && + (!gl::isPow2(width) || !gl::isPow2(height))) + { + val->setError(EGL_BAD_MATCH); + return false; + } + + return true; +} + +bool ValidateCreatePbufferFromClientBuffer(const ValidationContext *val, + const Display *display, + EGLenum buftype, + EGLClientBuffer buffer, + const Config *config, + const AttributeMap &attributes) +{ + ANGLE_VALIDATION_TRY(ValidateConfig(val, display, config)); + + const DisplayExtensions &displayExtensions = display->getExtensions(); + + attributes.initializeWithoutValidation(); + + switch (buftype) + { + case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE: + if (!displayExtensions.d3dShareHandleClientBuffer) + { + val->setError(EGL_BAD_PARAMETER); + return false; + } + if (buffer == nullptr) + { + val->setError(EGL_BAD_PARAMETER); + return false; + } + break; + + case EGL_D3D_TEXTURE_ANGLE: + if (!displayExtensions.d3dTextureClientBuffer) + { + val->setError(EGL_BAD_PARAMETER); + return false; + } + if (buffer == nullptr) + { + val->setError(EGL_BAD_PARAMETER); + return false; + } + break; + + case EGL_IOSURFACE_ANGLE: + if (!displayExtensions.iosurfaceClientBuffer) + { + val->setError(EGL_BAD_PARAMETER, + " EGL_IOSURFACE_ANGLE requires the " + "EGL_ANGLE_iosurface_client_buffer extension."); + return false; + } + if (buffer == nullptr) + { + val->setError(EGL_BAD_PARAMETER, " must be non null"); + return false; + } + break; + case EGL_EXTERNAL_SURFACE_ANGLE: + if (!display->getExtensions().externalContextAndSurface) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Attribute " + "EGL_EXTERNAL_SURFACE_ANGLE requires " + "EGL_ANGLE_external_context_and_surface."); + return false; + } + if (buffer != nullptr) + { + val->setError(EGL_BAD_PARAMETER, " must be null"); + return false; + } + break; + + default: + val->setError(EGL_BAD_PARAMETER); + return false; + } + + for (AttributeMap::const_iterator attributeIter = attributes.begin(); + attributeIter != attributes.end(); attributeIter++) + { + EGLAttrib attribute = attributeIter->first; + EGLAttrib value = attributeIter->second; + + switch (attribute) + { + case EGL_WIDTH: + case EGL_HEIGHT: + if (buftype != EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE && + buftype != EGL_D3D_TEXTURE_ANGLE && buftype != EGL_IOSURFACE_ANGLE && + buftype != EGL_EXTERNAL_SURFACE_ANGLE) + { + val->setError(EGL_BAD_PARAMETER, + "Width and Height are not supported for this "); + return false; + } + if (value < 0) + { + val->setError(EGL_BAD_PARAMETER, "Width and Height must be positive"); + return false; + } + break; + + case EGL_TEXTURE_FORMAT: + switch (value) + { + case EGL_NO_TEXTURE: + case EGL_TEXTURE_RGB: + case EGL_TEXTURE_RGBA: + break; + default: + val->setError(EGL_BAD_ATTRIBUTE, "Invalid value for EGL_TEXTURE_FORMAT"); + return false; + } + break; + + case EGL_TEXTURE_TARGET: + switch (value) + { + case EGL_NO_TEXTURE: + case EGL_TEXTURE_2D: + break; + case EGL_TEXTURE_RECTANGLE_ANGLE: + if (buftype != EGL_IOSURFACE_ANGLE) + { + val->setError(EGL_BAD_PARAMETER, + " doesn't support rectangle texture targets"); + return false; + } + break; + + default: + val->setError(EGL_BAD_ATTRIBUTE, "Invalid value for EGL_TEXTURE_TARGET"); + return false; + } + break; + + case EGL_MIPMAP_TEXTURE: + break; + + case EGL_IOSURFACE_PLANE_ANGLE: + if (buftype != EGL_IOSURFACE_ANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, " doesn't support iosurface plane"); + return false; + } + break; + + case EGL_TEXTURE_TYPE_ANGLE: + if (buftype != EGL_IOSURFACE_ANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, " doesn't support texture type"); + return false; + } + break; + + case EGL_TEXTURE_INTERNAL_FORMAT_ANGLE: + if (buftype != EGL_IOSURFACE_ANGLE && buftype != EGL_D3D_TEXTURE_ANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + " doesn't support texture internal format"); + return false; + } + break; + + case EGL_GL_COLORSPACE: + if (buftype != EGL_D3D_TEXTURE_ANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + " doesn't support setting GL colorspace"); + return false; + } + break; + + case EGL_IOSURFACE_USAGE_HINT_ANGLE: + if (value & ~(EGL_IOSURFACE_READ_HINT_ANGLE | EGL_IOSURFACE_WRITE_HINT_ANGLE)) + { + val->setError(EGL_BAD_ATTRIBUTE, + "IOSurface usage hint must only contain READ or WRITE"); + return false; + } + break; + + case EGL_TEXTURE_OFFSET_X_ANGLE: + case EGL_TEXTURE_OFFSET_Y_ANGLE: + if (buftype != EGL_D3D_TEXTURE_ANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + " doesn't support setting texture offset"); + return false; + } + break; + + case EGL_PROTECTED_CONTENT_EXT: + if (!displayExtensions.protectedContentEXT) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Attribute EGL_PROTECTED_CONTEXT_EXT requires " + "extension EGL_EXT_protected_content."); + return false; + } + if (value != EGL_TRUE && value != EGL_FALSE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_PROTECTED_CONTENT_EXT must " + "be either EGL_TRUE or EGL_FALSE."); + return false; + } + break; + + default: + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + } + + EGLAttrib colorspace = attributes.get(EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_LINEAR); + if (colorspace != EGL_GL_COLORSPACE_LINEAR && colorspace != EGL_GL_COLORSPACE_SRGB) + { + val->setError(EGL_BAD_ATTRIBUTE, "invalid GL colorspace"); + return false; + } + + if (!(config->surfaceType & EGL_PBUFFER_BIT)) + { + val->setError(EGL_BAD_MATCH); + return false; + } + + EGLAttrib textureFormat = attributes.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE); + EGLAttrib textureTarget = attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE); + if ((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) || + (textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE)) + { + val->setError(EGL_BAD_MATCH); + return false; + } + if ((textureFormat == EGL_TEXTURE_RGB && config->bindToTextureRGB != EGL_TRUE) || + (textureFormat == EGL_TEXTURE_RGBA && config->bindToTextureRGBA != EGL_TRUE)) + { + // TODO(cwallez@chromium.org): For IOSurface pbuffers we require that EGL_TEXTURE_RGBA is + // set so that eglBindTexImage works. Normally this is only allowed if the config exposes + // the bindToTextureRGB/RGBA flag. This issue is that enabling this flags means that + // eglBindTexImage should also work for regular pbuffers which isn't implemented on macOS. + // Instead of adding the flag we special case the check here to be ignored for IOSurfaces. + // The TODO is to find a proper solution for this, maybe by implementing eglBindTexImage on + // OSX? + if (buftype != EGL_IOSURFACE_ANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + } + + if (buftype == EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE) + { + EGLint width = static_cast(attributes.get(EGL_WIDTH, 0)); + EGLint height = static_cast(attributes.get(EGL_HEIGHT, 0)); + + if (width == 0 || height == 0) + { + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + + const Caps &caps = display->getCaps(); + if (textureFormat != EGL_NO_TEXTURE && !caps.textureNPOT && + (!gl::isPow2(width) || !gl::isPow2(height))) + { + val->setError(EGL_BAD_MATCH); + return false; + } + } + + if (buftype == EGL_IOSURFACE_ANGLE) + { + if (static_cast(textureTarget) != config->bindToTextureTarget) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_IOSURFACE requires the texture target to match the config"); + return false; + } + if (textureFormat != EGL_TEXTURE_RGBA) + { + val->setError(EGL_BAD_ATTRIBUTE, "EGL_IOSURFACE requires the EGL_TEXTURE_RGBA format"); + return false; + } + + if (!attributes.contains(EGL_WIDTH) || !attributes.contains(EGL_HEIGHT) || + !attributes.contains(EGL_TEXTURE_FORMAT) || + !attributes.contains(EGL_TEXTURE_TYPE_ANGLE) || + !attributes.contains(EGL_TEXTURE_INTERNAL_FORMAT_ANGLE) || + !attributes.contains(EGL_IOSURFACE_PLANE_ANGLE)) + { + val->setError(EGL_BAD_PARAMETER, "Missing required attribute for EGL_IOSURFACE"); + return false; + } + } + + ANGLE_EGL_TRY_RETURN(val->eglThread, + display->validateClientBuffer(config, buftype, buffer, attributes), + val->entryPoint, val->labeledObject, false); + + return true; +} + +bool ValidateCreatePixmapSurface(const ValidationContext *val, + const Display *display, + const Config *config, + EGLNativePixmapType pixmap, + const AttributeMap &attributes) +{ + ANGLE_VALIDATION_TRY(ValidateConfig(val, display, config)); + + const DisplayExtensions &displayExtensions = display->getExtensions(); + + attributes.initializeWithoutValidation(); + + for (const auto &attributePair : attributes) + { + EGLAttrib attribute = attributePair.first; + EGLAttrib value = attributePair.second; + + switch (attribute) + { + case EGL_GL_COLORSPACE: + ANGLE_VALIDATION_TRY(ValidateColorspaceAttribute(val, displayExtensions, value)); + break; + + case EGL_VG_COLORSPACE: + break; + case EGL_VG_ALPHA_FORMAT: + break; + + case EGL_TEXTURE_FORMAT: + if (!displayExtensions.textureFromPixmapNOK) + { + val->setError(EGL_BAD_ATTRIBUTE, "EGL_NOK_texture_from_pixmap is not enabled."); + return false; + } + switch (value) + { + case EGL_NO_TEXTURE: + case EGL_TEXTURE_RGB: + case EGL_TEXTURE_RGBA: + break; + default: + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + break; + + case EGL_TEXTURE_TARGET: + if (!displayExtensions.textureFromPixmapNOK) + { + val->setError(EGL_BAD_ATTRIBUTE, "EGL_NOK_texture_from_pixmap is not enabled."); + return false; + } + switch (value) + { + case EGL_NO_TEXTURE: + case EGL_TEXTURE_2D: + break; + default: + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + break; + + case EGL_MIPMAP_TEXTURE: + if (!displayExtensions.textureFromPixmapNOK) + { + val->setError(EGL_BAD_ATTRIBUTE, "EGL_NOK_texture_from_pixmap is not enabled."); + return false; + } + break; + + case EGL_PROTECTED_CONTENT_EXT: + if (!displayExtensions.protectedContentEXT) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Attribute EGL_PROTECTED_CONTEXT_EXT requires " + "extension EGL_EXT_protected_content."); + return false; + } + if (value != EGL_TRUE && value != EGL_FALSE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_PROTECTED_CONTENT_EXT must " + "be either EGL_TRUE or EGL_FALSE."); + return false; + } + break; + + default: + val->setError(EGL_BAD_ATTRIBUTE, "Unknown attribute: 0x%04" PRIxPTR, attribute); + return false; + } + } + + if (!(config->surfaceType & EGL_PIXMAP_BIT)) + { + val->setError(EGL_BAD_MATCH, "Congfig does not suport pixmaps."); + return false; + } + + ANGLE_EGL_TRY_RETURN(val->eglThread, display->valdiatePixmap(config, pixmap, attributes), + val->entryPoint, val->labeledObject, false); + + return true; +} + +bool ValidateMakeCurrent(const ValidationContext *val, + const Display *display, + const Surface *draw, + const Surface *read, + const gl::Context *context) +{ + if (context == EGL_NO_CONTEXT && (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE)) + { + val->setError(EGL_BAD_MATCH, "If ctx is EGL_NO_CONTEXT, surfaces must be EGL_NO_SURFACE"); + return false; + } + + // If ctx is EGL_NO_CONTEXT and either draw or read are not EGL_NO_SURFACE, an EGL_BAD_MATCH + // error is generated. EGL_KHR_surfaceless_context allows both surfaces to be EGL_NO_SURFACE. + if (context != EGL_NO_CONTEXT && (draw == EGL_NO_SURFACE || read == EGL_NO_SURFACE)) + { + if (display->getExtensions().surfacelessContext) + { + if ((draw == EGL_NO_SURFACE) != (read == EGL_NO_SURFACE)) + { + val->setError(EGL_BAD_MATCH, + "If ctx is not EGL_NOT_CONTEXT, draw or read must " + "both be EGL_NO_SURFACE, or both not"); + return false; + } + } + else + { + val->setError(EGL_BAD_MATCH, + "If ctx is not EGL_NO_CONTEXT, surfaces must not be EGL_NO_SURFACE"); + return false; + } + } + + // If either of draw or read is a valid surface and the other is EGL_NO_SURFACE, an + // EGL_BAD_MATCH error is generated. + if ((read == EGL_NO_SURFACE) != (draw == EGL_NO_SURFACE)) + { + val->setError(EGL_BAD_MATCH, + "read and draw must both be valid surfaces, or both be EGL_NO_SURFACE"); + return false; + } + + if (display == EGL_NO_DISPLAY || !Display::isValidDisplay(display)) + { + val->setError(EGL_BAD_DISPLAY, "'dpy' not a valid EGLDisplay handle"); + return false; + } + + // EGL 1.5 spec: dpy can be uninitialized if all other parameters are null + if (!display->isInitialized() && + (context != EGL_NO_CONTEXT || draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE)) + { + val->setError(EGL_NOT_INITIALIZED, "'dpy' not initialized"); + return false; + } + + if (context != EGL_NO_CONTEXT) + { + ANGLE_VALIDATION_TRY(ValidateContext(val, display, context)); + } + + if (display->isInitialized() && display->isDeviceLost()) + { + val->setError(EGL_CONTEXT_LOST); + return false; + } + + if (draw != EGL_NO_SURFACE) + { + ANGLE_VALIDATION_TRY(ValidateSurface(val, display, draw)); + } + + if (read != EGL_NO_SURFACE) + { + ANGLE_VALIDATION_TRY(ValidateSurface(val, display, read)); + ANGLE_VALIDATION_TRY(ValidateCompatibleSurface(val, display, context, read)); + } + + if (draw != read) + { + if (draw) + { + ANGLE_VALIDATION_TRY(ValidateCompatibleSurface(val, display, context, draw)); + } + if (read) + { + ANGLE_VALIDATION_TRY(ValidateCompatibleSurface(val, display, context, read)); + } + } + return true; +} + +bool ValidateCreateImage(const ValidationContext *val, + const Display *display, + const gl::Context *context, + EGLenum target, + EGLClientBuffer buffer, + const AttributeMap &attributes) +{ + + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + attributes.initializeWithoutValidation(); + + const DisplayExtensions &displayExtensions = display->getExtensions(); + + // TODO(geofflang): Complete validation from EGL_KHR_image_base: + // If the resource specified by , , , and is itself an + // EGLImage sibling, the error EGL_BAD_ACCESS is generated. + + for (AttributeMap::const_iterator attributeIter = attributes.begin(); + attributeIter != attributes.end(); attributeIter++) + { + EGLAttrib attribute = attributeIter->first; + EGLAttrib value = attributeIter->second; + + switch (attribute) + { + case EGL_IMAGE_PRESERVED: + switch (value) + { + case EGL_TRUE: + case EGL_FALSE: + break; + + default: + val->setError(EGL_BAD_PARAMETER, + "EGL_IMAGE_PRESERVED must be EGL_TRUE or EGL_FALSE."); + return false; + } + break; + + case EGL_GL_TEXTURE_LEVEL: + if (!displayExtensions.glTexture2DImage && + !displayExtensions.glTextureCubemapImage && !displayExtensions.glTexture3DImage) + { + val->setError(EGL_BAD_PARAMETER, + "EGL_GL_TEXTURE_LEVEL cannot be used " + "without KHR_gl_texture_*_image support."); + return false; + } + + if (value < 0) + { + val->setError(EGL_BAD_PARAMETER, "EGL_GL_TEXTURE_LEVEL cannot be negative."); + return false; + } + break; + + case EGL_GL_TEXTURE_ZOFFSET: + if (!displayExtensions.glTexture3DImage) + { + val->setError(EGL_BAD_PARAMETER, + "EGL_GL_TEXTURE_ZOFFSET cannot be used " + "without KHR_gl_texture_3D_image support."); + return false; + } + break; + + case EGL_GL_COLORSPACE: + if (!displayExtensions.glColorspace) + { + val->setError(EGL_BAD_PARAMETER, + "EGL_GL_COLORSPACE cannot be used " + "without EGL_KHR_gl_colorspace support."); + return false; + } + switch (value) + { + case EGL_GL_COLORSPACE_DEFAULT_EXT: + break; + default: + ANGLE_VALIDATION_TRY( + ValidateColorspaceAttribute(val, displayExtensions, value)); + break; + } + break; + + case EGL_TEXTURE_INTERNAL_FORMAT_ANGLE: + if (!displayExtensions.imageD3D11Texture && !displayExtensions.vulkanImageANGLE) + { + val->setError( + EGL_BAD_PARAMETER, + "EGL_TEXTURE_INTERNAL_FORMAT_ANGLE cannot be used without " + "EGL_ANGLE_image_d3d11_texture or EGL_ANGLE_vulkan_image support."); + return false; + } + break; + + case EGL_D3D11_TEXTURE_PLANE_ANGLE: + if (!displayExtensions.imageD3D11Texture) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_D3D11_TEXTURE_PLANE_ANGLE cannot be used without " + "EGL_ANGLE_image_d3d11_texture support."); + return false; + } + break; + + case EGL_D3D11_TEXTURE_ARRAY_SLICE_ANGLE: + if (!displayExtensions.imageD3D11Texture) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_D3D11_TEXTURE_ARRAY_SLICE_ANGLE cannot be used without " + "EGL_ANGLE_image_d3d11_texture support."); + return false; + } + break; + + case EGL_WIDTH: + case EGL_HEIGHT: + if (target != EGL_LINUX_DMA_BUF_EXT) + { + val->setError( + EGL_BAD_PARAMETER, + "Parameter cannot be used if target is not EGL_LINUX_DMA_BUF_EXT"); + return false; + } + break; + + case EGL_LINUX_DRM_FOURCC_EXT: + case EGL_DMA_BUF_PLANE0_FD_EXT: + case EGL_DMA_BUF_PLANE0_OFFSET_EXT: + case EGL_DMA_BUF_PLANE0_PITCH_EXT: + case EGL_DMA_BUF_PLANE1_FD_EXT: + case EGL_DMA_BUF_PLANE1_OFFSET_EXT: + case EGL_DMA_BUF_PLANE1_PITCH_EXT: + case EGL_DMA_BUF_PLANE2_FD_EXT: + case EGL_DMA_BUF_PLANE2_OFFSET_EXT: + case EGL_DMA_BUF_PLANE2_PITCH_EXT: + if (!displayExtensions.imageDmaBufImportEXT) + { + val->setError(EGL_BAD_PARAMETER, + "Parameter cannot be used without " + "EGL_EXT_image_dma_buf_import support."); + return false; + } + break; + + case EGL_YUV_COLOR_SPACE_HINT_EXT: + if (!displayExtensions.imageDmaBufImportEXT) + { + val->setError(EGL_BAD_PARAMETER, + "Parameter cannot be used without " + "EGL_EXT_image_dma_buf_import support."); + return false; + } + + switch (value) + { + case EGL_ITU_REC601_EXT: + case EGL_ITU_REC709_EXT: + case EGL_ITU_REC2020_EXT: + break; + + default: + val->setError(EGL_BAD_PARAMETER, + "Invalid value for EGL_YUV_COLOR_SPACE_HINT_EXT."); + return false; + } + break; + + case EGL_SAMPLE_RANGE_HINT_EXT: + if (!displayExtensions.imageDmaBufImportEXT) + { + val->setError(EGL_BAD_PARAMETER, + "Parameter cannot be used without " + "EGL_EXT_image_dma_buf_import support."); + return false; + } + + switch (value) + { + case EGL_YUV_FULL_RANGE_EXT: + case EGL_YUV_NARROW_RANGE_EXT: + break; + + default: + val->setError(EGL_BAD_PARAMETER, + "Invalid value for EGL_SAMPLE_RANGE_HINT_EXT."); + return false; + } + break; + + case EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT: + case EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT: + if (!displayExtensions.imageDmaBufImportEXT) + { + val->setError(EGL_BAD_PARAMETER, + "Parameter cannot be used without " + "EGL_EXT_image_dma_buf_import support."); + return false; + } + + switch (value) + { + case EGL_YUV_CHROMA_SITING_0_EXT: + case EGL_YUV_CHROMA_SITING_0_5_EXT: + break; + + default: + val->setError( + EGL_BAD_PARAMETER, + "Invalid value for EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT or " + "EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT."); + return false; + } + break; + + case EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT: + case EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT: + case EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT: + case EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT: + case EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT: + case EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT: + case EGL_DMA_BUF_PLANE3_FD_EXT: + case EGL_DMA_BUF_PLANE3_OFFSET_EXT: + case EGL_DMA_BUF_PLANE3_PITCH_EXT: + case EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT: + case EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT: + if (!displayExtensions.imageDmaBufImportModifiersEXT) + { + val->setError(EGL_BAD_PARAMETER, + "Parameter cannot be used without " + "EGL_EXT_image_dma_buf_import_modifiers support."); + return false; + } + break; + + case EGL_PROTECTED_CONTENT_EXT: + if (!displayExtensions.protectedContentEXT) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Attribute EGL_PROTECTED_CONTEXT_EXT requires " + "extension EGL_EXT_protected_content."); + return false; + } + if (value != EGL_TRUE && value != EGL_FALSE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_PROTECTED_CONTENT_EXT must " + "be either EGL_TRUE or EGL_FALSE."); + return false; + } + break; + + case EGL_VULKAN_IMAGE_CREATE_INFO_HI_ANGLE: + case EGL_VULKAN_IMAGE_CREATE_INFO_LO_ANGLE: + if (!displayExtensions.vulkanImageANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Attribute EGL_VULKAN_IMAGE_CREATE_INFO_{HI,LO}_ANGLE require " + "extension EGL_ANGLE_vulkan_image."); + return false; + } + break; + + default: + val->setError(EGL_BAD_PARAMETER, "invalid attribute: 0x%04" PRIxPTR "X", attribute); + return false; + } + } + + switch (target) + { + case EGL_GL_TEXTURE_2D: + { + if (!displayExtensions.glTexture2DImage) + { + val->setError(EGL_BAD_PARAMETER, "KHR_gl_texture_2D_image not supported."); + return false; + } + + if (buffer == 0) + { + val->setError(EGL_BAD_PARAMETER, + "buffer cannot reference a 2D texture with the name 0."); + return false; + } + + ANGLE_VALIDATION_TRY(ValidateContext(val, display, context)); + const gl::Texture *texture = + context->getTexture({egl_gl::EGLClientBufferToGLObjectHandle(buffer)}); + if (texture == nullptr || texture->getType() != gl::TextureType::_2D) + { + val->setError(EGL_BAD_PARAMETER, "target is not a 2D texture."); + return false; + } + + if (texture->getBoundSurface() != nullptr) + { + val->setError(EGL_BAD_ACCESS, "texture has a surface bound to it."); + return false; + } + + EGLAttrib level = attributes.get(EGL_GL_TEXTURE_LEVEL, 0); + if (texture->getWidth(gl::TextureTarget::_2D, static_cast(level)) == 0 || + texture->getHeight(gl::TextureTarget::_2D, static_cast(level)) == 0) + { + val->setError(EGL_BAD_PARAMETER, + "target 2D texture does not have a valid size at specified level."); + return false; + } + + bool protectedContentAttrib = + (attributes.getAsInt(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE) != EGL_FALSE); + if (protectedContentAttrib != texture->hasProtectedContent()) + { + val->setError(EGL_BAD_PARAMETER, + "EGL_PROTECTED_CONTENT_EXT attribute does not match protected state " + "of target."); + return false; + } + + ANGLE_VALIDATION_TRY(ValidateCreateImageMipLevelCommon(val, context, texture, level)); + } + break; + + case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + { + if (!displayExtensions.glTextureCubemapImage) + { + val->setError(EGL_BAD_PARAMETER, "KHR_gl_texture_cubemap_image not supported."); + return false; + } + + if (buffer == 0) + { + val->setError(EGL_BAD_PARAMETER, + "buffer cannot reference a cubemap texture with the name 0."); + return false; + } + + ANGLE_VALIDATION_TRY(ValidateContext(val, display, context)); + const gl::Texture *texture = + context->getTexture({egl_gl::EGLClientBufferToGLObjectHandle(buffer)}); + if (texture == nullptr || texture->getType() != gl::TextureType::CubeMap) + { + val->setError(EGL_BAD_PARAMETER, "target is not a cubemap texture."); + return false; + } + + if (texture->getBoundSurface() != nullptr) + { + val->setError(EGL_BAD_ACCESS, "texture has a surface bound to it."); + return false; + } + + EGLAttrib level = attributes.get(EGL_GL_TEXTURE_LEVEL, 0); + gl::TextureTarget cubeMapFace = egl_gl::EGLCubeMapTargetToCubeMapTarget(target); + if (texture->getWidth(cubeMapFace, static_cast(level)) == 0 || + texture->getHeight(cubeMapFace, static_cast(level)) == 0) + { + val->setError(EGL_BAD_PARAMETER, + "target cubemap texture does not have a valid " + "size at specified level and face."); + return false; + } + + ANGLE_VALIDATION_TRY(ValidateCreateImageMipLevelCommon(val, context, texture, level)); + + if (level == 0 && !texture->isMipmapComplete() && + CubeTextureHasUnspecifiedLevel0Face(texture)) + { + val->setError(EGL_BAD_PARAMETER, + "if level is zero and the texture is incomplete, " + "it must have all of its faces specified at level " + "zero."); + return false; + } + + bool protectedContentAttrib = + (attributes.getAsInt(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE) != EGL_FALSE); + if (protectedContentAttrib != texture->hasProtectedContent()) + { + val->setError(EGL_BAD_PARAMETER, + "EGL_PROTECTED_CONTENT_EXT attribute does not match protected state " + "of target."); + return false; + } + } + break; + + case EGL_GL_TEXTURE_3D: + { + if (!displayExtensions.glTexture3DImage) + { + val->setError(EGL_BAD_PARAMETER, "KHR_gl_texture_3D_image not supported."); + return false; + } + + if (buffer == 0) + { + val->setError(EGL_BAD_PARAMETER, + "buffer cannot reference a 3D texture with the name 0."); + return false; + } + + ANGLE_VALIDATION_TRY(ValidateContext(val, display, context)); + const gl::Texture *texture = + context->getTexture({egl_gl::EGLClientBufferToGLObjectHandle(buffer)}); + if (texture == nullptr || texture->getType() != gl::TextureType::_3D) + { + val->setError(EGL_BAD_PARAMETER, "target is not a 3D texture."); + return false; + } + + if (texture->getBoundSurface() != nullptr) + { + val->setError(EGL_BAD_ACCESS, "texture has a surface bound to it."); + return false; + } + + EGLAttrib level = attributes.get(EGL_GL_TEXTURE_LEVEL, 0); + EGLAttrib zOffset = attributes.get(EGL_GL_TEXTURE_ZOFFSET, 0); + if (texture->getWidth(gl::TextureTarget::_3D, static_cast(level)) == 0 || + texture->getHeight(gl::TextureTarget::_3D, static_cast(level)) == 0 || + texture->getDepth(gl::TextureTarget::_3D, static_cast(level)) == 0) + { + val->setError(EGL_BAD_PARAMETER, + "target 3D texture does not have a valid size at specified level."); + return false; + } + + if (static_cast(zOffset) >= + texture->getDepth(gl::TextureTarget::_3D, static_cast(level))) + { + val->setError(EGL_BAD_PARAMETER, + "target 3D texture does not have enough layers " + "for the specified Z offset at the specified " + "level."); + return false; + } + + bool protectedContentAttrib = + (attributes.getAsInt(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE) != EGL_FALSE); + if (protectedContentAttrib != texture->hasProtectedContent()) + { + val->setError(EGL_BAD_PARAMETER, + "EGL_PROTECTED_CONTENT_EXT attribute does not match protected state " + "of target."); + return false; + } + + ANGLE_VALIDATION_TRY(ValidateCreateImageMipLevelCommon(val, context, texture, level)); + } + break; + + case EGL_GL_RENDERBUFFER: + { + if (!displayExtensions.glRenderbufferImage) + { + val->setError(EGL_BAD_PARAMETER, "KHR_gl_renderbuffer_image not supported."); + return false; + } + + if (attributes.contains(EGL_GL_TEXTURE_LEVEL)) + { + val->setError(EGL_BAD_PARAMETER, + "EGL_GL_TEXTURE_LEVEL cannot be used in " + "conjunction with a renderbuffer target."); + return false; + } + + if (buffer == 0) + { + val->setError(EGL_BAD_PARAMETER, + "buffer cannot reference a renderbuffer with the name 0."); + return false; + } + + ANGLE_VALIDATION_TRY(ValidateContext(val, display, context)); + const gl::Renderbuffer *renderbuffer = + context->getRenderbuffer({egl_gl::EGLClientBufferToGLObjectHandle(buffer)}); + if (renderbuffer == nullptr) + { + val->setError(EGL_BAD_PARAMETER, "target is not a renderbuffer."); + return false; + } + + if (renderbuffer->getSamples() > 0) + { + val->setError(EGL_BAD_PARAMETER, "target renderbuffer cannot be multisampled."); + return false; + } + + bool protectedContentAttrib = + (attributes.getAsInt(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE) != EGL_FALSE); + if (protectedContentAttrib != renderbuffer->hasProtectedContent()) + { + val->setError(EGL_BAD_ACCESS, + "EGL_PROTECTED_CONTENT_EXT attribute does not match protected state " + "of target."); + return false; + } + } + break; + + case EGL_NATIVE_BUFFER_ANDROID: + { + if (!displayExtensions.imageNativeBuffer) + { + val->setError(EGL_BAD_PARAMETER, "EGL_ANDROID_image_native_buffer not supported."); + return false; + } + + if (context != nullptr) + { + val->setError(EGL_BAD_CONTEXT, "ctx must be EGL_NO_CONTEXT."); + return false; + } + + ANGLE_EGL_TRY_RETURN( + val->eglThread, + display->validateImageClientBuffer(context, target, buffer, attributes), + val->entryPoint, val->labeledObject, false); + } + break; + + case EGL_D3D11_TEXTURE_ANGLE: + if (!displayExtensions.imageD3D11Texture) + { + val->setError(EGL_BAD_PARAMETER, "EGL_ANGLE_image_d3d11_texture not supported."); + return false; + } + + if (context != nullptr) + { + val->setError(EGL_BAD_CONTEXT, "ctx must be EGL_NO_CONTEXT."); + return false; + } + + ANGLE_EGL_TRY_RETURN( + val->eglThread, + display->validateImageClientBuffer(context, target, buffer, attributes), + val->entryPoint, val->labeledObject, false); + break; + + case EGL_LINUX_DMA_BUF_EXT: + if (!displayExtensions.imageDmaBufImportEXT) + { + val->setError(EGL_BAD_PARAMETER, "EGL_EXT_image_dma_buf_import not supported."); + return false; + } + + if (context != nullptr) + { + val->setError(EGL_BAD_CONTEXT, "ctx must be EGL_NO_CONTEXT."); + return false; + } + + if (buffer != nullptr) + { + val->setError(EGL_BAD_PARAMETER, "buffer must be NULL."); + return false; + } + + { + EGLenum kRequiredParameters[] = {EGL_WIDTH, + EGL_HEIGHT, + EGL_LINUX_DRM_FOURCC_EXT, + EGL_DMA_BUF_PLANE0_FD_EXT, + EGL_DMA_BUF_PLANE0_OFFSET_EXT, + EGL_DMA_BUF_PLANE0_PITCH_EXT}; + for (EGLenum requiredParameter : kRequiredParameters) + { + if (!attributes.contains(requiredParameter)) + { + val->setError(EGL_BAD_PARAMETER, + "Missing required parameter 0x%X for image target " + "EGL_LINUX_DMA_BUF_EXT.", + requiredParameter); + return false; + } + } + + bool containPlane0ModifierLo = + attributes.contains(EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT); + bool containPlane0ModifierHi = + attributes.contains(EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT); + bool containPlane1ModifierLo = + attributes.contains(EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT); + bool containPlane1ModifierHi = + attributes.contains(EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT); + bool containPlane2ModifierLo = + attributes.contains(EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT); + bool containPlane2ModifierHi = + attributes.contains(EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT); + bool containPlane3ModifierLo = + attributes.contains(EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT); + bool containPlane3ModifierHi = + attributes.contains(EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT); + if ((containPlane0ModifierLo ^ containPlane0ModifierHi) || + (containPlane1ModifierLo ^ containPlane1ModifierHi) || + (containPlane2ModifierLo ^ containPlane2ModifierHi) || + (containPlane3ModifierLo ^ containPlane3ModifierHi)) + { + val->setError( + EGL_BAD_PARAMETER, + "the list of attributes contains EGL_DMA_BUF_PLANE*_MODIFIER_LO_EXT " + "but not EGL_DMA_BUF_PLANE*_MODIFIER_HI_EXT or vice versa."); + return false; + } + } + break; + + case EGL_METAL_TEXTURE_ANGLE: + if (!displayExtensions.mtlTextureClientBuffer) + { + val->setError(EGL_BAD_PARAMETER, + "EGL_ANGLE_metal_texture_client_buffer not supported."); + return false; + } + + if (context != nullptr) + { + val->setError(EGL_BAD_CONTEXT, "ctx must be EGL_NO_CONTEXT."); + return false; + } + + ANGLE_EGL_TRY_RETURN( + val->eglThread, + display->validateImageClientBuffer(context, target, buffer, attributes), + val->entryPoint, val->labeledObject, false); + break; + case EGL_VULKAN_IMAGE_ANGLE: + if (!displayExtensions.vulkanImageANGLE) + { + val->setError(EGL_BAD_PARAMETER, "EGL_ANGLE_vulkan_image not supported."); + return false; + } + + if (context != nullptr) + { + val->setError(EGL_BAD_CONTEXT, "ctx must be EGL_NO_CONTEXT."); + return false; + } + + { + const EGLenum kRequiredParameters[] = { + EGL_VULKAN_IMAGE_CREATE_INFO_HI_ANGLE, + EGL_VULKAN_IMAGE_CREATE_INFO_LO_ANGLE, + }; + for (EGLenum requiredParameter : kRequiredParameters) + { + if (!attributes.contains(requiredParameter)) + { + val->setError(EGL_BAD_PARAMETER, + "Missing required parameter 0x%X for image target " + "EGL_VULKAN_IMAGE_ANGLE.", + requiredParameter); + return false; + } + } + } + + ANGLE_EGL_TRY_RETURN( + val->eglThread, + display->validateImageClientBuffer(context, target, buffer, attributes), + val->entryPoint, val->labeledObject, false); + break; + default: + val->setError(EGL_BAD_PARAMETER, "invalid target: 0x%X", target); + return false; + } + + if (attributes.contains(EGL_GL_TEXTURE_ZOFFSET) && target != EGL_GL_TEXTURE_3D) + { + val->setError(EGL_BAD_PARAMETER, + "EGL_GL_TEXTURE_ZOFFSET must be used with a 3D texture target."); + return false; + } + + return true; +} + +bool ValidateDestroyImage(const ValidationContext *val, const Display *display, const Image *image) +{ + ANGLE_VALIDATION_TRY(ValidateImage(val, display, image)); + + return true; +} + +bool ValidateCreateImageKHR(const ValidationContext *val, + const Display *display, + const gl::Context *context, + EGLenum target, + EGLClientBuffer buffer, + const AttributeMap &attributes) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + if (!display->getExtensions().imageBase && !display->getExtensions().image) + { + // It is out of spec what happens when calling an extension function when the extension is + // not available. + // EGL_BAD_DISPLAY seems like a reasonable error. + val->setError(EGL_BAD_DISPLAY, "EGL_KHR_image not supported."); + return false; + } + + return ValidateCreateImage(val, display, context, target, buffer, attributes); +} + +bool ValidateDestroyImageKHR(const ValidationContext *val, + const Display *display, + const Image *image) +{ + ANGLE_VALIDATION_TRY(ValidateImage(val, display, image)); + + if (!display->getExtensions().imageBase && !display->getExtensions().image) + { + // It is out of spec what happens when calling an extension function when the extension is + // not available. + // EGL_BAD_DISPLAY seems like a reasonable error. + val->setError(EGL_BAD_DISPLAY); + return false; + } + + return true; +} + +bool ValidateCreateDeviceANGLE(const ValidationContext *val, + EGLint device_type, + const void *native_device, + const EGLAttrib *attrib_list) +{ + const ClientExtensions &clientExtensions = Display::GetClientExtensions(); + if (!clientExtensions.deviceCreation) + { + val->setError(EGL_BAD_ACCESS, "Device creation extension not active"); + return false; + } + + if (attrib_list != nullptr && attrib_list[0] != EGL_NONE) + { + val->setError(EGL_BAD_ATTRIBUTE, "Invalid attrib_list parameter"); + return false; + } + + switch (device_type) + { + case EGL_D3D11_DEVICE_ANGLE: + if (!clientExtensions.deviceCreationD3D11) + { + val->setError(EGL_BAD_ATTRIBUTE, "D3D11 device creation extension not active"); + return false; + } + break; + default: + val->setError(EGL_BAD_ATTRIBUTE, "Invalid device_type parameter"); + return false; + } + + return true; +} + +bool ValidateReleaseDeviceANGLE(const ValidationContext *val, const Device *device) +{ + const ClientExtensions &clientExtensions = Display::GetClientExtensions(); + if (!clientExtensions.deviceCreation) + { + val->setError(EGL_BAD_ACCESS, "Device creation extension not active"); + return false; + } + + if (device == EGL_NO_DEVICE_EXT || !Device::IsValidDevice(device)) + { + val->setError(EGL_BAD_DEVICE_EXT, "Invalid device parameter"); + return false; + } + + Display *owningDisplay = device->getOwningDisplay(); + if (owningDisplay != nullptr) + { + val->setError(EGL_BAD_DEVICE_EXT, "Device must have been created using eglCreateDevice"); + return false; + } + + return true; +} + +bool ValidateCreateSync(const ValidationContext *val, + const Display *display, + EGLenum type, + const AttributeMap &attribs) +{ + return ValidateCreateSyncBase(val, display, type, attribs, false); +} + +bool ValidateCreateSyncKHR(const ValidationContext *val, + const Display *display, + EGLenum type, + const AttributeMap &attribs) +{ + return ValidateCreateSyncBase(val, display, type, attribs, true); +} + +bool ValidateDestroySync(const ValidationContext *val, const Display *display, const Sync *sync) +{ + ANGLE_VALIDATION_TRY(ValidateSync(val, display, sync)); + return true; +} + +bool ValidateDestroySyncKHR(const ValidationContext *val, + const Display *dpyPacked, + const Sync *syncPacked) +{ + return ValidateDestroySync(val, dpyPacked, syncPacked); +} + +bool ValidateClientWaitSync(const ValidationContext *val, + const Display *display, + const Sync *sync, + EGLint flags, + EGLTime timeout) +{ + ANGLE_VALIDATION_TRY(ValidateSync(val, display, sync)); + return true; +} + +bool ValidateClientWaitSyncKHR(const ValidationContext *val, + const Display *dpyPacked, + const Sync *syncPacked, + EGLint flags, + EGLTimeKHR timeout) +{ + return ValidateClientWaitSync(val, dpyPacked, syncPacked, flags, timeout); +} + +bool ValidateWaitSync(const ValidationContext *val, + const Display *display, + const Sync *sync, + EGLint flags) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + const DisplayExtensions &extensions = display->getExtensions(); + if (!extensions.waitSync) + { + val->setError(EGL_BAD_ACCESS, "EGL_KHR_wait_sync extension is not available"); + return false; + } + + ANGLE_VALIDATION_TRY(ValidateSync(val, display, sync)); + + gl::Context *context = val->eglThread->getContext(); + if (context == nullptr) + { + val->setError(EGL_BAD_MATCH, "No context is current."); + return false; + } + + if (!context->getExtensions().EGLSyncOES) + { + val->setError(EGL_BAD_MATCH, + "Server-side waits cannot be performed without " + "GL_OES_EGL_sync support."); + return false; + } + + if (flags != 0) + { + val->setError(EGL_BAD_PARAMETER, "flags must be zero"); + return false; + } + + return true; +} + +bool ValidateWaitSyncKHR(const ValidationContext *val, + const Display *dpyPacked, + const Sync *syncPacked, + EGLint flags) +{ + return ValidateWaitSync(val, dpyPacked, syncPacked, flags); +} + +bool ValidateGetSyncAttrib(const ValidationContext *val, + const Display *display, + const Sync *sync, + EGLint attribute, + const EGLAttrib *value) +{ + if (value == nullptr) + { + val->setError(EGL_BAD_PARAMETER, "Invalid value parameter"); + return false; + } + return ValidateGetSyncAttribBase(val, display, sync, attribute); +} + +bool ValidateGetSyncAttribKHR(const ValidationContext *val, + const Display *display, + const Sync *sync, + EGLint attribute, + const EGLint *value) +{ + if (value == nullptr) + { + val->setError(EGL_BAD_PARAMETER, "Invalid value parameter"); + return false; + } + return ValidateGetSyncAttribBase(val, display, sync, attribute); +} + +bool ValidateCreateStreamKHR(const ValidationContext *val, + const Display *display, + const AttributeMap &attributes) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + const DisplayExtensions &displayExtensions = display->getExtensions(); + if (!displayExtensions.stream) + { + val->setError(EGL_BAD_ALLOC, "Stream extension not active"); + return false; + } + + attributes.initializeWithoutValidation(); + + for (const auto &attributeIter : attributes) + { + EGLAttrib attribute = attributeIter.first; + EGLAttrib value = attributeIter.second; + + ANGLE_VALIDATION_TRY(ValidateStreamAttribute(val, attribute, value, displayExtensions)); + } + + return true; +} + +bool ValidateDestroyStreamKHR(const ValidationContext *val, + const Display *display, + const Stream *stream) +{ + ANGLE_VALIDATION_TRY(ValidateStream(val, display, stream)); + return true; +} + +bool ValidateStreamAttribKHR(const ValidationContext *val, + const Display *display, + const Stream *stream, + EGLenum attribute, + EGLint value) +{ + ANGLE_VALIDATION_TRY(ValidateStream(val, display, stream)); + + if (stream->getState() == EGL_STREAM_STATE_DISCONNECTED_KHR) + { + val->setError(EGL_BAD_STATE_KHR, "Bad stream state"); + return false; + } + + return ValidateStreamAttribute(val, attribute, value, display->getExtensions()); +} + +bool ValidateQueryStreamKHR(const ValidationContext *val, + const Display *display, + const Stream *stream, + EGLenum attribute, + const EGLint *value) +{ + ANGLE_VALIDATION_TRY(ValidateStream(val, display, stream)); + + switch (attribute) + { + case EGL_STREAM_STATE_KHR: + case EGL_CONSUMER_LATENCY_USEC_KHR: + break; + case EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR: + if (!display->getExtensions().streamConsumerGLTexture) + { + val->setError(EGL_BAD_ATTRIBUTE, "Consumer GLTexture extension not active"); + return false; + } + break; + default: + val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute"); + return false; + } + + return true; +} + +bool ValidateQueryStreamu64KHR(const ValidationContext *val, + const Display *display, + const Stream *stream, + EGLenum attribute, + const EGLuint64KHR *value) +{ + ANGLE_VALIDATION_TRY(ValidateStream(val, display, stream)); + + switch (attribute) + { + case EGL_CONSUMER_FRAME_KHR: + case EGL_PRODUCER_FRAME_KHR: + break; + default: + val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute"); + return false; + } + + return true; +} + +bool ValidateStreamConsumerGLTextureExternalKHR(const ValidationContext *val, + const Display *display, + const Stream *stream) +{ + gl::Context *context = val->eglThread->getContext(); + ANGLE_VALIDATION_TRY(ValidateContext(val, display, context)); + + const DisplayExtensions &displayExtensions = display->getExtensions(); + if (!displayExtensions.streamConsumerGLTexture) + { + val->setError(EGL_BAD_ACCESS, "Stream consumer extension not active"); + return false; + } + + if (!context->getExtensions().EGLStreamConsumerExternalNV) + { + val->setError(EGL_BAD_ACCESS, "EGL stream consumer external GL extension not enabled"); + return false; + } + + if (stream == EGL_NO_STREAM_KHR || !display->isValidStream(stream)) + { + val->setError(EGL_BAD_STREAM_KHR, "Invalid stream"); + return false; + } + + if (stream->getState() != EGL_STREAM_STATE_CREATED_KHR) + { + val->setError(EGL_BAD_STATE_KHR, "Invalid stream state"); + return false; + } + + // Lookup the texture and ensure it is correct + gl::Texture *texture = context->getState().getTargetTexture(gl::TextureType::External); + if (texture == nullptr || texture->id().value == 0) + { + val->setError(EGL_BAD_ACCESS, "No external texture bound"); + return false; + } + + return true; +} + +bool ValidateStreamConsumerAcquireKHR(const ValidationContext *val, + const Display *display, + const Stream *stream) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + const DisplayExtensions &displayExtensions = display->getExtensions(); + if (!displayExtensions.streamConsumerGLTexture) + { + val->setError(EGL_BAD_ACCESS, "Stream consumer extension not active"); + return false; + } + + if (stream == EGL_NO_STREAM_KHR || !display->isValidStream(stream)) + { + val->setError(EGL_BAD_STREAM_KHR, "Invalid stream"); + return false; + } + + gl::Context *context = val->eglThread->getContext(); + if (!context) + { + val->setError(EGL_BAD_ACCESS, "No GL context current to calling thread."); + return false; + } + + ANGLE_VALIDATION_TRY(ValidateContext(val, display, context)); + + if (!stream->isConsumerBoundToContext(context)) + { + val->setError(EGL_BAD_ACCESS, "Current GL context not associated with stream consumer"); + return false; + } + + if (stream->getConsumerType() != Stream::ConsumerType::GLTextureRGB && + stream->getConsumerType() != Stream::ConsumerType::GLTextureYUV) + { + val->setError(EGL_BAD_ACCESS, "Invalid stream consumer type"); + return false; + } + + // Note: technically EGL_STREAM_STATE_EMPTY_KHR is a valid state when the timeout is non-zero. + // However, the timeout is effectively ignored since it has no useful functionality with the + // current producers that are implemented, so we don't allow that state + if (stream->getState() != EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR && + stream->getState() != EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR) + { + val->setError(EGL_BAD_STATE_KHR, "Invalid stream state"); + return false; + } + + return true; +} + +bool ValidateStreamConsumerReleaseKHR(const ValidationContext *val, + const Display *display, + const Stream *stream) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + const DisplayExtensions &displayExtensions = display->getExtensions(); + if (!displayExtensions.streamConsumerGLTexture) + { + val->setError(EGL_BAD_ACCESS, "Stream consumer extension not active"); + return false; + } + + if (stream == EGL_NO_STREAM_KHR || !display->isValidStream(stream)) + { + val->setError(EGL_BAD_STREAM_KHR, "Invalid stream"); + return false; + } + + gl::Context *context = val->eglThread->getContext(); + if (!context) + { + val->setError(EGL_BAD_ACCESS, "No GL context current to calling thread."); + return false; + } + + ANGLE_VALIDATION_TRY(ValidateContext(val, display, context)); + + if (!stream->isConsumerBoundToContext(context)) + { + val->setError(EGL_BAD_ACCESS, "Current GL context not associated with stream consumer"); + return false; + } + + if (stream->getConsumerType() != Stream::ConsumerType::GLTextureRGB && + stream->getConsumerType() != Stream::ConsumerType::GLTextureYUV) + { + val->setError(EGL_BAD_ACCESS, "Invalid stream consumer type"); + return false; + } + + if (stream->getState() != EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR && + stream->getState() != EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR) + { + val->setError(EGL_BAD_STATE_KHR, "Invalid stream state"); + return false; + } + + return true; +} + +bool ValidateStreamConsumerGLTextureExternalAttribsNV(const ValidationContext *val, + const Display *display, + const Stream *stream, + const AttributeMap &attribs) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + const DisplayExtensions &displayExtensions = display->getExtensions(); + if (!displayExtensions.streamConsumerGLTexture) + { + val->setError(EGL_BAD_ACCESS, "Stream consumer extension not active"); + return false; + } + + gl::Context *context = val->eglThread->getContext(); + ANGLE_VALIDATION_TRY(ValidateContext(val, display, context)); + + // Although technically not a requirement in spec, the context needs to be checked for support + // for external textures or future logic will cause assertations. This extension is also + // effectively useless without external textures. + if (!context->getExtensions().EGLStreamConsumerExternalNV) + { + val->setError(EGL_BAD_ACCESS, "EGL stream consumer external GL extension not enabled"); + return false; + } + + if (stream == EGL_NO_STREAM_KHR || !display->isValidStream(stream)) + { + val->setError(EGL_BAD_STREAM_KHR, "Invalid stream"); + return false; + } + + if (stream->getState() != EGL_STREAM_STATE_CREATED_KHR) + { + val->setError(EGL_BAD_STATE_KHR, "Invalid stream state"); + return false; + } + + const gl::Caps &glCaps = context->getCaps(); + + EGLAttrib colorBufferType = EGL_RGB_BUFFER; + EGLAttrib planeCount = -1; + EGLAttrib plane[3]; + for (int i = 0; i < 3; i++) + { + plane[i] = -1; + } + + attribs.initializeWithoutValidation(); + + for (const auto &attributeIter : attribs) + { + EGLAttrib attribute = attributeIter.first; + EGLAttrib value = attributeIter.second; + + switch (attribute) + { + case EGL_COLOR_BUFFER_TYPE: + if (value != EGL_RGB_BUFFER && value != EGL_YUV_BUFFER_EXT) + { + val->setError(EGL_BAD_PARAMETER, "Invalid color buffer type"); + return false; + } + colorBufferType = value; + break; + case EGL_YUV_NUMBER_OF_PLANES_EXT: + // planeCount = -1 is a tag for the default plane count so the value must be checked + // to be positive here to ensure future logic doesn't break on invalid negative + // inputs + if (value < 0) + { + val->setError(EGL_BAD_MATCH, "Invalid plane count"); + return false; + } + planeCount = value; + break; + default: + if (attribute >= EGL_YUV_PLANE0_TEXTURE_UNIT_NV && + attribute <= EGL_YUV_PLANE2_TEXTURE_UNIT_NV) + { + if ((value < 0 || + value >= static_cast(glCaps.maxCombinedTextureImageUnits)) && + value != EGL_NONE) + { + val->setError(EGL_BAD_ACCESS, "Invalid texture unit"); + return false; + } + plane[attribute - EGL_YUV_PLANE0_TEXTURE_UNIT_NV] = value; + } + else + { + val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute"); + return false; + } + } + } + + if (colorBufferType == EGL_RGB_BUFFER) + { + if (planeCount > 0) + { + val->setError(EGL_BAD_MATCH, "Plane count must be 0 for RGB buffer"); + return false; + } + for (int i = 0; i < 3; i++) + { + if (plane[i] != -1) + { + val->setError(EGL_BAD_MATCH, "Planes cannot be specified"); + return false; + } + } + + // Lookup the texture and ensure it is correct + gl::Texture *texture = context->getState().getTargetTexture(gl::TextureType::External); + if (texture == nullptr || texture->id().value == 0) + { + val->setError(EGL_BAD_ACCESS, "No external texture bound"); + return false; + } + } + else + { + if (planeCount == -1) + { + planeCount = 2; + } + if (planeCount < 1 || planeCount > 3) + { + val->setError(EGL_BAD_MATCH, "Invalid YUV plane count"); + return false; + } + for (EGLAttrib i = planeCount; i < 3; i++) + { + if (plane[i] != -1) + { + val->setError(EGL_BAD_MATCH, "Invalid plane specified"); + return false; + } + } + + // Set to ensure no texture is referenced more than once + std::set textureSet; + for (EGLAttrib i = 0; i < planeCount; i++) + { + if (plane[i] == -1) + { + val->setError(EGL_BAD_MATCH, "Not all planes specified"); + return false; + } + if (plane[i] != EGL_NONE) + { + gl::Texture *texture = context->getState().getSamplerTexture( + static_cast(plane[i]), gl::TextureType::External); + if (texture == nullptr || texture->id().value == 0) + { + val->setError( + EGL_BAD_ACCESS, + "No external texture bound at one or more specified texture units"); + return false; + } + if (textureSet.find(texture) != textureSet.end()) + { + val->setError(EGL_BAD_ACCESS, "Multiple planes bound to same texture object"); + return false; + } + textureSet.insert(texture); + } + } + } + + return true; +} + +bool ValidateCreateStreamProducerD3DTextureANGLE(const ValidationContext *val, + const Display *display, + const Stream *stream, + const AttributeMap &attribs) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + const DisplayExtensions &displayExtensions = display->getExtensions(); + if (!displayExtensions.streamProducerD3DTexture) + { + val->setError(EGL_BAD_ACCESS, "Stream producer extension not active"); + return false; + } + + ANGLE_VALIDATION_TRY(ValidateStream(val, display, stream)); + + attribs.initializeWithoutValidation(); + + if (!attribs.isEmpty()) + { + val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute"); + return false; + } + + if (stream->getState() != EGL_STREAM_STATE_CONNECTING_KHR) + { + val->setError(EGL_BAD_STATE_KHR, "Stream not in connecting state"); + return false; + } + + switch (stream->getConsumerType()) + { + case Stream::ConsumerType::GLTextureYUV: + if (stream->getPlaneCount() != 2) + { + val->setError(EGL_BAD_MATCH, "Incompatible stream consumer type"); + return false; + } + break; + + case Stream::ConsumerType::GLTextureRGB: + if (stream->getPlaneCount() != 1) + { + val->setError(EGL_BAD_MATCH, "Incompatible stream consumer type"); + return false; + } + break; + + default: + val->setError(EGL_BAD_MATCH, "Incompatible stream consumer type"); + return false; + } + + return true; +} + +bool ValidateStreamPostD3DTextureANGLE(const ValidationContext *val, + const Display *display, + const Stream *stream, + const void *texture, + const AttributeMap &attribs) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + const DisplayExtensions &displayExtensions = display->getExtensions(); + if (!displayExtensions.streamProducerD3DTexture) + { + val->setError(EGL_BAD_ACCESS, "Stream producer extension not active"); + return false; + } + + ANGLE_VALIDATION_TRY(ValidateStream(val, display, stream)); + + attribs.initializeWithoutValidation(); + + for (auto &attributeIter : attribs) + { + EGLAttrib attribute = attributeIter.first; + EGLAttrib value = attributeIter.second; + + switch (attribute) + { + case EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE: + if (value < 0) + { + val->setError(EGL_BAD_PARAMETER, "Invalid subresource index"); + return false; + } + break; + case EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG: + if (value < 0) + { + val->setError(EGL_BAD_PARAMETER, "Invalid plane offset"); + return false; + } + break; + default: + val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute"); + return false; + } + } + + if (stream->getState() != EGL_STREAM_STATE_EMPTY_KHR && + stream->getState() != EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR && + stream->getState() != EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR) + { + val->setError(EGL_BAD_STATE_KHR, "Stream not fully configured"); + return false; + } + + if (stream->getProducerType() != Stream::ProducerType::D3D11Texture) + { + val->setError(EGL_BAD_MATCH, "Incompatible stream producer"); + return false; + } + + if (texture == nullptr) + { + val->setError(EGL_BAD_PARAMETER, "Texture is null"); + return false; + } + + ANGLE_EGL_TRY_RETURN(val->eglThread, stream->validateD3D11Texture(texture, attribs), + val->entryPoint, val->labeledObject, false); + + return true; +} + +bool ValidateSyncControlCHROMIUM(const ValidationContext *val, + const Display *display, + const Surface *eglSurface) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + ANGLE_VALIDATION_TRY(ValidateSurface(val, display, eglSurface)); + + const DisplayExtensions &displayExtensions = display->getExtensions(); + if (!displayExtensions.syncControlCHROMIUM) + { + val->setError(EGL_BAD_ACCESS, "syncControlCHROMIUM extension not active"); + return false; + } + + return true; +} + +bool ValidateSyncControlRateANGLE(const ValidationContext *val, + const Display *display, + const Surface *eglSurface) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + ANGLE_VALIDATION_TRY(ValidateSurface(val, display, eglSurface)); + + const DisplayExtensions &displayExtensions = display->getExtensions(); + if (!displayExtensions.syncControlRateANGLE) + { + val->setError(EGL_BAD_ACCESS, "syncControlRateANGLE extension not active"); + return false; + } + + return true; +} + +bool ValidateGetMscRateANGLE(const ValidationContext *val, + const Display *display, + const Surface *eglSurface, + const EGLint *numerator, + const EGLint *denominator) +{ + ANGLE_VALIDATION_TRY(ValidateSyncControlRateANGLE(val, display, eglSurface)); + + if (numerator == nullptr) + { + val->setError(EGL_BAD_PARAMETER, "numerator is null"); + return false; + } + if (denominator == nullptr) + { + val->setError(EGL_BAD_PARAMETER, "denominator is null"); + return false; + } + + return true; +} + +bool ValidateGetSyncValuesCHROMIUM(const ValidationContext *val, + const Display *display, + const Surface *eglSurface, + const EGLuint64KHR *ust, + const EGLuint64KHR *msc, + const EGLuint64KHR *sbc) +{ + ANGLE_VALIDATION_TRY(ValidateSyncControlCHROMIUM(val, display, eglSurface)); + + if (ust == nullptr) + { + val->setError(EGL_BAD_PARAMETER, "ust is null"); + return false; + } + if (msc == nullptr) + { + val->setError(EGL_BAD_PARAMETER, "msc is null"); + return false; + } + if (sbc == nullptr) + { + val->setError(EGL_BAD_PARAMETER, "sbc is null"); + return false; + } + + return true; +} + +bool ValidateDestroySurface(const ValidationContext *val, + const Display *display, + const Surface *surface) +{ + ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); + return true; +} + +bool ValidateDestroyContext(const ValidationContext *val, + const Display *display, + const gl::Context *glCtx) +{ + ANGLE_VALIDATION_TRY(ValidateContext(val, display, glCtx)); + return true; +} + +bool ValidateSwapBuffers(const ValidationContext *val, + const Display *display, + const Surface *eglSurface) +{ + ANGLE_VALIDATION_TRY(ValidateSurface(val, display, eglSurface)); + + if (display->isDeviceLost()) + { + val->setError(EGL_CONTEXT_LOST); + return false; + } + + if (eglSurface->isLocked()) + { + val->setError(EGL_BAD_ACCESS); + return false; + } + + if (eglSurface == EGL_NO_SURFACE || !val->eglThread->getContext() || + val->eglThread->getCurrentDrawSurface() != eglSurface) + { + val->setError(EGL_BAD_SURFACE); + return false; + } + + return true; +} + +bool ValidateSwapBuffersWithDamageKHR(const ValidationContext *val, + const Display *display, + const Surface *surface, + const EGLint *rects, + EGLint n_rects) +{ + ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); + + if (!display->getExtensions().swapBuffersWithDamage) + { + // It is out of spec what happens when calling an extension function when the extension is + // not available. EGL_BAD_DISPLAY seems like a reasonable error. + val->setError(EGL_BAD_DISPLAY, "EGL_KHR_swap_buffers_with_damage is not available."); + return false; + } + + if (surface == EGL_NO_SURFACE) + { + val->setError(EGL_BAD_SURFACE, "Swap surface cannot be EGL_NO_SURFACE."); + return false; + } + + if (n_rects < 0) + { + val->setError(EGL_BAD_PARAMETER, "n_rects cannot be negative."); + return false; + } + + if (n_rects > 0 && rects == nullptr) + { + val->setError(EGL_BAD_PARAMETER, "n_rects cannot be greater than zero when rects is NULL."); + return false; + } + + if (surface->isLocked()) + { + val->setError(EGL_BAD_ACCESS); + return false; + } + + // TODO(jmadill): Validate Surface is bound to the thread. + + return true; +} + +bool ValidateWaitNative(const ValidationContext *val, const EGLint engine) +{ + if (val->eglThread->getDisplay() == nullptr) + { + // EGL spec says this about eglWaitNative - + // eglWaitNative is ignored if there is no current EGL rendering context. + return true; + } + + ANGLE_VALIDATION_TRY(ValidateDisplay(val, val->eglThread->getDisplay())); + + if (engine != EGL_CORE_NATIVE_ENGINE) + { + val->setError(EGL_BAD_PARAMETER, "the 'engine' parameter has an unrecognized value"); + return false; + } + + return true; +} + +bool ValidateCopyBuffers(const ValidationContext *val, + const Display *display, + const Surface *surface, + EGLNativePixmapType target) +{ + ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); + + if (display->isDeviceLost()) + { + val->setError(EGL_CONTEXT_LOST); + return false; + } + + return true; +} + +bool ValidateBindTexImage(const ValidationContext *val, + const Display *display, + const Surface *surface, + const EGLint buffer) +{ + ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); + + if (buffer != EGL_BACK_BUFFER) + { + val->setError(EGL_BAD_PARAMETER); + return false; + } + + if (surface->getType() == EGL_WINDOW_BIT) + { + val->setError(EGL_BAD_SURFACE); + return false; + } + + if (surface->getBoundTexture()) + { + val->setError(EGL_BAD_ACCESS); + return false; + } + + if (surface->getTextureFormat() == TextureFormat::NoTexture) + { + val->setError(EGL_BAD_MATCH); + return false; + } + + if (surface->isLocked()) + { + val->setError(EGL_BAD_ACCESS); + return false; + } + + gl::Context *context = val->eglThread->getContext(); + if (context && !context->isContextLost()) + { + gl::TextureType type = egl_gl::EGLTextureTargetToTextureType(surface->getTextureTarget()); + gl::Texture *textureObject = context->getTextureByType(type); + ASSERT(textureObject != nullptr); + + if (textureObject->getImmutableFormat()) + { + val->setError(EGL_BAD_MATCH); + return false; + } + } + + return true; +} + +bool ValidateReleaseTexImage(const ValidationContext *val, + const Display *display, + const Surface *surface, + const EGLint buffer) +{ + ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); + + if (buffer != EGL_BACK_BUFFER) + { + val->setError(EGL_BAD_PARAMETER); + return false; + } + + if (surface->getType() == EGL_WINDOW_BIT) + { + val->setError(EGL_BAD_SURFACE); + return false; + } + + if (surface->getTextureFormat() == TextureFormat::NoTexture) + { + val->setError(EGL_BAD_MATCH); + return false; + } + + return true; +} + +bool ValidateSwapInterval(const ValidationContext *val, const Display *display, EGLint interval) +{ + const gl::Context *context = val->eglThread->getContext(); + ANGLE_VALIDATION_TRY(ValidateContext(val, display, context)); + + Surface *drawSurface = val->eglThread->getCurrentDrawSurface(); + if (drawSurface == nullptr) + { + val->setError(EGL_BAD_SURFACE); + return false; + } + + return true; +} + +bool ValidateBindAPI(const ValidationContext *val, const EGLenum api) +{ + switch (api) + { + case EGL_OPENGL_ES_API: + case EGL_OPENGL_API: + break; + case EGL_OPENVG_API: + val->setError(EGL_BAD_PARAMETER); + return false; // Not supported by this implementation + default: + val->setError(EGL_BAD_PARAMETER); + return false; + } + + return true; +} + +bool ValidatePresentationTimeANDROID(const ValidationContext *val, + const Display *display, + const Surface *surface, + EGLnsecsANDROID time) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + if (!display->getExtensions().presentationTime) + { + // It is out of spec what happens when calling an extension function when the extension is + // not available. EGL_BAD_DISPLAY seems like a reasonable error. + val->setError(EGL_BAD_DISPLAY, "EGL_ANDROID_presentation_time is not available."); + return false; + } + + ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); + + return true; +} + +bool ValidateSetBlobCacheFuncsANDROID(const ValidationContext *val, + const Display *display, + EGLSetBlobFuncANDROID set, + EGLGetBlobFuncANDROID get) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + if (display->areBlobCacheFuncsSet()) + { + val->setError(EGL_BAD_PARAMETER, + "Blob cache functions can only be set once in the lifetime of a Display"); + return false; + } + + if (set == nullptr || get == nullptr) + { + val->setError(EGL_BAD_PARAMETER, "Blob cache callbacks cannot be null."); + return false; + } + + return true; +} + +bool ValidateGetConfigAttrib(const ValidationContext *val, + const Display *display, + const Config *config, + EGLint attribute, + const EGLint *value) +{ + ANGLE_VALIDATION_TRY(ValidateConfig(val, display, config)); + ANGLE_TRY(ValidateConfigAttribute(val, display, static_cast(attribute))); + return true; +} + +bool ValidateChooseConfig(const ValidationContext *val, + const Display *display, + const AttributeMap &attribs, + const EGLConfig *configs, + EGLint configSize, + const EGLint *numConfig) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + ANGLE_VALIDATION_TRY(ValidateConfigAttributes(val, display, attribs)); + + if (numConfig == nullptr) + { + val->setError(EGL_BAD_PARAMETER, "num_config cannot be null."); + return false; + } + + return true; +} + +bool ValidateGetConfigs(const ValidationContext *val, + const Display *display, + const EGLConfig *configs, + EGLint configSize, + const EGLint *numConfig) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + if (numConfig == nullptr) + { + val->setError(EGL_BAD_PARAMETER, "num_config cannot be null."); + return false; + } + + return true; +} + +bool ValidateGetPlatformDisplay(const ValidationContext *val, + EGLenum platform, + const void *native_display, + const AttributeMap &attribMap) +{ + return ValidateGetPlatformDisplayCommon(val, platform, native_display, attribMap); +} + +bool ValidateGetPlatformDisplayEXT(const ValidationContext *val, + EGLenum platform, + const void *native_display, + const AttributeMap &attribMap) +{ + return ValidateGetPlatformDisplayCommon(val, platform, native_display, attribMap); +} + +bool ValidateCreatePlatformWindowSurfaceEXT(const ValidationContext *val, + const Display *display, + const Config *configuration, + const void *nativeWindow, + const AttributeMap &attributes) +{ + if (!Display::GetClientExtensions().platformBase) + { + val->setError(EGL_BAD_ACCESS, "EGL_EXT_platform_base not supported"); + return false; + } + + const void *actualNativeWindow = display->getImplementation()->isX11() + ? *reinterpret_cast(nativeWindow) + : nativeWindow; + + return ValidateCreatePlatformWindowSurface(val, display, configuration, actualNativeWindow, + attributes); +} + +bool ValidateCreatePlatformPixmapSurfaceEXT(const ValidationContext *val, + const Display *display, + const Config *configuration, + const void *nativePixmap, + const AttributeMap &attributes) +{ + if (!Display::GetClientExtensions().platformBase) + { + val->setError(EGL_BAD_ACCESS, "EGL_EXT_platform_base not supported"); + return false; + } + + ANGLE_VALIDATION_TRY(ValidateConfig(val, display, configuration)); + + val->setError(EGL_BAD_DISPLAY, "ValidateCreatePlatformPixmapSurfaceEXT unimplemented."); + return false; +} + +bool ValidateProgramCacheGetAttribANGLE(const ValidationContext *val, + const Display *display, + EGLenum attrib) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + if (!display->getExtensions().programCacheControlANGLE) + { + val->setError(EGL_BAD_ACCESS, "Extension not supported"); + return false; + } + + switch (attrib) + { + case EGL_PROGRAM_CACHE_KEY_LENGTH_ANGLE: + case EGL_PROGRAM_CACHE_SIZE_ANGLE: + break; + + default: + val->setError(EGL_BAD_PARAMETER, "Invalid program cache attribute."); + return false; + } + + return true; +} + +bool ValidateProgramCacheQueryANGLE(const ValidationContext *val, + const Display *display, + EGLint index, + const void *key, + const EGLint *keysize, + const void *binary, + const EGLint *binarysize) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + if (!display->getExtensions().programCacheControlANGLE) + { + val->setError(EGL_BAD_ACCESS, "Extension not supported"); + return false; + } + + if (index < 0 || index >= display->programCacheGetAttrib(EGL_PROGRAM_CACHE_SIZE_ANGLE)) + { + val->setError(EGL_BAD_PARAMETER, "Program index out of range."); + return false; + } + + if (keysize == nullptr || binarysize == nullptr) + { + val->setError(EGL_BAD_PARAMETER, "keysize and binarysize must always be valid pointers."); + return false; + } + + if (binary && *keysize != static_cast(egl::BlobCache::kKeyLength)) + { + val->setError(EGL_BAD_PARAMETER, "Invalid program key size."); + return false; + } + + if ((key == nullptr) != (binary == nullptr)) + { + val->setError(EGL_BAD_PARAMETER, "key and binary must both be null or both non-null."); + return false; + } + + return true; +} + +bool ValidateProgramCachePopulateANGLE(const ValidationContext *val, + const Display *display, + const void *key, + EGLint keysize, + const void *binary, + EGLint binarysize) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + if (!display->getExtensions().programCacheControlANGLE) + { + val->setError(EGL_BAD_ACCESS, "Extension not supported"); + return false; + } + + if (keysize != static_cast(egl::BlobCache::kKeyLength)) + { + val->setError(EGL_BAD_PARAMETER, "Invalid program key size."); + return false; + } + + if (key == nullptr || binary == nullptr) + { + val->setError(EGL_BAD_PARAMETER, "null pointer in arguments."); + return false; + } + + // Upper bound for binarysize is arbitrary. + if (binarysize <= 0 || binarysize > egl::kProgramCacheSizeAbsoluteMax) + { + val->setError(EGL_BAD_PARAMETER, "binarysize out of valid range."); + return false; + } + + return true; +} + +bool ValidateProgramCacheResizeANGLE(const ValidationContext *val, + const Display *display, + EGLint limit, + EGLint mode) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + if (!display->getExtensions().programCacheControlANGLE) + { + val->setError(EGL_BAD_ACCESS, "Extension not supported"); + return false; + } + + if (limit < 0) + { + val->setError(EGL_BAD_PARAMETER, "limit must be non-negative."); + return false; + } + + switch (mode) + { + case EGL_PROGRAM_CACHE_RESIZE_ANGLE: + case EGL_PROGRAM_CACHE_TRIM_ANGLE: + break; + + default: + val->setError(EGL_BAD_PARAMETER, "Invalid cache resize mode."); + return false; + } + + return true; +} + +bool ValidateSurfaceAttrib(const ValidationContext *val, + const Display *display, + const Surface *surface, + EGLint attribute, + EGLint value) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); + + if (surface == EGL_NO_SURFACE) + { + val->setError(EGL_BAD_SURFACE, "Surface cannot be EGL_NO_SURFACE."); + return false; + } + + switch (attribute) + { + case EGL_MIPMAP_LEVEL: + break; + + case EGL_MULTISAMPLE_RESOLVE: + switch (value) + { + case EGL_MULTISAMPLE_RESOLVE_DEFAULT: + break; + + case EGL_MULTISAMPLE_RESOLVE_BOX: + if ((surface->getConfig()->surfaceType & EGL_MULTISAMPLE_RESOLVE_BOX_BIT) == 0) + { + val->setError(EGL_BAD_MATCH, + "Surface does not support EGL_MULTISAMPLE_RESOLVE_BOX."); + return false; + } + break; + + default: + val->setError(EGL_BAD_ATTRIBUTE, "Invalid multisample resolve type."); + return false; + } + break; + + case EGL_SWAP_BEHAVIOR: + switch (value) + { + case EGL_BUFFER_PRESERVED: + if ((surface->getConfig()->surfaceType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT) == 0) + { + val->setError(EGL_BAD_MATCH, + "Surface does not support EGL_SWAP_BEHAVIOR_PRESERVED."); + return false; + } + break; + + case EGL_BUFFER_DESTROYED: + break; + + default: + val->setError(EGL_BAD_ATTRIBUTE, "Invalid swap behaviour."); + return false; + } + break; + + case EGL_WIDTH: + case EGL_HEIGHT: + if (!display->getExtensions().windowFixedSize) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_WIDTH or EGL_HEIGHT cannot be set without " + "EGL_ANGLE_window_fixed_size support."); + return false; + } + if (!surface->isFixedSize()) + { + val->setError(EGL_BAD_MATCH, + "EGL_WIDTH or EGL_HEIGHT cannot be set without " + "EGL_FIXED_SIZE_ANGLE being enabled on the surface."); + return false; + } + break; + + case EGL_TIMESTAMPS_ANDROID: + if (!display->getExtensions().getFrameTimestamps && + !display->getExtensions().timestampSurfaceAttributeANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_TIMESTAMPS_ANDROID cannot be used without " + "EGL_ANDROID_get_frame_timestamps support."); + return false; + } + switch (value) + { + case EGL_TRUE: + case EGL_FALSE: + break; + + default: + val->setError(EGL_BAD_ATTRIBUTE, "Invalid value."); + return false; + } + break; + + case EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID: + ASSERT(value == EGL_TRUE || value == EGL_FALSE); + break; + + case EGL_RENDER_BUFFER: + if (value != EGL_BACK_BUFFER && value != EGL_SINGLE_BUFFER) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_RENDER_BUFFER must be EGL_BACK_BUFFER or EGL_SINGLE_BUFFER."); + return false; + } + + if (value == EGL_SINGLE_BUFFER) + { + if (!display->getExtensions().mutableRenderBufferKHR) + { + val->setError( + EGL_BAD_ATTRIBUTE, + "Attribute EGL_RENDER_BUFFER requires EGL_KHR_mutable_render_buffer."); + return false; + } + + if ((surface->getConfig()->surfaceType & EGL_MUTABLE_RENDER_BUFFER_BIT_KHR) == 0) + { + val->setError(EGL_BAD_MATCH, + "EGL_RENDER_BUFFER requires the surface type bit " + "EGL_MUTABLE_RENDER_BUFFER_BIT_KHR."); + return false; + } + } + break; + + default: + val->setError(EGL_BAD_ATTRIBUTE, "Invalid surface attribute: 0x%04X", attribute); + return false; + } + + return true; +} + +bool ValidateQuerySurface(const ValidationContext *val, + const Display *display, + const Surface *surface, + EGLint attribute, + const EGLint *value) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); + + if (surface == EGL_NO_SURFACE) + { + val->setError(EGL_BAD_SURFACE, "Surface cannot be EGL_NO_SURFACE."); + return false; + } + + switch (attribute) + { + case EGL_GL_COLORSPACE: + case EGL_VG_ALPHA_FORMAT: + case EGL_VG_COLORSPACE: + case EGL_CONFIG_ID: + case EGL_HEIGHT: + case EGL_HORIZONTAL_RESOLUTION: + case EGL_LARGEST_PBUFFER: + case EGL_MIPMAP_TEXTURE: + case EGL_MIPMAP_LEVEL: + case EGL_MULTISAMPLE_RESOLVE: + case EGL_PIXEL_ASPECT_RATIO: + case EGL_RENDER_BUFFER: + case EGL_SWAP_BEHAVIOR: + case EGL_TEXTURE_FORMAT: + case EGL_TEXTURE_TARGET: + case EGL_VERTICAL_RESOLUTION: + case EGL_WIDTH: + break; + + case EGL_POST_SUB_BUFFER_SUPPORTED_NV: + if (!display->getExtensions().postSubBuffer) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_POST_SUB_BUFFER_SUPPORTED_NV cannot be used " + "without EGL_ANGLE_surface_orientation support."); + return false; + } + break; + + case EGL_FIXED_SIZE_ANGLE: + if (!display->getExtensions().windowFixedSize) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_FIXED_SIZE_ANGLE cannot be used without " + "EGL_ANGLE_window_fixed_size support."); + return false; + } + break; + + case EGL_SURFACE_ORIENTATION_ANGLE: + if (!display->getExtensions().surfaceOrientation) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_SURFACE_ORIENTATION_ANGLE cannot be " + "queried without " + "EGL_ANGLE_surface_orientation support."); + return false; + } + break; + + case EGL_DIRECT_COMPOSITION_ANGLE: + if (!display->getExtensions().directComposition) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_DIRECT_COMPOSITION_ANGLE cannot be " + "used without " + "EGL_ANGLE_direct_composition support."); + return false; + } + break; + + case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE: + if (!display->getExtensions().robustResourceInitializationANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE cannot be " + "used without EGL_ANGLE_robust_resource_initialization " + "support."); + return false; + } + break; + + case EGL_TIMESTAMPS_ANDROID: + if (!display->getExtensions().getFrameTimestamps && + !display->getExtensions().timestampSurfaceAttributeANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_TIMESTAMPS_ANDROID cannot be used without " + "EGL_ANDROID_get_frame_timestamps support."); + return false; + } + break; + + case EGL_BUFFER_AGE_EXT: + { + if (!display->getExtensions().bufferAgeEXT) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_BUFFER_AGE_EXT cannot be used without " + "EGL_EXT_buffer_age support."); + return false; + } + gl::Context *context = val->eglThread->getContext(); + if ((context == nullptr) || (context->getCurrentDrawSurface() != surface)) + { + val->setError(EGL_BAD_SURFACE, + "The surface must be current to the current context " + "in order to query buffer age per extension " + "EGL_EXT_buffer_age."); + return false; + } + } + break; + + case EGL_BITMAP_PITCH_KHR: + case EGL_BITMAP_ORIGIN_KHR: + case EGL_BITMAP_PIXEL_RED_OFFSET_KHR: + case EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR: + case EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR: + case EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR: + case EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR: + case EGL_BITMAP_PIXEL_SIZE_KHR: + if (!display->getExtensions().lockSurface3KHR) + { + val->setError(EGL_BAD_ATTRIBUTE, "EGL_KHR_lock_surface3 is not supported."); + return false; + } + break; + + case EGL_PROTECTED_CONTENT_EXT: + if (!display->getExtensions().protectedContentEXT) + { + val->setError(EGL_BAD_ATTRIBUTE, "EGL_EXT_protected_content not supported"); + return false; + } + break; + + default: + val->setError(EGL_BAD_ATTRIBUTE, "Invalid surface attribute: 0x%04X", attribute); + return false; + } + + return true; +} + +bool ValidateQueryContext(const ValidationContext *val, + const Display *display, + const gl::Context *context, + EGLint attribute, + const EGLint *value) +{ + ANGLE_VALIDATION_TRY(ValidateContext(val, display, context)); + + switch (attribute) + { + case EGL_CONFIG_ID: + case EGL_CONTEXT_CLIENT_TYPE: + case EGL_CONTEXT_CLIENT_VERSION: + case EGL_RENDER_BUFFER: + break; + + case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE: + if (!display->getExtensions().robustResourceInitializationANGLE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE cannot be " + "used without EGL_ANGLE_robust_resource_initialization " + "support."); + return false; + } + break; + + case EGL_CONTEXT_PRIORITY_LEVEL_IMG: + if (!display->getExtensions().contextPriority) + { + val->setError(EGL_BAD_ATTRIBUTE, + "Attribute EGL_CONTEXT_PRIORITY_LEVEL_IMG requires " + "extension EGL_IMG_context_priority."); + return false; + } + break; + + case EGL_PROTECTED_CONTENT_EXT: + if (!display->getExtensions().protectedContentEXT) + { + val->setError(EGL_BAD_ATTRIBUTE, "EGL_EXT_protected_content not supported"); + return false; + } + break; + + default: + val->setError(EGL_BAD_ATTRIBUTE, "Invalid context attribute: 0x%04X", attribute); + return false; + } + + return true; +} + +bool ValidateDebugMessageControlKHR(const ValidationContext *val, + EGLDEBUGPROCKHR callback, + const AttributeMap &attribs) +{ + const ClientExtensions &clientExtensions = Display::GetClientExtensions(); + if (!clientExtensions.debug) + { + val->setError(EGL_BAD_ACCESS, "EGL_KHR_debug extension is not available."); + return false; + } + + attribs.initializeWithoutValidation(); + + for (const auto &attrib : attribs) + { + switch (attrib.first) + { + case EGL_DEBUG_MSG_CRITICAL_KHR: + case EGL_DEBUG_MSG_ERROR_KHR: + case EGL_DEBUG_MSG_WARN_KHR: + case EGL_DEBUG_MSG_INFO_KHR: + if (attrib.second != EGL_TRUE && attrib.second != EGL_FALSE) + { + val->setError(EGL_BAD_ATTRIBUTE, + "message controls must be EGL_TRUE or EGL_FALSE."); + return false; + } + break; + } + } + + return true; +} + +bool ValidateQueryDebugKHR(const ValidationContext *val, EGLint attribute, const EGLAttrib *value) +{ + const ClientExtensions &clientExtensions = Display::GetClientExtensions(); + if (!clientExtensions.debug) + { + val->setError(EGL_BAD_ACCESS, "EGL_KHR_debug extension is not available."); + return false; + } + + switch (attribute) + { + case EGL_DEBUG_MSG_CRITICAL_KHR: + case EGL_DEBUG_MSG_ERROR_KHR: + case EGL_DEBUG_MSG_WARN_KHR: + case EGL_DEBUG_MSG_INFO_KHR: + case EGL_DEBUG_CALLBACK_KHR: + break; + + default: + val->setError(EGL_BAD_ATTRIBUTE, "Unknown attribute: 0x%04X", attribute); + return false; + } + + return true; +} + +bool ValidateLabelObjectKHR(const ValidationContext *val, + const Display *display, + ObjectType objectType, + EGLObjectKHR object, + EGLLabelKHR label) +{ + const ClientExtensions &clientExtensions = Display::GetClientExtensions(); + if (!clientExtensions.debug) + { + val->setError(EGL_BAD_ACCESS, "EGL_KHR_debug extension is not available."); + return false; + } + + LabeledObject *labeledObject = nullptr; + ANGLE_VALIDATION_TRY(ValidateLabeledObject(val, display, objectType, object, &labeledObject)); + + return true; +} + +bool ValidateGetCompositorTimingSupportedANDROID(const ValidationContext *val, + const Display *display, + const Surface *surface, + CompositorTiming name) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + if (!display->getExtensions().getFrameTimestamps) + { + val->setError(EGL_BAD_DISPLAY, + "EGL_ANDROID_get_frame_timestamps extension is not available."); + return false; + } + + ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); + + if (!ValidCompositorTimingName(name)) + { + val->setError(EGL_BAD_PARAMETER, "invalid timing name."); + return false; + } + + return true; +} + +bool ValidateGetCompositorTimingANDROID(const ValidationContext *val, + const Display *display, + const Surface *surface, + EGLint numTimestamps, + const EGLint *names, + const EGLnsecsANDROID *values) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + if (!display->getExtensions().getFrameTimestamps) + { + val->setError(EGL_BAD_DISPLAY, + "EGL_ANDROID_get_frame_timestamps extension is not available."); + return false; + } + + ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); + + if (names == nullptr && numTimestamps > 0) + { + val->setError(EGL_BAD_PARAMETER, "names is NULL."); + return false; + } + + if (values == nullptr && numTimestamps > 0) + { + val->setError(EGL_BAD_PARAMETER, "values is NULL."); + return false; + } + + if (numTimestamps < 0) + { + val->setError(EGL_BAD_PARAMETER, "numTimestamps must be at least 0."); + return false; + } + + for (EGLint i = 0; i < numTimestamps; i++) + { + CompositorTiming name = FromEGLenum(names[i]); + + if (!ValidCompositorTimingName(name)) + { + val->setError(EGL_BAD_PARAMETER, "invalid compositor timing."); + return false; + } + + if (!surface->getSupportedCompositorTimings().test(name)) + { + val->setError(EGL_BAD_PARAMETER, "compositor timing not supported by surface."); + return false; + } + } + + return true; +} + +bool ValidateGetNextFrameIdANDROID(const ValidationContext *val, + const Display *display, + const Surface *surface, + const EGLuint64KHR *frameId) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + if (!display->getExtensions().getFrameTimestamps) + { + val->setError(EGL_BAD_DISPLAY, + "EGL_ANDROID_get_frame_timestamps extension is not available."); + return false; + } + + ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); + + if (frameId == nullptr) + { + val->setError(EGL_BAD_PARAMETER, "frameId is NULL."); + return false; + } + + return true; +} + +bool ValidateGetFrameTimestampSupportedANDROID(const ValidationContext *val, + const Display *display, + const Surface *surface, + Timestamp timestamp) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + if (!display->getExtensions().getFrameTimestamps) + { + val->setError(EGL_BAD_DISPLAY, + "EGL_ANDROID_get_frame_timestamps extension is not available."); + return false; + } + + ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); + + if (!ValidTimestampType(timestamp)) + { + val->setError(EGL_BAD_PARAMETER, "invalid timestamp type."); + return false; + } + + return true; +} + +bool ValidateGetFrameTimestampsANDROID(const ValidationContext *val, + const Display *display, + const Surface *surface, + EGLuint64KHR frameId, + EGLint numTimestamps, + const EGLint *timestamps, + const EGLnsecsANDROID *values) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + if (!display->getExtensions().getFrameTimestamps) + { + val->setError(EGL_BAD_DISPLAY, + "EGL_ANDROID_get_frame_timestamps extension is not available."); + return false; + } + + ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); + + if (!surface->isTimestampsEnabled()) + { + val->setError(EGL_BAD_SURFACE, "timestamp collection is not enabled for this surface."); + return false; + } + + if (timestamps == nullptr && numTimestamps > 0) + { + val->setError(EGL_BAD_PARAMETER, "timestamps is NULL."); + return false; + } + + if (values == nullptr && numTimestamps > 0) + { + val->setError(EGL_BAD_PARAMETER, "values is NULL."); + return false; + } + + if (numTimestamps < 0) + { + val->setError(EGL_BAD_PARAMETER, "numTimestamps must be at least 0."); + return false; + } + + for (EGLint i = 0; i < numTimestamps; i++) + { + Timestamp timestamp = FromEGLenum(timestamps[i]); + + if (!ValidTimestampType(timestamp)) + { + val->setError(EGL_BAD_PARAMETER, "invalid timestamp type."); + return false; + } + + if (!surface->getSupportedTimestamps().test(timestamp)) + { + val->setError(EGL_BAD_PARAMETER, "timestamp not supported by surface."); + return false; + } + } + + return true; +} + +bool ValidateQueryStringiANGLE(const ValidationContext *val, + const Display *display, + EGLint name, + EGLint index) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + if (!Display::GetClientExtensions().featureControlANGLE) + { + val->setError(EGL_BAD_DISPLAY, "EGL_ANGLE_feature_control extension is not available."); + return false; + } + + if (index < 0) + { + val->setError(EGL_BAD_PARAMETER, "index is negative."); + return false; + } + + switch (name) + { + case EGL_FEATURE_NAME_ANGLE: + case EGL_FEATURE_CATEGORY_ANGLE: + case EGL_FEATURE_DESCRIPTION_ANGLE: + case EGL_FEATURE_BUG_ANGLE: + case EGL_FEATURE_STATUS_ANGLE: + case EGL_FEATURE_CONDITION_ANGLE: + break; + default: + val->setError(EGL_BAD_PARAMETER, "name is not valid."); + return false; + } + + if (static_cast(index) >= display->getFeatures().size()) + { + val->setError(EGL_BAD_PARAMETER, "index is too big."); + return false; + } + + return true; +} + +bool ValidateQueryDisplayAttribEXT(const ValidationContext *val, + const Display *display, + const EGLint attribute, + const EGLAttrib *value) +{ + ANGLE_VALIDATION_TRY(ValidateQueryDisplayAttribBase(val, display, attribute)); + return true; +} + +bool ValidateQueryDisplayAttribANGLE(const ValidationContext *val, + const Display *display, + const EGLint attribute, + const EGLAttrib *value) +{ + ANGLE_VALIDATION_TRY(ValidateQueryDisplayAttribBase(val, display, attribute)); + return true; +} + +bool ValidateGetNativeClientBufferANDROID(const ValidationContext *val, + const AHardwareBuffer *buffer) +{ + // No extension check is done because no display is passed to eglGetNativeClientBufferANDROID + // despite it being a display extension. No display is needed for the implementation though. + if (buffer == nullptr) + { + val->setError(EGL_BAD_PARAMETER, "NULL buffer."); + return false; + } + + return true; +} + +bool ValidateCreateNativeClientBufferANDROID(const ValidationContext *val, + const egl::AttributeMap &attribMap) +{ + attribMap.initializeWithoutValidation(); + + if (attribMap.isEmpty() || attribMap.begin()->second == EGL_NONE) + { + val->setError(EGL_BAD_PARAMETER, "invalid attribute list."); + return false; + } + + int width = attribMap.getAsInt(EGL_WIDTH, 0); + int height = attribMap.getAsInt(EGL_HEIGHT, 0); + int redSize = attribMap.getAsInt(EGL_RED_SIZE, 0); + int greenSize = attribMap.getAsInt(EGL_GREEN_SIZE, 0); + int blueSize = attribMap.getAsInt(EGL_BLUE_SIZE, 0); + int alphaSize = attribMap.getAsInt(EGL_ALPHA_SIZE, 0); + int usage = attribMap.getAsInt(EGL_NATIVE_BUFFER_USAGE_ANDROID, 0); + + for (AttributeMap::const_iterator attributeIter = attribMap.begin(); + attributeIter != attribMap.end(); attributeIter++) + { + EGLAttrib attribute = attributeIter->first; + switch (attribute) + { + case EGL_WIDTH: + case EGL_HEIGHT: + // Validation done after the switch statement + break; + case EGL_RED_SIZE: + case EGL_GREEN_SIZE: + case EGL_BLUE_SIZE: + case EGL_ALPHA_SIZE: + if (redSize < 0 || greenSize < 0 || blueSize < 0 || alphaSize < 0) + { + val->setError(EGL_BAD_PARAMETER, "incorrect channel size requested"); + return false; + } + break; + case EGL_NATIVE_BUFFER_USAGE_ANDROID: + // The buffer must be used for either a texture or a renderbuffer. + if ((usage & ~(EGL_NATIVE_BUFFER_USAGE_PROTECTED_BIT_ANDROID | + EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID | + EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID)) != 0) + { + val->setError(EGL_BAD_PARAMETER, "invalid usage flag"); + return false; + } + break; + case EGL_NONE: + break; + default: + val->setError(EGL_BAD_ATTRIBUTE, "invalid attribute"); + return false; + } + } + + // Validate EGL_WIDTH and EGL_HEIGHT values passed in. Done here to account + // for the case where EGL_WIDTH and EGL_HEIGHT were not part of the attribute list. + if (width <= 0 || height <= 0) + { + val->setError(EGL_BAD_PARAMETER, "incorrect buffer dimensions requested"); + return false; + } + + if (gl::GetAndroidHardwareBufferFormatFromChannelSizes(attribMap) == 0) + { + val->setError(EGL_BAD_PARAMETER, "unsupported format"); + return false; + } + return true; +} + +bool ValidateCopyMetalSharedEventANGLE(const ValidationContext *val, + const Display *display, + const Sync *sync) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + if (!display->getExtensions().mtlSyncSharedEventANGLE) + { + val->setError(EGL_BAD_DISPLAY, "EGL_ANGLE_metal_shared_event_sync is not available."); + return false; + } + + ANGLE_VALIDATION_TRY(ValidateSync(val, display, sync)); + + return true; +} + +bool ValidateDupNativeFenceFDANDROID(const ValidationContext *val, + const Display *display, + const Sync *sync) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + if (!display->getExtensions().nativeFenceSyncANDROID) + { + val->setError(EGL_BAD_DISPLAY, "EGL_ANDROID_native_fence_sync extension is not available."); + return false; + } + + ANGLE_VALIDATION_TRY(ValidateSync(val, display, sync)); + + return true; +} + +bool ValidateSwapBuffersWithFrameTokenANGLE(const ValidationContext *val, + const Display *display, + const Surface *surface, + EGLFrameTokenANGLE frametoken) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + if (!display->getExtensions().swapWithFrameToken) + { + val->setError(EGL_BAD_DISPLAY, "EGL_ANGLE_swap_buffers_with_frame_token is not available."); + return false; + } + + ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); + + return true; +} + +bool ValidatePrepareSwapBuffersANGLE(const ValidationContext *val, + const Display *display, + const Surface *surface) +{ + return ValidateSwapBuffers(val, display, surface); +} + +bool ValidateSignalSyncKHR(const ValidationContext *val, + const Display *display, + const Sync *sync, + EGLenum mode) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + ANGLE_VALIDATION_TRY(ValidateSync(val, display, sync)); + + if (sync->getType() == EGL_SYNC_REUSABLE_KHR) + { + if (!display->getExtensions().reusableSyncKHR) + { + val->setError(EGL_BAD_MATCH, "EGL_KHR_reusable_sync extension is not available."); + return false; + } + + if ((mode != EGL_SIGNALED_KHR) && (mode != EGL_UNSIGNALED_KHR)) + { + val->setError(EGL_BAD_PARAMETER, "eglSignalSyncKHR invalid mode."); + return false; + } + + return true; + } + + val->setError(EGL_BAD_MATCH); + return false; +} + +bool ValidateQuerySurfacePointerANGLE(const ValidationContext *val, + const Display *display, + const Surface *eglSurface, + EGLint attribute, + void *const *value) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + if (!display->getExtensions().querySurfacePointer) + { + val->setError(EGL_BAD_ACCESS); + return false; + } + + ANGLE_VALIDATION_TRY(ValidateSurface(val, display, eglSurface)); + + // validate the attribute parameter + switch (attribute) + { + case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE: + if (!display->getExtensions().surfaceD3DTexture2DShareHandle) + { + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + break; + case EGL_DXGI_KEYED_MUTEX_ANGLE: + if (!display->getExtensions().keyedMutex) + { + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + break; + default: + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + + return true; +} + +bool ValidatePostSubBufferNV(const ValidationContext *val, + const Display *display, + const Surface *eglSurface, + EGLint x, + EGLint y, + EGLint width, + EGLint height) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + + if (!display->getExtensions().postSubBuffer) + { + val->setError(EGL_BAD_ACCESS); + return false; + } + + if (x < 0 || y < 0 || width < 0 || height < 0) + { + val->setError(EGL_BAD_PARAMETER); + return false; + } + + ANGLE_VALIDATION_TRY(ValidateSurface(val, display, eglSurface)); + + if (display->isDeviceLost()) + { + val->setError(EGL_CONTEXT_LOST); + return false; + } + + return true; +} + +bool ValidateQueryDeviceAttribEXT(const ValidationContext *val, + const Device *device, + EGLint attribute, + const EGLAttrib *value) +{ + ANGLE_VALIDATION_TRY(ValidateDevice(val, device)); + + if (!Display::GetClientExtensions().deviceQueryEXT) + { + val->setError(EGL_BAD_ACCESS, "EGL_EXT_device_query not supported."); + return false; + } + + // validate the attribute parameter + switch (attribute) + { + case EGL_D3D11_DEVICE_ANGLE: + case EGL_D3D9_DEVICE_ANGLE: + if (!device->getExtensions().deviceD3D || device->getType() != attribute) + { + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + break; + case EGL_EAGL_CONTEXT_ANGLE: + if (!device->getExtensions().deviceEAGL) + { + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + break; + case EGL_METAL_DEVICE_ANGLE: + if (!device->getExtensions().deviceMetal) + { + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + break; + case EGL_VULKAN_VERSION_ANGLE: + case EGL_VULKAN_INSTANCE_ANGLE: + case EGL_VULKAN_INSTANCE_EXTENSIONS_ANGLE: + case EGL_VULKAN_PHYSICAL_DEVICE_ANGLE: + case EGL_VULKAN_DEVICE_ANGLE: + case EGL_VULKAN_DEVICE_EXTENSIONS_ANGLE: + case EGL_VULKAN_FEATURES_ANGLE: + case EGL_VULKAN_QUEUE_ANGLE: + case EGL_VULKAN_QUEUE_FAMILIY_INDEX_ANGLE: + case EGL_VULKAN_GET_INSTANCE_PROC_ADDR: + if (!device->getExtensions().deviceVulkan) + { + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + break; + case EGL_CGL_CONTEXT_ANGLE: + case EGL_CGL_PIXEL_FORMAT_ANGLE: + if (!device->getExtensions().deviceCGL) + { + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + break; + default: + val->setError(EGL_BAD_ATTRIBUTE); + return false; + } + return true; +} + +bool ValidateQueryDeviceStringEXT(const ValidationContext *val, const Device *device, EGLint name) +{ + ANGLE_VALIDATION_TRY(ValidateDevice(val, device)); + return true; +} + +bool ValidateReleaseHighPowerGPUANGLE(const ValidationContext *val, + const Display *display, + const gl::Context *context) +{ + ANGLE_VALIDATION_TRY(ValidateContext(val, display, context)); + return true; +} + +bool ValidateReacquireHighPowerGPUANGLE(const ValidationContext *val, + const Display *display, + const gl::Context *context) +{ + ANGLE_VALIDATION_TRY(ValidateContext(val, display, context)); + return true; +} + +bool ValidateHandleGPUSwitchANGLE(const ValidationContext *val, const Display *display) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + return true; +} + +bool ValidateForceGPUSwitchANGLE(const ValidationContext *val, + const Display *display, + EGLint gpuIDHigh, + EGLint gpuIDLow) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + return true; +} + +bool ValidateGetCurrentDisplay(const ValidationContext *val) +{ + return true; +} + +bool ValidateGetCurrentSurface(const ValidationContext *val, EGLint readdraw) +{ + return true; +} + +bool ValidateGetDisplay(const ValidationContext *val, EGLNativeDisplayType display_id) +{ + return true; +} + +bool ValidateGetError(const ValidationContext *val) +{ + return true; +} + +bool ValidateGetProcAddress(const ValidationContext *val, const char *procname) +{ + return true; +} + +bool ValidateQueryString(const ValidationContext *val, const Display *dpyPacked, EGLint name) +{ + // The only situation where EGL_NO_DISPLAY is allowed is when querying + // EGL_EXTENSIONS or EGL_VERSION. + const bool canQueryWithoutDisplay = (name == EGL_VERSION || name == EGL_EXTENSIONS); + + if (dpyPacked != nullptr || !canQueryWithoutDisplay) + { + ANGLE_VALIDATION_TRY(ValidateDisplay(val, dpyPacked)); + } + + switch (name) + { + case EGL_CLIENT_APIS: + case EGL_EXTENSIONS: + case EGL_VENDOR: + case EGL_VERSION: + break; + default: + val->setError(EGL_BAD_PARAMETER); + return false; + } + return true; +} + +bool ValidateWaitGL(const ValidationContext *val) +{ + if (val->eglThread->getDisplay() == nullptr) + { + // EGL spec says this about eglWaitGL - + // eglWaitGL is ignored if there is no current EGL rendering context for OpenGL ES. + return true; + } + + ANGLE_VALIDATION_TRY(ValidateDisplay(val, val->eglThread->getDisplay())); + return true; +} + +bool ValidateQueryAPI(const ValidationContext *val) +{ + return true; +} + +bool ValidateReleaseThread(const ValidationContext *val) +{ + return true; +} + +bool ValidateWaitClient(const ValidationContext *val) +{ + if (val->eglThread->getDisplay() == nullptr) + { + // EGL spec says this about eglWaitClient - + // If there is no current context for the current rendering API, + // the function has no effect but still returns EGL_TRUE. + return true; + } + + ANGLE_VALIDATION_TRY(ValidateDisplay(val, val->eglThread->getDisplay())); + return true; +} + +bool ValidateGetCurrentContext(const ValidationContext *val) +{ + return true; +} + +bool ValidateCreatePlatformPixmapSurface(const ValidationContext *val, + const Display *dpyPacked, + const Config *configPacked, + const void *native_pixmap, + const AttributeMap &attrib_listPacked) +{ + EGLNativePixmapType nativePixmap = + reinterpret_cast(const_cast(native_pixmap)); + return ValidateCreatePixmapSurface(val, dpyPacked, configPacked, nativePixmap, + attrib_listPacked); +} + +bool ValidateCreatePlatformWindowSurface(const ValidationContext *val, + const Display *dpyPacked, + const Config *configPacked, + const void *native_window, + const AttributeMap &attrib_listPacked) +{ + EGLNativeWindowType nativeWindow = + reinterpret_cast(const_cast(native_window)); + return ValidateCreateWindowSurface(val, dpyPacked, configPacked, nativeWindow, + attrib_listPacked); +} + +bool ValidateLockSurfaceKHR(const ValidationContext *val, + const egl::Display *dpy, + const Surface *surface, + const AttributeMap &attributes) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, dpy)); + ANGLE_VALIDATION_TRY(ValidateSurface(val, dpy, surface)); + + if (!dpy->getExtensions().lockSurface3KHR) + { + val->setError(EGL_BAD_ACCESS); + return false; + } + + if (surface->isLocked()) + { + val->setError(EGL_BAD_ACCESS); + return false; + } + + if ((surface->getConfig()->surfaceType & EGL_LOCK_SURFACE_BIT_KHR) == false) + { + val->setError(EGL_BAD_ACCESS, "Config does not support EGL_LOCK_SURFACE_BIT"); + return false; + } + + if (surface->isCurrentOnAnyContext()) + { + val->setError(EGL_BAD_ACCESS, + "Surface cannot be current to a context for eglLockSurface()"); + return false; + } + + if (surface->hasProtectedContent()) + { + val->setError(EGL_BAD_ACCESS, "Surface cannot be protected content for eglLockSurface()"); + return false; + } + + attributes.initializeWithoutValidation(); + + for (const auto &attributeIter : attributes) + { + EGLAttrib attribute = attributeIter.first; + EGLAttrib value = attributeIter.second; + + switch (attribute) + { + case EGL_MAP_PRESERVE_PIXELS_KHR: + if (!((value == EGL_FALSE) || (value == EGL_TRUE))) + { + val->setError(EGL_BAD_ATTRIBUTE, "Invalid EGL_MAP_PRESERVE_PIXELS_KHR value"); + return false; + } + break; + case EGL_LOCK_USAGE_HINT_KHR: + if ((value & (EGL_READ_SURFACE_BIT_KHR | EGL_WRITE_SURFACE_BIT_KHR)) != value) + { + val->setError(EGL_BAD_ATTRIBUTE, "Invalid EGL_LOCK_USAGE_HINT_KHR value"); + return false; + } + break; + default: + val->setError(EGL_BAD_ATTRIBUTE, "Invalid query surface64 attribute"); + return false; + } + } + + return true; +} + +bool ValidateQuerySurface64KHR(const ValidationContext *val, + const egl::Display *dpy, + const Surface *surface, + EGLint attribute, + const EGLAttribKHR *value) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, dpy)); + ANGLE_VALIDATION_TRY(ValidateSurface(val, dpy, surface)); + + if (!dpy->getExtensions().lockSurface3KHR) + { + val->setError(EGL_BAD_ACCESS); + return false; + } + + switch (attribute) + { + case EGL_BITMAP_PITCH_KHR: + case EGL_BITMAP_ORIGIN_KHR: + case EGL_BITMAP_PIXEL_RED_OFFSET_KHR: + case EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR: + case EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR: + case EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR: + case EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR: + case EGL_BITMAP_PIXEL_SIZE_KHR: + case EGL_BITMAP_POINTER_KHR: + break; + default: + val->setError(EGL_BAD_ATTRIBUTE, "Invalid eglQuerySurface64 attribute"); + return false; + } + + if (value == nullptr) + { + val->setError(EGL_BAD_PARAMETER, "value is NULL."); + return false; + } + + if (!surface->isLocked()) + { + val->setError(EGL_BAD_ACCESS, "Surface is not locked"); + return false; + } + + return true; +} + +bool ValidateUnlockSurfaceKHR(const ValidationContext *val, + const egl::Display *dpy, + const Surface *surface) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, dpy)); + ANGLE_VALIDATION_TRY(ValidateSurface(val, dpy, surface)); + + if (!dpy->getExtensions().lockSurface3KHR) + { + val->setError(EGL_BAD_ACCESS); + return false; + } + + if (!surface->isLocked()) + { + val->setError(EGL_BAD_PARAMETER, "Surface is not locked."); + return false; + } + + return true; +} + +bool ValidateExportVkImageANGLE(const ValidationContext *val, + const Display *dpy, + const Image *image, + const void *vkImage, + const void *vkImageCreateInfo) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, dpy)); + ANGLE_VALIDATION_TRY(ValidateImage(val, dpy, image)); + + if (!dpy->getExtensions().vulkanImageANGLE) + { + val->setError(EGL_BAD_ACCESS); + return false; + } + + if (!vkImage) + { + val->setError(EGL_BAD_PARAMETER, "Output VkImage pointer is null."); + return false; + } + + if (!vkImageCreateInfo) + { + val->setError(EGL_BAD_PARAMETER, "Output VkImageCreateInfo pointer is null."); + return false; + } + + return true; +} + +bool ValidateSetDamageRegionKHR(const ValidationContext *val, + const Display *display, + const Surface *surface, + const EGLint *rects, + EGLint n_rects) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, display)); + ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface)); + + if (!(surface->getType() & EGL_WINDOW_BIT)) + { + val->setError(EGL_BAD_MATCH, "surface is not a postable surface"); + return false; + } + + if (surface != val->eglThread->getCurrentDrawSurface()) + { + val->setError(EGL_BAD_MATCH, + "surface is not the current draw surface for the calling thread"); + return false; + } + + if (surface->getSwapBehavior() != EGL_BUFFER_DESTROYED) + { + val->setError(EGL_BAD_MATCH, "surface's swap behavior is not EGL_BUFFER_DESTROYED"); + return false; + } + + if (surface->isDamageRegionSet()) + { + val->setError( + EGL_BAD_ACCESS, + "damage region has already been set on surface since the most recent frame boundary"); + return false; + } + + if (!surface->bufferAgeQueriedSinceLastSwap()) + { + val->setError(EGL_BAD_ACCESS, + "EGL_BUFFER_AGE_KHR attribute of surface has not been queried since the most " + "recent frame boundary"); + return false; + } + + return true; +} + +bool ValidateQueryDmaBufFormatsEXT(ValidationContext const *val, + Display const *dpy, + EGLint max_formats, + const EGLint *formats, + const EGLint *num_formats) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, dpy)); + + if (!dpy->getExtensions().imageDmaBufImportModifiersEXT) + { + val->setError(EGL_BAD_ACCESS, "EGL_EXT_dma_buf_import_modfier not supported"); + return false; + } + + if (max_formats < 0) + { + val->setError(EGL_BAD_PARAMETER, "max_formats should not be negative"); + return false; + } + + if (max_formats > 0 && formats == nullptr) + { + val->setError(EGL_BAD_PARAMETER, "if max_formats is positive, formats should not be NULL"); + return false; + } + + return true; +} + +bool ValidateQueryDmaBufModifiersEXT(ValidationContext const *val, + Display const *dpy, + EGLint format, + EGLint max_modifiers, + const EGLuint64KHR *modifiers, + const EGLBoolean *external_only, + const EGLint *num_modifiers) +{ + ANGLE_VALIDATION_TRY(ValidateDisplay(val, dpy)); + + if (!dpy->getExtensions().imageDmaBufImportModifiersEXT) + { + val->setError(EGL_BAD_ACCESS, "EGL_EXT_dma_buf_import_modfier not supported"); + return false; + } + + if (max_modifiers < 0) + { + val->setError(EGL_BAD_PARAMETER, "max_modifiers should not be negative"); + return false; + } + + if (max_modifiers > 0 && modifiers == nullptr) + { + val->setError(EGL_BAD_PARAMETER, + "if max_modifiers is positive, modifiers should not be NULL"); + return false; + } + + if (!dpy->supportsDmaBufFormat(format)) + { + val->setError(EGL_BAD_PARAMETER, + "format should be one of the formats advertised by QueryDmaBufFormatsEXT"); + return false; + } + return true; +} + +} // namespace egl diff --git a/gfx/angle/checkout/src/libANGLE/validationEGL.h b/gfx/angle/checkout/src/libANGLE/validationEGL.h new file mode 100644 index 0000000000..8f04de288f --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationEGL.h @@ -0,0 +1,201 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// validationEGL.h: Validation functions for generic EGL entry point parameters + +#ifndef LIBANGLE_VALIDATIONEGL_H_ +#define LIBANGLE_VALIDATIONEGL_H_ + +#include "common/PackedEnums.h" +#include "libANGLE/Error.h" +#include "libANGLE/Thread.h" + +#include +#include + +namespace gl +{ +class Context; +} + +namespace egl +{ +constexpr EGLint kEglMajorVersion = 1; +constexpr EGLint kEglMinorVersion = 5; + +class AttributeMap; +struct ClientExtensions; +struct Config; +class Device; +class Display; +class Image; +class Stream; +class Surface; +class Sync; +class Thread; +class LabeledObject; + +struct ValidationContext +{ + ValidationContext(Thread *threadIn, const char *entryPointIn, const LabeledObject *objectIn) + : eglThread(threadIn), entryPoint(entryPointIn), labeledObject(objectIn) + {} + + // We should remove the message-less overload once we have messages for all EGL errors. + void setError(EGLint error) const; + ANGLE_FORMAT_PRINTF(3, 4) + void setError(EGLint error, const char *message...) const; + + Thread *eglThread; + const char *entryPoint; + const LabeledObject *labeledObject; +}; + +// Object validation +bool ValidateDisplay(const ValidationContext *val, const Display *display); +bool ValidateSurface(const ValidationContext *val, const Display *display, const Surface *surface); +bool ValidateConfig(const ValidationContext *val, const Display *display, const Config *config); +bool ValidateContext(const ValidationContext *val, + const Display *display, + const gl::Context *context); +bool ValidateImage(const ValidationContext *val, const Display *display, const Image *image); +bool ValidateDevice(const ValidationContext *val, const Device *device); +bool ValidateSync(const ValidationContext *val, const Display *display, const Sync *sync); + +// Return the requested object only if it is valid (otherwise nullptr) +const Thread *GetThreadIfValid(const Thread *thread); +const Display *GetDisplayIfValid(const Display *display); +const Surface *GetSurfaceIfValid(const Display *display, const Surface *surface); +const Image *GetImageIfValid(const Display *display, const Image *image); +const Stream *GetStreamIfValid(const Display *display, const Stream *stream); +const gl::Context *GetContextIfValid(const Display *display, const gl::Context *context); +const Device *GetDeviceIfValid(const Device *device); +const Sync *GetSyncIfValid(const Display *display, const Sync *sync); +LabeledObject *GetLabeledObjectIfValid(Thread *thread, + const Display *display, + ObjectType objectType, + EGLObjectKHR object); + +// A template struct for determining the default value to return for each entry point. +template +struct DefaultReturnValue +{ + static constexpr ReturnType kValue = static_cast(0); +}; + +template +ReturnType GetDefaultReturnValue(Thread *thread); + +template <> +ANGLE_INLINE EGLint +GetDefaultReturnValue(Thread *thread) +{ + return thread->getError(); +} + +template +ANGLE_INLINE ReturnType GetDefaultReturnValue(Thread *thread) +{ + return DefaultReturnValue::kValue; +} + +// First case: handling packed enums. +template +typename std::enable_if::value, PackedT>::type PackParam(FromT from) +{ + return FromEGLenum(from); +} + +// This and the next 2 template specializations handle distinguishing between EGLint, EGLAttrib +// and other. This is needed because on some architectures EGLint and EGLAttrib are not the same +// base type. Previously the code conditionally compiled 2 specializations on 64 bit but it turns +// out on WatchOS the assumption about 32/64 bit and if EGLint and ELGAttrib are the same or +// different did not hold. +template ::value>::type * = nullptr, + typename std::enable_if::value>::type * = nullptr> +typename std::remove_reference::type PackParam(FromT attribs) +{ + return AttributeMap::CreateFromIntArray(attribs); +} + +template ::value>::type * = nullptr, + typename std::enable_if::value>::type * = nullptr, + typename std::enable_if::value>::type * = nullptr> +typename std::remove_reference::type PackParam(FromT attribs) +{ + return AttributeMap::CreateFromAttribArray(attribs); +} + +template ::value>::type * = nullptr, + typename std::enable_if::value>::type * = nullptr, + typename std::enable_if::value>::type * = nullptr> +typename std::remove_reference::type PackParam(FromT attribs) +{ + return static_cast(attribs); +} + +} // namespace egl + +#define ANGLE_EGL_VALIDATE(THREAD, EP, OBJ, RETURN_TYPE, ...) \ + do \ + { \ + const char *epname = "egl" #EP; \ + ValidationContext vctx(THREAD, epname, OBJ); \ + auto ANGLE_LOCAL_VAR = (Validate##EP(&vctx, ##__VA_ARGS__)); \ + if (!ANGLE_LOCAL_VAR) \ + { \ + return GetDefaultReturnValue(THREAD); \ + } \ + } while (0) + +#define ANGLE_EGL_VALIDATE_VOID(THREAD, EP, OBJ, ...) \ + do \ + { \ + const char *epname = "egl" #EP; \ + ValidationContext vctx(THREAD, epname, OBJ); \ + auto ANGLE_LOCAL_VAR = (Validate##EP(&vctx, ##__VA_ARGS__)); \ + if (!ANGLE_LOCAL_VAR) \ + { \ + return; \ + } \ + } while (0) + +#define ANGLE_EGL_TRY(THREAD, EXPR, FUNCNAME, LABELOBJECT) \ + do \ + { \ + auto ANGLE_LOCAL_VAR = (EXPR); \ + if (ANGLE_LOCAL_VAR.isError()) \ + return THREAD->setError(ANGLE_LOCAL_VAR, FUNCNAME, LABELOBJECT); \ + } while (0) + +#define ANGLE_EGL_TRY_RETURN(THREAD, EXPR, FUNCNAME, LABELOBJECT, RETVAL) \ + do \ + { \ + auto ANGLE_LOCAL_VAR = (EXPR); \ + if (ANGLE_LOCAL_VAR.isError()) \ + { \ + THREAD->setError(ANGLE_LOCAL_VAR, FUNCNAME, LABELOBJECT); \ + return RETVAL; \ + } \ + } while (0) + +#define ANGLE_EGLBOOLEAN_TRY(EXPR) \ + do \ + { \ + EGLBoolean ANGLE_LOCAL_VAR = (EXPR); \ + if (ANGLE_LOCAL_VAR != EGL_TRUE) \ + { \ + return ANGLE_LOCAL_VAR; \ + } \ + } while (0) + +#endif // LIBANGLE_VALIDATIONEGL_H_ diff --git a/gfx/angle/checkout/src/libANGLE/validationEGL_autogen.h b/gfx/angle/checkout/src/libANGLE/validationEGL_autogen.h new file mode 100644 index 0000000000..57bd334227 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationEGL_autogen.h @@ -0,0 +1,510 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from egl.xml and egl_angle_ext.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// validationEGL_autogen.h: +// Validation functions for the EGL entry points. + +#ifndef LIBANGLE_VALIDATION_EGL_AUTOGEN_H_ +#define LIBANGLE_VALIDATION_EGL_AUTOGEN_H_ + +#include "libANGLE/validationEGL.h" + +namespace egl +{ + +// EGL 1.0 +bool ValidateChooseConfig(const ValidationContext *val, + const egl::Display *dpyPacked, + const AttributeMap &attrib_listPacked, + const EGLConfig *configs, + EGLint config_size, + const EGLint *num_config); +bool ValidateCopyBuffers(const ValidationContext *val, + const egl::Display *dpyPacked, + const Surface *surfacePacked, + EGLNativePixmapType target); +bool ValidateCreateContext(const ValidationContext *val, + const egl::Display *dpyPacked, + const Config *configPacked, + const gl::Context *share_contextPacked, + const AttributeMap &attrib_listPacked); +bool ValidateCreatePbufferSurface(const ValidationContext *val, + const egl::Display *dpyPacked, + const Config *configPacked, + const AttributeMap &attrib_listPacked); +bool ValidateCreatePixmapSurface(const ValidationContext *val, + const egl::Display *dpyPacked, + const Config *configPacked, + EGLNativePixmapType pixmap, + const AttributeMap &attrib_listPacked); +bool ValidateCreateWindowSurface(const ValidationContext *val, + const egl::Display *dpyPacked, + const Config *configPacked, + EGLNativeWindowType win, + const AttributeMap &attrib_listPacked); +bool ValidateDestroyContext(const ValidationContext *val, + const egl::Display *dpyPacked, + const gl::Context *ctxPacked); +bool ValidateDestroySurface(const ValidationContext *val, + const egl::Display *dpyPacked, + const Surface *surfacePacked); +bool ValidateGetConfigAttrib(const ValidationContext *val, + const egl::Display *dpyPacked, + const Config *configPacked, + EGLint attribute, + const EGLint *value); +bool ValidateGetConfigs(const ValidationContext *val, + const egl::Display *dpyPacked, + const EGLConfig *configs, + EGLint config_size, + const EGLint *num_config); +bool ValidateGetCurrentDisplay(const ValidationContext *val); +bool ValidateGetCurrentSurface(const ValidationContext *val, EGLint readdraw); +bool ValidateGetDisplay(const ValidationContext *val, EGLNativeDisplayType display_id); +bool ValidateGetError(const ValidationContext *val); +bool ValidateGetProcAddress(const ValidationContext *val, const char *procname); +bool ValidateInitialize(const ValidationContext *val, + const egl::Display *dpyPacked, + const EGLint *major, + const EGLint *minor); +bool ValidateMakeCurrent(const ValidationContext *val, + const egl::Display *dpyPacked, + const Surface *drawPacked, + const Surface *readPacked, + const gl::Context *ctxPacked); +bool ValidateQueryContext(const ValidationContext *val, + const egl::Display *dpyPacked, + const gl::Context *ctxPacked, + EGLint attribute, + const EGLint *value); +bool ValidateQueryString(const ValidationContext *val, const egl::Display *dpyPacked, EGLint name); +bool ValidateQuerySurface(const ValidationContext *val, + const egl::Display *dpyPacked, + const Surface *surfacePacked, + EGLint attribute, + const EGLint *value); +bool ValidateSwapBuffers(const ValidationContext *val, + const egl::Display *dpyPacked, + const Surface *surfacePacked); +bool ValidateTerminate(const ValidationContext *val, const egl::Display *dpyPacked); +bool ValidateWaitGL(const ValidationContext *val); +bool ValidateWaitNative(const ValidationContext *val, EGLint engine); + +// EGL 1.1 +bool ValidateBindTexImage(const ValidationContext *val, + const egl::Display *dpyPacked, + const Surface *surfacePacked, + EGLint buffer); +bool ValidateReleaseTexImage(const ValidationContext *val, + const egl::Display *dpyPacked, + const Surface *surfacePacked, + EGLint buffer); +bool ValidateSurfaceAttrib(const ValidationContext *val, + const egl::Display *dpyPacked, + const Surface *surfacePacked, + EGLint attribute, + EGLint value); +bool ValidateSwapInterval(const ValidationContext *val, + const egl::Display *dpyPacked, + EGLint interval); + +// EGL 1.2 +bool ValidateBindAPI(const ValidationContext *val, EGLenum api); +bool ValidateCreatePbufferFromClientBuffer(const ValidationContext *val, + const egl::Display *dpyPacked, + EGLenum buftype, + EGLClientBuffer buffer, + const Config *configPacked, + const AttributeMap &attrib_listPacked); +bool ValidateQueryAPI(const ValidationContext *val); +bool ValidateReleaseThread(const ValidationContext *val); +bool ValidateWaitClient(const ValidationContext *val); + +// EGL 1.4 +bool ValidateGetCurrentContext(const ValidationContext *val); + +// EGL 1.5 +bool ValidateClientWaitSync(const ValidationContext *val, + const egl::Display *dpyPacked, + const Sync *syncPacked, + EGLint flags, + EGLTime timeout); +bool ValidateCreateImage(const ValidationContext *val, + const egl::Display *dpyPacked, + const gl::Context *ctxPacked, + EGLenum target, + EGLClientBuffer buffer, + const AttributeMap &attrib_listPacked); +bool ValidateCreatePlatformPixmapSurface(const ValidationContext *val, + const egl::Display *dpyPacked, + const Config *configPacked, + const void *native_pixmap, + const AttributeMap &attrib_listPacked); +bool ValidateCreatePlatformWindowSurface(const ValidationContext *val, + const egl::Display *dpyPacked, + const Config *configPacked, + const void *native_window, + const AttributeMap &attrib_listPacked); +bool ValidateCreateSync(const ValidationContext *val, + const egl::Display *dpyPacked, + EGLenum type, + const AttributeMap &attrib_listPacked); +bool ValidateDestroyImage(const ValidationContext *val, + const egl::Display *dpyPacked, + const Image *imagePacked); +bool ValidateDestroySync(const ValidationContext *val, + const egl::Display *dpyPacked, + const Sync *syncPacked); +bool ValidateGetPlatformDisplay(const ValidationContext *val, + EGLenum platform, + const void *native_display, + const AttributeMap &attrib_listPacked); +bool ValidateGetSyncAttrib(const ValidationContext *val, + const egl::Display *dpyPacked, + const Sync *syncPacked, + EGLint attribute, + const EGLAttrib *value); +bool ValidateWaitSync(const ValidationContext *val, + const egl::Display *dpyPacked, + const Sync *syncPacked, + EGLint flags); + +// EGL_ANDROID_blob_cache +bool ValidateSetBlobCacheFuncsANDROID(const ValidationContext *val, + const egl::Display *dpyPacked, + EGLSetBlobFuncANDROID set, + EGLGetBlobFuncANDROID get); + +// EGL_ANDROID_create_native_client_buffer +bool ValidateCreateNativeClientBufferANDROID(const ValidationContext *val, + const AttributeMap &attrib_listPacked); + +// EGL_ANDROID_get_frame_timestamps +bool ValidateGetCompositorTimingSupportedANDROID(const ValidationContext *val, + const egl::Display *dpyPacked, + const Surface *surfacePacked, + CompositorTiming namePacked); +bool ValidateGetCompositorTimingANDROID(const ValidationContext *val, + const egl::Display *dpyPacked, + const Surface *surfacePacked, + EGLint numTimestamps, + const EGLint *names, + const EGLnsecsANDROID *values); +bool ValidateGetNextFrameIdANDROID(const ValidationContext *val, + const egl::Display *dpyPacked, + const Surface *surfacePacked, + const EGLuint64KHR *frameId); +bool ValidateGetFrameTimestampSupportedANDROID(const ValidationContext *val, + const egl::Display *dpyPacked, + const Surface *surfacePacked, + Timestamp timestampPacked); +bool ValidateGetFrameTimestampsANDROID(const ValidationContext *val, + const egl::Display *dpyPacked, + const Surface *surfacePacked, + EGLuint64KHR frameId, + EGLint numTimestamps, + const EGLint *timestamps, + const EGLnsecsANDROID *values); + +// EGL_ANDROID_get_native_client_buffer +bool ValidateGetNativeClientBufferANDROID(const ValidationContext *val, + const struct AHardwareBuffer *buffer); + +// EGL_ANDROID_native_fence_sync +bool ValidateDupNativeFenceFDANDROID(const ValidationContext *val, + const egl::Display *dpyPacked, + const Sync *syncPacked); + +// EGL_ANDROID_presentation_time +bool ValidatePresentationTimeANDROID(const ValidationContext *val, + const egl::Display *dpyPacked, + const Surface *surfacePacked, + EGLnsecsANDROID time); + +// EGL_ANGLE_device_creation +bool ValidateCreateDeviceANGLE(const ValidationContext *val, + EGLint device_type, + const void *native_device, + const EGLAttrib *attrib_list); +bool ValidateReleaseDeviceANGLE(const ValidationContext *val, const Device *devicePacked); + +// EGL_ANGLE_feature_control +bool ValidateQueryStringiANGLE(const ValidationContext *val, + const egl::Display *dpyPacked, + EGLint name, + EGLint index); +bool ValidateQueryDisplayAttribANGLE(const ValidationContext *val, + const egl::Display *dpyPacked, + EGLint attribute, + const EGLAttrib *value); + +// EGL_ANGLE_metal_shared_event_sync +bool ValidateCopyMetalSharedEventANGLE(const ValidationContext *val, + const egl::Display *dpyPacked, + const Sync *syncPacked); + +// EGL_ANGLE_power_preference +bool ValidateReleaseHighPowerGPUANGLE(const ValidationContext *val, + const egl::Display *dpyPacked, + const gl::Context *ctxPacked); +bool ValidateReacquireHighPowerGPUANGLE(const ValidationContext *val, + const egl::Display *dpyPacked, + const gl::Context *ctxPacked); +bool ValidateHandleGPUSwitchANGLE(const ValidationContext *val, const egl::Display *dpyPacked); +bool ValidateForceGPUSwitchANGLE(const ValidationContext *val, + const egl::Display *dpyPacked, + EGLint gpuIDHigh, + EGLint gpuIDLow); + +// EGL_ANGLE_prepare_swap_buffers +bool ValidatePrepareSwapBuffersANGLE(const ValidationContext *val, + const egl::Display *dpyPacked, + const Surface *surfacePacked); + +// EGL_ANGLE_program_cache_control +bool ValidateProgramCacheGetAttribANGLE(const ValidationContext *val, + const egl::Display *dpyPacked, + EGLenum attrib); +bool ValidateProgramCacheQueryANGLE(const ValidationContext *val, + const egl::Display *dpyPacked, + EGLint index, + const void *key, + const EGLint *keysize, + const void *binary, + const EGLint *binarysize); +bool ValidateProgramCachePopulateANGLE(const ValidationContext *val, + const egl::Display *dpyPacked, + const void *key, + EGLint keysize, + const void *binary, + EGLint binarysize); +bool ValidateProgramCacheResizeANGLE(const ValidationContext *val, + const egl::Display *dpyPacked, + EGLint limit, + EGLint mode); + +// EGL_ANGLE_query_surface_pointer +bool ValidateQuerySurfacePointerANGLE(const ValidationContext *val, + const egl::Display *dpyPacked, + const Surface *surfacePacked, + EGLint attribute, + void *const *value); + +// EGL_ANGLE_stream_producer_d3d_texture +bool ValidateCreateStreamProducerD3DTextureANGLE(const ValidationContext *val, + const egl::Display *dpyPacked, + const Stream *streamPacked, + const AttributeMap &attrib_listPacked); +bool ValidateStreamPostD3DTextureANGLE(const ValidationContext *val, + const egl::Display *dpyPacked, + const Stream *streamPacked, + const void *texture, + const AttributeMap &attrib_listPacked); + +// EGL_ANGLE_swap_with_frame_token +bool ValidateSwapBuffersWithFrameTokenANGLE(const ValidationContext *val, + const egl::Display *dpyPacked, + const Surface *surfacePacked, + EGLFrameTokenANGLE frametoken); + +// EGL_ANGLE_sync_control_rate +bool ValidateGetMscRateANGLE(const ValidationContext *val, + const egl::Display *dpyPacked, + const Surface *surfacePacked, + const EGLint *numerator, + const EGLint *denominator); + +// EGL_ANGLE_vulkan_image +bool ValidateExportVkImageANGLE(const ValidationContext *val, + const egl::Display *dpyPacked, + const Image *imagePacked, + const void *vk_image, + const void *vk_image_create_info); + +// EGL_CHROMIUM_sync_control +bool ValidateGetSyncValuesCHROMIUM(const ValidationContext *val, + const egl::Display *dpyPacked, + const Surface *surfacePacked, + const EGLuint64KHR *ust, + const EGLuint64KHR *msc, + const EGLuint64KHR *sbc); + +// EGL_EXT_device_query +bool ValidateQueryDeviceAttribEXT(const ValidationContext *val, + const Device *devicePacked, + EGLint attribute, + const EGLAttrib *value); +bool ValidateQueryDeviceStringEXT(const ValidationContext *val, + const Device *devicePacked, + EGLint name); +bool ValidateQueryDisplayAttribEXT(const ValidationContext *val, + const egl::Display *dpyPacked, + EGLint attribute, + const EGLAttrib *value); + +// EGL_EXT_image_dma_buf_import_modifiers +bool ValidateQueryDmaBufFormatsEXT(const ValidationContext *val, + const egl::Display *dpyPacked, + EGLint max_formats, + const EGLint *formats, + const EGLint *num_formats); +bool ValidateQueryDmaBufModifiersEXT(const ValidationContext *val, + const egl::Display *dpyPacked, + EGLint format, + EGLint max_modifiers, + const EGLuint64KHR *modifiers, + const EGLBoolean *external_only, + const EGLint *num_modifiers); + +// EGL_EXT_platform_base +bool ValidateCreatePlatformPixmapSurfaceEXT(const ValidationContext *val, + const egl::Display *dpyPacked, + const Config *configPacked, + const void *native_pixmap, + const AttributeMap &attrib_listPacked); +bool ValidateCreatePlatformWindowSurfaceEXT(const ValidationContext *val, + const egl::Display *dpyPacked, + const Config *configPacked, + const void *native_window, + const AttributeMap &attrib_listPacked); +bool ValidateGetPlatformDisplayEXT(const ValidationContext *val, + EGLenum platform, + const void *native_display, + const AttributeMap &attrib_listPacked); + +// EGL_KHR_debug +bool ValidateDebugMessageControlKHR(const ValidationContext *val, + EGLDEBUGPROCKHR callback, + const AttributeMap &attrib_listPacked); +bool ValidateLabelObjectKHR(const ValidationContext *val, + const egl::Display *displayPacked, + ObjectType objectTypePacked, + EGLObjectKHR object, + EGLLabelKHR label); +bool ValidateQueryDebugKHR(const ValidationContext *val, EGLint attribute, const EGLAttrib *value); + +// EGL_KHR_fence_sync +bool ValidateClientWaitSyncKHR(const ValidationContext *val, + const egl::Display *dpyPacked, + const Sync *syncPacked, + EGLint flags, + EGLTimeKHR timeout); +bool ValidateCreateSyncKHR(const ValidationContext *val, + const egl::Display *dpyPacked, + EGLenum type, + const AttributeMap &attrib_listPacked); +bool ValidateDestroySyncKHR(const ValidationContext *val, + const egl::Display *dpyPacked, + const Sync *syncPacked); +bool ValidateGetSyncAttribKHR(const ValidationContext *val, + const egl::Display *dpyPacked, + const Sync *syncPacked, + EGLint attribute, + const EGLint *value); + +// EGL_KHR_image +bool ValidateCreateImageKHR(const ValidationContext *val, + const egl::Display *dpyPacked, + const gl::Context *ctxPacked, + EGLenum target, + EGLClientBuffer buffer, + const AttributeMap &attrib_listPacked); +bool ValidateDestroyImageKHR(const ValidationContext *val, + const egl::Display *dpyPacked, + const Image *imagePacked); + +// EGL_KHR_lock_surface3 +bool ValidateLockSurfaceKHR(const ValidationContext *val, + const egl::Display *dpyPacked, + const Surface *surfacePacked, + const AttributeMap &attrib_listPacked); +bool ValidateQuerySurface64KHR(const ValidationContext *val, + const egl::Display *dpyPacked, + const Surface *surfacePacked, + EGLint attribute, + const EGLAttribKHR *value); +bool ValidateUnlockSurfaceKHR(const ValidationContext *val, + const egl::Display *dpyPacked, + const Surface *surfacePacked); + +// EGL_KHR_partial_update +bool ValidateSetDamageRegionKHR(const ValidationContext *val, + const egl::Display *dpyPacked, + const Surface *surfacePacked, + const EGLint *rects, + EGLint n_rects); + +// EGL_KHR_reusable_sync +bool ValidateSignalSyncKHR(const ValidationContext *val, + const egl::Display *dpyPacked, + const Sync *syncPacked, + EGLenum mode); + +// EGL_KHR_stream +bool ValidateCreateStreamKHR(const ValidationContext *val, + const egl::Display *dpyPacked, + const AttributeMap &attrib_listPacked); +bool ValidateDestroyStreamKHR(const ValidationContext *val, + const egl::Display *dpyPacked, + const Stream *streamPacked); +bool ValidateQueryStreamKHR(const ValidationContext *val, + const egl::Display *dpyPacked, + const Stream *streamPacked, + EGLenum attribute, + const EGLint *value); +bool ValidateQueryStreamu64KHR(const ValidationContext *val, + const egl::Display *dpyPacked, + const Stream *streamPacked, + EGLenum attribute, + const EGLuint64KHR *value); +bool ValidateStreamAttribKHR(const ValidationContext *val, + const egl::Display *dpyPacked, + const Stream *streamPacked, + EGLenum attribute, + EGLint value); + +// EGL_KHR_stream_consumer_gltexture +bool ValidateStreamConsumerAcquireKHR(const ValidationContext *val, + const egl::Display *dpyPacked, + const Stream *streamPacked); +bool ValidateStreamConsumerGLTextureExternalKHR(const ValidationContext *val, + const egl::Display *dpyPacked, + const Stream *streamPacked); +bool ValidateStreamConsumerReleaseKHR(const ValidationContext *val, + const egl::Display *dpyPacked, + const Stream *streamPacked); + +// EGL_KHR_swap_buffers_with_damage +bool ValidateSwapBuffersWithDamageKHR(const ValidationContext *val, + const egl::Display *dpyPacked, + const Surface *surfacePacked, + const EGLint *rects, + EGLint n_rects); + +// EGL_KHR_wait_sync +bool ValidateWaitSyncKHR(const ValidationContext *val, + const egl::Display *dpyPacked, + const Sync *syncPacked, + EGLint flags); + +// EGL_NV_post_sub_buffer +bool ValidatePostSubBufferNV(const ValidationContext *val, + const egl::Display *dpyPacked, + const Surface *surfacePacked, + EGLint x, + EGLint y, + EGLint width, + EGLint height); + +// EGL_NV_stream_consumer_gltexture_yuv +bool ValidateStreamConsumerGLTextureExternalAttribsNV(const ValidationContext *val, + const egl::Display *dpyPacked, + const Stream *streamPacked, + const AttributeMap &attrib_listPacked); +} // namespace egl + +#endif // LIBANGLE_VALIDATION_EGL_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/validationES.cpp b/gfx/angle/checkout/src/libANGLE/validationES.cpp new file mode 100644 index 0000000000..ddc586b1ad --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationES.cpp @@ -0,0 +1,8666 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// validationES.h: Validation functions for generic OpenGL ES entry point parameters + +#include "libANGLE/validationES.h" + +#include "libANGLE/Context.h" +#include "libANGLE/Display.h" +#include "libANGLE/ErrorStrings.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/Image.h" +#include "libANGLE/Program.h" +#include "libANGLE/Query.h" +#include "libANGLE/Texture.h" +#include "libANGLE/TransformFeedback.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/queryconversions.h" +#include "libANGLE/queryutils.h" +#include "libANGLE/validationES2.h" +#include "libANGLE/validationES3.h" + +#include "common/mathutil.h" +#include "common/utilities.h" + +using namespace angle; + +namespace gl +{ +using namespace err; + +namespace +{ +bool CompressedTextureFormatRequiresExactSize(GLenum internalFormat) +{ + // List of compressed format that require that the texture size is smaller than or a multiple of + // the compressed block size. + switch (internalFormat) + { + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE: + case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE: + case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE: + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE: + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE: + case GL_COMPRESSED_RGBA8_LOSSY_DECODE_ETC2_EAC_ANGLE: + case GL_COMPRESSED_SRGB8_ALPHA8_LOSSY_DECODE_ETC2_EAC_ANGLE: + case GL_COMPRESSED_RED_RGTC1_EXT: + case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT: + case GL_COMPRESSED_RED_GREEN_RGTC2_EXT: + case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT: + case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT: + case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT: + case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT: + case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT: + return true; + + default: + return false; + } +} +bool CompressedSubTextureFormatRequiresExactSize(GLenum internalFormat) +{ + // Compressed sub textures have additional formats that requires exact size. + // ES 3.1, Section 8.7, Page 171 + return CompressedTextureFormatRequiresExactSize(internalFormat) || + IsETC2EACFormat(internalFormat) || IsASTC2DFormat(internalFormat); +} + +bool DifferenceCanOverflow(GLint a, GLint b) +{ + CheckedNumeric checkedA(a); + checkedA -= b; + // Use negation to make sure that the difference can't overflow regardless of the order. + checkedA = -checkedA; + return !checkedA.IsValid(); +} + +bool ValidReadPixelsTypeEnum(const Context *context, GLenum type) +{ + switch (type) + { + // Types referenced in Table 3.4 of the ES 2.0.25 spec + case GL_UNSIGNED_BYTE: + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_5_6_5: + return context->getClientVersion() >= ES_2_0; + + // Types referenced in Table 3.2 of the ES 3.0.5 spec (Except depth stencil) + case GL_BYTE: + case GL_INT: + case GL_SHORT: + case GL_UNSIGNED_INT: + case GL_UNSIGNED_INT_10F_11F_11F_REV: + case GL_UNSIGNED_INT_2_10_10_10_REV: + case GL_UNSIGNED_INT_5_9_9_9_REV: + case GL_UNSIGNED_SHORT: + case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: + case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: + return context->getClientVersion() >= ES_3_0; + + case GL_FLOAT: + return context->getClientVersion() >= ES_3_0 || + context->getExtensions().textureFloatOES || + context->getExtensions().colorBufferHalfFloatEXT; + + case GL_HALF_FLOAT: + return context->getClientVersion() >= ES_3_0 || + context->getExtensions().textureHalfFloatOES; + + case GL_HALF_FLOAT_OES: + return context->getExtensions().colorBufferHalfFloatEXT; + + default: + return false; + } +} + +bool ValidReadPixelsFormatEnum(const Context *context, GLenum format) +{ + switch (format) + { + // Formats referenced in Table 3.4 of the ES 2.0.25 spec (Except luminance) + case GL_RGBA: + case GL_RGB: + case GL_ALPHA: + return context->getClientVersion() >= ES_2_0; + + // Formats referenced in Table 3.2 of the ES 3.0.5 spec + case GL_RG: + case GL_RED: + case GL_RGBA_INTEGER: + case GL_RGB_INTEGER: + case GL_RG_INTEGER: + case GL_RED_INTEGER: + return context->getClientVersion() >= ES_3_0; + + case GL_SRGB_ALPHA_EXT: + case GL_SRGB_EXT: + return context->getExtensions().sRGBEXT; + + case GL_BGRA_EXT: + return context->getExtensions().readFormatBgraEXT; + + case GL_RGBX8_ANGLE: + return context->getExtensions().rgbxInternalFormatANGLE; + + default: + return false; + } +} + +bool ValidReadPixelsUnsignedNormalizedDepthType(const Context *context, + const gl::InternalFormat *info, + GLenum type) +{ + bool supportsReadDepthNV = context->getExtensions().readDepthNV && (info->depthBits > 0); + switch (type) + { + case GL_UNSIGNED_SHORT: + case GL_UNSIGNED_INT: + case GL_UNSIGNED_INT_24_8: + return supportsReadDepthNV; + default: + return false; + } +} + +bool ValidReadPixelsFloatDepthType(const Context *context, + const gl::InternalFormat *info, + GLenum type) +{ + return context->getExtensions().readDepthNV && (type == GL_FLOAT) && + context->getExtensions().depthBufferFloat2NV; +} + +bool ValidReadPixelsFormatType(const Context *context, + const gl::InternalFormat *info, + GLenum format, + GLenum type) +{ + switch (info->componentType) + { + case GL_UNSIGNED_NORMALIZED: + // TODO(geofflang): Don't accept BGRA here. Some chrome internals appear to try to use + // ReadPixels with BGRA even if the extension is not present + switch (format) + { + case GL_RGBA: + return ((type == GL_UNSIGNED_BYTE) && info->pixelBytes >= 1) || + (context->getExtensions().textureNorm16EXT && + (type == GL_UNSIGNED_SHORT) && info->pixelBytes >= 2); + case GL_BGRA_EXT: + return context->getExtensions().readFormatBgraEXT && (type == GL_UNSIGNED_BYTE); + case GL_STENCIL_INDEX_OES: + return context->getExtensions().readStencilNV && (type == GL_UNSIGNED_BYTE); + case GL_DEPTH_COMPONENT: + return ValidReadPixelsUnsignedNormalizedDepthType(context, info, type); + case GL_DEPTH_STENCIL_OES: + return context->getExtensions().readDepthStencilNV && + (type == GL_UNSIGNED_INT_24_8_OES) && info->stencilBits > 0; + case GL_RGBX8_ANGLE: + return context->getExtensions().rgbxInternalFormatANGLE && + (type == GL_UNSIGNED_BYTE); + default: + return false; + } + case GL_SIGNED_NORMALIZED: + return (format == GL_RGBA && type == GL_BYTE && info->pixelBytes >= 1) || + (context->getExtensions().textureNorm16EXT && format == GL_RGBA && + type == GL_UNSIGNED_SHORT && info->pixelBytes >= 2); + + case GL_INT: + return (format == GL_RGBA_INTEGER && type == GL_INT); + + case GL_UNSIGNED_INT: + return (format == GL_RGBA_INTEGER && type == GL_UNSIGNED_INT); + + case GL_FLOAT: + switch (format) + { + case GL_RGBA: + return (type == GL_FLOAT); + case GL_DEPTH_COMPONENT: + return ValidReadPixelsFloatDepthType(context, info, type); + case GL_DEPTH_STENCIL_OES: + return context->getExtensions().readDepthStencilNV && + type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV && info->stencilBits > 0; + default: + return false; + } + default: + UNREACHABLE(); + return false; + } +} + +template +bool ValidateTextureWrapModeValue(const Context *context, + angle::EntryPoint entryPoint, + const ParamType *params, + bool restrictedWrapModes) +{ + switch (ConvertToGLenum(params[0])) + { + case GL_CLAMP_TO_EDGE: + break; + + case GL_CLAMP_TO_BORDER: + if (!context->getExtensions().textureBorderClampAny() && + context->getClientVersion() < ES_3_2) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled); + return false; + } + break; + + case GL_REPEAT: + case GL_MIRRORED_REPEAT: + if (restrictedWrapModes) + { + // OES_EGL_image_external and ANGLE_texture_rectangle specifies this error. + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidWrapModeTexture); + return false; + } + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureWrap); + return false; + } + + return true; +} + +template +bool ValidateTextureMinFilterValue(const Context *context, + angle::EntryPoint entryPoint, + const ParamType *params, + bool restrictedMinFilter) +{ + switch (ConvertToGLenum(params[0])) + { + case GL_NEAREST: + case GL_LINEAR: + break; + + case GL_NEAREST_MIPMAP_NEAREST: + case GL_LINEAR_MIPMAP_NEAREST: + case GL_NEAREST_MIPMAP_LINEAR: + case GL_LINEAR_MIPMAP_LINEAR: + if (restrictedMinFilter) + { + // OES_EGL_image_external specifies this error. + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFilterTexture); + return false; + } + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureFilterParam); + return false; + } + + return true; +} + +template +bool ValidateTextureMagFilterValue(const Context *context, + angle::EntryPoint entryPoint, + const ParamType *params) +{ + switch (ConvertToGLenum(params[0])) + { + case GL_NEAREST: + case GL_LINEAR: + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureFilterParam); + return false; + } + + return true; +} + +template +bool ValidateTextureCompareModeValue(const Context *context, + angle::EntryPoint entryPoint, + const ParamType *params) +{ + // Acceptable mode parameters from GLES 3.0.2 spec, table 3.17 + switch (ConvertToGLenum(params[0])) + { + case GL_NONE: + case GL_COMPARE_REF_TO_TEXTURE: + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kUnknownParameter); + return false; + } + + return true; +} + +template +bool ValidateTextureCompareFuncValue(const Context *context, + angle::EntryPoint entryPoint, + const ParamType *params) +{ + // Acceptable function parameters from GLES 3.0.2 spec, table 3.17 + switch (ConvertToGLenum(params[0])) + { + case GL_LEQUAL: + case GL_GEQUAL: + case GL_LESS: + case GL_GREATER: + case GL_EQUAL: + case GL_NOTEQUAL: + case GL_ALWAYS: + case GL_NEVER: + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kUnknownParameter); + return false; + } + + return true; +} + +template +bool ValidateTextureSRGBDecodeValue(const Context *context, + angle::EntryPoint entryPoint, + const ParamType *params) +{ + if (!context->getExtensions().textureSRGBDecodeEXT) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled); + return false; + } + + switch (ConvertToGLenum(params[0])) + { + case GL_DECODE_EXT: + case GL_SKIP_DECODE_EXT: + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kUnknownParameter); + return false; + } + + return true; +} + +template +bool ValidateTextureSRGBOverrideValue(const Context *context, + angle::EntryPoint entryPoint, + const ParamType *params) +{ + if (!context->getExtensions().textureFormatSRGBOverrideEXT) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled); + return false; + } + + switch (ConvertToGLenum(params[0])) + { + case GL_SRGB: + case GL_NONE: + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kUnknownParameter); + return false; + } + + return true; +} + +bool ValidateTextureMaxAnisotropyExtensionEnabled(const Context *context, + angle::EntryPoint entryPoint) +{ + if (!context->getExtensions().textureFilterAnisotropicEXT) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled); + return false; + } + + return true; +} + +bool ValidateTextureMaxAnisotropyValue(const Context *context, + angle::EntryPoint entryPoint, + GLfloat paramValue) +{ + if (!ValidateTextureMaxAnisotropyExtensionEnabled(context, entryPoint)) + { + return false; + } + + GLfloat largest = context->getCaps().maxTextureAnisotropy; + + if (paramValue < 1 || paramValue > largest) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kOutsideOfBounds); + return false; + } + + return true; +} + +bool ValidateFragmentShaderColorBufferMaskMatch(const Context *context) +{ + const auto &glState = context->getState(); + const Program *program = context->getActiveLinkedProgram(); + const Framebuffer *framebuffer = glState.getDrawFramebuffer(); + + auto drawBufferMask = + framebuffer->getDrawBufferMask() & glState.getBlendStateExt().compareColorMask(0); + auto fragmentOutputMask = program->getExecutable().getActiveOutputVariablesMask(); + + return drawBufferMask == (drawBufferMask & fragmentOutputMask); +} + +bool ValidateFragmentShaderColorBufferTypeMatch(const Context *context) +{ + const ProgramExecutable *executable = context->getState().getLinkedProgramExecutable(context); + const Framebuffer *framebuffer = context->getState().getDrawFramebuffer(); + + return ValidateComponentTypeMasks(executable->getFragmentOutputsTypeMask().to_ulong(), + framebuffer->getDrawBufferTypeMask().to_ulong(), + executable->getActiveOutputVariablesMask().to_ulong(), + framebuffer->getDrawBufferMask().to_ulong()); +} + +bool ValidateVertexShaderAttributeTypeMatch(const Context *context) +{ + const auto &glState = context->getState(); + const Program *program = context->getActiveLinkedProgram(); + const VertexArray *vao = context->getState().getVertexArray(); + + if (!program) + { + return false; + } + + unsigned long stateCurrentValuesTypeBits = glState.getCurrentValuesTypeMask().to_ulong(); + unsigned long vaoAttribTypeBits = vao->getAttributesTypeMask().to_ulong(); + unsigned long vaoAttribEnabledMask = vao->getAttributesMask().to_ulong(); + + vaoAttribEnabledMask |= vaoAttribEnabledMask << kMaxComponentTypeMaskIndex; + vaoAttribTypeBits = (vaoAttribEnabledMask & vaoAttribTypeBits); + vaoAttribTypeBits |= (~vaoAttribEnabledMask & stateCurrentValuesTypeBits); + + const ProgramExecutable &executable = program->getExecutable(); + return ValidateComponentTypeMasks(executable.getAttributesTypeMask().to_ulong(), + vaoAttribTypeBits, executable.getAttributesMask().to_ulong(), + 0xFFFF); +} + +bool IsCompatibleDrawModeWithGeometryShader(PrimitiveMode drawMode, + PrimitiveMode geometryShaderInputPrimitiveType) +{ + // [EXT_geometry_shader] Section 11.1gs.1, Geometry Shader Input Primitives + switch (drawMode) + { + case PrimitiveMode::Points: + return geometryShaderInputPrimitiveType == PrimitiveMode::Points; + case PrimitiveMode::Lines: + case PrimitiveMode::LineStrip: + case PrimitiveMode::LineLoop: + return geometryShaderInputPrimitiveType == PrimitiveMode::Lines; + case PrimitiveMode::LinesAdjacency: + case PrimitiveMode::LineStripAdjacency: + return geometryShaderInputPrimitiveType == PrimitiveMode::LinesAdjacency; + case PrimitiveMode::Triangles: + case PrimitiveMode::TriangleFan: + case PrimitiveMode::TriangleStrip: + return geometryShaderInputPrimitiveType == PrimitiveMode::Triangles; + case PrimitiveMode::TrianglesAdjacency: + case PrimitiveMode::TriangleStripAdjacency: + return geometryShaderInputPrimitiveType == PrimitiveMode::TrianglesAdjacency; + default: + UNREACHABLE(); + return false; + } +} + +// GLES1 texture parameters are a small subset of the others +bool IsValidGLES1TextureParameter(GLenum pname) +{ + switch (pname) + { + case GL_TEXTURE_MAG_FILTER: + case GL_TEXTURE_MIN_FILTER: + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + case GL_TEXTURE_WRAP_R: + case GL_GENERATE_MIPMAP: + case GL_TEXTURE_CROP_RECT_OES: + return true; + default: + return false; + } +} + +unsigned int GetSamplerParameterCount(GLenum pname) +{ + return pname == GL_TEXTURE_BORDER_COLOR ? 4 : 1; +} + +const char *ValidateProgramDrawAdvancedBlendState(const Context *context, Program *program) +{ + const State &state = context->getState(); + const BlendEquationBitSet &supportedBlendEquations = + program->getExecutable().getAdvancedBlendEquations(); + const DrawBufferMask &enabledDrawBufferMask = state.getBlendStateExt().getEnabledMask(); + + for (size_t blendEnabledBufferIndex : enabledDrawBufferMask) + { + const gl::BlendEquationType &enabledBlendEquation = gl::FromGLenum( + state.getBlendStateExt().getEquationColorIndexed(blendEnabledBufferIndex)); + + if (enabledBlendEquation < gl::BlendEquationType::Multiply || + enabledBlendEquation > gl::BlendEquationType::HslLuminosity) + { + continue; + } + + if (!supportedBlendEquations.test(enabledBlendEquation)) + { + return gl::err::kBlendEquationNotEnabled; + } + } + + return nullptr; +} + +ANGLE_INLINE const char *ValidateProgramDrawStates(const Context *context, + const Extensions &extensions, + Program *program) +{ + const State &state = context->getState(); + if (extensions.multiviewOVR || extensions.multiview2OVR) + { + const int programNumViews = program->usesMultiview() ? program->getNumViews() : 1; + Framebuffer *framebuffer = state.getDrawFramebuffer(); + const int framebufferNumViews = framebuffer->getNumViews(); + + if (framebufferNumViews != programNumViews) + { + return gl::err::kMultiviewMismatch; + } + + if (state.isTransformFeedbackActiveUnpaused() && framebufferNumViews > 1) + { + return gl::err::kMultiviewTransformFeedback; + } + + if (extensions.disjointTimerQueryEXT && framebufferNumViews > 1 && + state.isQueryActive(QueryType::TimeElapsed)) + { + return gl::err::kMultiviewTimerQuery; + } + } + + // Uniform buffer validation + for (unsigned int uniformBlockIndex = 0; + uniformBlockIndex < program->getActiveUniformBlockCount(); uniformBlockIndex++) + { + const InterfaceBlock &uniformBlock = program->getUniformBlockByIndex(uniformBlockIndex); + GLuint blockBinding = program->getUniformBlockBinding(uniformBlockIndex); + const OffsetBindingPointer &uniformBuffer = + state.getIndexedUniformBuffer(blockBinding); + + if (uniformBuffer.get() == nullptr && context->isWebGL()) + { + // undefined behaviour + return gl::err::kUniformBufferUnbound; + } + + size_t uniformBufferSize = GetBoundBufferAvailableSize(uniformBuffer); + if (uniformBufferSize < uniformBlock.dataSize && + (context->isWebGL() || context->isBufferAccessValidationEnabled())) + { + // undefined behaviour + return gl::err::kUniformBufferTooSmall; + } + + if (uniformBuffer->hasWebGLXFBBindingConflict(context->isWebGL())) + { + return gl::err::kUniformBufferBoundForTransformFeedback; + } + } + + // Enabled blend equation validation + const char *errorString = nullptr; + + if (extensions.blendEquationAdvancedKHR) + { + errorString = ValidateProgramDrawAdvancedBlendState(context, program); + } + + return errorString; +} +} // anonymous namespace + +void SetRobustLengthParam(const GLsizei *length, GLsizei value) +{ + if (length) + { + // Currently we modify robust length parameters in the validation layer. We should be only + // doing this in the Context instead. + // TODO(http://anglebug.com/4406): Remove when possible. + *const_cast(length) = value; + } +} + +bool ValidTextureTarget(const Context *context, TextureType type) +{ + switch (type) + { + case TextureType::_2D: + case TextureType::CubeMap: + return true; + + case TextureType::Rectangle: + return context->getExtensions().textureRectangleANGLE; + + case TextureType::_3D: + return ((context->getClientMajorVersion() >= 3) || + context->getExtensions().texture3DOES); + + case TextureType::_2DArray: + return (context->getClientMajorVersion() >= 3); + + case TextureType::_2DMultisample: + return (context->getClientVersion() >= Version(3, 1) || + context->getExtensions().textureMultisampleANGLE); + case TextureType::_2DMultisampleArray: + return context->getExtensions().textureStorageMultisample2dArrayOES; + + case TextureType::CubeMapArray: + return (context->getClientVersion() >= Version(3, 2) || + context->getExtensions().textureCubeMapArrayAny()); + + case TextureType::VideoImage: + return context->getExtensions().videoTextureWEBGL; + + case TextureType::Buffer: + return (context->getClientVersion() >= Version(3, 2) || + context->getExtensions().textureBufferAny()); + + default: + return false; + } +} + +bool ValidTexture2DTarget(const Context *context, TextureType type) +{ + switch (type) + { + case TextureType::_2D: + case TextureType::CubeMap: + return true; + + case TextureType::Rectangle: + return context->getExtensions().textureRectangleANGLE; + + default: + return false; + } +} + +bool ValidTexture3DTarget(const Context *context, TextureType target) +{ + switch (target) + { + case TextureType::_3D: + case TextureType::_2DArray: + return (context->getClientMajorVersion() >= 3); + + case TextureType::CubeMapArray: + return (context->getClientVersion() >= Version(3, 2) || + context->getExtensions().textureCubeMapArrayAny()); + + default: + return false; + } +} + +// Most texture GL calls are not compatible with external textures, so we have a separate validation +// function for use in the GL calls that do +bool ValidTextureExternalTarget(const Context *context, TextureType target) +{ + return (target == TextureType::External) && + (context->getExtensions().EGLImageExternalOES || + context->getExtensions().EGLStreamConsumerExternalNV); +} + +bool ValidTextureExternalTarget(const Context *context, TextureTarget target) +{ + return (target == TextureTarget::External) && + ValidTextureExternalTarget(context, TextureType::External); +} + +// This function differs from ValidTextureTarget in that the target must be +// usable as the destination of a 2D operation-- so a cube face is valid, but +// GL_TEXTURE_CUBE_MAP is not. +// Note: duplicate of IsInternalTextureTarget +bool ValidTexture2DDestinationTarget(const Context *context, TextureTarget target) +{ + switch (target) + { + case TextureTarget::_2D: + case TextureTarget::CubeMapNegativeX: + case TextureTarget::CubeMapNegativeY: + case TextureTarget::CubeMapNegativeZ: + case TextureTarget::CubeMapPositiveX: + case TextureTarget::CubeMapPositiveY: + case TextureTarget::CubeMapPositiveZ: + return true; + case TextureTarget::Rectangle: + return context->getExtensions().textureRectangleANGLE; + case TextureTarget::VideoImage: + return context->getExtensions().videoTextureWEBGL; + default: + return false; + } +} + +bool ValidateTransformFeedbackPrimitiveMode(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode transformFeedbackPrimitiveMode, + PrimitiveMode renderPrimitiveMode) +{ + ASSERT(context); + + if ((!context->getExtensions().geometryShaderAny() || + !context->getExtensions().tessellationShaderEXT) && + context->getClientVersion() < ES_3_2) + { + // It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode + // that does not match the current transform feedback object's draw mode (if transform + // feedback is active), (3.0.2, section 2.14, pg 86) + return transformFeedbackPrimitiveMode == renderPrimitiveMode; + } + + const ProgramExecutable *executable = context->getState().getLinkedProgramExecutable(context); + ASSERT(executable); + if (executable->hasLinkedShaderStage(ShaderType::Geometry)) + { + // If geometry shader is active, transform feedback mode must match what is output from this + // stage. + renderPrimitiveMode = executable->getGeometryShaderOutputPrimitiveType(); + } + else if (executable->hasLinkedShaderStage(ShaderType::TessEvaluation)) + { + // Similarly with tessellation shaders, but only if no geometry shader is present. With + // tessellation shaders, only triangles are possibly output. + return transformFeedbackPrimitiveMode == PrimitiveMode::Triangles && + executable->getTessGenMode() == GL_TRIANGLES; + } + + // [GL_EXT_geometry_shader] Table 12.1gs + switch (renderPrimitiveMode) + { + case PrimitiveMode::Points: + return transformFeedbackPrimitiveMode == PrimitiveMode::Points; + case PrimitiveMode::Lines: + case PrimitiveMode::LineStrip: + case PrimitiveMode::LineLoop: + return transformFeedbackPrimitiveMode == PrimitiveMode::Lines; + case PrimitiveMode::Triangles: + case PrimitiveMode::TriangleFan: + case PrimitiveMode::TriangleStrip: + return transformFeedbackPrimitiveMode == PrimitiveMode::Triangles; + case PrimitiveMode::Patches: + return transformFeedbackPrimitiveMode == PrimitiveMode::Patches; + default: + UNREACHABLE(); + return false; + } +} + +bool ValidateDrawElementsInstancedBase(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLsizei count, + DrawElementsType type, + const void *indices, + GLsizei primcount) +{ + if (primcount <= 0) + { + if (primcount < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativePrimcount); + return false; + } + + // Early exit. + return ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, + primcount); + } + + if (!ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, primcount)) + { + return false; + } + + if (count == 0) + { + // Early exit. + return true; + } + + return ValidateDrawInstancedAttribs(context, entryPoint, primcount); +} + +bool ValidateDrawArraysInstancedBase(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLint first, + GLsizei count, + GLsizei primcount) +{ + if (primcount <= 0) + { + if (primcount < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativePrimcount); + return false; + } + + // Early exit. + return ValidateDrawArraysCommon(context, entryPoint, mode, first, count, primcount); + } + + if (!ValidateDrawArraysCommon(context, entryPoint, mode, first, count, primcount)) + { + return false; + } + + if (count == 0) + { + // Early exit. + return true; + } + + return ValidateDrawInstancedAttribs(context, entryPoint, primcount); +} + +bool ValidateDrawInstancedANGLE(const Context *context, angle::EntryPoint entryPoint) +{ + // Verify there is at least one active attribute with a divisor of zero + const State &state = context->getState(); + const ProgramExecutable *executable = state.getLinkedProgramExecutable(context); + + if (!executable) + { + // No executable means there is no Program/PPO bound, which is undefined behavior, but isn't + // an error. + context->getState().getDebug().insertMessage( + GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR, 0, GL_DEBUG_SEVERITY_HIGH, + std::string("Attempting to draw without a program"), gl::LOG_WARN, entryPoint); + return true; + } + + const auto &attribs = state.getVertexArray()->getVertexAttributes(); + const auto &bindings = state.getVertexArray()->getVertexBindings(); + for (size_t attributeIndex = 0; attributeIndex < attribs.size(); attributeIndex++) + { + const VertexAttribute &attrib = attribs[attributeIndex]; + const VertexBinding &binding = bindings[attrib.bindingIndex]; + if (executable->isAttribLocationActive(attributeIndex) && binding.getDivisor() == 0) + { + return true; + } + } + + context->validationError(entryPoint, GL_INVALID_OPERATION, kNoZeroDivisor); + return false; +} + +bool ValidTexture3DDestinationTarget(const Context *context, TextureTarget target) +{ + switch (target) + { + case TextureTarget::_3D: + case TextureTarget::_2DArray: + return true; + case TextureTarget::CubeMapArray: + return (context->getClientVersion() >= Version(3, 2) || + context->getExtensions().textureCubeMapArrayAny()); + default: + return false; + } +} + +bool ValidTexLevelDestinationTarget(const Context *context, TextureType type) +{ + switch (type) + { + case TextureType::_2D: + case TextureType::_2DArray: + case TextureType::_2DMultisample: + case TextureType::CubeMap: + case TextureType::_3D: + return true; + case TextureType::CubeMapArray: + return (context->getClientVersion() >= Version(3, 2) || + context->getExtensions().textureCubeMapArrayAny()); + case TextureType::Rectangle: + return context->getExtensions().textureRectangleANGLE; + case TextureType::_2DMultisampleArray: + return context->getExtensions().textureStorageMultisample2dArrayOES; + case TextureType::Buffer: + return (context->getClientVersion() >= Version(3, 2) || + context->getExtensions().textureBufferAny()); + default: + return false; + } +} + +bool ValidFramebufferTarget(const Context *context, GLenum target) +{ + static_assert(GL_DRAW_FRAMEBUFFER_ANGLE == GL_DRAW_FRAMEBUFFER && + GL_READ_FRAMEBUFFER_ANGLE == GL_READ_FRAMEBUFFER, + "ANGLE framebuffer enums must equal the ES3 framebuffer enums."); + + switch (target) + { + case GL_FRAMEBUFFER: + return true; + + case GL_READ_FRAMEBUFFER: + case GL_DRAW_FRAMEBUFFER: + return (context->getExtensions().framebufferBlitAny() || + context->getClientMajorVersion() >= 3); + + default: + return false; + } +} + +bool ValidMipLevel(const Context *context, TextureType type, GLint level) +{ + const auto &caps = context->getCaps(); + int maxDimension = 0; + switch (type) + { + case TextureType::_2D: + case TextureType::_2DArray: + case TextureType::_2DMultisample: + case TextureType::_2DMultisampleArray: + // TODO(http://anglebug.com/2775): It's a bit unclear what the "maximum allowable + // level-of-detail" for multisample textures should be. Could maybe make it zero. + maxDimension = caps.max2DTextureSize; + break; + + case TextureType::CubeMap: + case TextureType::CubeMapArray: + maxDimension = caps.maxCubeMapTextureSize; + break; + + case TextureType::External: + case TextureType::Rectangle: + case TextureType::VideoImage: + case TextureType::Buffer: + return level == 0; + + case TextureType::_3D: + maxDimension = caps.max3DTextureSize; + break; + + default: + UNREACHABLE(); + } + + return level <= log2(maxDimension) && level >= 0; +} + +bool ValidImageSizeParameters(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLint level, + GLsizei width, + GLsizei height, + GLsizei depth, + bool isSubImage) +{ + if (width < 0 || height < 0 || depth < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeSize); + return false; + } + // TexSubImage parameters can be NPOT without textureNPOT extension, + // as long as the destination texture is POT. + bool hasNPOTSupport = + context->getExtensions().textureNpotOES || context->getClientVersion() >= Version(3, 0); + if (!isSubImage && !hasNPOTSupport && + (level != 0 && (!isPow2(width) || !isPow2(height) || !isPow2(depth)))) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kTextureNotPow2); + return false; + } + + if (!ValidMipLevel(context, target, level)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel); + return false; + } + + return true; +} + +bool ValidCompressedBaseLevel(GLsizei size, GLuint blockSize, GLint level) +{ + // Already checked in ValidMipLevel. + ASSERT(level < 32); + // This function is used only for 4x4 BC formats. + ASSERT(blockSize == 4); + // Use the constant value to avoid division. + return ((size << level) % 4) == 0; +} + +bool ValidCompressedImageSize(const Context *context, + GLenum internalFormat, + GLint level, + GLsizei width, + GLsizei height, + GLsizei depth) +{ + if (width < 0 || height < 0) + { + return false; + } + + const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat); + + if (!formatInfo.compressed && !formatInfo.paletted) + { + return false; + } + + // A texture format can not be both block-compressed and paletted + ASSERT(!(formatInfo.compressed && formatInfo.paletted)); + + if (formatInfo.compressed) + { + // Only PVRTC1 requires dimensions to be powers of two + if (IsPVRTC1Format(internalFormat)) + { + if (!isPow2(width) || !isPow2(height)) + { + return false; + } + + if (context->getLimitations().squarePvrtc1) + { + if (width != height) + { + return false; + } + } + } + + if (CompressedTextureFormatRequiresExactSize(internalFormat)) + { + // In WebGL compatibility mode and D3D, enforce that the base level implied + // by the compressed texture's mip level would conform to the block + // size. + if (context->isWebGL() || + context->getLimitations().compressedBaseMipLevelMultipleOfFour) + { + // This check is performed only for BC formats. + ASSERT(formatInfo.compressedBlockDepth == 1); + if (!ValidCompressedBaseLevel(width, formatInfo.compressedBlockWidth, level) || + !ValidCompressedBaseLevel(height, formatInfo.compressedBlockHeight, level)) + { + return false; + } + } + // non-WebGL and non-D3D check is not necessary for the following formats + // From EXT_texture_compression_s3tc specification: + // If the width or height is not a multiple of four, there will be 4x4 blocks at the + // edge of the image that contain "extra" texels that are not part of the image. From + // EXT_texture_compression_bptc & EXT_texture_compression_rgtc specification: If an + // RGTC/BPTC image has a width or height that is not a multiple of four, the data + // corresponding to texels outside the image are irrelevant and undefined. + } + } + + if (formatInfo.paletted) + { + // TODO(http://anglebug.com/7688): multi-level paletted images + if (level != 0) + { + return false; + } + + if (!isPow2(width) || !isPow2(height)) + { + return false; + } + } + + return true; +} + +bool ValidCompressedSubImageSize(const Context *context, + GLenum internalFormat, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + size_t textureWidth, + size_t textureHeight, + size_t textureDepth) +{ + const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat); + if (!formatInfo.compressed) + { + return false; + } + + if (xoffset < 0 || yoffset < 0 || zoffset < 0 || width < 0 || height < 0 || depth < 0) + { + return false; + } + + // ANGLE does not support compressed 3D blocks (provided exclusively by ASTC 3D formats), so + // there is no need to check the depth here. Only width and height determine whether a 2D array + // element or a 2D slice of a sliced 3D texture fill the entire level. + bool fillsEntireMip = xoffset == 0 && yoffset == 0 && + static_cast(width) == textureWidth && + static_cast(height) == textureHeight; + + if (CompressedFormatRequiresWholeImage(internalFormat)) + { + return fillsEntireMip; + } + + if (CompressedSubTextureFormatRequiresExactSize(internalFormat)) + { + if (xoffset % formatInfo.compressedBlockWidth != 0 || + yoffset % formatInfo.compressedBlockHeight != 0 || + zoffset % formatInfo.compressedBlockDepth != 0) + { + return false; + } + + // Allowed to either have data that is a multiple of block size or is smaller than the block + // size but fills the entire mip + bool sizeMultipleOfBlockSize = (width % formatInfo.compressedBlockWidth) == 0 && + (height % formatInfo.compressedBlockHeight) == 0 && + (depth % formatInfo.compressedBlockDepth) == 0; + if (!sizeMultipleOfBlockSize && !fillsEntireMip) + { + return false; + } + } + + return true; +} + +bool ValidImageDataSize(const Context *context, + angle::EntryPoint entryPoint, + TextureType texType, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *pixels, + GLsizei imageSize) +{ + Buffer *pixelUnpackBuffer = context->getState().getTargetBuffer(BufferBinding::PixelUnpack); + if (pixelUnpackBuffer == nullptr && imageSize < 0) + { + // Checks are not required + return true; + } + + // ...the data would be unpacked from the buffer object such that the memory reads required + // would exceed the data store size. + const InternalFormat &formatInfo = GetInternalFormatInfo(format, type); + ASSERT(formatInfo.internalFormat != GL_NONE); + const Extents size(width, height, depth); + const auto &unpack = context->getState().getUnpackState(); + + bool targetIs3D = texType == TextureType::_3D || texType == TextureType::_2DArray; + GLuint endByte = 0; + if (!formatInfo.computePackUnpackEndByte(type, size, unpack, targetIs3D, &endByte)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kIntegerOverflow); + return false; + } + + if (pixelUnpackBuffer) + { + CheckedNumeric checkedEndByte(endByte); + CheckedNumeric checkedOffset(reinterpret_cast(pixels)); + checkedEndByte += checkedOffset; + + if (!checkedEndByte.IsValid() || + (checkedEndByte.ValueOrDie() > static_cast(pixelUnpackBuffer->getSize()))) + { + // Overflow past the end of the buffer + context->validationError(entryPoint, GL_INVALID_OPERATION, kIntegerOverflow); + return false; + } + if (pixelUnpackBuffer->hasWebGLXFBBindingConflict(context->isWebGL())) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kPixelUnpackBufferBoundForTransformFeedback); + return false; + } + } + else + { + ASSERT(imageSize >= 0); + if (pixels == nullptr && imageSize != 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kImageSizeMustBeZero); + return false; + } + + if (pixels != nullptr && endByte > static_cast(imageSize)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kImageSizeTooSmall); + return false; + } + } + + return true; +} + +bool ValidQueryType(const Context *context, QueryType queryType) +{ + switch (queryType) + { + case QueryType::AnySamples: + case QueryType::AnySamplesConservative: + return context->getClientMajorVersion() >= 3 || + context->getExtensions().occlusionQueryBooleanEXT; + case QueryType::TransformFeedbackPrimitivesWritten: + return (context->getClientMajorVersion() >= 3); + case QueryType::TimeElapsed: + return context->getExtensions().disjointTimerQueryEXT; + case QueryType::CommandsCompleted: + return context->getExtensions().syncQueryCHROMIUM; + case QueryType::PrimitivesGenerated: + return context->getClientVersion() >= ES_3_2 || + context->getExtensions().geometryShaderAny(); + default: + return false; + } +} + +bool ValidateWebGLVertexAttribPointer(const Context *context, + angle::EntryPoint entryPoint, + VertexAttribType type, + GLboolean normalized, + GLsizei stride, + const void *ptr, + bool pureInteger) +{ + ASSERT(context->isWebGL()); + // WebGL 1.0 [Section 6.11] Vertex Attribute Data Stride + // The WebGL API supports vertex attribute data strides up to 255 bytes. A call to + // vertexAttribPointer will generate an INVALID_VALUE error if the value for the stride + // parameter exceeds 255. + constexpr GLsizei kMaxWebGLStride = 255; + if (stride > kMaxWebGLStride) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kStrideExceedsWebGLLimit); + return false; + } + + // WebGL 1.0 [Section 6.4] Buffer Offset and Stride Requirements + // The offset arguments to drawElements and vertexAttribPointer, and the stride argument to + // vertexAttribPointer, must be a multiple of the size of the data type passed to the call, + // or an INVALID_OPERATION error is generated. + angle::FormatID internalType = GetVertexFormatID(type, normalized, 1, pureInteger); + size_t typeSize = GetVertexFormatSize(internalType); + + ASSERT(isPow2(typeSize) && typeSize > 0); + size_t sizeMask = (typeSize - 1); + if ((reinterpret_cast(ptr) & sizeMask) != 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kOffsetMustBeMultipleOfType); + return false; + } + + if ((stride & sizeMask) != 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kStrideMustBeMultipleOfType); + return false; + } + + return true; +} + +Program *GetValidProgramNoResolve(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID id) +{ + // ES3 spec (section 2.11.1) -- "Commands that accept shader or program object names will + // generate the error INVALID_VALUE if the provided name is not the name of either a shader + // or program object and INVALID_OPERATION if the provided name identifies an object + // that is not the expected type." + + Program *validProgram = context->getProgramNoResolveLink(id); + + if (!validProgram) + { + if (context->getShader(id)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExpectedProgramName); + } + else + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidProgramName); + } + } + + return validProgram; +} + +Program *GetValidProgram(const Context *context, angle::EntryPoint entryPoint, ShaderProgramID id) +{ + Program *program = GetValidProgramNoResolve(context, entryPoint, id); + if (program) + { + program->resolveLink(context); + } + return program; +} + +Shader *GetValidShader(const Context *context, angle::EntryPoint entryPoint, ShaderProgramID id) +{ + // See ValidProgram for spec details. + + Shader *validShader = context->getShader(id); + + if (!validShader) + { + if (context->getProgramNoResolveLink(id)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExpectedShaderName); + } + else + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidShaderName); + } + } + + return validShader; +} + +bool ValidateAttachmentTarget(const Context *context, + angle::EntryPoint entryPoint, + GLenum attachment) +{ + if (attachment >= GL_COLOR_ATTACHMENT1_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) + { + if (context->getClientMajorVersion() < 3 && !context->getExtensions().drawBuffersEXT) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidAttachment); + return false; + } + + // Color attachment 0 is validated below because it is always valid + const int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); + if (colorAttachment >= context->getCaps().maxColorAttachments) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidAttachment); + return false; + } + } + else + { + switch (attachment) + { + case GL_COLOR_ATTACHMENT0: + case GL_DEPTH_ATTACHMENT: + case GL_STENCIL_ATTACHMENT: + break; + + case GL_DEPTH_STENCIL_ATTACHMENT: + if (!context->isWebGL() && context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidAttachment); + return false; + } + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidAttachment); + return false; + } + } + + return true; +} + +bool ValidateRenderbufferStorageParametersBase(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height) +{ + switch (target) + { + case GL_RENDERBUFFER: + break; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidRenderbufferTarget); + return false; + } + + if (width < 0 || height < 0 || samples < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidRenderbufferWidthHeight); + return false; + } + + // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format. + GLenum convertedInternalFormat = context->getConvertedRenderbufferFormat(internalformat); + + const TextureCaps &formatCaps = context->getTextureCaps().get(convertedInternalFormat); + if (!formatCaps.renderbuffer) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidRenderbufferInternalFormat); + return false; + } + + // ANGLE_framebuffer_multisample does not explicitly state that the internal format must be + // sized but it does state that the format must be in the ES2.0 spec table 4.5 which contains + // only sized internal formats. + const InternalFormat &formatInfo = GetSizedInternalFormatInfo(convertedInternalFormat); + if (formatInfo.internalFormat == GL_NONE) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidRenderbufferInternalFormat); + return false; + } + + if (std::max(width, height) > context->getCaps().maxRenderbufferSize) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxRenderbufferSize); + return false; + } + + RenderbufferID id = context->getState().getRenderbufferId(); + if (id.value == 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidRenderbufferTarget); + return false; + } + + return true; +} + +bool ValidateBlitFramebufferParameters(const Context *context, + angle::EntryPoint entryPoint, + GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter) +{ + switch (filter) + { + case GL_NEAREST: + break; + case GL_LINEAR: + break; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kBlitInvalidFilter); + return false; + } + + if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kBlitInvalidMask); + return false; + } + + // ES3.0 spec, section 4.3.2 states that linear filtering is only available for the + // color buffer, leaving only nearest being unfiltered from above + if ((mask & ~GL_COLOR_BUFFER_BIT) != 0 && filter != GL_NEAREST) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kBlitOnlyNearestForNonColor); + return false; + } + + const auto &glState = context->getState(); + Framebuffer *readFramebuffer = glState.getReadFramebuffer(); + Framebuffer *drawFramebuffer = glState.getDrawFramebuffer(); + + if (!readFramebuffer || !drawFramebuffer) + { + context->validationError(entryPoint, GL_INVALID_FRAMEBUFFER_OPERATION, + kBlitFramebufferMissing); + return false; + } + + if (!ValidateFramebufferComplete(context, entryPoint, readFramebuffer)) + { + return false; + } + + if (!ValidateFramebufferComplete(context, entryPoint, drawFramebuffer)) + { + return false; + } + + // EXT_YUV_target disallows blitting to or from a YUV framebuffer + if ((mask & GL_COLOR_BUFFER_BIT) != 0 && + (readFramebuffer->hasYUVAttachment() || drawFramebuffer->hasYUVAttachment())) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kBlitYUVFramebuffer); + return false; + } + + // The draw and read framebuffers can only match if: + // - They are the default framebuffer AND + // - The read/draw surfaces are different + if ((readFramebuffer->id() == drawFramebuffer->id()) && + ((drawFramebuffer->id() != Framebuffer::kDefaultDrawFramebufferHandle) || + (context->getCurrentDrawSurface() == context->getCurrentReadSurface()))) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kBlitFeedbackLoop); + return false; + } + + // Not allow blitting to MS buffers, therefore if renderToTextureSamples exist, + // consider it MS. checkReadBufferResourceSamples = false + if (!ValidateFramebufferNotMultisampled(context, entryPoint, drawFramebuffer, false)) + { + return false; + } + + // This validation is specified in the WebGL 2.0 spec and not in the GLES 3.0.5 spec, but we + // always run it in order to avoid triggering driver bugs. + if (DifferenceCanOverflow(srcX0, srcX1) || DifferenceCanOverflow(srcY0, srcY1) || + DifferenceCanOverflow(dstX0, dstX1) || DifferenceCanOverflow(dstY0, dstY1)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kBlitDimensionsOutOfRange); + return false; + } + + bool sameBounds = srcX0 == dstX0 && srcY0 == dstY0 && srcX1 == dstX1 && srcY1 == dstY1; + + if (mask & GL_COLOR_BUFFER_BIT) + { + const FramebufferAttachment *readColorBuffer = readFramebuffer->getReadColorAttachment(); + const Extensions &extensions = context->getExtensions(); + + if (readColorBuffer) + { + const Format &readFormat = readColorBuffer->getFormat(); + + for (size_t drawbufferIdx = 0; + drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx) + { + const FramebufferAttachment *attachment = + drawFramebuffer->getDrawBuffer(drawbufferIdx); + if (attachment) + { + const Format &drawFormat = attachment->getFormat(); + + // The GL ES 3.0.2 spec (pg 193) states that: + // 1) If the read buffer is fixed point format, the draw buffer must be as well + // 2) If the read buffer is an unsigned integer format, the draw buffer must be + // as well + // 3) If the read buffer is a signed integer format, the draw buffer must be as + // well + // Changes with EXT_color_buffer_float: + // Case 1) is changed to fixed point OR floating point + GLenum readComponentType = readFormat.info->componentType; + GLenum drawComponentType = drawFormat.info->componentType; + bool readFixedPoint = (readComponentType == GL_UNSIGNED_NORMALIZED || + readComponentType == GL_SIGNED_NORMALIZED); + bool drawFixedPoint = (drawComponentType == GL_UNSIGNED_NORMALIZED || + drawComponentType == GL_SIGNED_NORMALIZED); + + if (extensions.colorBufferFloatEXT) + { + bool readFixedOrFloat = (readFixedPoint || readComponentType == GL_FLOAT); + bool drawFixedOrFloat = (drawFixedPoint || drawComponentType == GL_FLOAT); + + if (readFixedOrFloat != drawFixedOrFloat) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kBlitTypeMismatchFixedOrFloat); + return false; + } + } + else if (readFixedPoint != drawFixedPoint) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kBlitTypeMismatchFixedPoint); + return false; + } + + if (readComponentType == GL_UNSIGNED_INT && + drawComponentType != GL_UNSIGNED_INT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kBlitTypeMismatchUnsignedInteger); + return false; + } + + if (readComponentType == GL_INT && drawComponentType != GL_INT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kBlitTypeMismatchSignedInteger); + return false; + } + + if (readColorBuffer->getResourceSamples() > 0 && + (!Format::EquivalentForBlit(readFormat, drawFormat) || !sameBounds)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kBlitMultisampledFormatOrBoundsMismatch); + return false; + } + + if (context->isWebGL() && *readColorBuffer == *attachment) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kBlitSameImageColor); + return false; + } + } + } + + if (readFormat.info->isInt() && filter == GL_LINEAR) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kBlitIntegerWithLinearFilter); + return false; + } + } + // WebGL 2.0 BlitFramebuffer when blitting from a missing attachment + // In OpenGL ES it is undefined what happens when an operation tries to blit from a missing + // attachment and WebGL defines it to be an error. We do the check unconditionally as the + // situation is an application error that would lead to a crash in ANGLE. + else if (drawFramebuffer->hasEnabledDrawBuffer()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kBlitMissingColor); + return false; + } + } + + GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT}; + GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT}; + for (size_t i = 0; i < 2; i++) + { + if (mask & masks[i]) + { + const FramebufferAttachment *readBuffer = + readFramebuffer->getAttachment(context, attachments[i]); + const FramebufferAttachment *drawBuffer = + drawFramebuffer->getAttachment(context, attachments[i]); + + if (readBuffer && drawBuffer) + { + if (!Format::EquivalentForBlit(readBuffer->getFormat(), drawBuffer->getFormat())) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kBlitDepthOrStencilFormatMismatch); + return false; + } + + if (readBuffer->getResourceSamples() > 0 && !sameBounds) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kBlitMultisampledBoundsMismatch); + return false; + } + + if (context->isWebGL() && *readBuffer == *drawBuffer) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kBlitSameImageDepthOrStencil); + return false; + } + } + // WebGL 2.0 BlitFramebuffer when blitting from a missing attachment + else if (drawBuffer) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kBlitMissingDepthOrStencil); + return false; + } + } + } + + // OVR_multiview2: + // Calling BlitFramebuffer will result in an INVALID_FRAMEBUFFER_OPERATION error if the + // current draw framebuffer isMultiview() or the number of + // views in the current read framebuffer is more than one. + if (readFramebuffer->readDisallowedByMultiview()) + { + context->validationError(entryPoint, GL_INVALID_FRAMEBUFFER_OPERATION, kBlitFromMultiview); + return false; + } + if (drawFramebuffer->isMultiview()) + { + context->validationError(entryPoint, GL_INVALID_FRAMEBUFFER_OPERATION, kBlitToMultiview); + return false; + } + + return true; +} + +bool ValidateBindFramebufferBase(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + FramebufferID framebuffer) +{ + if (!ValidFramebufferTarget(context, target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFramebufferTarget); + return false; + } + + if (!context->getState().isBindGeneratesResourceEnabled() && + !context->isFramebufferGenerated(framebuffer)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kObjectNotGenerated); + return false; + } + + return true; +} + +bool ValidateBindRenderbufferBase(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + RenderbufferID renderbuffer) +{ + if (target != GL_RENDERBUFFER) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidRenderbufferTarget); + return false; + } + + if (!context->getState().isBindGeneratesResourceEnabled() && + !context->isRenderbufferGenerated(renderbuffer)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kObjectNotGenerated); + return false; + } + + return true; +} + +bool ValidateFramebufferParameteriBase(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum pname, + GLint param) +{ + if (!ValidFramebufferTarget(context, target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFramebufferTarget); + return false; + } + + switch (pname) + { + case GL_FRAMEBUFFER_DEFAULT_WIDTH: + { + GLint maxWidth = context->getCaps().maxFramebufferWidth; + if (param < 0 || param > maxWidth) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsFramebufferWidth); + return false; + } + break; + } + case GL_FRAMEBUFFER_DEFAULT_HEIGHT: + { + GLint maxHeight = context->getCaps().maxFramebufferHeight; + if (param < 0 || param > maxHeight) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsFramebufferHeight); + return false; + } + break; + } + case GL_FRAMEBUFFER_DEFAULT_SAMPLES: + { + GLint maxSamples = context->getCaps().maxFramebufferSamples; + if (param < 0 || param > maxSamples) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsFramebufferSamples); + return false; + } + break; + } + case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS: + { + break; + } + case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT: + { + if (!context->getExtensions().geometryShaderAny() && + context->getClientVersion() < ES_3_2) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kGeometryShaderExtensionNotEnabled); + return false; + } + GLint maxLayers = context->getCaps().maxFramebufferLayers; + if (param < 0 || param > maxLayers) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidFramebufferLayer); + return false; + } + break; + } + case GL_FRAMEBUFFER_FLIP_Y_MESA: + { + if (!context->getExtensions().framebufferFlipYMESA) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname); + return false; + } + break; + } + default: + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname); + return false; + } + } + + const Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target); + ASSERT(framebuffer); + if (framebuffer->isDefault()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultFramebuffer); + return false; + } + return true; +} + +bool ValidateFramebufferRenderbufferBase(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + GLenum renderbuffertarget, + RenderbufferID renderbuffer) +{ + if (!ValidFramebufferTarget(context, target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFramebufferTarget); + return false; + } + + if (renderbuffertarget != GL_RENDERBUFFER) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidRenderbufferTarget); + return false; + } + + Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target); + + ASSERT(framebuffer); + if (framebuffer->isDefault()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultFramebufferTarget); + return false; + } + + if (!ValidateAttachmentTarget(context, entryPoint, attachment)) + { + return false; + } + + // [OpenGL ES 2.0.25] Section 4.4.3 page 112 + // [OpenGL ES 3.0.2] Section 4.4.2 page 201 + // 'renderbuffer' must be either zero or the name of an existing renderbuffer object of + // type 'renderbuffertarget', otherwise an INVALID_OPERATION error is generated. + if (renderbuffer.value != 0) + { + if (!context->getRenderbuffer(renderbuffer)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidRenderbufferTarget); + return false; + } + } + + return true; +} + +bool ValidateFramebufferTextureBase(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + TextureID texture, + GLint level) +{ + if (!ValidFramebufferTarget(context, target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFramebufferTarget); + return false; + } + + if (!ValidateAttachmentTarget(context, entryPoint, attachment)) + { + return false; + } + + if (texture.value != 0) + { + Texture *tex = context->getTexture(texture); + + if (tex == nullptr) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kMissingTexture); + return false; + } + + if (level < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel); + return false; + } + + // GLES spec 3.1, Section 9.2.8 "Attaching Texture Images to a Framebuffer" + // An INVALID_VALUE error is generated if texture is not zero and level is + // not a supported texture level for textarget + + // Common criteria for not supported texture levels(other criteria are handled case by case + // in non base functions): If texture refers to an immutable-format texture, level must be + // greater than or equal to zero and smaller than the value of TEXTURE_IMMUTABLE_LEVELS for + // texture. + if (tex->getImmutableFormat() && context->getClientVersion() >= ES_3_1) + { + if (level >= static_cast(tex->getImmutableLevels())) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel); + return false; + } + } + + // GLES spec 3.2, Section 9.2.8 "Attaching Texture Images to a Framebuffer" + // An INVALID_OPERATION error is generated if is the name of a buffer texture. + if ((context->getClientVersion() >= ES_3_2 || + context->getExtensions().textureBufferAny()) && + tex->getType() == TextureType::Buffer) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureTarget); + return false; + } + + if (tex->getState().hasProtectedContent() != context->getState().hasProtectedContent()) + { + context->validationError( + entryPoint, GL_INVALID_OPERATION, + "Mismatch between Texture and Context Protected Content state"); + return false; + } + } + + const Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target); + ASSERT(framebuffer); + + if (framebuffer->isDefault()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultFramebufferTarget); + return false; + } + + return true; +} + +bool ValidateGenerateMipmapBase(const Context *context, + angle::EntryPoint entryPoint, + TextureType target) +{ + if (!ValidTextureTarget(context, target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + + Texture *texture = context->getTextureByType(target); + + if (texture == nullptr) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kTextureNotBound); + return false; + } + + const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel(); + + // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so + // that out-of-range base level has a non-color-renderable / non-texture-filterable format. + if (effectiveBaseLevel >= IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kBaseLevelOutOfRange); + return false; + } + + TextureTarget baseTarget = (target == TextureType::CubeMap) + ? TextureTarget::CubeMapPositiveX + : NonCubeTextureTypeToTarget(target); + const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info); + if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 || + format.stencilBits > 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kGenerateMipmapNotAllowed); + return false; + } + + // GenerateMipmap accepts formats that are unsized or both color renderable and filterable. + bool formatUnsized = !format.sized; + bool formatColorRenderableAndFilterable = + format.filterSupport(context->getClientVersion(), context->getExtensions()) && + format.textureAttachmentSupport(context->getClientVersion(), context->getExtensions()); + if (!formatUnsized && !formatColorRenderableAndFilterable) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kGenerateMipmapNotAllowed); + return false; + } + + // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap + // generation + if (format.colorEncoding == GL_SRGB && format.format == GL_RGB) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kGenerateMipmapNotAllowed); + return false; + } + + // According to the OpenGL extension spec EXT_sRGB.txt, EXT_SRGB is based on ES 2.0 and + // generateMipmap is not allowed if texture format is SRGB_EXT or SRGB_ALPHA_EXT. + if (context->getClientVersion() < Version(3, 0) && format.colorEncoding == GL_SRGB) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kGenerateMipmapNotAllowed); + return false; + } + + // Non-power of 2 ES2 check + if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNpotOES && + (!isPow2(static_cast(texture->getWidth(baseTarget, 0))) || + !isPow2(static_cast(texture->getHeight(baseTarget, 0))))) + { + ASSERT(target == TextureType::_2D || target == TextureType::Rectangle || + target == TextureType::CubeMap); + context->validationError(entryPoint, GL_INVALID_OPERATION, kTextureNotPow2); + return false; + } + + // Cube completeness check + if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kCubemapIncomplete); + return false; + } + + if (context->isWebGL() && (texture->getWidth(baseTarget, effectiveBaseLevel) == 0 || + texture->getHeight(baseTarget, effectiveBaseLevel) == 0)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kGenerateMipmapZeroSize); + return false; + } + + return true; +} + +bool ValidateReadPixelsRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + const GLsizei *length, + const GLsizei *columns, + const GLsizei *rows, + const void *pixels) +{ + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + GLsizei writeLength = 0; + GLsizei writeColumns = 0; + GLsizei writeRows = 0; + + if (!ValidateReadPixelsBase(context, entryPoint, x, y, width, height, format, type, bufSize, + &writeLength, &writeColumns, &writeRows, pixels)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength)) + { + return false; + } + + SetRobustLengthParam(length, writeLength); + SetRobustLengthParam(columns, writeColumns); + SetRobustLengthParam(rows, writeRows); + + return true; +} + +bool ValidateReadnPixelsEXT(const Context *context, + angle::EntryPoint entryPoint, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels) +{ + if (bufSize < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize); + return false; + } + + return ValidateReadPixelsBase(context, entryPoint, x, y, width, height, format, type, bufSize, + nullptr, nullptr, nullptr, pixels); +} + +bool ValidateReadnPixelsRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + const GLsizei *length, + const GLsizei *columns, + const GLsizei *rows, + const void *data) +{ + GLsizei writeLength = 0; + GLsizei writeColumns = 0; + GLsizei writeRows = 0; + + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + if (!ValidateReadPixelsBase(context, entryPoint, x, y, width, height, format, type, bufSize, + &writeLength, &writeColumns, &writeRows, data)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength)) + { + return false; + } + + SetRobustLengthParam(length, writeLength); + SetRobustLengthParam(columns, writeColumns); + SetRobustLengthParam(rows, writeRows); + + return true; +} + +bool ValidateGenQueriesEXT(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const QueryID *ids) +{ + if (!context->getExtensions().occlusionQueryBooleanEXT && + !context->getExtensions().disjointTimerQueryEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kQueryExtensionNotEnabled); + return false; + } + + return ValidateGenOrDelete(context, entryPoint, n); +} + +bool ValidateDeleteQueriesEXT(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const QueryID *ids) +{ + if (!context->getExtensions().occlusionQueryBooleanEXT && + !context->getExtensions().disjointTimerQueryEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kQueryExtensionNotEnabled); + return false; + } + + return ValidateGenOrDelete(context, entryPoint, n); +} + +bool ValidateIsQueryEXT(const Context *context, angle::EntryPoint entryPoint, QueryID id) +{ + if (!context->getExtensions().occlusionQueryBooleanEXT && + !context->getExtensions().disjointTimerQueryEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kQueryExtensionNotEnabled); + return false; + } + + return true; +} + +bool ValidateBeginQueryBase(const Context *context, + angle::EntryPoint entryPoint, + QueryType target, + QueryID id) +{ + if (!ValidQueryType(context, target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidQueryType); + return false; + } + + if (id.value == 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidQueryId); + return false; + } + + // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an + // of zero, if the active query object name for is non-zero (for the + // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if + // the active query for either target is non-zero), if is the name of an + // existing query object whose type does not match , or if is the + // active query object name for any query type, the error INVALID_OPERATION is + // generated. + + // Ensure no other queries are active + // NOTE: If other queries than occlusion are supported, we will need to check + // separately that: + // a) The query ID passed is not the current active query for any target/type + // b) There are no active queries for the requested target (and in the case + // of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, + // no query may be active for either if glBeginQuery targets either. + + if (context->getState().isQueryActive(target)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kOtherQueryActive); + return false; + } + + // check that name was obtained with glGenQueries + if (!context->isQueryGenerated(id)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidQueryId); + return false; + } + + // Check for type mismatch. If query is not yet started we're good to go. + Query *queryObject = context->getQuery(id); + if (queryObject && queryObject->getType() != target) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kQueryTargetMismatch); + return false; + } + + return true; +} + +bool ValidateBeginQueryEXT(const Context *context, + angle::EntryPoint entryPoint, + QueryType target, + QueryID id) +{ + if (!context->getExtensions().occlusionQueryBooleanEXT && + !context->getExtensions().disjointTimerQueryEXT && + !context->getExtensions().syncQueryCHROMIUM) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kQueryExtensionNotEnabled); + return false; + } + + return ValidateBeginQueryBase(context, entryPoint, target, id); +} + +bool ValidateEndQueryBase(const Context *context, angle::EntryPoint entryPoint, QueryType target) +{ + if (!ValidQueryType(context, target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidQueryType); + return false; + } + + const Query *queryObject = context->getState().getActiveQuery(target); + + if (queryObject == nullptr) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kQueryInactive); + return false; + } + + return true; +} + +bool ValidateEndQueryEXT(const Context *context, angle::EntryPoint entryPoint, QueryType target) +{ + if (!context->getExtensions().occlusionQueryBooleanEXT && + !context->getExtensions().disjointTimerQueryEXT && + !context->getExtensions().syncQueryCHROMIUM) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kQueryExtensionNotEnabled); + return false; + } + + return ValidateEndQueryBase(context, entryPoint, target); +} + +bool ValidateQueryCounterEXT(const Context *context, + angle::EntryPoint entryPoint, + QueryID id, + QueryType target) +{ + if (!context->getExtensions().disjointTimerQueryEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (target != QueryType::Timestamp) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidQueryTarget); + return false; + } + + if (!context->isQueryGenerated(id)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidQueryId); + return false; + } + + // If query object is not started, that's fine. + Query *queryObject = context->getQuery(id); + if (queryObject && context->getState().isQueryActive(queryObject)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kQueryActive); + return false; + } + + return true; +} + +bool ValidateGetQueryivBase(const Context *context, + angle::EntryPoint entryPoint, + QueryType target, + GLenum pname, + GLsizei *numParams) +{ + if (numParams) + { + *numParams = 0; + } + + if (!ValidQueryType(context, target) && target != QueryType::Timestamp) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidQueryType); + return false; + } + + switch (pname) + { + case GL_CURRENT_QUERY_EXT: + if (target == QueryType::Timestamp) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidQueryTarget); + return false; + } + break; + case GL_QUERY_COUNTER_BITS_EXT: + if (!context->getExtensions().disjointTimerQueryEXT || + (target != QueryType::Timestamp && target != QueryType::TimeElapsed)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname); + return false; + } + break; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname); + return false; + } + + if (numParams) + { + // All queries return only one value + *numParams = 1; + } + + return true; +} + +bool ValidateGetQueryivEXT(const Context *context, + angle::EntryPoint entryPoint, + QueryType target, + GLenum pname, + const GLint *params) +{ + if (!context->getExtensions().occlusionQueryBooleanEXT && + !context->getExtensions().disjointTimerQueryEXT && + !context->getExtensions().syncQueryCHROMIUM) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateGetQueryivBase(context, entryPoint, target, pname, nullptr); +} + +bool ValidateGetQueryivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + QueryType target, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params) +{ + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + GLsizei numParams = 0; + + if (!ValidateGetQueryivBase(context, entryPoint, target, pname, &numParams)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams)) + { + return false; + } + + SetRobustLengthParam(length, numParams); + + return true; +} + +bool ValidateGetQueryObjectValueBase(const Context *context, + angle::EntryPoint entryPoint, + QueryID id, + GLenum pname, + GLsizei *numParams) +{ + if (numParams) + { + *numParams = 1; + } + + if (context->isContextLost()) + { + context->validationError(entryPoint, GL_CONTEXT_LOST, kContextLost); + + if (pname == GL_QUERY_RESULT_AVAILABLE_EXT) + { + // Generate an error but still return true, the context still needs to return a + // value in this case. + return true; + } + else + { + return false; + } + } + + Query *queryObject = context->getQuery(id); + + if (!queryObject) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidQueryId); + return false; + } + + if (context->getState().isQueryActive(queryObject)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kQueryActive); + return false; + } + + switch (pname) + { + case GL_QUERY_RESULT_EXT: + case GL_QUERY_RESULT_AVAILABLE_EXT: + break; + + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + + return true; +} + +bool ValidateGetQueryObjectivEXT(const Context *context, + angle::EntryPoint entryPoint, + QueryID id, + GLenum pname, + const GLint *params) +{ + if (!context->getExtensions().disjointTimerQueryEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + return ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, nullptr); +} + +bool ValidateGetQueryObjectivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + QueryID id, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params) +{ + if (!context->getExtensions().disjointTimerQueryEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + GLsizei numParams = 0; + + if (!ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, &numParams)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams)) + { + return false; + } + + SetRobustLengthParam(length, numParams); + + return true; +} + +bool ValidateGetQueryObjectuivEXT(const Context *context, + angle::EntryPoint entryPoint, + QueryID id, + GLenum pname, + const GLuint *params) +{ + if (!context->getExtensions().disjointTimerQueryEXT && + !context->getExtensions().occlusionQueryBooleanEXT && + !context->getExtensions().syncQueryCHROMIUM) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + return ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, nullptr); +} + +bool ValidateGetQueryObjectuivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + QueryID id, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLuint *params) +{ + if (!context->getExtensions().disjointTimerQueryEXT && + !context->getExtensions().occlusionQueryBooleanEXT && + !context->getExtensions().syncQueryCHROMIUM) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + GLsizei numParams = 0; + + if (!ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, &numParams)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams)) + { + return false; + } + + SetRobustLengthParam(length, numParams); + + return true; +} + +bool ValidateGetQueryObjecti64vEXT(const Context *context, + angle::EntryPoint entryPoint, + QueryID id, + GLenum pname, + GLint64 *params) +{ + if (!context->getExtensions().disjointTimerQueryEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + return ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, nullptr); +} + +bool ValidateGetQueryObjecti64vRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + QueryID id, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + GLint64 *params) +{ + if (!context->getExtensions().disjointTimerQueryEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + GLsizei numParams = 0; + + if (!ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, &numParams)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams)) + { + return false; + } + + SetRobustLengthParam(length, numParams); + + return true; +} + +bool ValidateGetQueryObjectui64vEXT(const Context *context, + angle::EntryPoint entryPoint, + QueryID id, + GLenum pname, + GLuint64 *params) +{ + if (!context->getExtensions().disjointTimerQueryEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + return ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, nullptr); +} + +bool ValidateGetQueryObjectui64vRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + QueryID id, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + GLuint64 *params) +{ + if (!context->getExtensions().disjointTimerQueryEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + GLsizei numParams = 0; + + if (!ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, &numParams)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams)) + { + return false; + } + + SetRobustLengthParam(length, numParams); + + return true; +} + +bool ValidateUniformCommonBase(const Context *context, + angle::EntryPoint entryPoint, + const Program *program, + UniformLocation location, + GLsizei count, + const LinkedUniform **uniformOut) +{ + // TODO(Jiajia): Add image uniform check in future. + if (count < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeCount); + return false; + } + + if (!program) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidProgramName); + return false; + } + + if (!program->isLinked()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked); + return false; + } + + if (location.value == -1) + { + // Silently ignore the uniform command + return false; + } + + const auto &uniformLocations = program->getUniformLocations(); + size_t castedLocation = static_cast(location.value); + if (castedLocation >= uniformLocations.size()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidUniformLocation); + return false; + } + + const auto &uniformLocation = uniformLocations[castedLocation]; + if (uniformLocation.ignored) + { + // Silently ignore the uniform command + return false; + } + + if (!uniformLocation.used()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidUniformLocation); + return false; + } + + const auto &uniform = program->getUniformByIndex(uniformLocation.index); + + // attempting to write an array to a non-array uniform is an INVALID_OPERATION + if (count > 1 && !uniform.isArray()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidUniformCount); + return false; + } + + *uniformOut = &uniform; + return true; +} + +bool ValidateUniform1ivValue(const Context *context, + angle::EntryPoint entryPoint, + GLenum uniformType, + GLsizei count, + const GLint *value) +{ + // Value type is GL_INT, because we only get here from glUniform1i{v}. + // It is compatible with INT or BOOL. + // Do these cheap tests first, for a little extra speed. + if (GL_INT == uniformType || GL_BOOL == uniformType) + { + return true; + } + + if (IsSamplerType(uniformType)) + { + // Check that the values are in range. + const GLint max = context->getCaps().maxCombinedTextureImageUnits; + for (GLsizei i = 0; i < count; ++i) + { + if (value[i] < 0 || value[i] >= max) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kSamplerUniformValueOutOfRange); + return false; + } + } + return true; + } + + context->validationError(entryPoint, GL_INVALID_OPERATION, kUniformTypeMismatch); + return false; +} + +bool ValidateUniformMatrixValue(const Context *context, + angle::EntryPoint entryPoint, + GLenum valueType, + GLenum uniformType) +{ + // Check that the value type is compatible with uniform type. + if (valueType == uniformType) + { + return true; + } + + context->validationError(entryPoint, GL_INVALID_OPERATION, kUniformTypeMismatch); + return false; +} + +bool ValidateUniform(const Context *context, + angle::EntryPoint entryPoint, + GLenum valueType, + UniformLocation location, + GLsizei count) +{ + const LinkedUniform *uniform = nullptr; + Program *programObject = context->getActiveLinkedProgram(); + return ValidateUniformCommonBase(context, entryPoint, programObject, location, count, + &uniform) && + ValidateUniformValue(context, entryPoint, valueType, uniform->type); +} + +bool ValidateUniform1iv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + const GLint *value) +{ + const LinkedUniform *uniform = nullptr; + Program *programObject = context->getActiveLinkedProgram(); + return ValidateUniformCommonBase(context, entryPoint, programObject, location, count, + &uniform) && + ValidateUniform1ivValue(context, entryPoint, uniform->type, count, value); +} + +bool ValidateUniformMatrix(const Context *context, + angle::EntryPoint entryPoint, + GLenum valueType, + UniformLocation location, + GLsizei count, + GLboolean transpose) +{ + if (ConvertToBool(transpose) && context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kES3Required); + return false; + } + + const LinkedUniform *uniform = nullptr; + Program *programObject = context->getActiveLinkedProgram(); + return ValidateUniformCommonBase(context, entryPoint, programObject, location, count, + &uniform) && + ValidateUniformMatrixValue(context, entryPoint, valueType, uniform->type); +} + +bool ValidateStateQuery(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLenum *nativeType, + unsigned int *numParams) +{ + if (!context->getQueryParameterInfo(pname, nativeType, numParams)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname); + return false; + } + + const Caps &caps = context->getCaps(); + + if (pname >= GL_DRAW_BUFFER0 && pname <= GL_DRAW_BUFFER15) + { + int colorAttachment = (pname - GL_DRAW_BUFFER0); + + if (colorAttachment >= caps.maxDrawBuffers) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kIndexExceedsMaxDrawBuffer); + return false; + } + } + + switch (pname) + { + case GL_TEXTURE_BINDING_2D: + case GL_TEXTURE_BINDING_CUBE_MAP: + case GL_TEXTURE_BINDING_3D: + case GL_TEXTURE_BINDING_2D_ARRAY: + case GL_TEXTURE_BINDING_2D_MULTISAMPLE: + break; + case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY: + if (!context->getExtensions().textureStorageMultisample2dArrayOES) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kMultisampleArrayExtensionRequired); + return false; + } + break; + case GL_TEXTURE_BINDING_RECTANGLE_ANGLE: + if (!context->getExtensions().textureRectangleANGLE) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + break; + case GL_TEXTURE_BINDING_EXTERNAL_OES: + if (!context->getExtensions().EGLStreamConsumerExternalNV && + !context->getExtensions().EGLImageExternalOES) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + break; + case GL_TEXTURE_BUFFER_BINDING: + case GL_TEXTURE_BINDING_BUFFER: + case GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT: + case GL_MAX_TEXTURE_BUFFER_SIZE: + if (context->getClientVersion() < Version(3, 2) && + !context->getExtensions().textureBufferAny()) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kTextureBufferExtensionNotAvailable); + return false; + } + break; + + case GL_IMPLEMENTATION_COLOR_READ_TYPE: + case GL_IMPLEMENTATION_COLOR_READ_FORMAT: + { + Framebuffer *readFramebuffer = context->getState().getReadFramebuffer(); + ASSERT(readFramebuffer); + + if (!ValidateFramebufferComplete(context, entryPoint, + readFramebuffer)) + { + return false; + } + + if (readFramebuffer->getReadBufferState() == GL_NONE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kReadBufferNone); + return false; + } + + const FramebufferAttachment *attachment = readFramebuffer->getReadColorAttachment(); + if (!attachment) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kReadBufferNotAttached); + return false; + } + } + break; + + case GL_PRIMITIVE_BOUNDING_BOX: + if (!context->getExtensions().primitiveBoundingBoxAny()) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled); + return false; + } + break; + + case GL_SHADING_RATE_QCOM: + if (!context->getExtensions().shadingRateQCOM) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled); + return false; + } + break; + + default: + break; + } + + // pname is valid, but there are no parameters to return + if (*numParams == 0) + { + return false; + } + + return true; +} + +bool ValidateGetBooleanvRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLboolean *params) +{ + GLenum nativeType; + unsigned int numParams = 0; + + if (!ValidateRobustStateQuery(context, entryPoint, pname, bufSize, &nativeType, &numParams)) + { + return false; + } + + SetRobustLengthParam(length, numParams); + + return true; +} + +bool ValidateGetFloatvRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLfloat *params) +{ + GLenum nativeType; + unsigned int numParams = 0; + + if (!ValidateRobustStateQuery(context, entryPoint, pname, bufSize, &nativeType, &numParams)) + { + return false; + } + + SetRobustLengthParam(length, numParams); + + return true; +} + +bool ValidateGetIntegervRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *data) +{ + GLenum nativeType; + unsigned int numParams = 0; + + if (!ValidateRobustStateQuery(context, entryPoint, pname, bufSize, &nativeType, &numParams)) + { + return false; + } + + SetRobustLengthParam(length, numParams); + + return true; +} + +bool ValidateGetInteger64vRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + GLint64 *data) +{ + GLenum nativeType; + unsigned int numParams = 0; + + if (!ValidateRobustStateQuery(context, entryPoint, pname, bufSize, &nativeType, &numParams)) + { + return false; + } + + if (nativeType == GL_INT_64_ANGLEX) + { + CastStateValues(context, nativeType, pname, numParams, data); + return false; + } + + SetRobustLengthParam(length, numParams); + return true; +} + +bool ValidateRobustStateQuery(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLsizei bufSize, + GLenum *nativeType, + unsigned int *numParams) +{ + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + if (!ValidateStateQuery(context, entryPoint, pname, nativeType, numParams)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, entryPoint, bufSize, *numParams)) + { + return false; + } + + return true; +} + +bool ValidateCopyImageSubDataTarget(const Context *context, + angle::EntryPoint entryPoint, + GLuint name, + GLenum target) +{ + // From EXT_copy_image: INVALID_ENUM is generated if either or is not + // RENDERBUFFER or a valid non - proxy texture target, is TEXTURE_BUFFER, or is one of the + // cubemap face selectors described in table 3.17, or if the target does not match the type of + // the object. INVALID_VALUE is generated if either or does not correspond + // to a valid renderbuffer or texture object according to the corresponding target parameter. + switch (target) + { + case GL_RENDERBUFFER: + { + RenderbufferID renderbuffer = PackParam(name); + if (!context->isRenderbuffer(renderbuffer)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidRenderbufferName); + return false; + } + break; + } + case GL_TEXTURE_2D: + case GL_TEXTURE_3D: + case GL_TEXTURE_2D_ARRAY: + case GL_TEXTURE_CUBE_MAP: + case GL_TEXTURE_CUBE_MAP_ARRAY_EXT: + { + TextureID texture = PackParam(name); + if (!context->isTexture(texture)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidTextureName); + return false; + } + + Texture *textureObject = context->getTexture(texture); + if (textureObject && textureObject->getType() != PackParam(target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, err::kTextureTypeMismatch); + return false; + } + break; + } + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTarget); + return false; + } + + return true; +} + +bool ValidateCopyImageSubDataLevel(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLint level) +{ + switch (target) + { + case GL_RENDERBUFFER: + { + if (level != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel); + return false; + } + break; + } + case GL_TEXTURE_2D: + case GL_TEXTURE_3D: + case GL_TEXTURE_2D_ARRAY: + case GL_TEXTURE_CUBE_MAP: + case GL_TEXTURE_CUBE_MAP_ARRAY_EXT: + { + if (!ValidMipLevel(context, PackParam(target), level)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel); + return false; + } + break; + } + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTarget); + return false; + } + + return true; +} + +bool ValidateCopyImageSubDataTargetRegion(const Context *context, + angle::EntryPoint entryPoint, + GLuint name, + GLenum target, + GLint level, + GLint offsetX, + GLint offsetY, + GLint offsetZ, + GLsizei width, + GLsizei height, + GLsizei *samples) +{ + // INVALID_VALUE is generated if the dimensions of the either subregion exceeds the boundaries + // of the corresponding image object. + if (offsetX < 0 || offsetY < 0 || offsetZ < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset); + return false; + } + + if (target == GL_RENDERBUFFER) + { + // INVALID_VALUE is generated if the dimensions of the either subregion exceeds the + // boundaries of the corresponding image object + Renderbuffer *buffer = context->getRenderbuffer(PackParam(name)); + if ((buffer->getWidth() - offsetX < width) || (buffer->getHeight() - offsetY < height)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kSourceTextureTooSmall); + return false; + } + } + else + { + Texture *texture = context->getTexture(PackParam(name)); + + // INVALID_OPERATION is generated if either object is a texture and the texture is not + // complete + // This will handle the texture completeness check. Note that this ignores format-based + // compleness rules. + if (!texture->isSamplerCompleteForCopyImage(context, nullptr)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kNotTextureComplete); + return false; + } + + GLenum textureTargetToUse = target; + if (target == GL_TEXTURE_CUBE_MAP) + { + // Use GL_TEXTURE_CUBE_MAP_POSITIVE_X to properly gather the textureWidth/textureHeight + textureTargetToUse = GL_TEXTURE_CUBE_MAP_POSITIVE_X; + } + + const GLsizei textureWidth = static_cast( + texture->getWidth(PackParam(textureTargetToUse), level)); + const GLsizei textureHeight = static_cast( + texture->getHeight(PackParam(textureTargetToUse), level)); + + // INVALID_VALUE is generated if the dimensions of the either subregion exceeds the + // boundaries of the corresponding image object + if ((textureWidth - offsetX < width) || (textureHeight - offsetY < height)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kSourceTextureTooSmall); + return false; + } + + *samples = texture->getSamples(PackParam(textureTargetToUse), level); + *samples = (*samples == 0) ? 1 : *samples; + } + + return true; +} + +bool ValidateCompressedRegion(const Context *context, + angle::EntryPoint entryPoint, + const InternalFormat &formatInfo, + GLsizei width, + GLsizei height) +{ + ASSERT(formatInfo.compressed); + + // INVALID_VALUE is generated if the image format is compressed and the dimensions of the + // subregion fail to meet the alignment constraints of the format. + if ((width % formatInfo.compressedBlockWidth != 0) || + (height % formatInfo.compressedBlockHeight != 0)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidCompressedRegionSize); + return false; + } + + return true; +} + +const InternalFormat &GetTargetFormatInfo(const Context *context, + angle::EntryPoint entryPoint, + GLuint name, + GLenum target, + GLint level) +{ + static const InternalFormat defaultInternalFormat; + + switch (target) + { + case GL_RENDERBUFFER: + { + Renderbuffer *buffer = context->getRenderbuffer(PackParam(name)); + return *buffer->getFormat().info; + } + case GL_TEXTURE_2D: + case GL_TEXTURE_3D: + case GL_TEXTURE_2D_ARRAY: + case GL_TEXTURE_CUBE_MAP: + case GL_TEXTURE_CUBE_MAP_ARRAY_EXT: + { + Texture *texture = context->getTexture(PackParam(name)); + GLenum textureTargetToUse = target; + + if (target == GL_TEXTURE_CUBE_MAP) + { + // Use GL_TEXTURE_CUBE_MAP_POSITIVE_X to properly gather the + // textureWidth/textureHeight + textureTargetToUse = GL_TEXTURE_CUBE_MAP_POSITIVE_X; + } + return *texture->getFormat(PackParam(textureTargetToUse), level).info; + } + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTarget); + return defaultInternalFormat; + } +} + +bool ValidateCopyMixedFormatCompatible(GLenum uncompressedFormat, GLenum compressedFormat) +{ + // Validates mixed format compatibility (uncompressed and compressed) from Table 4.X.1 of the + // EXT_copy_image spec. + switch (compressedFormat) + { + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + case GL_COMPRESSED_RED_GREEN_RGTC2_EXT: + case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT: + case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT: + case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT: + case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT: + case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT: + case GL_COMPRESSED_RGBA8_ETC2_EAC: + case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: + case GL_COMPRESSED_RG11_EAC: + case GL_COMPRESSED_SIGNED_RG11_EAC: + case GL_COMPRESSED_RGBA_ASTC_4x4_KHR: + case GL_COMPRESSED_RGBA_ASTC_5x4_KHR: + case GL_COMPRESSED_RGBA_ASTC_5x5_KHR: + case GL_COMPRESSED_RGBA_ASTC_6x5_KHR: + case GL_COMPRESSED_RGBA_ASTC_6x6_KHR: + case GL_COMPRESSED_RGBA_ASTC_8x5_KHR: + case GL_COMPRESSED_RGBA_ASTC_8x6_KHR: + case GL_COMPRESSED_RGBA_ASTC_8x8_KHR: + case GL_COMPRESSED_RGBA_ASTC_10x5_KHR: + case GL_COMPRESSED_RGBA_ASTC_10x6_KHR: + case GL_COMPRESSED_RGBA_ASTC_10x8_KHR: + case GL_COMPRESSED_RGBA_ASTC_10x10_KHR: + case GL_COMPRESSED_RGBA_ASTC_12x10_KHR: + case GL_COMPRESSED_RGBA_ASTC_12x12_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: + case GL_COMPRESSED_RGBA_ASTC_3x3x3_OES: + case GL_COMPRESSED_RGBA_ASTC_4x3x3_OES: + case GL_COMPRESSED_RGBA_ASTC_4x4x3_OES: + case GL_COMPRESSED_RGBA_ASTC_4x4x4_OES: + case GL_COMPRESSED_RGBA_ASTC_5x4x4_OES: + case GL_COMPRESSED_RGBA_ASTC_5x5x4_OES: + case GL_COMPRESSED_RGBA_ASTC_5x5x5_OES: + case GL_COMPRESSED_RGBA_ASTC_6x5x5_OES: + case GL_COMPRESSED_RGBA_ASTC_6x6x5_OES: + case GL_COMPRESSED_RGBA_ASTC_6x6x6_OES: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES: + { + switch (uncompressedFormat) + { + case GL_RGBA32UI: + case GL_RGBA32I: + case GL_RGBA32F: + return true; + default: + return false; + } + } + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + case GL_COMPRESSED_RED_RGTC1_EXT: + case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT: + case GL_COMPRESSED_RGB8_ETC2: + case GL_COMPRESSED_SRGB8_ETC2: + case GL_COMPRESSED_R11_EAC: + case GL_COMPRESSED_SIGNED_R11_EAC: + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + { + switch (uncompressedFormat) + { + case GL_RGBA16UI: + case GL_RGBA16I: + case GL_RGBA16F: + case GL_RG32UI: + case GL_RG32I: + case GL_RG32F: + return true; + default: + return false; + } + } + default: + break; + } + + return false; +} + +bool ValidateCopyCompressedFormatCompatible(const InternalFormat &srcFormatInfo, + const InternalFormat &dstFormatInfo) +{ + // Validates compressed format compatibility from Table 4.X.2 of the EXT_copy_image spec. + + ASSERT(srcFormatInfo.internalFormat != dstFormatInfo.internalFormat); + + const GLenum srcFormat = srcFormatInfo.internalFormat; + const GLenum dstFormat = dstFormatInfo.internalFormat; + + switch (srcFormat) + { + case GL_COMPRESSED_RED_RGTC1_EXT: + return (dstFormat == GL_COMPRESSED_SIGNED_RED_RGTC1_EXT); + case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT: + return (dstFormat == GL_COMPRESSED_RED_RGTC1_EXT); + case GL_COMPRESSED_RED_GREEN_RGTC2_EXT: + return (dstFormat == GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT); + case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT: + return (dstFormat == GL_COMPRESSED_RED_GREEN_RGTC2_EXT); + case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT: + return (dstFormat == GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT); + case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT: + return (dstFormat == GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT); + case GL_COMPRESSED_R11_EAC: + return (dstFormat == GL_COMPRESSED_SIGNED_R11_EAC); + case GL_COMPRESSED_SIGNED_R11_EAC: + return (dstFormat == GL_COMPRESSED_R11_EAC); + case GL_COMPRESSED_RG11_EAC: + return (dstFormat == GL_COMPRESSED_SIGNED_RG11_EAC); + case GL_COMPRESSED_SIGNED_RG11_EAC: + return (dstFormat == GL_COMPRESSED_RG11_EAC); + default: + break; + } + + // Since they can't be the same format and are both compressed formats, one must be linear and + // the other nonlinear. + if (srcFormatInfo.colorEncoding == dstFormatInfo.colorEncoding) + { + return false; + } + + const GLenum linearFormat = (srcFormatInfo.colorEncoding == GL_LINEAR) ? srcFormat : dstFormat; + const GLenum nonLinearFormat = + (srcFormatInfo.colorEncoding != GL_LINEAR) ? srcFormat : dstFormat; + + switch (linearFormat) + { + case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT: + return (nonLinearFormat == GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT); + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + return (nonLinearFormat == GL_COMPRESSED_SRGB_S3TC_DXT1_EXT); + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + return (nonLinearFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT); + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + return (nonLinearFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT); + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + return (nonLinearFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT); + case GL_COMPRESSED_RGB8_ETC2: + return (nonLinearFormat == GL_COMPRESSED_SRGB8_ETC2); + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + return (nonLinearFormat == GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2); + case GL_COMPRESSED_RGBA8_ETC2_EAC: + return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC); + case GL_COMPRESSED_RGBA_ASTC_4x4_KHR: + return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR); + case GL_COMPRESSED_RGBA_ASTC_5x4_KHR: + return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR); + case GL_COMPRESSED_RGBA_ASTC_5x5_KHR: + return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR); + case GL_COMPRESSED_RGBA_ASTC_6x5_KHR: + return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR); + case GL_COMPRESSED_RGBA_ASTC_6x6_KHR: + return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR); + case GL_COMPRESSED_RGBA_ASTC_8x5_KHR: + return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR); + case GL_COMPRESSED_RGBA_ASTC_8x6_KHR: + return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR); + case GL_COMPRESSED_RGBA_ASTC_8x8_KHR: + return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR); + case GL_COMPRESSED_RGBA_ASTC_10x5_KHR: + return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR); + case GL_COMPRESSED_RGBA_ASTC_10x6_KHR: + return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR); + case GL_COMPRESSED_RGBA_ASTC_10x8_KHR: + return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR); + case GL_COMPRESSED_RGBA_ASTC_10x10_KHR: + return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR); + case GL_COMPRESSED_RGBA_ASTC_12x10_KHR: + return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR); + case GL_COMPRESSED_RGBA_ASTC_12x12_KHR: + return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR); + case GL_COMPRESSED_RGBA_ASTC_3x3x3_OES: + return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES); + case GL_COMPRESSED_RGBA_ASTC_4x3x3_OES: + return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES); + case GL_COMPRESSED_RGBA_ASTC_4x4x3_OES: + return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES); + case GL_COMPRESSED_RGBA_ASTC_4x4x4_OES: + return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES); + case GL_COMPRESSED_RGBA_ASTC_5x4x4_OES: + return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES); + case GL_COMPRESSED_RGBA_ASTC_5x5x4_OES: + return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES); + case GL_COMPRESSED_RGBA_ASTC_5x5x5_OES: + return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES); + case GL_COMPRESSED_RGBA_ASTC_6x5x5_OES: + return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES); + case GL_COMPRESSED_RGBA_ASTC_6x6x5_OES: + return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES); + case GL_COMPRESSED_RGBA_ASTC_6x6x6_OES: + return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES); + default: + break; + } + + return false; +} + +bool ValidateCopyFormatCompatible(const InternalFormat &srcFormatInfo, + const InternalFormat &dstFormatInfo) +{ + // Matching source and destination formats are compatible. + if (srcFormatInfo.internalFormat == dstFormatInfo.internalFormat) + { + return true; + } + + if (srcFormatInfo.compressed != dstFormatInfo.compressed) + { + GLenum uncompressedFormat = (!srcFormatInfo.compressed) ? srcFormatInfo.internalFormat + : dstFormatInfo.internalFormat; + GLenum compressedFormat = (srcFormatInfo.compressed) ? srcFormatInfo.internalFormat + : dstFormatInfo.internalFormat; + + return ValidateCopyMixedFormatCompatible(uncompressedFormat, compressedFormat); + } + + if (!srcFormatInfo.compressed) + { + // Source and destination are uncompressed formats. + return (srcFormatInfo.pixelBytes == dstFormatInfo.pixelBytes); + } + + return ValidateCopyCompressedFormatCompatible(srcFormatInfo, dstFormatInfo); +} + +bool ValidateCopyImageSubDataBase(const Context *context, + angle::EntryPoint entryPoint, + GLuint srcName, + GLenum srcTarget, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLuint dstName, + GLenum dstTarget, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth) +{ + // INVALID_VALUE is generated if the dimensions of the either subregion exceeds the boundaries + // of the corresponding image object + if ((srcWidth < 0) || (srcHeight < 0) || (srcDepth < 0)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeSize); + return false; + } + + if (!ValidateCopyImageSubDataTarget(context, entryPoint, srcName, srcTarget)) + { + return false; + } + if (!ValidateCopyImageSubDataTarget(context, entryPoint, dstName, dstTarget)) + { + return false; + } + + if (!ValidateCopyImageSubDataLevel(context, entryPoint, srcTarget, srcLevel)) + { + return false; + } + if (!ValidateCopyImageSubDataLevel(context, entryPoint, dstTarget, dstLevel)) + { + return false; + } + + const InternalFormat &srcFormatInfo = + GetTargetFormatInfo(context, entryPoint, srcName, srcTarget, srcLevel); + const InternalFormat &dstFormatInfo = + GetTargetFormatInfo(context, entryPoint, dstName, dstTarget, dstLevel); + GLsizei dstWidth = srcWidth; + GLsizei dstHeight = srcHeight; + GLsizei srcSamples = 1; + GLsizei dstSamples = 1; + + if (srcFormatInfo.internalFormat == GL_NONE || dstFormatInfo.internalFormat == GL_NONE) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidTextureLevel); + return false; + } + + if (!ValidateCopyImageSubDataTargetRegion(context, entryPoint, srcName, srcTarget, srcLevel, + srcX, srcY, srcZ, srcWidth, srcHeight, &srcSamples)) + { + return false; + } + + // When copying from a compressed image to an uncompressed image the image texel dimensions + // written to the uncompressed image will be source extent divided by the compressed texel block + // dimensions. + if ((srcFormatInfo.compressed) && (!dstFormatInfo.compressed)) + { + ASSERT(srcFormatInfo.compressedBlockWidth != 0); + ASSERT(srcFormatInfo.compressedBlockHeight != 0); + + dstWidth /= srcFormatInfo.compressedBlockWidth; + dstHeight /= srcFormatInfo.compressedBlockHeight; + } + // When copying from an uncompressed image to a compressed image the image texel dimensions + // written to the compressed image will be the source extent multiplied by the compressed texel + // block dimensions. + else if ((!srcFormatInfo.compressed) && (dstFormatInfo.compressed)) + { + dstWidth *= dstFormatInfo.compressedBlockWidth; + dstHeight *= dstFormatInfo.compressedBlockHeight; + } + + if (!ValidateCopyImageSubDataTargetRegion(context, entryPoint, dstName, dstTarget, dstLevel, + dstX, dstY, dstZ, dstWidth, dstHeight, &dstSamples)) + { + return false; + } + + bool fillsEntireMip = false; + gl::Texture *dstTexture = context->getTexture({dstName}); + gl::TextureTarget dstTargetPacked = gl::PackParam(dstTarget); + // TODO(http://anglebug.com/5643): Some targets (e.g., GL_TEXTURE_CUBE_MAP, GL_RENDERBUFFER) are + // unsupported when used with compressed formats due to gl::PackParam() returning + // TextureTarget::InvalidEnum. + if (dstTargetPacked != gl::TextureTarget::InvalidEnum) + { + const gl::Extents &dstExtents = dstTexture->getExtents(dstTargetPacked, dstLevel); + fillsEntireMip = dstX == 0 && dstY == 0 && dstZ == 0 && srcWidth == dstExtents.width && + srcHeight == dstExtents.height && srcDepth == dstExtents.depth; + } + + if (srcFormatInfo.compressed && !fillsEntireMip && + !ValidateCompressedRegion(context, entryPoint, srcFormatInfo, srcWidth, srcHeight)) + { + return false; + } + + if (dstFormatInfo.compressed && !fillsEntireMip && + !ValidateCompressedRegion(context, entryPoint, dstFormatInfo, dstWidth, dstHeight)) + { + return false; + } + + // From EXT_copy_image: INVALID_OPERATION is generated if the source and destination formats + // are not compatible, if one image is compressed and the other is uncompressed and the block + // size of compressed image is not equal to the texel size of the compressed image. + if (!ValidateCopyFormatCompatible(srcFormatInfo, dstFormatInfo)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kIncompatibleTextures); + return false; + } + + // INVALID_OPERATION is generated if the source and destination number of samples do not match + if (srcSamples != dstSamples) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kSamplesOutOfRange); + return false; + } + + return true; +} + +bool ValidateCopyTexImageParametersBase(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum internalformat, + bool isSubImage, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border, + Format *textureFormatOut) +{ + TextureType texType = TextureTargetToType(target); + + if (xoffset < 0 || yoffset < 0 || zoffset < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset); + return false; + } + + if (width < 0 || height < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeSize); + return false; + } + + if (std::numeric_limits::max() - xoffset < width || + std::numeric_limits::max() - yoffset < height) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kOffsetOverflow); + return false; + } + + if (std::numeric_limits::max() - width < x || + std::numeric_limits::max() - height < y) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kIntegerOverflow); + return false; + } + + if (border != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidBorder); + return false; + } + + if (!ValidMipLevel(context, texType, level)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel); + return false; + } + + const State &state = context->getState(); + Framebuffer *readFramebuffer = state.getReadFramebuffer(); + if (!ValidateFramebufferComplete(context, entryPoint, readFramebuffer)) + { + return false; + } + + // checkReadBufferResourceSamples = true. Treat renderToTexture textures as single sample since + // they will be resolved before copying. + if (!readFramebuffer->isDefault() && + !ValidateFramebufferNotMultisampled(context, entryPoint, readFramebuffer, true)) + { + return false; + } + + if (readFramebuffer->getReadBufferState() == GL_NONE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kReadBufferNone); + return false; + } + + // WebGL 1.0 [Section 6.26] Reading From a Missing Attachment + // In OpenGL ES it is undefined what happens when an operation tries to read from a missing + // attachment and WebGL defines it to be an error. We do the check unconditionally as the + // situation is an application error that would lead to a crash in ANGLE. + const FramebufferAttachment *source = readFramebuffer->getReadColorAttachment(); + if (source == nullptr) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kMissingReadAttachment); + return false; + } + + if (source->isYUV()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kCopyFromYUVFramebuffer); + return false; + } + + // ANGLE_multiview spec, Revision 1: + // Calling CopyTexSubImage3D, CopyTexImage2D, or CopyTexSubImage2D will result in an + // INVALID_FRAMEBUFFER_OPERATION error if the multi-view layout of the current read framebuffer + // is FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of views in the current read + // framebuffer is more than one. + if (readFramebuffer->readDisallowedByMultiview()) + { + context->validationError(entryPoint, GL_INVALID_FRAMEBUFFER_OPERATION, + kMultiviewReadFramebuffer); + return false; + } + + const Caps &caps = context->getCaps(); + + GLint maxDimension = 0; + switch (texType) + { + case TextureType::_2D: + maxDimension = caps.max2DTextureSize; + break; + + case TextureType::CubeMap: + case TextureType::CubeMapArray: + maxDimension = caps.maxCubeMapTextureSize; + break; + + case TextureType::Rectangle: + maxDimension = caps.maxRectangleTextureSize; + break; + + case TextureType::_2DArray: + maxDimension = caps.max2DTextureSize; + break; + + case TextureType::_3D: + maxDimension = caps.max3DTextureSize; + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + + Texture *texture = state.getTargetTexture(texType); + if (!texture) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kTextureNotBound); + return false; + } + + if (texture->getImmutableFormat() && !isSubImage) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kTextureIsImmutable); + return false; + } + + const InternalFormat &formatInfo = + isSubImage ? *texture->getFormat(target, level).info + : GetInternalFormatInfo(internalformat, GL_UNSIGNED_BYTE); + + if (formatInfo.depthBits > 0 || formatInfo.compressed) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat); + return false; + } + + if (isSubImage) + { + if (static_cast(xoffset + width) > texture->getWidth(target, level) || + static_cast(yoffset + height) > texture->getHeight(target, level) || + static_cast(zoffset) >= texture->getDepth(target, level)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kOffsetOverflow); + return false; + } + } + else + { + if ((texType == TextureType::CubeMap || texType == TextureType::CubeMapArray) && + width != height) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kCubemapIncomplete); + return false; + } + + if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions())) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, + internalformat); + return false; + } + + int maxLevelDimension = (maxDimension >> level); + if (static_cast(width) > maxLevelDimension || + static_cast(height) > maxLevelDimension) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize); + return false; + } + } + + // Do not leak the previous texture format for non-subImage case. + if (textureFormatOut && isSubImage) + { + *textureFormatOut = texture->getFormat(target, level); + } + + // Detect texture copying feedback loops for WebGL. + if (context->isWebGL()) + { + if (readFramebuffer->formsCopyingFeedbackLoopWith(texture->id(), level, zoffset)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kFeedbackLoop); + return false; + } + } + + return true; +} + +const char *ValidateProgramPipelineDrawStates(const Context *context, + const Extensions &extensions, + ProgramPipeline *programPipeline) +{ + for (const ShaderType shaderType : gl::AllShaderTypes()) + { + Program *program = programPipeline->getShaderProgram(shaderType); + if (program) + { + const char *errorMsg = ValidateProgramDrawStates(context, extensions, program); + if (errorMsg) + { + return errorMsg; + } + } + } + + return nullptr; +} + +const char *ValidateProgramPipelineAttachedPrograms(ProgramPipeline *programPipeline) +{ + // An INVALID_OPERATION error is generated by any command that transfers vertices to the + // GL or launches compute work if the current set of active + // program objects cannot be executed, for reasons including: + // - There is no current program object specified by UseProgram, there is a current program + // pipeline object, and that object is empty (no executable code is installed for any stage). + // - A program object is active for at least one, but not all of the shader + // stages that were present when the program was linked. + if (!programPipeline->getExecutable().getLinkedShaderStages().any()) + { + return gl::err::kNoExecutableCodeInstalled; + } + for (const ShaderType shaderType : gl::AllShaderTypes()) + { + Program *shaderProgram = programPipeline->getShaderProgram(shaderType); + if (shaderProgram) + { + ProgramExecutable &executable = shaderProgram->getExecutable(); + for (const ShaderType programShaderType : executable.getLinkedShaderStages()) + { + if (shaderProgram != programPipeline->getShaderProgram(programShaderType)) + { + return gl::err::kNotAllStagesOfSeparableProgramUsed; + } + } + } + } + + // [EXT_geometry_shader] Section 11.1.gs Geometry Shaders + // A non-separable program object or program pipeline object that includes + // a geometry shader must also include a vertex shader. + // An INVALID_OPERATION error is generated by any command that transfers + // vertices to the GL if the current program state has a geometry shader + // but no vertex shader. + if (!programPipeline->getShaderProgram(ShaderType::Vertex) && + programPipeline->getShaderProgram(ShaderType::Geometry)) + { + return gl::err::kNoActiveGraphicsShaderStage; + } + + return nullptr; +} + +// Note all errors returned from this function are INVALID_OPERATION except for the draw framebuffer +// completeness check. +const char *ValidateDrawStates(const Context *context) +{ + const Extensions &extensions = context->getExtensions(); + const State &state = context->getState(); + + // WebGL buffers cannot be mapped/unmapped because the MapBufferRange, FlushMappedBufferRange, + // and UnmapBuffer entry points are removed from the WebGL 2.0 API. + // https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.14 + VertexArray *vertexArray = state.getVertexArray(); + ASSERT(vertexArray); + + if (!extensions.webglCompatibilityANGLE && vertexArray->hasInvalidMappedArrayBuffer()) + { + return kBufferMapped; + } + + // Note: these separate values are not supported in WebGL, due to D3D's limitations. See + // Section 6.10 of the WebGL 1.0 spec. + Framebuffer *framebuffer = state.getDrawFramebuffer(); + ASSERT(framebuffer); + + if (context->getLimitations().noSeparateStencilRefsAndMasks || + extensions.webglCompatibilityANGLE) + { + ASSERT(framebuffer); + const FramebufferAttachment *dsAttachment = + framebuffer->getStencilOrDepthStencilAttachment(); + const GLuint stencilBits = dsAttachment ? dsAttachment->getStencilSize() : 0; + ASSERT(stencilBits <= 8); + + const DepthStencilState &depthStencilState = state.getDepthStencilState(); + if (depthStencilState.stencilTest && stencilBits > 0) + { + GLuint maxStencilValue = (1 << stencilBits) - 1; + + bool differentRefs = + clamp(state.getStencilRef(), 0, static_cast(maxStencilValue)) != + clamp(state.getStencilBackRef(), 0, static_cast(maxStencilValue)); + bool differentWritemasks = (depthStencilState.stencilWritemask & maxStencilValue) != + (depthStencilState.stencilBackWritemask & maxStencilValue); + bool differentMasks = (depthStencilState.stencilMask & maxStencilValue) != + (depthStencilState.stencilBackMask & maxStencilValue); + + if (differentRefs || differentWritemasks || differentMasks) + { + if (!extensions.webglCompatibilityANGLE) + { + WARN() << "This ANGLE implementation does not support separate front/back " + "stencil writemasks, reference values, or stencil mask values."; + } + return kStencilReferenceMaskOrMismatch; + } + } + } + + if (!extensions.floatBlendEXT) + { + const DrawBufferMask blendEnabledActiveFloat32ColorAttachmentDrawBufferMask = + state.getBlendEnabledDrawBufferMask() & + framebuffer->getActiveFloat32ColorAttachmentDrawBufferMask(); + if (blendEnabledActiveFloat32ColorAttachmentDrawBufferMask.any()) + { + return kUnsupportedFloatBlending; + } + } + + if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc || + extensions.webglCompatibilityANGLE) + { + if (state.hasSimultaneousConstantColorAndAlphaBlendFunc()) + { + if (extensions.webglCompatibilityANGLE) + { + return kInvalidConstantColor; + } + + WARN() << kConstantColorAlphaLimitation; + return kConstantColorAlphaLimitation; + } + } + + if (!framebuffer->isComplete(context)) + { + // Note: this error should be generated as INVALID_FRAMEBUFFER_OPERATION. + return kDrawFramebufferIncomplete; + } + + bool framebufferIsYUV = framebuffer->hasYUVAttachment(); + if (framebufferIsYUV) + { + const BlendState &blendState = state.getBlendState(); + if (!blendState.colorMaskRed || !blendState.colorMaskGreen || !blendState.colorMaskBlue) + { + // When rendering into a YUV framebuffer, the color mask must have r g and b set to + // true. + return kInvalidColorMaskForYUV; + } + + if (blendState.blend) + { + // When rendering into a YUV framebuffer, blending must be disabled. + return kInvalidBlendStateForYUV; + } + } + else + { + if (framebuffer->hasExternalTextureAttachment()) + { + // It is an error to render into an external texture that is not YUV. + return kExternalTextureAttachmentNotYUV; + } + } + + // Advanced blend equation can only be enabled for a single render target. + const BlendStateExt &blendStateExt = state.getBlendStateExt(); + if (blendStateExt.getUsesAdvancedBlendEquationMask().any()) + { + const size_t drawBufferCount = framebuffer->getDrawbufferStateCount(); + uint32_t advancedBlendRenderTargetCount = 0; + + for (size_t drawBufferIndex : blendStateExt.getUsesAdvancedBlendEquationMask()) + { + if (drawBufferIndex < drawBufferCount && + framebuffer->getDrawBufferState(drawBufferIndex) != GL_NONE && + blendStateExt.getEnabledMask().test(drawBufferIndex) && + blendStateExt.getUsesAdvancedBlendEquationMask().test(drawBufferIndex)) + { + ++advancedBlendRenderTargetCount; + } + } + + if (advancedBlendRenderTargetCount > 1) + { + return kAdvancedBlendEquationWithMRT; + } + } + + if (context->getStateCache().hasAnyEnabledClientAttrib()) + { + if (extensions.webglCompatibilityANGLE || !state.areClientArraysEnabled()) + { + // [WebGL 1.0] Section 6.5 Enabled Vertex Attributes and Range Checking + // If a vertex attribute is enabled as an array via enableVertexAttribArray but no + // buffer is bound to that attribute via bindBuffer and vertexAttribPointer, then calls + // to drawArrays or drawElements will generate an INVALID_OPERATION error. + return kVertexArrayNoBuffer; + } + + if (state.getVertexArray()->hasEnabledNullPointerClientArray()) + { + // This is an application error that would normally result in a crash, but we catch it + // and return an error + return kVertexArrayNoBufferPointer; + } + } + + // If we are running GLES1, there is no current program. + if (context->getClientVersion() >= Version(2, 0)) + { + Program *program = state.getLinkedProgram(context); + ProgramPipeline *programPipeline = state.getLinkedProgramPipeline(context); + const ProgramExecutable *executable = state.getProgramExecutable(); + + bool programIsYUVOutput = false; + + if (program) + { + const char *errorMsg = ValidateProgramDrawStates(context, extensions, program); + if (errorMsg) + { + return errorMsg; + } + + programIsYUVOutput = executable->isYUVOutput(); + } + else if (programPipeline) + { + const char *errorMsg = ValidateProgramPipelineAttachedPrograms(programPipeline); + if (errorMsg) + { + return errorMsg; + } + + errorMsg = ValidateProgramPipelineDrawStates(context, extensions, programPipeline); + if (errorMsg) + { + return errorMsg; + } + + if (!programPipeline->isLinked()) + { + return kProgramPipelineLinkFailed; + } + + programIsYUVOutput = executable->isYUVOutput(); + } + + if (executable) + { + if (!executable->validateSamplers(nullptr, context->getCaps())) + { + return kTextureTypeConflict; + } + + if (executable->hasLinkedTessellationShader()) + { + if (!executable->hasLinkedShaderStage(ShaderType::Vertex)) + { + return kTessellationShaderRequiresVertexShader; + } + + if (!executable->hasLinkedShaderStage(ShaderType::TessControl) || + !executable->hasLinkedShaderStage(ShaderType::TessEvaluation)) + { + return kTessellationShaderRequiresBothControlAndEvaluation; + } + } + + if (state.isTransformFeedbackActive()) + { + if (!ValidateProgramExecutableXFBBuffersPresent(context, executable)) + { + return kTransformFeedbackBufferMissing; + } + } + } + + if (programIsYUVOutput != framebufferIsYUV) + { + // Both the program and framebuffer must match in YUV output state. + return kYUVOutputMissmatch; + } + + if (!state.validateSamplerFormats()) + { + return kSamplerFormatMismatch; + } + + // Do some additional WebGL-specific validation + if (extensions.webglCompatibilityANGLE) + { + const TransformFeedback *transformFeedbackObject = state.getCurrentTransformFeedback(); + if (state.isTransformFeedbackActive() && + transformFeedbackObject->buffersBoundForOtherUseInWebGL()) + { + return kTransformFeedbackBufferDoubleBound; + } + + // Detect rendering feedback loops for WebGL. + if (framebuffer->formsRenderingFeedbackLoopWith(context)) + { + return kFeedbackLoop; + } + + // Detect that the vertex shader input types match the attribute types + if (!ValidateVertexShaderAttributeTypeMatch(context)) + { + return kVertexShaderTypeMismatch; + } + + if (!context->getState().getRasterizerState().rasterizerDiscard && + !context->getState().allActiveDrawBufferChannelsMasked()) + { + // Detect that if there's active color buffer without fragment shader output + if (!ValidateFragmentShaderColorBufferMaskMatch(context)) + { + return kDrawBufferMaskMismatch; + } + + // Detect that the color buffer types match the fragment shader output types + if (!ValidateFragmentShaderColorBufferTypeMatch(context)) + { + return kDrawBufferTypeMismatch; + } + } + + const VertexArray *vao = context->getState().getVertexArray(); + if (vao->hasTransformFeedbackBindingConflict(context)) + { + return kVertexBufferBoundForTransformFeedback; + } + + // Validate that we are rendering with a linked program. + if (!program->isLinked()) + { + return kProgramNotLinked; + } + } + } + + return nullptr; +} + +const char *ValidateProgramPipeline(const Context *context) +{ + const State &state = context->getState(); + // If we are running GLES1, there is no current program. + if (context->getClientVersion() >= Version(2, 0)) + { + ProgramPipeline *programPipeline = state.getProgramPipeline(); + if (programPipeline) + { + const char *errorMsg = ValidateProgramPipelineAttachedPrograms(programPipeline); + if (errorMsg) + { + return errorMsg; + } + } + } + return nullptr; +} + +void RecordDrawModeError(const Context *context, angle::EntryPoint entryPoint, PrimitiveMode mode) +{ + const State &state = context->getState(); + TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback(); + if (state.isTransformFeedbackActiveUnpaused()) + { + if (!ValidateTransformFeedbackPrimitiveMode(context, entryPoint, + curTransformFeedback->getPrimitiveMode(), mode)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInvalidDrawModeTransformFeedback); + return; + } + } + + const Extensions &extensions = context->getExtensions(); + + switch (mode) + { + case PrimitiveMode::Points: + case PrimitiveMode::Lines: + case PrimitiveMode::LineLoop: + case PrimitiveMode::LineStrip: + case PrimitiveMode::Triangles: + case PrimitiveMode::TriangleStrip: + case PrimitiveMode::TriangleFan: + break; + + case PrimitiveMode::LinesAdjacency: + case PrimitiveMode::LineStripAdjacency: + case PrimitiveMode::TrianglesAdjacency: + case PrimitiveMode::TriangleStripAdjacency: + if (!extensions.geometryShaderAny() && context->getClientVersion() < ES_3_2) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kGeometryShaderExtensionNotEnabled); + return; + } + break; + + case PrimitiveMode::Patches: + if (!extensions.tessellationShaderEXT && context->getClientVersion() < ES_3_2) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kTessellationShaderExtensionNotEnabled); + return; + } + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidDrawMode); + return; + } + + // If we are running GLES1, there is no current program. + if (context->getClientVersion() >= Version(2, 0)) + { + const ProgramExecutable *executable = state.getProgramExecutable(); + ASSERT(executable); + + // Do geometry shader specific validations + if (executable->hasLinkedShaderStage(ShaderType::Geometry)) + { + if (!IsCompatibleDrawModeWithGeometryShader( + mode, executable->getGeometryShaderInputPrimitiveType())) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kIncompatibleDrawModeAgainstGeometryShader); + return; + } + } + + if (executable->hasLinkedTessellationShader() && mode != PrimitiveMode::Patches) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kIncompatibleDrawModeWithTessellationShader); + return; + } + + if (!executable->hasLinkedTessellationShader() && mode == PrimitiveMode::Patches) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kIncompatibleDrawModeWithoutTessellationShader); + return; + } + } + + // An error should be recorded. + UNREACHABLE(); +} + +bool ValidateDrawArraysInstancedANGLE(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLint first, + GLsizei count, + GLsizei primcount) +{ + if (!context->getExtensions().instancedArraysANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (!ValidateDrawArraysInstancedBase(context, entryPoint, mode, first, count, primcount)) + { + return false; + } + + return ValidateDrawInstancedANGLE(context, entryPoint); +} + +bool ValidateDrawArraysInstancedEXT(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLint first, + GLsizei count, + GLsizei primcount) +{ + if (!context->getExtensions().instancedArraysEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (!ValidateDrawArraysInstancedBase(context, entryPoint, mode, first, count, primcount)) + { + return false; + } + + return true; +} + +const char *ValidateDrawElementsStates(const Context *context) +{ + const State &state = context->getState(); + + if (context->getStateCache().isTransformFeedbackActiveUnpaused()) + { + // EXT_geometry_shader allows transform feedback to work with all draw commands. + // [EXT_geometry_shader] Section 12.1, "Transform Feedback" + if (!context->getExtensions().geometryShaderAny() && context->getClientVersion() < ES_3_2) + { + // It is an invalid operation to call DrawElements, DrawRangeElements or + // DrawElementsInstanced while transform feedback is active, (3.0.2, section 2.14, pg + // 86) + return kUnsupportedDrawModeForTransformFeedback; + } + } + + const VertexArray *vao = state.getVertexArray(); + Buffer *elementArrayBuffer = vao->getElementArrayBuffer(); + + if (elementArrayBuffer) + { + if (elementArrayBuffer->hasWebGLXFBBindingConflict(context->isWebGL())) + { + return kElementArrayBufferBoundForTransformFeedback; + } + if (elementArrayBuffer->isMapped() && + (!elementArrayBuffer->isImmutable() || + (elementArrayBuffer->getAccessFlags() & GL_MAP_PERSISTENT_BIT_EXT) == 0)) + { + return kBufferMapped; + } + } + else + { + // [WebGL 1.0] Section 6.2 No Client Side Arrays + // If an indexed draw command (drawElements) is called and no WebGLBuffer is bound to + // the ELEMENT_ARRAY_BUFFER binding point, an INVALID_OPERATION error is generated. + if (!context->getState().areClientArraysEnabled() || context->isWebGL()) + { + return kMustHaveElementArrayBinding; + } + } + + return nullptr; +} + +bool ValidateDrawElementsInstancedANGLE(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLsizei count, + DrawElementsType type, + const void *indices, + GLsizei primcount) +{ + if (!context->getExtensions().instancedArraysANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (!ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices, + primcount)) + { + return false; + } + + return ValidateDrawInstancedANGLE(context, entryPoint); +} + +bool ValidateDrawElementsInstancedEXT(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLsizei count, + DrawElementsType type, + const void *indices, + GLsizei primcount) +{ + if (!context->getExtensions().instancedArraysEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (!ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices, + primcount)) + { + return false; + } + + return true; +} + +bool ValidateGetUniformBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location) +{ + if (program.value == 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kProgramDoesNotExist); + return false; + } + + Program *programObject = GetValidProgram(context, entryPoint, program); + if (!programObject) + { + return false; + } + + if (!programObject || !programObject->isLinked()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked); + return false; + } + + if (!programObject->isValidUniformLocation(location)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidUniformLocation); + return false; + } + + return true; +} + +bool ValidateSizedGetUniform(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + GLsizei *length) +{ + if (length) + { + *length = 0; + } + + if (!ValidateGetUniformBase(context, entryPoint, program, location)) + { + return false; + } + + if (bufSize < 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kNegativeBufferSize); + return false; + } + + Program *programObject = context->getProgramResolveLink(program); + ASSERT(programObject); + + // sized queries -- ensure the provided buffer is large enough + const LinkedUniform &uniform = programObject->getUniformByLocation(location); + size_t requiredBytes = VariableExternalSize(uniform.type); + if (static_cast(bufSize) < requiredBytes) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInsufficientBufferSize); + return false; + } + + if (length) + { + *length = VariableComponentCount(uniform.type); + } + return true; +} + +bool ValidateGetnUniformfvEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + const GLfloat *params) +{ + return ValidateSizedGetUniform(context, entryPoint, program, location, bufSize, nullptr); +} + +bool ValidateGetnUniformfvRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + const GLsizei *length, + const GLfloat *params) +{ + UNIMPLEMENTED(); + return false; +} + +bool ValidateGetnUniformivEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + const GLint *params) +{ + return ValidateSizedGetUniform(context, entryPoint, program, location, bufSize, nullptr); +} + +bool ValidateGetnUniformivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + const GLsizei *length, + const GLint *params) +{ + UNIMPLEMENTED(); + return false; +} + +bool ValidateGetnUniformuivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + const GLsizei *length, + const GLuint *params) +{ + UNIMPLEMENTED(); + return false; +} + +bool ValidateGetUniformfvRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + const GLsizei *length, + const GLfloat *params) +{ + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + GLsizei writeLength = 0; + + // bufSize is validated in ValidateSizedGetUniform + if (!ValidateSizedGetUniform(context, entryPoint, program, location, bufSize, &writeLength)) + { + return false; + } + + SetRobustLengthParam(length, writeLength); + + return true; +} + +bool ValidateGetUniformivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + const GLsizei *length, + const GLint *params) +{ + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + GLsizei writeLength = 0; + + // bufSize is validated in ValidateSizedGetUniform + if (!ValidateSizedGetUniform(context, entryPoint, program, location, bufSize, &writeLength)) + { + return false; + } + + SetRobustLengthParam(length, writeLength); + + return true; +} + +bool ValidateGetUniformuivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + const GLsizei *length, + const GLuint *params) +{ + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + GLsizei writeLength = 0; + + // bufSize is validated in ValidateSizedGetUniform + if (!ValidateSizedGetUniform(context, entryPoint, program, location, bufSize, &writeLength)) + { + return false; + } + + SetRobustLengthParam(length, writeLength); + + return true; +} + +bool ValidateDiscardFramebufferBase(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLsizei numAttachments, + const GLenum *attachments, + bool defaultFramebuffer) +{ + if (numAttachments < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeAttachments); + return false; + } + + for (GLsizei i = 0; i < numAttachments; ++i) + { + if (attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT31) + { + if (defaultFramebuffer) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kDefaultFramebufferInvalidAttachment); + return false; + } + + if (attachments[i] >= + GL_COLOR_ATTACHMENT0 + static_cast(context->getCaps().maxColorAttachments)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kExceedsMaxColorAttachments); + return false; + } + } + else + { + switch (attachments[i]) + { + case GL_DEPTH_ATTACHMENT: + case GL_STENCIL_ATTACHMENT: + case GL_DEPTH_STENCIL_ATTACHMENT: + if (defaultFramebuffer) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kDefaultFramebufferInvalidAttachment); + return false; + } + break; + case GL_COLOR: + case GL_DEPTH: + case GL_STENCIL: + if (!defaultFramebuffer) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kDefaultFramebufferAttachmentOnUserFBO); + return false; + } + break; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidAttachment); + return false; + } + } + } + + return true; +} + +bool ValidateInsertEventMarkerEXT(const Context *context, + angle::EntryPoint entryPoint, + GLsizei length, + const char *marker) +{ + if (!context->getExtensions().debugMarkerEXT) + { + // The debug marker calls should not set error state + // However, it seems reasonable to set an error state if the extension is not enabled + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + // Note that debug marker calls must not set error state + if (length < 0) + { + return false; + } + + if (marker == nullptr) + { + return false; + } + + return true; +} + +bool ValidatePushGroupMarkerEXT(const Context *context, + angle::EntryPoint entryPoint, + GLsizei length, + const char *marker) +{ + if (!context->getExtensions().debugMarkerEXT) + { + // The debug marker calls should not set error state + // However, it seems reasonable to set an error state if the extension is not enabled + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + // Note that debug marker calls must not set error state + if (length < 0) + { + return false; + } + + if (length > 0 && marker == nullptr) + { + return false; + } + + return true; +} + +bool ValidateEGLImageObject(const Context *context, + angle::EntryPoint entryPoint, + TextureType type, + GLeglImageOES image) +{ + egl::Image *imageObject = static_cast(image); + + ASSERT(context->getDisplay()); + if (!context->getDisplay()->isValidImage(imageObject)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidEGLImage); + return false; + } + + if (imageObject->getSamples() > 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kEGLImageCannotCreate2DMultisampled); + return false; + } + + if (!imageObject->isTexturable(context)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kEGLImageTextureFormatNotSupported); + return false; + } + + // Validate source egl image and target texture are compatible + size_t depth = static_cast(imageObject->getExtents().depth); + if (imageObject->isYUV() && type != TextureType::External) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + "Image is YUV, target must be TEXTURE_EXTERNAL_OES"); + return false; + } + + if (depth > 1 && type != TextureType::_2DArray && type != TextureType::CubeMap && + type != TextureType::CubeMapArray && type != TextureType::_3D) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kEGLImageTextureTargetMismatch); + return false; + } + + if (imageObject->isCubeMap() && type != TextureType::CubeMapArray && + (type != TextureType::CubeMap || depth > gl::kCubeFaceCount)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kEGLImageTextureTargetMismatch); + return false; + } + + if (imageObject->getLevelCount() > 1 && type == TextureType::External) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kEGLImageTextureTargetMismatch); + return false; + } + + // 3d EGLImages are currently not supported + if (type == TextureType::_3D) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kEGLImageTextureTargetMismatch); + return false; + } + + if (imageObject->hasProtectedContent() && !context->getState().hasProtectedContent()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + "Mismatch between Image and Context Protected Content state"); + return false; + } + + return true; +} + +bool ValidateEGLImageTargetTexture2DOES(const Context *context, + angle::EntryPoint entryPoint, + TextureType type, + GLeglImageOES image) +{ + if (!context->getExtensions().EGLImageOES && !context->getExtensions().EGLImageExternalOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + switch (type) + { + case TextureType::_2D: + if (!context->getExtensions().EGLImageOES) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, + ToGLenum(type)); + } + break; + + case TextureType::_2DArray: + if (!context->getExtensions().EGLImageArrayEXT) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, + ToGLenum(type)); + } + break; + + case TextureType::External: + if (!context->getExtensions().EGLImageExternalOES) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, + ToGLenum(type)); + } + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + + return ValidateEGLImageObject(context, entryPoint, type, image); +} + +bool ValidateEGLImageTargetRenderbufferStorageOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLeglImageOES image) +{ + if (!context->getExtensions().EGLImageOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + switch (target) + { + case GL_RENDERBUFFER: + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidRenderbufferTarget); + return false; + } + + egl::Image *imageObject = static_cast(image); + + ASSERT(context->getDisplay()); + if (!context->getDisplay()->isValidImage(imageObject)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidEGLImage); + return false; + } + + if (!imageObject->isRenderable(context)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kEGLImageRenderbufferFormatNotSupported); + return false; + } + + if (imageObject->hasProtectedContent() != context->getState().hasProtectedContent()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + "Mismatch between Image and Context Protected Content state"); + return false; + } + + return true; +} + +bool ValidateProgramBinaryBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLenum binaryFormat, + const void *binary, + GLint length) +{ + Program *programObject = GetValidProgram(context, entryPoint, program); + if (programObject == nullptr) + { + return false; + } + + const std::vector &programBinaryFormats = context->getCaps().programBinaryFormats; + if (std::find(programBinaryFormats.begin(), programBinaryFormats.end(), binaryFormat) == + programBinaryFormats.end()) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidProgramBinaryFormat); + return false; + } + + if (context->hasActiveTransformFeedback(program)) + { + // ES 3.0.4 section 2.15 page 91 + context->validationError(entryPoint, GL_INVALID_OPERATION, kTransformFeedbackProgramBinary); + return false; + } + + return true; +} + +bool ValidateGetProgramBinaryBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLsizei bufSize, + const GLsizei *length, + const GLenum *binaryFormat, + const void *binary) +{ + Program *programObject = GetValidProgram(context, entryPoint, program); + if (programObject == nullptr) + { + return false; + } + + if (!programObject->isLinked()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked); + return false; + } + + if (context->getCaps().programBinaryFormats.empty()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kNoProgramBinaryFormats); + return false; + } + + return true; +} + +bool ValidateDrawBuffersBase(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const GLenum *bufs) +{ + // INVALID_VALUE is generated if n is negative or greater than value of MAX_DRAW_BUFFERS + if (n < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeCount); + return false; + } + if (n > context->getCaps().maxDrawBuffers) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer); + return false; + } + + ASSERT(context->getState().getDrawFramebuffer()); + FramebufferID frameBufferId = context->getState().getDrawFramebuffer()->id(); + GLuint maxColorAttachment = GL_COLOR_ATTACHMENT0_EXT + context->getCaps().maxColorAttachments; + + // This should come first before the check for the default frame buffer + // because when we switch to ES3.1+, invalid enums will return INVALID_ENUM + // rather than INVALID_OPERATION + for (int colorAttachment = 0; colorAttachment < n; colorAttachment++) + { + const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment; + + if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != GL_BACK && + (bufs[colorAttachment] < GL_COLOR_ATTACHMENT0 || + bufs[colorAttachment] > GL_COLOR_ATTACHMENT31)) + { + // Value in bufs is not NONE, BACK, or GL_COLOR_ATTACHMENTi + // The 3.0.4 spec says to generate GL_INVALID_OPERATION here, but this + // was changed to GL_INVALID_ENUM in 3.1, which dEQP also expects. + // 3.1 is still a bit ambiguous about the error, but future specs are + // expected to clarify that GL_INVALID_ENUM is the correct error. + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidDrawBuffer); + return false; + } + else if (bufs[colorAttachment] >= maxColorAttachment) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExceedsMaxColorAttachments); + return false; + } + else if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment && + frameBufferId.value != 0) + { + // INVALID_OPERATION-GL is bound to buffer and ith argument + // is not COLOR_ATTACHMENTi or NONE + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidDrawBufferValue); + return false; + } + } + + // INVALID_OPERATION is generated if GL is bound to the default framebuffer + // and n is not 1 or bufs is bound to value other than BACK and NONE + if (frameBufferId.value == 0) + { + if (n != 1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInvalidDrawBufferCountForDefault); + return false; + } + + if (bufs[0] != GL_NONE && bufs[0] != GL_BACK) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kDefaultFramebufferInvalidDrawBuffer); + return false; + } + } + + return true; +} + +bool ValidateGetBufferPointervBase(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding target, + GLenum pname, + GLsizei *length, + void *const *params) +{ + if (length) + { + *length = 0; + } + + if (!context->isValidBufferBinding(target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBufferTypes); + return false; + } + + switch (pname) + { + case GL_BUFFER_MAP_POINTER: + break; + + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + + // GLES 3.0 section 2.10.1: "Attempts to attempts to modify or query buffer object state for a + // target bound to zero generate an INVALID_OPERATION error." + // GLES 3.1 section 6.6 explicitly specifies this error. + if (context->getState().getTargetBuffer(target) == nullptr) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferPointerNotAvailable); + return false; + } + + if (length) + { + *length = 1; + } + + return true; +} + +bool ValidateUnmapBufferBase(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding target) +{ + if (!context->isValidBufferBinding(target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBufferTypes); + return false; + } + + Buffer *buffer = context->getState().getTargetBuffer(target); + + if (buffer == nullptr || !buffer->isMapped()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferNotMapped); + return false; + } + + return true; +} + +bool ValidateMapBufferRangeBase(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding target, + GLintptr offset, + GLsizeiptr length, + GLbitfield access) +{ + if (!context->isValidBufferBinding(target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBufferTypes); + return false; + } + + if (offset < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset); + return false; + } + + if (length < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeLength); + return false; + } + + Buffer *buffer = context->getState().getTargetBuffer(target); + + if (!buffer) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferNotMappable); + return false; + } + + // Check for buffer overflow + CheckedNumeric checkedOffset(offset); + auto checkedSize = checkedOffset + length; + + if (!checkedSize.IsValid() || checkedSize.ValueOrDie() > static_cast(buffer->getSize())) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kMapOutOfRange); + return false; + } + + // Check for invalid bits in the mask + constexpr GLbitfield kAllAccessBits = + GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | + GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_UNSYNCHRONIZED_BIT; + + if (buffer->isImmutable()) + { + // GL_EXT_buffer_storage's additions to glMapBufferRange + constexpr GLbitfield kBufferStorageAccessBits = + kAllAccessBits | GL_MAP_PERSISTENT_BIT_EXT | GL_MAP_COHERENT_BIT_EXT; + + if ((access & ~kBufferStorageAccessBits) != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidAccessBits); + return false; + } + + // It is invalid if any of bufferStorageMatchedAccessBits bits are included in access, + // but the same bits are not included in the buffer's storage flags + constexpr GLbitfield kBufferStorageMatchedAccessBits = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | + GL_MAP_PERSISTENT_BIT_EXT | + GL_MAP_COHERENT_BIT_EXT; + GLbitfield accessFlags = access & kBufferStorageMatchedAccessBits; + if ((accessFlags & buffer->getStorageExtUsageFlags()) != accessFlags) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidAccessBits); + return false; + } + } + else if ((access & ~kAllAccessBits) != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidAccessBits); + return false; + } + + if (length == 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kLengthZero); + return false; + } + + if (buffer->isMapped()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferAlreadyMapped); + return false; + } + + // Check for invalid bit combinations + if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidAccessBitsReadWrite); + return false; + } + + GLbitfield writeOnlyBits = + GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT; + + if ((access & GL_MAP_READ_BIT) != 0 && (access & writeOnlyBits) != 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidAccessBitsRead); + return false; + } + + if ((access & GL_MAP_WRITE_BIT) == 0 && (access & GL_MAP_FLUSH_EXPLICIT_BIT) != 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidAccessBitsFlush); + return false; + } + + return ValidateMapBufferBase(context, entryPoint, target); +} + +bool ValidateFlushMappedBufferRangeBase(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding target, + GLintptr offset, + GLsizeiptr length) +{ + if (offset < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset); + return false; + } + + if (length < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeLength); + return false; + } + + if (!context->isValidBufferBinding(target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBufferTypes); + return false; + } + + Buffer *buffer = context->getState().getTargetBuffer(target); + + if (buffer == nullptr) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFlushZero); + return false; + } + + if (!buffer->isMapped() || (buffer->getAccessFlags() & GL_MAP_FLUSH_EXPLICIT_BIT) == 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFlushTarget); + return false; + } + + // Check for buffer overflow + CheckedNumeric checkedOffset(offset); + auto checkedSize = checkedOffset + length; + + if (!checkedSize.IsValid() || + checkedSize.ValueOrDie() > static_cast(buffer->getMapLength())) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidFlushOutOfRange); + return false; + } + + return true; +} + +bool ValidateGenOrDelete(const Context *context, angle::EntryPoint entryPoint, GLint n) +{ + if (n < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeCount); + return false; + } + return true; +} + +bool ValidateRobustEntryPoint(const Context *context, angle::EntryPoint entryPoint, GLsizei bufSize) +{ + if (!context->getExtensions().robustClientMemoryANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (bufSize < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize); + return false; + } + + return true; +} + +bool ValidateRobustBufferSize(const Context *context, + angle::EntryPoint entryPoint, + GLsizei bufSize, + GLsizei numParams) +{ + if (bufSize < numParams) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInsufficientParams); + return false; + } + + return true; +} + +bool ValidateGetFramebufferAttachmentParameterivBase(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + GLenum pname, + GLsizei *numParams) +{ + if (!ValidFramebufferTarget(context, target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFramebufferTarget); + return false; + } + + int clientVersion = context->getClientMajorVersion(); + + switch (pname) + { + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: + break; + + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR: + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR: + if (clientVersion < 3 || + !(context->getExtensions().multiviewOVR || context->getExtensions().multiview2OVR)) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + break; + + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT: + if (!context->getExtensions().multisampledRenderToTextureEXT) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + break; + + case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: + if (clientVersion < 3 && !context->getExtensions().sRGBEXT) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + break; + + case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE: + case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE: + case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE: + case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE: + case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE: + case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE: + case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER: + if (clientVersion < 3) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kES3Required); + return false; + } + break; + + case GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT: + if (!context->getExtensions().geometryShaderAny() && + context->getClientVersion() < ES_3_2) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kGeometryShaderExtensionNotEnabled); + return false; + } + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname); + return false; + } + + // Determine if the attachment is a valid enum + switch (attachment) + { + case GL_BACK: + case GL_DEPTH: + case GL_STENCIL: + if (clientVersion < 3) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidAttachment); + return false; + } + break; + + case GL_DEPTH_STENCIL_ATTACHMENT: + if (clientVersion < 3 && !context->isWebGL1()) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidAttachment); + return false; + } + break; + + case GL_COLOR_ATTACHMENT0: + case GL_DEPTH_ATTACHMENT: + case GL_STENCIL_ATTACHMENT: + break; + + default: + if ((clientVersion < 3 && !context->getExtensions().drawBuffersEXT) || + attachment < GL_COLOR_ATTACHMENT0_EXT || + (attachment - GL_COLOR_ATTACHMENT0_EXT) >= + static_cast(context->getCaps().maxColorAttachments)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidAttachment); + return false; + } + break; + } + + const Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target); + ASSERT(framebuffer); + + if (framebuffer->isDefault()) + { + if (clientVersion < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultFramebufferTarget); + return false; + } + + switch (attachment) + { + case GL_BACK: + case GL_DEPTH: + case GL_STENCIL: + break; + + default: + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidAttachment); + return false; + } + } + else + { + if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) + { + // Valid attachment query + } + else + { + switch (attachment) + { + case GL_DEPTH_ATTACHMENT: + case GL_STENCIL_ATTACHMENT: + break; + + case GL_DEPTH_STENCIL_ATTACHMENT: + if (!framebuffer->hasValidDepthStencil() && !context->isWebGL1()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInvalidAttachment); + return false; + } + break; + + default: + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidAttachment); + return false; + } + } + } + + const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(context, attachment); + if (attachmentObject) + { + ASSERT(attachmentObject->type() == GL_RENDERBUFFER || + attachmentObject->type() == GL_TEXTURE || + attachmentObject->type() == GL_FRAMEBUFFER_DEFAULT); + + switch (pname) + { + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: + if (attachmentObject->type() != GL_RENDERBUFFER && + attachmentObject->type() != GL_TEXTURE) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kFramebufferIncompleteAttachment); + return false; + } + break; + + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: + if (attachmentObject->type() != GL_TEXTURE) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kFramebufferIncompleteAttachment); + return false; + } + break; + + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: + if (attachmentObject->type() != GL_TEXTURE) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kFramebufferIncompleteAttachment); + return false; + } + break; + + case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: + if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidAttachment); + return false; + } + break; + + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER: + if (attachmentObject->type() != GL_TEXTURE) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kFramebufferIncompleteAttachment); + return false; + } + break; + + default: + break; + } + } + else + { + // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE + // is NONE, then querying any other pname will generate INVALID_ENUM. + + // ES 3.0.2 spec pg 235 states that if the attachment type is none, + // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an + // INVALID_OPERATION for all other pnames + + switch (pname) + { + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: + break; + + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: + if (clientVersion < 3) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kInvalidFramebufferAttachmentParameter); + return false; + } + break; + + default: + if (clientVersion < 3) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kInvalidFramebufferAttachmentParameter); + return false; + } + else + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInvalidFramebufferAttachmentParameter); + return false; + } + } + } + + if (numParams) + { + *numParams = 1; + } + + return true; +} + +bool ValidateGetFramebufferParameterivBase(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum pname, + const GLint *params) +{ + if (!ValidFramebufferTarget(context, target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFramebufferTarget); + return false; + } + + switch (pname) + { + case GL_FRAMEBUFFER_DEFAULT_WIDTH: + case GL_FRAMEBUFFER_DEFAULT_HEIGHT: + case GL_FRAMEBUFFER_DEFAULT_SAMPLES: + case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS: + break; + case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT: + if (!context->getExtensions().geometryShaderAny() && + context->getClientVersion() < ES_3_2) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kGeometryShaderExtensionNotEnabled); + return false; + } + break; + case GL_FRAMEBUFFER_FLIP_Y_MESA: + if (!context->getExtensions().framebufferFlipYMESA) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname); + return false; + } + break; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname); + return false; + } + + const Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target); + ASSERT(framebuffer); + + if (framebuffer->isDefault()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultFramebuffer); + return false; + } + return true; +} + +bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params) +{ + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + GLsizei numParams = 0; + if (!ValidateGetFramebufferAttachmentParameterivBase(context, entryPoint, target, attachment, + pname, &numParams)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams)) + { + return false; + } + + SetRobustLengthParam(length, numParams); + + return true; +} + +bool ValidateGetBufferParameterivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding target, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params) +{ + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + GLsizei numParams = 0; + + if (!ValidateGetBufferParameterBase(context, entryPoint, target, pname, false, &numParams)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams)) + { + return false; + } + + SetRobustLengthParam(length, numParams); + return true; +} + +bool ValidateGetBufferParameteri64vRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding target, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint64 *params) +{ + GLsizei numParams = 0; + + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + if (!ValidateGetBufferParameterBase(context, entryPoint, target, pname, false, &numParams)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams)) + { + return false; + } + + SetRobustLengthParam(length, numParams); + + return true; +} + +bool ValidateGetProgramivBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLenum pname, + GLsizei *numParams) +{ + // Currently, all GetProgramiv queries return 1 parameter + if (numParams) + { + *numParams = 1; + } + + if (context->isContextLost()) + { + context->validationError(entryPoint, GL_CONTEXT_LOST, kContextLost); + + if (context->getExtensions().parallelShaderCompileKHR && pname == GL_COMPLETION_STATUS_KHR) + { + // Generate an error but still return true, the context still needs to return a + // value in this case. + return true; + } + else + { + return false; + } + } + + // Special case for GL_COMPLETION_STATUS_KHR: don't resolve the link. Otherwise resolve it now. + Program *programObject = (pname == GL_COMPLETION_STATUS_KHR) + ? GetValidProgramNoResolve(context, entryPoint, program) + : GetValidProgram(context, entryPoint, program); + if (!programObject) + { + return false; + } + + switch (pname) + { + case GL_DELETE_STATUS: + case GL_LINK_STATUS: + case GL_VALIDATE_STATUS: + case GL_INFO_LOG_LENGTH: + case GL_ATTACHED_SHADERS: + case GL_ACTIVE_ATTRIBUTES: + case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: + case GL_ACTIVE_UNIFORMS: + case GL_ACTIVE_UNIFORM_MAX_LENGTH: + break; + + case GL_PROGRAM_BINARY_LENGTH: + if (context->getClientMajorVersion() < 3 && + !context->getExtensions().getProgramBinaryOES) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + break; + + case GL_ACTIVE_UNIFORM_BLOCKS: + case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: + case GL_TRANSFORM_FEEDBACK_BUFFER_MODE: + case GL_TRANSFORM_FEEDBACK_VARYINGS: + case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: + case GL_PROGRAM_BINARY_RETRIEVABLE_HINT: + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kEnumRequiresGLES30); + return false; + } + break; + + case GL_PROGRAM_SEPARABLE: + case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS: + if (context->getClientVersion() < Version(3, 1)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kEnumRequiresGLES31); + return false; + } + break; + + case GL_COMPUTE_WORK_GROUP_SIZE: + if (context->getClientVersion() < Version(3, 1)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kEnumRequiresGLES31); + return false; + } + + // [OpenGL ES 3.1] Chapter 7.12 Page 122 + // An INVALID_OPERATION error is generated if COMPUTE_WORK_GROUP_SIZE is queried for a + // program which has not been linked successfully, or which does not contain objects to + // form a compute shader. + if (!programObject->isLinked()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked); + return false; + } + if (!programObject->getExecutable().hasLinkedShaderStage(ShaderType::Compute)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kNoActiveComputeShaderStage); + return false; + } + break; + + case GL_GEOMETRY_LINKED_INPUT_TYPE_EXT: + case GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT: + case GL_GEOMETRY_LINKED_VERTICES_OUT_EXT: + case GL_GEOMETRY_SHADER_INVOCATIONS_EXT: + if (!context->getExtensions().geometryShaderAny() && + context->getClientVersion() < ES_3_2) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kGeometryShaderExtensionNotEnabled); + return false; + } + + // [EXT_geometry_shader] Chapter 7.12 + // An INVALID_OPERATION error is generated if GEOMETRY_LINKED_VERTICES_OUT_EXT, + // GEOMETRY_LINKED_INPUT_TYPE_EXT, GEOMETRY_LINKED_OUTPUT_TYPE_EXT, or + // GEOMETRY_SHADER_INVOCATIONS_EXT are queried for a program which has not been linked + // successfully, or which does not contain objects to form a geometry shader. + if (!programObject->isLinked()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked); + return false; + } + if (!programObject->getExecutable().hasLinkedShaderStage(ShaderType::Geometry)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kNoActiveGeometryShaderStage); + return false; + } + break; + + case GL_COMPLETION_STATUS_KHR: + if (!context->getExtensions().parallelShaderCompileKHR) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + break; + case GL_TESS_CONTROL_OUTPUT_VERTICES_EXT: + case GL_TESS_GEN_MODE_EXT: + case GL_TESS_GEN_SPACING_EXT: + case GL_TESS_GEN_VERTEX_ORDER_EXT: + case GL_TESS_GEN_POINT_MODE_EXT: + if (!context->getExtensions().tessellationShaderEXT && + context->getClientVersion() < ES_3_2) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kTessellationShaderExtensionNotEnabled); + return false; + } + if (!programObject->isLinked()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked); + return false; + } + break; + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + + return true; +} + +bool ValidateGetProgramivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params) +{ + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + GLsizei numParams = 0; + + if (!ValidateGetProgramivBase(context, entryPoint, program, pname, &numParams)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams)) + { + return false; + } + + SetRobustLengthParam(length, numParams); + + return true; +} + +bool ValidateGetRenderbufferParameterivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params) +{ + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + GLsizei numParams = 0; + + if (!ValidateGetRenderbufferParameterivBase(context, entryPoint, target, pname, &numParams)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams)) + { + return false; + } + + SetRobustLengthParam(length, numParams); + + return true; +} + +bool ValidateGetShaderivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID shader, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params) +{ + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + GLsizei numParams = 0; + + if (!ValidateGetShaderivBase(context, entryPoint, shader, pname, &numParams)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams)) + { + return false; + } + + SetRobustLengthParam(length, numParams); + + return true; +} + +bool ValidateGetTexParameterfvRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLfloat *params) +{ + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + GLsizei numParams = 0; + + if (!ValidateGetTexParameterBase(context, entryPoint, target, pname, &numParams)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams)) + { + return false; + } + + SetRobustLengthParam(length, numParams); + + return true; +} + +bool ValidateGetTexParameterivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params) +{ + + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + GLsizei numParams = 0; + if (!ValidateGetTexParameterBase(context, entryPoint, target, pname, &numParams)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams)) + { + return false; + } + + SetRobustLengthParam(length, numParams); + return true; +} + +bool ValidateGetTexParameterIivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params) +{ + UNIMPLEMENTED(); + return false; +} + +bool ValidateGetTexParameterIuivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLuint *params) +{ + UNIMPLEMENTED(); + return false; +} + +bool ValidateTexParameterfvRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum pname, + GLsizei bufSize, + const GLfloat *params) +{ + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + return ValidateTexParameterBase(context, entryPoint, target, pname, bufSize, true, params); +} + +bool ValidateTexParameterivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum pname, + GLsizei bufSize, + const GLint *params) +{ + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + return ValidateTexParameterBase(context, entryPoint, target, pname, bufSize, true, params); +} + +bool ValidateTexParameterIivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum pname, + GLsizei bufSize, + const GLint *params) +{ + UNIMPLEMENTED(); + return false; +} + +bool ValidateTexParameterIuivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum pname, + GLsizei bufSize, + const GLuint *params) +{ + UNIMPLEMENTED(); + return false; +} + +bool ValidateGetSamplerParameterfvRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + SamplerID sampler, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLfloat *params) +{ + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + GLsizei numParams = 0; + + if (!ValidateGetSamplerParameterBase(context, entryPoint, sampler, pname, &numParams)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams)) + { + return false; + } + + SetRobustLengthParam(length, numParams); + return true; +} + +bool ValidateGetSamplerParameterivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + SamplerID sampler, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params) +{ + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + GLsizei numParams = 0; + + if (!ValidateGetSamplerParameterBase(context, entryPoint, sampler, pname, &numParams)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams)) + { + return false; + } + + SetRobustLengthParam(length, numParams); + return true; +} + +bool ValidateGetSamplerParameterIivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + SamplerID sampler, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params) +{ + UNIMPLEMENTED(); + return false; +} + +bool ValidateGetSamplerParameterIuivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + SamplerID sampler, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLuint *params) +{ + UNIMPLEMENTED(); + return false; +} + +bool ValidateSamplerParameterfvRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + SamplerID sampler, + GLenum pname, + GLsizei bufSize, + const GLfloat *params) +{ + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + return ValidateSamplerParameterBase(context, entryPoint, sampler, pname, bufSize, true, params); +} + +bool ValidateSamplerParameterivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + SamplerID sampler, + GLenum pname, + GLsizei bufSize, + const GLint *params) +{ + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + return ValidateSamplerParameterBase(context, entryPoint, sampler, pname, bufSize, true, params); +} + +bool ValidateSamplerParameterIivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + SamplerID sampler, + GLenum pname, + GLsizei bufSize, + const GLint *param) +{ + UNIMPLEMENTED(); + return false; +} + +bool ValidateSamplerParameterIuivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + SamplerID sampler, + GLenum pname, + GLsizei bufSize, + const GLuint *param) +{ + UNIMPLEMENTED(); + return false; +} + +bool ValidateGetVertexAttribfvRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLfloat *params) +{ + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + GLsizei writeLength = 0; + + if (!ValidateGetVertexAttribBase(context, entryPoint, index, pname, &writeLength, false, false)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength)) + { + return false; + } + + SetRobustLengthParam(length, writeLength); + return true; +} + +bool ValidateGetVertexAttribivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params) +{ + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + GLsizei writeLength = 0; + + if (!ValidateGetVertexAttribBase(context, entryPoint, index, pname, &writeLength, false, false)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength)) + { + return false; + } + + SetRobustLengthParam(length, writeLength); + + return true; +} + +bool ValidateGetVertexAttribPointervRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + void *const *pointer) +{ + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + GLsizei writeLength = 0; + + if (!ValidateGetVertexAttribBase(context, entryPoint, index, pname, &writeLength, true, false)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength)) + { + return false; + } + + SetRobustLengthParam(length, writeLength); + + return true; +} + +bool ValidateGetVertexAttribIivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params) +{ + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + GLsizei writeLength = 0; + + if (!ValidateGetVertexAttribBase(context, entryPoint, index, pname, &writeLength, false, true)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength)) + { + return false; + } + + SetRobustLengthParam(length, writeLength); + + return true; +} + +bool ValidateGetVertexAttribIuivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLuint *params) +{ + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + GLsizei writeLength = 0; + + if (!ValidateGetVertexAttribBase(context, entryPoint, index, pname, &writeLength, false, true)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength)) + { + return false; + } + + SetRobustLengthParam(length, writeLength); + + return true; +} + +bool ValidateGetActiveUniformBlockivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformBlockIndex uniformBlockIndex, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params) +{ + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + GLsizei writeLength = 0; + + if (!ValidateGetActiveUniformBlockivBase(context, entryPoint, program, uniformBlockIndex, pname, + &writeLength)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength)) + { + return false; + } + + SetRobustLengthParam(length, writeLength); + + return true; +} + +bool ValidateGetInternalformativRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params) +{ + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + GLsizei numParams = 0; + + if (!ValidateGetInternalFormativBase(context, entryPoint, target, internalformat, pname, + bufSize, &numParams)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams)) + { + return false; + } + + SetRobustLengthParam(length, numParams); + + return true; +} + +// Perform validation from WebGL 2 section 5.10 "Invalid Clears": +// In the WebGL 2 API, trying to perform a clear when there is a mismatch between the type of the +// specified clear value and the type of a buffer that is being cleared generates an +// INVALID_OPERATION error instead of producing undefined results +bool ValidateWebGLFramebufferAttachmentClearType(const Context *context, + angle::EntryPoint entryPoint, + GLint drawbuffer, + const GLenum *validComponentTypes, + size_t validComponentTypeCount) +{ + const FramebufferAttachment *attachment = + context->getState().getDrawFramebuffer()->getDrawBuffer(drawbuffer); + if (attachment) + { + GLenum componentType = attachment->getFormat().info->componentType; + const GLenum *end = validComponentTypes + validComponentTypeCount; + if (std::find(validComponentTypes, end, componentType) == end) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kNoDefinedClearConversion); + return false; + } + } + + return true; +} + +bool ValidateRobustCompressedTexImageBase(const Context *context, + angle::EntryPoint entryPoint, + GLsizei imageSize, + GLsizei dataSize) +{ + if (!ValidateRobustEntryPoint(context, entryPoint, dataSize)) + { + return false; + } + + Buffer *pixelUnpackBuffer = context->getState().getTargetBuffer(BufferBinding::PixelUnpack); + if (pixelUnpackBuffer == nullptr) + { + if (dataSize < imageSize) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kCompressedDataSizeTooSmall); + } + } + return true; +} + +bool ValidateGetBufferParameterBase(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding target, + GLenum pname, + bool pointerVersion, + GLsizei *numParams) +{ + if (numParams) + { + *numParams = 0; + } + + if (!context->isValidBufferBinding(target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBufferTypes); + return false; + } + + const Buffer *buffer = context->getState().getTargetBuffer(target); + if (!buffer) + { + // A null buffer means that "0" is bound to the requested buffer target + context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferNotBound); + return false; + } + + const Extensions &extensions = context->getExtensions(); + + switch (pname) + { + case GL_BUFFER_USAGE: + case GL_BUFFER_SIZE: + break; + + case GL_BUFFER_ACCESS_OES: + if (!extensions.mapbufferOES) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + break; + + case GL_BUFFER_MAPPED: + static_assert(GL_BUFFER_MAPPED == GL_BUFFER_MAPPED_OES, "GL enums should be equal."); + if (context->getClientMajorVersion() < 3 && !extensions.mapbufferOES && + !extensions.mapBufferRangeEXT) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + break; + + case GL_BUFFER_MAP_POINTER: + if (!pointerVersion) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidMapPointerQuery); + return false; + } + break; + + case GL_BUFFER_ACCESS_FLAGS: + case GL_BUFFER_MAP_OFFSET: + case GL_BUFFER_MAP_LENGTH: + if (context->getClientMajorVersion() < 3 && !extensions.mapBufferRangeEXT) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + break; + + case GL_MEMORY_SIZE_ANGLE: + if (!context->getExtensions().memorySizeANGLE) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled); + return false; + } + break; + + case GL_RESOURCE_INITIALIZED_ANGLE: + if (!context->getExtensions().robustResourceInitializationANGLE) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kRobustResourceInitializationExtensionRequired); + return false; + } + break; + + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + + // All buffer parameter queries return one value. + if (numParams) + { + *numParams = 1; + } + + return true; +} + +bool ValidateGetRenderbufferParameterivBase(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum pname, + GLsizei *length) +{ + if (length) + { + *length = 0; + } + + if (target != GL_RENDERBUFFER) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidRenderbufferTarget); + return false; + } + + Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer(); + if (renderbuffer == nullptr) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kRenderbufferNotBound); + return false; + } + + switch (pname) + { + case GL_RENDERBUFFER_WIDTH: + case GL_RENDERBUFFER_HEIGHT: + case GL_RENDERBUFFER_INTERNAL_FORMAT: + case GL_RENDERBUFFER_RED_SIZE: + case GL_RENDERBUFFER_GREEN_SIZE: + case GL_RENDERBUFFER_BLUE_SIZE: + case GL_RENDERBUFFER_ALPHA_SIZE: + case GL_RENDERBUFFER_DEPTH_SIZE: + case GL_RENDERBUFFER_STENCIL_SIZE: + break; + + case GL_RENDERBUFFER_SAMPLES_ANGLE: + if (context->getClientMajorVersion() < 3 && + !context->getExtensions().framebufferMultisampleANGLE) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled); + return false; + } + break; + + case GL_MEMORY_SIZE_ANGLE: + if (!context->getExtensions().memorySizeANGLE) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled); + return false; + } + break; + + case GL_IMPLEMENTATION_COLOR_READ_FORMAT: + case GL_IMPLEMENTATION_COLOR_READ_TYPE: + if (!context->getExtensions().getImageANGLE) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kGetImageExtensionNotEnabled); + return false; + } + break; + + case GL_RESOURCE_INITIALIZED_ANGLE: + if (!context->getExtensions().robustResourceInitializationANGLE) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kRobustResourceInitializationExtensionRequired); + return false; + } + break; + + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + + if (length) + { + *length = 1; + } + return true; +} + +bool ValidateGetShaderivBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID shader, + GLenum pname, + GLsizei *length) +{ + if (length) + { + *length = 0; + } + + if (context->isContextLost()) + { + context->validationError(entryPoint, GL_CONTEXT_LOST, kContextLost); + + if (context->getExtensions().parallelShaderCompileKHR && pname == GL_COMPLETION_STATUS_KHR) + { + // Generate an error but still return true, the context still needs to return a + // value in this case. + return true; + } + else + { + return false; + } + } + + if (GetValidShader(context, entryPoint, shader) == nullptr) + { + return false; + } + + switch (pname) + { + case GL_SHADER_TYPE: + case GL_DELETE_STATUS: + case GL_COMPILE_STATUS: + case GL_INFO_LOG_LENGTH: + case GL_SHADER_SOURCE_LENGTH: + break; + + case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE: + if (!context->getExtensions().translatedShaderSourceANGLE) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled); + return false; + } + break; + + case GL_COMPLETION_STATUS_KHR: + if (!context->getExtensions().parallelShaderCompileKHR) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + break; + + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + + if (length) + { + *length = 1; + } + return true; +} + +bool ValidateGetTexParameterBase(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum pname, + GLsizei *length) +{ + if (length) + { + *length = 0; + } + + if ((!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target)) || + target == TextureType::Buffer) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + + if (context->getTextureByType(target) == nullptr) + { + // Should only be possible for external textures + context->validationError(entryPoint, GL_INVALID_ENUM, kTextureNotBound); + return false; + } + + if (context->getClientMajorVersion() == 1 && !IsValidGLES1TextureParameter(pname)) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + + switch (pname) + { + case GL_TEXTURE_MAG_FILTER: + case GL_TEXTURE_MIN_FILTER: + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + break; + + case GL_TEXTURE_USAGE_ANGLE: + if (!context->getExtensions().textureUsageANGLE) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + break; + + case GL_TEXTURE_MAX_ANISOTROPY_EXT: + if (!ValidateTextureMaxAnisotropyExtensionEnabled(context, entryPoint)) + { + return false; + } + break; + + case GL_TEXTURE_IMMUTABLE_FORMAT: + if (context->getClientMajorVersion() < 3 && !context->getExtensions().textureStorageEXT) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + break; + + case GL_TEXTURE_WRAP_R: + case GL_TEXTURE_IMMUTABLE_LEVELS: + case GL_TEXTURE_SWIZZLE_R: + case GL_TEXTURE_SWIZZLE_G: + case GL_TEXTURE_SWIZZLE_B: + case GL_TEXTURE_SWIZZLE_A: + case GL_TEXTURE_BASE_LEVEL: + case GL_TEXTURE_MAX_LEVEL: + case GL_TEXTURE_MIN_LOD: + case GL_TEXTURE_MAX_LOD: + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kEnumRequiresGLES30); + return false; + } + break; + + case GL_TEXTURE_COMPARE_MODE: + case GL_TEXTURE_COMPARE_FUNC: + if (context->getClientMajorVersion() < 3 && !context->getExtensions().shadowSamplersEXT) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + break; + + case GL_TEXTURE_SRGB_DECODE_EXT: + if (!context->getExtensions().textureSRGBDecodeEXT) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + break; + + case GL_DEPTH_STENCIL_TEXTURE_MODE: + case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE: + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kEnumRequiresGLES31); + return false; + } + break; + + case GL_GENERATE_MIPMAP: + case GL_TEXTURE_CROP_RECT_OES: + // TODO(lfy@google.com): Restrict to GL_OES_draw_texture + // after GL_OES_draw_texture functionality implemented + if (context->getClientMajorVersion() > 1) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kGLES1Only); + return false; + } + break; + + case GL_MEMORY_SIZE_ANGLE: + if (!context->getExtensions().memorySizeANGLE) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + break; + + case GL_TEXTURE_BORDER_COLOR: + if (!context->getExtensions().textureBorderClampOES && + context->getClientVersion() < ES_3_2) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled); + return false; + } + break; + + case GL_TEXTURE_NATIVE_ID_ANGLE: + if (!context->getExtensions().textureExternalUpdateANGLE) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled); + return false; + } + break; + + case GL_IMPLEMENTATION_COLOR_READ_FORMAT: + case GL_IMPLEMENTATION_COLOR_READ_TYPE: + if (!context->getExtensions().getImageANGLE) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kGetImageExtensionNotEnabled); + return false; + } + break; + + case GL_RESOURCE_INITIALIZED_ANGLE: + if (!context->getExtensions().robustResourceInitializationANGLE) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kRobustResourceInitializationExtensionRequired); + return false; + } + break; + + case GL_TEXTURE_PROTECTED_EXT: + if (!context->getExtensions().protectedTexturesEXT) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kProtectedTexturesExtensionRequired); + return false; + } + break; + + case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: + break; + + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + + if (length) + { + *length = GetTexParameterCount(pname); + } + return true; +} + +bool ValidateGetVertexAttribBase(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum pname, + GLsizei *length, + bool pointer, + bool pureIntegerEntryPoint) +{ + if (length) + { + *length = 0; + } + + if (pureIntegerEntryPoint && context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + if (index >= static_cast(context->getCaps().maxVertexAttributes)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute); + return false; + } + + if (pointer) + { + if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + } + else + { + switch (pname) + { + case GL_VERTEX_ATTRIB_ARRAY_ENABLED: + case GL_VERTEX_ATTRIB_ARRAY_SIZE: + case GL_VERTEX_ATTRIB_ARRAY_STRIDE: + case GL_VERTEX_ATTRIB_ARRAY_TYPE: + case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: + case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: + case GL_CURRENT_VERTEX_ATTRIB: + break; + + case GL_VERTEX_ATTRIB_ARRAY_DIVISOR: + static_assert( + GL_VERTEX_ATTRIB_ARRAY_DIVISOR == GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE, + "ANGLE extension enums not equal to GL enums."); + if (context->getClientMajorVersion() < 3 && + !context->getExtensions().instancedArraysAny()) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, + pname); + return false; + } + break; + + case GL_VERTEX_ATTRIB_ARRAY_INTEGER: + if (context->getClientMajorVersion() < 3) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, + pname); + return false; + } + break; + + case GL_VERTEX_ATTRIB_BINDING: + case GL_VERTEX_ATTRIB_RELATIVE_OFFSET: + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kEnumRequiresGLES31); + return false; + } + break; + + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + } + + if (length) + { + if (pname == GL_CURRENT_VERTEX_ATTRIB) + { + *length = 4; + } + else + { + *length = 1; + } + } + + return true; +} + +bool ValidatePixelPack(const Context *context, + angle::EntryPoint entryPoint, + GLenum format, + GLenum type, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLsizei bufSize, + GLsizei *length, + const void *pixels) +{ + // Check for pixel pack buffer related API errors + Buffer *pixelPackBuffer = context->getState().getTargetBuffer(BufferBinding::PixelPack); + if (pixelPackBuffer != nullptr && pixelPackBuffer->isMapped()) + { + // ...the buffer object's data store is currently mapped. + context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferMapped); + return false; + } + if (pixelPackBuffer != nullptr && + pixelPackBuffer->hasWebGLXFBBindingConflict(context->isWebGL())) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kPixelPackBufferBoundForTransformFeedback); + return false; + } + + // .. the data would be packed to the buffer object such that the memory writes required + // would exceed the data store size. + const InternalFormat &formatInfo = GetInternalFormatInfo(format, type); + const Extents size(width, height, 1); + const auto &pack = context->getState().getPackState(); + + GLuint endByte = 0; + if (!formatInfo.computePackUnpackEndByte(type, size, pack, false, &endByte)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kIntegerOverflow); + return false; + } + + if (bufSize >= 0) + { + if (pixelPackBuffer == nullptr && static_cast(bufSize) < endByte) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInsufficientBufferSize); + return false; + } + } + + if (pixelPackBuffer != nullptr) + { + CheckedNumeric checkedEndByte(endByte); + CheckedNumeric checkedOffset(reinterpret_cast(pixels)); + checkedEndByte += checkedOffset; + + if (checkedEndByte.ValueOrDie() > static_cast(pixelPackBuffer->getSize())) + { + // Overflow past the end of the buffer + context->validationError(entryPoint, GL_INVALID_OPERATION, kParamOverflow); + return false; + } + } + + if (pixelPackBuffer == nullptr && length != nullptr) + { + if (endByte > static_cast(std::numeric_limits::max())) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kIntegerOverflow); + return false; + } + + *length = static_cast(endByte); + } + + if (context->isWebGL()) + { + // WebGL 2.0 disallows the scenario: + // GL_PACK_SKIP_PIXELS + width > DataStoreWidth + // where: + // DataStoreWidth = (GL_PACK_ROW_LENGTH ? GL_PACK_ROW_LENGTH : width) + // Since these two pack parameters can only be set to non-zero values + // on WebGL 2.0 contexts, verify them for all WebGL contexts. + GLint dataStoreWidth = pack.rowLength ? pack.rowLength : width; + if (pack.skipPixels + width > dataStoreWidth) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInvalidPackParametersForWebGL); + return false; + } + } + + return true; +} + +bool ValidateReadPixelsBase(const Context *context, + angle::EntryPoint entryPoint, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + GLsizei *length, + GLsizei *columns, + GLsizei *rows, + const void *pixels) +{ + if (length != nullptr) + { + *length = 0; + } + if (rows != nullptr) + { + *rows = 0; + } + if (columns != nullptr) + { + *columns = 0; + } + + if (width < 0 || height < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeSize); + return false; + } + + Framebuffer *readFramebuffer = context->getState().getReadFramebuffer(); + ASSERT(readFramebuffer); + + if (!ValidateFramebufferComplete(context, entryPoint, readFramebuffer)) + { + return false; + } + + // needIntrinsic = true. Treat renderToTexture textures as single sample since they will be + // resolved before reading. + if (!readFramebuffer->isDefault() && + !ValidateFramebufferNotMultisampled(context, entryPoint, readFramebuffer, true)) + { + return false; + } + + if (readFramebuffer->getReadBufferState() == GL_NONE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kReadBufferNone); + return false; + } + + const FramebufferAttachment *readBuffer = nullptr; + switch (format) + { + case GL_DEPTH_COMPONENT: + readBuffer = readFramebuffer->getDepthAttachment(); + break; + case GL_STENCIL_INDEX_OES: + case GL_DEPTH_STENCIL_OES: + readBuffer = readFramebuffer->getStencilOrDepthStencilAttachment(); + break; + default: + readBuffer = readFramebuffer->getReadColorAttachment(); + break; + } + + // OVR_multiview2, Revision 1: + // ReadPixels generates an INVALID_FRAMEBUFFER_OPERATION error if + // the number of views in the current read framebuffer is more than one. + if (readFramebuffer->readDisallowedByMultiview()) + { + context->validationError(entryPoint, GL_INVALID_FRAMEBUFFER_OPERATION, + kMultiviewReadFramebuffer); + return false; + } + + if (context->isWebGL()) + { + // The ES 2.0 spec states that the format must be "among those defined in table 3.4, + // excluding formats LUMINANCE and LUMINANCE_ALPHA.". This requires validating the format + // and type before validating the combination of format and type. However, the + // dEQP-GLES3.functional.negative_api.buffer.read_pixels passes GL_LUMINANCE as a format and + // verifies that GL_INVALID_OPERATION is generated. + // TODO(geofflang): Update this check to be done in all/no cases once this is resolved in + // dEQP/WebGL. + if (!ValidReadPixelsFormatEnum(context, format)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat); + return false; + } + + if (!ValidReadPixelsTypeEnum(context, type)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType); + return false; + } + } + + // WebGL 1.0 [Section 6.26] Reading From a Missing Attachment + // In OpenGL ES it is undefined what happens when an operation tries to read from a missing + // attachment and WebGL defines it to be an error. We do the check unconditionally as the + // situation is an application error that would lead to a crash in ANGLE. + if (readBuffer == nullptr) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kMissingReadAttachment); + return false; + } + + GLenum currentFormat = GL_NONE; + GLenum currentType = GL_NONE; + + switch (format) + { + case GL_DEPTH_COMPONENT: + case GL_STENCIL_INDEX_OES: + case GL_DEPTH_STENCIL_OES: + // Only rely on ValidReadPixelsFormatType for depth/stencil formats + break; + default: + currentFormat = readFramebuffer->getImplementationColorReadFormat(context); + currentType = readFramebuffer->getImplementationColorReadType(context); + break; + } + + bool validFormatTypeCombination = + ValidReadPixelsFormatType(context, readBuffer->getFormat().info, format, type); + + if (!(currentFormat == format && currentType == type) && !validFormatTypeCombination) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kMismatchedTypeAndFormat); + return false; + } + + if (!ValidatePixelPack(context, entryPoint, format, type, x, y, width, height, bufSize, length, + pixels)) + { + return false; + } + + auto getClippedExtent = [](GLint start, GLsizei length, int bufferSize, GLsizei *outExtent) { + angle::CheckedNumeric clippedExtent(length); + if (start < 0) + { + // "subtract" the area that is less than 0 + clippedExtent += start; + } + + angle::CheckedNumeric readExtent = start; + readExtent += length; + if (!readExtent.IsValid()) + { + return false; + } + + if (readExtent.ValueOrDie() > bufferSize) + { + // Subtract the region to the right of the read buffer + clippedExtent -= (readExtent - bufferSize); + } + + if (!clippedExtent.IsValid()) + { + return false; + } + + *outExtent = std::max(clippedExtent.ValueOrDie(), 0); + return true; + }; + + GLsizei writtenColumns = 0; + if (!getClippedExtent(x, width, readBuffer->getSize().width, &writtenColumns)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kIntegerOverflow); + return false; + } + + GLsizei writtenRows = 0; + if (!getClippedExtent(y, height, readBuffer->getSize().height, &writtenRows)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kIntegerOverflow); + return false; + } + + if (columns != nullptr) + { + *columns = writtenColumns; + } + + if (rows != nullptr) + { + *rows = writtenRows; + } + + return true; +} + +template +bool ValidateTexParameterBase(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum pname, + GLsizei bufSize, + bool vectorParams, + const ParamType *params) +{ + if ((!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target)) || + target == TextureType::Buffer) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + + if (context->getTextureByType(target) == nullptr) + { + // Should only be possible for external textures + context->validationError(entryPoint, GL_INVALID_ENUM, kTextureNotBound); + return false; + } + + const GLsizei minBufSize = GetTexParameterCount(pname); + if (bufSize >= 0 && bufSize < minBufSize) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInsufficientBufferSize); + return false; + } + + if (context->getClientMajorVersion() == 1 && !IsValidGLES1TextureParameter(pname)) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + + switch (pname) + { + case GL_TEXTURE_WRAP_R: + case GL_TEXTURE_SWIZZLE_R: + case GL_TEXTURE_SWIZZLE_G: + case GL_TEXTURE_SWIZZLE_B: + case GL_TEXTURE_SWIZZLE_A: + case GL_TEXTURE_BASE_LEVEL: + case GL_TEXTURE_MAX_LEVEL: + case GL_TEXTURE_COMPARE_MODE: + case GL_TEXTURE_COMPARE_FUNC: + case GL_TEXTURE_MIN_LOD: + case GL_TEXTURE_MAX_LOD: + if (context->getClientMajorVersion() < 3 && + !(pname == GL_TEXTURE_WRAP_R && context->getExtensions().texture3DOES)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kES3Required); + return false; + } + if (target == TextureType::External && + !context->getExtensions().EGLImageExternalEssl3OES) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + if (target == TextureType::VideoImage && !context->getExtensions().videoTextureWEBGL) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + } + break; + + case GL_GENERATE_MIPMAP: + case GL_TEXTURE_CROP_RECT_OES: + if (context->getClientMajorVersion() > 1) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kGLES1Only); + return false; + } + break; + + default: + break; + } + + if (target == TextureType::_2DMultisample || target == TextureType::_2DMultisampleArray) + { + switch (pname) + { + case GL_TEXTURE_MIN_FILTER: + case GL_TEXTURE_MAG_FILTER: + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + case GL_TEXTURE_WRAP_R: + case GL_TEXTURE_MIN_LOD: + case GL_TEXTURE_MAX_LOD: + case GL_TEXTURE_COMPARE_MODE: + case GL_TEXTURE_COMPARE_FUNC: + case GL_TEXTURE_BORDER_COLOR: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname); + return false; + } + } + + switch (pname) + { + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + case GL_TEXTURE_WRAP_R: + { + bool restrictedWrapModes = ((target == TextureType::External && + !context->getExtensions().EGLImageExternalWrapModesEXT) || + target == TextureType::Rectangle); + if (!ValidateTextureWrapModeValue(context, entryPoint, params, restrictedWrapModes)) + { + return false; + } + } + break; + + case GL_TEXTURE_MIN_FILTER: + { + bool restrictedMinFilter = + target == TextureType::External || target == TextureType::Rectangle; + if (!ValidateTextureMinFilterValue(context, entryPoint, params, restrictedMinFilter)) + { + return false; + } + } + break; + + case GL_TEXTURE_MAG_FILTER: + if (!ValidateTextureMagFilterValue(context, entryPoint, params)) + { + return false; + } + break; + + case GL_TEXTURE_USAGE_ANGLE: + if (!context->getExtensions().textureUsageANGLE) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + + switch (ConvertToGLenum(params[0])) + { + case GL_NONE: + case GL_FRAMEBUFFER_ATTACHMENT_ANGLE: + break; + + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, + pname); + return false; + } + break; + + case GL_TEXTURE_MAX_ANISOTROPY_EXT: + { + GLfloat paramValue = static_cast(params[0]); + if (!ValidateTextureMaxAnisotropyValue(context, entryPoint, paramValue)) + { + return false; + } + ASSERT(static_cast(paramValue) == params[0]); + } + break; + + case GL_TEXTURE_MIN_LOD: + case GL_TEXTURE_MAX_LOD: + // any value is permissible + break; + + case GL_TEXTURE_COMPARE_MODE: + if (!ValidateTextureCompareModeValue(context, entryPoint, params)) + { + return false; + } + break; + + case GL_TEXTURE_COMPARE_FUNC: + if (!ValidateTextureCompareFuncValue(context, entryPoint, params)) + { + return false; + } + break; + + case GL_TEXTURE_SWIZZLE_R: + case GL_TEXTURE_SWIZZLE_G: + case GL_TEXTURE_SWIZZLE_B: + case GL_TEXTURE_SWIZZLE_A: + switch (ConvertToGLenum(params[0])) + { + case GL_RED: + case GL_GREEN: + case GL_BLUE: + case GL_ALPHA: + case GL_ZERO: + case GL_ONE: + break; + + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, + pname); + return false; + } + break; + + case GL_TEXTURE_BASE_LEVEL: + if (ConvertToGLint(params[0]) < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kBaseLevelNegative); + return false; + } + if (target == TextureType::External && static_cast(params[0]) != 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kBaseLevelNonZero); + return false; + } + if ((target == TextureType::_2DMultisample || + target == TextureType::_2DMultisampleArray) && + static_cast(params[0]) != 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kBaseLevelNonZero); + return false; + } + if (target == TextureType::Rectangle && static_cast(params[0]) != 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kBaseLevelNonZero); + return false; + } + break; + + case GL_TEXTURE_MAX_LEVEL: + if (ConvertToGLint(params[0]) < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel); + return false; + } + break; + + case GL_DEPTH_STENCIL_TEXTURE_MODE: + if (context->getClientVersion() < Version(3, 1)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kEnumRequiresGLES31); + return false; + } + switch (ConvertToGLenum(params[0])) + { + case GL_DEPTH_COMPONENT: + case GL_STENCIL_INDEX: + break; + + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, + pname); + return false; + } + break; + + case GL_TEXTURE_SRGB_DECODE_EXT: + if (!ValidateTextureSRGBDecodeValue(context, entryPoint, params)) + { + return false; + } + break; + + case GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT: + if (!ValidateTextureSRGBOverrideValue(context, entryPoint, params)) + { + return false; + } + break; + + case GL_GENERATE_MIPMAP: + if (context->getClientMajorVersion() > 1) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kGLES1Only); + return false; + } + break; + + case GL_TEXTURE_CROP_RECT_OES: + if (context->getClientMajorVersion() > 1) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kGLES1Only); + return false; + } + if (!vectorParams) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInsufficientBufferSize); + return false; + } + break; + + case GL_TEXTURE_BORDER_COLOR: + if (!context->getExtensions().textureBorderClampOES && + context->getClientVersion() < ES_3_2) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled); + return false; + } + if (!vectorParams) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInsufficientBufferSize); + return false; + } + break; + + case GL_RESOURCE_INITIALIZED_ANGLE: + if (!context->getExtensions().robustResourceInitializationANGLE) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kRobustResourceInitializationExtensionRequired); + return false; + } + break; + + case GL_TEXTURE_PROTECTED_EXT: + if (!context->getExtensions().protectedTexturesEXT) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kProtectedTexturesExtensionRequired); + return false; + } + if (ConvertToBool(params[0]) != context->getState().hasProtectedContent()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + "Protected Texture must match Protected Context"); + return false; + } + break; + + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + + return true; +} + +template bool ValidateTexParameterBase(const Context *, + angle::EntryPoint, + TextureType, + GLenum, + GLsizei, + bool, + const GLfloat *); +template bool ValidateTexParameterBase(const Context *, + angle::EntryPoint, + TextureType, + GLenum, + GLsizei, + bool, + const GLint *); +template bool ValidateTexParameterBase(const Context *, + angle::EntryPoint, + TextureType, + GLenum, + GLsizei, + bool, + const GLuint *); + +bool ValidateGetActiveUniformBlockivBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformBlockIndex uniformBlockIndex, + GLenum pname, + GLsizei *length) +{ + if (length) + { + *length = 0; + } + + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + Program *programObject = GetValidProgram(context, entryPoint, program); + if (!programObject) + { + return false; + } + + if (uniformBlockIndex.value >= programObject->getActiveUniformBlockCount()) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kIndexExceedsActiveUniformBlockCount); + return false; + } + + switch (pname) + { + case GL_UNIFORM_BLOCK_BINDING: + case GL_UNIFORM_BLOCK_DATA_SIZE: + case GL_UNIFORM_BLOCK_NAME_LENGTH: + case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: + case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: + case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER: + case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: + break; + + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + + if (length) + { + if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES) + { + const InterfaceBlock &uniformBlock = + programObject->getUniformBlockByIndex(uniformBlockIndex.value); + *length = static_cast(uniformBlock.memberIndexes.size()); + } + else + { + *length = 1; + } + } + + return true; +} + +template +bool ValidateSamplerParameterBase(const Context *context, + angle::EntryPoint entryPoint, + SamplerID sampler, + GLenum pname, + GLsizei bufSize, + bool vectorParams, + const ParamType *params) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + if (!context->isSampler(sampler)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidSampler); + return false; + } + + const GLsizei minBufSize = GetSamplerParameterCount(pname); + if (bufSize >= 0 && bufSize < minBufSize) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInsufficientBufferSize); + return false; + } + + switch (pname) + { + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + case GL_TEXTURE_WRAP_R: + if (!ValidateTextureWrapModeValue(context, entryPoint, params, false)) + { + return false; + } + break; + + case GL_TEXTURE_MIN_FILTER: + if (!ValidateTextureMinFilterValue(context, entryPoint, params, false)) + { + return false; + } + break; + + case GL_TEXTURE_MAG_FILTER: + if (!ValidateTextureMagFilterValue(context, entryPoint, params)) + { + return false; + } + break; + + case GL_TEXTURE_MIN_LOD: + case GL_TEXTURE_MAX_LOD: + // any value is permissible + break; + + case GL_TEXTURE_COMPARE_MODE: + if (!ValidateTextureCompareModeValue(context, entryPoint, params)) + { + return false; + } + break; + + case GL_TEXTURE_COMPARE_FUNC: + if (!ValidateTextureCompareFuncValue(context, entryPoint, params)) + { + return false; + } + break; + + case GL_TEXTURE_SRGB_DECODE_EXT: + if (!ValidateTextureSRGBDecodeValue(context, entryPoint, params)) + { + return false; + } + break; + + case GL_TEXTURE_MAX_ANISOTROPY_EXT: + { + GLfloat paramValue = static_cast(params[0]); + if (!ValidateTextureMaxAnisotropyValue(context, entryPoint, paramValue)) + { + return false; + } + } + break; + + case GL_TEXTURE_BORDER_COLOR: + if (!context->getExtensions().textureBorderClampOES && + context->getClientVersion() < ES_3_2) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled); + return false; + } + if (!vectorParams) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInsufficientBufferSize); + return false; + } + break; + + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + + return true; +} + +template bool ValidateSamplerParameterBase(const Context *, + angle::EntryPoint, + SamplerID, + GLenum, + GLsizei, + bool, + const GLfloat *); +template bool ValidateSamplerParameterBase(const Context *, + angle::EntryPoint, + SamplerID, + GLenum, + GLsizei, + bool, + const GLint *); +template bool ValidateSamplerParameterBase(const Context *, + angle::EntryPoint, + SamplerID, + GLenum, + GLsizei, + bool, + const GLuint *); + +bool ValidateGetSamplerParameterBase(const Context *context, + angle::EntryPoint entryPoint, + SamplerID sampler, + GLenum pname, + GLsizei *length) +{ + if (length) + { + *length = 0; + } + + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + if (!context->isSampler(sampler)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidSampler); + return false; + } + + switch (pname) + { + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + case GL_TEXTURE_WRAP_R: + case GL_TEXTURE_MIN_FILTER: + case GL_TEXTURE_MAG_FILTER: + case GL_TEXTURE_MIN_LOD: + case GL_TEXTURE_MAX_LOD: + case GL_TEXTURE_COMPARE_MODE: + case GL_TEXTURE_COMPARE_FUNC: + break; + + case GL_TEXTURE_MAX_ANISOTROPY_EXT: + if (!ValidateTextureMaxAnisotropyExtensionEnabled(context, entryPoint)) + { + return false; + } + break; + + case GL_TEXTURE_SRGB_DECODE_EXT: + if (!context->getExtensions().textureSRGBDecodeEXT) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + break; + + case GL_TEXTURE_BORDER_COLOR: + if (!context->getExtensions().textureBorderClampOES && + context->getClientVersion() < ES_3_2) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled); + return false; + } + break; + + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + + if (length) + { + *length = GetSamplerParameterCount(pname); + } + return true; +} + +bool ValidateGetInternalFormativBase(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei bufSize, + GLsizei *numParams) +{ + if (numParams) + { + *numParams = 0; + } + + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat); + if (!formatCaps.renderbuffer) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kFormatNotRenderable); + return false; + } + + switch (target) + { + case GL_RENDERBUFFER: + break; + + case GL_TEXTURE_2D_MULTISAMPLE: + if (context->getClientVersion() < ES_3_1 && + !context->getExtensions().textureMultisampleANGLE) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kMultisampleTextureExtensionOrES31Required); + return false; + } + break; + case GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES: + if (!context->getExtensions().textureStorageMultisample2dArrayOES) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kMultisampleArrayExtensionRequired); + return false; + } + break; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTarget); + return false; + } + + if (bufSize < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInsufficientBufferSize); + return false; + } + + GLsizei maxWriteParams = 0; + switch (pname) + { + case GL_NUM_SAMPLE_COUNTS: + maxWriteParams = 1; + break; + + case GL_SAMPLES: + maxWriteParams = static_cast(formatCaps.sampleCounts.size()); + break; + + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + + if (numParams) + { + // glGetInternalFormativ will not overflow bufSize + *numParams = std::min(bufSize, maxWriteParams); + } + + return true; +} + +bool ValidateFramebufferNotMultisampled(const Context *context, + angle::EntryPoint entryPoint, + const Framebuffer *framebuffer, + bool checkReadBufferResourceSamples) +{ + int samples = checkReadBufferResourceSamples + ? framebuffer->getReadBufferResourceSamples(context) + : framebuffer->getSamples(context); + if (samples != 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInvalidMultisampledFramebufferOperation); + return false; + } + return true; +} + +bool ValidateMultitextureUnit(const Context *context, angle::EntryPoint entryPoint, GLenum texture) +{ + if (texture < GL_TEXTURE0 || texture >= GL_TEXTURE0 + context->getCaps().maxMultitextureUnits) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidMultitextureUnit); + return false; + } + return true; +} + +bool ValidateTexStorageMultisample(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLsizei samples, + GLint internalFormat, + GLsizei width, + GLsizei height) +{ + const Caps &caps = context->getCaps(); + if (width > caps.max2DTextureSize || height > caps.max2DTextureSize) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kTextureWidthOrHeightOutOfRange); + return false; + } + + if (samples == 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kSamplesZero); + return false; + } + + const TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat); + if (!formatCaps.textureAttachment) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kRenderableInternalFormat); + return false; + } + + // The ES3.1 spec(section 8.8) states that an INVALID_ENUM error is generated if internalformat + // is one of the unsized base internalformats listed in table 8.11. + const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat); + if (formatInfo.internalFormat == GL_NONE) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kUnsizedInternalFormatUnsupported); + return false; + } + + if (static_cast(samples) > formatCaps.getMaxSamples()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kSamplesOutOfRange); + return false; + } + + Texture *texture = context->getTextureByType(target); + if (!texture || texture->id().value == 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kZeroBoundToTarget); + return false; + } + + if (texture->getImmutableFormat()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kImmutableTextureBound); + return false; + } + return true; +} + +bool ValidateTexStorage2DMultisampleBase(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLsizei samples, + GLint internalFormat, + GLsizei width, + GLsizei height) +{ + if (target != TextureType::_2DMultisample) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTarget); + return false; + } + + if (width < 1 || height < 1) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kTextureSizeTooSmall); + return false; + } + + return ValidateTexStorageMultisample(context, entryPoint, target, samples, internalFormat, + width, height); +} + +bool ValidateGetTexLevelParameterBase(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum pname, + GLsizei *length) +{ + + if (length) + { + *length = 0; + } + + TextureType type = TextureTargetToType(target); + + if (!ValidTexLevelDestinationTarget(context, type)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + + if (context->getTextureByType(type) == nullptr) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kTextureNotBound); + return false; + } + + if (!ValidMipLevel(context, type, level)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel); + return false; + } + + switch (pname) + { + case GL_TEXTURE_RED_TYPE: + case GL_TEXTURE_GREEN_TYPE: + case GL_TEXTURE_BLUE_TYPE: + case GL_TEXTURE_ALPHA_TYPE: + case GL_TEXTURE_DEPTH_TYPE: + case GL_TEXTURE_RED_SIZE: + case GL_TEXTURE_GREEN_SIZE: + case GL_TEXTURE_BLUE_SIZE: + case GL_TEXTURE_ALPHA_SIZE: + case GL_TEXTURE_DEPTH_SIZE: + case GL_TEXTURE_STENCIL_SIZE: + case GL_TEXTURE_SHARED_SIZE: + case GL_TEXTURE_INTERNAL_FORMAT: + case GL_TEXTURE_WIDTH: + case GL_TEXTURE_HEIGHT: + case GL_TEXTURE_DEPTH: + case GL_TEXTURE_SAMPLES: + case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS: + case GL_TEXTURE_COMPRESSED: + break; + + case GL_RESOURCE_INITIALIZED_ANGLE: + if (!context->getExtensions().robustResourceInitializationANGLE) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kRobustResourceInitializationExtensionRequired); + return false; + } + break; + + case GL_TEXTURE_BUFFER_DATA_STORE_BINDING: + case GL_TEXTURE_BUFFER_OFFSET: + case GL_TEXTURE_BUFFER_SIZE: + if (context->getClientVersion() < Version(3, 2) && + !context->getExtensions().textureBufferAny()) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kTextureBufferExtensionNotAvailable); + return false; + } + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname); + return false; + } + + if (length) + { + *length = 1; + } + return true; +} + +bool ValidateGetMultisamplefvBase(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLuint index, + const GLfloat *val) +{ + if (pname != GL_SAMPLE_POSITION) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname); + return false; + } + + Framebuffer *framebuffer = context->getState().getDrawFramebuffer(); + GLint samples = framebuffer->getSamples(context); + + if (index >= static_cast(samples)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsSamples); + return false; + } + + return true; +} + +bool ValidateSampleMaskiBase(const Context *context, + angle::EntryPoint entryPoint, + GLuint maskNumber, + GLbitfield mask) +{ + if (maskNumber >= static_cast(context->getCaps().maxSampleMaskWords)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidSampleMaskNumber); + return false; + } + + return true; +} + +void RecordDrawAttribsError(const Context *context, angle::EntryPoint entryPoint) +{ + // An overflow can happen when adding the offset. Check against a special constant. + if (context->getStateCache().getNonInstancedVertexElementLimit() == + VertexAttribute::kIntegerOverflow || + context->getStateCache().getInstancedVertexElementLimit() == + VertexAttribute::kIntegerOverflow) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kIntegerOverflow); + } + else + { + // [OpenGL ES 3.0.2] section 2.9.4 page 40: + // We can return INVALID_OPERATION if our buffer does not have enough backing data. + context->validationError(entryPoint, GL_INVALID_OPERATION, kInsufficientVertexBufferSize); + } +} + +bool ValidateLoseContextCHROMIUM(const Context *context, + angle::EntryPoint entryPoint, + GraphicsResetStatus current, + GraphicsResetStatus other) +{ + if (!context->getExtensions().loseContextCHROMIUM) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + switch (current) + { + case GraphicsResetStatus::GuiltyContextReset: + case GraphicsResetStatus::InnocentContextReset: + case GraphicsResetStatus::UnknownContextReset: + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidResetStatus); + } + + switch (other) + { + case GraphicsResetStatus::GuiltyContextReset: + case GraphicsResetStatus::InnocentContextReset: + case GraphicsResetStatus::UnknownContextReset: + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidResetStatus); + } + + return true; +} + +// GL_ANGLE_texture_storage_external +bool ValidateTexImage2DExternalANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type) +{ + if (!context->getExtensions().textureExternalUpdateANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (!ValidTexture2DDestinationTarget(context, target) && + !ValidTextureExternalTarget(context, target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + + if (context->getClientMajorVersion() <= 2) + { + if (!ValidateES2TexImageParametersBase(context, entryPoint, target, level, internalformat, + false, false, 0, 0, width, height, border, format, + type, -1, nullptr)) + { + return false; + } + } + else + { + if (!ValidateES3TexImageParametersBase(context, entryPoint, target, level, internalformat, + false, false, 0, 0, 0, width, height, 1, border, + format, type, -1, nullptr)) + { + return false; + } + } + + return true; +} + +bool ValidateInvalidateTextureANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureType target) +{ + if (!context->getExtensions().textureExternalUpdateANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + + return true; +} + +bool ValidateProgramExecutableXFBBuffersPresent(const Context *context, + const ProgramExecutable *programExecutable) +{ + size_t programXfbCount = programExecutable->getTransformFeedbackBufferCount(); + const TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback(); + for (size_t programXfbIndex = 0; programXfbIndex < programXfbCount; ++programXfbIndex) + { + const OffsetBindingPointer &buffer = + transformFeedback->getIndexedBuffer(programXfbIndex); + if (!buffer.get()) + { + return false; + } + } + + return true; +} + +bool ValidateLogicOpCommon(const Context *context, + angle::EntryPoint entryPoint, + LogicalOperation opcodePacked) +{ + switch (opcodePacked) + { + case LogicalOperation::And: + case LogicalOperation::AndInverted: + case LogicalOperation::AndReverse: + case LogicalOperation::Clear: + case LogicalOperation::Copy: + case LogicalOperation::CopyInverted: + case LogicalOperation::Equiv: + case LogicalOperation::Invert: + case LogicalOperation::Nand: + case LogicalOperation::Noop: + case LogicalOperation::Nor: + case LogicalOperation::Or: + case LogicalOperation::OrInverted: + case LogicalOperation::OrReverse: + case LogicalOperation::Set: + case LogicalOperation::Xor: + return true; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidLogicOp); + return false; + } +} +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/validationES.h b/gfx/angle/checkout/src/libANGLE/validationES.h new file mode 100644 index 0000000000..685e1e505b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationES.h @@ -0,0 +1,1272 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// validationES.h: Validation functions for generic OpenGL ES entry point parameters + +#ifndef LIBANGLE_VALIDATION_ES_H_ +#define LIBANGLE_VALIDATION_ES_H_ + +#include "common/PackedEnums.h" +#include "common/mathutil.h" +#include "common/utilities.h" +#include "libANGLE/Context.h" +#include "libANGLE/ErrorStrings.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/VertexArray.h" + +#include +#include +#include + +namespace egl +{ +class Display; +class Image; +} // namespace egl + +namespace gl +{ +class Context; +struct Format; +class Framebuffer; +struct LinkedUniform; +class Program; +class Shader; + +void SetRobustLengthParam(const GLsizei *length, GLsizei value); +bool ValidTextureTarget(const Context *context, TextureType type); +bool ValidTexture2DTarget(const Context *context, TextureType type); +bool ValidTexture3DTarget(const Context *context, TextureType target); +bool ValidTextureExternalTarget(const Context *context, TextureType target); +bool ValidTextureExternalTarget(const Context *context, TextureTarget target); +bool ValidTexture2DDestinationTarget(const Context *context, TextureTarget target); +bool ValidTexture3DDestinationTarget(const Context *context, TextureTarget target); +bool ValidTexLevelDestinationTarget(const Context *context, TextureType type); +bool ValidFramebufferTarget(const Context *context, GLenum target); +bool ValidMipLevel(const Context *context, TextureType type, GLint level); +bool ValidImageSizeParameters(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLint level, + GLsizei width, + GLsizei height, + GLsizei depth, + bool isSubImage); +bool ValidCompressedImageSize(const Context *context, + GLenum internalFormat, + GLint level, + GLsizei width, + GLsizei height, + GLsizei depth); +bool ValidCompressedSubImageSize(const Context *context, + GLenum internalFormat, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + size_t textureWidth, + size_t textureHeight, + size_t textureDepth); +bool ValidImageDataSize(const Context *context, + angle::EntryPoint entryPoint, + TextureType texType, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *pixels, + GLsizei imageSize); + +bool ValidQueryType(const Context *context, QueryType queryType); + +bool ValidateWebGLVertexAttribPointer(const Context *context, + angle::EntryPoint entryPoint, + VertexAttribType type, + GLboolean normalized, + GLsizei stride, + const void *ptr, + bool pureInteger); + +// Returns valid program if id is a valid program name +// Errors INVALID_OPERATION if valid shader is given and returns NULL +// Errors INVALID_VALUE otherwise and returns NULL +Program *GetValidProgram(const Context *context, angle::EntryPoint entryPoint, ShaderProgramID id); + +// Returns valid shader if id is a valid shader name +// Errors INVALID_OPERATION if valid program is given and returns NULL +// Errors INVALID_VALUE otherwise and returns NULL +Shader *GetValidShader(const Context *context, angle::EntryPoint entryPoint, ShaderProgramID id); + +bool ValidateAttachmentTarget(const Context *context, + angle::EntryPoint entryPoint, + GLenum attachment); + +bool ValidateBlitFramebufferParameters(const Context *context, + angle::EntryPoint entryPoint, + GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter); + +bool ValidateBindFramebufferBase(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + FramebufferID framebuffer); +bool ValidateBindRenderbufferBase(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + RenderbufferID renderbuffer); +bool ValidateFramebufferParameteriBase(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum pname, + GLint param); +bool ValidateFramebufferRenderbufferBase(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + GLenum renderbuffertarget, + RenderbufferID renderbuffer); +bool ValidateFramebufferTextureBase(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + TextureID texture, + GLint level); +bool ValidateGenerateMipmapBase(const Context *context, + angle::EntryPoint entryPoint, + TextureType target); + +bool ValidateRenderbufferStorageParametersBase(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height); + +bool ValidatePixelPack(const Context *context, + angle::EntryPoint entryPoint, + GLenum format, + GLenum type, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLsizei bufSize, + GLsizei *length, + const void *pixels); + +bool ValidateReadPixelsBase(const Context *context, + angle::EntryPoint entryPoint, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + GLsizei *length, + GLsizei *columns, + GLsizei *rows, + const void *pixels); +bool ValidateReadPixelsRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + const GLsizei *length, + const GLsizei *columns, + const GLsizei *rows, + const void *pixels); +bool ValidateReadnPixelsEXT(const Context *context, + angle::EntryPoint entryPoint, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels); +bool ValidateReadnPixelsRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + const GLsizei *length, + const GLsizei *columns, + const GLsizei *rows, + const void *data); + +bool ValidateGenQueriesEXT(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const QueryID *ids); +bool ValidateDeleteQueriesEXT(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const QueryID *ids); +bool ValidateIsQueryEXT(const Context *context, angle::EntryPoint entryPoint, QueryID id); +bool ValidateBeginQueryBase(const Context *context, + angle::EntryPoint entryPoint, + QueryType target, + QueryID id); +bool ValidateBeginQueryEXT(const Context *context, + angle::EntryPoint entryPoint, + QueryType target, + QueryID id); +bool ValidateEndQueryBase(const Context *context, angle::EntryPoint entryPoint, QueryType target); +bool ValidateEndQueryEXT(const Context *context, angle::EntryPoint entryPoint, QueryType target); +bool ValidateQueryCounterEXT(const Context *context, + angle::EntryPoint entryPoint, + QueryID id, + QueryType target); +bool ValidateGetQueryivBase(const Context *context, + angle::EntryPoint entryPoint, + QueryType target, + GLenum pname, + GLsizei *numParams); +bool ValidateGetQueryivEXT(const Context *context, + angle::EntryPoint entryPoint, + QueryType target, + GLenum pname, + const GLint *params); +bool ValidateGetQueryivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + QueryType target, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params); +bool ValidateGetQueryObjectValueBase(const Context *context, + angle::EntryPoint entryPoint, + QueryID id, + GLenum pname, + GLsizei *numParams); +bool ValidateGetQueryObjectivEXT(const Context *context, + angle::EntryPoint entryPoint, + QueryID id, + GLenum pname, + const GLint *params); +bool ValidateGetQueryObjectivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + QueryID id, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params); +bool ValidateGetQueryObjectuivEXT(const Context *context, + angle::EntryPoint entryPoint, + QueryID id, + GLenum pname, + const GLuint *params); +bool ValidateGetQueryObjectuivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + QueryID id, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLuint *params); +bool ValidateGetQueryObjecti64vEXT(const Context *context, + angle::EntryPoint entryPoint, + QueryID id, + GLenum pname, + GLint64 *params); +bool ValidateGetQueryObjecti64vRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + QueryID id, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + GLint64 *params); +bool ValidateGetQueryObjectui64vEXT(const Context *context, + angle::EntryPoint entryPoint, + QueryID id, + GLenum pname, + GLuint64 *params); +bool ValidateGetQueryObjectui64vRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + QueryID id, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + GLuint64 *params); + +bool ValidateUniformCommonBase(const Context *context, + angle::EntryPoint entryPoint, + const Program *program, + UniformLocation location, + GLsizei count, + const LinkedUniform **uniformOut); +bool ValidateUniform1ivValue(const Context *context, + angle::EntryPoint entryPoint, + GLenum uniformType, + GLsizei count, + const GLint *value); + +ANGLE_INLINE bool ValidateUniformValue(const Context *context, + angle::EntryPoint entryPoint, + GLenum valueType, + GLenum uniformType) +{ + // Check that the value type is compatible with uniform type. + // Do the cheaper test first, for a little extra speed. + if (valueType != uniformType && VariableBoolVectorType(valueType) != uniformType) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, err::kUniformSizeMismatch); + return false; + } + return true; +} + +bool ValidateUniformMatrixValue(const Context *context, + angle::EntryPoint entryPoint, + GLenum valueType, + GLenum uniformType); +bool ValidateUniform(const Context *context, + angle::EntryPoint entryPoint, + GLenum uniformType, + UniformLocation location, + GLsizei count); +bool ValidateUniformMatrix(const Context *context, + angle::EntryPoint entryPoint, + GLenum matrixType, + UniformLocation location, + GLsizei count, + GLboolean transpose); +bool ValidateGetBooleanvRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLboolean *params); +bool ValidateGetFloatvRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLfloat *params); +bool ValidateStateQuery(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLenum *nativeType, + unsigned int *numParams); +bool ValidateGetIntegervRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *data); +bool ValidateGetInteger64vRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + GLint64 *data); +bool ValidateRobustStateQuery(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLsizei bufSize, + GLenum *nativeType, + unsigned int *numParams); + +bool ValidateCopyImageSubDataBase(const Context *context, + angle::EntryPoint entryPoint, + GLuint srcName, + GLenum srcTarget, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLuint dstName, + GLenum dstTarget, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth); + +bool ValidateCopyTexImageParametersBase(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum internalformat, + bool isSubImage, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border, + Format *textureFormatOut); + +void RecordDrawModeError(const Context *context, angle::EntryPoint entryPoint, PrimitiveMode mode); +const char *ValidateDrawElementsStates(const Context *context); + +ANGLE_INLINE bool ValidateDrawBase(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode) +{ + intptr_t drawStatesError = context->getStateCache().getBasicDrawStatesError(context); + if (drawStatesError) + { + const char *errorMessage = reinterpret_cast(drawStatesError); + + // All errors from ValidateDrawStates should return INVALID_OPERATION except Framebuffer + // Incomplete. + bool isFramebufferIncomplete = strcmp(errorMessage, err::kDrawFramebufferIncomplete) == 0; + GLenum errorCode = + isFramebufferIncomplete ? GL_INVALID_FRAMEBUFFER_OPERATION : GL_INVALID_OPERATION; + context->validationError(entryPoint, errorCode, errorMessage); + return false; + } + + if (!context->getStateCache().isValidDrawMode(mode)) + { + RecordDrawModeError(context, entryPoint, mode); + return false; + } + + return true; +} + +bool ValidateDrawArraysInstancedBase(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLint first, + GLsizei count, + GLsizei primcount); +bool ValidateDrawArraysInstancedANGLE(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLint first, + GLsizei count, + GLsizei primcount); +bool ValidateDrawArraysInstancedEXT(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLint first, + GLsizei count, + GLsizei primcount); + +bool ValidateDrawElementsInstancedBase(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLsizei count, + DrawElementsType type, + const void *indices, + GLsizei primcount); +bool ValidateDrawElementsInstancedANGLE(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLsizei count, + DrawElementsType type, + const void *indices, + GLsizei primcount); +bool ValidateDrawElementsInstancedEXT(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLsizei count, + DrawElementsType type, + const void *indices, + GLsizei primcount); + +bool ValidateDrawInstancedANGLE(const Context *context, angle::EntryPoint entryPoint); + +bool ValidateGetUniformBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location); +bool ValidateSizedGetUniform(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + GLsizei *length); +bool ValidateGetnUniformfvEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + const GLfloat *params); +bool ValidateGetnUniformfvRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + const GLsizei *length, + const GLfloat *params); +bool ValidateGetnUniformivEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + const GLint *params); +bool ValidateGetnUniformivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + const GLsizei *length, + const GLint *params); +bool ValidateGetnUniformuivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + const GLsizei *length, + const GLuint *params); +bool ValidateGetUniformfvRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + const GLsizei *length, + const GLfloat *params); +bool ValidateGetUniformivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + const GLsizei *length, + const GLint *params); +bool ValidateGetUniformuivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + const GLsizei *length, + const GLuint *params); + +bool ValidateDiscardFramebufferBase(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLsizei numAttachments, + const GLenum *attachments, + bool defaultFramebuffer); + +bool ValidateInsertEventMarkerEXT(const Context *context, + angle::EntryPoint entryPoint, + GLsizei length, + const char *marker); +bool ValidatePushGroupMarkerEXT(const Context *context, + angle::EntryPoint entryPoint, + GLsizei length, + const char *marker); +bool ValidateEGLImageObject(const Context *context, + angle::EntryPoint entryPoint, + TextureType type, + GLeglImageOES image); +bool ValidateEGLImageTargetTexture2DOES(const Context *context, + angle::EntryPoint entryPoint, + TextureType type, + GLeglImageOES image); +bool ValidateEGLImageTargetRenderbufferStorageOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLeglImageOES image); + +bool ValidateProgramBinaryBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLenum binaryFormat, + const void *binary, + GLint length); +bool ValidateGetProgramBinaryBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLsizei bufSize, + const GLsizei *length, + const GLenum *binaryFormat, + const void *binary); + +bool ValidateDrawBuffersBase(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const GLenum *bufs); + +bool ValidateGetBufferPointervBase(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding target, + GLenum pname, + GLsizei *length, + void *const *params); +bool ValidateUnmapBufferBase(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding target); +bool ValidateMapBufferRangeBase(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding target, + GLintptr offset, + GLsizeiptr length, + GLbitfield access); +bool ValidateFlushMappedBufferRangeBase(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding target, + GLintptr offset, + GLsizeiptr length); + +bool ValidateGenOrDelete(const Context *context, angle::EntryPoint entryPoint, GLint n); + +bool ValidateRobustEntryPoint(const Context *context, + angle::EntryPoint entryPoint, + GLsizei bufSize); +bool ValidateRobustBufferSize(const Context *context, + angle::EntryPoint entryPoint, + GLsizei bufSize, + GLsizei numParams); + +bool ValidateGetFramebufferAttachmentParameterivBase(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + GLenum pname, + GLsizei *numParams); + +bool ValidateGetFramebufferParameterivBase(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum pname, + const GLint *params); + +bool ValidateGetBufferParameterBase(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding target, + GLenum pname, + bool pointerVersion, + GLsizei *numParams); + +bool ValidateGetProgramivBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLenum pname, + GLsizei *numParams); + +bool ValidateGetRenderbufferParameterivBase(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum pname, + GLsizei *length); + +bool ValidateGetShaderivBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID shader, + GLenum pname, + GLsizei *length); + +bool ValidateGetTexParameterBase(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum pname, + GLsizei *length); + +template +bool ValidateTexParameterBase(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum pname, + GLsizei bufSize, + bool vectorParams, + const ParamType *params); + +bool ValidateGetVertexAttribBase(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum pname, + GLsizei *length, + bool pointer, + bool pureIntegerEntryPoint); + +ANGLE_INLINE bool ValidateVertexFormat(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLint size, + VertexAttribTypeCase validation) +{ + const Caps &caps = context->getCaps(); + if (index >= static_cast(caps.maxVertexAttributes)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + err::kIndexExceedsMaxVertexAttribute); + return false; + } + + switch (validation) + { + case VertexAttribTypeCase::Invalid: + context->validationError(entryPoint, GL_INVALID_ENUM, err::kInvalidType); + return false; + case VertexAttribTypeCase::Valid: + if (size < 1 || size > 4) + { + context->validationError(entryPoint, GL_INVALID_VALUE, err::kInvalidVertexAttrSize); + return false; + } + break; + case VertexAttribTypeCase::ValidSize4Only: + if (size != 4) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + err::kInvalidVertexAttribSize2101010); + return false; + } + break; + case VertexAttribTypeCase::ValidSize3or4: + if (size != 3 && size != 4) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + err::kInvalidVertexAttribSize1010102); + return false; + } + break; + } + + return true; +} + +// Note: These byte, short, and int types are all converted to float for the shader. +ANGLE_INLINE bool ValidateFloatVertexFormat(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLint size, + VertexAttribType type) +{ + return ValidateVertexFormat(context, entryPoint, index, size, + context->getStateCache().getVertexAttribTypeValidation(type)); +} + +ANGLE_INLINE bool ValidateIntegerVertexFormat(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLint size, + VertexAttribType type) +{ + return ValidateVertexFormat( + context, entryPoint, index, size, + context->getStateCache().getIntegerVertexAttribTypeValidation(type)); +} + +bool ValidateWebGLFramebufferAttachmentClearType(const Context *context, + angle::EntryPoint entryPoint, + GLint drawbuffer, + const GLenum *validComponentTypes, + size_t validComponentTypeCount); + +bool ValidateRobustCompressedTexImageBase(const Context *context, + angle::EntryPoint entryPoint, + GLsizei imageSize, + GLsizei dataSize); + +bool ValidateVertexAttribIndex(const Context *context, angle::EntryPoint entryPoint, GLuint index); + +bool ValidateGetActiveUniformBlockivBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformBlockIndex uniformBlockIndex, + GLenum pname, + GLsizei *length); + +bool ValidateGetSamplerParameterBase(const Context *context, + angle::EntryPoint entryPoint, + SamplerID sampler, + GLenum pname, + GLsizei *length); + +template +bool ValidateSamplerParameterBase(const Context *context, + angle::EntryPoint entryPoint, + SamplerID sampler, + GLenum pname, + GLsizei bufSize, + bool vectorParams, + const ParamType *params); + +bool ValidateGetInternalFormativBase(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei bufSize, + GLsizei *numParams); + +bool ValidateFramebufferNotMultisampled(const Context *context, + angle::EntryPoint entryPoint, + const Framebuffer *framebuffer, + bool checkReadBufferResourceSamples); + +bool ValidateMultitextureUnit(const Context *context, angle::EntryPoint entryPoint, GLenum texture); + +bool ValidateTransformFeedbackPrimitiveMode(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode transformFeedbackPrimitiveMode, + PrimitiveMode renderPrimitiveMode); + +// Common validation for 2D and 3D variants of TexStorage*Multisample. +bool ValidateTexStorageMultisample(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLsizei samples, + GLint internalFormat, + GLsizei width, + GLsizei height); + +bool ValidateTexStorage2DMultisampleBase(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLsizei samples, + GLint internalFormat, + GLsizei width, + GLsizei height); + +bool ValidateGetTexLevelParameterBase(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum pname, + GLsizei *length); + +bool ValidateMapBufferBase(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding target); +bool ValidateIndexedStateQuery(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLuint index, + GLsizei *length); +bool ValidateES3TexImage2DParameters(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum internalformat, + bool isCompressed, + bool isSubImage, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + GLsizei imageSize, + const void *pixels); +bool ValidateES3CopyTexImage2DParameters(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum internalformat, + bool isSubImage, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border); +bool ValidateES3TexStorageParametersBase(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth); +bool ValidateES3TexStorage2DParameters(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth); +bool ValidateES3TexStorage3DParameters(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth); + +bool ValidateGetMultisamplefvBase(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLuint index, + const GLfloat *val); +bool ValidateSampleMaskiBase(const Context *context, + angle::EntryPoint entryPoint, + GLuint maskNumber, + GLbitfield mask); + +bool ValidateProgramExecutableXFBBuffersPresent(const Context *context, + const ProgramExecutable *programExecutable); + +// We should check with Khronos if returning INVALID_FRAMEBUFFER_OPERATION is OK when querying +// implementation format info for incomplete framebuffers. It seems like these queries are +// incongruent with the other errors. +// Inlined for speed. +template +ANGLE_INLINE bool ValidateFramebufferComplete(const Context *context, + angle::EntryPoint entryPoint, + const Framebuffer *framebuffer) +{ + const FramebufferStatus &framebufferStatus = framebuffer->checkStatus(context); + if (!framebufferStatus.isComplete()) + { + ASSERT(framebufferStatus.reason != nullptr); + context->validationError(entryPoint, ErrorCode, framebufferStatus.reason); + return false; + } + + return true; +} + +const char *ValidateProgramPipelineDrawStates(const State &state, + const Extensions &extensions, + ProgramPipeline *programPipeline); +const char *ValidateProgramPipelineAttachedPrograms(ProgramPipeline *programPipeline); +const char *ValidateDrawStates(const Context *context); +const char *ValidateProgramPipeline(const Context *context); + +void RecordDrawAttribsError(const Context *context, angle::EntryPoint entryPoint); + +ANGLE_INLINE bool ValidateDrawAttribs(const Context *context, + angle::EntryPoint entryPoint, + int64_t maxVertex) +{ + if (maxVertex > context->getStateCache().getNonInstancedVertexElementLimit()) + { + RecordDrawAttribsError(context, entryPoint); + return false; + } + + return true; +} + +ANGLE_INLINE bool ValidateDrawArraysAttribs(const Context *context, + angle::EntryPoint entryPoint, + GLint first, + GLsizei count) +{ + if (!context->isBufferAccessValidationEnabled()) + { + return true; + } + + // Check the computation of maxVertex doesn't overflow. + // - first < 0 has been checked as an error condition. + // - if count <= 0, skip validating no-op draw calls. + // From this we know maxVertex will be positive, and only need to check if it overflows GLint. + ASSERT(first >= 0); + ASSERT(count > 0); + int64_t maxVertex = static_cast(first) + static_cast(count) - 1; + if (maxVertex > static_cast(std::numeric_limits::max())) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, err::kIntegerOverflow); + return false; + } + + return ValidateDrawAttribs(context, entryPoint, maxVertex); +} + +ANGLE_INLINE bool ValidateDrawInstancedAttribs(const Context *context, + angle::EntryPoint entryPoint, + GLint primcount) +{ + if (!context->isBufferAccessValidationEnabled()) + { + return true; + } + + if ((primcount - 1) > context->getStateCache().getInstancedVertexElementLimit()) + { + RecordDrawAttribsError(context, entryPoint); + return false; + } + + return true; +} + +ANGLE_INLINE bool ValidateDrawArraysCommon(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLint first, + GLsizei count, + GLsizei primcount) +{ + if (first < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, err::kNegativeStart); + return false; + } + + if (count <= 0) + { + if (count < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, err::kNegativeCount); + return false; + } + + // Early exit. + return ValidateDrawBase(context, entryPoint, mode); + } + + if (primcount <= 0) + { + if (primcount < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, err::kNegativeCount); + return false; + } + // Early exit. + return ValidateDrawBase(context, entryPoint, mode); + } + + if (!ValidateDrawBase(context, entryPoint, mode)) + { + return false; + } + + if (context->getStateCache().isTransformFeedbackActiveUnpaused() && + !context->supportsGeometryOrTesselation()) + { + const State &state = context->getState(); + TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback(); + if (!curTransformFeedback->checkBufferSpaceForDraw(count, primcount)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + err::kTransformFeedbackBufferTooSmall); + return false; + } + } + + return ValidateDrawArraysAttribs(context, entryPoint, first, count); +} + +ANGLE_INLINE bool ValidateDrawElementsBase(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + DrawElementsType type) +{ + if (!context->getStateCache().isValidDrawElementsType(type)) + { + if (type == DrawElementsType::UnsignedInt) + { + context->validationError(entryPoint, GL_INVALID_ENUM, err::kTypeNotUnsignedShortByte); + return false; + } + + ASSERT(type == DrawElementsType::InvalidEnum); + context->validationErrorF(entryPoint, GL_INVALID_ENUM, err::kEnumInvalid); + return false; + } + + intptr_t drawElementsError = context->getStateCache().getBasicDrawElementsError(context); + if (drawElementsError) + { + // All errors from ValidateDrawElementsStates return INVALID_OPERATION. + const char *errorMessage = reinterpret_cast(drawElementsError); + context->validationError(entryPoint, GL_INVALID_OPERATION, errorMessage); + return false; + } + + // Note that we are missing overflow checks for active transform feedback buffers. + return true; +} + +ANGLE_INLINE bool ValidateDrawElementsCommon(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLsizei count, + DrawElementsType type, + const void *indices, + GLsizei primcount) +{ + if (!ValidateDrawElementsBase(context, entryPoint, mode, type)) + { + return false; + } + + ASSERT(isPow2(GetDrawElementsTypeSize(type)) && GetDrawElementsTypeSize(type) > 0); + + if (context->isWebGL()) + { + GLuint typeBytes = GetDrawElementsTypeSize(type); + + if ((reinterpret_cast(indices) & static_cast(typeBytes - 1)) != 0) + { + // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements + // The offset arguments to drawElements and [...], must be a multiple of the size of the + // data type passed to the call, or an INVALID_OPERATION error is generated. + context->validationError(entryPoint, GL_INVALID_OPERATION, + err::kOffsetMustBeMultipleOfType); + return false; + } + + // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements + // In addition the offset argument to drawElements must be non-negative or an INVALID_VALUE + // error is generated. + if (reinterpret_cast(indices) < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, err::kNegativeOffset); + return false; + } + } + + if (count <= 0) + { + if (count < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, err::kNegativeCount); + return false; + } + + // Early exit. + return ValidateDrawBase(context, entryPoint, mode); + } + + if (!ValidateDrawBase(context, entryPoint, mode)) + { + return false; + } + + const State &state = context->getState(); + const VertexArray *vao = state.getVertexArray(); + Buffer *elementArrayBuffer = vao->getElementArrayBuffer(); + + if (!elementArrayBuffer) + { + if (!indices) + { + // This is an application error that would normally result in a crash, but we catch + // it and return an error + context->validationError(entryPoint, GL_INVALID_OPERATION, + err::kElementArrayNoBufferOrPointer); + return false; + } + } + else + { + // The max possible type size is 8 and count is on 32 bits so doing the multiplication + // in a 64 bit integer is safe. Also we are guaranteed that here count > 0. + static_assert(std::is_same::value, "GLsizei isn't the expected type"); + constexpr uint64_t kMaxTypeSize = 8; + constexpr uint64_t kIntMax = std::numeric_limits::max(); + constexpr uint64_t kUint64Max = std::numeric_limits::max(); + static_assert(kIntMax < kUint64Max / kMaxTypeSize, ""); + + uint64_t elementCount = static_cast(count); + ASSERT(elementCount > 0 && GetDrawElementsTypeSize(type) <= kMaxTypeSize); + + // Doing the multiplication here is overflow-safe + uint64_t elementDataSizeNoOffset = elementCount << GetDrawElementsTypeShift(type); + + // The offset can be any value, check for overflows + uint64_t offset = static_cast(reinterpret_cast(indices)); + uint64_t elementDataSizeWithOffset = elementDataSizeNoOffset + offset; + if (elementDataSizeWithOffset < elementDataSizeNoOffset) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, err::kIntegerOverflow); + return false; + } + + // Related to possible test bug: https://github.com/KhronosGroup/WebGL/issues/3064 + if ((elementDataSizeWithOffset > static_cast(elementArrayBuffer->getSize())) && + (primcount > 0)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + err::kInsufficientBufferSize); + return false; + } + } + + if (context->isBufferAccessValidationEnabled() && primcount > 0) + { + // Use the parameter buffer to retrieve and cache the index range. + IndexRange indexRange{IndexRange::Undefined()}; + ANGLE_VALIDATION_TRY(vao->getIndexRange(context, type, count, indices, &indexRange)); + + // If we use an index greater than our maximum supported index range, return an error. + // The ES3 spec does not specify behaviour here, it is undefined, but ANGLE should + // always return an error if possible here. + if (static_cast(indexRange.end) >= context->getCaps().maxElementIndex) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, err::kExceedsMaxElement); + return false; + } + + if (!ValidateDrawAttribs(context, entryPoint, static_cast(indexRange.end))) + { + return false; + } + + // No op if there are no real indices in the index data (all are primitive restart). + return (indexRange.vertexIndexCount > 0); + } + + return true; +} + +ANGLE_INLINE bool ValidateBindVertexArrayBase(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID array) +{ + if (!context->isVertexArrayGenerated(array)) + { + // The default VAO should always exist + ASSERT(array.value != 0); + context->validationError(entryPoint, GL_INVALID_OPERATION, err::kInvalidVertexArray); + return false; + } + + return true; +} + +ANGLE_INLINE bool ValidateVertexAttribIndex(const Context *context, + angle::EntryPoint entryPoint, + GLuint index) +{ + if (index >= static_cast(context->getCaps().maxVertexAttributes)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + err::kIndexExceedsMaxVertexAttribute); + return false; + } + + return true; +} + +bool ValidateLogicOpCommon(const Context *context, + angle::EntryPoint entryPoint, + LogicalOperation opcodePacked); +} // namespace gl + +#endif // LIBANGLE_VALIDATION_ES_H_ diff --git a/gfx/angle/checkout/src/libANGLE/validationES1.cpp b/gfx/angle/checkout/src/libANGLE/validationES1.cpp new file mode 100644 index 0000000000..f872689492 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationES1.cpp @@ -0,0 +1,2129 @@ +// +// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// validationES1.cpp: Validation functions for OpenGL ES 1.0 entry point parameters + +#include "libANGLE/validationES1_autogen.h" + +#include "common/debug.h" +#include "libANGLE/Context.h" +#include "libANGLE/ErrorStrings.h" +#include "libANGLE/GLES1State.h" +#include "libANGLE/queryconversions.h" +#include "libANGLE/queryutils.h" +#include "libANGLE/validationES.h" + +#define ANGLE_VALIDATE_IS_GLES1(context, entryPoint) \ + do \ + { \ + if (context->getClientType() != EGL_OPENGL_API && context->getClientMajorVersion() > 1) \ + { \ + context->validationError(entryPoint, GL_INVALID_OPERATION, kGLES1Only); \ + return false; \ + } \ + } while (0) + +namespace gl +{ +using namespace err; + +bool ValidateAlphaFuncCommon(const Context *context, + angle::EntryPoint entryPoint, + AlphaTestFunc func) +{ + switch (func) + { + case AlphaTestFunc::AlwaysPass: + case AlphaTestFunc::Equal: + case AlphaTestFunc::Gequal: + case AlphaTestFunc::Greater: + case AlphaTestFunc::Lequal: + case AlphaTestFunc::Less: + case AlphaTestFunc::Never: + case AlphaTestFunc::NotEqual: + return true; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kEnumInvalid); + return false; + } +} + +bool ValidateClientStateCommon(const Context *context, + angle::EntryPoint entryPoint, + ClientVertexArrayType arrayType) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + switch (arrayType) + { + case ClientVertexArrayType::Vertex: + case ClientVertexArrayType::Normal: + case ClientVertexArrayType::Color: + case ClientVertexArrayType::TextureCoord: + return true; + case ClientVertexArrayType::PointSize: + if (!context->getExtensions().pointSizeArrayOES) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kPointSizeArrayExtensionNotEnabled); + return false; + } + return true; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidClientState); + return false; + } +} + +bool ValidateBuiltinVertexAttributeCommon(const Context *context, + angle::EntryPoint entryPoint, + ClientVertexArrayType arrayType, + GLint size, + VertexAttribType type, + GLsizei stride, + const void *pointer) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + + if (stride < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidVertexPointerStride); + return false; + } + + int minSize = 1; + int maxSize = 4; + + switch (arrayType) + { + case ClientVertexArrayType::Vertex: + case ClientVertexArrayType::TextureCoord: + minSize = 2; + maxSize = 4; + break; + case ClientVertexArrayType::Normal: + minSize = 3; + maxSize = 3; + break; + case ClientVertexArrayType::Color: + minSize = 4; + maxSize = 4; + break; + case ClientVertexArrayType::PointSize: + if (!context->getExtensions().pointSizeArrayOES) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kPointSizeArrayExtensionNotEnabled); + return false; + } + + minSize = 1; + maxSize = 1; + break; + default: + UNREACHABLE(); + return false; + } + + if (size < minSize || size > maxSize) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidVertexPointerSize); + return false; + } + + switch (type) + { + case VertexAttribType::Byte: + if (arrayType == ClientVertexArrayType::PointSize) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidVertexPointerType); + return false; + } + break; + case VertexAttribType::Short: + if (arrayType == ClientVertexArrayType::PointSize || + arrayType == ClientVertexArrayType::Color) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidVertexPointerType); + return false; + } + break; + case VertexAttribType::Fixed: + case VertexAttribType::Float: + break; + case VertexAttribType::UnsignedByte: + if (arrayType != ClientVertexArrayType::Color) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidVertexPointerType); + return false; + } + break; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidVertexPointerType); + return false; + } + + return true; +} + +bool ValidateLightCaps(const Context *context, angle::EntryPoint entryPoint, GLenum light) +{ + if (light < GL_LIGHT0 || light >= GL_LIGHT0 + context->getCaps().maxLights) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidLight); + return false; + } + + return true; +} + +bool ValidateLightCommon(const Context *context, + angle::EntryPoint entryPoint, + GLenum light, + LightParameter pname, + const GLfloat *params) +{ + + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + + if (!ValidateLightCaps(context, entryPoint, light)) + { + return false; + } + + switch (pname) + { + case LightParameter::Ambient: + case LightParameter::Diffuse: + case LightParameter::Specular: + case LightParameter::Position: + case LightParameter::SpotDirection: + return true; + case LightParameter::SpotExponent: + if (params[0] < 0.0f || params[0] > 128.0f) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kLightParameterOutOfRange); + return false; + } + return true; + case LightParameter::SpotCutoff: + if (params[0] == 180.0f) + { + return true; + } + if (params[0] < 0.0f || params[0] > 90.0f) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kLightParameterOutOfRange); + return false; + } + return true; + case LightParameter::ConstantAttenuation: + case LightParameter::LinearAttenuation: + case LightParameter::QuadraticAttenuation: + if (params[0] < 0.0f) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kLightParameterOutOfRange); + return false; + } + return true; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidLightParameter); + return false; + } +} + +bool ValidateLightSingleComponent(const Context *context, + angle::EntryPoint entryPoint, + GLenum light, + LightParameter pname, + GLfloat param) +{ + if (!ValidateLightCommon(context, entryPoint, light, pname, ¶m)) + { + return false; + } + + if (GetLightParameterCount(pname) > 1) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidLightParameter); + return false; + } + + return true; +} + +bool ValidateMaterialCommon(const Context *context, + angle::EntryPoint entryPoint, + GLenum face, + MaterialParameter pname, + const GLfloat *params) +{ + switch (pname) + { + case MaterialParameter::Ambient: + case MaterialParameter::AmbientAndDiffuse: + case MaterialParameter::Diffuse: + case MaterialParameter::Specular: + case MaterialParameter::Emission: + return true; + case MaterialParameter::Shininess: + if (params[0] < 0.0f || params[0] > 128.0f) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kMaterialParameterOutOfRange); + return false; + } + return true; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidMaterialParameter); + return false; + } +} + +bool ValidateMaterialSetting(const Context *context, + angle::EntryPoint entryPoint, + GLenum face, + MaterialParameter pname, + const GLfloat *params) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + + if (face != GL_FRONT_AND_BACK) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidMaterialFace); + return false; + } + + return ValidateMaterialCommon(context, entryPoint, face, pname, params); +} + +bool ValidateMaterialQuery(const Context *context, + angle::EntryPoint entryPoint, + GLenum face, + MaterialParameter pname) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + + if (face != GL_FRONT && face != GL_BACK) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidMaterialFace); + return false; + } + + GLfloat validateParams[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + + return ValidateMaterialCommon(context, entryPoint, face, pname, validateParams); +} + +bool ValidateMaterialSingleComponent(const Context *context, + angle::EntryPoint entryPoint, + GLenum face, + MaterialParameter pname, + GLfloat param) +{ + if (!ValidateMaterialSetting(context, entryPoint, face, pname, ¶m)) + { + return false; + } + + if (GetMaterialParameterCount(pname) > 1) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidMaterialParameter); + return false; + } + + return true; +} + +bool ValidateLightModelCommon(const Context *context, angle::EntryPoint entryPoint, GLenum pname) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + switch (pname) + { + case GL_LIGHT_MODEL_AMBIENT: + case GL_LIGHT_MODEL_TWO_SIDE: + return true; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidLightModelParameter); + return false; + } +} + +bool ValidateLightModelSingleComponent(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname) +{ + if (!ValidateLightModelCommon(context, entryPoint, pname)) + { + return false; + } + + switch (pname) + { + case GL_LIGHT_MODEL_TWO_SIDE: + return true; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidLightModelParameter); + return false; + } +} + +bool ValidateClipPlaneCommon(const Context *context, angle::EntryPoint entryPoint, GLenum plane) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + + if (plane < GL_CLIP_PLANE0 || plane >= GL_CLIP_PLANE0 + context->getCaps().maxClipPlanes) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidClipPlane); + return false; + } + + return true; +} + +bool ValidateFogCommon(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + const GLfloat *params) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + + switch (pname) + { + case GL_FOG_MODE: + { + GLenum modeParam = static_cast(params[0]); + switch (modeParam) + { + case GL_EXP: + case GL_EXP2: + case GL_LINEAR: + return true; + default: + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidFogMode); + return false; + } + } + case GL_FOG_START: + case GL_FOG_END: + case GL_FOG_COLOR: + break; + case GL_FOG_DENSITY: + if (params[0] < 0.0f) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidFogDensity); + return false; + } + break; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFogParameter); + return false; + } + return true; +} + +bool ValidateTexEnvCommon(const Context *context, + angle::EntryPoint entryPoint, + TextureEnvTarget target, + TextureEnvParameter pname, + const GLfloat *params) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + + switch (target) + { + case TextureEnvTarget::Env: + switch (pname) + { + case TextureEnvParameter::Mode: + { + TextureEnvMode mode = FromGLenum(ConvertToGLenum(params[0])); + switch (mode) + { + case TextureEnvMode::Add: + case TextureEnvMode::Blend: + case TextureEnvMode::Combine: + case TextureEnvMode::Decal: + case TextureEnvMode::Modulate: + case TextureEnvMode::Replace: + break; + default: + context->validationError(entryPoint, GL_INVALID_VALUE, + kInvalidTextureEnvMode); + return false; + } + break; + } + case TextureEnvParameter::CombineRgb: + case TextureEnvParameter::CombineAlpha: + { + TextureCombine combine = FromGLenum(ConvertToGLenum(params[0])); + switch (combine) + { + case TextureCombine::Add: + case TextureCombine::AddSigned: + case TextureCombine::Interpolate: + case TextureCombine::Modulate: + case TextureCombine::Replace: + case TextureCombine::Subtract: + break; + case TextureCombine::Dot3Rgb: + case TextureCombine::Dot3Rgba: + if (pname == TextureEnvParameter::CombineAlpha) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kInvalidTextureCombine); + return false; + } + break; + default: + context->validationError(entryPoint, GL_INVALID_VALUE, + kInvalidTextureCombine); + return false; + } + break; + } + case TextureEnvParameter::Src0Rgb: + case TextureEnvParameter::Src1Rgb: + case TextureEnvParameter::Src2Rgb: + case TextureEnvParameter::Src0Alpha: + case TextureEnvParameter::Src1Alpha: + case TextureEnvParameter::Src2Alpha: + { + TextureSrc combine = FromGLenum(ConvertToGLenum(params[0])); + switch (combine) + { + case TextureSrc::Constant: + case TextureSrc::Previous: + case TextureSrc::PrimaryColor: + case TextureSrc::Texture: + break; + default: + context->validationError(entryPoint, GL_INVALID_VALUE, + kInvalidTextureCombineSrc); + return false; + } + break; + } + case TextureEnvParameter::Op0Rgb: + case TextureEnvParameter::Op1Rgb: + case TextureEnvParameter::Op2Rgb: + case TextureEnvParameter::Op0Alpha: + case TextureEnvParameter::Op1Alpha: + case TextureEnvParameter::Op2Alpha: + { + TextureOp operand = FromGLenum(ConvertToGLenum(params[0])); + switch (operand) + { + case TextureOp::SrcAlpha: + case TextureOp::OneMinusSrcAlpha: + break; + case TextureOp::SrcColor: + case TextureOp::OneMinusSrcColor: + if (pname == TextureEnvParameter::Op0Alpha || + pname == TextureEnvParameter::Op1Alpha || + pname == TextureEnvParameter::Op2Alpha) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kInvalidTextureCombine); + return false; + } + break; + default: + context->validationError(entryPoint, GL_INVALID_VALUE, + kInvalidTextureCombineOp); + return false; + } + break; + } + case TextureEnvParameter::RgbScale: + case TextureEnvParameter::AlphaScale: + if (params[0] != 1.0f && params[0] != 2.0f && params[0] != 4.0f) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kInvalidTextureEnvScale); + return false; + } + break; + case TextureEnvParameter::Color: + break; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, + kInvalidTextureEnvParameter); + return false; + } + break; + case TextureEnvTarget::PointSprite: + if (!context->getExtensions().pointSpriteOES) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureEnvTarget); + return false; + } + switch (pname) + { + case TextureEnvParameter::PointCoordReplace: + break; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, + kInvalidTextureEnvParameter); + return false; + } + break; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureEnvTarget); + return false; + } + return true; +} + +bool ValidateGetTexEnvCommon(const Context *context, + angle::EntryPoint entryPoint, + TextureEnvTarget target, + TextureEnvParameter pname) +{ + GLfloat validateParams[4] = {}; + switch (pname) + { + case TextureEnvParameter::Mode: + ConvertPackedEnum(TextureEnvMode::Add, validateParams); + break; + case TextureEnvParameter::CombineRgb: + case TextureEnvParameter::CombineAlpha: + ConvertPackedEnum(TextureCombine::Add, validateParams); + break; + case TextureEnvParameter::Src0Rgb: + case TextureEnvParameter::Src1Rgb: + case TextureEnvParameter::Src2Rgb: + case TextureEnvParameter::Src0Alpha: + case TextureEnvParameter::Src1Alpha: + case TextureEnvParameter::Src2Alpha: + ConvertPackedEnum(TextureSrc::Constant, validateParams); + break; + case TextureEnvParameter::Op0Rgb: + case TextureEnvParameter::Op1Rgb: + case TextureEnvParameter::Op2Rgb: + case TextureEnvParameter::Op0Alpha: + case TextureEnvParameter::Op1Alpha: + case TextureEnvParameter::Op2Alpha: + ConvertPackedEnum(TextureOp::SrcAlpha, validateParams); + break; + case TextureEnvParameter::RgbScale: + case TextureEnvParameter::AlphaScale: + case TextureEnvParameter::PointCoordReplace: + validateParams[0] = 1.0f; + break; + default: + break; + } + + return ValidateTexEnvCommon(context, entryPoint, target, pname, validateParams); +} + +bool ValidatePointParameterCommon(const Context *context, + angle::EntryPoint entryPoint, + PointParameter pname, + const GLfloat *params) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + + switch (pname) + { + case PointParameter::PointSizeMin: + case PointParameter::PointSizeMax: + case PointParameter::PointFadeThresholdSize: + case PointParameter::PointDistanceAttenuation: + for (unsigned int i = 0; i < GetPointParameterCount(pname); i++) + { + if (params[i] < 0.0f) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kInvalidPointParameterValue); + return false; + } + } + break; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPointParameter); + return false; + } + + return true; +} + +bool ValidatePointSizeCommon(const Context *context, angle::EntryPoint entryPoint, GLfloat size) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + + if (size <= 0.0f) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPointSizeValue); + return false; + } + + return true; +} + +bool ValidateDrawTexCommon(const Context *context, + angle::EntryPoint entryPoint, + float width, + float height) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + + if (width <= 0.0f || height <= 0.0f) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNonPositiveDrawTextureDimension); + return false; + } + + return true; +} + +} // namespace gl + +namespace gl +{ + +bool ValidateAlphaFunc(const Context *context, + angle::EntryPoint entryPoint, + AlphaTestFunc func, + GLfloat ref) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + return ValidateAlphaFuncCommon(context, entryPoint, func); +} + +bool ValidateAlphaFuncx(const Context *context, + angle::EntryPoint entryPoint, + AlphaTestFunc func, + GLfixed ref) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + return ValidateAlphaFuncCommon(context, entryPoint, func); +} + +bool ValidateClearColorx(const Context *context, + angle::EntryPoint entryPoint, + GLfixed red, + GLfixed green, + GLfixed blue, + GLfixed alpha) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + return true; +} + +bool ValidateClearDepthx(const Context *context, angle::EntryPoint entryPoint, GLfixed depth) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + return true; +} + +bool ValidateClientActiveTexture(const Context *context, + angle::EntryPoint entryPoint, + GLenum texture) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + return ValidateMultitextureUnit(context, entryPoint, texture); +} + +bool ValidateClipPlanef(const Context *context, + angle::EntryPoint entryPoint, + GLenum plane, + const GLfloat *eqn) +{ + return ValidateClipPlaneCommon(context, entryPoint, plane); +} + +bool ValidateClipPlanex(const Context *context, + angle::EntryPoint entryPoint, + GLenum plane, + const GLfixed *equation) +{ + return ValidateClipPlaneCommon(context, entryPoint, plane); +} + +bool ValidateColor4f(const Context *context, + angle::EntryPoint entryPoint, + GLfloat red, + GLfloat green, + GLfloat blue, + GLfloat alpha) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + return true; +} + +bool ValidateColor4ub(const Context *context, + angle::EntryPoint entryPoint, + GLubyte red, + GLubyte green, + GLubyte blue, + GLubyte alpha) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + return true; +} + +bool ValidateColor4x(const Context *context, + angle::EntryPoint entryPoint, + GLfixed red, + GLfixed green, + GLfixed blue, + GLfixed alpha) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + return true; +} + +bool ValidateColorPointer(const Context *context, + angle::EntryPoint entryPoint, + GLint size, + VertexAttribType type, + GLsizei stride, + const void *pointer) +{ + return ValidateBuiltinVertexAttributeCommon(context, entryPoint, ClientVertexArrayType::Color, + size, type, stride, pointer); +} + +bool ValidateCullFace(const Context *context, angle::EntryPoint entryPoint, GLenum mode) +{ + UNIMPLEMENTED(); + return true; +} + +bool ValidateDepthRangex(const Context *context, angle::EntryPoint entryPoint, GLfixed n, GLfixed f) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + if (context->isWebGL() && n > f) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidDepthRange); + return false; + } + + return true; +} + +bool ValidateDisableClientState(const Context *context, + angle::EntryPoint entryPoint, + ClientVertexArrayType arrayType) +{ + return ValidateClientStateCommon(context, entryPoint, arrayType); +} + +bool ValidateEnableClientState(const Context *context, + angle::EntryPoint entryPoint, + ClientVertexArrayType arrayType) +{ + return ValidateClientStateCommon(context, entryPoint, arrayType); +} + +bool ValidateFogf(const Context *context, angle::EntryPoint entryPoint, GLenum pname, GLfloat param) +{ + return ValidateFogCommon(context, entryPoint, pname, ¶m); +} + +bool ValidateFogfv(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + const GLfloat *params) +{ + return ValidateFogCommon(context, entryPoint, pname, params); +} + +bool ValidateFogx(const Context *context, angle::EntryPoint entryPoint, GLenum pname, GLfixed param) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + GLfloat asFloat = + pname == GL_FOG_MODE ? static_cast(param) : ConvertFixedToFloat(param); + return ValidateFogCommon(context, entryPoint, pname, &asFloat); +} + +bool ValidateFogxv(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + const GLfixed *params) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + unsigned int paramCount = GetFogParameterCount(pname); + GLfloat paramsf[4] = {}; + + if (pname == GL_FOG_MODE) + { + paramsf[0] = static_cast(params[0]); + } + else + { + for (unsigned int i = 0; i < paramCount; i++) + { + paramsf[i] = ConvertFixedToFloat(params[i]); + } + } + + return ValidateFogCommon(context, entryPoint, pname, paramsf); +} + +bool ValidateFrustumf(const Context *context, + angle::EntryPoint entryPoint, + GLfloat l, + GLfloat r, + GLfloat b, + GLfloat t, + GLfloat n, + GLfloat f) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + if (l == r || b == t || n == f || n <= 0.0f || f <= 0.0f) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidProjectionMatrix); + return false; + } + return true; +} + +bool ValidateFrustumx(const Context *context, + angle::EntryPoint entryPoint, + GLfixed l, + GLfixed r, + GLfixed b, + GLfixed t, + GLfixed n, + GLfixed f) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + if (l == r || b == t || n == f || n <= 0 || f <= 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidProjectionMatrix); + return false; + } + return true; +} + +bool ValidateGetBufferParameteriv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum pname, + const GLint *params) +{ + UNIMPLEMENTED(); + return true; +} + +bool ValidateGetClipPlanef(const Context *context, + angle::EntryPoint entryPoint, + GLenum plane, + const GLfloat *equation) +{ + return ValidateClipPlaneCommon(context, entryPoint, plane); +} + +bool ValidateGetClipPlanex(const Context *context, + angle::EntryPoint entryPoint, + GLenum plane, + const GLfixed *equation) +{ + return ValidateClipPlaneCommon(context, entryPoint, plane); +} + +bool ValidateGetFixedv(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + const GLfixed *params) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + GLenum nativeType; + unsigned int numParams = 0; + return ValidateStateQuery(context, entryPoint, pname, &nativeType, &numParams); +} + +bool ValidateGetLightfv(const Context *context, + angle::EntryPoint entryPoint, + GLenum light, + LightParameter pname, + const GLfloat *params) +{ + GLfloat validateParams[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + return ValidateLightCommon(context, entryPoint, light, pname, validateParams); +} + +bool ValidateGetLightxv(const Context *context, + angle::EntryPoint entryPoint, + GLenum light, + LightParameter pname, + const GLfixed *params) +{ + GLfloat validateParams[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + return ValidateLightCommon(context, entryPoint, light, pname, validateParams); +} + +bool ValidateGetMaterialfv(const Context *context, + angle::EntryPoint entryPoint, + GLenum face, + MaterialParameter pname, + const GLfloat *params) +{ + return ValidateMaterialQuery(context, entryPoint, face, pname); +} + +bool ValidateGetMaterialxv(const Context *context, + angle::EntryPoint entryPoint, + GLenum face, + MaterialParameter pname, + const GLfixed *params) +{ + return ValidateMaterialQuery(context, entryPoint, face, pname); +} + +bool ValidateGetTexEnvfv(const Context *context, + angle::EntryPoint entryPoint, + TextureEnvTarget target, + TextureEnvParameter pname, + const GLfloat *params) +{ + return ValidateGetTexEnvCommon(context, entryPoint, target, pname); +} + +bool ValidateGetTexEnviv(const Context *context, + angle::EntryPoint entryPoint, + TextureEnvTarget target, + TextureEnvParameter pname, + const GLint *params) +{ + return ValidateGetTexEnvCommon(context, entryPoint, target, pname); +} + +bool ValidateGetTexEnvxv(const Context *context, + angle::EntryPoint entryPoint, + TextureEnvTarget target, + TextureEnvParameter pname, + const GLfixed *params) +{ + return ValidateGetTexEnvCommon(context, entryPoint, target, pname); +} + +bool ValidateGetTexParameterxv(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum pname, + const GLfixed *params) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + + if (!ValidateGetTexParameterBase(context, entryPoint, target, pname, nullptr)) + { + return false; + } + + return true; +} + +bool ValidateLightModelf(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLfloat param) +{ + return ValidateLightModelSingleComponent(context, entryPoint, pname); +} + +bool ValidateLightModelfv(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + const GLfloat *params) +{ + return ValidateLightModelCommon(context, entryPoint, pname); +} + +bool ValidateLightModelx(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLfixed param) +{ + return ValidateLightModelSingleComponent(context, entryPoint, pname); +} + +bool ValidateLightModelxv(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + const GLfixed *param) +{ + return ValidateLightModelCommon(context, entryPoint, pname); +} + +bool ValidateLightf(const Context *context, + angle::EntryPoint entryPoint, + GLenum light, + LightParameter pname, + GLfloat param) +{ + return ValidateLightSingleComponent(context, entryPoint, light, pname, param); +} + +bool ValidateLightfv(const Context *context, + angle::EntryPoint entryPoint, + GLenum light, + LightParameter pname, + const GLfloat *params) +{ + return ValidateLightCommon(context, entryPoint, light, pname, params); +} + +bool ValidateLightx(const Context *context, + angle::EntryPoint entryPoint, + GLenum light, + LightParameter pname, + GLfixed param) +{ + return ValidateLightSingleComponent(context, entryPoint, light, pname, + ConvertFixedToFloat(param)); +} + +bool ValidateLightxv(const Context *context, + angle::EntryPoint entryPoint, + GLenum light, + LightParameter pname, + const GLfixed *params) +{ + GLfloat paramsf[4]; + for (unsigned int i = 0; i < GetLightParameterCount(pname); i++) + { + paramsf[i] = ConvertFixedToFloat(params[i]); + } + + return ValidateLightCommon(context, entryPoint, light, pname, paramsf); +} + +bool ValidateLineWidthx(const Context *context, angle::EntryPoint entryPoint, GLfixed width) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + if (width <= 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidWidth); + return false; + } + + return true; +} + +bool ValidateLoadIdentity(const Context *context, angle::EntryPoint entryPoint) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + return true; +} + +bool ValidateLoadMatrixf(const Context *context, angle::EntryPoint entryPoint, const GLfloat *m) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + return true; +} + +bool ValidateLoadMatrixx(const Context *context, angle::EntryPoint entryPoint, const GLfixed *m) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + return true; +} + +bool ValidateLogicOp(const Context *context, angle::EntryPoint entryPoint, LogicalOperation opcode) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + return ValidateLogicOpCommon(context, entryPoint, opcode); +} + +bool ValidateMaterialf(const Context *context, + angle::EntryPoint entryPoint, + GLenum face, + MaterialParameter pname, + GLfloat param) +{ + return ValidateMaterialSingleComponent(context, entryPoint, face, pname, param); +} + +bool ValidateMaterialfv(const Context *context, + angle::EntryPoint entryPoint, + GLenum face, + MaterialParameter pname, + const GLfloat *params) +{ + return ValidateMaterialSetting(context, entryPoint, face, pname, params); +} + +bool ValidateMaterialx(const Context *context, + angle::EntryPoint entryPoint, + GLenum face, + MaterialParameter pname, + GLfixed param) +{ + return ValidateMaterialSingleComponent(context, entryPoint, face, pname, + ConvertFixedToFloat(param)); +} + +bool ValidateMaterialxv(const Context *context, + angle::EntryPoint entryPoint, + GLenum face, + MaterialParameter pname, + const GLfixed *params) +{ + GLfloat paramsf[4]; + + for (unsigned int i = 0; i < GetMaterialParameterCount(pname); i++) + { + paramsf[i] = ConvertFixedToFloat(params[i]); + } + + return ValidateMaterialSetting(context, entryPoint, face, pname, paramsf); +} + +bool ValidateMatrixMode(const Context *context, angle::EntryPoint entryPoint, MatrixType mode) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + switch (mode) + { + case MatrixType::Projection: + case MatrixType::Modelview: + case MatrixType::Texture: + return true; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidMatrixMode); + return false; + } +} + +bool ValidateMultMatrixf(const Context *context, angle::EntryPoint entryPoint, const GLfloat *m) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + return true; +} + +bool ValidateMultMatrixx(const Context *context, angle::EntryPoint entryPoint, const GLfixed *m) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + return true; +} + +bool ValidateMultiTexCoord4f(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLfloat s, + GLfloat t, + GLfloat r, + GLfloat q) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + return ValidateMultitextureUnit(context, entryPoint, target); +} + +bool ValidateMultiTexCoord4x(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLfixed s, + GLfixed t, + GLfixed r, + GLfixed q) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + return ValidateMultitextureUnit(context, entryPoint, target); +} + +bool ValidateNormal3f(const Context *context, + angle::EntryPoint entryPoint, + GLfloat nx, + GLfloat ny, + GLfloat nz) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + return true; +} + +bool ValidateNormal3x(const Context *context, + angle::EntryPoint entryPoint, + GLfixed nx, + GLfixed ny, + GLfixed nz) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + return true; +} + +bool ValidateNormalPointer(const Context *context, + angle::EntryPoint entryPoint, + VertexAttribType type, + GLsizei stride, + const void *pointer) +{ + return ValidateBuiltinVertexAttributeCommon(context, entryPoint, ClientVertexArrayType::Normal, + 3, type, stride, pointer); +} + +bool ValidateOrthof(const Context *context, + angle::EntryPoint entryPoint, + GLfloat l, + GLfloat r, + GLfloat b, + GLfloat t, + GLfloat n, + GLfloat f) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + // [OpenGL ES 1.1.12] section 2.10.2 page 31: + // If l is equal to r, b is equal to t, or n is equal to f, the + // error INVALID VALUE results. + if (l == r || b == t || n == f) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidProjectionMatrix); + return false; + } + return true; +} + +bool ValidateOrthox(const Context *context, + angle::EntryPoint entryPoint, + GLfixed l, + GLfixed r, + GLfixed b, + GLfixed t, + GLfixed n, + GLfixed f) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + if (l == r || b == t || n == f) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidProjectionMatrix); + return false; + } + return true; +} + +bool ValidatePointParameterf(const Context *context, + angle::EntryPoint entryPoint, + PointParameter pname, + GLfloat param) +{ + unsigned int paramCount = GetPointParameterCount(pname); + if (paramCount != 1) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPointParameter); + return false; + } + + return ValidatePointParameterCommon(context, entryPoint, pname, ¶m); +} + +bool ValidatePointParameterfv(const Context *context, + angle::EntryPoint entryPoint, + PointParameter pname, + const GLfloat *params) +{ + return ValidatePointParameterCommon(context, entryPoint, pname, params); +} + +bool ValidatePointParameterx(const Context *context, + angle::EntryPoint entryPoint, + PointParameter pname, + GLfixed param) +{ + unsigned int paramCount = GetPointParameterCount(pname); + if (paramCount != 1) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPointParameter); + return false; + } + + GLfloat paramf = ConvertFixedToFloat(param); + return ValidatePointParameterCommon(context, entryPoint, pname, ¶mf); +} + +bool ValidatePointParameterxv(const Context *context, + angle::EntryPoint entryPoint, + PointParameter pname, + const GLfixed *params) +{ + GLfloat paramsf[4] = {}; + for (unsigned int i = 0; i < GetPointParameterCount(pname); i++) + { + paramsf[i] = ConvertFixedToFloat(params[i]); + } + return ValidatePointParameterCommon(context, entryPoint, pname, paramsf); +} + +bool ValidatePointSize(const Context *context, angle::EntryPoint entryPoint, GLfloat size) +{ + return ValidatePointSizeCommon(context, entryPoint, size); +} + +bool ValidatePointSizex(const Context *context, angle::EntryPoint entryPoint, GLfixed size) +{ + return ValidatePointSizeCommon(context, entryPoint, ConvertFixedToFloat(size)); +} + +bool ValidatePolygonOffsetx(const Context *context, + angle::EntryPoint entryPoint, + GLfixed factor, + GLfixed units) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + return true; +} + +bool ValidatePopMatrix(const Context *context, angle::EntryPoint entryPoint) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + const auto &stack = context->getState().gles1().currentMatrixStack(); + if (stack.size() == 1) + { + context->validationError(entryPoint, GL_STACK_UNDERFLOW, kMatrixStackUnderflow); + return false; + } + return true; +} + +bool ValidatePushMatrix(const Context *context, angle::EntryPoint entryPoint) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + const auto &stack = context->getState().gles1().currentMatrixStack(); + if (stack.size() == stack.max_size()) + { + context->validationError(entryPoint, GL_STACK_OVERFLOW, kMatrixStackOverflow); + return false; + } + return true; +} + +bool ValidateRotatef(const Context *context, + angle::EntryPoint entryPoint, + GLfloat angle, + GLfloat x, + GLfloat y, + GLfloat z) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + return true; +} + +bool ValidateRotatex(const Context *context, + angle::EntryPoint entryPoint, + GLfixed angle, + GLfixed x, + GLfixed y, + GLfixed z) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + return true; +} + +bool ValidateSampleCoveragex(const Context *context, + angle::EntryPoint entryPoint, + GLclampx value, + GLboolean invert) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + return true; +} + +bool ValidateScalef(const Context *context, + angle::EntryPoint entryPoint, + GLfloat x, + GLfloat y, + GLfloat z) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + return true; +} + +bool ValidateScalex(const Context *context, + angle::EntryPoint entryPoint, + GLfixed x, + GLfixed y, + GLfixed z) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + return true; +} + +bool ValidateShadeModel(const Context *context, angle::EntryPoint entryPoint, ShadingModel mode) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + switch (mode) + { + case ShadingModel::Flat: + case ShadingModel::Smooth: + return true; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShadingModel); + return false; + } +} + +bool ValidateTexCoordPointer(const Context *context, + angle::EntryPoint entryPoint, + GLint size, + VertexAttribType type, + GLsizei stride, + const void *pointer) +{ + return ValidateBuiltinVertexAttributeCommon( + context, entryPoint, ClientVertexArrayType::TextureCoord, size, type, stride, pointer); +} + +bool ValidateTexEnvf(const Context *context, + angle::EntryPoint entryPoint, + TextureEnvTarget target, + TextureEnvParameter pname, + GLfloat param) +{ + return ValidateTexEnvCommon(context, entryPoint, target, pname, ¶m); +} + +bool ValidateTexEnvfv(const Context *context, + angle::EntryPoint entryPoint, + TextureEnvTarget target, + TextureEnvParameter pname, + const GLfloat *params) +{ + return ValidateTexEnvCommon(context, entryPoint, target, pname, params); +} + +bool ValidateTexEnvi(const Context *context, + angle::EntryPoint entryPoint, + TextureEnvTarget target, + TextureEnvParameter pname, + GLint param) +{ + GLfloat paramf = static_cast(param); + return ValidateTexEnvCommon(context, entryPoint, target, pname, ¶mf); +} + +bool ValidateTexEnviv(const Context *context, + angle::EntryPoint entryPoint, + TextureEnvTarget target, + TextureEnvParameter pname, + const GLint *params) +{ + GLfloat paramsf[4]; + for (unsigned int i = 0; i < GetTextureEnvParameterCount(pname); i++) + { + paramsf[i] = static_cast(params[i]); + } + return ValidateTexEnvCommon(context, entryPoint, target, pname, paramsf); +} + +bool ValidateTexEnvx(const Context *context, + angle::EntryPoint entryPoint, + TextureEnvTarget target, + TextureEnvParameter pname, + GLfixed param) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + GLfloat paramsf[4] = {}; + ConvertTextureEnvFromFixed(pname, ¶m, paramsf); + return ValidateTexEnvCommon(context, entryPoint, target, pname, paramsf); +} + +bool ValidateTexEnvxv(const Context *context, + angle::EntryPoint entryPoint, + TextureEnvTarget target, + TextureEnvParameter pname, + const GLfixed *params) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + GLfloat paramsf[4] = {}; + ConvertTextureEnvFromFixed(pname, params, paramsf); + return ValidateTexEnvCommon(context, entryPoint, target, pname, paramsf); +} + +bool ValidateTexParameterBaseForGLfixed(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum pname, + GLsizei bufSize, + bool vectorParams, + const GLfixed *params) +{ + // Convert GLfixed parameter for GL_TEXTURE_MAX_ANISOTROPY_EXT independently + // since it compares against 1 and maxTextureAnisotropy instead of just 0 + // (other values are fine to leave unconverted since they only check positive or negative or + // are used as enums) + GLfloat paramValue; + if (pname == GL_TEXTURE_MAX_ANISOTROPY_EXT) + { + paramValue = ConvertFixedToFloat(static_cast(params[0])); + } + else + { + paramValue = static_cast(params[0]); + } + return ValidateTexParameterBase(context, entryPoint, target, pname, bufSize, vectorParams, + ¶mValue); +} + +bool ValidateTexParameterx(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum pname, + GLfixed param) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + return ValidateTexParameterBaseForGLfixed(context, entryPoint, target, pname, -1, false, + ¶m); +} + +bool ValidateTexParameterxv(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum pname, + const GLfixed *params) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + return ValidateTexParameterBaseForGLfixed(context, entryPoint, target, pname, -1, true, params); +} + +bool ValidateTranslatef(const Context *context, + angle::EntryPoint entryPoint, + GLfloat x, + GLfloat y, + GLfloat z) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + return true; +} + +bool ValidateTranslatex(const Context *context, + angle::EntryPoint entryPoint, + GLfixed x, + GLfixed y, + GLfixed z) +{ + ANGLE_VALIDATE_IS_GLES1(context, entryPoint); + return true; +} + +bool ValidateVertexPointer(const Context *context, + angle::EntryPoint entryPoint, + GLint size, + VertexAttribType type, + GLsizei stride, + const void *pointer) +{ + return ValidateBuiltinVertexAttributeCommon(context, entryPoint, ClientVertexArrayType::Vertex, + size, type, stride, pointer); +} + +bool ValidateDrawTexfOES(const Context *context, + angle::EntryPoint entryPoint, + GLfloat x, + GLfloat y, + GLfloat z, + GLfloat width, + GLfloat height) +{ + return ValidateDrawTexCommon(context, entryPoint, width, height); +} + +bool ValidateDrawTexfvOES(const Context *context, + angle::EntryPoint entryPoint, + const GLfloat *coords) +{ + return ValidateDrawTexCommon(context, entryPoint, coords[3], coords[4]); +} + +bool ValidateDrawTexiOES(const Context *context, + angle::EntryPoint entryPoint, + GLint x, + GLint y, + GLint z, + GLint width, + GLint height) +{ + return ValidateDrawTexCommon(context, entryPoint, static_cast(width), + static_cast(height)); +} + +bool ValidateDrawTexivOES(const Context *context, angle::EntryPoint entryPoint, const GLint *coords) +{ + return ValidateDrawTexCommon(context, entryPoint, static_cast(coords[3]), + static_cast(coords[4])); +} + +bool ValidateDrawTexsOES(const Context *context, + angle::EntryPoint entryPoint, + GLshort x, + GLshort y, + GLshort z, + GLshort width, + GLshort height) +{ + return ValidateDrawTexCommon(context, entryPoint, static_cast(width), + static_cast(height)); +} + +bool ValidateDrawTexsvOES(const Context *context, + angle::EntryPoint entryPoint, + const GLshort *coords) +{ + return ValidateDrawTexCommon(context, entryPoint, static_cast(coords[3]), + static_cast(coords[4])); +} + +bool ValidateDrawTexxOES(const Context *context, + angle::EntryPoint entryPoint, + GLfixed x, + GLfixed y, + GLfixed z, + GLfixed width, + GLfixed height) +{ + return ValidateDrawTexCommon(context, entryPoint, ConvertFixedToFloat(width), + ConvertFixedToFloat(height)); +} + +bool ValidateDrawTexxvOES(const Context *context, + angle::EntryPoint entryPoint, + const GLfixed *coords) +{ + return ValidateDrawTexCommon(context, entryPoint, ConvertFixedToFloat(coords[3]), + ConvertFixedToFloat(coords[4])); +} + +bool ValidateCurrentPaletteMatrixOES(const Context *context, + angle::EntryPoint entryPoint, + GLuint matrixpaletteindex) +{ + UNIMPLEMENTED(); + return true; +} + +bool ValidateLoadPaletteFromModelViewMatrixOES(const Context *context, angle::EntryPoint entryPoint) +{ + UNIMPLEMENTED(); + return true; +} + +bool ValidateMatrixIndexPointerOES(const Context *context, + angle::EntryPoint entryPoint, + GLint size, + GLenum type, + GLsizei stride, + const void *pointer) +{ + UNIMPLEMENTED(); + return true; +} + +bool ValidateWeightPointerOES(const Context *context, + angle::EntryPoint entryPoint, + GLint size, + GLenum type, + GLsizei stride, + const void *pointer) +{ + UNIMPLEMENTED(); + return true; +} + +bool ValidatePointSizePointerOES(const Context *context, + angle::EntryPoint entryPoint, + VertexAttribType type, + GLsizei stride, + const void *pointer) +{ + return ValidateBuiltinVertexAttributeCommon( + context, entryPoint, ClientVertexArrayType::PointSize, 1, type, stride, pointer); +} + +bool ValidateQueryMatrixxOES(const Context *context, + angle::EntryPoint entryPoint, + const GLfixed *mantissa, + const GLint *exponent) +{ + UNIMPLEMENTED(); + return true; +} + +bool ValidateGenFramebuffersOES(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const FramebufferID *framebuffers) +{ + if (!context->getExtensions().framebufferObjectOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateGenOrDelete(context, entryPoint, n); +} + +bool ValidateDeleteFramebuffersOES(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const FramebufferID *framebuffers) +{ + if (!context->getExtensions().framebufferObjectOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateGenOrDelete(context, entryPoint, n); +} + +bool ValidateGenRenderbuffersOES(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const RenderbufferID *renderbuffers) +{ + if (!context->getExtensions().framebufferObjectOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateGenOrDelete(context, entryPoint, n); +} + +bool ValidateDeleteRenderbuffersOES(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const RenderbufferID *renderbuffers) +{ + if (!context->getExtensions().framebufferObjectOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateGenOrDelete(context, entryPoint, n); +} + +bool ValidateBindFramebufferOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + FramebufferID framebuffer) +{ + if (!context->getExtensions().framebufferObjectOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateBindFramebufferBase(context, entryPoint, target, framebuffer); +} + +bool ValidateBindRenderbufferOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + RenderbufferID renderbuffer) +{ + if (!context->getExtensions().framebufferObjectOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateBindRenderbufferBase(context, entryPoint, target, renderbuffer); +} + +bool ValidateCheckFramebufferStatusOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum target) +{ + if (!context->getExtensions().framebufferObjectOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (!ValidFramebufferTarget(context, target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFramebufferTarget); + return false; + } + + return true; +} + +bool ValidateFramebufferRenderbufferOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + GLenum rbtarget, + RenderbufferID renderbuffer) +{ + if (!context->getExtensions().framebufferObjectOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateFramebufferRenderbufferBase(context, entryPoint, target, attachment, rbtarget, + renderbuffer); +} + +bool ValidateFramebufferTexture2DOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + TextureTarget textarget, + TextureID texture, + GLint level) +{ + if (!context->getExtensions().framebufferObjectOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (level != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidFramebufferTextureLevel); + return false; + } + + if (!ValidateFramebufferTextureBase(context, entryPoint, target, attachment, texture, level)) + { + return false; + } + + if (texture.value != 0) + { + Texture *tex = context->getTexture(texture); + ASSERT(tex); + + const Caps &caps = context->getCaps(); + + switch (textarget) + { + case TextureTarget::_2D: + { + if (level > log2(caps.max2DTextureSize)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel); + return false; + } + if (tex->getType() != TextureType::_2D) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInvalidTextureTarget); + return false; + } + } + break; + + case TextureTarget::CubeMapNegativeX: + case TextureTarget::CubeMapNegativeY: + case TextureTarget::CubeMapNegativeZ: + case TextureTarget::CubeMapPositiveX: + case TextureTarget::CubeMapPositiveY: + case TextureTarget::CubeMapPositiveZ: + { + if (!context->getExtensions().textureCubeMapOES) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + + if (level > log2(caps.maxCubeMapTextureSize)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel); + return false; + } + if (tex->getType() != TextureType::CubeMap) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kTextureTargetMismatch); + return false; + } + } + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + } + + return true; +} + +bool ValidateGenerateMipmapOES(const Context *context, + angle::EntryPoint entryPoint, + TextureType target) +{ + if (!context->getExtensions().framebufferObjectOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateGenerateMipmapBase(context, entryPoint, target); +} + +bool ValidateGetFramebufferAttachmentParameterivOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + GLenum pname, + const GLint *params) +{ + if (!context->getExtensions().framebufferObjectOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateGetFramebufferAttachmentParameterivBase(context, entryPoint, target, attachment, + pname, nullptr); +} + +bool ValidateGetRenderbufferParameterivOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum pname, + const GLint *params) +{ + if (!context->getExtensions().framebufferObjectOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateGetRenderbufferParameterivBase(context, entryPoint, target, pname, nullptr); +} + +bool ValidateIsFramebufferOES(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebuffer) +{ + if (!context->getExtensions().framebufferObjectOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return true; +} + +bool ValidateIsRenderbufferOES(const Context *context, + angle::EntryPoint entryPoint, + RenderbufferID renderbuffer) +{ + if (!context->getExtensions().framebufferObjectOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return true; +} + +bool ValidateRenderbufferStorageOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum internalformat, + GLsizei width, + GLsizei height) +{ + if (!context->getExtensions().framebufferObjectOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateRenderbufferStorageParametersBase(context, entryPoint, target, 0, internalformat, + width, height); +} + +// GL_OES_texture_cube_map + +bool ValidateGetTexGenfvOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + const GLfloat *params) +{ + UNIMPLEMENTED(); + return true; +} + +bool ValidateGetTexGenivOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + const int *params) +{ + UNIMPLEMENTED(); + return true; +} + +bool ValidateGetTexGenxvOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + const GLfixed *params) +{ + UNIMPLEMENTED(); + return true; +} + +bool ValidateTexGenfvOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + const GLfloat *params) +{ + UNIMPLEMENTED(); + return true; +} + +bool ValidateTexGenivOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + const GLint *param) +{ + UNIMPLEMENTED(); + return true; +} + +bool ValidateTexGenxvOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + const GLint *param) +{ + UNIMPLEMENTED(); + return true; +} + +bool ValidateTexGenfOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + GLfloat param) +{ + UNIMPLEMENTED(); + return true; +} + +bool ValidateTexGeniOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + GLint param) +{ + UNIMPLEMENTED(); + return true; +} + +bool ValidateTexGenxOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + GLfixed param) +{ + UNIMPLEMENTED(); + return true; +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/validationES1.h b/gfx/angle/checkout/src/libANGLE/validationES1.h new file mode 100644 index 0000000000..e2e6248400 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationES1.h @@ -0,0 +1,20 @@ +// +// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// validationES1.h: +// Inlined validation functions for OpenGL ES 1.0 entry points. + +#ifndef LIBANGLE_VALIDATION_ES1_H_ +#define LIBANGLE_VALIDATION_ES1_H_ + +#include "libANGLE/ErrorStrings.h" +#include "libANGLE/validationES1_autogen.h" + +namespace gl +{ +// Nothing here yet. +} // namespace gl + +#endif // LIBANGLE_VALIDATION_ES1_H_ diff --git a/gfx/angle/checkout/src/libANGLE/validationES1_autogen.h b/gfx/angle/checkout/src/libANGLE/validationES1_autogen.h new file mode 100644 index 0000000000..81f168e573 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationES1_autogen.h @@ -0,0 +1,395 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// validationES1_autogen.h: +// Validation functions for the OpenGL ES 1.0 entry points. + +#ifndef LIBANGLE_VALIDATION_ES1_AUTOGEN_H_ +#define LIBANGLE_VALIDATION_ES1_AUTOGEN_H_ + +#include "common/PackedEnums.h" +#include "common/entry_points_enum_autogen.h" + +namespace gl +{ +class Context; + +bool ValidateAlphaFunc(const Context *context, + angle::EntryPoint entryPoint, + AlphaTestFunc funcPacked, + GLfloat ref); +bool ValidateAlphaFuncx(const Context *context, + angle::EntryPoint entryPoint, + AlphaTestFunc funcPacked, + GLfixed ref); +bool ValidateClearColorx(const Context *context, + angle::EntryPoint entryPoint, + GLfixed red, + GLfixed green, + GLfixed blue, + GLfixed alpha); +bool ValidateClearDepthx(const Context *context, angle::EntryPoint entryPoint, GLfixed depth); +bool ValidateClientActiveTexture(const Context *context, + angle::EntryPoint entryPoint, + GLenum texture); +bool ValidateClipPlanef(const Context *context, + angle::EntryPoint entryPoint, + GLenum p, + const GLfloat *eqn); +bool ValidateClipPlanex(const Context *context, + angle::EntryPoint entryPoint, + GLenum plane, + const GLfixed *equation); +bool ValidateColor4f(const Context *context, + angle::EntryPoint entryPoint, + GLfloat red, + GLfloat green, + GLfloat blue, + GLfloat alpha); +bool ValidateColor4ub(const Context *context, + angle::EntryPoint entryPoint, + GLubyte red, + GLubyte green, + GLubyte blue, + GLubyte alpha); +bool ValidateColor4x(const Context *context, + angle::EntryPoint entryPoint, + GLfixed red, + GLfixed green, + GLfixed blue, + GLfixed alpha); +bool ValidateColorPointer(const Context *context, + angle::EntryPoint entryPoint, + GLint size, + VertexAttribType typePacked, + GLsizei stride, + const void *pointer); +bool ValidateDepthRangex(const Context *context, + angle::EntryPoint entryPoint, + GLfixed n, + GLfixed f); +bool ValidateDisableClientState(const Context *context, + angle::EntryPoint entryPoint, + ClientVertexArrayType arrayPacked); +bool ValidateEnableClientState(const Context *context, + angle::EntryPoint entryPoint, + ClientVertexArrayType arrayPacked); +bool ValidateFogf(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLfloat param); +bool ValidateFogfv(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + const GLfloat *params); +bool ValidateFogx(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLfixed param); +bool ValidateFogxv(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + const GLfixed *param); +bool ValidateFrustumf(const Context *context, + angle::EntryPoint entryPoint, + GLfloat l, + GLfloat r, + GLfloat b, + GLfloat t, + GLfloat n, + GLfloat f); +bool ValidateFrustumx(const Context *context, + angle::EntryPoint entryPoint, + GLfixed l, + GLfixed r, + GLfixed b, + GLfixed t, + GLfixed n, + GLfixed f); +bool ValidateGetClipPlanef(const Context *context, + angle::EntryPoint entryPoint, + GLenum plane, + const GLfloat *equation); +bool ValidateGetClipPlanex(const Context *context, + angle::EntryPoint entryPoint, + GLenum plane, + const GLfixed *equation); +bool ValidateGetFixedv(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + const GLfixed *params); +bool ValidateGetLightfv(const Context *context, + angle::EntryPoint entryPoint, + GLenum light, + LightParameter pnamePacked, + const GLfloat *params); +bool ValidateGetLightxv(const Context *context, + angle::EntryPoint entryPoint, + GLenum light, + LightParameter pnamePacked, + const GLfixed *params); +bool ValidateGetMaterialfv(const Context *context, + angle::EntryPoint entryPoint, + GLenum face, + MaterialParameter pnamePacked, + const GLfloat *params); +bool ValidateGetMaterialxv(const Context *context, + angle::EntryPoint entryPoint, + GLenum face, + MaterialParameter pnamePacked, + const GLfixed *params); +bool ValidateGetTexEnvfv(const Context *context, + angle::EntryPoint entryPoint, + TextureEnvTarget targetPacked, + TextureEnvParameter pnamePacked, + const GLfloat *params); +bool ValidateGetTexEnviv(const Context *context, + angle::EntryPoint entryPoint, + TextureEnvTarget targetPacked, + TextureEnvParameter pnamePacked, + const GLint *params); +bool ValidateGetTexEnvxv(const Context *context, + angle::EntryPoint entryPoint, + TextureEnvTarget targetPacked, + TextureEnvParameter pnamePacked, + const GLfixed *params); +bool ValidateGetTexParameterxv(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + const GLfixed *params); +bool ValidateLightModelf(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLfloat param); +bool ValidateLightModelfv(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + const GLfloat *params); +bool ValidateLightModelx(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLfixed param); +bool ValidateLightModelxv(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + const GLfixed *param); +bool ValidateLightf(const Context *context, + angle::EntryPoint entryPoint, + GLenum light, + LightParameter pnamePacked, + GLfloat param); +bool ValidateLightfv(const Context *context, + angle::EntryPoint entryPoint, + GLenum light, + LightParameter pnamePacked, + const GLfloat *params); +bool ValidateLightx(const Context *context, + angle::EntryPoint entryPoint, + GLenum light, + LightParameter pnamePacked, + GLfixed param); +bool ValidateLightxv(const Context *context, + angle::EntryPoint entryPoint, + GLenum light, + LightParameter pnamePacked, + const GLfixed *params); +bool ValidateLineWidthx(const Context *context, angle::EntryPoint entryPoint, GLfixed width); +bool ValidateLoadIdentity(const Context *context, angle::EntryPoint entryPoint); +bool ValidateLoadMatrixf(const Context *context, angle::EntryPoint entryPoint, const GLfloat *m); +bool ValidateLoadMatrixx(const Context *context, angle::EntryPoint entryPoint, const GLfixed *m); +bool ValidateLogicOp(const Context *context, + angle::EntryPoint entryPoint, + LogicalOperation opcodePacked); +bool ValidateMaterialf(const Context *context, + angle::EntryPoint entryPoint, + GLenum face, + MaterialParameter pnamePacked, + GLfloat param); +bool ValidateMaterialfv(const Context *context, + angle::EntryPoint entryPoint, + GLenum face, + MaterialParameter pnamePacked, + const GLfloat *params); +bool ValidateMaterialx(const Context *context, + angle::EntryPoint entryPoint, + GLenum face, + MaterialParameter pnamePacked, + GLfixed param); +bool ValidateMaterialxv(const Context *context, + angle::EntryPoint entryPoint, + GLenum face, + MaterialParameter pnamePacked, + const GLfixed *param); +bool ValidateMatrixMode(const Context *context, + angle::EntryPoint entryPoint, + MatrixType modePacked); +bool ValidateMultMatrixf(const Context *context, angle::EntryPoint entryPoint, const GLfloat *m); +bool ValidateMultMatrixx(const Context *context, angle::EntryPoint entryPoint, const GLfixed *m); +bool ValidateMultiTexCoord4f(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLfloat s, + GLfloat t, + GLfloat r, + GLfloat q); +bool ValidateMultiTexCoord4x(const Context *context, + angle::EntryPoint entryPoint, + GLenum texture, + GLfixed s, + GLfixed t, + GLfixed r, + GLfixed q); +bool ValidateNormal3f(const Context *context, + angle::EntryPoint entryPoint, + GLfloat nx, + GLfloat ny, + GLfloat nz); +bool ValidateNormal3x(const Context *context, + angle::EntryPoint entryPoint, + GLfixed nx, + GLfixed ny, + GLfixed nz); +bool ValidateNormalPointer(const Context *context, + angle::EntryPoint entryPoint, + VertexAttribType typePacked, + GLsizei stride, + const void *pointer); +bool ValidateOrthof(const Context *context, + angle::EntryPoint entryPoint, + GLfloat l, + GLfloat r, + GLfloat b, + GLfloat t, + GLfloat n, + GLfloat f); +bool ValidateOrthox(const Context *context, + angle::EntryPoint entryPoint, + GLfixed l, + GLfixed r, + GLfixed b, + GLfixed t, + GLfixed n, + GLfixed f); +bool ValidatePointParameterf(const Context *context, + angle::EntryPoint entryPoint, + PointParameter pnamePacked, + GLfloat param); +bool ValidatePointParameterfv(const Context *context, + angle::EntryPoint entryPoint, + PointParameter pnamePacked, + const GLfloat *params); +bool ValidatePointParameterx(const Context *context, + angle::EntryPoint entryPoint, + PointParameter pnamePacked, + GLfixed param); +bool ValidatePointParameterxv(const Context *context, + angle::EntryPoint entryPoint, + PointParameter pnamePacked, + const GLfixed *params); +bool ValidatePointSize(const Context *context, angle::EntryPoint entryPoint, GLfloat size); +bool ValidatePointSizex(const Context *context, angle::EntryPoint entryPoint, GLfixed size); +bool ValidatePolygonOffsetx(const Context *context, + angle::EntryPoint entryPoint, + GLfixed factor, + GLfixed units); +bool ValidatePopMatrix(const Context *context, angle::EntryPoint entryPoint); +bool ValidatePushMatrix(const Context *context, angle::EntryPoint entryPoint); +bool ValidateRotatef(const Context *context, + angle::EntryPoint entryPoint, + GLfloat angle, + GLfloat x, + GLfloat y, + GLfloat z); +bool ValidateRotatex(const Context *context, + angle::EntryPoint entryPoint, + GLfixed angle, + GLfixed x, + GLfixed y, + GLfixed z); +bool ValidateSampleCoveragex(const Context *context, + angle::EntryPoint entryPoint, + GLclampx value, + GLboolean invert); +bool ValidateScalef(const Context *context, + angle::EntryPoint entryPoint, + GLfloat x, + GLfloat y, + GLfloat z); +bool ValidateScalex(const Context *context, + angle::EntryPoint entryPoint, + GLfixed x, + GLfixed y, + GLfixed z); +bool ValidateShadeModel(const Context *context, + angle::EntryPoint entryPoint, + ShadingModel modePacked); +bool ValidateTexCoordPointer(const Context *context, + angle::EntryPoint entryPoint, + GLint size, + VertexAttribType typePacked, + GLsizei stride, + const void *pointer); +bool ValidateTexEnvf(const Context *context, + angle::EntryPoint entryPoint, + TextureEnvTarget targetPacked, + TextureEnvParameter pnamePacked, + GLfloat param); +bool ValidateTexEnvfv(const Context *context, + angle::EntryPoint entryPoint, + TextureEnvTarget targetPacked, + TextureEnvParameter pnamePacked, + const GLfloat *params); +bool ValidateTexEnvi(const Context *context, + angle::EntryPoint entryPoint, + TextureEnvTarget targetPacked, + TextureEnvParameter pnamePacked, + GLint param); +bool ValidateTexEnviv(const Context *context, + angle::EntryPoint entryPoint, + TextureEnvTarget targetPacked, + TextureEnvParameter pnamePacked, + const GLint *params); +bool ValidateTexEnvx(const Context *context, + angle::EntryPoint entryPoint, + TextureEnvTarget targetPacked, + TextureEnvParameter pnamePacked, + GLfixed param); +bool ValidateTexEnvxv(const Context *context, + angle::EntryPoint entryPoint, + TextureEnvTarget targetPacked, + TextureEnvParameter pnamePacked, + const GLfixed *params); +bool ValidateTexParameterx(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + GLfixed param); +bool ValidateTexParameterxv(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + const GLfixed *params); +bool ValidateTranslatef(const Context *context, + angle::EntryPoint entryPoint, + GLfloat x, + GLfloat y, + GLfloat z); +bool ValidateTranslatex(const Context *context, + angle::EntryPoint entryPoint, + GLfixed x, + GLfixed y, + GLfixed z); +bool ValidateVertexPointer(const Context *context, + angle::EntryPoint entryPoint, + GLint size, + VertexAttribType typePacked, + GLsizei stride, + const void *pointer); +} // namespace gl + +#endif // LIBANGLE_VALIDATION_ES1_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/validationES2.cpp b/gfx/angle/checkout/src/libANGLE/validationES2.cpp new file mode 100644 index 0000000000..00f5fc5502 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationES2.cpp @@ -0,0 +1,6544 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// validationES2.cpp: Validation functions for OpenGL ES 2.0 entry point parameters + +#include "libANGLE/validationES2_autogen.h" + +#include + +#include "common/mathutil.h" +#include "common/string_utils.h" +#include "common/utilities.h" +#include "libANGLE/Context.h" +#include "libANGLE/ErrorStrings.h" +#include "libANGLE/Fence.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/MemoryObject.h" +#include "libANGLE/Renderbuffer.h" +#include "libANGLE/Shader.h" +#include "libANGLE/Texture.h" +#include "libANGLE/Uniform.h" +#include "libANGLE/VertexArray.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/validationES.h" +#include "libANGLE/validationES2.h" +#include "libANGLE/validationES3_autogen.h" + +namespace gl +{ +using namespace err; + +namespace +{ + +bool IsPartialBlit(const Context *context, + const FramebufferAttachment *readBuffer, + const FramebufferAttachment *writeBuffer, + GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1) +{ + const Extents &writeSize = writeBuffer->getSize(); + const Extents &readSize = readBuffer->getSize(); + + if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 || dstX1 != writeSize.width || + dstY1 != writeSize.height || srcX1 != readSize.width || srcY1 != readSize.height) + { + return true; + } + + if (context->getState().isScissorTestEnabled()) + { + const Rectangle &scissor = context->getState().getScissor(); + return scissor.x > 0 || scissor.y > 0 || scissor.width < writeSize.width || + scissor.height < writeSize.height; + } + + return false; +} + +bool IsValidCopyTextureSourceInternalFormatEnum(GLenum internalFormat) +{ + // Table 1.1 from the CHROMIUM_copy_texture spec + switch (GetUnsizedFormat(internalFormat)) + { + case GL_RED: + case GL_ALPHA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_RGB: + case GL_RGBA: + case GL_RGB8: + case GL_RGBA8: + case GL_BGRA_EXT: + case GL_BGRA8_EXT: + return true; + + default: + return false; + } +} + +bool IsValidCopySubTextureSourceInternalFormat(GLenum internalFormat) +{ + return IsValidCopyTextureSourceInternalFormatEnum(internalFormat); +} + +bool IsValidCopyTextureDestinationInternalFormatEnum(GLint internalFormat) +{ + // Table 1.0 from the CHROMIUM_copy_texture spec + switch (internalFormat) + { + case GL_ALPHA: + case GL_BGRA8_EXT: + case GL_BGRA_EXT: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_R11F_G11F_B10F: + case GL_R16F: + case GL_R32F: + case GL_R8: + case GL_R8UI: + case GL_RG16F: + case GL_RG32F: + case GL_RG8: + case GL_RG8UI: + case GL_RGB: + case GL_RGB10_A2: + case GL_RGB16F: + case GL_RGB32F: + case GL_RGB565: + case GL_RGB5_A1: + case GL_RGB8: + case GL_RGB8UI: + case GL_RGB9_E5: + case GL_RGBA: + case GL_RGBA16F: + case GL_RGBA32F: + case GL_RGBA4: + case GL_RGBA8: + case GL_RGBA8UI: + case GL_RGBX8_ANGLE: + case GL_SRGB8: + case GL_SRGB8_ALPHA8: + case GL_SRGB_ALPHA_EXT: + case GL_SRGB_EXT: + return true; + + default: + return false; + } +} + +bool IsValidCopySubTextureDestionationInternalFormat(GLenum internalFormat) +{ + return IsValidCopyTextureDestinationInternalFormatEnum(internalFormat); +} + +bool IsValidCopyTextureDestinationFormatType(const Context *context, + angle::EntryPoint entryPoint, + GLint internalFormat, + GLenum type) +{ + if (!IsValidCopyTextureDestinationInternalFormatEnum(internalFormat)) + { + context->validationErrorF(entryPoint, GL_INVALID_OPERATION, kInvalidInternalFormat, + internalFormat); + return false; + } + + if (!ValidES3FormatCombination(GetUnsizedFormat(internalFormat), type, internalFormat)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kMismatchedTypeAndFormat); + return false; + } + + const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type); + if (!internalFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions())) + { + context->validationErrorF(entryPoint, GL_INVALID_OPERATION, kInvalidInternalFormat, + internalFormat); + return false; + } + + return true; +} + +bool IsValidCopyTextureDestinationTargetEnum(const Context *context, TextureTarget target) +{ + switch (target) + { + case TextureTarget::_2D: + case TextureTarget::CubeMapNegativeX: + case TextureTarget::CubeMapNegativeY: + case TextureTarget::CubeMapNegativeZ: + case TextureTarget::CubeMapPositiveX: + case TextureTarget::CubeMapPositiveY: + case TextureTarget::CubeMapPositiveZ: + return true; + + case TextureTarget::Rectangle: + return context->getExtensions().textureRectangleANGLE; + + default: + return false; + } +} + +bool IsValidCopyTextureDestinationTarget(const Context *context, + TextureType textureType, + TextureTarget target) +{ + return TextureTargetToType(target) == textureType; +} + +bool IsValidCopyTextureSourceTarget(const Context *context, TextureType type) +{ + switch (type) + { + case TextureType::_2D: + return true; + case TextureType::Rectangle: + return context->getExtensions().textureRectangleANGLE; + case TextureType::External: + return context->getExtensions().EGLImageExternalOES; + case TextureType::VideoImage: + return context->getExtensions().videoTextureWEBGL; + default: + return false; + } +} + +bool IsValidCopyTextureSourceLevel(const Context *context, TextureType type, GLint level) +{ + if (!ValidMipLevel(context, type, level)) + { + return false; + } + + if (level > 0 && context->getClientVersion() < ES_3_0) + { + return false; + } + + return true; +} + +bool IsValidCopyTextureDestinationLevel(const Context *context, + angle::EntryPoint entryPoint, + TextureType type, + GLint level, + GLsizei width, + GLsizei height, + bool isSubImage) +{ + if (!ValidMipLevel(context, type, level)) + { + return false; + } + + if (!ValidImageSizeParameters(context, entryPoint, type, level, width, height, 1, isSubImage)) + { + return false; + } + + const Caps &caps = context->getCaps(); + switch (type) + { + case TextureType::_2D: + return width <= (caps.max2DTextureSize >> level) && + height <= (caps.max2DTextureSize >> level); + case TextureType::Rectangle: + ASSERT(level == 0); + return width <= (caps.max2DTextureSize >> level) && + height <= (caps.max2DTextureSize >> level); + + case TextureType::CubeMap: + return width <= (caps.maxCubeMapTextureSize >> level) && + height <= (caps.maxCubeMapTextureSize >> level); + default: + return true; + } +} + +bool IsValidStencilFunc(GLenum func) +{ + switch (func) + { + case GL_NEVER: + case GL_ALWAYS: + case GL_LESS: + case GL_LEQUAL: + case GL_EQUAL: + case GL_GEQUAL: + case GL_GREATER: + case GL_NOTEQUAL: + return true; + + default: + return false; + } +} + +bool IsValidStencilFace(GLenum face) +{ + switch (face) + { + case GL_FRONT: + case GL_BACK: + case GL_FRONT_AND_BACK: + return true; + + default: + return false; + } +} + +bool IsValidStencilOp(GLenum op) +{ + switch (op) + { + case GL_ZERO: + case GL_KEEP: + case GL_REPLACE: + case GL_INCR: + case GL_DECR: + case GL_INVERT: + case GL_INCR_WRAP: + case GL_DECR_WRAP: + return true; + + default: + return false; + } +} + +static inline bool Valid1to4ComponentFloatColorBufferFormat(const Context *context, GLenum format) +{ + return (context->getExtensions().textureFloatOES && + (format == GL_RGBA32F || format == GL_RGB32F || format == GL_RG32F || + format == GL_R32F)) || + (context->getExtensions().textureHalfFloatOES && + (format == GL_RGBA16F || format == GL_RGB16F || format == GL_RG16F || + format == GL_R16F)); +} + +static inline bool Valid2to4ComponentFloatColorBufferFormat(const Context *context, GLenum format) +{ + return (context->getExtensions().textureFloatOES && + (format == GL_RGBA32F || format == GL_RGB32F || format == GL_RG32F)) || + (context->getExtensions().textureHalfFloatOES && + (format == GL_RGBA16F || format == GL_RGB16F || format == GL_RG16F)); +} + +static inline bool Valid3to4ComponentFloatColorBufferFormat(const Context *context, GLenum format) +{ + return (context->getExtensions().textureFloatOES && + (format == GL_RGBA32F || format == GL_RGB32F)) || + (context->getExtensions().textureHalfFloatOES && + (format == GL_RGBA16F || format == GL_RGB16F)); +} + +static inline bool Valid4ComponentFloatColorBufferFormat(const Context *context, GLenum format) +{ + return (context->getExtensions().textureFloatOES && format == GL_RGBA32F) || + (context->getExtensions().textureHalfFloatOES && format == GL_RGBA16F); +} + +bool ValidateES2CopyTexImageParameters(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum internalformat, + bool isSubImage, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border) +{ + if (!ValidTexture2DDestinationTarget(context, target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + + TextureType texType = TextureTargetToType(target); + if (!ValidImageSizeParameters(context, entryPoint, texType, level, width, height, 1, + isSubImage)) + { + // Error is already handled. + return false; + } + + Format textureFormat = Format::Invalid(); + if (!ValidateCopyTexImageParametersBase(context, entryPoint, target, level, internalformat, + isSubImage, xoffset, yoffset, 0, x, y, width, height, + border, &textureFormat)) + { + return false; + } + + ASSERT(textureFormat.valid() || !isSubImage); + + const Framebuffer *framebuffer = context->getState().getReadFramebuffer(); + GLenum colorbufferFormat = + framebuffer->getReadColorAttachment()->getFormat().info->sizedInternalFormat; + const auto &formatInfo = *textureFormat.info; + + // ValidateCopyTexImageParametersBase rejects compressed formats with GL_INVALID_OPERATION. + ASSERT(!formatInfo.compressed); + ASSERT(!GetInternalFormatInfo(internalformat, GL_UNSIGNED_BYTE).compressed); + + // ValidateCopyTexImageParametersBase rejects depth formats with GL_INVALID_OPERATION. + ASSERT(!formatInfo.depthBits); + ASSERT(!GetInternalFormatInfo(internalformat, GL_UNSIGNED_BYTE).depthBits); + + // [OpenGL ES 2.0.24] table 3.9 + if (isSubImage) + { + switch (formatInfo.format) + { + case GL_ALPHA: + if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 && + colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES && + colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX && + !Valid4ComponentFloatColorBufferFormat(context, colorbufferFormat)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat); + return false; + } + break; + case GL_LUMINANCE: + if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT && + colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES && + colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 && + colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT && + colorbufferFormat != GL_BGR5_A1_ANGLEX && + colorbufferFormat != GL_BGRX8_ANGLEX && colorbufferFormat != GL_RGBX8_ANGLE && + !Valid1to4ComponentFloatColorBufferFormat(context, colorbufferFormat)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat); + return false; + } + break; + case GL_RED_EXT: + if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT && + colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES && + colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 && + colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F && + colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F && + colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT && + colorbufferFormat != GL_BGR5_A1_ANGLEX && + colorbufferFormat != GL_BGRX8_ANGLEX && colorbufferFormat != GL_RGBX8_ANGLE && + !Valid1to4ComponentFloatColorBufferFormat(context, colorbufferFormat)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat); + return false; + } + break; + case GL_RG_EXT: + if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 && + colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 && + colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES && + colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F && + colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT && + colorbufferFormat != GL_BGR5_A1_ANGLEX && + colorbufferFormat != GL_BGRX8_ANGLEX && colorbufferFormat != GL_RGBX8_ANGLE && + !Valid2to4ComponentFloatColorBufferFormat(context, colorbufferFormat)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat); + return false; + } + break; + case GL_RGB: + if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES && + colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 && + colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F && + colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT && + colorbufferFormat != GL_BGR5_A1_ANGLEX && + colorbufferFormat != GL_BGRX8_ANGLEX && colorbufferFormat != GL_RGBX8_ANGLE && + !Valid3to4ComponentFloatColorBufferFormat(context, colorbufferFormat)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat); + return false; + } + break; + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 && + colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F && + colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX && + !Valid4ComponentFloatColorBufferFormat(context, colorbufferFormat)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat); + return false; + } + break; + default: + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat); + return false; + } + + if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloatOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat); + return false; + } + } + else + { + switch (internalformat) + { + case GL_ALPHA: + if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 && + colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT && + colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX && + !Valid4ComponentFloatColorBufferFormat(context, colorbufferFormat)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat); + return false; + } + break; + case GL_LUMINANCE: + case GL_RED_EXT: + if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT && + colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES && + colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 && + colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES && + colorbufferFormat != GL_BGR5_A1_ANGLEX && + colorbufferFormat != GL_BGRX8_ANGLEX && colorbufferFormat != GL_RGBX8_ANGLE && + !Valid1to4ComponentFloatColorBufferFormat(context, colorbufferFormat)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat); + return false; + } + break; + case GL_RG_EXT: + if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 && + colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 && + colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT && + colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX && + colorbufferFormat != GL_BGRX8_ANGLEX && colorbufferFormat != GL_RGBX8_ANGLE && + !Valid2to4ComponentFloatColorBufferFormat(context, colorbufferFormat)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat); + return false; + } + break; + case GL_RGB: + if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES && + colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 && + colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES && + colorbufferFormat != GL_BGR5_A1_ANGLEX && + colorbufferFormat != GL_BGRX8_ANGLEX && colorbufferFormat != GL_RGBX8_ANGLE && + !Valid3to4ComponentFloatColorBufferFormat(context, colorbufferFormat)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat); + return false; + } + break; + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 && + colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES && + colorbufferFormat != GL_BGR5_A1_ANGLEX && colorbufferFormat != GL_RGBA16F && + !Valid4ComponentFloatColorBufferFormat(context, colorbufferFormat)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat); + return false; + } + break; + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, + internalformat); + return false; + } + } + + // If width or height is zero, it is a no-op. Return false without setting an error. + return (width > 0 && height > 0); +} + +bool ValidCap(const Context *context, GLenum cap, bool queryOnly) +{ + switch (cap) + { + // EXT_multisample_compatibility + case GL_MULTISAMPLE_EXT: + case GL_SAMPLE_ALPHA_TO_ONE_EXT: + return context->getExtensions().multisampleCompatibilityEXT; + + case GL_CULL_FACE: + case GL_POLYGON_OFFSET_FILL: + case GL_SAMPLE_ALPHA_TO_COVERAGE: + case GL_SAMPLE_COVERAGE: + case GL_SCISSOR_TEST: + case GL_STENCIL_TEST: + case GL_DEPTH_TEST: + case GL_BLEND: + case GL_DITHER: + return true; + + case GL_PRIMITIVE_RESTART_FIXED_INDEX: + case GL_RASTERIZER_DISCARD: + return (context->getClientMajorVersion() >= 3); + + case GL_DEBUG_OUTPUT_SYNCHRONOUS: + case GL_DEBUG_OUTPUT: + return context->getExtensions().debugKHR; + + case GL_BIND_GENERATES_RESOURCE_CHROMIUM: + return queryOnly && context->getExtensions().bindGeneratesResourceCHROMIUM; + + case GL_CLIENT_ARRAYS_ANGLE: + return queryOnly && context->getExtensions().clientArraysANGLE; + + case GL_FRAMEBUFFER_SRGB_EXT: + return context->getExtensions().sRGBWriteControlEXT; + + case GL_SAMPLE_MASK: + return context->getClientVersion() >= Version(3, 1); + + case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE: + return queryOnly && context->getExtensions().robustResourceInitializationANGLE; + + case GL_TEXTURE_RECTANGLE_ANGLE: + return context->isWebGL(); + + // GL_APPLE_clip_distance/GL_EXT_clip_cull_distance + case GL_CLIP_DISTANCE0_EXT: + case GL_CLIP_DISTANCE1_EXT: + case GL_CLIP_DISTANCE2_EXT: + case GL_CLIP_DISTANCE3_EXT: + case GL_CLIP_DISTANCE4_EXT: + case GL_CLIP_DISTANCE5_EXT: + case GL_CLIP_DISTANCE6_EXT: + case GL_CLIP_DISTANCE7_EXT: + if (context->getExtensions().clipDistanceAPPLE || + context->getExtensions().clipCullDistanceEXT) + { + return true; + } + break; + case GL_SAMPLE_SHADING: + return context->getExtensions().sampleShadingOES; + case GL_SHADING_RATE_PRESERVE_ASPECT_RATIO_QCOM: + return context->getExtensions().shadingRateQCOM; + + // COLOR_LOGIC_OP is in GLES1, but exposed through an ANGLE extension. + case GL_COLOR_LOGIC_OP: + return context->getClientVersion() < Version(2, 0) || + context->getExtensions().logicOpANGLE; + + default: + break; + } + + // GLES1 emulation: GLES1-specific caps after this point + if (context->getClientVersion().major != 1) + { + return false; + } + + switch (cap) + { + case GL_ALPHA_TEST: + case GL_VERTEX_ARRAY: + case GL_NORMAL_ARRAY: + case GL_COLOR_ARRAY: + case GL_TEXTURE_COORD_ARRAY: + case GL_TEXTURE_2D: + case GL_LIGHTING: + case GL_LIGHT0: + case GL_LIGHT1: + case GL_LIGHT2: + case GL_LIGHT3: + case GL_LIGHT4: + case GL_LIGHT5: + case GL_LIGHT6: + case GL_LIGHT7: + case GL_NORMALIZE: + case GL_RESCALE_NORMAL: + case GL_COLOR_MATERIAL: + case GL_CLIP_PLANE0: + case GL_CLIP_PLANE1: + case GL_CLIP_PLANE2: + case GL_CLIP_PLANE3: + case GL_CLIP_PLANE4: + case GL_CLIP_PLANE5: + case GL_FOG: + case GL_POINT_SMOOTH: + case GL_LINE_SMOOTH: + return context->getClientVersion() < Version(2, 0); + case GL_POINT_SIZE_ARRAY_OES: + return context->getClientVersion() < Version(2, 0) && + context->getExtensions().pointSizeArrayOES; + case GL_TEXTURE_CUBE_MAP: + return context->getClientVersion() < Version(2, 0) && + context->getExtensions().textureCubeMapOES; + case GL_POINT_SPRITE_OES: + return context->getClientVersion() < Version(2, 0) && + context->getExtensions().pointSpriteOES; + default: + return false; + } +} + +// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section +// 3.1. +bool IsValidESSLCharacter(unsigned char c) +{ + // Printing characters are valid except " $ ` @ \ ' DEL. + if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' && + c != '\'') + { + return true; + } + + // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid. + if (c >= 9 && c <= 13) + { + return true; + } + + return false; +} + +bool IsValidESSLString(const char *str, size_t len) +{ + for (size_t i = 0; i < len; i++) + { + if (!IsValidESSLCharacter(str[i])) + { + return false; + } + } + + return true; +} + +bool ValidateWebGLNamePrefix(const Context *context, + angle::EntryPoint entryPoint, + const GLchar *name) +{ + ASSERT(context->isWebGL()); + + // WebGL 1.0 [Section 6.16] GLSL Constructs + // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL. + if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kWebglBindAttribLocationReservedPrefix); + return false; + } + + return true; +} + +bool ValidateWebGLNameLength(const Context *context, angle::EntryPoint entryPoint, size_t length) +{ + ASSERT(context->isWebGL()); + + if (context->isWebGL1() && length > 256) + { + // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths + // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute + // locations. + context->validationError(entryPoint, GL_INVALID_VALUE, kWebglNameLengthLimitExceeded); + + return false; + } + else if (length > 1024) + { + // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of + // uniform and attribute locations. + context->validationError(entryPoint, GL_INVALID_VALUE, kWebgl2NameLengthLimitExceeded); + return false; + } + + return true; +} + +bool ValidBlendFunc(const Context *context, GLenum val) +{ + const Extensions &ext = context->getExtensions(); + + // these are always valid for src and dst. + switch (val) + { + case GL_ZERO: + case GL_ONE: + case GL_SRC_COLOR: + case GL_ONE_MINUS_SRC_COLOR: + case GL_DST_COLOR: + case GL_ONE_MINUS_DST_COLOR: + case GL_SRC_ALPHA: + case GL_ONE_MINUS_SRC_ALPHA: + case GL_DST_ALPHA: + case GL_ONE_MINUS_DST_ALPHA: + case GL_CONSTANT_COLOR: + case GL_ONE_MINUS_CONSTANT_COLOR: + case GL_CONSTANT_ALPHA: + case GL_ONE_MINUS_CONSTANT_ALPHA: + return true; + + // EXT_blend_func_extended. + case GL_SRC1_COLOR_EXT: + case GL_SRC1_ALPHA_EXT: + case GL_ONE_MINUS_SRC1_COLOR_EXT: + case GL_ONE_MINUS_SRC1_ALPHA_EXT: + case GL_SRC_ALPHA_SATURATE_EXT: + return ext.blendFuncExtendedEXT; + + default: + return false; + } +} + +bool ValidSrcBlendFunc(const Context *context, GLenum val) +{ + if (ValidBlendFunc(context, val)) + return true; + + if (val == GL_SRC_ALPHA_SATURATE) + return true; + + return false; +} + +bool ValidDstBlendFunc(const Context *context, GLenum val) +{ + if (ValidBlendFunc(context, val)) + return true; + + if (val == GL_SRC_ALPHA_SATURATE) + { + if (context->getClientMajorVersion() >= 3) + return true; + } + + return false; +} + +bool ValidateES2TexImageParameters(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum internalformat, + bool isCompressed, + bool isSubImage, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + GLsizei imageSize, + const void *pixels) +{ + if (!ValidTexture2DDestinationTarget(context, target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + + return ValidateES2TexImageParametersBase(context, entryPoint, target, level, internalformat, + isCompressed, isSubImage, xoffset, yoffset, width, + height, border, format, type, imageSize, pixels); +} + +} // anonymous namespace + +bool ValidateES2TexImageParametersBase(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum internalformat, + bool isCompressed, + bool isSubImage, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + GLsizei imageSize, + const void *pixels) +{ + + TextureType texType = TextureTargetToType(target); + if (!ValidImageSizeParameters(context, entryPoint, texType, level, width, height, 1, + isSubImage)) + { + // Error already handled. + return false; + } + + if (!ValidMipLevel(context, texType, level)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel); + return false; + } + + if ((xoffset < 0 || std::numeric_limits::max() - xoffset < width) || + (yoffset < 0 || std::numeric_limits::max() - yoffset < height)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize); + return false; + } + + const Caps &caps = context->getCaps(); + + switch (texType) + { + case TextureType::_2D: + case TextureType::External: + case TextureType::VideoImage: + if (width > (caps.max2DTextureSize >> level) || + height > (caps.max2DTextureSize >> level)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize); + return false; + } + break; + + case TextureType::Rectangle: + ASSERT(level == 0); + if (width > caps.maxRectangleTextureSize || height > caps.maxRectangleTextureSize) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize); + return false; + } + if (isCompressed) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kRectangleTextureCompressed); + return false; + } + break; + + case TextureType::CubeMap: + if (!isSubImage && width != height) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kCubemapFacesEqualDimensions); + return false; + } + + if (width > (caps.maxCubeMapTextureSize >> level) || + height > (caps.maxCubeMapTextureSize >> level)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize); + return false; + } + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + + Texture *texture = context->getTextureByType(texType); + if (!texture) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferNotBound); + return false; + } + + // Verify zero border + if (border != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidBorder); + return false; + } + + bool nonEqualFormatsAllowed = false; + + if (isCompressed) + { + GLenum actualInternalFormat = + isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat + : internalformat; + + const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(actualInternalFormat); + + if (!internalFormatInfo.compressed && !internalFormatInfo.paletted) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kInvalidInternalFormat, + internalformat); + return false; + } + + if (!internalFormatInfo.textureSupport(context->getClientVersion(), + context->getExtensions())) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kInvalidInternalFormat, + internalformat); + return false; + } + + if (isSubImage) + { + // From OpenGL ES Version 1.1.12, section 3.7.4 Compressed Paletted + // Textures: + // + // Subimages may not be specified for compressed paletted textures. + // Calling CompressedTexSubImage2D with any of the PALETTE* + // arguments in table 3.11 will generate an INVALID OPERATION error. + if (internalFormatInfo.paletted) + { + context->validationErrorF(entryPoint, GL_INVALID_OPERATION, kInvalidInternalFormat, + internalformat); + return false; + } + + // From the OES_compressed_ETC1_RGB8_texture spec: + // + // INVALID_OPERATION is generated by CompressedTexSubImage2D, TexSubImage2D, or + // CopyTexSubImage2D if the texture image bound to has internal format + // ETC1_RGB8_OES. + // + // This is relaxed if GL_EXT_compressed_ETC1_RGB8_sub_texture is supported. + if (IsETC1Format(actualInternalFormat) && + !context->getExtensions().compressedETC1RGB8SubTextureEXT) + { + context->validationErrorF(entryPoint, GL_INVALID_OPERATION, kInvalidInternalFormat, + internalformat); + return false; + } + + if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, 0, + width, height, 1, texture->getWidth(target, level), + texture->getHeight(target, level), + texture->getDepth(target, level))) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInvalidCompressedImageSize); + return false; + } + + if (format != actualInternalFormat) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat); + return false; + } + } + else + { + if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height, 1)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInvalidCompressedImageSize); + return false; + } + } + } + else + { + // validate by itself (used as secondary key below) + switch (type) + { + case GL_UNSIGNED_BYTE: + case GL_UNSIGNED_SHORT_5_6_5: + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT: + case GL_UNSIGNED_INT: + case GL_UNSIGNED_INT_24_8_OES: + case GL_HALF_FLOAT_OES: + case GL_FLOAT: + break; + case GL_UNSIGNED_INT_2_10_10_10_REV_EXT: + if (!context->getExtensions().textureType2101010REVEXT) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, type); + return false; + } + break; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType); + return false; + } + + // validate + combinations + // - invalid -> sets INVALID_ENUM + // - invalid + combination -> sets INVALID_OPERATION + switch (format) + { + case GL_ALPHA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + switch (type) + { + case GL_UNSIGNED_BYTE: + case GL_FLOAT: + case GL_HALF_FLOAT_OES: + break; + default: + context->validationError(entryPoint, GL_INVALID_OPERATION, + kMismatchedTypeAndFormat); + return false; + } + break; + case GL_RED: + case GL_RG: + if (!context->getExtensions().textureRgEXT) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, + format); + return false; + } + switch (type) + { + case GL_UNSIGNED_BYTE: + break; + case GL_FLOAT: + if (!context->getExtensions().textureFloatOES) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, + kEnumNotSupported, type); + return false; + } + break; + case GL_HALF_FLOAT_OES: + if (!context->getExtensions().textureFloatOES && + !context->getExtensions().textureHalfFloatOES) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, + kEnumNotSupported, type); + return false; + } + break; + case GL_SHORT: + case GL_UNSIGNED_SHORT: + if (!context->getExtensions().textureNorm16EXT) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, + kEnumNotSupported, type); + return false; + } + break; + default: + context->validationError(entryPoint, GL_INVALID_OPERATION, + kMismatchedTypeAndFormat); + return false; + } + break; + case GL_RGB: + switch (type) + { + case GL_UNSIGNED_BYTE: + case GL_UNSIGNED_SHORT_5_6_5: + case GL_UNSIGNED_INT_2_10_10_10_REV_EXT: + case GL_FLOAT: + case GL_HALF_FLOAT_OES: + break; + case GL_SHORT: + case GL_UNSIGNED_SHORT: + if (!context->getExtensions().textureNorm16EXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kMismatchedTypeAndFormat); + return false; + } + break; + default: + context->validationError(entryPoint, GL_INVALID_OPERATION, + kMismatchedTypeAndFormat); + return false; + } + break; + case GL_RGBA: + switch (type) + { + case GL_UNSIGNED_BYTE: + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_FLOAT: + case GL_HALF_FLOAT_OES: + case GL_UNSIGNED_INT_2_10_10_10_REV_EXT: + break; + case GL_SHORT: + case GL_UNSIGNED_SHORT: + if (!context->getExtensions().textureNorm16EXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kMismatchedTypeAndFormat); + return false; + } + break; + default: + context->validationError(entryPoint, GL_INVALID_OPERATION, + kMismatchedTypeAndFormat); + return false; + } + break; + case GL_BGRA_EXT: + if (!context->getExtensions().textureFormatBGRA8888EXT) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, + format); + return false; + } + switch (type) + { + case GL_UNSIGNED_BYTE: + break; + default: + context->validationError(entryPoint, GL_INVALID_OPERATION, + kMismatchedTypeAndFormat); + return false; + } + break; + case GL_SRGB_EXT: + case GL_SRGB_ALPHA_EXT: + if (!context->getExtensions().sRGBEXT) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, + format); + return false; + } + switch (type) + { + case GL_UNSIGNED_BYTE: + break; + default: + context->validationError(entryPoint, GL_INVALID_OPERATION, + kMismatchedTypeAndFormat); + return false; + } + break; + case GL_DEPTH_COMPONENT: + switch (type) + { + case GL_UNSIGNED_SHORT: + case GL_UNSIGNED_INT: + break; + case GL_FLOAT: + if (!context->getExtensions().depthBufferFloat2NV) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kMismatchedTypeAndFormat); + return false; + } + break; + default: + context->validationError(entryPoint, GL_INVALID_OPERATION, + kMismatchedTypeAndFormat); + return false; + } + break; + case GL_DEPTH_STENCIL_OES: + switch (type) + { + case GL_UNSIGNED_INT_24_8_OES: + break; + default: + context->validationError(entryPoint, GL_INVALID_OPERATION, + kMismatchedTypeAndFormat); + return false; + } + break; + case GL_STENCIL_INDEX: + switch (type) + { + case GL_UNSIGNED_BYTE: + break; + default: + context->validationError(entryPoint, GL_INVALID_OPERATION, + kMismatchedTypeAndFormat); + return false; + } + break; + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, format); + return false; + } + + switch (format) + { + case GL_DEPTH_COMPONENT: + case GL_DEPTH_STENCIL_OES: + if (!context->getExtensions().depthTextureANGLE && + !((context->getExtensions().packedDepthStencilOES || + context->getExtensions().depthTextureCubeMapOES) && + context->getExtensions().depthTextureOES)) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, + format); + return false; + } + + switch (target) + { + case TextureTarget::_2D: + break; + case TextureTarget::CubeMapNegativeX: + case TextureTarget::CubeMapNegativeY: + case TextureTarget::CubeMapNegativeZ: + case TextureTarget::CubeMapPositiveX: + case TextureTarget::CubeMapPositiveY: + case TextureTarget::CubeMapPositiveZ: + if (!context->getExtensions().depthTextureCubeMapOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kMismatchedTargetAndFormat); + return false; + } + break; + default: + context->validationError(entryPoint, GL_INVALID_OPERATION, + kMismatchedTargetAndFormat); + return false; + } + + // OES_depth_texture supports loading depth data and multiple levels, + // but ANGLE_depth_texture does not + if (!context->getExtensions().depthTextureOES) + { + if (pixels != nullptr) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kPixelDataNotNull); + return false; + } + if (level != 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kLevelNotZero); + return false; + } + } + break; + case GL_STENCIL_INDEX: + if (!context->getExtensions().textureStencil8OES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat); + return false; + } + + switch (target) + { + case TextureTarget::_2D: + case TextureTarget::_2DArray: + case TextureTarget::CubeMapNegativeX: + case TextureTarget::CubeMapNegativeY: + case TextureTarget::CubeMapNegativeZ: + case TextureTarget::CubeMapPositiveX: + case TextureTarget::CubeMapPositiveY: + case TextureTarget::CubeMapPositiveZ: + break; + default: + context->validationError(entryPoint, GL_INVALID_OPERATION, + kMismatchedTargetAndFormat); + return false; + } + + if (internalformat != GL_STENCIL_INDEX8) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kMismatchedTargetAndFormat); + return false; + } + break; + default: + break; + } + + if (!isSubImage) + { + switch (internalformat) + { + // Core ES 2.0 formats + case GL_ALPHA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_RGB: + case GL_RGBA: + break; + + case GL_RGBA32F: + if (!context->getExtensions().colorBufferFloatRgbaCHROMIUM) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat); + return false; + } + + nonEqualFormatsAllowed = true; + + if (type != GL_FLOAT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kMismatchedTypeAndFormat); + return false; + } + if (format != GL_RGBA) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kMismatchedTypeAndFormat); + return false; + } + break; + + case GL_RGB32F: + if (!context->getExtensions().colorBufferFloatRgbCHROMIUM) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat); + return false; + } + + nonEqualFormatsAllowed = true; + + if (type != GL_FLOAT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kMismatchedTypeAndFormat); + return false; + } + if (format != GL_RGB) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kMismatchedTypeAndFormat); + return false; + } + break; + + case GL_BGRA_EXT: + if (!context->getExtensions().textureFormatBGRA8888EXT) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat); + return false; + } + break; + + case GL_DEPTH_COMPONENT: + if (!(context->getExtensions().depthTextureAny())) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat); + return false; + } + break; + + case GL_DEPTH_STENCIL: + if (!(context->getExtensions().depthTextureANGLE || + context->getExtensions().packedDepthStencilOES || + context->getExtensions().depthTextureCubeMapOES)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat); + return false; + } + break; + + case GL_STENCIL_INDEX8: + if (!context->getExtensions().textureStencil8OES) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat); + return false; + } + break; + + case GL_RED: + case GL_RG: + if (!context->getExtensions().textureRgEXT) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat); + return false; + } + break; + + case GL_SRGB_EXT: + case GL_SRGB_ALPHA_EXT: + if (!context->getExtensions().sRGBEXT) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, + internalformat); + return false; + } + break; + + case GL_RGB10_A2_EXT: + if (!context->getExtensions().textureType2101010REVEXT) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, + internalformat); + return false; + } + + if (type != GL_UNSIGNED_INT_2_10_10_10_REV_EXT || format != GL_RGBA) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kMismatchedTypeAndFormat); + return false; + } + + nonEqualFormatsAllowed = true; + + break; + + case GL_RGB5_A1: + if (context->getExtensions().textureType2101010REVEXT && + type == GL_UNSIGNED_INT_2_10_10_10_REV_EXT && format == GL_RGBA) + { + nonEqualFormatsAllowed = true; + } + + break; + + case GL_RGBX8_ANGLE: + if (context->getExtensions().rgbxInternalFormatANGLE && + type == GL_UNSIGNED_BYTE && format == GL_RGB) + { + nonEqualFormatsAllowed = true; + } + + break; + + case GL_R16_EXT: + case GL_RG16_EXT: + case GL_RGB16_EXT: + case GL_RGBA16_EXT: + case GL_R16_SNORM_EXT: + case GL_RG16_SNORM_EXT: + case GL_RGB16_SNORM_EXT: + case GL_RGBA16_SNORM_EXT: + if (!context->getExtensions().textureNorm16EXT) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, + internalformat); + return false; + } + break; + default: + // Compressed formats are not valid internal formats for glTexImage*D + context->validationErrorF(entryPoint, GL_INVALID_VALUE, kInvalidInternalFormat, + internalformat); + return false; + } + } + + if (type == GL_FLOAT) + { + if (!context->getExtensions().textureFloatOES) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, type); + return false; + } + } + else if (type == GL_HALF_FLOAT_OES) + { + if (!context->getExtensions().textureHalfFloatOES) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, type); + return false; + } + } + } + + if (isSubImage) + { + const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info; + if (textureInternalFormat.internalFormat == GL_NONE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureLevel); + return false; + } + + if (format != textureInternalFormat.format) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, err::kTextureFormatMismatch); + return false; + } + + if (context->isWebGL()) + { + if (GetInternalFormatInfo(format, type).sizedInternalFormat != + textureInternalFormat.sizedInternalFormat) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kTextureTypeMismatch); + return false; + } + } + + if (static_cast(xoffset + width) > texture->getWidth(target, level) || + static_cast(yoffset + height) > texture->getHeight(target, level)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kOffsetOverflow); + return false; + } + + if (width > 0 && height > 0 && pixels == nullptr && + context->getState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kPixelDataNull); + return false; + } + } + else + { + if (texture->getImmutableFormat()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kTextureIsImmutable); + return false; + } + } + + // From GL_CHROMIUM_color_buffer_float_rgb[a]: + // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for + // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the + // internalformat parameter and format parameter of TexImage2D must match is lifted for this + // case. + if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormatCombination); + return false; + } + + GLenum sizeCheckFormat = isSubImage ? format : internalformat; + return ValidImageDataSize(context, entryPoint, texType, width, height, 1, sizeCheckFormat, type, + pixels, imageSize); +} + +bool ValidateES2TexStorageParametersBase(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height) +{ + if (target != TextureType::_2D && target != TextureType::CubeMap && + target != TextureType::Rectangle) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + + if (width < 1 || height < 1 || levels < 1) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kTextureSizeTooSmall); + return false; + } + + if (target == TextureType::CubeMap && width != height) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kCubemapFacesEqualDimensions); + return false; + } + + if (levels != 1 && levels != log2(std::max(width, height)) + 1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidMipLevels); + return false; + } + + const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat); + if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat); + return false; + } + + const Caps &caps = context->getCaps(); + + switch (target) + { + case TextureType::_2D: + if (width > caps.max2DTextureSize || height > caps.max2DTextureSize) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize); + return false; + } + break; + case TextureType::Rectangle: + if (levels != 1) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel); + return false; + } + + if (width > caps.maxRectangleTextureSize || height > caps.maxRectangleTextureSize) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize); + return false; + } + if (formatInfo.compressed) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kRectangleTextureCompressed); + return false; + } + break; + case TextureType::CubeMap: + if (width > caps.maxCubeMapTextureSize || height > caps.maxCubeMapTextureSize) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize); + return false; + } + break; + case TextureType::InvalidEnum: + context->validationError(entryPoint, GL_INVALID_ENUM, kEnumInvalid); + return false; + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, + ToGLenum(target)); + return false; + } + + if (levels != 1 && !context->getExtensions().textureNpotOES) + { + if (!isPow2(width) || !isPow2(height)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kDimensionsMustBePow2); + return false; + } + } + + if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions())) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat); + return false; + } + + // Even with OES_texture_npot, some compressed formats may impose extra restrictions. + if (formatInfo.compressed) + { + if (!ValidCompressedImageSize(context, formatInfo.internalFormat, 0, width, height, 1)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidCompressedImageSize); + return false; + } + } + + switch (internalformat) + { + case GL_DEPTH_COMPONENT16: + case GL_DEPTH_COMPONENT32_OES: + switch (target) + { + case TextureType::_2D: + break; + case TextureType::CubeMap: + if (!context->getExtensions().depthTextureCubeMapOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInvalidTextureTarget); + return false; + } + break; + default: + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInvalidTextureTarget); + return false; + } + + // ANGLE_depth_texture only supports 1-level textures + if (!context->getExtensions().depthTextureOES) + { + if (levels != 1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidMipLevels); + return false; + } + } + break; + case GL_DEPTH24_STENCIL8_OES: + switch (target) + { + case TextureType::_2D: + break; + case TextureType::CubeMap: + if (!context->getExtensions().depthTextureCubeMapOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInvalidTextureTarget); + return false; + } + break; + default: + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInvalidTextureTarget); + return false; + } + + if (!context->getExtensions().packedDepthStencilOES && + !context->getExtensions().depthTextureCubeMapOES) + { + // ANGLE_depth_texture only supports 1-level textures + if (levels != 1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidMipLevels); + return false; + } + } + break; + + default: + break; + } + + Texture *texture = context->getTextureByType(target); + if (!texture || texture->id().value == 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kMissingTexture); + return false; + } + + if (texture->getImmutableFormat()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kTextureIsImmutable); + return false; + } + + return true; +} + +bool ValidateDiscardFramebufferEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLsizei numAttachments, + const GLenum *attachments) +{ + if (!context->getExtensions().discardFramebufferEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + bool defaultFramebuffer = false; + + switch (target) + { + case GL_FRAMEBUFFER: + defaultFramebuffer = + (context->getState().getTargetFramebuffer(GL_FRAMEBUFFER)->isDefault()); + break; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFramebufferTarget); + return false; + } + + return ValidateDiscardFramebufferBase(context, entryPoint, target, numAttachments, attachments, + defaultFramebuffer); +} + +bool ValidateBindVertexArrayOES(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID array) +{ + if (!context->getExtensions().vertexArrayObjectOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateBindVertexArrayBase(context, entryPoint, array); +} + +bool ValidateDeleteVertexArraysOES(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const VertexArrayID *arrays) +{ + if (!context->getExtensions().vertexArrayObjectOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateGenOrDelete(context, entryPoint, n); +} + +bool ValidateGenVertexArraysOES(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const VertexArrayID *arrays) +{ + if (!context->getExtensions().vertexArrayObjectOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateGenOrDelete(context, entryPoint, n); +} + +bool ValidateIsVertexArrayOES(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID array) +{ + if (!context->getExtensions().vertexArrayObjectOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return true; +} + +bool ValidateProgramBinaryOES(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLenum binaryFormat, + const void *binary, + GLint length) +{ + if (!context->getExtensions().getProgramBinaryOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramBinaryBase(context, entryPoint, program, binaryFormat, binary, length); +} + +bool ValidateGetProgramBinaryOES(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLsizei bufSize, + const GLsizei *length, + const GLenum *binaryFormat, + const void *binary) +{ + if (!context->getExtensions().getProgramBinaryOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateGetProgramBinaryBase(context, entryPoint, program, bufSize, length, binaryFormat, + binary); +} + +static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication) +{ + switch (source) + { + case GL_DEBUG_SOURCE_API: + case GL_DEBUG_SOURCE_SHADER_COMPILER: + case GL_DEBUG_SOURCE_WINDOW_SYSTEM: + case GL_DEBUG_SOURCE_OTHER: + // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted + return !mustBeThirdPartyOrApplication; + + case GL_DEBUG_SOURCE_THIRD_PARTY: + case GL_DEBUG_SOURCE_APPLICATION: + return true; + + default: + return false; + } +} + +static bool ValidDebugType(GLenum type) +{ + switch (type) + { + case GL_DEBUG_TYPE_ERROR: + case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: + case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: + case GL_DEBUG_TYPE_PERFORMANCE: + case GL_DEBUG_TYPE_PORTABILITY: + case GL_DEBUG_TYPE_OTHER: + case GL_DEBUG_TYPE_MARKER: + case GL_DEBUG_TYPE_PUSH_GROUP: + case GL_DEBUG_TYPE_POP_GROUP: + return true; + + default: + return false; + } +} + +static bool ValidDebugSeverity(GLenum severity) +{ + switch (severity) + { + case GL_DEBUG_SEVERITY_HIGH: + case GL_DEBUG_SEVERITY_MEDIUM: + case GL_DEBUG_SEVERITY_LOW: + case GL_DEBUG_SEVERITY_NOTIFICATION: + return true; + + default: + return false; + } +} + +bool ValidateDebugMessageControlKHR(const Context *context, + angle::EntryPoint entryPoint, + GLenum source, + GLenum type, + GLenum severity, + GLsizei count, + const GLuint *ids, + GLboolean enabled) +{ + if (!context->getExtensions().debugKHR) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (!ValidDebugSource(source, false) && source != GL_DONT_CARE) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidDebugSource); + return false; + } + + if (!ValidDebugType(type) && type != GL_DONT_CARE) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidDebugType); + return false; + } + + if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidDebugSeverity); + return false; + } + + if (count > 0) + { + if (source == GL_DONT_CARE || type == GL_DONT_CARE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidDebugSourceType); + return false; + } + + if (severity != GL_DONT_CARE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidDebugSeverity); + return false; + } + } + + return true; +} + +bool ValidateDebugMessageInsertKHR(const Context *context, + angle::EntryPoint entryPoint, + GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar *buf) +{ + if (!context->getExtensions().debugKHR) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (!context->getState().getDebug().isOutputEnabled()) + { + // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do + // not generate an error. + return false; + } + + if (!ValidDebugSeverity(severity)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidDebugSource); + return false; + } + + if (!ValidDebugType(type)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidDebugType); + return false; + } + + if (!ValidDebugSource(source, true)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidDebugSource); + return false; + } + + size_t messageLength = (length < 0) ? strlen(buf) : length; + if (messageLength > context->getCaps().maxDebugMessageLength) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxDebugMessageLength); + return false; + } + + return true; +} + +bool ValidateDebugMessageCallbackKHR(const Context *context, + angle::EntryPoint entryPoint, + GLDEBUGPROCKHR callback, + const void *userParam) +{ + if (!context->getExtensions().debugKHR) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return true; +} + +bool ValidateGetDebugMessageLogKHR(const Context *context, + angle::EntryPoint entryPoint, + GLuint count, + GLsizei bufSize, + const GLenum *sources, + const GLenum *types, + const GLuint *ids, + const GLenum *severities, + const GLsizei *lengths, + const GLchar *messageLog) +{ + if (!context->getExtensions().debugKHR) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (bufSize < 0 && messageLog != nullptr) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize); + return false; + } + + return true; +} + +bool ValidatePushDebugGroupKHR(const Context *context, + angle::EntryPoint entryPoint, + GLenum source, + GLuint id, + GLsizei length, + const GLchar *message) +{ + if (!context->getExtensions().debugKHR) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (!ValidDebugSource(source, true)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidDebugSource); + return false; + } + + size_t messageLength = (length < 0) ? strlen(message) : length; + if (messageLength > context->getCaps().maxDebugMessageLength) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxDebugMessageLength); + return false; + } + + size_t currentStackSize = context->getState().getDebug().getGroupStackDepth(); + if (currentStackSize >= context->getCaps().maxDebugGroupStackDepth) + { + context->validationError(entryPoint, GL_STACK_OVERFLOW, kExceedsMaxDebugGroupStackDepth); + return false; + } + + return true; +} + +bool ValidatePopDebugGroupKHR(const Context *context, angle::EntryPoint entryPoint) +{ + if (!context->getExtensions().debugKHR) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + size_t currentStackSize = context->getState().getDebug().getGroupStackDepth(); + if (currentStackSize <= 1) + { + context->validationError(entryPoint, GL_STACK_UNDERFLOW, kCannotPopDefaultDebugGroup); + return false; + } + + return true; +} + +static bool ValidateObjectIdentifierAndName(const Context *context, + angle::EntryPoint entryPoint, + GLenum identifier, + GLuint name) +{ + switch (identifier) + { + case GL_BUFFER: + if (context->getBuffer({name}) == nullptr) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidBufferName); + return false; + } + return true; + + case GL_SHADER: + if (context->getShader({name}) == nullptr) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidShaderName); + return false; + } + return true; + + case GL_PROGRAM: + if (context->getProgramNoResolveLink({name}) == nullptr) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidProgramName); + return false; + } + return true; + + case GL_VERTEX_ARRAY: + if (context->getVertexArray({name}) == nullptr) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidVertexArrayName); + return false; + } + return true; + + case GL_QUERY: + if (context->getQuery({name}) == nullptr) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidQueryName); + return false; + } + return true; + + case GL_TRANSFORM_FEEDBACK: + if (context->getTransformFeedback({name}) == nullptr) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kInvalidTransformFeedbackName); + return false; + } + return true; + + case GL_SAMPLER: + if (context->getSampler({name}) == nullptr) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidSamplerName); + return false; + } + return true; + + case GL_TEXTURE: + if (context->getTexture({name}) == nullptr) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidTextureName); + return false; + } + return true; + + case GL_RENDERBUFFER: + if (!context->isRenderbuffer({name})) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidRenderbufferName); + return false; + } + return true; + + case GL_FRAMEBUFFER: + if (context->getFramebuffer({name}) == nullptr) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidFramebufferName); + return false; + } + return true; + + case GL_PROGRAM_PIPELINE: + if (context->getProgramPipeline({name}) == nullptr) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidProgramPipelineName); + return false; + } + return true; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidIndentifier); + return false; + } +} + +static bool ValidateLabelLength(const Context *context, + angle::EntryPoint entryPoint, + GLsizei length, + const GLchar *label) +{ + size_t labelLength = 0; + + if (length < 0) + { + if (label != nullptr) + { + labelLength = strlen(label); + } + } + else + { + labelLength = static_cast(length); + } + + if (labelLength > context->getCaps().maxLabelLength) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxLabelLength); + return false; + } + + return true; +} + +bool ValidateObjectLabelKHR(const Context *context, + angle::EntryPoint entryPoint, + GLenum identifier, + GLuint name, + GLsizei length, + const GLchar *label) +{ + if (!context->getExtensions().debugKHR) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (!ValidateObjectIdentifierAndName(context, entryPoint, identifier, name)) + { + return false; + } + + if (!ValidateLabelLength(context, entryPoint, length, label)) + { + return false; + } + + return true; +} + +bool ValidateGetObjectLabelKHR(const Context *context, + angle::EntryPoint entryPoint, + GLenum identifier, + GLuint name, + GLsizei bufSize, + const GLsizei *length, + const GLchar *label) +{ + if (!context->getExtensions().debugKHR) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (bufSize < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize); + return false; + } + + if (!ValidateObjectIdentifierAndName(context, entryPoint, identifier, name)) + { + return false; + } + + return true; +} + +static bool ValidateObjectPtrName(const Context *context, + angle::EntryPoint entryPoint, + const void *ptr) +{ + if (context->getSync(reinterpret_cast(const_cast(ptr))) == nullptr) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidSyncPointer); + return false; + } + + return true; +} + +bool ValidateObjectPtrLabelKHR(const Context *context, + angle::EntryPoint entryPoint, + const void *ptr, + GLsizei length, + const GLchar *label) +{ + if (!context->getExtensions().debugKHR) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (!ValidateObjectPtrName(context, entryPoint, ptr)) + { + return false; + } + + if (!ValidateLabelLength(context, entryPoint, length, label)) + { + return false; + } + + return true; +} + +bool ValidateGetObjectPtrLabelKHR(const Context *context, + angle::EntryPoint entryPoint, + const void *ptr, + GLsizei bufSize, + const GLsizei *length, + const GLchar *label) +{ + if (!context->getExtensions().debugKHR) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (bufSize < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize); + return false; + } + + if (!ValidateObjectPtrName(context, entryPoint, ptr)) + { + return false; + } + + return true; +} + +bool ValidateGetPointervKHR(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + void *const *params) +{ + if (!context->getExtensions().debugKHR) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + // TODO: represent this in Context::getQueryParameterInfo. + switch (pname) + { + case GL_DEBUG_CALLBACK_FUNCTION: + case GL_DEBUG_CALLBACK_USER_PARAM: + break; + + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + + return true; +} + +bool ValidateGetPointervRobustANGLERobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + void *const *params) +{ + UNIMPLEMENTED(); + return false; +} + +bool ValidateBlitFramebufferANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter) +{ + if (!context->getExtensions().framebufferBlitANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kBlitExtensionNotAvailable); + return false; + } + + if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0) + { + // TODO(jmadill): Determine if this should be available on other implementations. + context->validationError(entryPoint, GL_INVALID_OPERATION, kBlitExtensionScaleOrFlip); + return false; + } + + if (filter == GL_LINEAR) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kBlitExtensionLinear); + return false; + } + + Framebuffer *readFramebuffer = context->getState().getReadFramebuffer(); + Framebuffer *drawFramebuffer = context->getState().getDrawFramebuffer(); + + if (mask & GL_COLOR_BUFFER_BIT) + { + const FramebufferAttachment *readColorAttachment = + readFramebuffer->getReadColorAttachment(); + const FramebufferAttachment *drawColorAttachment = + drawFramebuffer->getFirstColorAttachment(); + + if (readColorAttachment && drawColorAttachment) + { + if (!(readColorAttachment->type() == GL_TEXTURE && + (readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D || + readColorAttachment->getTextureImageIndex().getType() == + TextureType::Rectangle)) && + readColorAttachment->type() != GL_RENDERBUFFER && + readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kBlitExtensionFromInvalidAttachmentType); + return false; + } + + for (size_t drawbufferIdx = 0; + drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx) + { + const FramebufferAttachment *attachment = + drawFramebuffer->getDrawBuffer(drawbufferIdx); + if (attachment) + { + if (!(attachment->type() == GL_TEXTURE && + (attachment->getTextureImageIndex().getType() == TextureType::_2D || + attachment->getTextureImageIndex().getType() == + TextureType::Rectangle)) && + attachment->type() != GL_RENDERBUFFER && + attachment->type() != GL_FRAMEBUFFER_DEFAULT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kBlitExtensionToInvalidAttachmentType); + return false; + } + + // Return an error if the destination formats do not match + if (!Format::EquivalentForBlit(attachment->getFormat(), + readColorAttachment->getFormat())) + { + context->validationErrorF( + entryPoint, GL_INVALID_OPERATION, kBlitExtensionFormatMismatch, + readColorAttachment->getFormat().info->sizedInternalFormat, + attachment->getFormat().info->sizedInternalFormat); + return false; + } + } + } + + GLint samples = readFramebuffer->getSamples(context); + if (samples != 0 && + IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0, + srcX1, srcY1, dstX0, dstY0, dstX1, dstY1)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kBlitExtensionMultisampledWholeBufferBlit); + return false; + } + } + } + + GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT}; + GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT}; + for (size_t i = 0; i < 2; i++) + { + if (mask & masks[i]) + { + const FramebufferAttachment *readBuffer = + readFramebuffer->getAttachment(context, attachments[i]); + const FramebufferAttachment *drawBuffer = + drawFramebuffer->getAttachment(context, attachments[i]); + + if (readBuffer && drawBuffer) + { + if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1)) + { + // only whole-buffer copies are permitted + context->validationError(entryPoint, GL_INVALID_OPERATION, + kBlitExtensionDepthStencilWholeBufferBlit); + return false; + } + + if (readBuffer->getResourceSamples() != 0 || drawBuffer->getResourceSamples() != 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kBlitExtensionMultisampledDepthOrStencil); + return false; + } + } + } + } + + return ValidateBlitFramebufferParameters(context, entryPoint, srcX0, srcY0, srcX1, srcY1, dstX0, + dstY0, dstX1, dstY1, mask, filter); +} + +bool ValidateBlitFramebufferNV(const Context *context, + angle::EntryPoint entryPoint, + GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter) +{ + if (!context->getExtensions().framebufferBlitANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kBlitExtensionNotAvailable); + return false; + } + + return ValidateBlitFramebufferParameters(context, entryPoint, srcX0, srcY0, srcX1, srcY1, dstX0, + dstY0, dstX1, dstY1, mask, filter); +} + +bool ValidateClear(const Context *context, angle::EntryPoint entryPoint, GLbitfield mask) +{ + Framebuffer *fbo = context->getState().getDrawFramebuffer(); + const Extensions &extensions = context->getExtensions(); + + if (!ValidateFramebufferComplete(context, entryPoint, fbo)) + { + return false; + } + + if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidClearMask); + return false; + } + + if (extensions.webglCompatibilityANGLE && (mask & GL_COLOR_BUFFER_BIT) != 0) + { + constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED, + GL_SIGNED_NORMALIZED}; + + for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount(); + drawBufferIdx++) + { + if (!ValidateWebGLFramebufferAttachmentClearType(context, entryPoint, drawBufferIdx, + validComponentTypes, + ArraySize(validComponentTypes))) + { + return false; + } + } + } + + if ((extensions.multiviewOVR || extensions.multiview2OVR) && extensions.disjointTimerQueryEXT) + { + const State &state = context->getState(); + Framebuffer *framebuffer = state.getDrawFramebuffer(); + if (framebuffer->getNumViews() > 1 && state.isQueryActive(QueryType::TimeElapsed)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kMultiviewTimerQuery); + return false; + } + } + + return true; +} + +bool ValidateDrawBuffersEXT(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const GLenum *bufs) +{ + if (!context->getExtensions().drawBuffersEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateDrawBuffersBase(context, entryPoint, n, bufs); +} + +bool ValidateTexImage2D(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + const void *pixels) +{ + if (context->getClientMajorVersion() < 3) + { + return ValidateES2TexImageParameters(context, entryPoint, target, level, internalformat, + false, false, 0, 0, width, height, border, format, + type, -1, pixels); + } + + ASSERT(context->getClientMajorVersion() >= 3); + return ValidateES3TexImage2DParameters(context, entryPoint, target, level, internalformat, + false, false, 0, 0, 0, width, height, 1, border, format, + type, -1, pixels); +} + +bool ValidateTexImage2DRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels) +{ + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + if (context->getClientMajorVersion() < 3) + { + return ValidateES2TexImageParameters(context, entryPoint, target, level, internalformat, + false, false, 0, 0, width, height, border, format, + type, bufSize, pixels); + } + + ASSERT(context->getClientMajorVersion() >= 3); + return ValidateES3TexImage2DParameters(context, entryPoint, target, level, internalformat, + false, false, 0, 0, 0, width, height, 1, border, format, + type, bufSize, pixels); +} + +bool ValidateTexSubImage2D(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void *pixels) +{ + + if (context->getClientMajorVersion() < 3) + { + return ValidateES2TexImageParameters(context, entryPoint, target, level, GL_NONE, false, + true, xoffset, yoffset, width, height, 0, format, type, + -1, pixels); + } + + ASSERT(context->getClientMajorVersion() >= 3); + return ValidateES3TexImage2DParameters(context, entryPoint, target, level, GL_NONE, false, true, + xoffset, yoffset, 0, width, height, 1, 0, format, type, + -1, pixels); +} + +bool ValidateTexSubImage2DRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels) +{ + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + if (context->getClientMajorVersion() < 3) + { + return ValidateES2TexImageParameters(context, entryPoint, target, level, GL_NONE, false, + true, xoffset, yoffset, width, height, 0, format, type, + bufSize, pixels); + } + + ASSERT(context->getClientMajorVersion() >= 3); + return ValidateES3TexImage2DParameters(context, entryPoint, target, level, GL_NONE, false, true, + xoffset, yoffset, 0, width, height, 1, 0, format, type, + bufSize, pixels); +} + +bool ValidateTexSubImage3DOES(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *pixels) +{ + return ValidateTexSubImage3D(context, entryPoint, target, level, xoffset, yoffset, zoffset, + width, height, depth, format, type, pixels); +} + +bool ValidateCompressedTexImage2D(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + const void *data) +{ + if (context->getClientMajorVersion() < 3) + { + if (!ValidateES2TexImageParameters(context, entryPoint, target, level, internalformat, true, + false, 0, 0, width, height, border, GL_NONE, GL_NONE, -1, + data)) + { + return false; + } + } + else + { + ASSERT(context->getClientMajorVersion() >= 3); + if (!ValidateES3TexImage2DParameters(context, entryPoint, target, level, internalformat, + true, false, 0, 0, 0, width, height, 1, border, + GL_NONE, GL_NONE, -1, data)) + { + return false; + } + } + + const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat); + + GLuint expectedImageSize = 0; + if (!formatInfo.computeCompressedImageSize(Extents(width, height, 1), &expectedImageSize)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kIntegerOverflow); + return false; + } + + if (imageSize < 0 || static_cast(imageSize) != expectedImageSize) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kCompressedTextureDimensionsMustMatchData); + return false; + } + + if (target == TextureTarget::Rectangle) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kRectangleTextureCompressed); + return false; + } + + return true; +} + +bool ValidateCompressedTexImage2DRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + GLsizei dataSize, + const void *data) +{ + if (!ValidateRobustCompressedTexImageBase(context, entryPoint, imageSize, dataSize)) + { + return false; + } + + return ValidateCompressedTexImage2D(context, entryPoint, target, level, internalformat, width, + height, border, imageSize, data); +} + +bool ValidateCompressedTexImage3DOES(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + const void *data) +{ + return ValidateCompressedTexImage3D(context, entryPoint, target, level, internalformat, width, + height, depth, border, imageSize, data); +} + +bool ValidateCompressedTexSubImage2DRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + GLsizei dataSize, + const void *data) +{ + if (!ValidateRobustCompressedTexImageBase(context, entryPoint, imageSize, dataSize)) + { + return false; + } + + return ValidateCompressedTexSubImage2D(context, entryPoint, target, level, xoffset, yoffset, + width, height, format, imageSize, data); +} + +bool ValidateCompressedTexSubImage2D(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + const void *data) +{ + if (context->getClientMajorVersion() < 3) + { + if (!ValidateES2TexImageParameters(context, entryPoint, target, level, GL_NONE, true, true, + xoffset, yoffset, width, height, 0, format, GL_NONE, -1, + data)) + { + return false; + } + } + else + { + ASSERT(context->getClientMajorVersion() >= 3); + if (!ValidateES3TexImage2DParameters(context, entryPoint, target, level, GL_NONE, true, + true, xoffset, yoffset, 0, width, height, 1, 0, format, + GL_NONE, -1, data)) + { + return false; + } + } + + const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format); + GLuint blockSize = 0; + if (!formatInfo.computeCompressedImageSize(Extents(width, height, 1), &blockSize)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kIntegerOverflow); + return false; + } + + if (imageSize < 0 || static_cast(imageSize) != blockSize) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidCompressedImageSize); + return false; + } + + return true; +} + +bool ValidateCompressedTexSubImage3DOES(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const void *data) +{ + return ValidateCompressedTexSubImage3D(context, entryPoint, target, level, xoffset, yoffset, + zoffset, width, height, depth, format, imageSize, data); +} + +bool ValidateGetBufferPointervOES(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding target, + GLenum pname, + void *const *params) +{ + if (!context->getExtensions().mapbufferOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateGetBufferPointervBase(context, entryPoint, target, pname, nullptr, params); +} + +bool ValidateMapBufferOES(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding target, + GLenum access) +{ + if (!context->getExtensions().mapbufferOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (!context->isValidBufferBinding(target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBufferTypes); + return false; + } + + Buffer *buffer = context->getState().getTargetBuffer(target); + + if (buffer == nullptr) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferNotMappable); + return false; + } + + if (access != GL_WRITE_ONLY_OES) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidAccessBits); + return false; + } + + // Though there is no explicit mention of an interaction between GL_EXT_buffer_storage + // and GL_OES_mapbuffer extension, allow it as long as the access type of glmapbufferOES + // is compatible with the buffer's usage flags specified during glBufferStorageEXT + if (buffer->isImmutable() && (buffer->getStorageExtUsageFlags() & GL_MAP_WRITE_BIT) == 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferNotMappable); + return false; + } + + if (buffer->isMapped()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferAlreadyMapped); + return false; + } + + return ValidateMapBufferBase(context, entryPoint, target); +} + +bool ValidateUnmapBufferOES(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding target) +{ + if (!context->getExtensions().mapbufferOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateUnmapBufferBase(context, entryPoint, target); +} + +bool ValidateMapBufferRangeEXT(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding target, + GLintptr offset, + GLsizeiptr length, + GLbitfield access) +{ + if (!context->getExtensions().mapBufferRangeEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateMapBufferRangeBase(context, entryPoint, target, offset, length, access); +} + +bool ValidateMapBufferBase(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding target) +{ + Buffer *buffer = context->getState().getTargetBuffer(target); + ASSERT(buffer != nullptr); + + // Check if this buffer is currently being used as a transform feedback output buffer + if (context->getState().isTransformFeedbackActive()) + { + TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback(); + for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++) + { + const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i); + if (transformFeedbackBuffer.get() == buffer) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kBufferBoundForTransformFeedback); + return false; + } + } + } + + if (buffer->hasWebGLXFBBindingConflict(context->isWebGL())) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kBufferBoundForTransformFeedback); + return false; + } + + return true; +} + +bool ValidateFlushMappedBufferRangeEXT(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding target, + GLintptr offset, + GLsizeiptr length) +{ + if (!context->getExtensions().mapBufferRangeEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateFlushMappedBufferRangeBase(context, entryPoint, target, offset, length); +} + +bool ValidateBindUniformLocationCHROMIUM(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + const GLchar *name) +{ + if (!context->getExtensions().bindUniformLocationCHROMIUM) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + Program *programObject = GetValidProgram(context, entryPoint, program); + if (!programObject) + { + return false; + } + + if (location.value < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeLocation); + return false; + } + + const Caps &caps = context->getCaps(); + if (static_cast(location.value) >= + (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidBindUniformLocation); + return false; + } + + // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for + // shader-related entry points + if (context->isWebGL() && !IsValidESSLString(name, strlen(name))) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidNameCharacters); + return false; + } + + if (strncmp(name, "gl_", 3) == 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNameBeginsWithGL); + return false; + } + + return true; +} + +bool ValidateCoverageModulationCHROMIUM(const Context *context, + angle::EntryPoint entryPoint, + GLenum components) +{ + if (!context->getExtensions().framebufferMixedSamplesCHROMIUM) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + switch (components) + { + case GL_RGB: + case GL_RGBA: + case GL_ALPHA: + case GL_NONE: + break; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidCoverageComponents); + return false; + } + + return true; +} + +bool ValidateCopyTextureCHROMIUM(const Context *context, + angle::EntryPoint entryPoint, + TextureID sourceId, + GLint sourceLevel, + TextureTarget destTarget, + TextureID destId, + GLint destLevel, + GLint internalFormat, + GLenum destType, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha) +{ + if (!context->getExtensions().copyTextureCHROMIUM) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + const Texture *source = context->getTexture(sourceId); + if (source == nullptr) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidSourceTexture); + return false; + } + + if (!IsValidCopyTextureSourceTarget(context, source->getType())) + { + context->validationErrorF(entryPoint, GL_INVALID_OPERATION, kInvalidInternalFormat, + internalFormat); + return false; + } + + TextureType sourceType = source->getType(); + ASSERT(sourceType != TextureType::CubeMap); + TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType); + + if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidSourceTextureLevel); + return false; + } + + GLsizei sourceWidth = static_cast(source->getWidth(sourceTarget, sourceLevel)); + GLsizei sourceHeight = static_cast(source->getHeight(sourceTarget, sourceLevel)); + if (sourceWidth == 0 || sourceHeight == 0) + { + context->validationErrorF(entryPoint, GL_INVALID_OPERATION, kInvalidInternalFormat, + internalFormat); + return false; + } + + const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info; + if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInvalidSourceTextureInternalFormat); + return false; + } + + if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + + const Texture *dest = context->getTexture(destId); + if (dest == nullptr) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidDestinationTexture); + return false; + } + + const InternalFormat &destInternalFormatInfo = GetInternalFormatInfo(internalFormat, destType); + if (sourceType == TextureType::External && destInternalFormatInfo.isInt() && + !context->getExtensions().EGLImageExternalEssl3OES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kANGLECopyTextureMissingRequiredExtension); + return false; + } + + if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidDestinationTextureType); + return false; + } + + if (!IsValidCopyTextureDestinationLevel(context, entryPoint, dest->getType(), destLevel, + sourceWidth, sourceHeight, false)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel); + return false; + } + + if (!IsValidCopyTextureDestinationFormatType(context, entryPoint, internalFormat, destType)) + { + return false; + } + + if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kCubemapFacesEqualDimensions); + return false; + } + + if (dest->getImmutableFormat()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kDestinationImmutable); + return false; + } + + return true; +} + +bool ValidateCopySubTextureCHROMIUM(const Context *context, + angle::EntryPoint entryPoint, + TextureID sourceId, + GLint sourceLevel, + TextureTarget destTarget, + TextureID destId, + GLint destLevel, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha) +{ + if (!context->getExtensions().copyTextureCHROMIUM) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + const Texture *source = context->getTexture(sourceId); + if (source == nullptr) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidSourceTexture); + return false; + } + + if (!IsValidCopyTextureSourceTarget(context, source->getType())) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidSourceTextureType); + return false; + } + + TextureType sourceType = source->getType(); + ASSERT(sourceType != TextureType::CubeMap); + TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType); + + if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel); + return false; + } + + if (source->getWidth(sourceTarget, sourceLevel) == 0 || + source->getHeight(sourceTarget, sourceLevel) == 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidSourceTextureLevel); + return false; + } + + if (x < 0 || y < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset); + return false; + } + + if (width < 0 || height < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeSize); + return false; + } + + if (static_cast(x + width) > source->getWidth(sourceTarget, sourceLevel) || + static_cast(y + height) > source->getHeight(sourceTarget, sourceLevel)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kSourceTextureTooSmall); + return false; + } + + const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel); + if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat)) + { + context->validationErrorF(entryPoint, GL_INVALID_OPERATION, kInvalidInternalFormat, + sourceFormat.info->internalFormat); + return false; + } + + if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + + const Texture *dest = context->getTexture(destId); + if (dest == nullptr) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidDestinationTexture); + return false; + } + + if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidDestinationTextureType); + return false; + } + + if (!IsValidCopyTextureDestinationLevel(context, entryPoint, dest->getType(), destLevel, width, + height, true)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel); + return false; + } + + if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kDestinationLevelNotDefined); + return false; + } + + const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info; + if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormatCombination); + return false; + } + + if (sourceType == TextureType::External && destFormat.isInt() && + !context->getExtensions().EGLImageExternalEssl3OES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kANGLECopyTextureMissingRequiredExtension); + return false; + } + + if (xoffset < 0 || yoffset < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset); + return false; + } + + if (static_cast(xoffset + width) > dest->getWidth(destTarget, destLevel) || + static_cast(yoffset + height) > dest->getHeight(destTarget, destLevel)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kOffsetOverflow); + return false; + } + + return true; +} + +bool ValidateCompressedCopyTextureCHROMIUM(const Context *context, + angle::EntryPoint entryPoint, + TextureID sourceId, + TextureID destId) +{ + if (!context->getExtensions().copyCompressedTextureCHROMIUM) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + const Texture *source = context->getTexture(sourceId); + if (source == nullptr) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidSourceTexture); + return false; + } + + if (source->getType() != TextureType::_2D) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidSourceTextureType); + return false; + } + + if (source->getWidth(TextureTarget::_2D, 0) == 0 || + source->getHeight(TextureTarget::_2D, 0) == 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kSourceTextureLevelZeroDefined); + return false; + } + + const Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0); + if (!sourceFormat.info->compressed) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kSourceTextureMustBeCompressed); + return false; + } + + const Texture *dest = context->getTexture(destId); + if (dest == nullptr) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidDestinationTexture); + return false; + } + + if (dest->getType() != TextureType::_2D) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidDestinationTextureType); + return false; + } + + if (dest->getImmutableFormat()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kDestinationImmutable); + return false; + } + + return true; +} + +bool ValidateCreateShader(const Context *context, angle::EntryPoint entryPoint, ShaderType type) +{ + switch (type) + { + case ShaderType::Vertex: + case ShaderType::Fragment: + break; + + case ShaderType::Compute: + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kES31Required); + return false; + } + break; + + case ShaderType::Geometry: + if (!context->getExtensions().geometryShaderAny() && + context->getClientVersion() < ES_3_2) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShaderType); + return false; + } + break; + + case ShaderType::TessControl: + if (!context->getExtensions().tessellationShaderEXT && + context->getClientVersion() < ES_3_2) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShaderType); + return false; + } + break; + + case ShaderType::TessEvaluation: + if (!context->getExtensions().tessellationShaderEXT && + context->getClientVersion() < ES_3_2) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShaderType); + return false; + } + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShaderType); + return false; + } + + return true; +} + +bool ValidateBufferData(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding target, + GLsizeiptr size, + const void *data, + BufferUsage usage) +{ + if (size < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeSize); + return false; + } + + switch (usage) + { + case BufferUsage::StreamDraw: + case BufferUsage::StaticDraw: + case BufferUsage::DynamicDraw: + break; + + case BufferUsage::StreamRead: + case BufferUsage::StaticRead: + case BufferUsage::DynamicRead: + case BufferUsage::StreamCopy: + case BufferUsage::StaticCopy: + case BufferUsage::DynamicCopy: + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBufferUsage); + return false; + } + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBufferUsage); + return false; + } + + if (!context->isValidBufferBinding(target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBufferTypes); + return false; + } + + Buffer *buffer = context->getState().getTargetBuffer(target); + + if (!buffer) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferNotBound); + return false; + } + + if (buffer->hasWebGLXFBBindingConflict(context->isWebGL())) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kBufferBoundForTransformFeedback); + return false; + } + + if (buffer->isImmutable()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferImmutable); + return false; + } + + return true; +} + +bool ValidateBufferSubData(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding target, + GLintptr offset, + GLsizeiptr size, + const void *data) +{ + if (size < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeSize); + return false; + } + + if (offset < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset); + return false; + } + + if (!context->isValidBufferBinding(target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBufferTypes); + return false; + } + + Buffer *buffer = context->getState().getTargetBuffer(target); + + if (!buffer) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferNotBound); + return false; + } + + // EXT_buffer_storage allows persistently mapped buffers to be updated via glBufferSubData + bool isPersistent = (buffer->getAccessFlags() & GL_MAP_PERSISTENT_BIT_EXT) != 0; + + // Verify that buffer is not currently mapped unless persistent + if (buffer->isMapped() && !isPersistent) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferMapped); + return false; + } + + if (buffer->hasWebGLXFBBindingConflict(context->isWebGL())) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kBufferBoundForTransformFeedback); + return false; + } + + if (buffer->isImmutable() && + (buffer->getStorageExtUsageFlags() & GL_DYNAMIC_STORAGE_BIT_EXT) == 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferNotUpdatable); + return false; + } + + // Check for possible overflow of size + offset + angle::CheckedNumeric checkedSize(size); + checkedSize += offset; + if (!checkedSize.IsValid()) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kParamOverflow); + return false; + } + + if (size + offset > buffer->getSize()) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInsufficientBufferSize); + return false; + } + + return true; +} + +bool ValidateRequestExtensionANGLE(const Context *context, + angle::EntryPoint entryPoint, + const GLchar *name) +{ + if (!context->getExtensions().requestExtensionANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (!context->isExtensionRequestable(name)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotRequestable); + return false; + } + + return true; +} + +bool ValidateDisableExtensionANGLE(const Context *context, + angle::EntryPoint entryPoint, + const GLchar *name) +{ + if (!context->getExtensions().requestExtensionANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (!context->isExtensionDisablable(name)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotDisablable); + return false; + } + + return true; +} + +bool ValidateActiveTexture(const Context *context, angle::EntryPoint entryPoint, GLenum texture) +{ + if (context->getClientMajorVersion() < 2) + { + return ValidateMultitextureUnit(context, entryPoint, texture); + } + + if (texture < GL_TEXTURE0 || + texture > + GL_TEXTURE0 + static_cast(context->getCaps().maxCombinedTextureImageUnits) - 1) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidCombinedImageUnit); + return false; + } + + return true; +} + +bool ValidateAttachShader(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + ShaderProgramID shader) +{ + Program *programObject = GetValidProgram(context, entryPoint, program); + if (!programObject) + { + return false; + } + + Shader *shaderObject = GetValidShader(context, entryPoint, shader); + if (!shaderObject) + { + return false; + } + + if (programObject->getAttachedShader(shaderObject->getType())) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kShaderAttachmentHasShader); + return false; + } + + return true; +} + +bool ValidateBindAttribLocation(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLuint index, + const GLchar *name) +{ + if (index >= static_cast(context->getCaps().maxVertexAttributes)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute); + return false; + } + + if (strncmp(name, "gl_", 3) == 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kNameBeginsWithGL); + return false; + } + + if (context->isWebGL()) + { + const size_t length = strlen(name); + + if (!IsValidESSLString(name, length)) + { + // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters + // for shader-related entry points + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidNameCharacters); + return false; + } + + if (!ValidateWebGLNameLength(context, entryPoint, length) || + !ValidateWebGLNamePrefix(context, entryPoint, name)) + { + return false; + } + } + + return GetValidProgram(context, entryPoint, program) != nullptr; +} + +bool ValidateBindFramebuffer(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + FramebufferID framebuffer) +{ + return ValidateBindFramebufferBase(context, entryPoint, target, framebuffer); +} + +bool ValidateBindRenderbuffer(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + RenderbufferID renderbuffer) +{ + return ValidateBindRenderbufferBase(context, entryPoint, target, renderbuffer); +} + +static bool ValidBlendEquationMode(const Context *context, GLenum mode) +{ + switch (mode) + { + case GL_FUNC_ADD: + case GL_FUNC_SUBTRACT: + case GL_FUNC_REVERSE_SUBTRACT: + return true; + + case GL_MIN: + case GL_MAX: + return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinmaxEXT; + + default: + return false; + } +} + +static bool ValidAdvancedBlendEquationMode(const Context *context, GLenum mode) +{ + switch (mode) + { + case GL_MULTIPLY_KHR: + case GL_SCREEN_KHR: + case GL_OVERLAY_KHR: + case GL_DARKEN_KHR: + case GL_LIGHTEN_KHR: + case GL_COLORDODGE_KHR: + case GL_COLORBURN_KHR: + case GL_HARDLIGHT_KHR: + case GL_SOFTLIGHT_KHR: + case GL_DIFFERENCE_KHR: + case GL_EXCLUSION_KHR: + case GL_HSL_HUE_KHR: + case GL_HSL_SATURATION_KHR: + case GL_HSL_COLOR_KHR: + case GL_HSL_LUMINOSITY_KHR: + return context->getClientVersion() >= ES_3_2 || + context->getExtensions().blendEquationAdvancedKHR; + + default: + return false; + } +} + +bool ValidateBlendColor(const Context *context, + angle::EntryPoint entryPoint, + GLfloat red, + GLfloat green, + GLfloat blue, + GLfloat alpha) +{ + return true; +} + +bool ValidateBlendEquation(const Context *context, angle::EntryPoint entryPoint, GLenum mode) +{ + if (!ValidBlendEquationMode(context, mode) && !ValidAdvancedBlendEquationMode(context, mode)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBlendEquation); + return false; + } + + return true; +} + +bool ValidateBlendEquationSeparate(const Context *context, + angle::EntryPoint entryPoint, + GLenum modeRGB, + GLenum modeAlpha) +{ + if (!ValidBlendEquationMode(context, modeRGB)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBlendEquation); + return false; + } + + if (!ValidBlendEquationMode(context, modeAlpha)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBlendEquation); + return false; + } + + return true; +} + +bool ValidateBlendFunc(const Context *context, + angle::EntryPoint entryPoint, + GLenum sfactor, + GLenum dfactor) +{ + return ValidateBlendFuncSeparate(context, entryPoint, sfactor, dfactor, sfactor, dfactor); +} + +bool ValidateBlendFuncSeparate(const Context *context, + angle::EntryPoint entryPoint, + GLenum srcRGB, + GLenum dstRGB, + GLenum srcAlpha, + GLenum dstAlpha) +{ + if (!ValidSrcBlendFunc(context, srcRGB)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBlendFunction); + return false; + } + + if (!ValidDstBlendFunc(context, dstRGB)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBlendFunction); + return false; + } + + if (!ValidSrcBlendFunc(context, srcAlpha)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBlendFunction); + return false; + } + + if (!ValidDstBlendFunc(context, dstAlpha)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBlendFunction); + return false; + } + + if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc || + context->isWebGL()) + { + bool constantColorUsed = + (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR || + dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR); + + bool constantAlphaUsed = + (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA || + dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA); + + if (constantColorUsed && constantAlphaUsed) + { + if (context->isWebGL()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidConstantColor); + return false; + } + + WARN() << kConstantColorAlphaLimitation; + context->validationError(entryPoint, GL_INVALID_OPERATION, + kConstantColorAlphaLimitation); + return false; + } + } + + return true; +} + +bool ValidateGetString(const Context *context, angle::EntryPoint entryPoint, GLenum name) +{ + switch (name) + { + case GL_VENDOR: + case GL_RENDERER: + case GL_VERSION: + case GL_SHADING_LANGUAGE_VERSION: + case GL_EXTENSIONS: + break; + + case GL_REQUESTABLE_EXTENSIONS_ANGLE: + if (!context->getExtensions().requestExtensionANGLE) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidName); + return false; + } + break; + + case GL_SERIALIZED_CONTEXT_STRING_ANGLE: + if (!context->getExtensions().getSerializedContextStringANGLE) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidName); + return false; + } + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidName); + return false; + } + + return true; +} + +bool ValidateLineWidth(const Context *context, angle::EntryPoint entryPoint, GLfloat width) +{ + if (width <= 0.0f || isNaN(width)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidWidth); + return false; + } + + return true; +} + +bool ValidateDepthRangef(const Context *context, + angle::EntryPoint entryPoint, + GLfloat zNear, + GLfloat zFar) +{ + if (context->isWebGL() && zNear > zFar) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidDepthRange); + return false; + } + + return true; +} + +bool ValidateRenderbufferStorage(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum internalformat, + GLsizei width, + GLsizei height) +{ + return ValidateRenderbufferStorageParametersBase(context, entryPoint, target, 0, internalformat, + width, height); +} + +bool ValidateRenderbufferStorageMultisampleANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height) +{ + if (!context->getExtensions().framebufferMultisampleANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal + // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_VALUE is + // generated. + if (samples > context->getCaps().maxSamples) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kSamplesOutOfRange); + return false; + } + + // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create + // the specified storage. This is different than ES 3.0 in which a sample number higher + // than the maximum sample number supported by this format generates a GL_INVALID_VALUE. + // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3. + if (context->getClientMajorVersion() >= 3) + { + const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat); + if (static_cast(samples) > formatCaps.getMaxSamples()) + { + context->validationError(entryPoint, GL_OUT_OF_MEMORY, kSamplesOutOfRange); + return false; + } + } + + return ValidateRenderbufferStorageParametersBase(context, entryPoint, target, samples, + internalformat, width, height); +} + +bool ValidateCheckFramebufferStatus(const Context *context, + angle::EntryPoint entryPoint, + GLenum target) +{ + if (!ValidFramebufferTarget(context, target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFramebufferTarget); + return false; + } + + return true; +} + +bool ValidateClearColor(const Context *context, + angle::EntryPoint entryPoint, + GLfloat red, + GLfloat green, + GLfloat blue, + GLfloat alpha) +{ + return true; +} + +bool ValidateClearDepthf(const Context *context, angle::EntryPoint entryPoint, GLfloat depth) +{ + return true; +} + +bool ValidateClearStencil(const Context *context, angle::EntryPoint entryPoint, GLint s) +{ + return true; +} + +bool ValidateColorMask(const Context *context, + angle::EntryPoint entryPoint, + GLboolean red, + GLboolean green, + GLboolean blue, + GLboolean alpha) +{ + return true; +} + +bool ValidateCompileShader(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID shader) +{ + return true; +} + +bool ValidateCreateProgram(const Context *context, angle::EntryPoint entryPoint) +{ + return true; +} + +bool ValidateCullFace(const Context *context, angle::EntryPoint entryPoint, CullFaceMode mode) +{ + switch (mode) + { + case CullFaceMode::Front: + case CullFaceMode::Back: + case CullFaceMode::FrontAndBack: + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidCullMode); + return false; + } + + return true; +} + +bool ValidateDeleteProgram(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program) +{ + if (program.value == 0) + { + return false; + } + + if (!context->getProgramResolveLink(program)) + { + if (context->getShader(program)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExpectedProgramName); + return false; + } + else + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidProgramName); + return false; + } + } + + return true; +} + +bool ValidateDeleteShader(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID shader) +{ + if (shader.value == 0) + { + return false; + } + + if (!context->getShader(shader)) + { + if (context->getProgramResolveLink(shader)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidShaderName); + return false; + } + else + { + context->validationError(entryPoint, GL_INVALID_VALUE, kExpectedShaderName); + return false; + } + } + + return true; +} + +bool ValidateDepthFunc(const Context *context, angle::EntryPoint entryPoint, GLenum func) +{ + switch (func) + { + case GL_NEVER: + case GL_ALWAYS: + case GL_LESS: + case GL_LEQUAL: + case GL_EQUAL: + case GL_GREATER: + case GL_GEQUAL: + case GL_NOTEQUAL: + break; + + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, func); + return false; + } + + return true; +} + +bool ValidateDepthMask(const Context *context, angle::EntryPoint entryPoint, GLboolean flag) +{ + return true; +} + +bool ValidateDetachShader(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + ShaderProgramID shader) +{ + Program *programObject = GetValidProgram(context, entryPoint, program); + if (!programObject) + { + return false; + } + + Shader *shaderObject = GetValidShader(context, entryPoint, shader); + if (!shaderObject) + { + return false; + } + + const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType()); + if (attachedShader != shaderObject) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kShaderToDetachMustBeAttached); + return false; + } + + return true; +} + +bool ValidateDisableVertexAttribArray(const Context *context, + angle::EntryPoint entryPoint, + GLuint index) +{ + if (index >= static_cast(context->getCaps().maxVertexAttributes)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute); + return false; + } + + return true; +} + +bool ValidateEnableVertexAttribArray(const Context *context, + angle::EntryPoint entryPoint, + GLuint index) +{ + if (index >= static_cast(context->getCaps().maxVertexAttributes)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute); + return false; + } + + return true; +} + +bool ValidateFinish(const Context *context, angle::EntryPoint entryPoint) +{ + return true; +} + +bool ValidateFlush(const Context *context, angle::EntryPoint entryPoint) +{ + return true; +} + +bool ValidateFrontFace(const Context *context, angle::EntryPoint entryPoint, GLenum mode) +{ + switch (mode) + { + case GL_CW: + case GL_CCW: + break; + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, mode); + return false; + } + + return true; +} + +bool ValidateGetActiveAttrib(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLuint index, + GLsizei bufsize, + const GLsizei *length, + const GLint *size, + const GLenum *type, + const GLchar *name) +{ + if (bufsize < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize); + return false; + } + + Program *programObject = GetValidProgram(context, entryPoint, program); + + if (!programObject) + { + return false; + } + + if (index >= static_cast(programObject->getActiveAttributeCount())) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform); + return false; + } + + return true; +} + +bool ValidateGetActiveUniform(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLuint index, + GLsizei bufsize, + const GLsizei *length, + const GLint *size, + const GLenum *type, + const GLchar *name) +{ + if (bufsize < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize); + return false; + } + + Program *programObject = GetValidProgram(context, entryPoint, program); + + if (!programObject) + { + return false; + } + + if (index >= static_cast(programObject->getActiveUniformCount())) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform); + return false; + } + + return true; +} + +bool ValidateGetAttachedShaders(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLsizei maxcount, + const GLsizei *count, + const ShaderProgramID *shaders) +{ + if (maxcount < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeMaxCount); + return false; + } + + Program *programObject = GetValidProgram(context, entryPoint, program); + + if (!programObject) + { + return false; + } + + return true; +} + +bool ValidateGetAttribLocation(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + const GLchar *name) +{ + if (strncmp(name, "gl_", 3) == 0) + { + return false; + } + + if (context->isWebGL()) + { + const size_t length = strlen(name); + + if (!IsValidESSLString(name, length)) + { + // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters + // for shader-related entry points + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidNameCharacters); + return false; + } + + if (!ValidateWebGLNameLength(context, entryPoint, length) || + strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0) + { + return false; + } + } + + Program *programObject = GetValidProgram(context, entryPoint, program); + + if (!programObject) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotBound); + return false; + } + + if (!programObject->isLinked()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked); + return false; + } + + return true; +} + +bool ValidateGetBooleanv(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + const GLboolean *params) +{ + GLenum nativeType; + unsigned int numParams = 0; + return ValidateStateQuery(context, entryPoint, pname, &nativeType, &numParams); +} + +bool ValidateGetError(const Context *context, angle::EntryPoint entryPoint) +{ + return true; +} + +bool ValidateGetFloatv(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + const GLfloat *params) +{ + GLenum nativeType; + unsigned int numParams = 0; + return ValidateStateQuery(context, entryPoint, pname, &nativeType, &numParams); +} + +bool ValidateGetIntegerv(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + const GLint *params) +{ + GLenum nativeType; + unsigned int numParams = 0; + return ValidateStateQuery(context, entryPoint, pname, &nativeType, &numParams); +} + +bool ValidateGetProgramInfoLog(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLsizei bufsize, + const GLsizei *length, + const GLchar *infolog) +{ + if (bufsize < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize); + return false; + } + + Program *programObject = GetValidProgram(context, entryPoint, program); + if (!programObject) + { + return false; + } + + return true; +} + +bool ValidateGetShaderInfoLog(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID shader, + GLsizei bufsize, + const GLsizei *length, + const GLchar *infolog) +{ + if (bufsize < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize); + return false; + } + + Shader *shaderObject = GetValidShader(context, entryPoint, shader); + if (!shaderObject) + { + return false; + } + + return true; +} + +bool ValidateGetShaderPrecisionFormat(const Context *context, + angle::EntryPoint entryPoint, + GLenum shadertype, + GLenum precisiontype, + const GLint *range, + const GLint *precision) +{ + switch (shadertype) + { + case GL_VERTEX_SHADER: + case GL_FRAGMENT_SHADER: + break; + case GL_COMPUTE_SHADER: + context->validationError(entryPoint, GL_INVALID_OPERATION, + kUnimplementedComputeShaderPrecision); + return false; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShaderType); + return false; + } + + switch (precisiontype) + { + case GL_LOW_FLOAT: + case GL_MEDIUM_FLOAT: + case GL_HIGH_FLOAT: + case GL_LOW_INT: + case GL_MEDIUM_INT: + case GL_HIGH_INT: + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPrecision); + return false; + } + + return true; +} + +bool ValidateGetShaderSource(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID shader, + GLsizei bufsize, + const GLsizei *length, + const GLchar *source) +{ + if (bufsize < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize); + return false; + } + + Shader *shaderObject = GetValidShader(context, entryPoint, shader); + if (!shaderObject) + { + return false; + } + + return true; +} + +bool ValidateGetUniformLocation(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + const GLchar *name) +{ + if (strstr(name, "gl_") == name) + { + return false; + } + + // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for + // shader-related entry points + if (context->isWebGL() && !IsValidESSLString(name, strlen(name))) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidNameCharacters); + return false; + } + + Program *programObject = GetValidProgram(context, entryPoint, program); + + if (!programObject) + { + return false; + } + + if (!programObject->isLinked()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked); + return false; + } + + return true; +} + +bool ValidateHint(const Context *context, angle::EntryPoint entryPoint, GLenum target, GLenum mode) +{ + switch (mode) + { + case GL_FASTEST: + case GL_NICEST: + case GL_DONT_CARE: + break; + + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, mode); + return false; + } + + switch (target) + { + case GL_GENERATE_MIPMAP_HINT: + break; + + case GL_TEXTURE_FILTERING_HINT_CHROMIUM: + if (!context->getExtensions().textureFilteringHintCHROMIUM) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, target); + return false; + } + break; + + case GL_FRAGMENT_SHADER_DERIVATIVE_HINT: + if (context->getClientVersion() < ES_3_0 && + !context->getExtensions().standardDerivativesOES) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, target); + return false; + } + break; + + case GL_PERSPECTIVE_CORRECTION_HINT: + case GL_POINT_SMOOTH_HINT: + case GL_LINE_SMOOTH_HINT: + case GL_FOG_HINT: + if (context->getClientMajorVersion() >= 2) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, target); + return false; + } + break; + + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, target); + return false; + } + + return true; +} + +bool ValidateIsBuffer(const Context *context, angle::EntryPoint entryPoint, BufferID buffer) +{ + return true; +} + +bool ValidateIsFramebuffer(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebuffer) +{ + return true; +} + +bool ValidateIsProgram(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program) +{ + return true; +} + +bool ValidateIsRenderbuffer(const Context *context, + angle::EntryPoint entryPoint, + RenderbufferID renderbuffer) +{ + return true; +} + +bool ValidateIsShader(const Context *context, angle::EntryPoint entryPoint, ShaderProgramID shader) +{ + return true; +} + +bool ValidateIsTexture(const Context *context, angle::EntryPoint entryPoint, TextureID texture) +{ + return true; +} + +bool ValidatePixelStorei(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLint param) +{ + if (context->getClientMajorVersion() < 3) + { + switch (pname) + { + case GL_UNPACK_IMAGE_HEIGHT: + case GL_UNPACK_SKIP_IMAGES: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname); + return false; + + case GL_UNPACK_ROW_LENGTH: + case GL_UNPACK_SKIP_ROWS: + case GL_UNPACK_SKIP_PIXELS: + if (!context->getExtensions().unpackSubimageEXT) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname); + return false; + } + break; + + case GL_PACK_ROW_LENGTH: + case GL_PACK_SKIP_ROWS: + case GL_PACK_SKIP_PIXELS: + if (!context->getExtensions().packSubimageNV) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname); + return false; + } + break; + } + } + + if (param < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeParam); + return false; + } + + switch (pname) + { + case GL_UNPACK_ALIGNMENT: + if (param != 1 && param != 2 && param != 4 && param != 8) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidUnpackAlignment); + return false; + } + break; + + case GL_PACK_ALIGNMENT: + if (param != 1 && param != 2 && param != 4 && param != 8) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidUnpackAlignment); + return false; + } + break; + + case GL_PACK_REVERSE_ROW_ORDER_ANGLE: + if (!context->getExtensions().packReverseRowOrderANGLE) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + } + break; + + case GL_UNPACK_ROW_LENGTH: + case GL_UNPACK_IMAGE_HEIGHT: + case GL_UNPACK_SKIP_IMAGES: + case GL_UNPACK_SKIP_ROWS: + case GL_UNPACK_SKIP_PIXELS: + case GL_PACK_ROW_LENGTH: + case GL_PACK_SKIP_ROWS: + case GL_PACK_SKIP_PIXELS: + break; + + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + + return true; +} + +bool ValidatePolygonOffset(const Context *context, + angle::EntryPoint entryPoint, + GLfloat factor, + GLfloat units) +{ + return true; +} + +bool ValidateReleaseShaderCompiler(const Context *context, angle::EntryPoint entryPoint) +{ + return true; +} + +bool ValidateSampleCoverage(const Context *context, + angle::EntryPoint entryPoint, + GLfloat value, + GLboolean invert) +{ + return true; +} + +bool ValidateScissor(const Context *context, + angle::EntryPoint entryPoint, + GLint x, + GLint y, + GLsizei width, + GLsizei height) +{ + if (width < 0 || height < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeSize); + return false; + } + + return true; +} + +bool ValidateShaderBinary(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const ShaderProgramID *shaders, + GLenum binaryformat, + const void *binary, + GLsizei length) +{ + const std::vector &shaderBinaryFormats = context->getCaps().shaderBinaryFormats; + if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) == + shaderBinaryFormats.end()) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShaderBinaryFormat); + return false; + } + + return true; +} + +bool ValidateShaderSource(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID shader, + GLsizei count, + const GLchar *const *string, + const GLint *length) +{ + if (count < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeCount); + return false; + } + + Shader *shaderObject = GetValidShader(context, entryPoint, shader); + if (!shaderObject) + { + return false; + } + + return true; +} + +bool ValidateStencilFunc(const Context *context, + angle::EntryPoint entryPoint, + GLenum func, + GLint ref, + GLuint mask) +{ + if (!IsValidStencilFunc(func)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidStencil); + return false; + } + + return true; +} + +bool ValidateStencilFuncSeparate(const Context *context, + angle::EntryPoint entryPoint, + GLenum face, + GLenum func, + GLint ref, + GLuint mask) +{ + if (!IsValidStencilFace(face)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidStencil); + return false; + } + + if (!IsValidStencilFunc(func)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidStencil); + return false; + } + + return true; +} + +bool ValidateStencilMask(const Context *context, angle::EntryPoint entryPoint, GLuint mask) +{ + return true; +} + +bool ValidateStencilMaskSeparate(const Context *context, + angle::EntryPoint entryPoint, + GLenum face, + GLuint mask) +{ + if (!IsValidStencilFace(face)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidStencil); + return false; + } + + return true; +} + +bool ValidateStencilOp(const Context *context, + angle::EntryPoint entryPoint, + GLenum fail, + GLenum zfail, + GLenum zpass) +{ + if (!IsValidStencilOp(fail)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidStencil); + return false; + } + + if (!IsValidStencilOp(zfail)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidStencil); + return false; + } + + if (!IsValidStencilOp(zpass)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidStencil); + return false; + } + + return true; +} + +bool ValidateStencilOpSeparate(const Context *context, + angle::EntryPoint entryPoint, + GLenum face, + GLenum fail, + GLenum zfail, + GLenum zpass) +{ + if (!IsValidStencilFace(face)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidStencil); + return false; + } + + return ValidateStencilOp(context, entryPoint, fail, zfail, zpass); +} + +bool ValidateUniform1f(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLfloat x) +{ + return ValidateUniform(context, entryPoint, GL_FLOAT, location, 1); +} + +bool ValidateUniform1fv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + const GLfloat *v) +{ + return ValidateUniform(context, entryPoint, GL_FLOAT, location, count); +} + +bool ValidateUniform1i(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLint x) +{ + return ValidateUniform1iv(context, entryPoint, location, 1, &x); +} + +bool ValidateUniform2fv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + const GLfloat *v) +{ + return ValidateUniform(context, entryPoint, GL_FLOAT_VEC2, location, count); +} + +bool ValidateUniform2i(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLint x, + GLint y) +{ + return ValidateUniform(context, entryPoint, GL_INT_VEC2, location, 1); +} + +bool ValidateUniform2iv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + const GLint *v) +{ + return ValidateUniform(context, entryPoint, GL_INT_VEC2, location, count); +} + +bool ValidateUniform3f(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLfloat x, + GLfloat y, + GLfloat z) +{ + return ValidateUniform(context, entryPoint, GL_FLOAT_VEC3, location, 1); +} + +bool ValidateUniform3fv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + const GLfloat *v) +{ + return ValidateUniform(context, entryPoint, GL_FLOAT_VEC3, location, count); +} + +bool ValidateUniform3i(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLint x, + GLint y, + GLint z) +{ + return ValidateUniform(context, entryPoint, GL_INT_VEC3, location, 1); +} + +bool ValidateUniform3iv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + const GLint *v) +{ + return ValidateUniform(context, entryPoint, GL_INT_VEC3, location, count); +} + +bool ValidateUniform4f(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLfloat x, + GLfloat y, + GLfloat z, + GLfloat w) +{ + return ValidateUniform(context, entryPoint, GL_FLOAT_VEC4, location, 1); +} + +bool ValidateUniform4fv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + const GLfloat *v) +{ + return ValidateUniform(context, entryPoint, GL_FLOAT_VEC4, location, count); +} + +bool ValidateUniform4i(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLint x, + GLint y, + GLint z, + GLint w) +{ + return ValidateUniform(context, entryPoint, GL_INT_VEC4, location, 1); +} + +bool ValidateUniform4iv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + const GLint *v) +{ + return ValidateUniform(context, entryPoint, GL_INT_VEC4, location, count); +} + +bool ValidateUniformMatrix2fv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateUniformMatrix(context, entryPoint, GL_FLOAT_MAT2, location, count, transpose); +} + +bool ValidateUniformMatrix3fv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateUniformMatrix(context, entryPoint, GL_FLOAT_MAT3, location, count, transpose); +} + +bool ValidateUniformMatrix4fv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateUniformMatrix(context, entryPoint, GL_FLOAT_MAT4, location, count, transpose); +} + +bool ValidateValidateProgram(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program) +{ + Program *programObject = GetValidProgram(context, entryPoint, program); + + if (!programObject) + { + return false; + } + + return true; +} + +bool ValidateVertexAttrib1f(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLfloat x) +{ + return ValidateVertexAttribIndex(context, entryPoint, index); +} + +bool ValidateVertexAttrib1fv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLfloat *values) +{ + return ValidateVertexAttribIndex(context, entryPoint, index); +} + +bool ValidateVertexAttrib2f(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLfloat x, + GLfloat y) +{ + return ValidateVertexAttribIndex(context, entryPoint, index); +} + +bool ValidateVertexAttrib2fv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLfloat *values) +{ + return ValidateVertexAttribIndex(context, entryPoint, index); +} + +bool ValidateVertexAttrib3f(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLfloat x, + GLfloat y, + GLfloat z) +{ + return ValidateVertexAttribIndex(context, entryPoint, index); +} + +bool ValidateVertexAttrib3fv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLfloat *values) +{ + return ValidateVertexAttribIndex(context, entryPoint, index); +} + +bool ValidateVertexAttrib4f(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLfloat x, + GLfloat y, + GLfloat z, + GLfloat w) +{ + return ValidateVertexAttribIndex(context, entryPoint, index); +} + +bool ValidateVertexAttrib4fv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLfloat *values) +{ + return ValidateVertexAttribIndex(context, entryPoint, index); +} + +bool ValidateViewport(const Context *context, + angle::EntryPoint entryPoint, + GLint x, + GLint y, + GLsizei width, + GLsizei height) +{ + if (width < 0 || height < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kViewportNegativeSize); + return false; + } + + return true; +} + +bool ValidateGetFramebufferAttachmentParameteriv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + GLenum pname, + const GLint *params) +{ + return ValidateGetFramebufferAttachmentParameterivBase(context, entryPoint, target, attachment, + pname, nullptr); +} + +bool ValidateGetProgramiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLenum pname, + const GLint *params) +{ + return ValidateGetProgramivBase(context, entryPoint, program, pname, nullptr); +} + +bool ValidateCopyTexImage2D(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum internalformat, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border) +{ + if (context->getClientMajorVersion() < 3) + { + return ValidateES2CopyTexImageParameters(context, entryPoint, target, level, internalformat, + false, 0, 0, x, y, width, height, border); + } + + ASSERT(context->getClientMajorVersion() == 3); + return ValidateES3CopyTexImage2DParameters(context, entryPoint, target, level, internalformat, + false, 0, 0, 0, x, y, width, height, border); +} + +bool ValidateCopyTexSubImage2D(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) +{ + if (context->getClientMajorVersion() < 3) + { + return ValidateES2CopyTexImageParameters(context, entryPoint, target, level, GL_NONE, true, + xoffset, yoffset, x, y, width, height, 0); + } + + return ValidateES3CopyTexImage2DParameters(context, entryPoint, target, level, GL_NONE, true, + xoffset, yoffset, 0, x, y, width, height, 0); +} + +bool ValidateCopyTexSubImage3DOES(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) +{ + return ValidateCopyTexSubImage3D(context, entryPoint, target, level, xoffset, yoffset, zoffset, + x, y, width, height); +} + +bool ValidateDeleteBuffers(const Context *context, + angle::EntryPoint entryPoint, + GLint n, + const BufferID *buffers) +{ + return ValidateGenOrDelete(context, entryPoint, n); +} + +bool ValidateDeleteFramebuffers(const Context *context, + angle::EntryPoint entryPoint, + GLint n, + const FramebufferID *framebuffers) +{ + return ValidateGenOrDelete(context, entryPoint, n); +} + +bool ValidateDeleteRenderbuffers(const Context *context, + angle::EntryPoint entryPoint, + GLint n, + const RenderbufferID *renderbuffers) +{ + return ValidateGenOrDelete(context, entryPoint, n); +} + +bool ValidateDeleteTextures(const Context *context, + angle::EntryPoint entryPoint, + GLint n, + const TextureID *textures) +{ + return ValidateGenOrDelete(context, entryPoint, n); +} + +bool ValidateDisable(const Context *context, angle::EntryPoint entryPoint, GLenum cap) +{ + if (!ValidCap(context, cap, false)) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, cap); + return false; + } + + return true; +} + +bool ValidateEnable(const Context *context, angle::EntryPoint entryPoint, GLenum cap) +{ + if (!ValidCap(context, cap, false)) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, cap); + return false; + } + + if (context->getLimitations().noSampleAlphaToCoverageSupport && + cap == GL_SAMPLE_ALPHA_TO_COVERAGE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kNoSampleAlphaToCoveragesLimitation); + + // We also output an error message to the debugger window if tracing is active, so that + // developers can see the error message. + ERR() << kNoSampleAlphaToCoveragesLimitation; + return false; + } + + return true; +} + +bool ValidateFramebufferRenderbuffer(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + GLenum renderbuffertarget, + RenderbufferID renderbuffer) +{ + return ValidateFramebufferRenderbufferBase(context, entryPoint, target, attachment, + renderbuffertarget, renderbuffer); +} + +bool ValidateFramebufferTexture2D(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + TextureTarget textarget, + TextureID texture, + GLint level) +{ + // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap + // extension + if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmapOES && + level != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidFramebufferTextureLevel); + return false; + } + + if (!ValidateFramebufferTextureBase(context, entryPoint, target, attachment, texture, level)) + { + return false; + } + + if (texture.value != 0) + { + Texture *tex = context->getTexture(texture); + ASSERT(tex); + + const Caps &caps = context->getCaps(); + + switch (textarget) + { + case TextureTarget::_2D: + { + if (level > log2(caps.max2DTextureSize)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel); + return false; + } + if (tex->getType() != TextureType::_2D) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInvalidTextureTarget); + return false; + } + } + break; + + case TextureTarget::Rectangle: + { + if (level != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel); + return false; + } + if (tex->getType() != TextureType::Rectangle) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kTextureTargetMismatch); + return false; + } + } + break; + + case TextureTarget::CubeMapNegativeX: + case TextureTarget::CubeMapNegativeY: + case TextureTarget::CubeMapNegativeZ: + case TextureTarget::CubeMapPositiveX: + case TextureTarget::CubeMapPositiveY: + case TextureTarget::CubeMapPositiveZ: + { + if (level > log2(caps.maxCubeMapTextureSize)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel); + return false; + } + if (tex->getType() != TextureType::CubeMap) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kTextureTargetMismatch); + return false; + } + } + break; + + case TextureTarget::_2DMultisample: + { + if (context->getClientVersion() < ES_3_1 && + !context->getExtensions().textureMultisampleANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kMultisampleTextureExtensionOrES31Required); + return false; + } + + if (level != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kLevelNotZero); + return false; + } + if (tex->getType() != TextureType::_2DMultisample) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kTextureTargetMismatch); + return false; + } + } + break; + + case TextureTarget::External: + { + if (!context->getExtensions().YUVTargetEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kYUVTargetExtensionRequired); + return false; + } + + if (attachment != GL_COLOR_ATTACHMENT0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidAttachment); + return false; + } + + if (tex->getType() != TextureType::External) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kTextureTargetMismatch); + return false; + } + } + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + } + + return true; +} + +bool ValidateFramebufferTexture3DOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + TextureTarget textargetPacked, + TextureID texture, + GLint level, + GLint zoffset) +{ + // We don't call into a base ValidateFramebufferTexture3D here because + // it doesn't exist for OpenGL ES. This function is replaced by + // FramebufferTextureLayer in ES 3.x, which has broader support. + if (!context->getExtensions().texture3DOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + // Attachments are required to be bound to level 0 without ES3 or the + // GL_OES_fbo_render_mipmap extension + if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmapOES && + level != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidFramebufferTextureLevel); + return false; + } + + if (!ValidateFramebufferTextureBase(context, entryPoint, target, attachment, texture, level)) + { + return false; + } + + if (texture.value != 0) + { + Texture *tex = context->getTexture(texture); + ASSERT(tex); + + const Caps &caps = context->getCaps(); + + switch (textargetPacked) + { + case TextureTarget::_3D: + { + if (level > log2(caps.max3DTextureSize)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel); + return false; + } + if (zoffset >= caps.max3DTextureSize) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidZOffset); + return false; + } + if (tex->getType() != TextureType::_3D) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureType); + return false; + } + } + break; + + default: + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureTarget); + return false; + } + } + + return true; +} + +bool ValidateGenBuffers(const Context *context, + angle::EntryPoint entryPoint, + GLint n, + const BufferID *buffers) +{ + return ValidateGenOrDelete(context, entryPoint, n); +} + +bool ValidateGenFramebuffers(const Context *context, + angle::EntryPoint entryPoint, + GLint n, + const FramebufferID *framebuffers) +{ + return ValidateGenOrDelete(context, entryPoint, n); +} + +bool ValidateGenRenderbuffers(const Context *context, + angle::EntryPoint entryPoint, + GLint n, + const RenderbufferID *renderbuffers) +{ + return ValidateGenOrDelete(context, entryPoint, n); +} + +bool ValidateGenTextures(const Context *context, + angle::EntryPoint entryPoint, + GLint n, + const TextureID *textures) +{ + return ValidateGenOrDelete(context, entryPoint, n); +} + +bool ValidateGenerateMipmap(const Context *context, + angle::EntryPoint entryPoint, + TextureType target) +{ + return ValidateGenerateMipmapBase(context, entryPoint, target); +} + +bool ValidateGetBufferParameteriv(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding target, + GLenum pname, + const GLint *params) +{ + return ValidateGetBufferParameterBase(context, entryPoint, target, pname, false, nullptr); +} + +bool ValidateGetRenderbufferParameteriv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum pname, + const GLint *params) +{ + return ValidateGetRenderbufferParameterivBase(context, entryPoint, target, pname, nullptr); +} + +bool ValidateGetShaderiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID shader, + GLenum pname, + const GLint *params) +{ + return ValidateGetShaderivBase(context, entryPoint, shader, pname, nullptr); +} + +bool ValidateGetTexParameterfv(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum pname, + const GLfloat *params) +{ + return ValidateGetTexParameterBase(context, entryPoint, target, pname, nullptr); +} + +bool ValidateGetTexParameteriv(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum pname, + const GLint *params) +{ + return ValidateGetTexParameterBase(context, entryPoint, target, pname, nullptr); +} + +bool ValidateGetTexParameterIivOES(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum pname, + const GLint *params) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + return ValidateGetTexParameterBase(context, entryPoint, target, pname, nullptr); +} + +bool ValidateGetTexParameterIuivOES(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum pname, + const GLuint *params) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + return ValidateGetTexParameterBase(context, entryPoint, target, pname, nullptr); +} + +bool ValidateGetUniformfv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + const GLfloat *params) +{ + return ValidateGetUniformBase(context, entryPoint, program, location); +} + +bool ValidateGetUniformiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + const GLint *params) +{ + return ValidateGetUniformBase(context, entryPoint, program, location); +} + +bool ValidateGetVertexAttribfv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum pname, + const GLfloat *params) +{ + return ValidateGetVertexAttribBase(context, entryPoint, index, pname, nullptr, false, false); +} + +bool ValidateGetVertexAttribiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum pname, + const GLint *params) +{ + return ValidateGetVertexAttribBase(context, entryPoint, index, pname, nullptr, false, false); +} + +bool ValidateGetVertexAttribPointerv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum pname, + void *const *pointer) +{ + return ValidateGetVertexAttribBase(context, entryPoint, index, pname, nullptr, true, false); +} + +bool ValidateIsEnabled(const Context *context, angle::EntryPoint entryPoint, GLenum cap) +{ + if (!ValidCap(context, cap, true)) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, cap); + return false; + } + + return true; +} + +bool ValidateLinkProgram(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program) +{ + if (context->hasActiveTransformFeedback(program)) + { + // ES 3.0.4 section 2.15 page 91 + context->validationError(entryPoint, GL_INVALID_OPERATION, + kTransformFeedbackActiveDuringLink); + return false; + } + + Program *programObject = GetValidProgram(context, entryPoint, program); + if (!programObject) + { + return false; + } + + return true; +} + +bool ValidateReadPixels(const Context *context, + angle::EntryPoint entryPoint, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void *pixels) +{ + return ValidateReadPixelsBase(context, entryPoint, x, y, width, height, format, type, -1, + nullptr, nullptr, nullptr, pixels); +} + +bool ValidateTexParameterf(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum pname, + GLfloat param) +{ + return ValidateTexParameterBase(context, entryPoint, target, pname, -1, false, ¶m); +} + +bool ValidateTexParameterfv(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum pname, + const GLfloat *params) +{ + return ValidateTexParameterBase(context, entryPoint, target, pname, -1, true, params); +} + +bool ValidateTexParameteri(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum pname, + GLint param) +{ + return ValidateTexParameterBase(context, entryPoint, target, pname, -1, false, ¶m); +} + +bool ValidateTexParameteriv(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum pname, + const GLint *params) +{ + return ValidateTexParameterBase(context, entryPoint, target, pname, -1, true, params); +} + +bool ValidateTexParameterIivOES(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum pname, + const GLint *params) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + return ValidateTexParameterBase(context, entryPoint, target, pname, -1, true, params); +} + +bool ValidateTexParameterIuivOES(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum pname, + const GLuint *params) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + return ValidateTexParameterBase(context, entryPoint, target, pname, -1, true, params); +} + +bool ValidateUseProgram(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program) +{ + if (program.value != 0) + { + Program *programObject = context->getProgramResolveLink(program); + if (!programObject) + { + // ES 3.1.0 section 7.3 page 72 + if (context->getShader(program)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExpectedProgramName); + return false; + } + else + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidProgramName); + return false; + } + } + if (!programObject->isLinked()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked); + return false; + } + } + if (context->getState().isTransformFeedbackActiveUnpaused()) + { + // ES 3.0.4 section 2.15 page 91 + context->validationError(entryPoint, GL_INVALID_OPERATION, kTransformFeedbackUseProgram); + return false; + } + + return true; +} + +bool ValidateDeleteFencesNV(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const FenceNVID *fences) +{ + if (!context->getExtensions().fenceNV) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kNVFenceNotSupported); + return false; + } + + if (n < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeCount); + return false; + } + + return true; +} + +bool ValidateFinishFenceNV(const Context *context, angle::EntryPoint entryPoint, FenceNVID fence) +{ + if (!context->getExtensions().fenceNV) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kNVFenceNotSupported); + return false; + } + + FenceNV *fenceObject = context->getFenceNV(fence); + + if (fenceObject == nullptr) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFence); + return false; + } + + if (!fenceObject->isSet()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFenceState); + return false; + } + + return true; +} + +bool ValidateGenFencesNV(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const FenceNVID *fences) +{ + if (!context->getExtensions().fenceNV) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kNVFenceNotSupported); + return false; + } + + if (n < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeCount); + return false; + } + + return true; +} + +bool ValidateGetFenceivNV(const Context *context, + angle::EntryPoint entryPoint, + FenceNVID fence, + GLenum pname, + const GLint *params) +{ + if (!context->getExtensions().fenceNV) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kNVFenceNotSupported); + return false; + } + + FenceNV *fenceObject = context->getFenceNV(fence); + + if (fenceObject == nullptr) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFence); + return false; + } + + if (!fenceObject->isSet()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFenceState); + return false; + } + + switch (pname) + { + case GL_FENCE_STATUS_NV: + case GL_FENCE_CONDITION_NV: + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname); + return false; + } + + return true; +} + +bool ValidateGetGraphicsResetStatusEXT(const Context *context, angle::EntryPoint entryPoint) +{ + if (!context->getExtensions().robustnessEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return true; +} + +bool ValidateGetTranslatedShaderSourceANGLE(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID shader, + GLsizei bufsize, + const GLsizei *length, + const GLchar *source) +{ + if (!context->getExtensions().translatedShaderSourceANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (bufsize < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize); + return false; + } + + Shader *shaderObject = context->getShader(shader); + + if (!shaderObject) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidShaderName); + return false; + } + + return true; +} + +bool ValidateIsFenceNV(const Context *context, angle::EntryPoint entryPoint, FenceNVID fence) +{ + if (!context->getExtensions().fenceNV) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kNVFenceNotSupported); + return false; + } + + return true; +} + +bool ValidateSetFenceNV(const Context *context, + angle::EntryPoint entryPoint, + FenceNVID fence, + GLenum condition) +{ + if (!context->getExtensions().fenceNV) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kNVFenceNotSupported); + return false; + } + + if (condition != GL_ALL_COMPLETED_NV) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFenceCondition); + return false; + } + + FenceNV *fenceObject = context->getFenceNV(fence); + + if (fenceObject == nullptr) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFence); + return false; + } + + return true; +} + +bool ValidateTestFenceNV(const Context *context, angle::EntryPoint entryPoint, FenceNVID fence) +{ + if (!context->getExtensions().fenceNV) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kNVFenceNotSupported); + return false; + } + + FenceNV *fenceObject = context->getFenceNV(fence); + + if (fenceObject == nullptr) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFence); + return false; + } + + if (fenceObject->isSet() != GL_TRUE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFenceState); + return false; + } + + return true; +} + +bool ValidateTexStorage2DEXT(const Context *context, + angle::EntryPoint entryPoint, + TextureType type, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height) +{ + if (!context->getExtensions().textureStorageEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (context->getClientMajorVersion() < 3) + { + return ValidateES2TexStorageParametersBase(context, entryPoint, type, levels, + internalformat, width, height); + } + + ASSERT(context->getClientMajorVersion() >= 3); + return ValidateES3TexStorage2DParameters(context, entryPoint, type, levels, internalformat, + width, height, 1); +} + +bool ValidateVertexAttribDivisorANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLuint divisor) +{ + if (!context->getExtensions().instancedArraysANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (index >= static_cast(context->getCaps().maxVertexAttributes)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute); + return false; + } + + if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT) + { + if (index == 0 && divisor != 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kAttributeZeroRequiresDivisorLimitation); + + // We also output an error message to the debugger window if tracing is active, so + // that developers can see the error message. + ERR() << kAttributeZeroRequiresDivisorLimitation; + return false; + } + } + + return true; +} + +bool ValidateVertexAttribDivisorEXT(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLuint divisor) +{ + if (!context->getExtensions().instancedArraysEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (index >= static_cast(context->getCaps().maxVertexAttributes)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute); + return false; + } + + return true; +} + +bool ValidateTexImage3DOES(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const void *pixels) +{ + return ValidateTexImage3D(context, entryPoint, target, level, internalformat, width, height, + depth, border, format, type, pixels); +} + +bool ValidatePopGroupMarkerEXT(const Context *context, angle::EntryPoint entryPoint) +{ + if (!context->getExtensions().debugMarkerEXT) + { + // The debug marker calls should not set error state + // However, it seems reasonable to set an error state if the extension is not enabled + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return true; +} + +bool ValidateTexStorage1DEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width) +{ + UNIMPLEMENTED(); + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; +} + +bool ValidateTexStorage3DEXT(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth) +{ + if (!context->getExtensions().textureStorageEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateES3TexStorage3DParameters(context, entryPoint, target, levels, internalformat, + width, height, depth); +} + +bool ValidateMaxShaderCompilerThreadsKHR(const Context *context, + angle::EntryPoint entryPoint, + GLuint count) +{ + if (!context->getExtensions().parallelShaderCompileKHR) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + return true; +} + +bool ValidateMultiDrawArraysANGLE(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + const GLint *firsts, + const GLsizei *counts, + GLsizei drawcount) +{ + if (!context->getExtensions().multiDrawANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + for (GLsizei drawID = 0; drawID < drawcount; ++drawID) + { + if (!ValidateDrawArrays(context, entryPoint, mode, firsts[drawID], counts[drawID])) + { + return false; + } + } + return true; +} + +bool ValidateMultiDrawElementsANGLE(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + const GLsizei *counts, + DrawElementsType type, + const GLvoid *const *indices, + GLsizei drawcount) +{ + if (!context->getExtensions().multiDrawANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + for (GLsizei drawID = 0; drawID < drawcount; ++drawID) + { + if (!ValidateDrawElements(context, entryPoint, mode, counts[drawID], type, indices[drawID])) + { + return false; + } + } + return true; +} + +bool ValidateProvokingVertexANGLE(const Context *context, + angle::EntryPoint entryPoint, + ProvokingVertexConvention modePacked) +{ + if (!context->getExtensions().provokingVertexANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + switch (modePacked) + { + case ProvokingVertexConvention::FirstVertexConvention: + case ProvokingVertexConvention::LastVertexConvention: + break; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidProvokingVertex); + return false; + } + + return true; +} + +bool ValidateFramebufferTexture2DMultisampleEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + TextureTarget textarget, + TextureID texture, + GLint level, + GLsizei samples) +{ + if (!context->getExtensions().multisampledRenderToTextureEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (samples < 0) + { + return false; + } + + // EXT_multisampled_render_to_texture states that the value of samples + // must be less than or equal to MAX_SAMPLES_EXT (Context::getCaps().maxSamples) + // otherwise GL_INVALID_VALUE is generated. + if (samples > context->getCaps().maxSamples) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kSamplesOutOfRange); + return false; + } + + if (!ValidateFramebufferTextureBase(context, entryPoint, target, attachment, texture, level)) + { + return false; + } + + // EXT_multisampled_render_to_texture returns INVALID_OPERATION when a sample number higher than + // the maximum sample number supported by this format is passed. + // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3. + if (texture.value != 0 && context->getClientMajorVersion() >= 3) + { + Texture *tex = context->getTexture(texture); + GLenum sizedInternalFormat = tex->getFormat(textarget, level).info->sizedInternalFormat; + const TextureCaps &formatCaps = context->getTextureCaps().get(sizedInternalFormat); + if (static_cast(samples) > formatCaps.getMaxSamples()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kSamplesOutOfRange); + return false; + } + } + + // Unless EXT_multisampled_render_to_texture2 is enabled, only color attachment 0 can be used. + if (!context->getExtensions().multisampledRenderToTexture2EXT && + attachment != GL_COLOR_ATTACHMENT0) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidAttachment); + return false; + } + + if (!ValidTexture2DDestinationTarget(context, textarget)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + + return true; +} + +bool ValidateRenderbufferStorageMultisampleEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height) +{ + if (!context->getExtensions().multisampledRenderToTextureEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + if (!ValidateRenderbufferStorageParametersBase(context, entryPoint, target, samples, + internalformat, width, height)) + { + return false; + } + + // EXT_multisampled_render_to_texture states that the value of samples + // must be less than or equal to MAX_SAMPLES_EXT (Context::getCaps().maxSamples) + // otherwise GL_INVALID_VALUE is generated. + if (samples > context->getCaps().maxSamples) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kSamplesOutOfRange); + return false; + } + + // EXT_multisampled_render_to_texture returns GL_OUT_OF_MEMORY on failure to create + // the specified storage. This is different than ES 3.0 in which a sample number higher + // than the maximum sample number supported by this format generates a GL_INVALID_VALUE. + // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3. + if (context->getClientMajorVersion() >= 3) + { + const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat); + if (static_cast(samples) > formatCaps.getMaxSamples()) + { + context->validationError(entryPoint, GL_OUT_OF_MEMORY, kSamplesOutOfRange); + return false; + } + } + + return true; +} + +void RecordBindTextureTypeError(const Context *context, + angle::EntryPoint entryPoint, + TextureType target) +{ + ASSERT(!context->getStateCache().isValidBindTextureType(target)); + + switch (target) + { + case TextureType::Rectangle: + ASSERT(!context->getExtensions().textureRectangleANGLE); + context->validationError(entryPoint, GL_INVALID_ENUM, kTextureRectangleNotSupported); + break; + + case TextureType::_3D: + case TextureType::_2DArray: + ASSERT(context->getClientMajorVersion() < 3); + context->validationError(entryPoint, GL_INVALID_ENUM, kES3Required); + break; + + case TextureType::_2DMultisample: + ASSERT(context->getClientVersion() < Version(3, 1) && + !context->getExtensions().textureMultisampleANGLE); + context->validationError(entryPoint, GL_INVALID_ENUM, + kMultisampleTextureExtensionOrES31Required); + break; + + case TextureType::_2DMultisampleArray: + ASSERT(!context->getExtensions().textureStorageMultisample2dArrayOES); + context->validationError(entryPoint, GL_INVALID_ENUM, + kMultisampleArrayExtensionRequired); + break; + + case TextureType::External: + ASSERT(!context->getExtensions().EGLImageExternalOES && + !context->getExtensions().EGLStreamConsumerExternalNV); + context->validationError(entryPoint, GL_INVALID_ENUM, kExternalTextureNotSupported); + break; + + case TextureType::VideoImage: + ASSERT(!context->getExtensions().videoTextureWEBGL); + context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled); + break; + + case TextureType::Buffer: + ASSERT(!context->getExtensions().textureBufferOES && + !context->getExtensions().textureBufferEXT); + context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled); + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + } +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/validationES2.h b/gfx/angle/checkout/src/libANGLE/validationES2.h new file mode 100644 index 0000000000..399779aa7c --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationES2.h @@ -0,0 +1,207 @@ +// +// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// validationES2.h: +// Inlined validation functions for OpenGL ES 2.0 entry points. + +#ifndef LIBANGLE_VALIDATION_ES2_H_ +#define LIBANGLE_VALIDATION_ES2_H_ + +#include "libANGLE/ErrorStrings.h" +#include "libANGLE/validationES.h" +#include "libANGLE/validationES2_autogen.h" + +namespace gl +{ +ANGLE_INLINE bool ValidateDrawArrays(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLint first, + GLsizei count) +{ + return ValidateDrawArraysCommon(context, entryPoint, mode, first, count, 1); +} + +ANGLE_INLINE bool ValidateUniform2f(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLfloat x, + GLfloat y) +{ + return ValidateUniform(context, entryPoint, GL_FLOAT_VEC2, location, 1); +} + +ANGLE_INLINE bool ValidateBindBuffer(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding target, + BufferID buffer) +{ + if (!context->isValidBufferBinding(target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, err::kInvalidBufferTypes); + return false; + } + + if (!context->getState().isBindGeneratesResourceEnabled() && + !context->isBufferGenerated(buffer)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, err::kObjectNotGenerated); + return false; + } + + return true; +} + +ANGLE_INLINE bool ValidateDrawElements(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLsizei count, + DrawElementsType type, + const void *indices) +{ + return ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 1); +} + +ANGLE_INLINE bool ValidateVertexAttribPointer(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLint size, + VertexAttribType type, + GLboolean normalized, + GLsizei stride, + const void *ptr) +{ + if (!ValidateFloatVertexFormat(context, entryPoint, index, size, type)) + { + return false; + } + + if (stride < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, err::kNegativeStride); + return false; + } + + if (context->getClientVersion() >= ES_3_1) + { + const Caps &caps = context->getCaps(); + if (stride > caps.maxVertexAttribStride) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + err::kExceedsMaxVertexAttribStride); + return false; + } + + if (index >= static_cast(caps.maxVertexAttribBindings)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + err::kExceedsMaxVertexAttribBindings); + return false; + } + } + + // [OpenGL ES 3.0.2] Section 2.8 page 24: + // An INVALID_OPERATION error is generated when a non-zero vertex array object + // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point, + // and the pointer argument is not NULL. + bool nullBufferAllowed = context->getState().areClientArraysEnabled() && + context->getState().getVertexArray()->id().value == 0; + if (!nullBufferAllowed && context->getState().getTargetBuffer(BufferBinding::Array) == 0 && + ptr != nullptr) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, err::kClientDataInVertexArray); + return false; + } + + if (context->isWebGL()) + { + // WebGL 1.0 [Section 6.14] Fixed point support + // The WebGL API does not support the GL_FIXED data type. + if (type == VertexAttribType::Fixed) + { + context->validationError(entryPoint, GL_INVALID_ENUM, err::kFixedNotInWebGL); + return false; + } + + if (!ValidateWebGLVertexAttribPointer(context, entryPoint, type, normalized, stride, ptr, + false)) + { + return false; + } + } + + return true; +} + +void RecordBindTextureTypeError(const Context *context, + angle::EntryPoint entryPoint, + TextureType target); + +ANGLE_INLINE bool ValidateBindTexture(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + TextureID texture) +{ + if (!context->getStateCache().isValidBindTextureType(target)) + { + RecordBindTextureTypeError(context, entryPoint, target); + return false; + } + + if (texture.value == 0) + { + return true; + } + + Texture *textureObject = context->getTexture(texture); + if (textureObject && textureObject->getType() != target) + { + context->validationErrorF( + entryPoint, GL_INVALID_OPERATION, err::kTextureTargetMismatchWithLabel, + static_cast(target), static_cast(textureObject->getType()), + textureObject->getLabel().c_str()); + return false; + } + + if (!context->getState().isBindGeneratesResourceEnabled() && + !context->isTextureGenerated(texture)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, err::kObjectNotGenerated); + return false; + } + + return true; +} + +// Validation of all Tex[Sub]Image2D parameters except TextureTarget. +bool ValidateES2TexImageParametersBase(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum internalformat, + bool isCompressed, + bool isSubImage, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + GLsizei imageSize, + const void *pixels); + +// Validation of TexStorage*2DEXT +bool ValidateES2TexStorageParametersBase(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height); + +} // namespace gl + +#endif // LIBANGLE_VALIDATION_ES2_H_ diff --git a/gfx/angle/checkout/src/libANGLE/validationES2_autogen.h b/gfx/angle/checkout/src/libANGLE/validationES2_autogen.h new file mode 100644 index 0000000000..335139fe70 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationES2_autogen.h @@ -0,0 +1,666 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// validationES2_autogen.h: +// Validation functions for the OpenGL ES 2.0 entry points. + +#ifndef LIBANGLE_VALIDATION_ES2_AUTOGEN_H_ +#define LIBANGLE_VALIDATION_ES2_AUTOGEN_H_ + +#include "common/PackedEnums.h" +#include "common/entry_points_enum_autogen.h" + +namespace gl +{ +class Context; + +bool ValidateActiveTexture(const Context *context, angle::EntryPoint entryPoint, GLenum texture); +bool ValidateAttachShader(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + ShaderProgramID shaderPacked); +bool ValidateBindAttribLocation(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLuint index, + const GLchar *name); +bool ValidateBindBuffer(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding targetPacked, + BufferID bufferPacked); +bool ValidateBindFramebuffer(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + FramebufferID framebufferPacked); +bool ValidateBindRenderbuffer(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + RenderbufferID renderbufferPacked); +bool ValidateBindTexture(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + TextureID texturePacked); +bool ValidateBlendColor(const Context *context, + angle::EntryPoint entryPoint, + GLfloat red, + GLfloat green, + GLfloat blue, + GLfloat alpha); +bool ValidateBlendEquation(const Context *context, angle::EntryPoint entryPoint, GLenum mode); +bool ValidateBlendEquationSeparate(const Context *context, + angle::EntryPoint entryPoint, + GLenum modeRGB, + GLenum modeAlpha); +bool ValidateBlendFunc(const Context *context, + angle::EntryPoint entryPoint, + GLenum sfactor, + GLenum dfactor); +bool ValidateBlendFuncSeparate(const Context *context, + angle::EntryPoint entryPoint, + GLenum sfactorRGB, + GLenum dfactorRGB, + GLenum sfactorAlpha, + GLenum dfactorAlpha); +bool ValidateBufferData(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding targetPacked, + GLsizeiptr size, + const void *data, + BufferUsage usagePacked); +bool ValidateBufferSubData(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding targetPacked, + GLintptr offset, + GLsizeiptr size, + const void *data); +bool ValidateCheckFramebufferStatus(const Context *context, + angle::EntryPoint entryPoint, + GLenum target); +bool ValidateClear(const Context *context, angle::EntryPoint entryPoint, GLbitfield mask); +bool ValidateClearColor(const Context *context, + angle::EntryPoint entryPoint, + GLfloat red, + GLfloat green, + GLfloat blue, + GLfloat alpha); +bool ValidateClearDepthf(const Context *context, angle::EntryPoint entryPoint, GLfloat d); +bool ValidateClearStencil(const Context *context, angle::EntryPoint entryPoint, GLint s); +bool ValidateColorMask(const Context *context, + angle::EntryPoint entryPoint, + GLboolean red, + GLboolean green, + GLboolean blue, + GLboolean alpha); +bool ValidateCompileShader(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID shaderPacked); +bool ValidateCompressedTexImage2D(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + const void *data); +bool ValidateCompressedTexSubImage2D(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + const void *data); +bool ValidateCopyTexImage2D(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLenum internalformat, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border); +bool ValidateCopyTexSubImage2D(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height); +bool ValidateCreateProgram(const Context *context, angle::EntryPoint entryPoint); +bool ValidateCreateShader(const Context *context, + angle::EntryPoint entryPoint, + ShaderType typePacked); +bool ValidateCullFace(const Context *context, + angle::EntryPoint entryPoint, + CullFaceMode modePacked); +bool ValidateDeleteBuffers(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const BufferID *buffersPacked); +bool ValidateDeleteFramebuffers(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const FramebufferID *framebuffersPacked); +bool ValidateDeleteProgram(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked); +bool ValidateDeleteRenderbuffers(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const RenderbufferID *renderbuffersPacked); +bool ValidateDeleteShader(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID shaderPacked); +bool ValidateDeleteTextures(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const TextureID *texturesPacked); +bool ValidateDepthFunc(const Context *context, angle::EntryPoint entryPoint, GLenum func); +bool ValidateDepthMask(const Context *context, angle::EntryPoint entryPoint, GLboolean flag); +bool ValidateDepthRangef(const Context *context, + angle::EntryPoint entryPoint, + GLfloat n, + GLfloat f); +bool ValidateDetachShader(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + ShaderProgramID shaderPacked); +bool ValidateDisable(const Context *context, angle::EntryPoint entryPoint, GLenum cap); +bool ValidateDisableVertexAttribArray(const Context *context, + angle::EntryPoint entryPoint, + GLuint index); +bool ValidateDrawArrays(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + GLint first, + GLsizei count); +bool ValidateDrawElements(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices); +bool ValidateEnable(const Context *context, angle::EntryPoint entryPoint, GLenum cap); +bool ValidateEnableVertexAttribArray(const Context *context, + angle::EntryPoint entryPoint, + GLuint index); +bool ValidateFinish(const Context *context, angle::EntryPoint entryPoint); +bool ValidateFlush(const Context *context, angle::EntryPoint entryPoint); +bool ValidateFramebufferRenderbuffer(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + GLenum renderbuffertarget, + RenderbufferID renderbufferPacked); +bool ValidateFramebufferTexture2D(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + TextureTarget textargetPacked, + TextureID texturePacked, + GLint level); +bool ValidateFrontFace(const Context *context, angle::EntryPoint entryPoint, GLenum mode); +bool ValidateGenBuffers(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const BufferID *buffersPacked); +bool ValidateGenFramebuffers(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const FramebufferID *framebuffersPacked); +bool ValidateGenRenderbuffers(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const RenderbufferID *renderbuffersPacked); +bool ValidateGenTextures(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const TextureID *texturesPacked); +bool ValidateGenerateMipmap(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked); +bool ValidateGetActiveAttrib(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLuint index, + GLsizei bufSize, + const GLsizei *length, + const GLint *size, + const GLenum *type, + const GLchar *name); +bool ValidateGetActiveUniform(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLuint index, + GLsizei bufSize, + const GLsizei *length, + const GLint *size, + const GLenum *type, + const GLchar *name); +bool ValidateGetAttachedShaders(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLsizei maxCount, + const GLsizei *count, + const ShaderProgramID *shadersPacked); +bool ValidateGetAttribLocation(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + const GLchar *name); +bool ValidateGetBooleanv(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + const GLboolean *data); +bool ValidateGetBufferParameteriv(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding targetPacked, + GLenum pname, + const GLint *params); +bool ValidateGetError(const Context *context, angle::EntryPoint entryPoint); +bool ValidateGetFloatv(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + const GLfloat *data); +bool ValidateGetFramebufferAttachmentParameteriv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + GLenum pname, + const GLint *params); +bool ValidateGetIntegerv(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + const GLint *data); +bool ValidateGetProgramInfoLog(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLsizei bufSize, + const GLsizei *length, + const GLchar *infoLog); +bool ValidateGetProgramiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLenum pname, + const GLint *params); +bool ValidateGetRenderbufferParameteriv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum pname, + const GLint *params); +bool ValidateGetShaderInfoLog(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID shaderPacked, + GLsizei bufSize, + const GLsizei *length, + const GLchar *infoLog); +bool ValidateGetShaderPrecisionFormat(const Context *context, + angle::EntryPoint entryPoint, + GLenum shadertype, + GLenum precisiontype, + const GLint *range, + const GLint *precision); +bool ValidateGetShaderSource(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID shaderPacked, + GLsizei bufSize, + const GLsizei *length, + const GLchar *source); +bool ValidateGetShaderiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID shaderPacked, + GLenum pname, + const GLint *params); +bool ValidateGetString(const Context *context, angle::EntryPoint entryPoint, GLenum name); +bool ValidateGetTexParameterfv(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + const GLfloat *params); +bool ValidateGetTexParameteriv(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + const GLint *params); +bool ValidateGetUniformLocation(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + const GLchar *name); +bool ValidateGetUniformfv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + const GLfloat *params); +bool ValidateGetUniformiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + const GLint *params); +bool ValidateGetVertexAttribPointerv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum pname, + void *const *pointer); +bool ValidateGetVertexAttribfv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum pname, + const GLfloat *params); +bool ValidateGetVertexAttribiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum pname, + const GLint *params); +bool ValidateHint(const Context *context, angle::EntryPoint entryPoint, GLenum target, GLenum mode); +bool ValidateIsBuffer(const Context *context, angle::EntryPoint entryPoint, BufferID bufferPacked); +bool ValidateIsEnabled(const Context *context, angle::EntryPoint entryPoint, GLenum cap); +bool ValidateIsFramebuffer(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebufferPacked); +bool ValidateIsProgram(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked); +bool ValidateIsRenderbuffer(const Context *context, + angle::EntryPoint entryPoint, + RenderbufferID renderbufferPacked); +bool ValidateIsShader(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID shaderPacked); +bool ValidateIsTexture(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked); +bool ValidateLineWidth(const Context *context, angle::EntryPoint entryPoint, GLfloat width); +bool ValidateLinkProgram(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked); +bool ValidatePixelStorei(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLint param); +bool ValidatePolygonOffset(const Context *context, + angle::EntryPoint entryPoint, + GLfloat factor, + GLfloat units); +bool ValidateReadPixels(const Context *context, + angle::EntryPoint entryPoint, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void *pixels); +bool ValidateReleaseShaderCompiler(const Context *context, angle::EntryPoint entryPoint); +bool ValidateRenderbufferStorage(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum internalformat, + GLsizei width, + GLsizei height); +bool ValidateSampleCoverage(const Context *context, + angle::EntryPoint entryPoint, + GLfloat value, + GLboolean invert); +bool ValidateScissor(const Context *context, + angle::EntryPoint entryPoint, + GLint x, + GLint y, + GLsizei width, + GLsizei height); +bool ValidateShaderBinary(const Context *context, + angle::EntryPoint entryPoint, + GLsizei count, + const ShaderProgramID *shadersPacked, + GLenum binaryFormat, + const void *binary, + GLsizei length); +bool ValidateShaderSource(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID shaderPacked, + GLsizei count, + const GLchar *const *string, + const GLint *length); +bool ValidateStencilFunc(const Context *context, + angle::EntryPoint entryPoint, + GLenum func, + GLint ref, + GLuint mask); +bool ValidateStencilFuncSeparate(const Context *context, + angle::EntryPoint entryPoint, + GLenum face, + GLenum func, + GLint ref, + GLuint mask); +bool ValidateStencilMask(const Context *context, angle::EntryPoint entryPoint, GLuint mask); +bool ValidateStencilMaskSeparate(const Context *context, + angle::EntryPoint entryPoint, + GLenum face, + GLuint mask); +bool ValidateStencilOp(const Context *context, + angle::EntryPoint entryPoint, + GLenum fail, + GLenum zfail, + GLenum zpass); +bool ValidateStencilOpSeparate(const Context *context, + angle::EntryPoint entryPoint, + GLenum face, + GLenum sfail, + GLenum dpfail, + GLenum dppass); +bool ValidateTexImage2D(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + const void *pixels); +bool ValidateTexParameterf(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + GLfloat param); +bool ValidateTexParameterfv(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + const GLfloat *params); +bool ValidateTexParameteri(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + GLint param); +bool ValidateTexParameteriv(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + const GLint *params); +bool ValidateTexSubImage2D(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void *pixels); +bool ValidateUniform1f(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLfloat v0); +bool ValidateUniform1fv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value); +bool ValidateUniform1i(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLint v0); +bool ValidateUniform1iv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + const GLint *value); +bool ValidateUniform2f(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLfloat v0, + GLfloat v1); +bool ValidateUniform2fv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value); +bool ValidateUniform2i(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLint v0, + GLint v1); +bool ValidateUniform2iv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + const GLint *value); +bool ValidateUniform3f(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLfloat v0, + GLfloat v1, + GLfloat v2); +bool ValidateUniform3fv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value); +bool ValidateUniform3i(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLint v0, + GLint v1, + GLint v2); +bool ValidateUniform3iv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + const GLint *value); +bool ValidateUniform4f(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLfloat v0, + GLfloat v1, + GLfloat v2, + GLfloat v3); +bool ValidateUniform4fv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value); +bool ValidateUniform4i(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLint v0, + GLint v1, + GLint v2, + GLint v3); +bool ValidateUniform4iv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + const GLint *value); +bool ValidateUniformMatrix2fv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateUniformMatrix3fv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateUniformMatrix4fv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateUseProgram(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked); +bool ValidateValidateProgram(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked); +bool ValidateVertexAttrib1f(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLfloat x); +bool ValidateVertexAttrib1fv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLfloat *v); +bool ValidateVertexAttrib2f(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLfloat x, + GLfloat y); +bool ValidateVertexAttrib2fv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLfloat *v); +bool ValidateVertexAttrib3f(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLfloat x, + GLfloat y, + GLfloat z); +bool ValidateVertexAttrib3fv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLfloat *v); +bool ValidateVertexAttrib4f(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLfloat x, + GLfloat y, + GLfloat z, + GLfloat w); +bool ValidateVertexAttrib4fv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLfloat *v); +bool ValidateVertexAttribPointer(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLint size, + VertexAttribType typePacked, + GLboolean normalized, + GLsizei stride, + const void *pointer); +bool ValidateViewport(const Context *context, + angle::EntryPoint entryPoint, + GLint x, + GLint y, + GLsizei width, + GLsizei height); +} // namespace gl + +#endif // LIBANGLE_VALIDATION_ES2_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/validationES3.cpp b/gfx/angle/checkout/src/libANGLE/validationES3.cpp new file mode 100644 index 0000000000..633cc02da9 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationES3.cpp @@ -0,0 +1,5311 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// validationES3.cpp: Validation functions for OpenGL ES 3.0 entry point parameters + +#include "libANGLE/validationES3_autogen.h" + +#include "anglebase/numerics/safe_conversions.h" +#include "common/mathutil.h" +#include "common/utilities.h" +#include "libANGLE/Context.h" +#include "libANGLE/ErrorStrings.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/PixelLocalStorage.h" +#include "libANGLE/Renderbuffer.h" +#include "libANGLE/Texture.h" +#include "libANGLE/VertexArray.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/validationES.h" + +using namespace angle; + +namespace gl +{ +using namespace err; + +namespace +{ +bool ValidateFramebufferTextureMultiviewBaseANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + TextureID texture, + GLint level, + GLsizei numViews) +{ + if (!(context->getExtensions().multiviewOVR || context->getExtensions().multiview2OVR)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kMultiviewNotAvailable); + return false; + } + + if (!ValidateFramebufferTextureBase(context, entryPoint, target, attachment, texture, level)) + { + return false; + } + + if (texture.value != 0 && numViews < 1) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kMultiviewViewsTooSmall); + return false; + } + + if (static_cast(numViews) > context->getCaps().maxViews) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kMultiviewViewsTooLarge); + return false; + } + + return true; +} + +bool ValidateFramebufferTextureMultiviewLevelAndFormat(const Context *context, + angle::EntryPoint entryPoint, + const Texture *texture, + GLint level) +{ + TextureType type = texture->getType(); + if (!ValidMipLevel(context, type, level)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel); + return false; + } + + const auto &format = texture->getFormat(NonCubeTextureTypeToTarget(type), level); + if (format.info->compressed) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kCompressedTexturesNotAttachable); + return false; + } + return true; +} + +bool ValidateUniformES3(const Context *context, + angle::EntryPoint entryPoint, + GLenum uniformType, + UniformLocation location, + GLint count) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + return ValidateUniform(context, entryPoint, uniformType, location, count); +} + +bool ValidateUniformMatrixES3(const Context *context, + angle::EntryPoint entryPoint, + GLenum valueType, + UniformLocation location, + GLsizei count, + GLboolean transpose) +{ + // Check for ES3 uniform entry points + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + return ValidateUniformMatrix(context, entryPoint, valueType, location, count, transpose); +} + +bool ValidateGenOrDeleteES3(const Context *context, angle::EntryPoint entryPoint, GLint n) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + return ValidateGenOrDelete(context, entryPoint, n); +} + +bool ValidateGenOrDeleteCountES3(const Context *context, angle::EntryPoint entryPoint, GLint count) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + if (count < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeCount); + return false; + } + return true; +} + +bool ValidateCopyTexture3DCommon(const Context *context, + angle::EntryPoint entryPoint, + const Texture *source, + GLint sourceLevel, + GLint srcInternalFormat, + const Texture *dest, + GLint destLevel, + GLint internalFormat, + TextureTarget destTarget) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + if (!context->getExtensions().copyTexture3dANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kANGLECopyTexture3DUnavailable); + return false; + } + + if (!ValidTexture3DTarget(context, source->getType())) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + + // Table 1.1 from the ANGLE_copy_texture_3d spec + switch (GetUnsizedFormat(srcInternalFormat)) + { + case GL_ALPHA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_RED: + case GL_RED_INTEGER: + case GL_RG: + case GL_RG_INTEGER: + case GL_RGB: + case GL_RGB_INTEGER: + case GL_RGBA: + case GL_RGBA_INTEGER: + case GL_DEPTH_COMPONENT: + case GL_DEPTH_STENCIL: + break; + default: + context->validationErrorF(entryPoint, GL_INVALID_OPERATION, kInvalidInternalFormat, + srcInternalFormat); + return false; + } + + if (!ValidTexture3DTarget(context, TextureTargetToType(destTarget))) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + + // Table 1.0 from the ANGLE_copy_texture_3d spec + switch (internalFormat) + { + case GL_RGB: + case GL_RGBA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_ALPHA: + case GL_R8: + case GL_R8_SNORM: + case GL_R16F: + case GL_R32F: + case GL_R8UI: + case GL_R8I: + case GL_R16UI: + case GL_R16I: + case GL_R32UI: + case GL_R32I: + case GL_RG: + case GL_RG8: + case GL_RG8_SNORM: + case GL_RG16F: + case GL_RG32F: + case GL_RG8UI: + case GL_RG8I: + case GL_RG16UI: + case GL_RG16I: + case GL_RG32UI: + case GL_RG32I: + case GL_RGB8: + case GL_RGBX8_ANGLE: + case GL_SRGB8: + case GL_RGB565: + case GL_RGB8_SNORM: + case GL_R11F_G11F_B10F: + case GL_RGB9_E5: + case GL_RGB16F: + case GL_RGB32F: + case GL_RGB8UI: + case GL_RGB8I: + case GL_RGB16UI: + case GL_RGB16I: + case GL_RGB32UI: + case GL_RGB32I: + case GL_RGBA8: + case GL_SRGB8_ALPHA8: + case GL_RGBA8_SNORM: + case GL_RGB5_A1: + case GL_RGBA4: + case GL_RGB10_A2: + case GL_RGBA16F: + case GL_RGBA32F: + case GL_RGBA8UI: + case GL_RGBA8I: + case GL_RGB10_A2UI: + case GL_RGBA16UI: + case GL_RGBA16I: + case GL_RGBA32I: + case GL_RGBA32UI: + break; + default: + context->validationErrorF(entryPoint, GL_INVALID_OPERATION, kInvalidInternalFormat, + internalFormat); + return false; + } + + return true; +} +} // anonymous namespace + +static bool ValidateTexImageFormatCombination(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum internalFormat, + GLenum format, + GLenum type) +{ + // Different validation if on desktop api + if (context->getClientType() == EGL_OPENGL_API) + { + // The type and format are valid if any supported internal format has that type and format + if (!ValidDesktopFormat(format)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat); + return false; + } + + if (!ValidDesktopType(type)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType); + return false; + } + } + else + { + // The type and format are valid if any supported internal format has that type and format. + // ANGLE_texture_external_yuv_sampling extension adds support for YUV formats + if (gl::IsYuvFormat(format)) + { + if (!context->getExtensions().yuvInternalFormatANGLE) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat); + return false; + } + } + else + { + if (!ValidES3Format(format)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat); + return false; + } + } + + if (!ValidES3Type(type) || (type == GL_HALF_FLOAT_OES && context->isWebGL())) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType); + return false; + } + } + + // For historical reasons, glTexImage2D and glTexImage3D pass in their internal format as a + // GLint instead of a GLenum. Therefor an invalid internal format gives a GL_INVALID_VALUE + // error instead of a GL_INVALID_ENUM error. As this validation function is only called in + // the validation codepaths for glTexImage2D/3D, we record a GL_INVALID_VALUE error. + if (!ValidES3InternalFormat(internalFormat)) + { + context->validationErrorF(entryPoint, GL_INVALID_VALUE, kInvalidInternalFormat, + internalFormat); + return false; + } + + // From the ES 3.0 spec section 3.8.3: + // Textures with a base internal format of DEPTH_COMPONENT or DEPTH_STENCIL are supported by + // texture image specification commands only if target is TEXTURE_2D, TEXTURE_2D_ARRAY, or + // TEXTURE_CUBE_MAP.Using these formats in conjunction with any other target will result in an + // INVALID_OPERATION error. + if (target == TextureType::_3D && (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, k3DDepthStencil); + return false; + } + + if (context->getClientType() == EGL_OPENGL_API) + { + // Check if this is a valid format combination to load texture data + if (!ValidDesktopFormatCombination(format, type, internalFormat)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormatCombination); + return false; + } + } + else + { + // Check if this is a valid format combination to load texture data + // ANGLE_texture_external_yuv_sampling extension adds support for YUV formats + if (gl::IsYuvFormat(format)) + { + if (type != GL_UNSIGNED_BYTE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInvalidFormatCombination); + return false; + } + } + else + { + if (!ValidES3FormatCombination(format, type, internalFormat)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInvalidFormatCombination); + return false; + } + } + } + + const InternalFormat &formatInfo = GetInternalFormatInfo(internalFormat, type); + if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions())) + { + context->validationErrorF(entryPoint, GL_INVALID_OPERATION, kInvalidInternalFormat, + internalFormat); + return false; + } + + return true; +} + +static bool ValidateES3CompressedFormatForTexture2DArray(const Context *context, + angle::EntryPoint entryPoint, + GLenum format) +{ + if (IsETC1Format(format) || IsPVRTC1Format(format)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInternalFormatRequiresTexture2D); + return false; + } + + return true; +} + +static bool ValidateES3CompressedFormatForTexture3D(const Context *context, + angle::EntryPoint entryPoint, + GLenum format) +{ + if (IsETC1Format(format) || IsPVRTC1Format(format)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInternalFormatRequiresTexture2D); + return false; + } + + if (IsETC2EACFormat(format)) + { + // ES 3.1, Section 8.7, page 169. + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInternalFormatRequiresTexture2DArray); + return false; + } + + if (IsASTC2DFormat(format) && !(context->getExtensions().textureCompressionAstcHdrKHR || + context->getExtensions().textureCompressionAstcSliced3dKHR)) + { + // GL_KHR_texture_compression_astc_hdr, TEXTURE_3D is not supported without HDR profile + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInternalFormatRequiresTexture2DArrayASTC); + return false; + } + + if (IsS3TCFormat(format)) + { + // GL_EXT_texture_compression_s3tc + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInternalFormatRequiresTexture2DArrayS3TC); + return false; + } + + if (IsRGTCFormat(format)) + { + // GL_EXT_texture_compression_rgtc + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInternalFormatRequiresTexture2DArrayRGTC); + return false; + } + + if (IsBPTCFormat(format) && (context->getLimitations().noCompressedTexture3D)) + { + // GL_EXT_texture_compression_bptc + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInternalFormatRequiresTexture2DArrayBPTC); + return false; + } + + return true; +} + +bool ValidateES3TexImageParametersBase(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum internalformat, + bool isCompressed, + bool isSubImage, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + GLsizei imageSize, + const void *pixels) +{ + TextureType texType = TextureTargetToType(target); + + if (gl::IsYuvFormat(format)) + { + // According to ANGLE_yuv_internal_format, the texture needs to be an immutable + // texture, texture target can only be TEXTURE_2D and there is no mipmap support + if (!context->getExtensions().yuvInternalFormatANGLE || !isSubImage) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat); + return false; + } + + if (target != TextureTarget::_2D) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + + if (level != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel); + return false; + } + } + + // Validate image size + if (!ValidImageSizeParameters(context, entryPoint, texType, level, width, height, depth, + isSubImage)) + { + // Error already processed. + return false; + } + + // Verify zero border + if (border != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidBorder); + return false; + } + + if (xoffset < 0 || yoffset < 0 || zoffset < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset); + return false; + } + + if (std::numeric_limits::max() - xoffset < width || + std::numeric_limits::max() - yoffset < height || + std::numeric_limits::max() - zoffset < depth) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kOffsetOverflow); + return false; + } + + const Caps &caps = context->getCaps(); + + switch (texType) + { + case TextureType::_2D: + case TextureType::External: + case TextureType::VideoImage: + if (width > (caps.max2DTextureSize >> level) || + height > (caps.max2DTextureSize >> level)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize); + return false; + } + break; + + case TextureType::Rectangle: + ASSERT(level == 0); + if (width > caps.maxRectangleTextureSize || height > caps.maxRectangleTextureSize) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize); + return false; + } + if (isCompressed) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kRectangleTextureCompressed); + return false; + } + break; + + case TextureType::CubeMap: + if (!isSubImage && width != height) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kCubemapFacesEqualDimensions); + return false; + } + + if (width > (caps.maxCubeMapTextureSize >> level)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize); + return false; + } + break; + + case TextureType::_3D: + if (width > (caps.max3DTextureSize >> level) || + height > (caps.max3DTextureSize >> level) || + depth > (caps.max3DTextureSize >> level)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize); + return false; + } + break; + + case TextureType::_2DArray: + if (width > (caps.max2DTextureSize >> level) || + height > (caps.max2DTextureSize >> level) || depth > caps.maxArrayTextureLayers) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize); + return false; + } + break; + + case TextureType::CubeMapArray: + if (!isSubImage && width != height) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kCubemapFacesEqualDimensions); + return false; + } + + if (width > (caps.maxCubeMapTextureSize >> level)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize); + return false; + } + + if (width > (caps.max3DTextureSize >> level) || + height > (caps.max3DTextureSize >> level) || + depth > (caps.max3DTextureSize >> level)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize); + return false; + } + + if (!isSubImage && depth % 6 != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kCubemapInvalidDepth); + return false; + } + break; + + case TextureType::InvalidEnum: + context->validationError(entryPoint, GL_INVALID_ENUM, kEnumInvalid); + return false; + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, + ToGLenum(texType)); + return false; + } + + Texture *texture = context->getTextureByType(texType); + if (!texture) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kMissingTexture); + return false; + } + + if (texture->getImmutableFormat() && !isSubImage) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kTextureIsImmutable); + return false; + } + + // Validate texture formats + GLenum actualInternalFormat = + isSubImage ? texture->getFormat(target, level).info->internalFormat : internalformat; + if (isSubImage && actualInternalFormat == GL_NONE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidMipLevel); + return false; + } + + const InternalFormat &actualFormatInfo = isSubImage + ? *texture->getFormat(target, level).info + : GetInternalFormatInfo(internalformat, type); + if (isCompressed) + { + // compressedTexSubImage does not generate GL_INVALID_ENUM when format is unknown or invalid + if (!isSubImage) + { + if (!actualFormatInfo.compressed && !actualFormatInfo.paletted) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kCompressedMismatch); + return false; + } + + if (!actualFormatInfo.textureSupport(context->getClientVersion(), + context->getExtensions())) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat); + return false; + } + } + + if (texType == TextureType::_2DArray) + { + GLenum compressedDataFormat = isSubImage ? format : internalformat; + if (!ValidateES3CompressedFormatForTexture2DArray(context, entryPoint, + compressedDataFormat)) + { + // Error already generated. + return false; + } + } + + if (texType == TextureType::_3D) + { + GLenum compressedDataFormat = isSubImage ? format : internalformat; + if (!ValidateES3CompressedFormatForTexture3D(context, entryPoint, compressedDataFormat)) + { + // Error already generated. + return false; + } + } + + if (isSubImage) + { + if (!ValidCompressedSubImageSize( + context, actualFormatInfo.internalFormat, xoffset, yoffset, zoffset, width, + height, depth, texture->getWidth(target, level), + texture->getHeight(target, level), texture->getDepth(target, level))) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInvalidCompressedImageSize); + return false; + } + + if (format != actualInternalFormat) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kMismatchedFormat); + return false; + } + + // GL_EXT_compressed_ETC1_RGB8_sub_texture allows this format + if (IsETC1Format(actualInternalFormat) && + !context->getExtensions().compressedETC1RGB8SubTextureEXT) + { + context->validationErrorF(entryPoint, GL_INVALID_OPERATION, kInvalidInternalFormat, + internalformat); + return false; + } + } + else + { + if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height, + depth)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInvalidCompressedImageSize); + return false; + } + } + + // Disallow 3D-only compressed formats from being set on 2D textures + if (actualFormatInfo.compressedBlockDepth > 1 && texType != TextureType::_2DArray) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureTarget); + return false; + } + } + else + { + // Compressed formats are not valid internal formats for glTexImage*D + if (!isSubImage) + { + const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(internalformat); + if (internalFormatInfo.compressed) + { + context->validationErrorF(entryPoint, GL_INVALID_VALUE, kInvalidInternalFormat, + internalformat); + return false; + } + } + + if (!ValidateTexImageFormatCombination(context, entryPoint, texType, actualInternalFormat, + format, type)) + { + return false; + } + } + + // Validate sub image parameters + if (isSubImage) + { + if (isCompressed != actualFormatInfo.compressed) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kCompressedMismatch); + return false; + } + + if (xoffset < 0 || yoffset < 0 || zoffset < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset); + return false; + } + + if (std::numeric_limits::max() - xoffset < width || + std::numeric_limits::max() - yoffset < height || + std::numeric_limits::max() - zoffset < depth) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kOffsetOverflow); + return false; + } + + if (static_cast(xoffset + width) > texture->getWidth(target, level) || + static_cast(yoffset + height) > texture->getHeight(target, level) || + static_cast(zoffset + depth) > texture->getDepth(target, level)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kOffsetOverflow); + return false; + } + + if (width > 0 && height > 0 && depth > 0 && pixels == nullptr && + context->getState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kPixelDataNull); + return false; + } + } + + GLenum sizeCheckFormat = isSubImage ? format : internalformat; + if (!ValidImageDataSize(context, entryPoint, texType, width, height, depth, sizeCheckFormat, + type, pixels, imageSize)) + { + return false; + } + + // Check for pixel unpack buffer related API errors + Buffer *pixelUnpackBuffer = context->getState().getTargetBuffer(BufferBinding::PixelUnpack); + if (pixelUnpackBuffer != nullptr) + { + // ...data is not evenly divisible into the number of bytes needed to store in memory a + // datum + // indicated by type. + if (!isCompressed) + { + size_t offset = reinterpret_cast(pixels); + size_t dataBytesPerPixel = static_cast(GetTypeInfo(type).bytes); + + if ((offset % dataBytesPerPixel) != 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kDataTypeNotAligned); + return false; + } + } + + // ...the buffer object's data store is currently mapped but not persistently. + if (pixelUnpackBuffer->isMapped() && !pixelUnpackBuffer->isPersistentlyMapped()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferMapped); + return false; + } + } + + if (context->getExtensions().webglCompatibilityANGLE) + { + // Define: + // DataStoreWidth = (GL_UNPACK_ROW_LENGTH ? GL_UNPACK_ROW_LENGTH : width) + // DataStoreHeight = (GL_UNPACK_IMAGE_HEIGHT ? GL_UNPACK_IMAGE_HEIGHT : height) + // + // WebGL 2.0 imposes the following additional constraints: + // + // 1) texImage2D and texSubImage2D generate INVALID_OPERATION if: + // GL_UNPACK_SKIP_PIXELS + width > DataStoreWidth + // except for texImage2D if no GL_PIXEL_UNPACK_BUFFER is + // bound and _pixels_ is null. + // + // 2) texImage3D and texSubImage3D generate INVALID_OPERATION if: + // GL_UNPACK_SKIP_PIXELS + width > DataStoreWidth + // GL_UNPACK_SKIP_ROWS + height > DataStoreHeight + // except for texImage3D if no GL_PIXEL_UNPACK_BUFFER is + // bound and _pixels_ is null. + if (!pixelUnpackBuffer && !pixels && !isSubImage) + { + // Exception case for texImage2D or texImage3D, above. + } + else + { + const auto &unpack = context->getState().getUnpackState(); + GLint dataStoreWidth = unpack.rowLength ? unpack.rowLength : width; + if (unpack.skipPixels + width > dataStoreWidth) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInvalidUnpackParametersForWebGL); + return false; + } + if (target == TextureTarget::_3D || target == TextureTarget::_2DArray) + { + GLint dataStoreHeight = unpack.imageHeight ? unpack.imageHeight : height; + if (unpack.skipRows + height > dataStoreHeight) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInvalidUnpackParametersForWebGL); + return false; + } + } + } + } + + return true; +} + +bool ValidateES3TexImage2DParameters(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum internalformat, + bool isCompressed, + bool isSubImage, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + GLsizei imageSize, + const void *pixels) +{ + if (!ValidTexture2DDestinationTarget(context, target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + + return ValidateES3TexImageParametersBase( + context, entryPoint, target, level, internalformat, isCompressed, isSubImage, xoffset, + yoffset, zoffset, width, height, depth, border, format, type, imageSize, pixels); +} + +bool ValidateES3TexImage3DParameters(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum internalformat, + bool isCompressed, + bool isSubImage, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels) +{ + if (!ValidTexture3DDestinationTarget(context, target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + + return ValidateES3TexImageParametersBase( + context, entryPoint, target, level, internalformat, isCompressed, isSubImage, xoffset, + yoffset, zoffset, width, height, depth, border, format, type, bufSize, pixels); +} + +struct EffectiveInternalFormatInfo +{ + GLenum effectiveFormat; + GLenum destFormat; + GLuint minRedBits; + GLuint maxRedBits; + GLuint minGreenBits; + GLuint maxGreenBits; + GLuint minBlueBits; + GLuint maxBlueBits; + GLuint minAlphaBits; + GLuint maxAlphaBits; +}; + +static bool QueryEffectiveFormatList(const InternalFormat &srcFormat, + GLenum targetFormat, + const EffectiveInternalFormatInfo *list, + size_t size, + GLenum *outEffectiveFormat) +{ + for (size_t curFormat = 0; curFormat < size; ++curFormat) + { + const EffectiveInternalFormatInfo &formatInfo = list[curFormat]; + if ((formatInfo.destFormat == targetFormat) && + (formatInfo.minRedBits <= srcFormat.redBits && + formatInfo.maxRedBits >= srcFormat.redBits) && + (formatInfo.minGreenBits <= srcFormat.greenBits && + formatInfo.maxGreenBits >= srcFormat.greenBits) && + (formatInfo.minBlueBits <= srcFormat.blueBits && + formatInfo.maxBlueBits >= srcFormat.blueBits) && + (formatInfo.minAlphaBits <= srcFormat.alphaBits && + formatInfo.maxAlphaBits >= srcFormat.alphaBits)) + { + *outEffectiveFormat = formatInfo.effectiveFormat; + return true; + } + } + + *outEffectiveFormat = GL_NONE; + return false; +} + +bool GetSizedEffectiveInternalFormatInfo(const InternalFormat &srcFormat, + GLenum *outEffectiveFormat) +{ + // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141: + // Effective internal format coresponding to destination internal format and linear source + // buffer component sizes. + // | Source channel min/max sizes | + // Effective Internal Format | N/A | R | G | B | A | + // clang-format off + constexpr EffectiveInternalFormatInfo list[] = { + { GL_ALPHA8_EXT, GL_NONE, 0, 0, 0, 0, 0, 0, 1, 8 }, + { GL_R8, GL_NONE, 1, 8, 0, 0, 0, 0, 0, 0 }, + { GL_RG8, GL_NONE, 1, 8, 1, 8, 0, 0, 0, 0 }, + { GL_RGB565, GL_NONE, 1, 5, 1, 6, 1, 5, 0, 0 }, + { GL_RGB8, GL_NONE, 6, 8, 7, 8, 6, 8, 0, 0 }, + { GL_RGBA4, GL_NONE, 1, 4, 1, 4, 1, 4, 1, 4 }, + { GL_RGB5_A1, GL_NONE, 5, 5, 5, 5, 5, 5, 1, 1 }, + { GL_RGBA8, GL_NONE, 5, 8, 5, 8, 5, 8, 2, 8 }, + { GL_RGB10_A2, GL_NONE, 9, 10, 9, 10, 9, 10, 2, 2 }, + }; + // clang-format on + + return QueryEffectiveFormatList(srcFormat, GL_NONE, list, ArraySize(list), outEffectiveFormat); +} + +bool GetUnsizedEffectiveInternalFormatInfo(const InternalFormat &srcFormat, + const InternalFormat &destFormat, + GLenum *outEffectiveFormat) +{ + constexpr GLuint umax = UINT_MAX; + + // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141: + // Effective internal format coresponding to destination internal format andlinear source buffer + // component sizes. + // | Source channel min/max sizes | + // Effective Internal Format | Dest Format | R | G | B | A | + // clang-format off + constexpr EffectiveInternalFormatInfo list[] = { + { GL_ALPHA8_EXT, GL_ALPHA, 0, umax, 0, umax, 0, umax, 1, 8 }, + { GL_LUMINANCE8_EXT, GL_LUMINANCE, 1, 8, 0, umax, 0, umax, 0, umax }, + { GL_LUMINANCE8_ALPHA8_EXT, GL_LUMINANCE_ALPHA, 1, 8, 0, umax, 0, umax, 1, 8 }, + { GL_RGB565, GL_RGB, 1, 5, 1, 6, 1, 5, 0, umax }, + { GL_RGB8, GL_RGB, 6, 8, 7, 8, 6, 8, 0, umax }, + { GL_RGBA4, GL_RGBA, 1, 4, 1, 4, 1, 4, 1, 4 }, + { GL_RGB5_A1, GL_RGBA, 5, 5, 5, 5, 5, 5, 1, 1 }, + { GL_RGBA8, GL_RGBA, 5, 8, 5, 8, 5, 8, 5, 8 }, + }; + // clang-format on + + return QueryEffectiveFormatList(srcFormat, destFormat.format, list, ArraySize(list), + outEffectiveFormat); +} + +static bool GetEffectiveInternalFormat(const InternalFormat &srcFormat, + const InternalFormat &destFormat, + GLenum *outEffectiveFormat) +{ + if (destFormat.sized) + { + return GetSizedEffectiveInternalFormatInfo(srcFormat, outEffectiveFormat); + } + else + { + return GetUnsizedEffectiveInternalFormatInfo(srcFormat, destFormat, outEffectiveFormat); + } +} + +static bool EqualOrFirstZero(GLuint first, GLuint second) +{ + return first == 0 || first == second; +} + +static bool IsValidES3CopyTexImageCombination(const InternalFormat &textureFormatInfo, + const InternalFormat &framebufferFormatInfo, + FramebufferID readBufferHandle) +{ + if (!ValidES3CopyConversion(textureFormatInfo.format, framebufferFormatInfo.format)) + { + return false; + } + + // Section 3.8.5 of the GLES 3.0.3 spec states that source and destination formats + // must both be signed, unsigned, or fixed point and both source and destinations + // must be either both SRGB or both not SRGB. EXT_color_buffer_float adds allowed + // conversion between fixed and floating point. + + if ((textureFormatInfo.colorEncoding == GL_SRGB) != + (framebufferFormatInfo.colorEncoding == GL_SRGB)) + { + return false; + } + + if (((textureFormatInfo.componentType == GL_INT) != + (framebufferFormatInfo.componentType == GL_INT)) || + ((textureFormatInfo.componentType == GL_UNSIGNED_INT) != + (framebufferFormatInfo.componentType == GL_UNSIGNED_INT))) + { + return false; + } + + if ((textureFormatInfo.componentType == GL_UNSIGNED_NORMALIZED || + textureFormatInfo.componentType == GL_SIGNED_NORMALIZED) && + !(framebufferFormatInfo.componentType == GL_UNSIGNED_NORMALIZED || + framebufferFormatInfo.componentType == GL_SIGNED_NORMALIZED)) + { + return false; + } + + // SNORM is not supported (e.g. is not in the tables of "effective internal format" that + // correspond to internal formats. + if (textureFormatInfo.componentType == GL_SIGNED_NORMALIZED) + { + return false; + } + + // Section 3.8.5 of the GLES 3.0.3 (and section 8.6 of the GLES 3.2) spec has a caveat, that + // the KHR dEQP tests enforce: + // + // Note that the above rules disallow matches where some components sizes are smaller and + // others are larger (such as RGB10_A2). + if (!textureFormatInfo.sized && (framebufferFormatInfo.internalFormat == GL_RGB10_A2)) + { + return false; + } + + // GLES specification 3.0.3, sec 3.8.5, pg 139-140: + // The effective internal format of the source buffer is determined with the following rules + // applied in order: + // * If the source buffer is a texture or renderbuffer that was created with a sized internal + // format then the effective internal format is the source buffer's sized internal format. + // * If the source buffer is a texture that was created with an unsized base internal format, + // then the effective internal format is the source image array's effective internal + // format, as specified by table 3.12, which is determined from the and + // that were used when the source image array was specified by TexImage*. + // * Otherwise the effective internal format is determined by the row in table 3.17 or 3.18 + // where Destination Internal Format matches internalformat and where the [source channel + // sizes] are consistent with the values of the source buffer's [channel sizes]. Table 3.17 + // is used if the FRAMEBUFFER_ATTACHMENT_ENCODING is LINEAR and table 3.18 is used if the + // FRAMEBUFFER_ATTACHMENT_ENCODING is SRGB. + const InternalFormat *sourceEffectiveFormat = nullptr; + if (readBufferHandle.value != 0) + { + // Not the default framebuffer, therefore the read buffer must be a user-created texture or + // renderbuffer + if (framebufferFormatInfo.sized) + { + sourceEffectiveFormat = &framebufferFormatInfo; + } + else + { + // Renderbuffers cannot be created with an unsized internal format, so this must be an + // unsized-format texture. We can use the same table we use when creating textures to + // get its effective sized format. + sourceEffectiveFormat = + &GetSizedInternalFormatInfo(framebufferFormatInfo.sizedInternalFormat); + } + } + else + { + // The effective internal format must be derived from the source framebuffer's channel + // sizes. This is done in GetEffectiveInternalFormat for linear buffers (table 3.17) + if (framebufferFormatInfo.colorEncoding == GL_LINEAR) + { + GLenum effectiveFormat; + if (GetEffectiveInternalFormat(framebufferFormatInfo, textureFormatInfo, + &effectiveFormat)) + { + sourceEffectiveFormat = &GetSizedInternalFormatInfo(effectiveFormat); + } + else + { + return false; + } + } + else if (framebufferFormatInfo.colorEncoding == GL_SRGB) + { + // SRGB buffers can only be copied to sized format destinations according to table 3.18 + if (textureFormatInfo.sized && + (framebufferFormatInfo.redBits >= 1 && framebufferFormatInfo.redBits <= 8) && + (framebufferFormatInfo.greenBits >= 1 && framebufferFormatInfo.greenBits <= 8) && + (framebufferFormatInfo.blueBits >= 1 && framebufferFormatInfo.blueBits <= 8) && + (framebufferFormatInfo.alphaBits >= 1 && framebufferFormatInfo.alphaBits <= 8)) + { + sourceEffectiveFormat = &GetSizedInternalFormatInfo(GL_SRGB8_ALPHA8); + } + else + { + return false; + } + } + else + { + UNREACHABLE(); + return false; + } + } + + if (textureFormatInfo.sized) + { + // Section 3.8.5 of the GLES 3.0.3 spec, pg 139, requires that, if the destination format is + // sized, component sizes of the source and destination formats must exactly match if the + // destination format exists. + if (!EqualOrFirstZero(textureFormatInfo.redBits, sourceEffectiveFormat->redBits) || + !EqualOrFirstZero(textureFormatInfo.greenBits, sourceEffectiveFormat->greenBits) || + !EqualOrFirstZero(textureFormatInfo.blueBits, sourceEffectiveFormat->blueBits) || + !EqualOrFirstZero(textureFormatInfo.alphaBits, sourceEffectiveFormat->alphaBits)) + { + return false; + } + } + + return true; // A conversion function exists, and no rule in the specification has precluded + // conversion between these formats. +} + +bool ValidateES3CopyTexImageParametersBase(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum internalformat, + bool isSubImage, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border) +{ + Format textureFormat = Format::Invalid(); + if (!ValidateCopyTexImageParametersBase(context, entryPoint, target, level, internalformat, + isSubImage, xoffset, yoffset, zoffset, x, y, width, + height, border, &textureFormat)) + { + return false; + } + ASSERT(textureFormat.valid() || !isSubImage); + + const auto &state = context->getState(); + Framebuffer *framebuffer = state.getReadFramebuffer(); + FramebufferID readFramebufferID = framebuffer->id(); + + if (!ValidateFramebufferComplete(context, entryPoint, framebuffer)) + { + return false; + } + + // needIntrinsic = true. Treat renderToTexture textures as single sample since they will be + // resolved before copying + if (!framebuffer->isDefault() && + !ValidateFramebufferNotMultisampled(context, entryPoint, framebuffer, true)) + { + return false; + } + + const FramebufferAttachment *source = framebuffer->getReadColorAttachment(); + + // According to ES 3.x spec, if the internalformat of the texture + // is RGB9_E5 and copy to such a texture, generate INVALID_OPERATION. + if (textureFormat.info->internalFormat == GL_RGB9_E5) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat); + return false; + } + + if (isSubImage) + { + if (!IsValidES3CopyTexImageCombination(*textureFormat.info, *source->getFormat().info, + readFramebufferID)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidCopyCombination); + return false; + } + } + else + { + // Use format/type from the source FBO. (Might not be perfect for all cases?) + const InternalFormat &framebufferFormat = *source->getFormat().info; + const InternalFormat ©Format = GetInternalFormatInfo(internalformat, GL_UNSIGNED_BYTE); + if (!IsValidES3CopyTexImageCombination(copyFormat, framebufferFormat, readFramebufferID)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidCopyCombination); + return false; + } + } + + // If width or height is zero, it is a no-op. Return false without setting an error. + return (width > 0 && height > 0); +} + +bool ValidateES3CopyTexImage2DParameters(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum internalformat, + bool isSubImage, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border) +{ + if (!ValidTexture2DDestinationTarget(context, target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + + return ValidateES3CopyTexImageParametersBase(context, entryPoint, target, level, internalformat, + isSubImage, xoffset, yoffset, zoffset, x, y, width, + height, border); +} + +bool ValidateES3CopyTexImage3DParameters(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum internalformat, + bool isSubImage, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border) +{ + if (!ValidTexture3DDestinationTarget(context, target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + + return ValidateES3CopyTexImageParametersBase(context, entryPoint, target, level, internalformat, + isSubImage, xoffset, yoffset, zoffset, x, y, width, + height, border); +} + +bool ValidateES3TexStorageParametersLevel(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLsizei levels, + GLsizei width, + GLsizei height, + GLsizei depth) +{ + GLsizei maxDim = std::max(width, height); + if (target != TextureType::_2DArray) + { + maxDim = std::max(maxDim, depth); + } + + if (levels > log2(maxDim) + 1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidMipLevels); + return false; + } + + return true; +} + +bool ValidateES3TexStorageParametersExtent(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLsizei levels, + GLsizei width, + GLsizei height, + GLsizei depth) +{ + const Caps &caps = context->getCaps(); + + switch (target) + { + case TextureType::_2D: + { + if (width > caps.max2DTextureSize || height > caps.max2DTextureSize) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize); + return false; + } + } + break; + + case TextureType::Rectangle: + { + if (levels != 1) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevels); + return false; + } + + if (width > caps.maxRectangleTextureSize || height > caps.maxRectangleTextureSize) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize); + return false; + } + } + break; + + case TextureType::CubeMap: + { + if (width != height) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kCubemapFacesEqualDimensions); + return false; + } + + if (width > caps.maxCubeMapTextureSize) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize); + return false; + } + } + break; + + case TextureType::_3D: + { + if (width > caps.max3DTextureSize || height > caps.max3DTextureSize || + depth > caps.max3DTextureSize) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize); + return false; + } + } + break; + + case TextureType::_2DArray: + { + if (width > caps.max2DTextureSize || height > caps.max2DTextureSize || + depth > caps.maxArrayTextureLayers) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize); + return false; + } + } + break; + + case TextureType::CubeMapArray: + { + if (width != height) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kCubemapFacesEqualDimensions); + return false; + } + + if (width > caps.maxCubeMapTextureSize) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize); + return false; + } + + if (width > caps.max3DTextureSize || height > caps.max3DTextureSize || + depth > caps.max3DTextureSize) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize); + return false; + } + + if (depth % 6 != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kCubemapInvalidDepth); + return false; + } + } + break; + + default: + UNREACHABLE(); + return false; + } + + return true; +} + +bool ValidateES3TexStorageParametersTexObject(const Context *context, + angle::EntryPoint entryPoint, + TextureType target) +{ + Texture *texture = context->getTextureByType(target); + if (!texture || texture->id().value == 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kMissingTexture); + return false; + } + + if (texture->getImmutableFormat()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kTextureIsImmutable); + return false; + } + + return true; +} + +bool ValidateES3TexStorageParametersFormat(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth) +{ + // From ANGLE_texture_external_yuv_sampling: + // Texture target can only be TEXTURE_2D, there is no mipmap support + if (gl::IsYuvFormat(internalformat)) + { + if (!context->getExtensions().yuvInternalFormatANGLE) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat); + return false; + } + + if (target != TextureType::_2D) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + + if (levels != 1) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel); + return false; + } + } + + const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat); + if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions())) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat); + return false; + } + + if (!formatInfo.sized) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat); + return false; + } + + if (formatInfo.compressed) + { + if (target == TextureType::Rectangle) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kRectangleTextureCompressed); + return false; + } + + if (target == TextureType::_2DArray) + { + if (!ValidateES3CompressedFormatForTexture2DArray(context, entryPoint, + formatInfo.internalFormat)) + { + // Error already generated. + return false; + } + } + + if (target == TextureType::_3D) + { + if (!ValidateES3CompressedFormatForTexture3D(context, entryPoint, + formatInfo.internalFormat)) + { + // Error already generated. + return false; + } + } + + if (!ValidCompressedImageSize(context, formatInfo.internalFormat, 0, width, height, depth)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidCompressedImageSize); + return false; + } + } + + return true; +} + +bool ValidateES3TexStorageParametersBase(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth) +{ + if (width < 1 || height < 1 || depth < 1 || levels < 1) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kTextureSizeTooSmall); + return false; + } + + if (!ValidateES3TexStorageParametersLevel(context, entryPoint, target, levels, width, height, + depth)) + { + // Error already generated. + return false; + } + + if (!ValidateES3TexStorageParametersExtent(context, entryPoint, target, levels, width, height, + depth)) + { + // Error already generated. + return false; + } + + if (!ValidateES3TexStorageParametersTexObject(context, entryPoint, target)) + { + // Error already generated. + return false; + } + + if (!ValidateES3TexStorageParametersFormat(context, entryPoint, target, levels, internalformat, + width, height, depth)) + { + // Error already generated. + return false; + } + + return true; +} + +bool ValidateES3TexStorage2DParameters(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth) +{ + if (!ValidTexture2DTarget(context, target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + + return ValidateES3TexStorageParametersBase(context, entryPoint, target, levels, internalformat, + width, height, depth); +} + +bool ValidateES3TexStorage3DParameters(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth) +{ + if (!ValidTexture3DTarget(context, target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + + return ValidateES3TexStorageParametersBase(context, entryPoint, target, levels, internalformat, + width, height, depth); +} + +bool ValidateBeginQuery(const Context *context, + angle::EntryPoint entryPoint, + QueryType target, + QueryID id) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + return ValidateBeginQueryBase(context, entryPoint, target, id); +} + +bool ValidateEndQuery(const Context *context, angle::EntryPoint entryPoint, QueryType target) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + return ValidateEndQueryBase(context, entryPoint, target); +} + +bool ValidateGetQueryiv(const Context *context, + angle::EntryPoint entryPoint, + QueryType target, + GLenum pname, + const GLint *params) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + return ValidateGetQueryivBase(context, entryPoint, target, pname, nullptr); +} + +bool ValidateGetQueryObjectuiv(const Context *context, + angle::EntryPoint entryPoint, + QueryID id, + GLenum pname, + const GLuint *params) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + return ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, nullptr); +} + +bool ValidateFramebufferTextureLayer(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + TextureID texture, + GLint level, + GLint layer) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + if (!ValidateFramebufferTextureBase(context, entryPoint, target, attachment, texture, level)) + { + return false; + } + + const Caps &caps = context->getCaps(); + if (texture.value != 0) + { + if (layer < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeLayer); + return false; + } + + Texture *tex = context->getTexture(texture); + ASSERT(tex); + + switch (tex->getType()) + { + case TextureType::_2DArray: + { + if (level > log2(caps.max2DTextureSize)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kFramebufferTextureInvalidMipLevel); + return false; + } + + if (layer >= caps.maxArrayTextureLayers) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kFramebufferTextureInvalidLayer); + return false; + } + } + break; + + case TextureType::_3D: + { + if (level > log2(caps.max3DTextureSize)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kFramebufferTextureInvalidMipLevel); + return false; + } + + if (layer >= caps.max3DTextureSize) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kFramebufferTextureInvalidLayer); + return false; + } + } + break; + + case TextureType::_2DMultisampleArray: + { + if (level != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kFramebufferTextureInvalidMipLevel); + return false; + } + + if (layer >= caps.maxArrayTextureLayers) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kFramebufferTextureInvalidLayer); + return false; + } + } + break; + + case TextureType::CubeMap: + { + if (level > log2(caps.maxCubeMapTextureSize)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kFramebufferTextureInvalidMipLevel); + return false; + } + + if (layer >= static_cast(kCubeFaceCount)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kFramebufferTextureInvalidLayer); + return false; + } + } + break; + + case TextureType::CubeMapArray: + { + if (level > log2(caps.maxCubeMapTextureSize)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kFramebufferTextureInvalidMipLevel); + return false; + } + + if (layer >= caps.maxArrayTextureLayers) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kFramebufferTextureInvalidLayer); + return false; + } + } + break; + + default: + context->validationError(entryPoint, GL_INVALID_OPERATION, + kFramebufferTextureLayerIncorrectTextureType); + return false; + } + + const auto &format = tex->getFormat(TextureTypeToTarget(tex->getType(), layer), level); + if (format.info->compressed) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kCompressedTexturesNotAttachable); + return false; + } + } + + return true; +} + +bool ValidateInvalidateFramebuffer(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLsizei numAttachments, + const GLenum *attachments) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + bool defaultFramebuffer = false; + + switch (target) + { + case GL_DRAW_FRAMEBUFFER: + case GL_FRAMEBUFFER: + defaultFramebuffer = context->getState().getDrawFramebuffer()->isDefault(); + break; + case GL_READ_FRAMEBUFFER: + defaultFramebuffer = context->getState().getReadFramebuffer()->isDefault(); + break; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFramebufferTarget); + return false; + } + + return ValidateDiscardFramebufferBase(context, entryPoint, target, numAttachments, attachments, + defaultFramebuffer); +} + +bool ValidateInvalidateSubFramebuffer(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLsizei numAttachments, + const GLenum *attachments, + GLint x, + GLint y, + GLsizei width, + GLsizei height) +{ + if (width < 0 || height < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeSize); + return false; + } + + return ValidateInvalidateFramebuffer(context, entryPoint, target, numAttachments, attachments); +} + +bool ValidateClearBuffer(const Context *context, angle::EntryPoint entryPoint) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + if (!ValidateFramebufferComplete(context, entryPoint, context->getState().getDrawFramebuffer())) + { + return false; + } + + return true; +} + +bool ValidateDrawRangeElements(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLuint start, + GLuint end, + GLsizei count, + DrawElementsType type, + const void *indices) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + if (end < start) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidElementRange); + return false; + } + + if (!ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 0)) + { + return false; + } + + // Skip range checks for no-op calls. + if (count <= 0) + { + return true; + } + + return true; +} + +bool ValidateGetUniformuiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + const GLuint *params) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + return ValidateGetUniformBase(context, entryPoint, program, location); +} + +bool ValidateReadBuffer(const Context *context, angle::EntryPoint entryPoint, GLenum src) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + const Framebuffer *readFBO = context->getState().getReadFramebuffer(); + + if (readFBO == nullptr) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kNoReadFramebuffer); + return false; + } + + if (src == GL_NONE) + { + return true; + } + + if (src != GL_BACK && (src < GL_COLOR_ATTACHMENT0 || src > GL_COLOR_ATTACHMENT31)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidReadBuffer); + return false; + } + + if (readFBO->isDefault()) + { + if (src != GL_BACK) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidDefaultReadBuffer); + return false; + } + } + else + { + GLuint drawBuffer = static_cast(src - GL_COLOR_ATTACHMENT0); + + if (drawBuffer >= static_cast(context->getCaps().maxColorAttachments)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExceedsMaxColorAttachments); + return false; + } + } + + return true; +} + +bool ValidateCompressedTexImage3D(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + const void *data) +{ + if ((context->getClientMajorVersion() < 3) && !context->getExtensions().texture3DOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + if (!ValidTextureTarget(context, TextureTargetToType(target))) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + + // Validate image size + if (!ValidImageSizeParameters(context, entryPoint, TextureTargetToType(target), level, width, + height, depth, false)) + { + // Error already generated. + return false; + } + + const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat); + if (!formatInfo.compressed) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidCompressedFormat); + return false; + } + + GLuint blockSize = 0; + if (!formatInfo.computeCompressedImageSize(Extents(width, height, depth), &blockSize)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kIntegerOverflow); + return false; + } + + if (imageSize < 0 || static_cast(imageSize) != blockSize) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidCompressedImageSize); + return false; + } + + // 3D texture target validation + if (target != TextureTarget::_3D && target != TextureTarget::_2DArray) + { + if (context->getClientVersion() < ES_3_2 || target != TextureTarget::CubeMapArray) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + } + + // validateES3TexImageFormat sets the error code if there is an error + if (!ValidateES3TexImage3DParameters(context, entryPoint, target, level, internalformat, true, + false, 0, 0, 0, width, height, depth, border, GL_NONE, + GL_NONE, -1, data)) + { + return false; + } + + return true; +} + +bool ValidateCompressedTexImage3DRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + GLsizei dataSize, + const void *data) +{ + if (!ValidateRobustCompressedTexImageBase(context, entryPoint, imageSize, dataSize)) + { + return false; + } + + return ValidateCompressedTexImage3D(context, entryPoint, target, level, internalformat, width, + height, depth, border, imageSize, data); +} + +bool ValidateBindVertexArray(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID array) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + return ValidateBindVertexArrayBase(context, entryPoint, array); +} + +bool ValidateIsVertexArray(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID array) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + return true; +} + +static bool ValidateBindBufferCommon(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding target, + GLuint index, + BufferID buffer, + GLintptr offset, + GLsizeiptr size) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + if (buffer.value != 0 && offset < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset); + return false; + } + + if (!context->getState().isBindGeneratesResourceEnabled() && + !context->isBufferGenerated(buffer)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kObjectNotGenerated); + return false; + } + + const Caps &caps = context->getCaps(); + switch (target) + { + case BufferBinding::TransformFeedback: + { + if (index >= static_cast(caps.maxTransformFeedbackSeparateAttributes)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kIndexExceedsTransformFeedbackBufferBindings); + return false; + } + if (buffer.value != 0 && ((offset % 4) != 0 || (size % 4) != 0)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kOffsetAndSizeAlignment); + return false; + } + + if (context->getState().isTransformFeedbackActive()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kTransformFeedbackTargetActive); + return false; + } + break; + } + case BufferBinding::Uniform: + { + if (index >= static_cast(caps.maxUniformBufferBindings)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kIndexExceedsMaxUniformBufferBindings); + return false; + } + + ASSERT(caps.uniformBufferOffsetAlignment); + if (buffer.value != 0 && (offset % caps.uniformBufferOffsetAlignment) != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kUniformBufferOffsetAlignment); + return false; + } + break; + } + case BufferBinding::AtomicCounter: + { + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kEnumRequiresGLES31); + return false; + } + if (index >= static_cast(caps.maxAtomicCounterBufferBindings)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kIndexExceedsMaxAtomicCounterBufferBindings); + return false; + } + if (buffer.value != 0 && (offset % 4) != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kOffsetAlignment); + return false; + } + break; + } + case BufferBinding::ShaderStorage: + { + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kEnumRequiresGLES31); + return false; + } + if (index >= static_cast(caps.maxShaderStorageBufferBindings)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kExceedsMaxShaderStorageBufferBindings); + return false; + } + ASSERT(caps.shaderStorageBufferOffsetAlignment); + if (buffer.value != 0 && (offset % caps.shaderStorageBufferOffsetAlignment) != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kShaderStorageBufferOffsetAlignment); + return false; + } + break; + } + case BufferBinding::Texture: + { + if (!context->getExtensions().textureBufferAny()) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kTextureBufferExtensionNotAvailable); + return false; + } + if (index != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kIndexExceedsMaxUniformBufferBindings); + return false; + } + if (buffer.value != 0 && (offset % caps.textureBufferOffsetAlignment) != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kTextureBufferOffsetAlignment); + return false; + } + break; + } + case BufferBinding::InvalidEnum: + context->validationError(entryPoint, GL_INVALID_ENUM, kEnumInvalid); + return false; + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, + ToGLenum(target)); + return false; + } + + return true; +} + +bool ValidateBindBufferBase(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding target, + GLuint index, + BufferID buffer) +{ + return ValidateBindBufferCommon(context, entryPoint, target, index, buffer, 0, 0); +} + +bool ValidateBindBufferRange(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding target, + GLuint index, + BufferID buffer, + GLintptr offset, + GLsizeiptr size) +{ + if (buffer.value != 0 && size <= 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidBindBufferSize); + return false; + } + return ValidateBindBufferCommon(context, entryPoint, target, index, buffer, offset, size); +} + +bool ValidateProgramBinary(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLenum binaryFormat, + const void *binary, + GLsizei length) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + return ValidateProgramBinaryBase(context, entryPoint, program, binaryFormat, binary, length); +} + +bool ValidateGetProgramBinary(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLsizei bufSize, + const GLsizei *length, + const GLenum *binaryFormat, + const void *binary) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + return ValidateGetProgramBinaryBase(context, entryPoint, program, bufSize, length, binaryFormat, + binary); +} + +bool ValidateProgramParameteriBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLenum pname, + GLint value) +{ + if (GetValidProgram(context, entryPoint, program) == nullptr) + { + return false; + } + + switch (pname) + { + case GL_PROGRAM_BINARY_RETRIEVABLE_HINT: + if (value != GL_FALSE && value != GL_TRUE) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidBooleanValue); + return false; + } + break; + + case GL_PROGRAM_SEPARABLE: + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kES31Required); + return false; + } + + if (value != GL_FALSE && value != GL_TRUE) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidBooleanValue); + return false; + } + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname); + return false; + } + + return true; +} + +bool ValidateProgramParameteri(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLenum pname, + GLint value) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + return ValidateProgramParameteriBase(context, entryPoint, program, pname, value); +} + +bool ValidateBlitFramebuffer(const Context *context, + angle::EntryPoint entryPoint, + GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter) +{ + if (context->getClientMajorVersion() < 3 && !context->getExtensions().framebufferBlitNV) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + return ValidateBlitFramebufferParameters(context, entryPoint, srcX0, srcY0, srcX1, srcY1, dstX0, + dstY0, dstX1, dstY1, mask, filter); +} + +bool ValidateClearBufferiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum buffer, + GLint drawbuffer, + const GLint *value) +{ + switch (buffer) + { + case GL_COLOR: + if (drawbuffer < 0 || drawbuffer >= context->getCaps().maxDrawBuffers) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer); + return false; + } + if (context->getExtensions().webglCompatibilityANGLE) + { + constexpr GLenum validComponentTypes[] = {GL_INT}; + if (!ValidateWebGLFramebufferAttachmentClearType(context, entryPoint, drawbuffer, + validComponentTypes, + ArraySize(validComponentTypes))) + { + return false; + } + } + break; + + case GL_STENCIL: + if (drawbuffer != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kInvalidDepthStencilDrawBuffer); + return false; + } + break; + + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, buffer); + return false; + } + + return ValidateClearBuffer(context, entryPoint); +} + +bool ValidateClearBufferuiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum buffer, + GLint drawbuffer, + const GLuint *value) +{ + switch (buffer) + { + case GL_COLOR: + if (drawbuffer < 0 || drawbuffer >= context->getCaps().maxDrawBuffers) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer); + return false; + } + if (context->getExtensions().webglCompatibilityANGLE) + { + constexpr GLenum validComponentTypes[] = {GL_UNSIGNED_INT}; + if (!ValidateWebGLFramebufferAttachmentClearType(context, entryPoint, drawbuffer, + validComponentTypes, + ArraySize(validComponentTypes))) + { + return false; + } + } + break; + + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, buffer); + return false; + } + + return ValidateClearBuffer(context, entryPoint); +} + +bool ValidateClearBufferfv(const Context *context, + angle::EntryPoint entryPoint, + GLenum buffer, + GLint drawbuffer, + const GLfloat *value) +{ + switch (buffer) + { + case GL_COLOR: + if (drawbuffer < 0 || drawbuffer >= context->getCaps().maxDrawBuffers) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer); + return false; + } + if (context->getExtensions().webglCompatibilityANGLE) + { + constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED, + GL_SIGNED_NORMALIZED}; + if (!ValidateWebGLFramebufferAttachmentClearType(context, entryPoint, drawbuffer, + validComponentTypes, + ArraySize(validComponentTypes))) + { + return false; + } + } + break; + + case GL_DEPTH: + if (drawbuffer != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kInvalidDepthStencilDrawBuffer); + return false; + } + break; + + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, buffer); + return false; + } + + return ValidateClearBuffer(context, entryPoint); +} + +bool ValidateClearBufferfi(const Context *context, + angle::EntryPoint entryPoint, + GLenum buffer, + GLint drawbuffer, + GLfloat depth, + GLint stencil) +{ + switch (buffer) + { + case GL_DEPTH_STENCIL: + if (drawbuffer != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kInvalidDepthStencilDrawBuffer); + return false; + } + break; + + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, buffer); + return false; + } + + return ValidateClearBuffer(context, entryPoint); +} + +bool ValidateDrawBuffers(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const GLenum *bufs) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + return ValidateDrawBuffersBase(context, entryPoint, n, bufs); +} + +bool ValidateCopyTexSubImage3D(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) +{ + if ((context->getClientMajorVersion() < 3) && !context->getExtensions().texture3DOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + return ValidateES3CopyTexImage3DParameters(context, entryPoint, target, level, GL_NONE, true, + xoffset, yoffset, zoffset, x, y, width, height, 0); +} + +bool ValidateCopyTexture3DANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureID sourceId, + GLint sourceLevel, + TextureTarget destTarget, + TextureID destId, + GLint destLevel, + GLint internalFormat, + GLenum destType, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha) +{ + const Texture *source = context->getTexture(sourceId); + if (source == nullptr) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidSourceTexture); + return false; + } + + TextureType sourceType = source->getType(); + ASSERT(sourceType != TextureType::CubeMap); + TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType); + const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel); + + const Texture *dest = context->getTexture(destId); + if (dest == nullptr) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidDestinationTexture); + return false; + } + + if (!ValidateCopyTexture3DCommon(context, entryPoint, source, sourceLevel, + sourceFormat.info->internalFormat, dest, destLevel, + internalFormat, destTarget)) + { + return false; + } + + if (!ValidMipLevel(context, source->getType(), sourceLevel)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidSourceTextureLevel); + return false; + } + + GLsizei sourceWidth = static_cast(source->getWidth(sourceTarget, sourceLevel)); + GLsizei sourceHeight = static_cast(source->getHeight(sourceTarget, sourceLevel)); + if (sourceWidth == 0 || sourceHeight == 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidSourceTextureSize); + return false; + } + + if (dest->getImmutableFormat()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kDestinationImmutable); + return false; + } + + return true; +} + +bool ValidateCopySubTexture3DANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureID sourceId, + GLint sourceLevel, + TextureTarget destTarget, + TextureID destId, + GLint destLevel, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLint z, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha) +{ + const Texture *source = context->getTexture(sourceId); + if (source == nullptr) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidSourceTexture); + return false; + } + + TextureType sourceType = source->getType(); + ASSERT(sourceType != TextureType::CubeMap); + TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType); + const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel); + + const Texture *dest = context->getTexture(destId); + if (dest == nullptr) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidDestinationTexture); + return false; + } + + const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info; + + if (!ValidateCopyTexture3DCommon(context, entryPoint, source, sourceLevel, + sourceFormat.info->internalFormat, dest, destLevel, + destFormat.internalFormat, destTarget)) + { + return false; + } + + if (x < 0 || y < 0 || z < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeXYZ); + return false; + } + + if (width < 0 || height < 0 || depth < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeHeightWidthDepth); + return false; + } + + if (static_cast(x + width) > source->getWidth(sourceTarget, sourceLevel) || + static_cast(y + height) > source->getHeight(sourceTarget, sourceLevel) || + static_cast(z + depth) > source->getDepth(sourceTarget, sourceLevel)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kSourceTextureTooSmall); + return false; + } + + if (TextureTargetToType(destTarget) != dest->getType()) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidDestinationTextureType); + return false; + } + + if (xoffset < 0 || yoffset < 0 || zoffset < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset); + return false; + } + + if (static_cast(xoffset + width) > dest->getWidth(destTarget, destLevel) || + static_cast(yoffset + height) > dest->getHeight(destTarget, destLevel) || + static_cast(zoffset + depth) > dest->getDepth(destTarget, destLevel)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kDestinationTextureTooSmall); + return false; + } + + return true; +} + +bool ValidateTexImage3D(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const void *pixels) +{ + if ((context->getClientMajorVersion() < 3) && !context->getExtensions().texture3DOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateES3TexImage3DParameters(context, entryPoint, target, level, internalformat, + false, false, 0, 0, 0, width, height, depth, border, + format, type, -1, pixels); +} + +bool ValidateTexImage3DRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + return ValidateES3TexImage3DParameters(context, entryPoint, target, level, internalformat, + false, false, 0, 0, 0, width, height, depth, border, + format, type, bufSize, pixels); +} + +bool ValidateTexSubImage3D(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *pixels) +{ + if ((context->getClientMajorVersion() < 3) && !context->getExtensions().texture3DOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + return ValidateES3TexImage3DParameters(context, entryPoint, target, level, GL_NONE, false, true, + xoffset, yoffset, zoffset, width, height, depth, 0, + format, type, -1, pixels); +} + +bool ValidateTexSubImage3DRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + return ValidateES3TexImage3DParameters(context, entryPoint, target, level, GL_NONE, false, true, + xoffset, yoffset, zoffset, width, height, depth, 0, + format, type, bufSize, pixels); +} + +bool ValidateCompressedTexSubImage3D(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const void *data) +{ + if ((context->getClientMajorVersion() < 3) && !context->getExtensions().texture3DOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + if (!ValidateES3TexImage3DParameters(context, entryPoint, target, level, GL_NONE, true, true, + xoffset, yoffset, zoffset, width, height, depth, 0, format, + GL_NONE, -1, data)) + { + return false; + } + + const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format); + + if (!formatInfo.compressed) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidCompressedFormat); + return false; + } + + GLuint blockSize = 0; + if (!formatInfo.computeCompressedImageSize(Extents(width, height, depth), &blockSize)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kIntegerOverflow); + return false; + } + + if (imageSize < 0 || static_cast(imageSize) != blockSize) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidCompressedImageSize); + return false; + } + + if (data == nullptr) + { + if (context->getState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr) + { + // If data is null, we need an unpack buffer to read from + context->validationError(entryPoint, GL_INVALID_VALUE, kPixelDataNull); + return false; + } + + if (context->getTextureByTarget(target)->isCompressedFormatEmulated(context, target, level)) + { + // TODO (anglebug.com/7464): Can't populate from a buffer using emulated format + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidEmulatedFormat); + return false; + } + } + + return true; +} + +bool ValidateCompressedTexSubImage3DRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + GLsizei dataSize, + const void *data) +{ + if (!ValidateRobustCompressedTexImageBase(context, entryPoint, imageSize, dataSize)) + { + return false; + } + + return ValidateCompressedTexSubImage3D(context, entryPoint, target, level, xoffset, yoffset, + zoffset, width, height, depth, format, imageSize, data); +} + +bool ValidateGenQueries(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const QueryID *queries) +{ + return ValidateGenOrDeleteES3(context, entryPoint, n); +} + +bool ValidateDeleteQueries(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const QueryID *queries) +{ + return ValidateGenOrDeleteES3(context, entryPoint, n); +} + +bool ValidateGenSamplers(const Context *context, + angle::EntryPoint entryPoint, + GLsizei count, + const SamplerID *samplers) +{ + return ValidateGenOrDeleteCountES3(context, entryPoint, count); +} + +bool ValidateDeleteSamplers(const Context *context, + angle::EntryPoint entryPoint, + GLsizei count, + const SamplerID *samplers) +{ + return ValidateGenOrDeleteCountES3(context, entryPoint, count); +} + +bool ValidateGenTransformFeedbacks(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const TransformFeedbackID *ids) +{ + return ValidateGenOrDeleteES3(context, entryPoint, n); +} + +bool ValidateDeleteTransformFeedbacks(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const TransformFeedbackID *ids) +{ + if (!ValidateGenOrDeleteES3(context, entryPoint, n)) + { + return false; + } + for (GLint i = 0; i < n; ++i) + { + auto *transformFeedback = context->getTransformFeedback(ids[i]); + if (transformFeedback != nullptr && transformFeedback->isActive()) + { + // ES 3.0.4 section 2.15.1 page 86 + context->validationError(entryPoint, GL_INVALID_OPERATION, + kTransformFeedbackActiveDelete); + return false; + } + } + return true; +} + +bool ValidateGenVertexArrays(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const VertexArrayID *arrays) +{ + return ValidateGenOrDeleteES3(context, entryPoint, n); +} + +bool ValidateDeleteVertexArrays(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const VertexArrayID *arrays) +{ + return ValidateGenOrDeleteES3(context, entryPoint, n); +} + +bool ValidateBeginTransformFeedback(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode primitiveMode) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + switch (primitiveMode) + { + case PrimitiveMode::Triangles: + case PrimitiveMode::Lines: + case PrimitiveMode::Points: + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPrimitiveMode); + return false; + } + + TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback(); + ASSERT(transformFeedback != nullptr); + + if (transformFeedback->isActive()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kTransfomFeedbackAlreadyActive); + return false; + } + + for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++) + { + const OffsetBindingPointer &buffer = transformFeedback->getIndexedBuffer(i); + if (buffer.get()) + { + if (buffer->isMapped()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferMapped); + return false; + } + if ((context->getLimitations().noDoubleBoundTransformFeedbackBuffers || + context->getExtensions().webglCompatibilityANGLE) && + buffer->isDoubleBoundForTransformFeedback()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kTransformFeedbackBufferMultipleOutputs); + return false; + } + } + } + + const ProgramExecutable *programExecutable = + context->getState().getLinkedProgramExecutable(context); + if (!programExecutable) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotBound); + return false; + } + + if (programExecutable->getLinkedTransformFeedbackVaryings().empty()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kNoTransformFeedbackOutputVariables); + return false; + } + + if (!ValidateProgramExecutableXFBBuffersPresent(context, programExecutable)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kTransformFeedbackBufferMissing); + return false; + } + + return true; +} + +bool ValidateGetBufferPointerv(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding target, + GLenum pname, + void *const *params) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + return ValidateGetBufferPointervBase(context, entryPoint, target, pname, nullptr, params); +} + +bool ValidateGetBufferPointervRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding target, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + void *const *params) +{ + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + GLsizei numParams = 0; + + if (context->getClientMajorVersion() < 3 && !context->getExtensions().mapbufferOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (!ValidateGetBufferPointervBase(context, entryPoint, target, pname, &numParams, params)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams)) + { + return false; + } + + SetRobustLengthParam(length, numParams); + + return true; +} + +bool ValidateUnmapBuffer(const Context *context, angle::EntryPoint entryPoint, BufferBinding target) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + return ValidateUnmapBufferBase(context, entryPoint, target); +} + +bool ValidateMapBufferRange(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding target, + GLintptr offset, + GLsizeiptr length, + GLbitfield access) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + return ValidateMapBufferRangeBase(context, entryPoint, target, offset, length, access); +} + +bool ValidateFlushMappedBufferRange(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding target, + GLintptr offset, + GLsizeiptr length) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + return ValidateFlushMappedBufferRangeBase(context, entryPoint, target, offset, length); +} + +bool ValidateIndexedStateQuery(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLuint index, + GLsizei *length) +{ + if (length) + { + *length = 0; + } + + GLenum nativeType; + unsigned int numParams; + if (!context->getIndexedQueryParameterInfo(pname, &nativeType, &numParams)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname); + return false; + } + + const Caps &caps = context->getCaps(); + switch (pname) + { + case GL_BLEND_SRC_RGB: + case GL_BLEND_SRC_ALPHA: + case GL_BLEND_DST_RGB: + case GL_BLEND_DST_ALPHA: + case GL_BLEND_EQUATION_RGB: + case GL_BLEND_EQUATION_ALPHA: + case GL_COLOR_WRITEMASK: + if (!context->getExtensions().drawBuffersIndexedAny()) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kDrawBuffersIndexedExtensionNotAvailable); + return false; + } + if (index >= static_cast(caps.maxDrawBuffers)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer); + return false; + } + break; + case GL_TRANSFORM_FEEDBACK_BUFFER_START: + case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: + case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: + if (index >= static_cast(caps.maxTransformFeedbackSeparateAttributes)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kIndexExceedsMaxTransformFeedbackAttribs); + return false; + } + break; + + case GL_UNIFORM_BUFFER_START: + case GL_UNIFORM_BUFFER_SIZE: + case GL_UNIFORM_BUFFER_BINDING: + if (index >= static_cast(caps.maxUniformBufferBindings)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kIndexExceedsMaxUniformBufferBindings); + return false; + } + break; + + case GL_MAX_COMPUTE_WORK_GROUP_SIZE: + case GL_MAX_COMPUTE_WORK_GROUP_COUNT: + if (index >= 3u) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kIndexExceedsMaxWorkgroupDimensions); + return false; + } + break; + + case GL_ATOMIC_COUNTER_BUFFER_START: + case GL_ATOMIC_COUNTER_BUFFER_SIZE: + case GL_ATOMIC_COUNTER_BUFFER_BINDING: + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kEnumRequiresGLES31); + return false; + } + if (index >= static_cast(caps.maxAtomicCounterBufferBindings)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kIndexExceedsMaxAtomicCounterBufferBindings); + return false; + } + break; + + case GL_SHADER_STORAGE_BUFFER_START: + case GL_SHADER_STORAGE_BUFFER_SIZE: + case GL_SHADER_STORAGE_BUFFER_BINDING: + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kEnumRequiresGLES31); + return false; + } + if (index >= static_cast(caps.maxShaderStorageBufferBindings)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kExceedsMaxShaderStorageBufferBindings); + return false; + } + break; + + case GL_VERTEX_BINDING_BUFFER: + case GL_VERTEX_BINDING_DIVISOR: + case GL_VERTEX_BINDING_OFFSET: + case GL_VERTEX_BINDING_STRIDE: + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kEnumRequiresGLES31); + return false; + } + if (index >= static_cast(caps.maxVertexAttribBindings)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kExceedsMaxVertexAttribBindings); + return false; + } + break; + case GL_SAMPLE_MASK_VALUE: + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kEnumRequiresGLES31); + return false; + } + if (index >= static_cast(caps.maxSampleMaskWords)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidSampleMaskNumber); + return false; + } + break; + case GL_IMAGE_BINDING_NAME: + case GL_IMAGE_BINDING_LEVEL: + case GL_IMAGE_BINDING_LAYERED: + case GL_IMAGE_BINDING_LAYER: + case GL_IMAGE_BINDING_ACCESS: + case GL_IMAGE_BINDING_FORMAT: + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kEnumRequiresGLES31); + return false; + } + if (index >= static_cast(caps.maxImageUnits)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxImageUnits); + return false; + } + break; + // GL_ANGLE_shader_pixel_local_storage + case GL_PIXEL_LOCAL_FORMAT_ANGLE: + case GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE: + case GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE: + case GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE: + { + // Check that the pixel local storage extension is enabled at all. + if (!context->getExtensions().shaderPixelLocalStorageANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kPLSExtensionNotEnabled); + return false; + } + // INVALID_FRAMEBUFFER_OPERATION is generated if the default framebuffer object name 0 + // is bound to DRAW_FRAMEBUFFER. + Framebuffer *framebuffer = context->getState().getDrawFramebuffer(); + if (framebuffer->id().value == 0) + { + context->validationError(entryPoint, GL_INVALID_FRAMEBUFFER_OPERATION, + kPLSDefaultFramebufferBound); + return false; + } + // INVALID_VALUE is generated if >= MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE. + if (index >= context->getCaps().maxPixelLocalStoragePlanes) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kPLSPlaneOutOfRange); + return false; + } + break; + } + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + + if (length) + { + if (pname == GL_COLOR_WRITEMASK) + { + *length = 4; + } + else + { + *length = 1; + } + } + + return true; +} + +bool ValidateGetIntegeri_v(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index, + const GLint *data) +{ + if (context->getClientVersion() < ES_3_0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + return ValidateIndexedStateQuery(context, entryPoint, target, index, nullptr); +} + +bool ValidateGetIntegeri_vRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index, + GLsizei bufSize, + const GLsizei *length, + const GLint *data) +{ + if (context->getClientVersion() < ES_3_0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + GLsizei numParams = 0; + + if (!ValidateIndexedStateQuery(context, entryPoint, target, index, &numParams)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams)) + { + return false; + } + + SetRobustLengthParam(length, numParams); + + return true; +} + +bool ValidateGetInteger64i_v(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index, + const GLint64 *data) +{ + if (context->getClientVersion() < ES_3_0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + return ValidateIndexedStateQuery(context, entryPoint, target, index, nullptr); +} + +bool ValidateGetInteger64i_vRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index, + GLsizei bufSize, + const GLsizei *length, + const GLint64 *data) +{ + if (context->getClientVersion() < ES_3_0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + GLsizei numParams = 0; + + if (!ValidateIndexedStateQuery(context, entryPoint, target, index, &numParams)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams)) + { + return false; + } + + SetRobustLengthParam(length, numParams); + + return true; +} + +bool ValidateCopyBufferSubData(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding readTarget, + BufferBinding writeTarget, + GLintptr readOffset, + GLintptr writeOffset, + GLsizeiptr size) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + if (!context->isValidBufferBinding(readTarget) || !context->isValidBufferBinding(writeTarget)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBufferTypes); + return false; + } + + Buffer *readBuffer = context->getState().getTargetBuffer(readTarget); + Buffer *writeBuffer = context->getState().getTargetBuffer(writeTarget); + + if (!readBuffer || !writeBuffer) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferNotBound); + return false; + } + + // EXT_buffer_storage allows persistently mapped buffers to be updated via glCopyBufferSubData + bool isReadPersistent = (readBuffer->getAccessFlags() & GL_MAP_PERSISTENT_BIT_EXT) != 0; + bool isWritePersistent = (writeBuffer->getAccessFlags() & GL_MAP_PERSISTENT_BIT_EXT) != 0; + + // Verify that readBuffer and writeBuffer are not currently mapped unless persistent + if ((readBuffer->isMapped() && !isReadPersistent) || + (writeBuffer->isMapped() && !isWritePersistent)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferMapped); + return false; + } + + if (readBuffer->hasWebGLXFBBindingConflict(context->isWebGL()) || + writeBuffer->hasWebGLXFBBindingConflict(context->isWebGL())) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kBufferBoundForTransformFeedback); + return false; + } + + CheckedNumeric checkedReadOffset(readOffset); + CheckedNumeric checkedWriteOffset(writeOffset); + CheckedNumeric checkedSize(size); + + auto checkedReadSum = checkedReadOffset + checkedSize; + auto checkedWriteSum = checkedWriteOffset + checkedSize; + + if (!checkedReadSum.IsValid() || !checkedWriteSum.IsValid() || + !IsValueInRangeForNumericType(readBuffer->getSize()) || + !IsValueInRangeForNumericType(writeBuffer->getSize())) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kIntegerOverflow); + return false; + } + + if (readOffset < 0 || writeOffset < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset); + return false; + } + + if (size < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeSize); + return false; + } + + if (checkedReadSum.ValueOrDie() > readBuffer->getSize() || + checkedWriteSum.ValueOrDie() > writeBuffer->getSize()) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kBufferOffsetOverflow); + return false; + } + + if (readBuffer == writeBuffer) + { + auto checkedOffsetDiff = (checkedReadOffset - checkedWriteOffset).Abs(); + if (!checkedOffsetDiff.IsValid()) + { + // This shold not be possible. + UNREACHABLE(); + context->validationError(entryPoint, GL_INVALID_VALUE, kIntegerOverflow); + return false; + } + + if (checkedOffsetDiff.ValueOrDie() < size) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kCopyAlias); + return false; + } + } + + return true; +} + +bool ValidateGetStringi(const Context *context, + angle::EntryPoint entryPoint, + GLenum name, + GLuint index) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + switch (name) + { + case GL_EXTENSIONS: + if (index >= context->getExtensionStringCount()) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsNumExtensions); + return false; + } + break; + + case GL_REQUESTABLE_EXTENSIONS_ANGLE: + if (!context->getExtensions().requestExtensionANGLE) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidName); + return false; + } + if (index >= context->getRequestableExtensionStringCount()) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kExceedsNumRequestableExtensions); + return false; + } + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidName); + return false; + } + + return true; +} + +bool ValidateRenderbufferStorageMultisample(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + if (!ValidateRenderbufferStorageParametersBase(context, entryPoint, target, samples, + internalformat, width, height)) + { + return false; + } + + // The ES3 spec(section 4.4.2) states that the internal format must be sized and not an integer + // format if samples is greater than zero. In ES3.1(section 9.2.5), it can support integer + // multisample renderbuffer, but the samples should not be greater than MAX_INTEGER_SAMPLES. + const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat); + if (formatInfo.isInt()) + { + if ((samples > 0 && context->getClientVersion() == ES_3_0) || + samples > context->getCaps().maxIntegerSamples) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kSamplesOutOfRange); + return false; + } + } + + // The behavior is different than the ANGLE version, which would generate a GL_OUT_OF_MEMORY. + const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat); + if (static_cast(samples) > formatCaps.getMaxSamples()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kSamplesOutOfRange); + return false; + } + + return true; +} + +bool ValidateVertexAttribIPointer(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLint size, + VertexAttribType type, + GLsizei stride, + const void *pointer) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + if (!ValidateIntegerVertexFormat(context, entryPoint, index, size, type)) + { + return false; + } + + if (stride < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeStride); + return false; + } + + const Caps &caps = context->getCaps(); + if (context->getClientVersion() >= ES_3_1) + { + if (stride > caps.maxVertexAttribStride) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxVertexAttribStride); + return false; + } + + // [OpenGL ES 3.1] Section 10.3.1 page 245: + // glVertexAttribBinding is part of the equivalent code of VertexAttribIPointer, so its + // validation should be inherited. + if (index >= static_cast(caps.maxVertexAttribBindings)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings); + return false; + } + } + + // [OpenGL ES 3.0.2] Section 2.8 page 24: + // An INVALID_OPERATION error is generated when a non-zero vertex array object + // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point, + // and the pointer argument is not NULL. + if (context->getState().getVertexArrayId().value != 0 && + context->getState().getTargetBuffer(BufferBinding::Array) == 0 && pointer != nullptr) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kClientDataInVertexArray); + return false; + } + + if (context->getExtensions().webglCompatibilityANGLE) + { + if (!ValidateWebGLVertexAttribPointer(context, entryPoint, type, false, stride, pointer, + true)) + { + return false; + } + } + + return true; +} + +bool ValidateGetSynciv(const Context *context, + angle::EntryPoint entryPoint, + GLsync sync, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *values) +{ + if ((context->getClientMajorVersion() < 3) && !context->getExtensions().syncARB) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + if (bufSize < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize); + return false; + } + + if (context->isContextLost()) + { + context->validationError(entryPoint, GL_CONTEXT_LOST, kContextLost); + + if (pname == GL_SYNC_STATUS) + { + // Generate an error but still return true, the context still needs to return a + // value in this case. + return true; + } + else + { + return false; + } + } + + Sync *syncObject = context->getSync(sync); + if (!syncObject) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kSyncMissing); + return false; + } + + switch (pname) + { + case GL_OBJECT_TYPE: + case GL_SYNC_CONDITION: + case GL_SYNC_FLAGS: + case GL_SYNC_STATUS: + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname); + return false; + } + + return true; +} + +bool ValidateDrawElementsInstanced(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLsizei count, + DrawElementsType type, + const void *indices, + GLsizei instanceCount) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices, + instanceCount); +} + +bool ValidateMultiDrawArraysInstancedANGLE(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + const GLint *firsts, + const GLsizei *counts, + const GLsizei *instanceCounts, + GLsizei drawcount) +{ + if (!context->getExtensions().multiDrawANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + if (context->getClientMajorVersion() < 3) + { + if (!context->getExtensions().instancedArraysAny()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + if (!ValidateDrawInstancedANGLE(context, entryPoint)) + { + return false; + } + } + for (GLsizei drawID = 0; drawID < drawcount; ++drawID) + { + if (!ValidateDrawArraysInstancedBase(context, entryPoint, mode, firsts[drawID], + counts[drawID], instanceCounts[drawID])) + { + return false; + } + } + return true; +} + +bool ValidateMultiDrawElementsInstancedANGLE(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + const GLsizei *counts, + DrawElementsType type, + const GLvoid *const *indices, + const GLsizei *instanceCounts, + GLsizei drawcount) +{ + if (!context->getExtensions().multiDrawANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + if (context->getClientMajorVersion() < 3) + { + if (!context->getExtensions().instancedArraysAny()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + if (!ValidateDrawInstancedANGLE(context, entryPoint)) + { + return false; + } + } + for (GLsizei drawID = 0; drawID < drawcount; ++drawID) + { + if (!ValidateDrawElementsInstancedBase(context, entryPoint, mode, counts[drawID], type, + indices[drawID], instanceCounts[drawID])) + { + return false; + } + } + return true; +} + +bool ValidateDrawArraysInstancedBaseInstanceANGLE(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLint first, + GLsizei count, + GLsizei instanceCount, + GLuint baseInstance) +{ + if (!context->getExtensions().baseVertexBaseInstanceANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateDrawArraysInstancedBase(context, entryPoint, mode, first, count, instanceCount); +} + +bool ValidateDrawElementsInstancedBaseVertexBaseInstanceANGLE(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLsizei count, + DrawElementsType type, + const GLvoid *indices, + GLsizei instanceCount, + GLint baseVertex, + GLuint baseInstance) +{ + if (!context->getExtensions().baseVertexBaseInstanceANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices, + instanceCount); +} + +bool ValidateMultiDrawArraysInstancedBaseInstanceANGLE(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + const GLint *firsts, + const GLsizei *counts, + const GLsizei *instanceCounts, + const GLuint *baseInstances, + GLsizei drawcount) +{ + if (!context->getExtensions().multiDrawANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + if (drawcount < 0) + { + return false; + } + for (GLsizei drawID = 0; drawID < drawcount; ++drawID) + { + if (!ValidateDrawArraysInstancedBase(context, entryPoint, modePacked, firsts[drawID], + counts[drawID], instanceCounts[drawID])) + { + return false; + } + } + return true; +} + +bool ValidateMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + const GLsizei *counts, + DrawElementsType typePacked, + const GLvoid *const *indices, + const GLsizei *instanceCounts, + const GLint *baseVertices, + const GLuint *baseInstances, + GLsizei drawcount) +{ + if (!context->getExtensions().multiDrawANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + if (drawcount < 0) + { + return false; + } + for (GLsizei drawID = 0; drawID < drawcount; ++drawID) + { + if (!ValidateDrawElementsInstancedBase(context, entryPoint, modePacked, counts[drawID], + typePacked, indices[drawID], instanceCounts[drawID])) + { + return false; + } + } + return true; +} + +bool ValidateFramebufferTextureMultiviewOVR(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + TextureID texture, + GLint level, + GLint baseViewIndex, + GLsizei numViews) +{ + if (!ValidateFramebufferTextureMultiviewBaseANGLE(context, entryPoint, target, attachment, + texture, level, numViews)) + { + return false; + } + + if (texture.value != 0) + { + if (baseViewIndex < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBaseViewIndex); + return false; + } + + Texture *tex = context->getTexture(texture); + ASSERT(tex); + + switch (tex->getType()) + { + case TextureType::_2DArray: + case TextureType::_2DMultisampleArray: + { + if (tex->getType() == TextureType::_2DMultisampleArray) + { + if (!context->getExtensions().multiviewMultisampleANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInvalidTextureType); + return false; + } + } + + const Caps &caps = context->getCaps(); + if (baseViewIndex + numViews > caps.maxArrayTextureLayers) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kViewsExceedMaxArrayLayers); + return false; + } + + break; + } + default: + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureType); + return false; + } + + if (!ValidateFramebufferTextureMultiviewLevelAndFormat(context, entryPoint, tex, level)) + { + return false; + } + } + + return true; +} + +bool ValidateUniform1ui(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLuint v0) +{ + return ValidateUniformES3(context, entryPoint, GL_UNSIGNED_INT, location, 1); +} + +bool ValidateUniform2ui(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLuint v0, + GLuint v1) +{ + return ValidateUniformES3(context, entryPoint, GL_UNSIGNED_INT_VEC2, location, 1); +} + +bool ValidateUniform3ui(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLuint v0, + GLuint v1, + GLuint v2) +{ + return ValidateUniformES3(context, entryPoint, GL_UNSIGNED_INT_VEC3, location, 1); +} + +bool ValidateUniform4ui(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3) +{ + return ValidateUniformES3(context, entryPoint, GL_UNSIGNED_INT_VEC4, location, 1); +} + +bool ValidateUniform1uiv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + const GLuint *value) +{ + return ValidateUniformES3(context, entryPoint, GL_UNSIGNED_INT, location, count); +} + +bool ValidateUniform2uiv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + const GLuint *value) +{ + return ValidateUniformES3(context, entryPoint, GL_UNSIGNED_INT_VEC2, location, count); +} + +bool ValidateUniform3uiv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + const GLuint *value) +{ + return ValidateUniformES3(context, entryPoint, GL_UNSIGNED_INT_VEC3, location, count); +} + +bool ValidateUniform4uiv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + const GLuint *value) +{ + return ValidateUniformES3(context, entryPoint, GL_UNSIGNED_INT_VEC4, location, count); +} + +bool ValidateIsQuery(const Context *context, angle::EntryPoint entryPoint, QueryID id) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + return true; +} + +bool ValidateUniformMatrix2x3fv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateUniformMatrixES3(context, entryPoint, GL_FLOAT_MAT2x3, location, count, + transpose); +} + +bool ValidateUniformMatrix3x2fv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateUniformMatrixES3(context, entryPoint, GL_FLOAT_MAT3x2, location, count, + transpose); +} + +bool ValidateUniformMatrix2x4fv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateUniformMatrixES3(context, entryPoint, GL_FLOAT_MAT2x4, location, count, + transpose); +} + +bool ValidateUniformMatrix4x2fv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateUniformMatrixES3(context, entryPoint, GL_FLOAT_MAT4x2, location, count, + transpose); +} + +bool ValidateUniformMatrix3x4fv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateUniformMatrixES3(context, entryPoint, GL_FLOAT_MAT3x4, location, count, + transpose); +} + +bool ValidateUniformMatrix4x3fv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateUniformMatrixES3(context, entryPoint, GL_FLOAT_MAT4x3, location, count, + transpose); +} + +bool ValidateEndTransformFeedback(const Context *context, angle::EntryPoint entryPoint) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback(); + ASSERT(transformFeedback != nullptr); + + if (!transformFeedback->isActive()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kTransformFeedbackNotActive); + return false; + } + + return true; +} + +bool ValidateTransformFeedbackVaryings(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLsizei count, + const GLchar *const *varyings, + GLenum bufferMode) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + if (count < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeCount); + return false; + } + + switch (bufferMode) + { + case GL_INTERLEAVED_ATTRIBS: + break; + case GL_SEPARATE_ATTRIBS: + { + const Caps &caps = context->getCaps(); + if (count > caps.maxTransformFeedbackSeparateAttributes) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kInvalidTransformFeedbackAttribsCount); + return false; + } + break; + } + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, bufferMode); + return false; + } + + Program *programObject = GetValidProgram(context, entryPoint, program); + if (!programObject) + { + return false; + } + + return true; +} + +bool ValidateGetTransformFeedbackVarying(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLuint index, + GLsizei bufSize, + const GLsizei *length, + const GLsizei *size, + const GLenum *type, + const GLchar *name) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + if (bufSize < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize); + return false; + } + + Program *programObject = GetValidProgram(context, entryPoint, program); + if (!programObject) + { + return false; + } + + if (index >= static_cast(programObject->getTransformFeedbackVaryingCount())) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kTransformFeedbackVaryingIndexOutOfRange); + return false; + } + + return true; +} + +bool ValidateBindTransformFeedback(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + TransformFeedbackID id) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + switch (target) + { + case GL_TRANSFORM_FEEDBACK: + { + // Cannot bind a transform feedback object if the current one is started and not + // paused (3.0.2 pg 85 section 2.14.1) + if (context->getState().isTransformFeedbackActiveUnpaused()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kTransformFeedbackNotPaused); + return false; + } + + // Cannot bind a transform feedback object that does not exist (3.0.2 pg 85 section + // 2.14.1) + if (!context->isTransformFeedbackGenerated(id)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kTransformFeedbackDoesNotExist); + return false; + } + } + break; + + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, target); + return false; + } + + return true; +} + +bool ValidateIsTransformFeedback(const Context *context, + angle::EntryPoint entryPoint, + TransformFeedbackID id) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + return true; +} + +bool ValidatePauseTransformFeedback(const Context *context, angle::EntryPoint entryPoint) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback(); + ASSERT(transformFeedback != nullptr); + + // Current transform feedback must be active and not paused in order to pause (3.0.2 pg 86) + if (!transformFeedback->isActive()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kTransformFeedbackNotActive); + return false; + } + + if (transformFeedback->isPaused()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kTransformFeedbackPaused); + return false; + } + + return true; +} + +bool ValidateResumeTransformFeedback(const Context *context, angle::EntryPoint entryPoint) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback(); + ASSERT(transformFeedback != nullptr); + + // Current transform feedback must be active and paused in order to resume (3.0.2 pg 86) + if (!transformFeedback->isActive()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kTransformFeedbackNotActive); + return false; + } + + if (!transformFeedback->isPaused()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kTransformFeedbackNotPaused); + return false; + } + + if (!ValidateProgramExecutableXFBBuffersPresent( + context, context->getState().getLinkedProgramExecutable(context))) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kTransformFeedbackBufferMissing); + return false; + } + + return true; +} + +bool ValidateVertexAttribI4i(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLint x, + GLint y, + GLint z, + GLint w) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + return ValidateVertexAttribIndex(context, entryPoint, index); +} + +bool ValidateVertexAttribI4ui(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLuint x, + GLuint y, + GLuint z, + GLuint w) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + return ValidateVertexAttribIndex(context, entryPoint, index); +} + +bool ValidateVertexAttribI4iv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLint *v) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + return ValidateVertexAttribIndex(context, entryPoint, index); +} + +bool ValidateVertexAttribI4uiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLuint *v) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + return ValidateVertexAttribIndex(context, entryPoint, index); +} + +bool ValidateGetFragDataLocation(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + const GLchar *name) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + Program *programObject = GetValidProgram(context, entryPoint, program); + if (!programObject) + { + return false; + } + + if (!programObject->isLinked()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked); + return false; + } + + return true; +} + +bool ValidateGetUniformIndices(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLsizei uniformCount, + const GLchar *const *uniformNames, + const GLuint *uniformIndices) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + if (uniformCount < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeCount); + return false; + } + + Program *programObject = GetValidProgram(context, entryPoint, program); + if (!programObject) + { + return false; + } + + return true; +} + +bool ValidateGetActiveUniformsiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLsizei uniformCount, + const GLuint *uniformIndices, + GLenum pname, + const GLint *params) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + if (uniformCount < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeCount); + return false; + } + + Program *programObject = GetValidProgram(context, entryPoint, program); + if (!programObject) + { + return false; + } + + switch (pname) + { + case GL_UNIFORM_TYPE: + case GL_UNIFORM_SIZE: + break; + case GL_UNIFORM_NAME_LENGTH: + if (context->getExtensions().webglCompatibilityANGLE) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + break; + case GL_UNIFORM_BLOCK_INDEX: + case GL_UNIFORM_OFFSET: + case GL_UNIFORM_ARRAY_STRIDE: + case GL_UNIFORM_MATRIX_STRIDE: + case GL_UNIFORM_IS_ROW_MAJOR: + break; + + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname); + return false; + } + + if (uniformCount > programObject->getActiveUniformCount()) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform); + return false; + } + + for (int uniformId = 0; uniformId < uniformCount; uniformId++) + { + const GLuint index = uniformIndices[uniformId]; + + if (index >= static_cast(programObject->getActiveUniformCount())) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform); + return false; + } + } + + return true; +} + +bool ValidateGetUniformBlockIndex(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + const GLchar *uniformBlockName) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + Program *programObject = GetValidProgram(context, entryPoint, program); + if (!programObject) + { + return false; + } + + return true; +} + +bool ValidateGetActiveUniformBlockiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformBlockIndex uniformBlockIndex, + GLenum pname, + const GLint *params) +{ + return ValidateGetActiveUniformBlockivBase(context, entryPoint, program, uniformBlockIndex, + pname, nullptr); +} + +bool ValidateGetActiveUniformBlockName(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformBlockIndex uniformBlockIndex, + GLsizei bufSize, + const GLsizei *length, + const GLchar *uniformBlockName) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + Program *programObject = GetValidProgram(context, entryPoint, program); + if (!programObject) + { + return false; + } + + if (uniformBlockIndex.value >= programObject->getActiveUniformBlockCount()) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxActiveUniformBlock); + return false; + } + + return true; +} + +bool ValidateUniformBlockBinding(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformBlockIndex uniformBlockIndex, + GLuint uniformBlockBinding) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + if (uniformBlockBinding >= static_cast(context->getCaps().maxUniformBufferBindings)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kIndexExceedsMaxUniformBufferBindings); + return false; + } + + Program *programObject = GetValidProgram(context, entryPoint, program); + if (!programObject) + { + return false; + } + + // if never linked, there won't be any uniform blocks + if (uniformBlockIndex.value >= programObject->getActiveUniformBlockCount()) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kIndexExceedsMaxUniformBufferBindings); + return false; + } + + return true; +} + +bool ValidateDrawArraysInstanced(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLint first, + GLsizei count, + GLsizei primcount) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + return ValidateDrawArraysInstancedBase(context, entryPoint, mode, first, count, primcount); +} + +bool ValidateFenceSync(const Context *context, + angle::EntryPoint entryPoint, + GLenum condition, + GLbitfield flags) +{ + if ((context->getClientMajorVersion() < 3) && !context->getExtensions().syncARB) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + if (condition != GL_SYNC_GPU_COMMANDS_COMPLETE) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFenceCondition); + return false; + } + + if (flags != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidFlags); + return false; + } + + return true; +} + +bool ValidateIsSync(const Context *context, angle::EntryPoint entryPoint, GLsync sync) +{ + if ((context->getClientMajorVersion() < 3) && !context->getExtensions().syncARB) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + return true; +} + +bool ValidateDeleteSync(const Context *context, angle::EntryPoint entryPoint, GLsync sync) +{ + if ((context->getClientMajorVersion() < 3) && !context->getExtensions().syncARB) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + if (sync != static_cast(0) && !context->getSync(sync)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kSyncMissing); + return false; + } + + return true; +} + +bool ValidateClientWaitSync(const Context *context, + angle::EntryPoint entryPoint, + GLsync sync, + GLbitfield flags, + GLuint64 timeout) +{ + if ((context->getClientMajorVersion() < 3) && !context->getExtensions().syncARB) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + if ((flags & ~(GL_SYNC_FLUSH_COMMANDS_BIT)) != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidFlags); + return false; + } + + Sync *clientWaitSync = context->getSync(sync); + if (!clientWaitSync) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kSyncMissing); + return false; + } + + return true; +} + +bool ValidateWaitSync(const Context *context, + angle::EntryPoint entryPoint, + GLsync sync, + GLbitfield flags, + GLuint64 timeout) +{ + if ((context->getClientMajorVersion() < 3) && !context->getExtensions().syncARB) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + if (flags != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidFlags); + return false; + } + + if (timeout != GL_TIMEOUT_IGNORED) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidTimeout); + return false; + } + + Sync *waitSync = context->getSync(sync); + if (!waitSync) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kSyncMissing); + return false; + } + + return true; +} + +bool ValidateGetInteger64v(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + const GLint64 *params) +{ + if ((context->getClientMajorVersion() < 3) && !context->getExtensions().syncARB) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + GLenum nativeType = GL_NONE; + unsigned int numParams = 0; + if (!ValidateStateQuery(context, entryPoint, pname, &nativeType, &numParams)) + { + return false; + } + + return true; +} + +bool ValidateIsSampler(const Context *context, angle::EntryPoint entryPoint, SamplerID sampler) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + return true; +} + +bool ValidateBindSampler(const Context *context, + angle::EntryPoint entryPoint, + GLuint unit, + SamplerID sampler) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + if (GetIDValue(sampler) != 0 && !context->isSampler(sampler)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidSampler); + return false; + } + + if (unit >= static_cast(context->getCaps().maxCombinedTextureImageUnits)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidCombinedImageUnit); + return false; + } + + return true; +} + +bool ValidateVertexAttribDivisor(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLuint divisor) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + return ValidateVertexAttribIndex(context, entryPoint, index); +} + +bool ValidateTexStorage2D(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + if (!ValidateES3TexStorage2DParameters(context, entryPoint, target, levels, internalformat, + width, height, 1)) + { + return false; + } + + return true; +} + +bool ValidateTexStorage3D(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + + if (!ValidateES3TexStorage3DParameters(context, entryPoint, target, levels, internalformat, + width, height, depth)) + { + return false; + } + + return true; +} + +bool ValidateGetBufferParameteri64v(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding target, + GLenum pname, + const GLint64 *params) +{ + return ValidateGetBufferParameterBase(context, entryPoint, target, pname, false, nullptr); +} + +bool ValidateGetSamplerParameterfv(const Context *context, + angle::EntryPoint entryPoint, + SamplerID sampler, + GLenum pname, + const GLfloat *params) +{ + return ValidateGetSamplerParameterBase(context, entryPoint, sampler, pname, nullptr); +} + +bool ValidateGetSamplerParameteriv(const Context *context, + angle::EntryPoint entryPoint, + SamplerID sampler, + GLenum pname, + const GLint *params) +{ + return ValidateGetSamplerParameterBase(context, entryPoint, sampler, pname, nullptr); +} + +bool ValidateGetSamplerParameterIivOES(const Context *context, + angle::EntryPoint entryPoint, + SamplerID sampler, + GLenum pname, + const GLint *params) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + return ValidateGetSamplerParameterBase(context, entryPoint, sampler, pname, nullptr); +} + +bool ValidateGetSamplerParameterIuivOES(const Context *context, + angle::EntryPoint entryPoint, + SamplerID sampler, + GLenum pname, + const GLuint *params) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + return ValidateGetSamplerParameterBase(context, entryPoint, sampler, pname, nullptr); +} + +bool ValidateSamplerParameterf(const Context *context, + angle::EntryPoint entryPoint, + SamplerID sampler, + GLenum pname, + GLfloat param) +{ + return ValidateSamplerParameterBase(context, entryPoint, sampler, pname, -1, false, ¶m); +} + +bool ValidateSamplerParameterfv(const Context *context, + angle::EntryPoint entryPoint, + SamplerID sampler, + GLenum pname, + const GLfloat *params) +{ + return ValidateSamplerParameterBase(context, entryPoint, sampler, pname, -1, true, params); +} + +bool ValidateSamplerParameteri(const Context *context, + angle::EntryPoint entryPoint, + SamplerID sampler, + GLenum pname, + GLint param) +{ + return ValidateSamplerParameterBase(context, entryPoint, sampler, pname, -1, false, ¶m); +} + +bool ValidateSamplerParameteriv(const Context *context, + angle::EntryPoint entryPoint, + SamplerID sampler, + GLenum pname, + const GLint *params) +{ + return ValidateSamplerParameterBase(context, entryPoint, sampler, pname, -1, true, params); +} + +bool ValidateSamplerParameterIivOES(const Context *context, + angle::EntryPoint entryPoint, + SamplerID sampler, + GLenum pname, + const GLint *params) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + return ValidateSamplerParameterBase(context, entryPoint, sampler, pname, -1, true, params); +} + +bool ValidateSamplerParameterIuivOES(const Context *context, + angle::EntryPoint entryPoint, + SamplerID sampler, + GLenum pname, + const GLuint *params) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + return ValidateSamplerParameterBase(context, entryPoint, sampler, pname, -1, true, params); +} + +bool ValidateGetVertexAttribIiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum pname, + const GLint *params) +{ + return ValidateGetVertexAttribBase(context, entryPoint, index, pname, nullptr, false, true); +} + +bool ValidateGetVertexAttribIuiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum pname, + const GLuint *params) +{ + return ValidateGetVertexAttribBase(context, entryPoint, index, pname, nullptr, false, true); +} + +bool ValidateGetInternalformativ(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei bufSize, + const GLint *params) +{ + return ValidateGetInternalFormativBase(context, entryPoint, target, internalformat, pname, + bufSize, nullptr); +} + +bool ValidateBindFragDataLocationIndexedEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLuint colorNumber, + GLuint index, + const char *name) +{ + if (!context->getExtensions().blendFuncExtendedEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + if (index > 1) + { + // This error is not explicitly specified but the spec does say that " may be zero or + // one to specify that the color be used as either the first or second color input to the + // blend equation, respectively" + context->validationError(entryPoint, GL_INVALID_VALUE, kFragDataBindingIndexOutOfRange); + return false; + } + if (index == 1) + { + if (colorNumber >= context->getCaps().maxDualSourceDrawBuffers) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kColorNumberGreaterThanMaxDualSourceDrawBuffers); + return false; + } + } + else + { + if (colorNumber >= static_cast(context->getCaps().maxDrawBuffers)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, + kColorNumberGreaterThanMaxDrawBuffers); + return false; + } + } + Program *programObject = GetValidProgram(context, entryPoint, program); + if (!programObject) + { + return false; + } + return true; +} + +bool ValidateBindFragDataLocationEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLuint colorNumber, + const char *name) +{ + return ValidateBindFragDataLocationIndexedEXT(context, entryPoint, program, colorNumber, 0u, + name); +} + +bool ValidateGetFragDataIndexEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + const char *name) +{ + if (!context->getExtensions().blendFuncExtendedEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + Program *programObject = GetValidProgram(context, entryPoint, program); + if (!programObject) + { + return false; + } + if (!programObject->isLinked()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked); + return false; + } + return true; +} + +bool ValidateTexStorage2DMultisampleANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLsizei samples, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLboolean fixedSampleLocations) +{ + if (!context->getExtensions().textureMultisampleANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kMultisampleTextureExtensionOrES31Required); + return false; + } + + return ValidateTexStorage2DMultisampleBase(context, entryPoint, target, samples, internalFormat, + width, height); +} + +bool ValidateGetTexLevelParameterfvANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum pname, + const GLfloat *params) +{ + if (!context->getExtensions().textureMultisampleANGLE && + !context->getExtensions().getTexLevelParameterANGLE) + { + context->validationError( + entryPoint, GL_INVALID_OPERATION, + kMultisampleTextureExtensionOrGetTexLevelParameterExtensionOrES31Required); + return false; + } + + return ValidateGetTexLevelParameterBase(context, entryPoint, target, level, pname, nullptr); +} + +bool ValidateGetTexLevelParameterivANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum pname, + const GLint *params) +{ + if (!context->getExtensions().textureMultisampleANGLE && + !context->getExtensions().getTexLevelParameterANGLE) + { + context->validationError( + entryPoint, GL_INVALID_OPERATION, + kMultisampleTextureExtensionOrGetTexLevelParameterExtensionOrES31Required); + return false; + } + + return ValidateGetTexLevelParameterBase(context, entryPoint, target, level, pname, nullptr); +} + +bool ValidateGetMultisamplefvANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLuint index, + const GLfloat *val) +{ + if (!context->getExtensions().textureMultisampleANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kMultisampleTextureExtensionOrES31Required); + return false; + } + + return ValidateGetMultisamplefvBase(context, entryPoint, pname, index, val); +} + +bool ValidateSampleMaskiANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLuint maskNumber, + GLbitfield mask) +{ + if (!context->getExtensions().textureMultisampleANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kMultisampleTextureExtensionOrES31Required); + return false; + } + + return ValidateSampleMaskiBase(context, entryPoint, maskNumber, mask); +} +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/validationES3.h b/gfx/angle/checkout/src/libANGLE/validationES3.h new file mode 100644 index 0000000000..dcea322874 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationES3.h @@ -0,0 +1,72 @@ +// +// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// validationES3.h: +// Inlined validation functions for OpenGL ES 3.0 entry points. + +#ifndef LIBANGLE_VALIDATION_ES3_H_ +#define LIBANGLE_VALIDATION_ES3_H_ + +#include "libANGLE/ErrorStrings.h" +#include "libANGLE/validationES3_autogen.h" + +namespace gl +{ +bool ValidateES3TexImageParametersBase(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum internalformat, + bool isCompressed, + bool isSubImage, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + GLsizei imageSize, + const void *pixels); + +bool ValidateES3TexStorageParametersLevel(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLsizei levels, + GLsizei width, + GLsizei height, + GLsizei depth); + +bool ValidateES3TexStorageParametersExtent(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLsizei levels, + GLsizei width, + GLsizei height, + GLsizei depth); + +bool ValidateES3TexStorageParametersTexObject(const Context *context, + angle::EntryPoint entryPoint, + TextureType target); + +bool ValidateES3TexStorageParametersFormat(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth); + +bool ValidateProgramParameteriBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLenum pname, + GLint value); +} // namespace gl + +#endif // LIBANGLE_VALIDATION_ES3_H_ diff --git a/gfx/angle/checkout/src/libANGLE/validationES31.cpp b/gfx/angle/checkout/src/libANGLE/validationES31.cpp new file mode 100644 index 0000000000..c0222f7497 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationES31.cpp @@ -0,0 +1,3157 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// validationES31.cpp: Validation functions for OpenGL ES 3.1 entry point parameters + +#include "libANGLE/validationES31_autogen.h" + +#include "libANGLE/Context.h" +#include "libANGLE/ErrorStrings.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/ProgramExecutable.h" +#include "libANGLE/VertexArray.h" +#include "libANGLE/validationES.h" +#include "libANGLE/validationES2_autogen.h" +#include "libANGLE/validationES31.h" +#include "libANGLE/validationES3_autogen.h" + +#include "common/utilities.h" + +using namespace angle; + +namespace gl +{ +using namespace err; + +namespace +{ + +bool ValidateNamedProgramInterface(GLenum programInterface) +{ + switch (programInterface) + { + case GL_UNIFORM: + case GL_UNIFORM_BLOCK: + case GL_PROGRAM_INPUT: + case GL_PROGRAM_OUTPUT: + case GL_TRANSFORM_FEEDBACK_VARYING: + case GL_BUFFER_VARIABLE: + case GL_SHADER_STORAGE_BLOCK: + return true; + default: + return false; + } +} + +bool ValidateLocationProgramInterface(GLenum programInterface) +{ + switch (programInterface) + { + case GL_UNIFORM: + case GL_PROGRAM_INPUT: + case GL_PROGRAM_OUTPUT: + return true; + default: + return false; + } +} + +bool ValidateProgramInterface(GLenum programInterface) +{ + return (programInterface == GL_ATOMIC_COUNTER_BUFFER || + ValidateNamedProgramInterface(programInterface)); +} + +bool ValidateProgramResourceProperty(const Context *context, + angle::EntryPoint entryPoint, + GLenum prop) +{ + ASSERT(context); + switch (prop) + { + case GL_ACTIVE_VARIABLES: + case GL_BUFFER_BINDING: + case GL_NUM_ACTIVE_VARIABLES: + + case GL_ARRAY_SIZE: + + case GL_ARRAY_STRIDE: + case GL_BLOCK_INDEX: + case GL_IS_ROW_MAJOR: + case GL_MATRIX_STRIDE: + + case GL_ATOMIC_COUNTER_BUFFER_INDEX: + + case GL_BUFFER_DATA_SIZE: + + case GL_LOCATION: + + case GL_NAME_LENGTH: + + case GL_OFFSET: + + case GL_REFERENCED_BY_VERTEX_SHADER: + case GL_REFERENCED_BY_FRAGMENT_SHADER: + case GL_REFERENCED_BY_COMPUTE_SHADER: + + case GL_TOP_LEVEL_ARRAY_SIZE: + case GL_TOP_LEVEL_ARRAY_STRIDE: + + case GL_TYPE: + return true; + + case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT: + return context->getExtensions().geometryShaderAny() || + context->getClientVersion() >= ES_3_2; + + case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT: + case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT: + case GL_IS_PER_PATCH_EXT: + return context->getExtensions().tessellationShaderEXT || + context->getClientVersion() >= ES_3_2; + + case GL_LOCATION_INDEX_EXT: + return context->getExtensions().blendFuncExtendedEXT; + + default: + return false; + } +} + +// GLES 3.10 spec: Page 82 -- Table 7.2 +bool ValidateProgramResourcePropertyByInterface(GLenum prop, GLenum programInterface) +{ + switch (prop) + { + case GL_ACTIVE_VARIABLES: + case GL_BUFFER_BINDING: + case GL_NUM_ACTIVE_VARIABLES: + { + switch (programInterface) + { + case GL_ATOMIC_COUNTER_BUFFER: + case GL_SHADER_STORAGE_BLOCK: + case GL_UNIFORM_BLOCK: + return true; + default: + return false; + } + } + + case GL_ARRAY_SIZE: + { + switch (programInterface) + { + case GL_BUFFER_VARIABLE: + case GL_PROGRAM_INPUT: + case GL_PROGRAM_OUTPUT: + case GL_TRANSFORM_FEEDBACK_VARYING: + case GL_UNIFORM: + return true; + default: + return false; + } + } + + case GL_ARRAY_STRIDE: + case GL_BLOCK_INDEX: + case GL_IS_ROW_MAJOR: + case GL_MATRIX_STRIDE: + { + switch (programInterface) + { + case GL_BUFFER_VARIABLE: + case GL_UNIFORM: + return true; + default: + return false; + } + } + + case GL_ATOMIC_COUNTER_BUFFER_INDEX: + { + if (programInterface == GL_UNIFORM) + { + return true; + } + return false; + } + + case GL_BUFFER_DATA_SIZE: + { + switch (programInterface) + { + case GL_ATOMIC_COUNTER_BUFFER: + case GL_SHADER_STORAGE_BLOCK: + case GL_UNIFORM_BLOCK: + return true; + default: + return false; + } + } + + case GL_LOCATION: + { + return ValidateLocationProgramInterface(programInterface); + } + + case GL_LOCATION_INDEX_EXT: + { + // EXT_blend_func_extended + return (programInterface == GL_PROGRAM_OUTPUT); + } + + case GL_NAME_LENGTH: + { + return ValidateNamedProgramInterface(programInterface); + } + + case GL_OFFSET: + { + switch (programInterface) + { + case GL_BUFFER_VARIABLE: + case GL_UNIFORM: + return true; + default: + return false; + } + } + + case GL_REFERENCED_BY_VERTEX_SHADER: + case GL_REFERENCED_BY_FRAGMENT_SHADER: + case GL_REFERENCED_BY_COMPUTE_SHADER: + case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT: + case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT: + case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT: + { + switch (programInterface) + { + case GL_ATOMIC_COUNTER_BUFFER: + case GL_BUFFER_VARIABLE: + case GL_PROGRAM_INPUT: + case GL_PROGRAM_OUTPUT: + case GL_SHADER_STORAGE_BLOCK: + case GL_UNIFORM: + case GL_UNIFORM_BLOCK: + return true; + default: + return false; + } + } + + case GL_TOP_LEVEL_ARRAY_SIZE: + case GL_TOP_LEVEL_ARRAY_STRIDE: + { + if (programInterface == GL_BUFFER_VARIABLE) + { + return true; + } + return false; + } + + case GL_TYPE: + { + switch (programInterface) + { + case GL_BUFFER_VARIABLE: + case GL_PROGRAM_INPUT: + case GL_PROGRAM_OUTPUT: + case GL_TRANSFORM_FEEDBACK_VARYING: + case GL_UNIFORM: + return true; + default: + return false; + } + } + case GL_IS_PER_PATCH_EXT: + switch (programInterface) + { + case GL_PROGRAM_INPUT: + case GL_PROGRAM_OUTPUT: + return true; + } + return false; + + default: + return false; + } +} + +bool ValidateProgramResourceIndex(const Program *programObject, + GLenum programInterface, + GLuint index) +{ + switch (programInterface) + { + case GL_PROGRAM_INPUT: + return (index < + static_cast(programObject->getState().getProgramInputs().size())); + + case GL_PROGRAM_OUTPUT: + return (index < static_cast(programObject->getOutputResourceCount())); + + case GL_UNIFORM: + return (index < static_cast(programObject->getActiveUniformCount())); + + case GL_BUFFER_VARIABLE: + return (index < static_cast(programObject->getActiveBufferVariableCount())); + + case GL_SHADER_STORAGE_BLOCK: + return (index < static_cast(programObject->getActiveShaderStorageBlockCount())); + + case GL_UNIFORM_BLOCK: + return (index < programObject->getActiveUniformBlockCount()); + + case GL_ATOMIC_COUNTER_BUFFER: + return (index < programObject->getActiveAtomicCounterBufferCount()); + + case GL_TRANSFORM_FEEDBACK_VARYING: + return (index < static_cast(programObject->getTransformFeedbackVaryingCount())); + + default: + UNREACHABLE(); + return false; + } +} + +bool ValidateProgramUniformBase(const Context *context, + angle::EntryPoint entryPoint, + GLenum valueType, + ShaderProgramID program, + UniformLocation location, + GLsizei count) +{ + const LinkedUniform *uniform = nullptr; + Program *programObject = GetValidProgram(context, entryPoint, program); + return ValidateUniformCommonBase(context, entryPoint, programObject, location, count, + &uniform) && + ValidateUniformValue(context, entryPoint, valueType, uniform->type); +} + +bool ValidateProgramUniformMatrixBase(const Context *context, + angle::EntryPoint entryPoint, + GLenum valueType, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose) +{ + const LinkedUniform *uniform = nullptr; + Program *programObject = GetValidProgram(context, entryPoint, program); + return ValidateUniformCommonBase(context, entryPoint, programObject, location, count, + &uniform) && + ValidateUniformMatrixValue(context, entryPoint, valueType, uniform->type); +} + +bool ValidateVertexAttribFormatCommon(const Context *context, + angle::EntryPoint entryPoint, + GLuint relativeOffset) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + const Caps &caps = context->getCaps(); + if (relativeOffset > static_cast(caps.maxVertexAttribRelativeOffset)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kRelativeOffsetTooLarge); + return false; + } + + // [OpenGL ES 3.1] Section 10.3.1 page 243: + // An INVALID_OPERATION error is generated if the default vertex array object is bound. + if (context->getState().getVertexArrayId().value == 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultVertexArray); + return false; + } + + return true; +} + +} // anonymous namespace + +bool ValidateGetBooleani_v(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index, + const GLboolean *data) +{ + if (context->getClientVersion() < ES_3_1 && !context->getExtensions().drawBuffersIndexedAny()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kES31OrDrawBuffersIndexedExtensionNotAvailable); + return false; + } + + if (!ValidateIndexedStateQuery(context, entryPoint, target, index, nullptr)) + { + return false; + } + + return true; +} + +bool ValidateGetBooleani_vRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index, + GLsizei bufSize, + const GLsizei *length, + const GLboolean *data) +{ + if (context->getClientVersion() < ES_3_1 && !context->getExtensions().drawBuffersIndexedAny()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kES31OrDrawBuffersIndexedExtensionNotAvailable); + return false; + } + + if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) + { + return false; + } + + GLsizei numParams = 0; + + if (!ValidateIndexedStateQuery(context, entryPoint, target, index, &numParams)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams)) + { + return false; + } + + SetRobustLengthParam(length, numParams); + return true; +} + +bool ValidateDrawIndirectBase(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + const void *indirect) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + // Here the third parameter 1 is only to pass the count validation. + if (!ValidateDrawBase(context, entryPoint, mode)) + { + return false; + } + + const State &state = context->getState(); + + // An INVALID_OPERATION error is generated if zero is bound to VERTEX_ARRAY_BINDING, + // DRAW_INDIRECT_BUFFER or to any enabled vertex array. + if (state.getVertexArrayId().value == 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultVertexArray); + return false; + } + + if (context->getStateCache().hasAnyActiveClientAttrib()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kClientDataInVertexArray); + return false; + } + + Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect); + if (!drawIndirectBuffer) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kDrawIndirectBufferNotBound); + return false; + } + + // An INVALID_VALUE error is generated if indirect is not a multiple of the size, in basic + // machine units, of uint. + GLint64 offset = reinterpret_cast(indirect); + if ((static_cast(offset) % sizeof(GLuint)) != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidIndirectOffset); + return false; + } + + return true; +} + +bool ValidateDrawArraysIndirect(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + const void *indirect) +{ + const State &state = context->getState(); + TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback(); + if (curTransformFeedback && curTransformFeedback->isActive() && + !curTransformFeedback->isPaused()) + { + // EXT_geometry_shader allows transform feedback to work with all draw commands. + // [EXT_geometry_shader] Section 12.1, "Transform Feedback" + if (context->getExtensions().geometryShaderAny() || context->getClientVersion() >= ES_3_2) + { + if (!ValidateTransformFeedbackPrimitiveMode( + context, entryPoint, curTransformFeedback->getPrimitiveMode(), mode)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInvalidDrawModeTransformFeedback); + return false; + } + } + else + { + // An INVALID_OPERATION error is generated if transform feedback is active and not + // paused. + context->validationError(entryPoint, GL_INVALID_OPERATION, + kUnsupportedDrawModeForTransformFeedback); + return false; + } + } + + if (!ValidateDrawIndirectBase(context, entryPoint, mode, indirect)) + return false; + + Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect); + CheckedNumeric checkedOffset(reinterpret_cast(indirect)); + // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawArraysIndirectCommand + // which's size is 4 * sizeof(uint). + auto checkedSum = checkedOffset + 4 * sizeof(GLuint); + if (!checkedSum.IsValid() || + checkedSum.ValueOrDie() > static_cast(drawIndirectBuffer->getSize())) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kParamOverflow); + return false; + } + + return true; +} + +bool ValidateDrawElementsIndirect(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + DrawElementsType type, + const void *indirect) +{ + if (!ValidateDrawElementsBase(context, entryPoint, mode, type)) + { + return false; + } + + const State &state = context->getState(); + const VertexArray *vao = state.getVertexArray(); + Buffer *elementArrayBuffer = vao->getElementArrayBuffer(); + if (!elementArrayBuffer) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kMustHaveElementArrayBinding); + return false; + } + + if (!ValidateDrawIndirectBase(context, entryPoint, mode, indirect)) + return false; + + Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect); + CheckedNumeric checkedOffset(reinterpret_cast(indirect)); + // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawElementsIndirectCommand + // which's size is 5 * sizeof(uint). + auto checkedSum = checkedOffset + 5 * sizeof(GLuint); + if (!checkedSum.IsValid() || + checkedSum.ValueOrDie() > static_cast(drawIndirectBuffer->getSize())) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kParamOverflow); + return false; + } + + return true; +} + +bool ValidateMultiDrawIndirectBase(const Context *context, + angle::EntryPoint entryPoint, + GLsizei drawcount, + GLsizei stride) +{ + if (!context->getExtensions().multiDrawIndirectEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + // An INVALID_VALUE error is generated if stride is neither 0 nor a multiple of 4. + if ((stride & 3) != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidDrawBufferValue); + return false; + } + + // An INVALID_VALUE error is generated if drawcount is not positive. + if (drawcount <= 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidValueNonPositive); + return false; + } + + return true; +} + +bool ValidateProgramUniform1iBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLint v0) +{ + return ValidateProgramUniform1ivBase(context, entryPoint, program, location, 1, &v0); +} + +bool ValidateProgramUniform2iBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLint v0, + GLint v1) +{ + GLint xy[2] = {v0, v1}; + return ValidateProgramUniform2ivBase(context, entryPoint, program, location, 1, xy); +} + +bool ValidateProgramUniform3iBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLint v0, + GLint v1, + GLint v2) +{ + GLint xyz[3] = {v0, v1, v2}; + return ValidateProgramUniform3ivBase(context, entryPoint, program, location, 1, xyz); +} + +bool ValidateProgramUniform4iBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLint v0, + GLint v1, + GLint v2, + GLint v3) +{ + GLint xyzw[4] = {v0, v1, v2, v3}; + return ValidateProgramUniform4ivBase(context, entryPoint, program, location, 1, xyzw); +} + +bool ValidateProgramUniform1uiBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLuint v0) +{ + return ValidateProgramUniform1uivBase(context, entryPoint, program, location, 1, &v0); +} + +bool ValidateProgramUniform2uiBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLuint v0, + GLuint v1) +{ + GLuint xy[2] = {v0, v1}; + return ValidateProgramUniform2uivBase(context, entryPoint, program, location, 1, xy); +} + +bool ValidateProgramUniform3uiBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLuint v0, + GLuint v1, + GLuint v2) +{ + GLuint xyz[3] = {v0, v1, v2}; + return ValidateProgramUniform3uivBase(context, entryPoint, program, location, 1, xyz); +} + +bool ValidateProgramUniform4uiBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3) +{ + GLuint xyzw[4] = {v0, v1, v2, v3}; + return ValidateProgramUniform4uivBase(context, entryPoint, program, location, 1, xyzw); +} + +bool ValidateProgramUniform1fBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLfloat v0) +{ + return ValidateProgramUniform1fvBase(context, entryPoint, program, location, 1, &v0); +} + +bool ValidateProgramUniform2fBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLfloat v0, + GLfloat v1) +{ + GLfloat xy[2] = {v0, v1}; + return ValidateProgramUniform2fvBase(context, entryPoint, program, location, 1, xy); +} + +bool ValidateProgramUniform3fBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLfloat v0, + GLfloat v1, + GLfloat v2) +{ + GLfloat xyz[3] = {v0, v1, v2}; + return ValidateProgramUniform3fvBase(context, entryPoint, program, location, 1, xyz); +} + +bool ValidateProgramUniform4fBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLfloat v0, + GLfloat v1, + GLfloat v2, + GLfloat v3) +{ + GLfloat xyzw[4] = {v0, v1, v2, v3}; + return ValidateProgramUniform4fvBase(context, entryPoint, program, location, 1, xyzw); +} + +bool ValidateProgramUniform1ivBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLint *value) +{ + const LinkedUniform *uniform = nullptr; + Program *programObject = GetValidProgram(context, entryPoint, program); + return ValidateUniformCommonBase(context, entryPoint, programObject, location, count, + &uniform) && + ValidateUniform1ivValue(context, entryPoint, uniform->type, count, value); +} + +bool ValidateProgramUniform2ivBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLint *value) +{ + return ValidateProgramUniformBase(context, entryPoint, GL_INT_VEC2, program, location, count); +} + +bool ValidateProgramUniform3ivBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLint *value) +{ + return ValidateProgramUniformBase(context, entryPoint, GL_INT_VEC3, program, location, count); +} + +bool ValidateProgramUniform4ivBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLint *value) +{ + return ValidateProgramUniformBase(context, entryPoint, GL_INT_VEC4, program, location, count); +} + +bool ValidateProgramUniform1uivBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLuint *value) +{ + return ValidateProgramUniformBase(context, entryPoint, GL_UNSIGNED_INT, program, location, + count); +} + +bool ValidateProgramUniform2uivBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLuint *value) +{ + return ValidateProgramUniformBase(context, entryPoint, GL_UNSIGNED_INT_VEC2, program, location, + count); +} + +bool ValidateProgramUniform3uivBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLuint *value) +{ + return ValidateProgramUniformBase(context, entryPoint, GL_UNSIGNED_INT_VEC3, program, location, + count); +} + +bool ValidateProgramUniform4uivBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLuint *value) +{ + return ValidateProgramUniformBase(context, entryPoint, GL_UNSIGNED_INT_VEC4, program, location, + count); +} + +bool ValidateProgramUniform1fvBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLfloat *value) +{ + return ValidateProgramUniformBase(context, entryPoint, GL_FLOAT, program, location, count); +} + +bool ValidateProgramUniform2fvBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLfloat *value) +{ + return ValidateProgramUniformBase(context, entryPoint, GL_FLOAT_VEC2, program, location, count); +} + +bool ValidateProgramUniform3fvBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLfloat *value) +{ + return ValidateProgramUniformBase(context, entryPoint, GL_FLOAT_VEC3, program, location, count); +} + +bool ValidateProgramUniform4fvBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLfloat *value) +{ + return ValidateProgramUniformBase(context, entryPoint, GL_FLOAT_VEC4, program, location, count); +} + +bool ValidateProgramUniformMatrix2fvBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT2, program, location, + count, transpose); +} + +bool ValidateProgramUniformMatrix3fvBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT3, program, location, + count, transpose); +} + +bool ValidateProgramUniformMatrix4fvBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT4, program, location, + count, transpose); +} + +bool ValidateProgramUniformMatrix2x3fvBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT2x3, program, location, + count, transpose); +} + +bool ValidateProgramUniformMatrix3x2fvBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT3x2, program, location, + count, transpose); +} + +bool ValidateProgramUniformMatrix2x4fvBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT2x4, program, location, + count, transpose); +} + +bool ValidateProgramUniformMatrix4x2fvBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT4x2, program, location, + count, transpose); +} + +bool ValidateProgramUniformMatrix3x4fvBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT3x4, program, location, + count, transpose); +} + +bool ValidateProgramUniformMatrix4x3fvBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT4x3, program, location, + count, transpose); +} + +bool ValidateGetTexLevelParameterfv(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum pname, + const GLfloat *params) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateGetTexLevelParameterBase(context, entryPoint, target, level, pname, nullptr); +} + +bool ValidateGetTexLevelParameterfvRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLfloat *params) +{ + UNIMPLEMENTED(); + return false; +} + +bool ValidateGetTexLevelParameteriv(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum pname, + const GLint *params) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateGetTexLevelParameterBase(context, entryPoint, target, level, pname, nullptr); +} + +bool ValidateGetTexLevelParameterivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params) +{ + UNIMPLEMENTED(); + return false; +} + +bool ValidateTexStorage2DMultisample(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLsizei samples, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLboolean fixedSampleLocations) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateTexStorage2DMultisampleBase(context, entryPoint, target, samples, internalFormat, + width, height); +} + +bool ValidateTexStorageMem2DMultisampleEXT(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLsizei samples, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLboolean fixedSampleLocations, + MemoryObjectID memory, + GLuint64 offset) +{ + if (!context->getExtensions().memoryObjectEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + UNIMPLEMENTED(); + return false; +} + +bool ValidateGetMultisamplefv(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLuint index, + const GLfloat *val) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateGetMultisamplefvBase(context, entryPoint, pname, index, val); +} + +bool ValidateGetMultisamplefvRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLuint index, + GLsizei bufSize, + const GLsizei *length, + const GLfloat *val) +{ + UNIMPLEMENTED(); + return false; +} + +bool ValidateFramebufferParameteri(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum pname, + GLint param) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateFramebufferParameteriBase(context, entryPoint, target, pname, param); +} + +bool ValidateGetFramebufferParameteriv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum pname, + const GLint *params) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateGetFramebufferParameterivBase(context, entryPoint, target, pname, params); +} + +bool ValidateGetFramebufferParameterivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params) +{ + UNIMPLEMENTED(); + return false; +} + +bool ValidateGetProgramResourceIndex(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLenum programInterface, + const GLchar *name) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + Program *programObject = GetValidProgram(context, entryPoint, program); + if (programObject == nullptr) + { + return false; + } + + if (!ValidateNamedProgramInterface(programInterface)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidProgramInterface); + return false; + } + + return true; +} + +bool ValidateBindVertexBuffer(const Context *context, + angle::EntryPoint entryPoint, + GLuint bindingIndex, + BufferID buffer, + GLintptr offset, + GLsizei stride) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + if (!context->isBufferGenerated(buffer)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kObjectNotGenerated); + return false; + } + + const Caps &caps = context->getCaps(); + if (bindingIndex >= static_cast(caps.maxVertexAttribBindings)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings); + return false; + } + + if (offset < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset); + return false; + } + + if (stride < 0 || stride > caps.maxVertexAttribStride) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxVertexAttribStride); + return false; + } + + // [OpenGL ES 3.1] Section 10.3.1 page 244: + // An INVALID_OPERATION error is generated if the default vertex array object is bound. + if (context->getState().getVertexArrayId().value == 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultVertexArray); + return false; + } + + return true; +} + +bool ValidateVertexBindingDivisor(const Context *context, + angle::EntryPoint entryPoint, + GLuint bindingIndex, + GLuint divisor) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + const Caps &caps = context->getCaps(); + if (bindingIndex >= static_cast(caps.maxVertexAttribBindings)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings); + return false; + } + + // [OpenGL ES 3.1] Section 10.3.1 page 243: + // An INVALID_OPERATION error is generated if the default vertex array object is bound. + if (context->getState().getVertexArrayId().value == 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultVertexArray); + return false; + } + + return true; +} + +bool ValidateVertexAttribFormat(const Context *context, + angle::EntryPoint entryPoint, + GLuint attribindex, + GLint size, + VertexAttribType type, + GLboolean normalized, + GLuint relativeoffset) +{ + if (!ValidateVertexAttribFormatCommon(context, entryPoint, relativeoffset)) + { + return false; + } + + return ValidateFloatVertexFormat(context, entryPoint, attribindex, size, type); +} + +bool ValidateVertexAttribIFormat(const Context *context, + angle::EntryPoint entryPoint, + GLuint attribindex, + GLint size, + VertexAttribType type, + GLuint relativeoffset) +{ + if (!ValidateVertexAttribFormatCommon(context, entryPoint, relativeoffset)) + { + return false; + } + + return ValidateIntegerVertexFormat(context, entryPoint, attribindex, size, type); +} + +bool ValidateVertexAttribBinding(const Context *context, + angle::EntryPoint entryPoint, + GLuint attribIndex, + GLuint bindingIndex) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + // [OpenGL ES 3.1] Section 10.3.1 page 243: + // An INVALID_OPERATION error is generated if the default vertex array object is bound. + if (context->getState().getVertexArrayId().value == 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultVertexArray); + return false; + } + + const Caps &caps = context->getCaps(); + if (attribIndex >= static_cast(caps.maxVertexAttributes)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute); + return false; + } + + if (bindingIndex >= static_cast(caps.maxVertexAttribBindings)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings); + return false; + } + + return true; +} + +bool ValidateGetProgramResourceName(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLenum programInterface, + GLuint index, + GLsizei bufSize, + const GLsizei *length, + const GLchar *name) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + Program *programObject = GetValidProgram(context, entryPoint, program); + if (programObject == nullptr) + { + return false; + } + + if (!ValidateNamedProgramInterface(programInterface)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidProgramInterface); + return false; + } + + if (!ValidateProgramResourceIndex(programObject, programInterface, index)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidProgramResourceIndex); + return false; + } + + if (bufSize < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize); + return false; + } + + return true; +} + +bool ValidateDispatchCompute(const Context *context, + angle::EntryPoint entryPoint, + GLuint numGroupsX, + GLuint numGroupsY, + GLuint numGroupsZ) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + const State &state = context->getState(); + const ProgramExecutable *executable = state.getProgramExecutable(); + + if (executable == nullptr || !executable->hasLinkedShaderStage(ShaderType::Compute)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kNoActiveProgramWithComputeShader); + return false; + } + + const Caps &caps = context->getCaps(); + if (numGroupsX > static_cast(caps.maxComputeWorkGroupCount[0])) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsComputeWorkGroupCountX); + return false; + } + if (numGroupsY > static_cast(caps.maxComputeWorkGroupCount[1])) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsComputeWorkGroupCountY); + return false; + } + if (numGroupsZ > static_cast(caps.maxComputeWorkGroupCount[2])) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsComputeWorkGroupCountZ); + return false; + } + + return true; +} + +bool ValidateDispatchComputeIndirect(const Context *context, + angle::EntryPoint entryPoint, + GLintptr indirect) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + const State &state = context->getState(); + const ProgramExecutable *executable = state.getProgramExecutable(); + + if (executable == nullptr || !executable->hasLinkedShaderStage(ShaderType::Compute)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kNoActiveProgramWithComputeShader); + return false; + } + + if (indirect < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset); + return false; + } + + if ((indirect & (sizeof(GLuint) - 1)) != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kOffsetMustBeMultipleOfUint); + return false; + } + + Buffer *dispatchIndirectBuffer = state.getTargetBuffer(BufferBinding::DispatchIndirect); + if (!dispatchIndirectBuffer) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kDispatchIndirectBufferNotBound); + return false; + } + + CheckedNumeric checkedOffset(static_cast(indirect)); + auto checkedSum = checkedOffset + static_cast(3 * sizeof(GLuint)); + if (!checkedSum.IsValid() || + checkedSum.ValueOrDie() > static_cast(dispatchIndirectBuffer->getSize())) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInsufficientBufferSize); + return false; + } + + return true; +} + +bool ValidateBindImageTexture(const Context *context, + angle::EntryPoint entryPoint, + GLuint unit, + TextureID texture, + GLint level, + GLboolean layered, + GLint layer, + GLenum access, + GLenum format) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + GLuint maxImageUnits = static_cast(context->getCaps().maxImageUnits); + if (unit >= maxImageUnits) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxImageUnits); + return false; + } + + if (level < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeLevel); + return false; + } + + if (layer < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeLayer); + return false; + } + + if (access != GL_READ_ONLY && access != GL_WRITE_ONLY && access != GL_READ_WRITE) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidImageAccess); + return false; + } + + switch (format) + { + case GL_RGBA32F: + case GL_RGBA16F: + case GL_R32F: + case GL_RGBA32UI: + case GL_RGBA16UI: + case GL_RGBA8UI: + case GL_R32UI: + case GL_RGBA32I: + case GL_RGBA16I: + case GL_RGBA8I: + case GL_R32I: + case GL_RGBA8: + case GL_RGBA8_SNORM: + break; + default: + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidImageFormat); + return false; + } + + if (texture.value != 0) + { + Texture *tex = context->getTexture(texture); + + if (tex == nullptr) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kMissingTextureName); + return false; + } + + if (!tex->getImmutableFormat() && tex->getType() != gl::TextureType::Buffer) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kTextureIsNeitherImmutableNorTextureBuffer); + return false; + } + } + + return true; +} + +bool ValidateGetProgramResourceLocation(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLenum programInterface, + const GLchar *name) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + Program *programObject = GetValidProgram(context, entryPoint, program); + if (programObject == nullptr) + { + return false; + } + + if (!programObject->isLinked()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked); + return false; + } + + if (!ValidateLocationProgramInterface(programInterface)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidProgramInterface); + return false; + } + return true; +} + +bool ValidateGetProgramResourceiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLenum programInterface, + GLuint index, + GLsizei propCount, + const GLenum *props, + GLsizei bufSize, + const GLsizei *length, + const GLint *params) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + Program *programObject = GetValidProgram(context, entryPoint, program); + if (programObject == nullptr) + { + return false; + } + if (!ValidateProgramInterface(programInterface)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidProgramInterface); + return false; + } + if (propCount <= 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPropCount); + return false; + } + if (bufSize < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufSize); + return false; + } + if (!ValidateProgramResourceIndex(programObject, programInterface, index)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidProgramResourceIndex); + return false; + } + for (GLsizei i = 0; i < propCount; i++) + { + if (!ValidateProgramResourceProperty(context, entryPoint, props[i])) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidProgramResourceProperty); + return false; + } + if (!ValidateProgramResourcePropertyByInterface(props[i], programInterface)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInvalidPropertyForProgramInterface); + return false; + } + } + return true; +} + +bool ValidateGetProgramInterfaceiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLenum programInterface, + GLenum pname, + const GLint *params) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + Program *programObject = GetValidProgram(context, entryPoint, program); + if (programObject == nullptr) + { + return false; + } + + if (!ValidateProgramInterface(programInterface)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidProgramInterface); + return false; + } + + switch (pname) + { + case GL_ACTIVE_RESOURCES: + case GL_MAX_NAME_LENGTH: + case GL_MAX_NUM_ACTIVE_VARIABLES: + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname); + return false; + } + + if (pname == GL_MAX_NAME_LENGTH && programInterface == GL_ATOMIC_COUNTER_BUFFER) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kAtomicCounterResourceName); + return false; + } + + if (pname == GL_MAX_NUM_ACTIVE_VARIABLES) + { + switch (programInterface) + { + case GL_ATOMIC_COUNTER_BUFFER: + case GL_SHADER_STORAGE_BLOCK: + case GL_UNIFORM_BLOCK: + break; + + default: + context->validationError(entryPoint, GL_INVALID_OPERATION, + kMaxActiveVariablesInterface); + return false; + } + } + + return true; +} + +bool ValidateGetProgramInterfaceivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLenum programInterface, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params) +{ + UNIMPLEMENTED(); + return false; +} + +bool ValidateGenProgramPipelinesBase(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const ProgramPipelineID *pipelines) +{ + return ValidateGenOrDelete(context, entryPoint, n); +} + +bool ValidateDeleteProgramPipelinesBase(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const ProgramPipelineID *pipelines) +{ + return ValidateGenOrDelete(context, entryPoint, n); +} + +bool ValidateBindProgramPipelineBase(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipeline) +{ + if (!context->isProgramPipelineGenerated({pipeline})) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kObjectNotGenerated); + return false; + } + + return true; +} + +bool ValidateIsProgramPipelineBase(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipeline) +{ + return true; +} + +bool ValidateUseProgramStagesBase(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipeline, + GLbitfield stages, + ShaderProgramID programId) +{ + // GL_INVALID_VALUE is generated if shaders contains set bits that are not recognized, and is + // not the reserved value GL_ALL_SHADER_BITS. + GLbitfield knownShaderBits = + GL_VERTEX_SHADER_BIT | GL_FRAGMENT_SHADER_BIT | GL_COMPUTE_SHADER_BIT; + + if (context->getClientVersion() >= ES_3_2 || context->getExtensions().geometryShaderAny()) + { + knownShaderBits |= GL_GEOMETRY_SHADER_BIT; + } + + if (context->getClientVersion() >= ES_3_2 || context->getExtensions().tessellationShaderEXT) + { + knownShaderBits |= GL_TESS_CONTROL_SHADER_BIT; + knownShaderBits |= GL_TESS_EVALUATION_SHADER_BIT; + } + + if ((stages & ~knownShaderBits) && (stages != GL_ALL_SHADER_BITS)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kUnrecognizedShaderStageBit); + return false; + } + + // GL_INVALID_OPERATION is generated if pipeline is not a name previously returned from a call + // to glGenProgramPipelines or if such a name has been deleted by a call to + // glDeleteProgramPipelines. + if (!context->isProgramPipelineGenerated({pipeline})) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kObjectNotGenerated); + return false; + } + + // If program is zero, or refers to a program object with no valid shader executable for a given + // stage, it is as if the pipeline object has no programmable stage configured for the indicated + // shader stages. + if (programId.value == 0) + { + return true; + } + + Program *program = context->getProgramNoResolveLink(programId); + if (!program) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kProgramDoesNotExist); + return false; + } + + // GL_INVALID_OPERATION is generated if program refers to a program object that was not linked + // with its GL_PROGRAM_SEPARABLE status set. + // resolveLink() may not have been called if glCreateShaderProgramv() was not used and + // glDetachShader() was not called. + program->resolveLink(context); + if (!program->isSeparable()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotSeparable); + return false; + } + + // GL_INVALID_OPERATION is generated if program refers to a program object that has not been + // successfully linked. + if (!program->isLinked()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked); + return false; + } + + return true; +} + +bool ValidateActiveShaderProgramBase(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipeline, + ShaderProgramID programId) +{ + // An INVALID_OPERATION error is generated if pipeline is not a name returned from a previous + // call to GenProgramPipelines or if such a name has since been deleted by + // DeleteProgramPipelines. + if (!context->isProgramPipelineGenerated({pipeline})) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kObjectNotGenerated); + return false; + } + + // An INVALID_VALUE error is generated if program is not zero and is not the name of either a + // program or shader object. + if ((programId.value != 0) && !context->isProgram(programId) && !context->isShader(programId)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kProgramDoesNotExist); + return false; + } + + // An INVALID_OPERATION error is generated if program is the name of a shader object. + if (context->isShader(programId)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExpectedProgramName); + return false; + } + + // An INVALID_OPERATION error is generated if program is not zero and has not been linked, or + // was last linked unsuccessfully. The active program is not modified. + Program *program = context->getProgramNoResolveLink(programId); + if ((programId.value != 0) && !program->isLinked()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked); + return false; + } + + return true; +} + +bool ValidateCreateShaderProgramvBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderType type, + GLsizei count, + const GLchar *const *strings) +{ + switch (type) + { + case ShaderType::InvalidEnum: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShaderType); + return false; + case ShaderType::Vertex: + case ShaderType::Fragment: + case ShaderType::Compute: + break; + case ShaderType::Geometry: + if (!context->getExtensions().geometryShaderAny() && + context->getClientVersion() < ES_3_2) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShaderType); + return false; + } + break; + case ShaderType::TessControl: + case ShaderType::TessEvaluation: + if (!context->getExtensions().tessellationShaderEXT && + context->getClientVersion() < ES_3_2) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShaderType); + return false; + } + break; + default: + UNREACHABLE(); + } + + // GL_INVALID_VALUE is generated if count is negative. + if (count < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeCount); + return false; + } + + return true; +} + +bool ValidateCreateShaderProgramvBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderType type, + GLsizei count, + const GLchar **strings) +{ + const GLchar *const *tmpStrings = strings; + return ValidateCreateShaderProgramvBase(context, entryPoint, type, count, tmpStrings); +} + +bool ValidateGetProgramPipelineivBase(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipeline, + GLenum pname, + const GLint *params) +{ + // An INVALID_OPERATION error is generated if pipeline is not a name returned from a previous + // call to GenProgramPipelines or if such a name has since been deleted by + // DeleteProgramPipelines. + if ((pipeline.value == 0) || (!context->isProgramPipelineGenerated(pipeline))) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramPipelineDoesNotExist); + return false; + } + + // An INVALID_ENUM error is generated if pname is not ACTIVE_PROGRAM, + // INFO_LOG_LENGTH, VALIDATE_STATUS, or one of the type arguments in + // table 7.1. + switch (pname) + { + case GL_ACTIVE_PROGRAM: + case GL_INFO_LOG_LENGTH: + case GL_VALIDATE_STATUS: + case GL_VERTEX_SHADER: + case GL_FRAGMENT_SHADER: + case GL_COMPUTE_SHADER: + break; + case GL_GEOMETRY_SHADER: + return context->getExtensions().geometryShaderAny() || + context->getClientVersion() >= ES_3_2; + case GL_TESS_CONTROL_SHADER: + case GL_TESS_EVALUATION_SHADER: + return context->getExtensions().tessellationShaderEXT || + context->getClientVersion() >= ES_3_2; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname); + return false; + } + + return true; +} + +bool ValidateValidateProgramPipelineBase(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipeline) +{ + if (pipeline.value == 0) + { + return false; + } + + if (!context->isProgramPipelineGenerated(pipeline)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramPipelineDoesNotExist); + return false; + } + + return true; +} + +bool ValidateGetProgramPipelineInfoLogBase(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipeline, + GLsizei bufSize, + const GLsizei *length, + const GLchar *infoLog) +{ + if (bufSize < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize); + return false; + } + + if (!context->isProgramPipelineGenerated(pipeline)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kProgramPipelineDoesNotExist); + return false; + } + + return true; +} + +bool ValidateActiveShaderProgram(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked, + ShaderProgramID programPacked) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateActiveShaderProgramBase(context, entryPoint, pipelinePacked, programPacked); +} + +bool ValidateBindProgramPipeline(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateBindProgramPipelineBase(context, entryPoint, pipelinePacked); +} + +bool ValidateCreateShaderProgramv(const Context *context, + angle::EntryPoint entryPoint, + ShaderType typePacked, + GLsizei count, + const GLchar *const *strings) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateCreateShaderProgramvBase(context, entryPoint, typePacked, count, strings); +} + +bool ValidateDeleteProgramPipelines(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const ProgramPipelineID *pipelinesPacked) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateDeleteProgramPipelinesBase(context, entryPoint, n, pipelinesPacked); +} + +bool ValidateGenProgramPipelines(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const ProgramPipelineID *pipelinesPacked) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateGenProgramPipelinesBase(context, entryPoint, n, pipelinesPacked); +} + +bool ValidateGetProgramPipelineInfoLog(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked, + GLsizei bufSize, + const GLsizei *length, + const GLchar *infoLog) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateGetProgramPipelineInfoLogBase(context, entryPoint, pipelinePacked, bufSize, + length, infoLog); +} + +bool ValidateGetProgramPipelineiv(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked, + GLenum pname, + const GLint *params) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateGetProgramPipelineivBase(context, entryPoint, pipelinePacked, pname, params); +} + +bool ValidateIsProgramPipeline(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateIsProgramPipelineBase(context, entryPoint, pipelinePacked); +} + +bool ValidateProgramUniform1f(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLfloat v0) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniform1fBase(context, entryPoint, programPacked, locationPacked, v0); +} + +bool ValidateProgramUniform1fv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniform1fvBase(context, entryPoint, programPacked, locationPacked, count, + value); +} + +bool ValidateProgramUniform1i(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLint v0) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniform1iBase(context, entryPoint, programPacked, locationPacked, v0); +} + +bool ValidateProgramUniform1iv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniform1ivBase(context, entryPoint, programPacked, locationPacked, count, + value); +} + +bool ValidateProgramUniform1ui(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLuint v0) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniform1uiBase(context, entryPoint, programPacked, locationPacked, v0); +} + +bool ValidateProgramUniform1uiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniform1uivBase(context, entryPoint, programPacked, locationPacked, count, + value); +} + +bool ValidateProgramUniform2f(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLfloat v0, + GLfloat v1) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniform2fBase(context, entryPoint, programPacked, locationPacked, v0, v1); +} + +bool ValidateProgramUniform2fv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniform2fvBase(context, entryPoint, programPacked, locationPacked, count, + value); +} + +bool ValidateProgramUniform2i(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLint v0, + GLint v1) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniform2iBase(context, entryPoint, programPacked, locationPacked, v0, v1); +} + +bool ValidateProgramUniform2iv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniform2ivBase(context, entryPoint, programPacked, locationPacked, count, + value); +} + +bool ValidateProgramUniform2ui(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLuint v0, + GLuint v1) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniform2uiBase(context, entryPoint, programPacked, locationPacked, v0, + v1); +} + +bool ValidateProgramUniform2uiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniform2uivBase(context, entryPoint, programPacked, locationPacked, count, + value); +} + +bool ValidateProgramUniform3f(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLfloat v0, + GLfloat v1, + GLfloat v2) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniform3fBase(context, entryPoint, programPacked, locationPacked, v0, v1, + v2); +} + +bool ValidateProgramUniform3fv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniform3fvBase(context, entryPoint, programPacked, locationPacked, count, + value); +} + +bool ValidateProgramUniform3i(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLint v0, + GLint v1, + GLint v2) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniform3iBase(context, entryPoint, programPacked, locationPacked, v0, v1, + v2); +} + +bool ValidateProgramUniform3iv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniform3ivBase(context, entryPoint, programPacked, locationPacked, count, + value); +} + +bool ValidateProgramUniform3ui(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLuint v0, + GLuint v1, + GLuint v2) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniform3uiBase(context, entryPoint, programPacked, locationPacked, v0, v1, + v2); +} + +bool ValidateProgramUniform3uiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniform3uivBase(context, entryPoint, programPacked, locationPacked, count, + value); +} + +bool ValidateProgramUniform4f(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLfloat v0, + GLfloat v1, + GLfloat v2, + GLfloat v3) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniform4fBase(context, entryPoint, programPacked, locationPacked, v0, v1, + v2, v3); +} + +bool ValidateProgramUniform4fv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniform4fvBase(context, entryPoint, programPacked, locationPacked, count, + value); +} + +bool ValidateProgramUniform4i(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLint v0, + GLint v1, + GLint v2, + GLint v3) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniform4iBase(context, entryPoint, programPacked, locationPacked, v0, v1, + v2, v3); +} + +bool ValidateProgramUniform4iv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniform4ivBase(context, entryPoint, programPacked, locationPacked, count, + value); +} + +bool ValidateProgramUniform4ui(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniform4uiBase(context, entryPoint, programPacked, locationPacked, v0, v1, + v2, v3); +} + +bool ValidateProgramUniform4uiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniform4uivBase(context, entryPoint, programPacked, locationPacked, count, + value); +} + +bool ValidateProgramUniformMatrix2fv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniformMatrix2fvBase(context, entryPoint, programPacked, locationPacked, + count, transpose, value); +} + +bool ValidateProgramUniformMatrix2x3fv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniformMatrix2x3fvBase(context, entryPoint, programPacked, locationPacked, + count, transpose, value); +} + +bool ValidateProgramUniformMatrix2x4fv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniformMatrix2x4fvBase(context, entryPoint, programPacked, locationPacked, + count, transpose, value); +} + +bool ValidateProgramUniformMatrix3fv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniformMatrix3fvBase(context, entryPoint, programPacked, locationPacked, + count, transpose, value); +} + +bool ValidateProgramUniformMatrix3x2fv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniformMatrix3x2fvBase(context, entryPoint, programPacked, locationPacked, + count, transpose, value); +} + +bool ValidateProgramUniformMatrix3x4fv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniformMatrix3x4fvBase(context, entryPoint, programPacked, locationPacked, + count, transpose, value); +} + +bool ValidateProgramUniformMatrix4fv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniformMatrix4fvBase(context, entryPoint, programPacked, locationPacked, + count, transpose, value); +} + +bool ValidateProgramUniformMatrix4x2fv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniformMatrix4x2fvBase(context, entryPoint, programPacked, locationPacked, + count, transpose, value); +} + +bool ValidateProgramUniformMatrix4x3fv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateProgramUniformMatrix4x3fvBase(context, entryPoint, programPacked, locationPacked, + count, transpose, value); +} + +bool ValidateUseProgramStages(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked, + GLbitfield stages, + ShaderProgramID programPacked) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateUseProgramStagesBase(context, entryPoint, pipelinePacked, stages, programPacked); +} + +bool ValidateValidateProgramPipeline(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateValidateProgramPipelineBase(context, entryPoint, pipelinePacked); +} + +bool ValidateMemoryBarrier(const Context *context, + angle::EntryPoint entryPoint, + GLbitfield barriers) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + if (barriers == GL_ALL_BARRIER_BITS) + { + return true; + } + + GLbitfield supported_barrier_bits = + GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT | + GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_COMMAND_BARRIER_BIT | + GL_PIXEL_BUFFER_BARRIER_BIT | GL_TEXTURE_UPDATE_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT | + GL_FRAMEBUFFER_BARRIER_BIT | GL_TRANSFORM_FEEDBACK_BARRIER_BIT | + GL_ATOMIC_COUNTER_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT; + + if (context->getExtensions().bufferStorageEXT) + { + supported_barrier_bits |= GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT; + } + + if (barriers == 0 || (barriers & ~supported_barrier_bits) != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMemoryBarrierBit); + return false; + } + + return true; +} + +bool ValidateMemoryBarrierByRegion(const Context *context, + angle::EntryPoint entryPoint, + GLbitfield barriers) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + if (barriers == GL_ALL_BARRIER_BITS) + { + return true; + } + + GLbitfield supported_barrier_bits = GL_ATOMIC_COUNTER_BARRIER_BIT | GL_FRAMEBUFFER_BARRIER_BIT | + GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | + GL_SHADER_STORAGE_BARRIER_BIT | + GL_TEXTURE_FETCH_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT; + if (barriers == 0 || (barriers & ~supported_barrier_bits) != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMemoryBarrierBit); + return false; + } + + return true; +} + +bool ValidateSampleMaski(const Context *context, + angle::EntryPoint entryPoint, + GLuint maskNumber, + GLbitfield mask) +{ + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + + return ValidateSampleMaskiBase(context, entryPoint, maskNumber, mask); +} + +bool ValidateMinSampleShadingOES(const Context *context, + angle::EntryPoint entryPoint, + GLfloat value) +{ + if (!context->getExtensions().sampleShadingOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return true; +} + +bool ValidateFramebufferTextureCommon(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + TextureID texture, + GLint level) +{ + if (texture.value != 0) + { + Texture *tex = context->getTexture(texture); + + // [EXT_geometry_shader] Section 9.2.8 "Attaching Texture Images to a Framebuffer" + // An INVALID_VALUE error is generated if is not the name of a texture object. + // We put this validation before ValidateFramebufferTextureBase because it is an + // INVALID_OPERATION error for both FramebufferTexture2D and FramebufferTextureLayer: + // [OpenGL ES 3.1] Chapter 9.2.8 (FramebufferTexture2D) + // An INVALID_OPERATION error is generated if texture is not zero, and does not name an + // existing texture object of type matching textarget. + // [OpenGL ES 3.1 Chapter 9.2.8 (FramebufferTextureLayer) + // An INVALID_OPERATION error is generated if texture is non-zero and is not the name of a + // three-dimensional or two-dimensional array texture. + if (tex == nullptr) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidTextureName); + return false; + } + + if (!ValidMipLevel(context, tex->getType(), level)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel); + return false; + } + + // GLES spec 3.1, Section 9.2.8 "Attaching Texture Images to a Framebuffer" + // If textarget is TEXTURE_2D_MULTISAMPLE, then level must be zero. + if (tex->getType() == TextureType::_2DMultisample && level != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kLevelNotZero); + return false; + } + + // [OES_texture_storage_multisample_2d_array] Section 9.2.2 "Attaching Images to Framebuffer + // Objects" + // If texture is a two-dimensional multisample array texture, then level must be zero. + if (context->getExtensions().textureStorageMultisample2dArrayOES && + tex->getType() == TextureType::_2DMultisampleArray && level != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kLevelNotZero); + return false; + } + } + + if (!ValidateFramebufferTextureBase(context, entryPoint, target, attachment, texture, level)) + { + return false; + } + + return true; +} + +bool ValidateFramebufferTextureEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + TextureID texture, + GLint level) +{ + if (!context->getExtensions().geometryShaderEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kGeometryShaderExtensionNotEnabled); + return false; + } + + return ValidateFramebufferTextureCommon(context, entryPoint, target, attachment, texture, + level); +} + +bool ValidateFramebufferTextureOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + TextureID texture, + GLint level) +{ + if (!context->getExtensions().geometryShaderOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kGeometryShaderExtensionNotEnabled); + return false; + } + + return ValidateFramebufferTextureCommon(context, entryPoint, target, attachment, texture, + level); +} + +// GL_OES_texture_storage_multisample_2d_array +bool ValidateTexStorage3DMultisampleOES(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLsizei samples, + GLenum sizedinternalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedsamplelocations) +{ + if (!context->getExtensions().textureStorageMultisample2dArrayOES) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kMultisampleArrayExtensionRequired); + return false; + } + + if (target != TextureType::_2DMultisampleArray) + { + context->validationError(entryPoint, GL_INVALID_ENUM, + kTargetMustBeTexture2DMultisampleArrayOES); + return false; + } + + if (width < 1 || height < 1 || depth < 1) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeSize); + return false; + } + + if (depth > context->getCaps().maxArrayTextureLayers) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kTextureDepthOutOfRange); + return false; + } + + return ValidateTexStorageMultisample(context, entryPoint, target, samples, sizedinternalformat, + width, height); +} + +bool ValidateTexStorageMem3DMultisampleEXT(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLsizei samples, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedSampleLocations, + MemoryObjectID memory, + GLuint64 offset) +{ + if (!context->getExtensions().memoryObjectEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + UNIMPLEMENTED(); + return false; +} + +bool ValidateGetProgramResourceLocationIndexEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLenum programInterface, + const char *name) +{ + if (!context->getExtensions().blendFuncExtendedEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + if (context->getClientVersion() < ES_3_1) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); + return false; + } + if (programInterface != GL_PROGRAM_OUTPUT) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kProgramInterfaceMustBeProgramOutput); + return false; + } + Program *programObject = GetValidProgram(context, entryPoint, program); + if (!programObject) + { + return false; + } + if (!programObject->isLinked()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked); + return false; + } + return true; +} + +// GL_OES_texture_buffer +bool ValidateTexBufferOES(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum internalformat, + BufferID bufferPacked) +{ + if (!context->getExtensions().textureBufferOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kTextureBufferExtensionNotAvailable); + return false; + } + + return ValidateTexBufferBase(context, entryPoint, target, internalformat, bufferPacked); +} + +bool ValidateTexBufferRangeOES(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum internalformat, + BufferID bufferPacked, + GLintptr offset, + GLsizeiptr size) +{ + if (!context->getExtensions().textureBufferOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kTextureBufferExtensionNotAvailable); + return false; + } + + return ValidateTexBufferRangeBase(context, entryPoint, target, internalformat, bufferPacked, + offset, size); +} + +// GL_EXT_texture_buffer +bool ValidateTexBufferEXT(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum internalformat, + BufferID bufferPacked) +{ + if (!context->getExtensions().textureBufferEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kTextureBufferExtensionNotAvailable); + return false; + } + + return ValidateTexBufferBase(context, entryPoint, target, internalformat, bufferPacked); +} + +bool ValidateTexBufferRangeEXT(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum internalformat, + BufferID bufferPacked, + GLintptr offset, + GLsizeiptr size) +{ + if (!context->getExtensions().textureBufferEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kTextureBufferExtensionNotAvailable); + return false; + } + + return ValidateTexBufferRangeBase(context, entryPoint, target, internalformat, bufferPacked, + offset, size); +} + +bool ValidateTexBufferBase(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum internalformat, + BufferID bufferPacked) +{ + if (target != TextureType::Buffer) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kTextureBufferTarget); + return false; + } + + switch (internalformat) + { + case GL_R8: + case GL_R16F: + case GL_R32F: + case GL_R8I: + case GL_R16I: + case GL_R32I: + case GL_R8UI: + case GL_R16UI: + case GL_R32UI: + case GL_RG8: + case GL_RG16F: + case GL_RG32F: + case GL_RG8I: + case GL_RG16I: + case GL_RG32I: + case GL_RG8UI: + case GL_RG16UI: + case GL_RG32UI: + case GL_RGB32F: + case GL_RGB32I: + case GL_RGB32UI: + case GL_RGBA8: + case GL_RGBA16F: + case GL_RGBA32F: + case GL_RGBA8I: + case GL_RGBA16I: + case GL_RGBA32I: + case GL_RGBA8UI: + case GL_RGBA16UI: + case GL_RGBA32UI: + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kTextureBufferInternalFormat); + return false; + } + + if (bufferPacked.value != 0) + { + if (!context->isBufferGenerated(bufferPacked)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kTextureBufferInvalidBuffer); + return false; + } + } + + return true; +} + +bool ValidateTexBufferRangeBase(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum internalformat, + BufferID bufferPacked, + GLintptr offset, + GLsizeiptr size) +{ + const Caps &caps = context->getCaps(); + + if (offset < 0 || (offset % caps.textureBufferOffsetAlignment) != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kTextureBufferOffsetAlignment); + return false; + } + if (size <= 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kTextureBufferSize); + return false; + } + const Buffer *buffer = context->getBuffer(bufferPacked); + + if (!buffer) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferNotBound); + return false; + } + + if (offset + size > buffer->getSize()) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kTextureBufferSizeOffset); + return false; + } + + return ValidateTexBufferBase(context, entryPoint, target, internalformat, bufferPacked); +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/validationES31.h b/gfx/angle/checkout/src/libANGLE/validationES31.h new file mode 100644 index 0000000000..c41cedf0da --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationES31.h @@ -0,0 +1,300 @@ +// +// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// validationES31.h: +// Inlined validation functions for OpenGL ES 3.1 entry points. + +#ifndef LIBANGLE_VALIDATION_ES31_H_ +#define LIBANGLE_VALIDATION_ES31_H_ + +#include "libANGLE/ErrorStrings.h" +#include "libANGLE/validationES31_autogen.h" + +namespace gl +{ + +bool ValidateTexBufferBase(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum internalformat, + BufferID bufferPacked); +bool ValidateTexBufferRangeBase(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum internalformat, + BufferID bufferPacked, + GLintptr offset, + GLsizeiptr size); + +// GL_EXT_multi_draw_indirect +bool ValidateMultiDrawIndirectBase(const Context *context, + angle::EntryPoint entryPoint, + GLsizei drawcount, + GLsizei stride); + +// GL_EXT_separate_shader_objects +bool ValidateActiveShaderProgramBase(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked, + ShaderProgramID programPacked); +bool ValidateBindProgramPipelineBase(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked); +bool ValidateCreateShaderProgramvBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderType typePacked, + GLsizei count, + const GLchar **strings); +bool ValidateDeleteProgramPipelinesBase(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const ProgramPipelineID *pipelinesPacked); +bool ValidateGenProgramPipelinesBase(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const ProgramPipelineID *pipelinesPacked); +bool ValidateGetProgramPipelineInfoLogBase(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked, + GLsizei bufSize, + const GLsizei *length, + const GLchar *infoLog); +bool ValidateGetProgramPipelineivBase(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked, + GLenum pname, + const GLint *params); +bool ValidateIsProgramPipelineBase(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked); +bool ValidateProgramParameteriBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLenum pname, + GLint value); +bool ValidateProgramUniform1fBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLfloat v0); +bool ValidateProgramUniform1fvBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value); +bool ValidateProgramUniform1iBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLint v0); +bool ValidateProgramUniform1ivBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value); +bool ValidateProgramUniform1uiBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLuint v0); +bool ValidateProgramUniform1uivBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value); +bool ValidateProgramUniform2fBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLfloat v0, + GLfloat v1); +bool ValidateProgramUniform2fvBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value); +bool ValidateProgramUniform2iBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLint v0, + GLint v1); +bool ValidateProgramUniform2ivBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value); +bool ValidateProgramUniform2uiBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLuint v0, + GLuint v1); +bool ValidateProgramUniform2uivBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value); +bool ValidateProgramUniform3fBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLfloat v0, + GLfloat v1, + GLfloat v2); +bool ValidateProgramUniform3fvBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value); +bool ValidateProgramUniform3iBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLint v0, + GLint v1, + GLint v2); +bool ValidateProgramUniform3ivBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value); +bool ValidateProgramUniform3uiBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLuint v0, + GLuint v1, + GLuint v2); +bool ValidateProgramUniform3uivBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value); +bool ValidateProgramUniform4fBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLfloat v0, + GLfloat v1, + GLfloat v2, + GLfloat v3); +bool ValidateProgramUniform4fvBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value); +bool ValidateProgramUniform4iBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLint v0, + GLint v1, + GLint v2, + GLint v3); +bool ValidateProgramUniform4ivBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value); +bool ValidateProgramUniform4uiBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3); +bool ValidateProgramUniform4uivBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value); +bool ValidateProgramUniformMatrix2fvBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix2x3fvBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix2x4fvBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix3fvBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix3x2fvBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix3x4fvBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix4fvBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix4x2fvBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix4x3fvBase(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateUseProgramStagesBase(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked, + GLbitfield stages, + ShaderProgramID programPacked); +bool ValidateValidateProgramPipelineBase(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked); +} // namespace gl + +#endif // LIBANGLE_VALIDATION_ES31_H_ diff --git a/gfx/angle/checkout/src/libANGLE/validationES31_autogen.h b/gfx/angle/checkout/src/libANGLE/validationES31_autogen.h new file mode 100644 index 0000000000..3e2adb50d0 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationES31_autogen.h @@ -0,0 +1,415 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// validationES31_autogen.h: +// Validation functions for the OpenGL ES 3.1 entry points. + +#ifndef LIBANGLE_VALIDATION_ES31_AUTOGEN_H_ +#define LIBANGLE_VALIDATION_ES31_AUTOGEN_H_ + +#include "common/PackedEnums.h" +#include "common/entry_points_enum_autogen.h" + +namespace gl +{ +class Context; + +bool ValidateActiveShaderProgram(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked, + ShaderProgramID programPacked); +bool ValidateBindImageTexture(const Context *context, + angle::EntryPoint entryPoint, + GLuint unit, + TextureID texturePacked, + GLint level, + GLboolean layered, + GLint layer, + GLenum access, + GLenum format); +bool ValidateBindProgramPipeline(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked); +bool ValidateBindVertexBuffer(const Context *context, + angle::EntryPoint entryPoint, + GLuint bindingindex, + BufferID bufferPacked, + GLintptr offset, + GLsizei stride); +bool ValidateCreateShaderProgramv(const Context *context, + angle::EntryPoint entryPoint, + ShaderType typePacked, + GLsizei count, + const GLchar *const *strings); +bool ValidateDeleteProgramPipelines(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const ProgramPipelineID *pipelinesPacked); +bool ValidateDispatchCompute(const Context *context, + angle::EntryPoint entryPoint, + GLuint num_groups_x, + GLuint num_groups_y, + GLuint num_groups_z); +bool ValidateDispatchComputeIndirect(const Context *context, + angle::EntryPoint entryPoint, + GLintptr indirect); +bool ValidateDrawArraysIndirect(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + const void *indirect); +bool ValidateDrawElementsIndirect(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + DrawElementsType typePacked, + const void *indirect); +bool ValidateFramebufferParameteri(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum pname, + GLint param); +bool ValidateGenProgramPipelines(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const ProgramPipelineID *pipelinesPacked); +bool ValidateGetBooleani_v(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index, + const GLboolean *data); +bool ValidateGetFramebufferParameteriv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum pname, + const GLint *params); +bool ValidateGetMultisamplefv(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLuint index, + const GLfloat *val); +bool ValidateGetProgramInterfaceiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLenum programInterface, + GLenum pname, + const GLint *params); +bool ValidateGetProgramPipelineInfoLog(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked, + GLsizei bufSize, + const GLsizei *length, + const GLchar *infoLog); +bool ValidateGetProgramPipelineiv(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked, + GLenum pname, + const GLint *params); +bool ValidateGetProgramResourceIndex(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLenum programInterface, + const GLchar *name); +bool ValidateGetProgramResourceLocation(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLenum programInterface, + const GLchar *name); +bool ValidateGetProgramResourceName(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLenum programInterface, + GLuint index, + GLsizei bufSize, + const GLsizei *length, + const GLchar *name); +bool ValidateGetProgramResourceiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLenum programInterface, + GLuint index, + GLsizei propCount, + const GLenum *props, + GLsizei count, + const GLsizei *length, + const GLint *params); +bool ValidateGetTexLevelParameterfv(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLenum pname, + const GLfloat *params); +bool ValidateGetTexLevelParameteriv(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLenum pname, + const GLint *params); +bool ValidateIsProgramPipeline(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked); +bool ValidateMemoryBarrier(const Context *context, + angle::EntryPoint entryPoint, + GLbitfield barriers); +bool ValidateMemoryBarrierByRegion(const Context *context, + angle::EntryPoint entryPoint, + GLbitfield barriers); +bool ValidateProgramUniform1f(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLfloat v0); +bool ValidateProgramUniform1fv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value); +bool ValidateProgramUniform1i(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLint v0); +bool ValidateProgramUniform1iv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value); +bool ValidateProgramUniform1ui(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLuint v0); +bool ValidateProgramUniform1uiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value); +bool ValidateProgramUniform2f(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLfloat v0, + GLfloat v1); +bool ValidateProgramUniform2fv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value); +bool ValidateProgramUniform2i(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLint v0, + GLint v1); +bool ValidateProgramUniform2iv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value); +bool ValidateProgramUniform2ui(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLuint v0, + GLuint v1); +bool ValidateProgramUniform2uiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value); +bool ValidateProgramUniform3f(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLfloat v0, + GLfloat v1, + GLfloat v2); +bool ValidateProgramUniform3fv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value); +bool ValidateProgramUniform3i(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLint v0, + GLint v1, + GLint v2); +bool ValidateProgramUniform3iv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value); +bool ValidateProgramUniform3ui(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLuint v0, + GLuint v1, + GLuint v2); +bool ValidateProgramUniform3uiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value); +bool ValidateProgramUniform4f(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLfloat v0, + GLfloat v1, + GLfloat v2, + GLfloat v3); +bool ValidateProgramUniform4fv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value); +bool ValidateProgramUniform4i(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLint v0, + GLint v1, + GLint v2, + GLint v3); +bool ValidateProgramUniform4iv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value); +bool ValidateProgramUniform4ui(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3); +bool ValidateProgramUniform4uiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value); +bool ValidateProgramUniformMatrix2fv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix2x3fv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix2x4fv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix3fv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix3x2fv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix3x4fv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix4fv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix4x2fv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix4x3fv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateSampleMaski(const Context *context, + angle::EntryPoint entryPoint, + GLuint maskNumber, + GLbitfield mask); +bool ValidateTexStorage2DMultisample(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations); +bool ValidateUseProgramStages(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked, + GLbitfield stages, + ShaderProgramID programPacked); +bool ValidateValidateProgramPipeline(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked); +bool ValidateVertexAttribBinding(const Context *context, + angle::EntryPoint entryPoint, + GLuint attribindex, + GLuint bindingindex); +bool ValidateVertexAttribFormat(const Context *context, + angle::EntryPoint entryPoint, + GLuint attribindex, + GLint size, + VertexAttribType typePacked, + GLboolean normalized, + GLuint relativeoffset); +bool ValidateVertexAttribIFormat(const Context *context, + angle::EntryPoint entryPoint, + GLuint attribindex, + GLint size, + VertexAttribType typePacked, + GLuint relativeoffset); +bool ValidateVertexBindingDivisor(const Context *context, + angle::EntryPoint entryPoint, + GLuint bindingindex, + GLuint divisor); +} // namespace gl + +#endif // LIBANGLE_VALIDATION_ES31_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/validationES32.cpp b/gfx/angle/checkout/src/libANGLE/validationES32.cpp new file mode 100644 index 0000000000..b7d412393b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationES32.cpp @@ -0,0 +1,628 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// validationES32.cpp: Validation functions for OpenGL ES 3.2 entry point parameters + +#include "libANGLE/validationES32_autogen.h" + +#include "libANGLE/Context.h" +#include "libANGLE/ErrorStrings.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/VertexArray.h" +#include "libANGLE/validationES.h" +#include "libANGLE/validationES2_autogen.h" +#include "libANGLE/validationES31.h" +#include "libANGLE/validationES31_autogen.h" +#include "libANGLE/validationES3_autogen.h" + +#include "common/utilities.h" + +using namespace angle; + +namespace gl +{ +using namespace err; + +bool ValidateBlendBarrier(const Context *context, angle::EntryPoint entryPoint) +{ + return true; +} + +bool ValidateBlendEquationSeparatei(const Context *context, + angle::EntryPoint entryPoint, + GLuint buf, + GLenum modeRGB, + GLenum modeAlpha) +{ + if (buf >= static_cast(context->getCaps().maxDrawBuffers)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxDrawBuffers); + return false; + } + + if (!ValidateBlendEquationSeparate(context, entryPoint, modeRGB, modeAlpha)) + { + // error already generated + return false; + } + + return true; +} + +bool ValidateBlendEquationi(const Context *context, + angle::EntryPoint entryPoint, + GLuint buf, + GLenum mode) +{ + if (buf >= static_cast(context->getCaps().maxDrawBuffers)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxDrawBuffers); + return false; + } + + if (!ValidateBlendEquation(context, entryPoint, mode)) + { + // error already generated + return false; + } + + return true; +} + +bool ValidateBlendFuncSeparatei(const Context *context, + angle::EntryPoint entryPoint, + GLuint buf, + GLenum srcRGB, + GLenum dstRGB, + GLenum srcAlpha, + GLenum dstAlpha) +{ + if (buf >= static_cast(context->getCaps().maxDrawBuffers)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxDrawBuffers); + return false; + } + + if (!ValidateBlendFuncSeparate(context, entryPoint, srcRGB, dstRGB, srcAlpha, dstAlpha)) + { + // error already generated + return false; + } + + return true; +} + +bool ValidateBlendFunci(const Context *context, + angle::EntryPoint entryPoint, + GLuint buf, + GLenum src, + GLenum dst) +{ + if (buf >= static_cast(context->getCaps().maxDrawBuffers)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxDrawBuffers); + return false; + } + + if (!ValidateBlendFunc(context, entryPoint, src, dst)) + { + // error already generated + return false; + } + + return true; +} + +bool ValidateColorMaski(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLboolean r, + GLboolean g, + GLboolean b, + GLboolean a) +{ + if (index >= static_cast(context->getCaps().maxDrawBuffers)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer); + return false; + } + + return true; +} + +bool ValidateCopyImageSubData(const Context *context, + angle::EntryPoint entryPoint, + GLuint srcName, + GLenum srcTarget, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLuint dstName, + GLenum dstTarget, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth) +{ + if (context->getClientVersion() < ES_3_2) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES32Required); + return false; + } + + return ValidateCopyImageSubDataBase(context, entryPoint, srcName, srcTarget, srcLevel, srcX, + srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ, + srcWidth, srcHeight, srcDepth); +} + +bool ValidateDebugMessageCallback(const Context *context, + angle::EntryPoint entryPoint, + GLDEBUGPROC callback, + const void *userParam) +{ + return true; +} + +bool ValidateDebugMessageControl(const Context *context, + angle::EntryPoint entryPoint, + GLenum source, + GLenum type, + GLenum severity, + GLsizei count, + const GLuint *ids, + GLboolean enabled) +{ + return true; +} + +bool ValidateDebugMessageInsert(const Context *context, + angle::EntryPoint entryPoint, + GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar *buf) +{ + return true; +} + +bool ValidateDisablei(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index) +{ + switch (target) + { + case GL_BLEND: + if (index >= static_cast(context->getCaps().maxDrawBuffers)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer); + return false; + } + break; + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, target); + return false; + } + return true; +} + +bool ValidateDrawElementsBaseVertex(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLsizei count, + DrawElementsType type, + const void *indices, + GLint basevertex) +{ + return ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 1); +} + +bool ValidateDrawElementsInstancedBaseVertex(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLsizei count, + DrawElementsType type, + const void *indices, + GLsizei instancecount, + GLint basevertex) +{ + return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices, + instancecount); +} + +bool ValidateDrawRangeElementsBaseVertex(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLuint start, + GLuint end, + GLsizei count, + DrawElementsType type, + const void *indices, + GLint basevertex) +{ + if (end < start) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidElementRange); + return false; + } + + if (!ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 0)) + { + return false; + } + + // Skip range checks for no-op calls. + if (count <= 0) + { + return true; + } + + return true; +} + +bool ValidateEnablei(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index) +{ + switch (target) + { + case GL_BLEND: + if (index >= static_cast(context->getCaps().maxDrawBuffers)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer); + return false; + } + break; + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, target); + return false; + } + return true; +} + +bool ValidateFramebufferTexture(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + TextureID texture, + GLint level) +{ + return true; +} + +bool ValidateGetDebugMessageLog(const Context *context, + angle::EntryPoint entryPoint, + GLuint count, + GLsizei bufSize, + const GLenum *sources, + const GLenum *types, + const GLuint *ids, + const GLenum *severities, + const GLsizei *lengths, + const GLchar *messageLog) +{ + return true; +} + +bool ValidateGetGraphicsResetStatus(const Context *context, angle::EntryPoint entryPoint) +{ + return true; +} + +bool ValidateGetObjectLabel(const Context *context, + angle::EntryPoint entryPoint, + GLenum identifier, + GLuint name, + GLsizei bufSize, + const GLsizei *length, + const GLchar *label) +{ + return true; +} + +bool ValidateGetObjectPtrLabel(const Context *context, + angle::EntryPoint entryPoint, + const void *ptr, + GLsizei bufSize, + const GLsizei *length, + const GLchar *label) +{ + return true; +} + +bool ValidateGetPointerv(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + void *const *params) +{ + Version clientVersion = context->getClientVersion(); + + if ((clientVersion == ES_1_0) || (clientVersion == ES_1_1)) + { + switch (pname) + { + case GL_VERTEX_ARRAY_POINTER: + case GL_NORMAL_ARRAY_POINTER: + case GL_COLOR_ARRAY_POINTER: + case GL_TEXTURE_COORD_ARRAY_POINTER: + case GL_POINT_SIZE_ARRAY_POINTER_OES: + return true; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPointerQuery); + return false; + } + } + else if (clientVersion == ES_3_2) + { + switch (pname) + { + case GL_DEBUG_CALLBACK_FUNCTION: + case GL_DEBUG_CALLBACK_USER_PARAM: + return true; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPointerQuery); + return false; + } + } + else + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES1or32Required); + return false; + } +} + +bool ValidateGetSamplerParameterIiv(const Context *context, + angle::EntryPoint entryPoint, + SamplerID sampler, + GLenum pname, + const GLint *params) +{ + return true; +} + +bool ValidateGetSamplerParameterIuiv(const Context *context, + angle::EntryPoint entryPoint, + SamplerID sampler, + GLenum pname, + const GLuint *params) +{ + return true; +} + +bool ValidateGetTexParameterIiv(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + const GLint *params) +{ + return true; +} + +bool ValidateGetTexParameterIuiv(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + const GLuint *params) +{ + return true; +} + +bool ValidateGetnUniformfv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + const GLfloat *params) +{ + return ValidateSizedGetUniform(context, entryPoint, program, location, bufSize, nullptr); +} + +bool ValidateGetnUniformiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + const GLint *params) +{ + return ValidateSizedGetUniform(context, entryPoint, program, location, bufSize, nullptr); +} + +bool ValidateGetnUniformuiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + const GLuint *params) +{ + return ValidateSizedGetUniform(context, entryPoint, program, location, bufSize, nullptr); +} + +bool ValidateIsEnabledi(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index) +{ + switch (target) + { + case GL_BLEND: + if (index >= static_cast(context->getCaps().maxDrawBuffers)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer); + return false; + } + break; + default: + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, target); + return false; + } + return true; +} + +bool ValidateMinSampleShading(const Context *context, angle::EntryPoint entryPoint, GLfloat value) +{ + return true; +} + +bool ValidateObjectLabel(const Context *context, + angle::EntryPoint entryPoint, + GLenum identifier, + GLuint name, + GLsizei length, + const GLchar *label) +{ + return true; +} + +bool ValidateObjectPtrLabel(const Context *context, + angle::EntryPoint entryPoint, + const void *ptr, + GLsizei length, + const GLchar *label) +{ + return true; +} + +bool ValidatePatchParameteri(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLint value) +{ + return true; +} + +bool ValidatePopDebugGroup(const Context *context, angle::EntryPoint entryPoint) +{ + return true; +} + +bool ValidatePrimitiveBoundingBox(const Context *context, + angle::EntryPoint entryPoint, + GLfloat minX, + GLfloat minY, + GLfloat minZ, + GLfloat minW, + GLfloat maxX, + GLfloat maxY, + GLfloat maxZ, + GLfloat maxW) +{ + return true; +} + +bool ValidatePushDebugGroup(const Context *context, + angle::EntryPoint entryPoint, + GLenum source, + GLuint id, + GLsizei length, + const GLchar *message) +{ + return true; +} + +bool ValidateReadnPixels(const Context *context, + angle::EntryPoint entryPoint, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *data) +{ + return true; +} + +bool ValidateSamplerParameterIiv(const Context *context, + angle::EntryPoint entryPoint, + SamplerID sampler, + GLenum pname, + const GLint *param) +{ + return true; +} + +bool ValidateSamplerParameterIuiv(const Context *context, + angle::EntryPoint entryPoint, + SamplerID sampler, + GLenum pname, + const GLuint *param) +{ + return true; +} + +bool ValidateTexBuffer(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum internalformat, + BufferID buffer) +{ + if (context->getClientVersion() < ES_3_2) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES32Required); + return false; + } + + return ValidateTexBufferBase(context, entryPoint, target, internalformat, buffer); +} + +bool ValidateTexBufferRange(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLenum internalformat, + BufferID buffer, + GLintptr offset, + GLsizeiptr size) +{ + if (context->getClientVersion() < ES_3_2) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES32Required); + return false; + } + + return ValidateTexBufferRangeBase(context, entryPoint, target, internalformat, buffer, offset, + size); +} + +bool ValidateTexParameterIiv(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + const GLint *params) +{ + return true; +} + +bool ValidateTexParameterIuiv(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + const GLuint *params) +{ + return true; +} + +bool ValidateTexStorage3DMultisample(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedsamplelocations) +{ + return true; +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/validationES32.h b/gfx/angle/checkout/src/libANGLE/validationES32.h new file mode 100644 index 0000000000..674bc81d06 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationES32.h @@ -0,0 +1,20 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// validationES32.h: +// Inlined validation functions for OpenGL ES 3.2 entry points. + +#ifndef LIBANGLE_VALIDATION_ES32_H_ +#define LIBANGLE_VALIDATION_ES32_H_ + +#include "libANGLE/ErrorStrings.h" +#include "libANGLE/validationES32_autogen.h" + +namespace gl +{ +// Nothing here yet. +} // namespace gl + +#endif // LIBANGLE_VALIDATION_ES32_H_ diff --git a/gfx/angle/checkout/src/libANGLE/validationES32_autogen.h b/gfx/angle/checkout/src/libANGLE/validationES32_autogen.h new file mode 100644 index 0000000000..171f94d55c --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationES32_autogen.h @@ -0,0 +1,281 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// validationES32_autogen.h: +// Validation functions for the OpenGL ES 3.2 entry points. + +#ifndef LIBANGLE_VALIDATION_ES32_AUTOGEN_H_ +#define LIBANGLE_VALIDATION_ES32_AUTOGEN_H_ + +#include "common/PackedEnums.h" +#include "common/entry_points_enum_autogen.h" + +namespace gl +{ +class Context; + +bool ValidateBlendBarrier(const Context *context, angle::EntryPoint entryPoint); +bool ValidateBlendEquationSeparatei(const Context *context, + angle::EntryPoint entryPoint, + GLuint buf, + GLenum modeRGB, + GLenum modeAlpha); +bool ValidateBlendEquationi(const Context *context, + angle::EntryPoint entryPoint, + GLuint buf, + GLenum mode); +bool ValidateBlendFuncSeparatei(const Context *context, + angle::EntryPoint entryPoint, + GLuint buf, + GLenum srcRGB, + GLenum dstRGB, + GLenum srcAlpha, + GLenum dstAlpha); +bool ValidateBlendFunci(const Context *context, + angle::EntryPoint entryPoint, + GLuint buf, + GLenum src, + GLenum dst); +bool ValidateColorMaski(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLboolean r, + GLboolean g, + GLboolean b, + GLboolean a); +bool ValidateCopyImageSubData(const Context *context, + angle::EntryPoint entryPoint, + GLuint srcName, + GLenum srcTarget, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLuint dstName, + GLenum dstTarget, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth); +bool ValidateDebugMessageCallback(const Context *context, + angle::EntryPoint entryPoint, + GLDEBUGPROC callback, + const void *userParam); +bool ValidateDebugMessageControl(const Context *context, + angle::EntryPoint entryPoint, + GLenum source, + GLenum type, + GLenum severity, + GLsizei count, + const GLuint *ids, + GLboolean enabled); +bool ValidateDebugMessageInsert(const Context *context, + angle::EntryPoint entryPoint, + GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar *buf); +bool ValidateDisablei(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index); +bool ValidateDrawElementsBaseVertex(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLint basevertex); +bool ValidateDrawElementsInstancedBaseVertex(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLsizei instancecount, + GLint basevertex); +bool ValidateDrawRangeElementsBaseVertex(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + GLuint start, + GLuint end, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLint basevertex); +bool ValidateEnablei(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index); +bool ValidateFramebufferTexture(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + TextureID texturePacked, + GLint level); +bool ValidateGetDebugMessageLog(const Context *context, + angle::EntryPoint entryPoint, + GLuint count, + GLsizei bufSize, + const GLenum *sources, + const GLenum *types, + const GLuint *ids, + const GLenum *severities, + const GLsizei *lengths, + const GLchar *messageLog); +bool ValidateGetGraphicsResetStatus(const Context *context, angle::EntryPoint entryPoint); +bool ValidateGetObjectLabel(const Context *context, + angle::EntryPoint entryPoint, + GLenum identifier, + GLuint name, + GLsizei bufSize, + const GLsizei *length, + const GLchar *label); +bool ValidateGetObjectPtrLabel(const Context *context, + angle::EntryPoint entryPoint, + const void *ptr, + GLsizei bufSize, + const GLsizei *length, + const GLchar *label); +bool ValidateGetPointerv(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + void *const *params); +bool ValidateGetSamplerParameterIiv(const Context *context, + angle::EntryPoint entryPoint, + SamplerID samplerPacked, + GLenum pname, + const GLint *params); +bool ValidateGetSamplerParameterIuiv(const Context *context, + angle::EntryPoint entryPoint, + SamplerID samplerPacked, + GLenum pname, + const GLuint *params); +bool ValidateGetTexParameterIiv(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + const GLint *params); +bool ValidateGetTexParameterIuiv(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + const GLuint *params); +bool ValidateGetnUniformfv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + const GLfloat *params); +bool ValidateGetnUniformiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + const GLint *params); +bool ValidateGetnUniformuiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + const GLuint *params); +bool ValidateIsEnabledi(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index); +bool ValidateMinSampleShading(const Context *context, angle::EntryPoint entryPoint, GLfloat value); +bool ValidateObjectLabel(const Context *context, + angle::EntryPoint entryPoint, + GLenum identifier, + GLuint name, + GLsizei length, + const GLchar *label); +bool ValidateObjectPtrLabel(const Context *context, + angle::EntryPoint entryPoint, + const void *ptr, + GLsizei length, + const GLchar *label); +bool ValidatePatchParameteri(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLint value); +bool ValidatePopDebugGroup(const Context *context, angle::EntryPoint entryPoint); +bool ValidatePrimitiveBoundingBox(const Context *context, + angle::EntryPoint entryPoint, + GLfloat minX, + GLfloat minY, + GLfloat minZ, + GLfloat minW, + GLfloat maxX, + GLfloat maxY, + GLfloat maxZ, + GLfloat maxW); +bool ValidatePushDebugGroup(const Context *context, + angle::EntryPoint entryPoint, + GLenum source, + GLuint id, + GLsizei length, + const GLchar *message); +bool ValidateReadnPixels(const Context *context, + angle::EntryPoint entryPoint, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *data); +bool ValidateSamplerParameterIiv(const Context *context, + angle::EntryPoint entryPoint, + SamplerID samplerPacked, + GLenum pname, + const GLint *param); +bool ValidateSamplerParameterIuiv(const Context *context, + angle::EntryPoint entryPoint, + SamplerID samplerPacked, + GLenum pname, + const GLuint *param); +bool ValidateTexBuffer(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum internalformat, + BufferID bufferPacked); +bool ValidateTexBufferRange(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum internalformat, + BufferID bufferPacked, + GLintptr offset, + GLsizeiptr size); +bool ValidateTexParameterIiv(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + const GLint *params); +bool ValidateTexParameterIuiv(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + const GLuint *params); +bool ValidateTexStorage3DMultisample(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedsamplelocations); +} // namespace gl + +#endif // LIBANGLE_VALIDATION_ES32_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/validationES3_autogen.h b/gfx/angle/checkout/src/libANGLE/validationES3_autogen.h new file mode 100644 index 0000000000..10465c63f5 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationES3_autogen.h @@ -0,0 +1,578 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// validationES3_autogen.h: +// Validation functions for the OpenGL ES 3.0 entry points. + +#ifndef LIBANGLE_VALIDATION_ES3_AUTOGEN_H_ +#define LIBANGLE_VALIDATION_ES3_AUTOGEN_H_ + +#include "common/PackedEnums.h" +#include "common/entry_points_enum_autogen.h" + +namespace gl +{ +class Context; + +bool ValidateBeginQuery(const Context *context, + angle::EntryPoint entryPoint, + QueryType targetPacked, + QueryID idPacked); +bool ValidateBeginTransformFeedback(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode primitiveModePacked); +bool ValidateBindBufferBase(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding targetPacked, + GLuint index, + BufferID bufferPacked); +bool ValidateBindBufferRange(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding targetPacked, + GLuint index, + BufferID bufferPacked, + GLintptr offset, + GLsizeiptr size); +bool ValidateBindSampler(const Context *context, + angle::EntryPoint entryPoint, + GLuint unit, + SamplerID samplerPacked); +bool ValidateBindTransformFeedback(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + TransformFeedbackID idPacked); +bool ValidateBindVertexArray(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID arrayPacked); +bool ValidateBlitFramebuffer(const Context *context, + angle::EntryPoint entryPoint, + GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter); +bool ValidateClearBufferfi(const Context *context, + angle::EntryPoint entryPoint, + GLenum buffer, + GLint drawbuffer, + GLfloat depth, + GLint stencil); +bool ValidateClearBufferfv(const Context *context, + angle::EntryPoint entryPoint, + GLenum buffer, + GLint drawbuffer, + const GLfloat *value); +bool ValidateClearBufferiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum buffer, + GLint drawbuffer, + const GLint *value); +bool ValidateClearBufferuiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum buffer, + GLint drawbuffer, + const GLuint *value); +bool ValidateClientWaitSync(const Context *context, + angle::EntryPoint entryPoint, + GLsync sync, + GLbitfield flags, + GLuint64 timeout); +bool ValidateCompressedTexImage3D(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + const void *data); +bool ValidateCompressedTexSubImage3D(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const void *data); +bool ValidateCopyBufferSubData(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding readTargetPacked, + BufferBinding writeTargetPacked, + GLintptr readOffset, + GLintptr writeOffset, + GLsizeiptr size); +bool ValidateCopyTexSubImage3D(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height); +bool ValidateDeleteQueries(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const QueryID *idsPacked); +bool ValidateDeleteSamplers(const Context *context, + angle::EntryPoint entryPoint, + GLsizei count, + const SamplerID *samplersPacked); +bool ValidateDeleteSync(const Context *context, angle::EntryPoint entryPoint, GLsync sync); +bool ValidateDeleteTransformFeedbacks(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const TransformFeedbackID *idsPacked); +bool ValidateDeleteVertexArrays(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const VertexArrayID *arraysPacked); +bool ValidateDrawArraysInstanced(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + GLint first, + GLsizei count, + GLsizei instancecount); +bool ValidateDrawBuffers(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const GLenum *bufs); +bool ValidateDrawElementsInstanced(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLsizei instancecount); +bool ValidateDrawRangeElements(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + GLuint start, + GLuint end, + GLsizei count, + DrawElementsType typePacked, + const void *indices); +bool ValidateEndQuery(const Context *context, angle::EntryPoint entryPoint, QueryType targetPacked); +bool ValidateEndTransformFeedback(const Context *context, angle::EntryPoint entryPoint); +bool ValidateFenceSync(const Context *context, + angle::EntryPoint entryPoint, + GLenum condition, + GLbitfield flags); +bool ValidateFlushMappedBufferRange(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding targetPacked, + GLintptr offset, + GLsizeiptr length); +bool ValidateFramebufferTextureLayer(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + TextureID texturePacked, + GLint level, + GLint layer); +bool ValidateGenQueries(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const QueryID *idsPacked); +bool ValidateGenSamplers(const Context *context, + angle::EntryPoint entryPoint, + GLsizei count, + const SamplerID *samplersPacked); +bool ValidateGenTransformFeedbacks(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const TransformFeedbackID *idsPacked); +bool ValidateGenVertexArrays(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const VertexArrayID *arraysPacked); +bool ValidateGetActiveUniformBlockName(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformBlockIndex uniformBlockIndexPacked, + GLsizei bufSize, + const GLsizei *length, + const GLchar *uniformBlockName); +bool ValidateGetActiveUniformBlockiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformBlockIndex uniformBlockIndexPacked, + GLenum pname, + const GLint *params); +bool ValidateGetActiveUniformsiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLsizei uniformCount, + const GLuint *uniformIndices, + GLenum pname, + const GLint *params); +bool ValidateGetBufferParameteri64v(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding targetPacked, + GLenum pname, + const GLint64 *params); +bool ValidateGetBufferPointerv(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding targetPacked, + GLenum pname, + void *const *params); +bool ValidateGetFragDataLocation(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + const GLchar *name); +bool ValidateGetInteger64i_v(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index, + const GLint64 *data); +bool ValidateGetInteger64v(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + const GLint64 *data); +bool ValidateGetIntegeri_v(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index, + const GLint *data); +bool ValidateGetInternalformativ(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei count, + const GLint *params); +bool ValidateGetProgramBinary(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLsizei bufSize, + const GLsizei *length, + const GLenum *binaryFormat, + const void *binary); +bool ValidateGetQueryObjectuiv(const Context *context, + angle::EntryPoint entryPoint, + QueryID idPacked, + GLenum pname, + const GLuint *params); +bool ValidateGetQueryiv(const Context *context, + angle::EntryPoint entryPoint, + QueryType targetPacked, + GLenum pname, + const GLint *params); +bool ValidateGetSamplerParameterfv(const Context *context, + angle::EntryPoint entryPoint, + SamplerID samplerPacked, + GLenum pname, + const GLfloat *params); +bool ValidateGetSamplerParameteriv(const Context *context, + angle::EntryPoint entryPoint, + SamplerID samplerPacked, + GLenum pname, + const GLint *params); +bool ValidateGetStringi(const Context *context, + angle::EntryPoint entryPoint, + GLenum name, + GLuint index); +bool ValidateGetSynciv(const Context *context, + angle::EntryPoint entryPoint, + GLsync sync, + GLenum pname, + GLsizei count, + const GLsizei *length, + const GLint *values); +bool ValidateGetTransformFeedbackVarying(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLuint index, + GLsizei bufSize, + const GLsizei *length, + const GLsizei *size, + const GLenum *type, + const GLchar *name); +bool ValidateGetUniformBlockIndex(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + const GLchar *uniformBlockName); +bool ValidateGetUniformIndices(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLsizei uniformCount, + const GLchar *const *uniformNames, + const GLuint *uniformIndices); +bool ValidateGetUniformuiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + const GLuint *params); +bool ValidateGetVertexAttribIiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum pname, + const GLint *params); +bool ValidateGetVertexAttribIuiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum pname, + const GLuint *params); +bool ValidateInvalidateFramebuffer(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLsizei numAttachments, + const GLenum *attachments); +bool ValidateInvalidateSubFramebuffer(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLsizei numAttachments, + const GLenum *attachments, + GLint x, + GLint y, + GLsizei width, + GLsizei height); +bool ValidateIsQuery(const Context *context, angle::EntryPoint entryPoint, QueryID idPacked); +bool ValidateIsSampler(const Context *context, + angle::EntryPoint entryPoint, + SamplerID samplerPacked); +bool ValidateIsSync(const Context *context, angle::EntryPoint entryPoint, GLsync sync); +bool ValidateIsTransformFeedback(const Context *context, + angle::EntryPoint entryPoint, + TransformFeedbackID idPacked); +bool ValidateIsVertexArray(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID arrayPacked); +bool ValidateMapBufferRange(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding targetPacked, + GLintptr offset, + GLsizeiptr length, + GLbitfield access); +bool ValidatePauseTransformFeedback(const Context *context, angle::EntryPoint entryPoint); +bool ValidateProgramBinary(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLenum binaryFormat, + const void *binary, + GLsizei length); +bool ValidateProgramParameteri(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLenum pname, + GLint value); +bool ValidateReadBuffer(const Context *context, angle::EntryPoint entryPoint, GLenum src); +bool ValidateRenderbufferStorageMultisample(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height); +bool ValidateResumeTransformFeedback(const Context *context, angle::EntryPoint entryPoint); +bool ValidateSamplerParameterf(const Context *context, + angle::EntryPoint entryPoint, + SamplerID samplerPacked, + GLenum pname, + GLfloat param); +bool ValidateSamplerParameterfv(const Context *context, + angle::EntryPoint entryPoint, + SamplerID samplerPacked, + GLenum pname, + const GLfloat *param); +bool ValidateSamplerParameteri(const Context *context, + angle::EntryPoint entryPoint, + SamplerID samplerPacked, + GLenum pname, + GLint param); +bool ValidateSamplerParameteriv(const Context *context, + angle::EntryPoint entryPoint, + SamplerID samplerPacked, + GLenum pname, + const GLint *param); +bool ValidateTexImage3D(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const void *pixels); +bool ValidateTexStorage2D(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height); +bool ValidateTexStorage3D(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth); +bool ValidateTexSubImage3D(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *pixels); +bool ValidateTransformFeedbackVaryings(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLsizei count, + const GLchar *const *varyings, + GLenum bufferMode); +bool ValidateUniform1ui(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLuint v0); +bool ValidateUniform1uiv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value); +bool ValidateUniform2ui(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLuint v0, + GLuint v1); +bool ValidateUniform2uiv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value); +bool ValidateUniform3ui(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLuint v0, + GLuint v1, + GLuint v2); +bool ValidateUniform3uiv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value); +bool ValidateUniform4ui(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3); +bool ValidateUniform4uiv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value); +bool ValidateUniformBlockBinding(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformBlockIndex uniformBlockIndexPacked, + GLuint uniformBlockBinding); +bool ValidateUniformMatrix2x3fv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateUniformMatrix2x4fv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateUniformMatrix3x2fv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateUniformMatrix3x4fv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateUniformMatrix4x2fv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateUniformMatrix4x3fv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateUnmapBuffer(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding targetPacked); +bool ValidateVertexAttribDivisor(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLuint divisor); +bool ValidateVertexAttribI4i(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLint x, + GLint y, + GLint z, + GLint w); +bool ValidateVertexAttribI4iv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLint *v); +bool ValidateVertexAttribI4ui(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLuint x, + GLuint y, + GLuint z, + GLuint w); +bool ValidateVertexAttribI4uiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLuint *v); +bool ValidateVertexAttribIPointer(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLint size, + VertexAttribType typePacked, + GLsizei stride, + const void *pointer); +bool ValidateWaitSync(const Context *context, + angle::EntryPoint entryPoint, + GLsync sync, + GLbitfield flags, + GLuint64 timeout); +} // namespace gl + +#endif // LIBANGLE_VALIDATION_ES3_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/validationESEXT.cpp b/gfx/angle/checkout/src/libANGLE/validationESEXT.cpp new file mode 100644 index 0000000000..c708206412 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationESEXT.cpp @@ -0,0 +1,3599 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// validationESEXT.cpp: Validation functions for OpenGL ES extension entry points. + +#include "libANGLE/validationESEXT_autogen.h" + +#include "libANGLE/Context.h" +#include "libANGLE/ErrorStrings.h" +#include "libANGLE/MemoryObject.h" +#include "libANGLE/PixelLocalStorage.h" +#include "libANGLE/validationES.h" +#include "libANGLE/validationES2.h" +#include "libANGLE/validationES3.h" +#include "libANGLE/validationES31.h" +#include "libANGLE/validationES32.h" + +namespace gl +{ +using namespace err; + +namespace +{ +template +bool ValidateGetImageFormatAndType(const Context *context, + angle::EntryPoint entryPoint, + ObjectT *obj, + GLenum format, + GLenum type) +{ + GLenum implFormat = obj->getImplementationColorReadFormat(context); + if (!ValidES3Format(format) && (format != implFormat || format == GL_NONE)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat); + return false; + } + + GLenum implType = obj->getImplementationColorReadType(context); + if (!ValidES3Type(type) && (type != implType || type == GL_NONE)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType); + return false; + } + + // Format/type combinations are not yet validated. + + return true; +} + +bool IsValidImageLayout(ImageLayout layout) +{ + switch (layout) + { + case ImageLayout::Undefined: + case ImageLayout::General: + case ImageLayout::ColorAttachment: + case ImageLayout::DepthStencilAttachment: + case ImageLayout::DepthStencilReadOnlyAttachment: + case ImageLayout::ShaderReadOnly: + case ImageLayout::TransferSrc: + case ImageLayout::TransferDst: + case ImageLayout::DepthReadOnlyStencilAttachment: + case ImageLayout::DepthAttachmentStencilReadOnly: + return true; + + default: + return false; + } +} + +bool IsValidMemoryObjectParamater(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname) +{ + switch (pname) + { + case GL_DEDICATED_MEMORY_OBJECT_EXT: + return true; + + case GL_PROTECTED_MEMORY_OBJECT_EXT: + if (!context->getExtensions().protectedTexturesEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + return true; + + default: + return false; + } +} + +bool ValidateObjectIdentifierAndName(const Context *context, + angle::EntryPoint entryPoint, + GLenum identifier, + GLuint name) +{ + bool isGLES11 = context->getClientVersion() == Version(1, 1); + bool isGLES3 = context->getClientMajorVersion() >= 3; + bool isGLES31 = context->getClientVersion() >= Version(3, 1); + switch (identifier) + { + case GL_BUFFER_OBJECT_EXT: + if (context->getBuffer({name}) == nullptr) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidBufferName); + return false; + } + return true; + + case GL_SHADER_OBJECT_EXT: + if (isGLES11) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType); + return false; + } + if (context->getShader({name}) == nullptr) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidShaderName); + return false; + } + return true; + + case GL_PROGRAM_OBJECT_EXT: + if (isGLES11) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType); + return false; + } + if (context->getProgramNoResolveLink({name}) == nullptr) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidProgramName); + return false; + } + return true; + + case GL_VERTEX_ARRAY_OBJECT_EXT: + if (!isGLES3 && !context->getExtensions().vertexArrayObjectOES) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType); + return false; + } + if (context->getVertexArray({name}) == nullptr) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidVertexArrayName); + return false; + } + return true; + + case GL_QUERY_OBJECT_EXT: + if (!isGLES3 && !context->getExtensions().occlusionQueryBooleanEXT) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType); + return false; + } + if (context->getQuery({name}) == nullptr) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidQueryName); + return false; + } + return true; + + case GL_TRANSFORM_FEEDBACK: + if (!isGLES3) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType); + return false; + } + if (context->getTransformFeedback({name}) == nullptr) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInvalidTransformFeedbackName); + return false; + } + return true; + + case GL_SAMPLER: + if (!isGLES3) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType); + return false; + } + if (context->getSampler({name}) == nullptr) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidSamplerName); + return false; + } + return true; + + case GL_TEXTURE: + if (context->getTexture({name}) == nullptr) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureName); + return false; + } + return true; + + case GL_RENDERBUFFER: + if (!context->isRenderbuffer({name})) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInvalidRenderbufferName); + return false; + } + return true; + + case GL_FRAMEBUFFER: + if (context->getFramebuffer({name}) == nullptr) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFramebufferName); + return false; + } + return true; + + case GL_PROGRAM_PIPELINE_OBJECT_EXT: + if (!isGLES31 && !context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType); + return false; + } + if (context->getProgramPipeline({name}) == nullptr) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInvalidProgramPipelineName); + return false; + } + return true; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidIndentifier); + return false; + } +} +} // namespace + +bool ValidateGetTexImage(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level) +{ + if (!context->getExtensions().getImageANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kGetImageExtensionNotEnabled); + return false; + } + + if (!ValidTexture2DDestinationTarget(context, target) && + !ValidTexture3DDestinationTarget(context, target)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + + if (level < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeLevel); + return false; + } + + TextureType textureType = TextureTargetToType(target); + if (!ValidMipLevel(context, textureType, level)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel); + return false; + } + + return true; +} + +bool ValidateGetTexImageANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum format, + GLenum type, + const void *pixels) +{ + if (!ValidateGetTexImage(context, entryPoint, target, level)) + { + return false; + } + + Texture *texture = context->getTextureByTarget(target); + + if (!ValidateGetImageFormatAndType(context, entryPoint, texture, format, type)) + { + return false; + } + + GLsizei width = static_cast(texture->getWidth(target, level)); + GLsizei height = static_cast(texture->getHeight(target, level)); + if (!ValidatePixelPack(context, entryPoint, format, type, 0, 0, width, height, -1, nullptr, + pixels)) + { + return false; + } + + if (texture->getFormat(target, level).info->compressed) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kGetImageCompressed); + return false; + } + + return true; +} + +bool ValidateGetCompressedTexImageANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + const void *pixels) +{ + if (!ValidateGetTexImage(context, entryPoint, target, level)) + { + return false; + } + + Texture *texture = context->getTextureByTarget(target); + if (!texture->getFormat(target, level).info->compressed) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kGetImageNotCompressed); + return false; + } + + if (texture->isCompressedFormatEmulated(context, target, level)) + { + // TODO (anglebug.com/7464): We can't currently read back from an emulated format + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidEmulatedFormat); + return false; + } + + return true; +} + +bool ValidateGetRenderbufferImageANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum format, + GLenum type, + const void *pixels) +{ + if (!context->getExtensions().getImageANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kGetImageExtensionNotEnabled); + return false; + } + + if (target != GL_RENDERBUFFER) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidRenderbufferTarget); + return false; + } + + Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer(); + + if (!ValidateGetImageFormatAndType(context, entryPoint, renderbuffer, format, type)) + { + return false; + } + + GLsizei width = renderbuffer->getWidth(); + GLsizei height = renderbuffer->getHeight(); + if (!ValidatePixelPack(context, entryPoint, format, type, 0, 0, width, height, -1, nullptr, + pixels)) + { + return false; + } + + return true; +} + +bool ValidateDrawElementsBaseVertexEXT(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLsizei count, + DrawElementsType type, + const void *indices, + GLint basevertex) +{ + if (!context->getExtensions().drawElementsBaseVertexAny()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 1); +} + +bool ValidateDrawElementsInstancedBaseVertexEXT(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLsizei count, + DrawElementsType type, + const void *indices, + GLsizei instancecount, + GLint basevertex) +{ + if (!context->getExtensions().drawElementsBaseVertexAny()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices, + instancecount); +} + +bool ValidateDrawRangeElementsBaseVertexEXT(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLuint start, + GLuint end, + GLsizei count, + DrawElementsType type, + const void *indices, + GLint basevertex) +{ + if (!context->getExtensions().drawElementsBaseVertexAny()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (end < start) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidElementRange); + return false; + } + + if (!ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 0)) + { + return false; + } + + // Skip range checks for no-op calls. + if (count <= 0) + { + return true; + } + + // Note that resolving the index range is a bit slow. We should probably optimize this. + IndexRange indexRange; + ANGLE_VALIDATION_TRY(context->getState().getVertexArray()->getIndexRange(context, type, count, + indices, &indexRange)); + + if (indexRange.end > end || indexRange.start < start) + { + // GL spec says that behavior in this case is undefined - generating an error is fine. + context->validationError(entryPoint, GL_INVALID_OPERATION, kExceedsElementRange); + return false; + } + return true; +} + +bool ValidateMultiDrawElementsBaseVertexEXT(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + const GLsizei *count, + DrawElementsType type, + const void *const *indices, + GLsizei drawcount, + const GLint *basevertex) +{ + return true; +} + +bool ValidateMultiDrawArraysIndirectEXT(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + const void *indirect, + GLsizei drawcount, + GLsizei stride) +{ + if (!ValidateMultiDrawIndirectBase(context, entryPoint, drawcount, stride)) + { + return false; + } + + if (!ValidateDrawArraysIndirect(context, entryPoint, modePacked, indirect)) + { + return false; + } + + return true; +} + +bool ValidateMultiDrawElementsIndirectEXT(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + DrawElementsType typePacked, + const void *indirect, + GLsizei drawcount, + GLsizei stride) +{ + if (!ValidateMultiDrawIndirectBase(context, entryPoint, drawcount, stride)) + { + return false; + } + + const State &state = context->getState(); + TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback(); + if (!ValidateDrawElementsIndirect(context, entryPoint, modePacked, typePacked, indirect)) + { + return false; + } + + if (curTransformFeedback && curTransformFeedback->isActive() && + !curTransformFeedback->isPaused()) + { + // EXT_geometry_shader allows transform feedback to work with all draw commands. + // [EXT_geometry_shader] Section 12.1, "Transform Feedback" + if (context->getExtensions().geometryShaderAny() || context->getClientVersion() >= ES_3_2) + { + if (!ValidateTransformFeedbackPrimitiveMode( + context, entryPoint, curTransformFeedback->getPrimitiveMode(), modePacked)) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kInvalidDrawModeTransformFeedback); + return false; + } + } + else + { + // An INVALID_OPERATION error is generated if transform feedback is active and not + // paused. + context->validationError(entryPoint, GL_INVALID_OPERATION, + kUnsupportedDrawModeForTransformFeedback); + return false; + } + } + + return true; +} + +bool ValidateDrawArraysInstancedBaseInstanceEXT(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLint first, + GLsizei count, + GLsizei instanceCount, + GLuint baseInstance) +{ + if (!context->getExtensions().baseInstanceEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateDrawArraysInstancedBase(context, entryPoint, mode, first, count, instanceCount); +} + +bool ValidateDrawElementsInstancedBaseInstanceEXT(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLsizei count, + DrawElementsType type, + void const *indices, + GLsizei instancecount, + GLuint baseinstance) +{ + if (!context->getExtensions().baseInstanceEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices, + instancecount); +} + +bool ValidateDrawElementsInstancedBaseVertexBaseInstanceEXT(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLsizei instancecount, + GLint basevertex, + GLuint baseinstance) +{ + if (!context->getExtensions().baseInstanceEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, typePacked, indices, + instancecount); +} + +bool ValidateDrawElementsBaseVertexOES(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLsizei count, + DrawElementsType type, + const void *indices, + GLint basevertex) +{ + if (!context->getExtensions().drawElementsBaseVertexAny()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 1); +} + +bool ValidateDrawElementsInstancedBaseVertexOES(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLsizei count, + DrawElementsType type, + const void *indices, + GLsizei instancecount, + GLint basevertex) +{ + if (!context->getExtensions().drawElementsBaseVertexAny()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices, + instancecount); +} + +bool ValidateDrawRangeElementsBaseVertexOES(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLuint start, + GLuint end, + GLsizei count, + DrawElementsType type, + const void *indices, + GLint basevertex) +{ + if (!context->getExtensions().drawElementsBaseVertexAny()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (end < start) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidElementRange); + return false; + } + + if (!ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 0)) + { + return false; + } + + // Skip range checks for no-op calls. + if (count <= 0) + { + return true; + } + + // Note that resolving the index range is a bit slow. We should probably optimize this. + IndexRange indexRange; + ANGLE_VALIDATION_TRY(context->getState().getVertexArray()->getIndexRange(context, type, count, + indices, &indexRange)); + + if (indexRange.end > end || indexRange.start < start) + { + // GL spec says that behavior in this case is undefined - generating an error is fine. + context->validationError(entryPoint, GL_INVALID_OPERATION, kExceedsElementRange); + return false; + } + return true; +} + +// GL_KHR_blend_equation_advanced +bool ValidateBlendBarrierKHR(const Context *context, angle::EntryPoint entryPoint) +{ + const Extensions &extensions = context->getExtensions(); + + if (!extensions.blendEquationAdvancedKHR) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kAdvancedBlendExtensionNotEnabled); + } + + return true; +} + +bool ValidateBlendEquationSeparateiEXT(const Context *context, + angle::EntryPoint entryPoint, + GLuint buf, + GLenum modeRGB, + GLenum modeAlpha) +{ + if (!context->getExtensions().drawBuffersIndexedEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateBlendEquationSeparatei(context, entryPoint, buf, modeRGB, modeAlpha); +} + +bool ValidateBlendEquationiEXT(const Context *context, + angle::EntryPoint entryPoint, + GLuint buf, + GLenum mode) +{ + if (!context->getExtensions().drawBuffersIndexedEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateBlendEquationi(context, entryPoint, buf, mode); +} + +bool ValidateBlendFuncSeparateiEXT(const Context *context, + angle::EntryPoint entryPoint, + GLuint buf, + GLenum srcRGB, + GLenum dstRGB, + GLenum srcAlpha, + GLenum dstAlpha) +{ + if (!context->getExtensions().drawBuffersIndexedEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateBlendFuncSeparatei(context, entryPoint, buf, srcRGB, dstRGB, srcAlpha, dstAlpha); +} + +bool ValidateBlendFunciEXT(const Context *context, + angle::EntryPoint entryPoint, + GLuint buf, + GLenum src, + GLenum dst) +{ + if (!context->getExtensions().drawBuffersIndexedEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateBlendFunci(context, entryPoint, buf, src, dst); +} + +bool ValidateColorMaskiEXT(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLboolean r, + GLboolean g, + GLboolean b, + GLboolean a) +{ + if (!context->getExtensions().drawBuffersIndexedEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateColorMaski(context, entryPoint, index, r, g, b, a); +} + +bool ValidateDisableiEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index) +{ + if (!context->getExtensions().drawBuffersIndexedEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateDisablei(context, entryPoint, target, index); +} + +bool ValidateEnableiEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index) +{ + if (!context->getExtensions().drawBuffersIndexedEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateEnablei(context, entryPoint, target, index); +} + +bool ValidateIsEnablediEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index) +{ + if (!context->getExtensions().drawBuffersIndexedEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateIsEnabledi(context, entryPoint, target, index); +} + +bool ValidateBlendEquationSeparateiOES(const Context *context, + angle::EntryPoint entryPoint, + GLuint buf, + GLenum modeRGB, + GLenum modeAlpha) +{ + if (!context->getExtensions().drawBuffersIndexedOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateBlendEquationSeparatei(context, entryPoint, buf, modeRGB, modeAlpha); +} + +bool ValidateBlendEquationiOES(const Context *context, + angle::EntryPoint entryPoint, + GLuint buf, + GLenum mode) +{ + if (!context->getExtensions().drawBuffersIndexedOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateBlendEquationi(context, entryPoint, buf, mode); +} + +bool ValidateBlendFuncSeparateiOES(const Context *context, + angle::EntryPoint entryPoint, + GLuint buf, + GLenum srcRGB, + GLenum dstRGB, + GLenum srcAlpha, + GLenum dstAlpha) +{ + if (!context->getExtensions().drawBuffersIndexedOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateBlendFuncSeparatei(context, entryPoint, buf, srcRGB, dstRGB, srcAlpha, dstAlpha); +} + +bool ValidateBlendFunciOES(const Context *context, + angle::EntryPoint entryPoint, + GLuint buf, + GLenum src, + GLenum dst) +{ + if (!context->getExtensions().drawBuffersIndexedOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateBlendFunci(context, entryPoint, buf, src, dst); +} + +bool ValidateColorMaskiOES(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLboolean r, + GLboolean g, + GLboolean b, + GLboolean a) +{ + if (!context->getExtensions().drawBuffersIndexedOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateColorMaski(context, entryPoint, index, r, g, b, a); +} + +bool ValidateDisableiOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index) +{ + if (!context->getExtensions().drawBuffersIndexedOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateDisablei(context, entryPoint, target, index); +} + +bool ValidateEnableiOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index) +{ + if (!context->getExtensions().drawBuffersIndexedOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateEnablei(context, entryPoint, target, index); +} + +bool ValidateIsEnablediOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index) +{ + if (!context->getExtensions().drawBuffersIndexedOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateIsEnabledi(context, entryPoint, target, index); +} + +bool ValidateGetInteger64vEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + const GLint64 *data) +{ + if (!context->getExtensions().disjointTimerQueryEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + GLenum nativeType = GL_NONE; + unsigned int numParams = 0; + if (!ValidateStateQuery(context, entryPoint, pname, &nativeType, &numParams)) + { + return false; + } + + return true; +} + +bool ValidateCopyImageSubDataEXT(const Context *context, + angle::EntryPoint entryPoint, + GLuint srcName, + GLenum srcTarget, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLuint dstName, + GLenum dstTarget, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth) +{ + if (!context->getExtensions().copyImageEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateCopyImageSubDataBase(context, entryPoint, srcName, srcTarget, srcLevel, srcX, + srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ, + srcWidth, srcHeight, srcDepth); +} + +bool ValidateCopyImageSubDataOES(const Context *context, + angle::EntryPoint entryPoint, + GLuint srcName, + GLenum srcTarget, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLuint dstName, + GLenum dstTarget, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth) +{ + if (!context->getExtensions().copyImageEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateCopyImageSubDataBase(context, entryPoint, srcName, srcTarget, srcLevel, srcX, + srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ, + srcWidth, srcHeight, srcDepth); +} + +bool ValidateBufferStorageMemEXT(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLsizeiptr size, + MemoryObjectID memory, + GLuint64 offset) +{ + if (!context->getExtensions().memoryObjectEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + UNIMPLEMENTED(); + return false; +} + +bool ValidateCreateMemoryObjectsEXT(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const MemoryObjectID *memoryObjects) +{ + if (!context->getExtensions().memoryObjectEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateGenOrDelete(context, entryPoint, n); +} + +bool ValidateDeleteMemoryObjectsEXT(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const MemoryObjectID *memoryObjects) +{ + if (!context->getExtensions().memoryObjectEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateGenOrDelete(context, entryPoint, n); +} + +bool ValidateGetMemoryObjectParameterivEXT(const Context *context, + angle::EntryPoint entryPoint, + MemoryObjectID memoryObject, + GLenum pname, + const GLint *params) +{ + if (!context->getExtensions().memoryObjectEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + const MemoryObject *memory = context->getMemoryObject(memoryObject); + if (memory == nullptr) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMemoryObject); + } + + if (!IsValidMemoryObjectParamater(context, entryPoint, pname)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidMemoryObjectParameter); + return false; + } + + return true; +} + +bool ValidateGetUnsignedBytevEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + const GLubyte *data) +{ + if (!context->getExtensions().memoryObjectEXT && !context->getExtensions().semaphoreEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + UNIMPLEMENTED(); + return false; +} + +bool ValidateGetUnsignedBytei_vEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index, + const GLubyte *data) +{ + if (!context->getExtensions().memoryObjectEXT && !context->getExtensions().semaphoreEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + UNIMPLEMENTED(); + return false; +} + +bool ValidateIsMemoryObjectEXT(const Context *context, + angle::EntryPoint entryPoint, + MemoryObjectID memoryObject) +{ + if (!context->getExtensions().memoryObjectEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return true; +} + +bool ValidateMemoryObjectParameterivEXT(const Context *context, + angle::EntryPoint entryPoint, + MemoryObjectID memoryObject, + GLenum pname, + const GLint *params) +{ + if (!context->getExtensions().memoryObjectEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + const MemoryObject *memory = context->getMemoryObject(memoryObject); + if (memory == nullptr) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMemoryObject); + return false; + } + + if (memory->isImmutable()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kImmutableMemoryObject); + return false; + } + + if (!IsValidMemoryObjectParamater(context, entryPoint, pname)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidMemoryObjectParameter); + return false; + } + + return true; +} + +bool ValidateTexStorageMem2DEXT(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height, + MemoryObjectID memory, + GLuint64 offset) +{ + if (!context->getExtensions().memoryObjectEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (context->getClientMajorVersion() < 3) + { + return ValidateES2TexStorageParametersBase(context, entryPoint, target, levels, + internalFormat, width, height); + } + + ASSERT(context->getClientMajorVersion() >= 3); + return ValidateES3TexStorage2DParameters(context, entryPoint, target, levels, internalFormat, + width, height, 1); +} + +bool ValidateTexStorageMem3DEXT(const Context *context, + angle::EntryPoint entryPoint, + TextureType target, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth, + MemoryObjectID memory, + GLuint64 offset) +{ + if (!context->getExtensions().memoryObjectEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + UNIMPLEMENTED(); + return false; +} + +bool ValidateImportMemoryFdEXT(const Context *context, + angle::EntryPoint entryPoint, + MemoryObjectID memory, + GLuint64 size, + HandleType handleType, + GLint fd) +{ + if (!context->getExtensions().memoryObjectFdEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + switch (handleType) + { + case HandleType::OpaqueFd: + break; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidHandleType); + return false; + } + + return true; +} + +bool ValidateImportMemoryZirconHandleANGLE(const Context *context, + angle::EntryPoint entryPoint, + MemoryObjectID memory, + GLuint64 size, + HandleType handleType, + GLuint handle) +{ + if (!context->getExtensions().memoryObjectFuchsiaANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + switch (handleType) + { + case HandleType::ZirconVmo: + break; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidHandleType); + return false; + } + + return true; +} + +bool ValidateDeleteSemaphoresEXT(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const SemaphoreID *semaphores) +{ + if (!context->getExtensions().semaphoreEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateGenOrDelete(context, entryPoint, n); +} + +bool ValidateGenSemaphoresEXT(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const SemaphoreID *semaphores) +{ + if (!context->getExtensions().semaphoreEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateGenOrDelete(context, entryPoint, n); +} + +bool ValidateGetSemaphoreParameterui64vEXT(const Context *context, + angle::EntryPoint entryPoint, + SemaphoreID semaphore, + GLenum pname, + const GLuint64 *params) +{ + if (!context->getExtensions().semaphoreEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + UNIMPLEMENTED(); + return false; +} + +bool ValidateIsSemaphoreEXT(const Context *context, + angle::EntryPoint entryPoint, + SemaphoreID semaphore) +{ + if (!context->getExtensions().semaphoreEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return true; +} + +bool ValidateSemaphoreParameterui64vEXT(const Context *context, + angle::EntryPoint entryPoint, + SemaphoreID semaphore, + GLenum pname, + const GLuint64 *params) +{ + if (!context->getExtensions().semaphoreEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + UNIMPLEMENTED(); + return false; +} + +bool ValidateSignalSemaphoreEXT(const Context *context, + angle::EntryPoint entryPoint, + SemaphoreID semaphore, + GLuint numBufferBarriers, + const BufferID *buffers, + GLuint numTextureBarriers, + const TextureID *textures, + const GLenum *dstLayouts) +{ + if (!context->getExtensions().semaphoreEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + for (GLuint i = 0; i < numBufferBarriers; ++i) + { + if (!context->getBuffer(buffers[i])) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidBufferName); + return false; + } + } + + for (GLuint i = 0; i < numTextureBarriers; ++i) + { + if (!context->getTexture(textures[i])) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureName); + return false; + } + if (!IsValidImageLayout(FromGLenum(dstLayouts[i]))) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidImageLayout); + return false; + } + } + + return true; +} + +bool ValidateWaitSemaphoreEXT(const Context *context, + angle::EntryPoint entryPoint, + SemaphoreID semaphore, + GLuint numBufferBarriers, + const BufferID *buffers, + GLuint numTextureBarriers, + const TextureID *textures, + const GLenum *srcLayouts) +{ + if (!context->getExtensions().semaphoreEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + for (GLuint i = 0; i < numBufferBarriers; ++i) + { + if (!context->getBuffer(buffers[i])) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidBufferName); + return false; + } + } + + for (GLuint i = 0; i < numTextureBarriers; ++i) + { + if (!context->getTexture(textures[i])) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureName); + return false; + } + if (!IsValidImageLayout(FromGLenum(srcLayouts[i]))) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidImageLayout); + return false; + } + } + + return true; +} + +bool ValidateImportSemaphoreFdEXT(const Context *context, + angle::EntryPoint entryPoint, + SemaphoreID semaphore, + HandleType handleType, + GLint fd) +{ + if (!context->getExtensions().semaphoreFdEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + switch (handleType) + { + case HandleType::OpaqueFd: + break; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidHandleType); + return false; + } + + return true; +} + +bool ValidateGetSamplerParameterIivEXT(const Context *context, + angle::EntryPoint entryPoint, + SamplerID samplerPacked, + GLenum pname, + const GLint *params) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + return ValidateGetSamplerParameterBase(context, entryPoint, samplerPacked, pname, nullptr); +} + +bool ValidateGetSamplerParameterIuivEXT(const Context *context, + angle::EntryPoint entryPoint, + SamplerID samplerPacked, + GLenum pname, + const GLuint *params) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + return ValidateGetSamplerParameterBase(context, entryPoint, samplerPacked, pname, nullptr); +} + +bool ValidateGetTexParameterIivEXT(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + const GLint *params) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + return ValidateGetTexParameterBase(context, entryPoint, targetPacked, pname, nullptr); +} + +bool ValidateGetTexParameterIuivEXT(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + const GLuint *params) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + return ValidateGetTexParameterBase(context, entryPoint, targetPacked, pname, nullptr); +} + +bool ValidateSamplerParameterIivEXT(const Context *context, + angle::EntryPoint entryPoint, + SamplerID samplerPacked, + GLenum pname, + const GLint *param) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + return ValidateSamplerParameterBase(context, entryPoint, samplerPacked, pname, -1, true, param); +} + +bool ValidateSamplerParameterIuivEXT(const Context *context, + angle::EntryPoint entryPoint, + SamplerID samplerPacked, + GLenum pname, + const GLuint *param) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + return ValidateSamplerParameterBase(context, entryPoint, samplerPacked, pname, -1, true, param); +} + +bool ValidateTexParameterIivEXT(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + const GLint *params) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + return ValidateTexParameterBase(context, entryPoint, targetPacked, pname, -1, true, params); +} + +bool ValidateTexParameterIuivEXT(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + const GLuint *params) +{ + if (context->getClientMajorVersion() < 3) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); + return false; + } + return ValidateTexParameterBase(context, entryPoint, targetPacked, pname, -1, true, params); +} + +bool ValidateImportSemaphoreZirconHandleANGLE(const Context *context, + angle::EntryPoint entryPoint, + SemaphoreID semaphore, + HandleType handleType, + GLuint handle) +{ + if (!context->getExtensions().semaphoreFuchsiaANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + switch (handleType) + { + case HandleType::ZirconEvent: + break; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidHandleType); + return false; + } + + return true; +} + +namespace +{ +enum class PLSExpectedStatus : bool +{ + Inactive, + Active +}; + +bool ValidatePLSCommon(const Context *context, + angle::EntryPoint entryPoint, + PLSExpectedStatus expectedStatus) +{ + // Check that the pixel local storage extension is enabled at all. + if (!context->getExtensions().shaderPixelLocalStorageANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kPLSExtensionNotEnabled); + return false; + } + + // INVALID_FRAMEBUFFER_OPERATION is generated if the default framebuffer object name 0 is + // bound to DRAW_FRAMEBUFFER. + if (context->getState().getDrawFramebuffer()->id().value == 0) + { + context->validationError(entryPoint, GL_INVALID_FRAMEBUFFER_OPERATION, + kPLSDefaultFramebufferBound); + return false; + } + + if (expectedStatus == PLSExpectedStatus::Inactive) + { + // INVALID_OPERATION is generated if PIXEL_LOCAL_STORAGE_ACTIVE_ANGLE is TRUE. + if (context->getState().getPixelLocalStorageActive()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kPLSActive); + return false; + } + } + else + { + ASSERT(expectedStatus == PLSExpectedStatus::Active); + + // INVALID_OPERATION is generated if PIXEL_LOCAL_STORAGE_ACTIVE_ANGLE is FALSE. + if (!context->getState().getPixelLocalStorageActive()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kPLSInactive); + return false; + } + } + + return true; +} + +bool ValidatePLSCommon(const Context *context, angle::EntryPoint entryPoint, GLint plane) +{ + if (!ValidatePLSCommon(context, entryPoint, PLSExpectedStatus::Inactive)) + { + return false; + } + + // INVALID_VALUE is generated if < 0 or >= MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE. + if (plane < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kPLSPlaneLessThanZero); + return false; + } + if (plane >= static_cast(context->getCaps().maxPixelLocalStoragePlanes)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kPLSPlaneOutOfRange); + return false; + } + + return true; +} + +bool ValidatePLSInternalformat(const Context *context, + angle::EntryPoint entryPoint, + GLenum internalformat) +{ + // INVALID_ENUM is generated if is not one of the acceptable values in Table + // X.2, or NONE. + switch (internalformat) + { + case GL_RGBA8: + case GL_RGBA8I: + case GL_RGBA8UI: + case GL_R32F: + case GL_R32UI: + return true; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kPLSInvalidInternalformat); + return false; + } +} + +bool ValidatePLSTextureType(const Context *context, + angle::EntryPoint entryPoint, + Texture *tex, + size_t *textureDepth) +{ + // INVALID_ENUM is generated if is nonzero and not of type GL_TEXTURE_2D, + // GL_TEXTURE_CUBE_MAP, GL_TEXTURE_2D_ARRAY, or GL_TEXTURE_3D. + switch (tex->getType()) + { + case TextureType::_2D: + *textureDepth = 1; + return true; + case TextureType::CubeMap: + *textureDepth = 6; + return true; + case TextureType::_2DArray: + *textureDepth = tex->getDepth(TextureTarget::_2DArray, 0); + return true; + case TextureType::_3D: + *textureDepth = tex->getDepth(TextureTarget::_3D, 0); + return true; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kPLSInvalidTextureType); + return false; + } +} + +bool ValidatePLSLoadOperation(const Context *context, angle::EntryPoint entryPoint, GLenum loadop) +{ + // INVALID_ENUM is generated if [0..-1] is not one of the Load Operations + // enumerated in Table X.1. + switch (loadop) + { + case GL_ZERO: + case GL_CLEAR_ANGLE: + case GL_KEEP: + case GL_DONT_CARE: + case GL_DISABLE_ANGLE: + return true; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kPLSInvalidLoadOperation); + return false; + } +} +} // namespace + +bool ValidateFramebufferMemorylessPixelLocalStorageANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLint plane, + GLenum internalformat) +{ + if (!ValidatePLSCommon(context, entryPoint, plane)) + { + return false; + } + + // INVALID_ENUM is generated if is not one of the acceptable values in Table + // X.2, or NONE. + if (internalformat != GL_NONE) + { + if (!ValidatePLSInternalformat(context, entryPoint, internalformat)) + { + return false; + } + } + + return true; +} + +bool ValidateFramebufferTexturePixelLocalStorageANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLint plane, + TextureID backingtexture, + GLint level, + GLint layer) +{ + if (!ValidatePLSCommon(context, entryPoint, plane)) + { + return false; + } + + if (backingtexture.value != 0) + { + Texture *tex = context->getTexture(backingtexture); + + // INVALID_OPERATION is generated if is not the name of an existing + // immutable texture object, or zero. + if (!tex) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureName); + return false; + } + if (!tex->getImmutableFormat()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kTextureIsNotImmutable); + return false; + } + + // INVALID_ENUM is generated if is nonzero and not of type GL_TEXTURE_2D, + // GL_TEXTURE_CUBE_MAP, GL_TEXTURE_2D_ARRAY, or GL_TEXTURE_3D. + size_t textureDepth; + if (!ValidatePLSTextureType(context, entryPoint, tex, &textureDepth)) + { + return false; + } + + // INVALID_VALUE is generated if is nonzero and < 0. + if (level < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeLevel); + return false; + } + + // INVALID_VALUE is generated if is nonzero and >= the + // immutable number of mipmap levels in . + if (static_cast(level) >= tex->getImmutableLevels()) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kTextureLevelOutOfRange); + return false; + } + + // INVALID_VALUE is generated if is nonzero and < 0. + if (layer < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeLayer); + return false; + } + + // INVALID_VALUE is generated if is nonzero and >= the immutable + // number of texture layers in . + if ((size_t)layer >= textureDepth) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kTextureLayerOutOfRange); + return false; + } + + // INVALID_ENUM is generated if is nonzero and its internalformat is not + // one of the acceptable values in Table X.2. + ASSERT(tex->getImmutableFormat()); + GLenum internalformat = tex->getState().getBaseLevelDesc().format.info->internalFormat; + if (!ValidatePLSInternalformat(context, entryPoint, internalformat)) + { + return false; + } + } + + return true; +} + +bool ValidateBeginPixelLocalStorageANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLsizei planes, + const GLenum loadops[], + const void *cleardata) +{ + if (!ValidatePLSCommon(context, entryPoint, PLSExpectedStatus::Inactive)) + { + return false; + } + + const State &state = context->getState(); + const Framebuffer *framebuffer = state.getDrawFramebuffer(); + + // INVALID_OPERATION is generated if the value of SAMPLE_BUFFERS is 1 (i.e., if rendering to a + // multisampled framebuffer). + if (framebuffer->getSamples(context) != 0) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kPLSMultisamplingEnabled); + return false; + } + + // INVALID_OPERATION is generated if DITHER is enabled. + if (state.isDitherEnabled()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kPLSDitherEnabled); + return false; + } + + // INVALID_OPERATION is generated if RASTERIZER_DISCARD is enabled. + if (state.isRasterizerDiscardEnabled()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kPLSRasterizerDiscardEnabled); + return false; + } + + // INVALID_OPERATION is generated if SAMPLE_ALPHA_TO_COVERAGE is enabled. + if (state.isSampleAlphaToCoverageEnabled()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kPLSSampleAlphaToCoverageEnabled); + return false; + } + + // INVALID_OPERATION is generated if SAMPLE_COVERAGE is enabled. + if (state.isSampleCoverageEnabled()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kPLSSampleCoverageEnabled); + return false; + } + + // INVALID_VALUE is generated if < 1 or > + // MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE. + if (planes < 1) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kPLSPlanesLessThanOne); + return false; + } + if (planes > static_cast(context->getCaps().maxPixelLocalStoragePlanes)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kPLSPlanesOutOfRange); + return false; + } + + // INVALID_FRAMEBUFFER_OPERATION is generated if the draw framebuffer has an image attached to + // any color attachment point on or after: + // + // COLOR_ATTACHMENT0 + + // MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE_ANGLE + // + const Caps &caps = context->getCaps(); + for (int i = caps.maxColorAttachmentsWithActivePixelLocalStorage; i < caps.maxColorAttachments; + ++i) + { + if (framebuffer->getColorAttachment(i)) + { + context->validationError(entryPoint, GL_INVALID_FRAMEBUFFER_OPERATION, + kPLSMaxColorAttachmentsExceded); + return false; + } + } + + // INVALID_FRAMEBUFFER_OPERATION is generated if the draw framebuffer has an image attached to + // any color attachment point on or after: + // + // COLOR_ATTACHMENT0 + + // MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES_ANGLE - + // + // + for (GLuint i = caps.maxCombinedDrawBuffersAndPixelLocalStoragePlanes - planes; + i < caps.maxColorAttachmentsWithActivePixelLocalStorage; ++i) + { + if (framebuffer->getColorAttachment(i)) + { + context->validationError(entryPoint, GL_INVALID_FRAMEBUFFER_OPERATION, + kPLSMaxCombinedDrawBuffersAndPlanesExceded); + return false; + } + } + + // INVALID_VALUE is generated if is NULL. + if (!loadops) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kPLSNullLoadOps); + return false; + } + + const PixelLocalStorage *pls = framebuffer->peekPixelLocalStorage(); + bool hasTextureBackedPLSPlanes = false; + Extents textureBackedPLSExtents{}; + + for (int i = 0; i < planes; ++i) + { + // INVALID_ENUM is generated if [0..-1] is not one of the Load + // Operations enumerated in Table X.1. + if (!ValidatePLSLoadOperation(context, entryPoint, loadops[i])) + { + return false; + } + + if (loadops[i] == GL_DISABLE_ANGLE) + { + continue; + } + + // INVALID_VALUE is generated if [0..-1] is CLEAR_ANGLE and is + // NULL. + if (loadops[i] == GL_CLEAR_ANGLE && !cleardata) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kPLSNullClearData); + return false; + } + + // INVALID_OPERATION is generated if [0..-1] is not DISABLE_ANGLE, and + // the pixel local storage plane at that same index is is in a deinitialized state. + if (pls == nullptr || pls->getPlane(i).isDeinitialized()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kPLSEnablingDeinitializedPlane); + return false; + } + + // [ANGLE_shader_pixel_local_storage] Section 4.4.2.X "Configuring Pixel Local Storage + // on a Framebuffer": When a texture object is deleted, any pixel local storage plane to + // which it was bound is automatically converted to a memoryless plane of matching + // internalformat. + const PixelLocalStoragePlane &plane = pls->getPlane(i); + + Extents textureExtents; + if (plane.getTextureImageExtents(context, &textureExtents)) + { + // INVALID_OPERATION is generated if all enabled, texture-backed pixel local storage + // planes do not have the same width and height. + if (!hasTextureBackedPLSPlanes) + { + textureBackedPLSExtents = textureExtents; + hasTextureBackedPLSPlanes = true; + } + else if (textureExtents != textureBackedPLSExtents) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kPLSMismatchedBackingTextureSizes); + return false; + } + } + else + { + // INVALID_OPERATION is generated if [0..-1] is KEEP and the pixel + // local storage plane at that same index is memoryless. + if (loadops[i] == GL_KEEP) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kPLSKeepingMemorylessPlane); + return false; + } + } + } + + const FramebufferAttachment *firstAttachment = + framebuffer->getState().getFirstNonNullAttachment(); + if (firstAttachment) + { + // INVALID_OPERATION is generated if the draw framebuffer has other attachments, and its + // enabled, texture-backed pixel local storage planes do not have identical dimensions + // with the rendering area. + if (hasTextureBackedPLSPlanes && + textureBackedPLSExtents != framebuffer->getState().getAttachmentExtentsIntersection()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kPLSDimensionsDontMatchRenderingArea); + return false; + } + } + else + { + // INVALID_OPERATION is generated if the draw framebuffer has no attachments and no + // enabled, texture-backed pixel local storage planes. + if (!hasTextureBackedPLSPlanes) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kPLSNoAttachmentsNoTextureBacked); + return false; + } + } + + // INVALID_OPERATION is generated if a single texture image is bound to more than one pixel + // local storage plane. + // + // TODO(anglebug.com/7279): Block feedback loops + // + + // INVALID_OPERATION is generated if a single texture image is simultaneously bound to a pixel + // local storage plane and attached to the draw framebuffer. + // + // TODO(anglebug.com/7279): Block feedback loops + // + + return true; +} + +bool ValidateEndPixelLocalStorageANGLE(const Context *context, angle::EntryPoint entryPoint) +{ + return ValidatePLSCommon(context, entryPoint, PLSExpectedStatus::Active); +} + +bool ValidatePixelLocalStorageBarrierANGLE(const Context *context, angle::EntryPoint entryPoint) +{ + return ValidatePLSCommon(context, entryPoint, PLSExpectedStatus::Active); +} + +bool ValidateFramebufferFetchBarrierEXT(const Context *context, angle::EntryPoint entryPoint) +{ + if (!context->getExtensions().shaderFramebufferFetchNonCoherentEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kFramebufferFetchNonCoherentExtensionNotEnabled); + return false; + } + return true; +} + +bool ValidatePatchParameteriEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLint value) +{ + if (!context->getExtensions().tessellationShaderEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, + kTessellationShaderExtensionNotEnabled); + return false; + } + + if (pname != GL_PATCH_VERTICES) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname); + return false; + } + + if (value <= 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidValueNonPositive); + return false; + } + + if (value > context->getCaps().maxPatchVertices) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidValueExceedsMaxPatchSize); + return false; + } + + return true; +} + +bool ValidateTexStorageMemFlags2DANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height, + MemoryObjectID memoryPacked, + GLuint64 offset, + GLbitfield createFlags, + GLbitfield usageFlags, + const void *imageCreateInfoPNext) +{ + if (!context->getExtensions().memoryObjectFlagsANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (!ValidateTexStorageMem2DEXT(context, entryPoint, targetPacked, levels, internalFormat, + width, height, memoryPacked, offset)) + { + return false; + } + + // |createFlags| and |usageFlags| must only have bits specified by the extension. + constexpr GLbitfield kAllCreateFlags = + GL_CREATE_SPARSE_BINDING_BIT_ANGLE | GL_CREATE_SPARSE_RESIDENCY_BIT_ANGLE | + GL_CREATE_SPARSE_ALIASED_BIT_ANGLE | GL_CREATE_MUTABLE_FORMAT_BIT_ANGLE | + GL_CREATE_CUBE_COMPATIBLE_BIT_ANGLE | GL_CREATE_ALIAS_BIT_ANGLE | + GL_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_ANGLE | GL_CREATE_2D_ARRAY_COMPATIBLE_BIT_ANGLE | + GL_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_ANGLE | GL_CREATE_EXTENDED_USAGE_BIT_ANGLE | + GL_CREATE_PROTECTED_BIT_ANGLE | GL_CREATE_DISJOINT_BIT_ANGLE | + GL_CREATE_CORNER_SAMPLED_BIT_ANGLE | GL_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_ANGLE | + GL_CREATE_SUBSAMPLED_BIT_ANGLE; + + if ((createFlags & ~kAllCreateFlags) != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidExternalCreateFlags); + return false; + } + + constexpr GLbitfield kAllUsageFlags = + GL_USAGE_TRANSFER_SRC_BIT_ANGLE | GL_USAGE_TRANSFER_DST_BIT_ANGLE | + GL_USAGE_SAMPLED_BIT_ANGLE | GL_USAGE_STORAGE_BIT_ANGLE | + GL_USAGE_COLOR_ATTACHMENT_BIT_ANGLE | GL_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT_ANGLE | + GL_USAGE_TRANSIENT_ATTACHMENT_BIT_ANGLE | GL_USAGE_INPUT_ATTACHMENT_BIT_ANGLE | + GL_USAGE_SHADING_RATE_IMAGE_BIT_ANGLE | GL_USAGE_FRAGMENT_DENSITY_MAP_BIT_ANGLE; + + if ((usageFlags & ~kAllUsageFlags) != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidExternalUsageFlags); + return false; + } + + return true; +} + +bool ValidateTexStorageMemFlags2DMultisampleANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLsizei samples, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLboolean fixedSampleLocations, + MemoryObjectID memoryPacked, + GLuint64 offset, + GLbitfield createFlags, + GLbitfield usageFlags, + const void *imageCreateInfoPNext) +{ + UNIMPLEMENTED(); + return false; +} + +bool ValidateTexStorageMemFlags3DANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth, + MemoryObjectID memoryPacked, + GLuint64 offset, + GLbitfield createFlags, + GLbitfield usageFlags, + const void *imageCreateInfoPNext) +{ + UNIMPLEMENTED(); + return false; +} + +bool ValidateTexStorageMemFlags3DMultisampleANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLsizei samples, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedSampleLocations, + MemoryObjectID memoryPacked, + GLuint64 offset, + GLbitfield createFlags, + GLbitfield usageFlags, + const void *imageCreateInfoPNext) +{ + UNIMPLEMENTED(); + return false; +} + +// GL_EXT_buffer_storage +bool ValidateBufferStorageEXT(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding targetPacked, + GLsizeiptr size, + const void *data, + GLbitfield flags) +{ + if (!context->isValidBufferBinding(targetPacked)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBufferTypes); + return false; + } + + if (size <= 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNonPositiveSize); + return false; + } + + constexpr GLbitfield kAllUsageFlags = + (GL_DYNAMIC_STORAGE_BIT_EXT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | + GL_MAP_PERSISTENT_BIT_EXT | GL_MAP_COHERENT_BIT_EXT | GL_CLIENT_STORAGE_BIT_EXT); + if ((flags & ~kAllUsageFlags) != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidBufferUsageFlags); + return false; + } + + if (((flags & GL_MAP_PERSISTENT_BIT_EXT) != 0) && + ((flags & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidBufferUsageFlags); + return false; + } + + if (((flags & GL_MAP_COHERENT_BIT_EXT) != 0) && ((flags & GL_MAP_PERSISTENT_BIT_EXT) == 0)) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidBufferUsageFlags); + return false; + } + + Buffer *buffer = context->getState().getTargetBuffer(targetPacked); + + if (buffer == nullptr) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferNotBound); + return false; + } + + if (buffer->isImmutable()) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferImmutable); + return false; + } + + return true; +} + +// GL_EXT_clip_control +bool ValidateClipControlEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum origin, + GLenum depth) +{ + if ((origin != GL_LOWER_LEFT_EXT) && (origin != GL_UPPER_LEFT_EXT)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidOriginEnum); + return false; + } + + if ((depth != GL_NEGATIVE_ONE_TO_ONE_EXT) && (depth != GL_ZERO_TO_ONE_EXT)) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidDepthEnum); + return false; + } + + return true; +} + +// GL_EXT_external_buffer +bool ValidateBufferStorageExternalEXT(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding targetPacked, + GLintptr offset, + GLsizeiptr size, + GLeglClientBufferEXT clientBuffer, + GLbitfield flags) +{ + if (!ValidateBufferStorageEXT(context, entryPoint, targetPacked, size, nullptr, flags)) + { + return false; + } + + if (offset != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kExternalBufferInvalidOffset); + return false; + } + + if (clientBuffer == nullptr && size > 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kClientBufferInvalid); + return false; + } + + return true; +} + +bool ValidateNamedBufferStorageExternalEXT(const Context *context, + angle::EntryPoint entryPoint, + GLuint buffer, + GLintptr offset, + GLsizeiptr size, + GLeglClientBufferEXT clientBuffer, + GLbitfield flags) +{ + UNIMPLEMENTED(); + return false; +} + +// GL_EXT_primitive_bounding_box +bool ValidatePrimitiveBoundingBoxEXT(const Context *context, + angle::EntryPoint entryPoint, + GLfloat minX, + GLfloat minY, + GLfloat minZ, + GLfloat minW, + GLfloat maxX, + GLfloat maxY, + GLfloat maxZ, + GLfloat maxW) +{ + if (!context->getExtensions().primitiveBoundingBoxEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return true; +} + +// GL_OES_primitive_bounding_box +bool ValidatePrimitiveBoundingBoxOES(const Context *context, + angle::EntryPoint entryPoint, + GLfloat minX, + GLfloat minY, + GLfloat minZ, + GLfloat minW, + GLfloat maxX, + GLfloat maxY, + GLfloat maxZ, + GLfloat maxW) +{ + if (!context->getExtensions().primitiveBoundingBoxOES) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return true; +} + +// GL_EXT_separate_shader_objects +bool ValidateActiveShaderProgramEXT(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked, + ShaderProgramID programPacked) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateActiveShaderProgramBase(context, entryPoint, pipelinePacked, programPacked); +} + +bool ValidateBindProgramPipelineEXT(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateBindProgramPipelineBase(context, entryPoint, pipelinePacked); +} + +bool ValidateCreateShaderProgramvEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderType typePacked, + GLsizei count, + const GLchar **strings) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateCreateShaderProgramvBase(context, entryPoint, typePacked, count, strings); +} + +bool ValidateDeleteProgramPipelinesEXT(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const ProgramPipelineID *pipelinesPacked) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateDeleteProgramPipelinesBase(context, entryPoint, n, pipelinesPacked); +} + +bool ValidateGenProgramPipelinesEXT(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const ProgramPipelineID *pipelinesPacked) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateGenProgramPipelinesBase(context, entryPoint, n, pipelinesPacked); +} + +bool ValidateGetProgramPipelineInfoLogEXT(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked, + GLsizei bufSize, + const GLsizei *length, + const GLchar *infoLog) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateGetProgramPipelineInfoLogBase(context, entryPoint, pipelinePacked, bufSize, + length, infoLog); +} + +bool ValidateGetProgramPipelineivEXT(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked, + GLenum pname, + const GLint *params) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateGetProgramPipelineivBase(context, entryPoint, pipelinePacked, pname, params); +} + +bool ValidateIsProgramPipelineEXT(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateIsProgramPipelineBase(context, entryPoint, pipelinePacked); +} + +bool ValidateProgramParameteriEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLenum pname, + GLint value) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramParameteriBase(context, entryPoint, programPacked, pname, value); +} + +bool ValidateProgramUniform1fEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLfloat v0) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramUniform1fBase(context, entryPoint, programPacked, locationPacked, v0); +} + +bool ValidateProgramUniform1fvEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramUniform1fvBase(context, entryPoint, programPacked, locationPacked, count, + value); +} + +bool ValidateProgramUniform1iEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLint v0) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramUniform1iBase(context, entryPoint, programPacked, locationPacked, v0); +} + +bool ValidateProgramUniform1ivEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramUniform1ivBase(context, entryPoint, programPacked, locationPacked, count, + value); +} + +bool ValidateProgramUniform1uiEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLuint v0) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramUniform1uiBase(context, entryPoint, programPacked, locationPacked, v0); +} + +bool ValidateProgramUniform1uivEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramUniform1uivBase(context, entryPoint, programPacked, locationPacked, count, + value); +} + +bool ValidateProgramUniform2fEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLfloat v0, + GLfloat v1) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramUniform2fBase(context, entryPoint, programPacked, locationPacked, v0, v1); +} + +bool ValidateProgramUniform2fvEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramUniform2fvBase(context, entryPoint, programPacked, locationPacked, count, + value); +} + +bool ValidateProgramUniform2iEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLint v0, + GLint v1) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramUniform2iBase(context, entryPoint, programPacked, locationPacked, v0, v1); +} + +bool ValidateProgramUniform2ivEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramUniform2ivBase(context, entryPoint, programPacked, locationPacked, count, + value); +} + +bool ValidateProgramUniform2uiEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLuint v0, + GLuint v1) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramUniform2uiBase(context, entryPoint, programPacked, locationPacked, v0, + v1); +} + +bool ValidateProgramUniform2uivEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramUniform2uivBase(context, entryPoint, programPacked, locationPacked, count, + value); +} + +bool ValidateProgramUniform3fEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLfloat v0, + GLfloat v1, + GLfloat v2) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramUniform3fBase(context, entryPoint, programPacked, locationPacked, v0, v1, + v2); +} + +bool ValidateProgramUniform3fvEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramUniform3fvBase(context, entryPoint, programPacked, locationPacked, count, + value); +} + +bool ValidateProgramUniform3iEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLint v0, + GLint v1, + GLint v2) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramUniform3iBase(context, entryPoint, programPacked, locationPacked, v0, v1, + v2); +} + +bool ValidateProgramUniform3ivEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramUniform3ivBase(context, entryPoint, programPacked, locationPacked, count, + value); +} + +bool ValidateProgramUniform3uiEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLuint v0, + GLuint v1, + GLuint v2) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramUniform3uiBase(context, entryPoint, programPacked, locationPacked, v0, v1, + v2); +} + +bool ValidateProgramUniform3uivEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramUniform3uivBase(context, entryPoint, programPacked, locationPacked, count, + value); +} + +bool ValidateProgramUniform4fEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLfloat v0, + GLfloat v1, + GLfloat v2, + GLfloat v3) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramUniform4fBase(context, entryPoint, programPacked, locationPacked, v0, v1, + v2, v3); +} + +bool ValidateProgramUniform4fvEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramUniform4fvBase(context, entryPoint, programPacked, locationPacked, count, + value); +} + +bool ValidateProgramUniform4iEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLint v0, + GLint v1, + GLint v2, + GLint v3) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramUniform4iBase(context, entryPoint, programPacked, locationPacked, v0, v1, + v2, v3); +} + +bool ValidateProgramUniform4ivEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value) +{ + return ValidateProgramUniform4ivBase(context, entryPoint, programPacked, locationPacked, count, + value); +} + +bool ValidateProgramUniform4uiEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramUniform4uiBase(context, entryPoint, programPacked, locationPacked, v0, v1, + v2, v3); +} + +bool ValidateProgramUniform4uivEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value) +{ + return ValidateProgramUniform4uivBase(context, entryPoint, programPacked, locationPacked, count, + value); +} + +bool ValidateProgramUniformMatrix2fvEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramUniformMatrix2fvBase(context, entryPoint, programPacked, locationPacked, + count, transpose, value); +} + +bool ValidateProgramUniformMatrix2x3fvEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramUniformMatrix2x3fvBase(context, entryPoint, programPacked, locationPacked, + count, transpose, value); +} + +bool ValidateProgramUniformMatrix2x4fvEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramUniformMatrix2x4fvBase(context, entryPoint, programPacked, locationPacked, + count, transpose, value); +} + +bool ValidateProgramUniformMatrix3fvEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramUniformMatrix3fvBase(context, entryPoint, programPacked, locationPacked, + count, transpose, value); +} + +bool ValidateProgramUniformMatrix3x2fvEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramUniformMatrix3x2fvBase(context, entryPoint, programPacked, locationPacked, + count, transpose, value); +} + +bool ValidateProgramUniformMatrix3x4fvEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramUniformMatrix3x4fvBase(context, entryPoint, programPacked, locationPacked, + count, transpose, value); +} + +bool ValidateProgramUniformMatrix4fvEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramUniformMatrix4fvBase(context, entryPoint, programPacked, locationPacked, + count, transpose, value); +} + +bool ValidateProgramUniformMatrix4x2fvEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramUniformMatrix4x2fvBase(context, entryPoint, programPacked, locationPacked, + count, transpose, value); +} + +bool ValidateProgramUniformMatrix4x3fvEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateProgramUniformMatrix4x3fvBase(context, entryPoint, programPacked, locationPacked, + count, transpose, value); +} + +bool ValidateUseProgramStagesEXT(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked, + GLbitfield stages, + ShaderProgramID programPacked) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateUseProgramStagesBase(context, entryPoint, pipelinePacked, stages, programPacked); +} + +bool ValidateValidateProgramPipelineEXT(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked) +{ + if (!context->getExtensions().separateShaderObjectsEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateValidateProgramPipelineBase(context, entryPoint, pipelinePacked); +} + +// GL_EXT_debug_label +bool ValidateGetObjectLabelEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + GLuint object, + GLsizei bufSize, + const GLsizei *length, + const GLchar *label) +{ + if (!context->getExtensions().debugLabelEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (bufSize < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize); + return false; + } + + return ValidateObjectIdentifierAndName(context, entryPoint, type, object); +} + +bool ValidateLabelObjectEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + GLuint object, + GLsizei length, + const GLchar *label) +{ + if (!context->getExtensions().debugLabelEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (length < 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeLength); + return false; + } + + return ValidateObjectIdentifierAndName(context, entryPoint, type, object); +} + +bool ValidateEGLImageTargetTextureStorageEXT(const Context *context, + angle::EntryPoint entryPoint, + GLuint texture, + GLeglImageOES image, + const GLint *attrib_list) +{ + UNREACHABLE(); + return false; +} + +bool ValidateEGLImageTargetTexStorageEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLeglImageOES image, + const GLint *attrib_list) +{ + if (!context->getExtensions().EGLImageStorageEXT) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + gl::TextureType targetType = FromGLenum(target); + switch (targetType) + { + case TextureType::External: + if (!context->getExtensions().EGLImageExternalOES) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, + ToGLenum(targetType)); + } + break; + case TextureType::CubeMapArray: + if (!context->getExtensions().textureCubeMapArrayAny()) + { + context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, + ToGLenum(targetType)); + } + break; + case TextureType::_2D: + case TextureType::_2DArray: + case TextureType::_3D: + case TextureType::CubeMap: + break; + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); + return false; + } + + // Validate egl source image is valid + egl::Image *imageObject = static_cast(image); + if (!ValidateEGLImageObject(context, entryPoint, targetType, image)) + { + return false; + } + + // attrib list validation + if (attrib_list != nullptr && attrib_list[0] != GL_NONE) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kAttributeListNotNull); + return false; + } + + GLsizei levelCount = imageObject->getLevelCount(); + Extents size = imageObject->getExtents(); + GLsizei width = static_cast(size.width); + GLsizei height = static_cast(size.height); + GLsizei depth = static_cast(size.depth); + GLenum internalformat = imageObject->getFormat().info->sizedInternalFormat; + + if (width < 1 || height < 1 || depth < 1 || levelCount < 1) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kTextureSizeTooSmall); + return false; + } + + if (!ValidateES3TexStorageParametersLevel(context, entryPoint, targetType, levelCount, width, + height, depth)) + { + // Error already generated. + return false; + } + + if (targetType == TextureType::External) + { + const Caps &caps = context->getCaps(); + if (width > caps.max2DTextureSize || height > caps.max2DTextureSize) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize); + return false; + } + } + else if (!ValidateES3TexStorageParametersExtent(context, entryPoint, targetType, levelCount, + width, height, depth)) + { + // Error already generated. + return false; + } + + if (!ValidateES3TexStorageParametersTexObject(context, entryPoint, targetType)) + { + // Error already generated. + return false; + } + + if (!ValidateES3TexStorageParametersFormat(context, entryPoint, targetType, levelCount, + internalformat, width, height, depth)) + { + // Error already generated. + return false; + } + + return true; +} + +bool ValidateAcquireTexturesANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLuint numTextures, + const TextureID *textures, + const GLenum *layouts) +{ + if (!context->getExtensions().vulkanImageANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + for (GLuint i = 0; i < numTextures; ++i) + { + if (!context->getTexture(textures[i])) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureName); + return false; + } + if (!IsValidImageLayout(FromGLenum(layouts[i]))) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidImageLayout); + return false; + } + } + + return true; +} + +bool ValidateReleaseTexturesANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLuint numTextures, + const TextureID *textures, + const GLenum *layouts) +{ + if (!context->getExtensions().vulkanImageANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + for (GLuint i = 0; i < numTextures; ++i) + { + if (!context->getTexture(textures[i])) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureName); + return false; + } + } + + return true; +} + +bool ValidateFramebufferParameteriMESA(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum pname, + GLint param) +{ + if (pname != GL_FRAMEBUFFER_FLIP_Y_MESA) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname); + return false; + } + return ValidateFramebufferParameteriBase(context, entryPoint, target, pname, param); +} + +bool ValidateGetFramebufferParameterivMESA(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum pname, + const GLint *params) +{ + if (pname != GL_FRAMEBUFFER_FLIP_Y_MESA) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname); + return false; + } + return ValidateGetFramebufferParameterivBase(context, entryPoint, target, pname, params); +} + +// GL_AMD_performance_monitor +bool ValidateBeginPerfMonitorAMD(const Context *context, + angle::EntryPoint entryPoint, + GLuint monitor) +{ + if (!context->getExtensions().performanceMonitorAMD) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + UNIMPLEMENTED(); + return false; +} + +bool ValidateDeletePerfMonitorsAMD(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const GLuint *monitors) +{ + if (!context->getExtensions().performanceMonitorAMD) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + UNIMPLEMENTED(); + return false; +} + +bool ValidateEndPerfMonitorAMD(const Context *context, angle::EntryPoint entryPoint, GLuint monitor) +{ + if (!context->getExtensions().performanceMonitorAMD) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + UNIMPLEMENTED(); + return false; +} + +bool ValidateGenPerfMonitorsAMD(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const GLuint *monitors) +{ + if (!context->getExtensions().performanceMonitorAMD) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + UNIMPLEMENTED(); + return false; +} + +bool ValidateGetPerfMonitorCounterDataAMD(const Context *context, + angle::EntryPoint entryPoint, + GLuint monitor, + GLenum pname, + GLsizei dataSize, + const GLuint *data, + const GLint *bytesWritten) +{ + if (!context->getExtensions().performanceMonitorAMD) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + if (monitor != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPerfMonitor); + return false; + } + + switch (pname) + { + case GL_PERFMON_RESULT_AVAILABLE_AMD: + case GL_PERFMON_RESULT_SIZE_AMD: + case GL_PERFMON_RESULT_AMD: + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname); + return false; + } + + return true; +} + +bool ValidateGetPerfMonitorCounterInfoAMD(const Context *context, + angle::EntryPoint entryPoint, + GLuint group, + GLuint counter, + GLenum pname, + const void *data) +{ + if (!context->getExtensions().performanceMonitorAMD) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + const angle::PerfMonitorCounterGroups &groups = context->getPerfMonitorCounterGroups(); + + if (group >= groups.size()) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPerfMonitorGroup); + return false; + } + + if (counter >= groups[group].counters.size()) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPerfMonitorCounter); + return false; + } + + switch (pname) + { + case GL_COUNTER_TYPE_AMD: + case GL_COUNTER_RANGE_AMD: + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname); + return false; + } + + return true; +} + +bool ValidateGetPerfMonitorCounterStringAMD(const Context *context, + angle::EntryPoint entryPoint, + GLuint group, + GLuint counter, + GLsizei bufSize, + const GLsizei *length, + const GLchar *counterString) +{ + if (!context->getExtensions().performanceMonitorAMD) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + const angle::PerfMonitorCounterGroups &groups = context->getPerfMonitorCounterGroups(); + + if (group >= groups.size()) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPerfMonitorGroup); + return false; + } + + if (counter >= groups[group].counters.size()) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPerfMonitorCounter); + return false; + } + + return true; +} + +bool ValidateGetPerfMonitorCountersAMD(const Context *context, + angle::EntryPoint entryPoint, + GLuint group, + const GLint *numCounters, + const GLint *maxActiveCounters, + GLsizei counterSize, + const GLuint *counters) +{ + if (!context->getExtensions().performanceMonitorAMD) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + const angle::PerfMonitorCounterGroups &groups = context->getPerfMonitorCounterGroups(); + + if (group >= groups.size()) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPerfMonitorGroup); + return false; + } + + return true; +} + +bool ValidateGetPerfMonitorGroupStringAMD(const Context *context, + angle::EntryPoint entryPoint, + GLuint group, + GLsizei bufSize, + const GLsizei *length, + const GLchar *groupString) +{ + if (!context->getExtensions().performanceMonitorAMD) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + const angle::PerfMonitorCounterGroups &groups = context->getPerfMonitorCounterGroups(); + + if (group >= groups.size()) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPerfMonitorGroup); + return false; + } + + return true; +} + +bool ValidateGetPerfMonitorGroupsAMD(const Context *context, + angle::EntryPoint entryPoint, + const GLint *numGroups, + GLsizei groupsSize, + const GLuint *groups) +{ + if (!context->getExtensions().performanceMonitorAMD) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return true; +} + +bool ValidateSelectPerfMonitorCountersAMD(const Context *context, + angle::EntryPoint entryPoint, + GLuint monitor, + GLboolean enable, + GLuint group, + GLint numCounters, + const GLuint *counterList) +{ + if (!context->getExtensions().performanceMonitorAMD) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + UNIMPLEMENTED(); + return false; +} + +bool ValidateShadingRateQCOM(const Context *context, angle::EntryPoint entryPoint, GLenum rate) +{ + if (!context->getExtensions().shadingRateQCOM) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + gl::ShadingRate shadingRate = gl::FromGLenum(rate); + if (shadingRate == gl::ShadingRate::Undefined || shadingRate == gl::ShadingRate::InvalidEnum) + { + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShadingRate); + return false; + } + + return true; +} + +bool ValidateLogicOpANGLE(const Context *context, + angle::EntryPoint entryPoint, + LogicalOperation opcodePacked) +{ + if (!context->getExtensions().logicOpANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); + return false; + } + + return ValidateLogicOpCommon(context, entryPoint, opcodePacked); +} +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/validationESEXT.h b/gfx/angle/checkout/src/libANGLE/validationESEXT.h new file mode 100644 index 0000000000..b22ed4e379 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationESEXT.h @@ -0,0 +1,20 @@ +// +// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// validationESEXT.h: +// Inlined validation functions for OpenGL ES extension entry points. + +#ifndef LIBANGLE_VALIDATION_ESEXT_H_ +#define LIBANGLE_VALIDATION_ESEXT_H_ + +#include "libANGLE/ErrorStrings.h" +#include "libANGLE/validationESEXT_autogen.h" + +namespace gl +{ +// Nothing here yet. +} // namespace gl + +#endif // LIBANGLE_VALIDATION_ESEXT_H_ diff --git a/gfx/angle/checkout/src/libANGLE/validationESEXT_autogen.h b/gfx/angle/checkout/src/libANGLE/validationESEXT_autogen.h new file mode 100644 index 0000000000..47be44ab2f --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationESEXT_autogen.h @@ -0,0 +1,2646 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// validationESEXT_autogen.h: +// Validation functions for the OpenGL ES extension entry points. + +#ifndef LIBANGLE_VALIDATION_ESEXT_AUTOGEN_H_ +#define LIBANGLE_VALIDATION_ESEXT_AUTOGEN_H_ + +#include "common/PackedEnums.h" +#include "common/entry_points_enum_autogen.h" + +namespace gl +{ +class Context; + +// GL_AMD_performance_monitor +bool ValidateBeginPerfMonitorAMD(const Context *context, + angle::EntryPoint entryPoint, + GLuint monitor); +bool ValidateDeletePerfMonitorsAMD(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const GLuint *monitors); +bool ValidateEndPerfMonitorAMD(const Context *context, + angle::EntryPoint entryPoint, + GLuint monitor); +bool ValidateGenPerfMonitorsAMD(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const GLuint *monitors); +bool ValidateGetPerfMonitorCounterDataAMD(const Context *context, + angle::EntryPoint entryPoint, + GLuint monitor, + GLenum pname, + GLsizei dataSize, + const GLuint *data, + const GLint *bytesWritten); +bool ValidateGetPerfMonitorCounterInfoAMD(const Context *context, + angle::EntryPoint entryPoint, + GLuint group, + GLuint counter, + GLenum pname, + const void *data); +bool ValidateGetPerfMonitorCounterStringAMD(const Context *context, + angle::EntryPoint entryPoint, + GLuint group, + GLuint counter, + GLsizei bufSize, + const GLsizei *length, + const GLchar *counterString); +bool ValidateGetPerfMonitorCountersAMD(const Context *context, + angle::EntryPoint entryPoint, + GLuint group, + const GLint *numCounters, + const GLint *maxActiveCounters, + GLsizei counterSize, + const GLuint *counters); +bool ValidateGetPerfMonitorGroupStringAMD(const Context *context, + angle::EntryPoint entryPoint, + GLuint group, + GLsizei bufSize, + const GLsizei *length, + const GLchar *groupString); +bool ValidateGetPerfMonitorGroupsAMD(const Context *context, + angle::EntryPoint entryPoint, + const GLint *numGroups, + GLsizei groupsSize, + const GLuint *groups); +bool ValidateSelectPerfMonitorCountersAMD(const Context *context, + angle::EntryPoint entryPoint, + GLuint monitor, + GLboolean enable, + GLuint group, + GLint numCounters, + const GLuint *counterList); + +// GL_ANDROID_extension_pack_es31a + +// GL_ANGLE_base_vertex_base_instance +bool ValidateDrawArraysInstancedBaseInstanceANGLE(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + GLint first, + GLsizei count, + GLsizei instanceCount, + GLuint baseInstance); +bool ValidateDrawElementsInstancedBaseVertexBaseInstanceANGLE(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const GLvoid *indices, + GLsizei instanceCount, + GLint baseVertex, + GLuint baseInstance); +bool ValidateMultiDrawArraysInstancedBaseInstanceANGLE(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + const GLint *firsts, + const GLsizei *counts, + const GLsizei *instanceCounts, + const GLuint *baseInstances, + GLsizei drawcount); +bool ValidateMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + const GLsizei *counts, + DrawElementsType typePacked, + const GLvoid *const *indices, + const GLsizei *instanceCounts, + const GLint *baseVertices, + const GLuint *baseInstances, + GLsizei drawcount); + +// GL_ANGLE_copy_texture_3d +bool ValidateCopyTexture3DANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureID sourceIdPacked, + GLint sourceLevel, + TextureTarget destTargetPacked, + TextureID destIdPacked, + GLint destLevel, + GLint internalFormat, + GLenum destType, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha); +bool ValidateCopySubTexture3DANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureID sourceIdPacked, + GLint sourceLevel, + TextureTarget destTargetPacked, + TextureID destIdPacked, + GLint destLevel, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLint z, + GLint width, + GLint height, + GLint depth, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha); + +// GL_ANGLE_depth_texture + +// GL_ANGLE_framebuffer_blit +bool ValidateBlitFramebufferANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter); + +// GL_ANGLE_framebuffer_multisample +bool ValidateRenderbufferStorageMultisampleANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height); + +// GL_ANGLE_get_image +bool ValidateGetTexImageANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLenum format, + GLenum type, + const void *pixels); +bool ValidateGetCompressedTexImageANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + const void *pixels); +bool ValidateGetRenderbufferImageANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum format, + GLenum type, + const void *pixels); + +// GL_ANGLE_get_tex_level_parameter +bool ValidateGetTexLevelParameterivANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLenum pname, + const GLint *params); +bool ValidateGetTexLevelParameterfvANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLenum pname, + const GLfloat *params); + +// GL_ANGLE_instanced_arrays +bool ValidateDrawArraysInstancedANGLE(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + GLint first, + GLsizei count, + GLsizei primcount); +bool ValidateDrawElementsInstancedANGLE(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLsizei primcount); +bool ValidateVertexAttribDivisorANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLuint divisor); + +// GL_ANGLE_logic_op +bool ValidateLogicOpANGLE(const Context *context, + angle::EntryPoint entryPoint, + LogicalOperation opcodePacked); + +// GL_ANGLE_memory_object_flags +bool ValidateTexStorageMemFlags2DANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height, + MemoryObjectID memoryPacked, + GLuint64 offset, + GLbitfield createFlags, + GLbitfield usageFlags, + const void *imageCreateInfoPNext); +bool ValidateTexStorageMemFlags2DMultisampleANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLsizei samples, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLboolean fixedSampleLocations, + MemoryObjectID memoryPacked, + GLuint64 offset, + GLbitfield createFlags, + GLbitfield usageFlags, + const void *imageCreateInfoPNext); +bool ValidateTexStorageMemFlags3DANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth, + MemoryObjectID memoryPacked, + GLuint64 offset, + GLbitfield createFlags, + GLbitfield usageFlags, + const void *imageCreateInfoPNext); +bool ValidateTexStorageMemFlags3DMultisampleANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLsizei samples, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedSampleLocations, + MemoryObjectID memoryPacked, + GLuint64 offset, + GLbitfield createFlags, + GLbitfield usageFlags, + const void *imageCreateInfoPNext); + +// GL_ANGLE_memory_object_fuchsia +bool ValidateImportMemoryZirconHandleANGLE(const Context *context, + angle::EntryPoint entryPoint, + MemoryObjectID memoryPacked, + GLuint64 size, + HandleType handleTypePacked, + GLuint handle); + +// GL_ANGLE_multi_draw +bool ValidateMultiDrawArraysANGLE(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + const GLint *firsts, + const GLsizei *counts, + GLsizei drawcount); +bool ValidateMultiDrawArraysInstancedANGLE(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + const GLint *firsts, + const GLsizei *counts, + const GLsizei *instanceCounts, + GLsizei drawcount); +bool ValidateMultiDrawElementsANGLE(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + const GLsizei *counts, + DrawElementsType typePacked, + const GLvoid *const *indices, + GLsizei drawcount); +bool ValidateMultiDrawElementsInstancedANGLE(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + const GLsizei *counts, + DrawElementsType typePacked, + const GLvoid *const *indices, + const GLsizei *instanceCounts, + GLsizei drawcount); + +// GL_ANGLE_pack_reverse_row_order + +// GL_ANGLE_program_binary + +// GL_ANGLE_provoking_vertex +bool ValidateProvokingVertexANGLE(const Context *context, + angle::EntryPoint entryPoint, + ProvokingVertexConvention modePacked); + +// GL_ANGLE_request_extension +bool ValidateRequestExtensionANGLE(const Context *context, + angle::EntryPoint entryPoint, + const GLchar *name); +bool ValidateDisableExtensionANGLE(const Context *context, + angle::EntryPoint entryPoint, + const GLchar *name); + +// GL_ANGLE_robust_client_memory +bool ValidateGetBooleanvRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLboolean *params); +bool ValidateGetBufferParameterivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding targetPacked, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params); +bool ValidateGetFloatvRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLfloat *params); +bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params); +bool ValidateGetIntegervRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *data); +bool ValidateGetProgramivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params); +bool ValidateGetRenderbufferParameterivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params); +bool ValidateGetShaderivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID shaderPacked, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params); +bool ValidateGetTexParameterfvRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLfloat *params); +bool ValidateGetTexParameterivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params); +bool ValidateGetUniformfvRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + const GLsizei *length, + const GLfloat *params); +bool ValidateGetUniformivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + const GLsizei *length, + const GLint *params); +bool ValidateGetVertexAttribfvRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLfloat *params); +bool ValidateGetVertexAttribivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params); +bool ValidateGetVertexAttribPointervRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + void *const *pointer); +bool ValidateReadPixelsRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + const GLsizei *length, + const GLsizei *columns, + const GLsizei *rows, + const void *pixels); +bool ValidateTexImage2DRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels); +bool ValidateTexParameterfvRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + GLsizei bufSize, + const GLfloat *params); +bool ValidateTexParameterivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + GLsizei bufSize, + const GLint *params); +bool ValidateTexSubImage2DRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels); +bool ValidateTexImage3DRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels); +bool ValidateTexSubImage3DRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels); +bool ValidateCompressedTexImage2DRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + GLsizei dataSize, + const GLvoid *data); +bool ValidateCompressedTexSubImage2DRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLsizei xoffset, + GLsizei yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + GLsizei dataSize, + const GLvoid *data); +bool ValidateCompressedTexImage3DRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + GLsizei dataSize, + const GLvoid *data); +bool ValidateCompressedTexSubImage3DRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + GLsizei dataSize, + const GLvoid *data); +bool ValidateGetQueryivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + QueryType targetPacked, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params); +bool ValidateGetQueryObjectuivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + QueryID idPacked, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLuint *params); +bool ValidateGetBufferPointervRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding targetPacked, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + void *const *params); +bool ValidateGetIntegeri_vRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index, + GLsizei bufSize, + const GLsizei *length, + const GLint *data); +bool ValidateGetInternalformativRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params); +bool ValidateGetVertexAttribIivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params); +bool ValidateGetVertexAttribIuivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLuint *params); +bool ValidateGetUniformuivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + const GLsizei *length, + const GLuint *params); +bool ValidateGetActiveUniformBlockivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformBlockIndex uniformBlockIndexPacked, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params); +bool ValidateGetInteger64vRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint64 *data); +bool ValidateGetInteger64i_vRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index, + GLsizei bufSize, + const GLsizei *length, + const GLint64 *data); +bool ValidateGetBufferParameteri64vRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding targetPacked, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint64 *params); +bool ValidateSamplerParameterivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + SamplerID samplerPacked, + GLuint pname, + GLsizei bufSize, + const GLint *param); +bool ValidateSamplerParameterfvRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + SamplerID samplerPacked, + GLenum pname, + GLsizei bufSize, + const GLfloat *param); +bool ValidateGetSamplerParameterivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + SamplerID samplerPacked, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params); +bool ValidateGetSamplerParameterfvRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + SamplerID samplerPacked, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLfloat *params); +bool ValidateGetFramebufferParameterivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params); +bool ValidateGetProgramInterfaceivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLenum programInterface, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params); +bool ValidateGetBooleani_vRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index, + GLsizei bufSize, + const GLsizei *length, + const GLboolean *data); +bool ValidateGetMultisamplefvRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLuint index, + GLsizei bufSize, + const GLsizei *length, + const GLfloat *val); +bool ValidateGetTexLevelParameterivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params); +bool ValidateGetTexLevelParameterfvRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLfloat *params); +bool ValidateGetPointervRobustANGLERobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + void *const *params); +bool ValidateReadnPixelsRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + const GLsizei *length, + const GLsizei *columns, + const GLsizei *rows, + const void *data); +bool ValidateGetnUniformfvRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + const GLsizei *length, + const GLfloat *params); +bool ValidateGetnUniformivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + const GLsizei *length, + const GLint *params); +bool ValidateGetnUniformuivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + const GLsizei *length, + const GLuint *params); +bool ValidateTexParameterIivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + GLsizei bufSize, + const GLint *params); +bool ValidateTexParameterIuivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + GLsizei bufSize, + const GLuint *params); +bool ValidateGetTexParameterIivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params); +bool ValidateGetTexParameterIuivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLuint *params); +bool ValidateSamplerParameterIivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + SamplerID samplerPacked, + GLenum pname, + GLsizei bufSize, + const GLint *param); +bool ValidateSamplerParameterIuivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + SamplerID samplerPacked, + GLenum pname, + GLsizei bufSize, + const GLuint *param); +bool ValidateGetSamplerParameterIivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + SamplerID samplerPacked, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params); +bool ValidateGetSamplerParameterIuivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + SamplerID samplerPacked, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLuint *params); +bool ValidateGetQueryObjectivRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + QueryID idPacked, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint *params); +bool ValidateGetQueryObjecti64vRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + QueryID idPacked, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLint64 *params); +bool ValidateGetQueryObjectui64vRobustANGLE(const Context *context, + angle::EntryPoint entryPoint, + QueryID idPacked, + GLenum pname, + GLsizei bufSize, + const GLsizei *length, + const GLuint64 *params); + +// GL_ANGLE_robust_resource_initialization + +// GL_ANGLE_semaphore_fuchsia +bool ValidateImportSemaphoreZirconHandleANGLE(const Context *context, + angle::EntryPoint entryPoint, + SemaphoreID semaphorePacked, + HandleType handleTypePacked, + GLuint handle); + +// GL_ANGLE_shader_pixel_local_storage +bool ValidateFramebufferMemorylessPixelLocalStorageANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLint plane, + GLenum internalformat); +bool ValidateFramebufferTexturePixelLocalStorageANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLint plane, + TextureID backingtexturePacked, + GLint level, + GLint layer); +bool ValidateBeginPixelLocalStorageANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLsizei planes, + const GLenum *loadops, + const void *cleardata); +bool ValidateEndPixelLocalStorageANGLE(const Context *context, angle::EntryPoint entryPoint); +bool ValidatePixelLocalStorageBarrierANGLE(const Context *context, angle::EntryPoint entryPoint); + +// GL_ANGLE_texture_compression_dxt3 + +// GL_ANGLE_texture_compression_dxt5 + +// GL_ANGLE_texture_external_update +bool ValidateTexImage2DExternalANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type); +bool ValidateInvalidateTextureANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked); + +// GL_ANGLE_texture_multisample +bool ValidateTexStorage2DMultisampleANGLE(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations); +bool ValidateGetMultisamplefvANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLuint index, + const GLfloat *val); +bool ValidateSampleMaskiANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLuint maskNumber, + GLbitfield mask); + +// GL_ANGLE_texture_usage + +// GL_ANGLE_translated_shader_source +bool ValidateGetTranslatedShaderSourceANGLE(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID shaderPacked, + GLsizei bufSize, + const GLsizei *length, + const GLchar *source); + +// GL_ANGLE_vulkan_image +bool ValidateAcquireTexturesANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLuint numTextures, + const TextureID *texturesPacked, + const GLenum *layouts); +bool ValidateReleaseTexturesANGLE(const Context *context, + angle::EntryPoint entryPoint, + GLuint numTextures, + const TextureID *texturesPacked, + const GLenum *layouts); + +// GL_APPLE_clip_distance + +// GL_ARB_sync + +// GL_CHROMIUM_bind_uniform_location +bool ValidateBindUniformLocationCHROMIUM(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + const GLchar *name); + +// GL_CHROMIUM_copy_compressed_texture +bool ValidateCompressedCopyTextureCHROMIUM(const Context *context, + angle::EntryPoint entryPoint, + TextureID sourceIdPacked, + TextureID destIdPacked); + +// GL_CHROMIUM_copy_texture +bool ValidateCopyTextureCHROMIUM(const Context *context, + angle::EntryPoint entryPoint, + TextureID sourceIdPacked, + GLint sourceLevel, + TextureTarget destTargetPacked, + TextureID destIdPacked, + GLint destLevel, + GLint internalFormat, + GLenum destType, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha); +bool ValidateCopySubTextureCHROMIUM(const Context *context, + angle::EntryPoint entryPoint, + TextureID sourceIdPacked, + GLint sourceLevel, + TextureTarget destTargetPacked, + TextureID destIdPacked, + GLint destLevel, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLint width, + GLint height, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha); + +// GL_CHROMIUM_framebuffer_mixed_samples +bool ValidateCoverageModulationCHROMIUM(const Context *context, + angle::EntryPoint entryPoint, + GLenum components); + +// GL_CHROMIUM_lose_context +bool ValidateLoseContextCHROMIUM(const Context *context, + angle::EntryPoint entryPoint, + GraphicsResetStatus currentPacked, + GraphicsResetStatus otherPacked); + +// GL_EXT_EGL_image_array + +// GL_EXT_EGL_image_storage +bool ValidateEGLImageTargetTexStorageEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLeglImageOES image, + const GLint *attrib_list); +bool ValidateEGLImageTargetTextureStorageEXT(const Context *context, + angle::EntryPoint entryPoint, + GLuint texture, + GLeglImageOES image, + const GLint *attrib_list); + +// GL_EXT_YUV_target + +// GL_EXT_base_instance +bool ValidateDrawArraysInstancedBaseInstanceEXT(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + GLint first, + GLsizei count, + GLsizei instancecount, + GLuint baseinstance); +bool ValidateDrawElementsInstancedBaseInstanceEXT(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLsizei instancecount, + GLuint baseinstance); +bool ValidateDrawElementsInstancedBaseVertexBaseInstanceEXT(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLsizei instancecount, + GLint basevertex, + GLuint baseinstance); + +// GL_EXT_blend_func_extended +bool ValidateBindFragDataLocationEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLuint color, + const GLchar *name); +bool ValidateBindFragDataLocationIndexedEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLuint colorNumber, + GLuint index, + const GLchar *name); +bool ValidateGetFragDataIndexEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + const GLchar *name); +bool ValidateGetProgramResourceLocationIndexEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLenum programInterface, + const GLchar *name); + +// GL_EXT_blend_minmax + +// GL_EXT_buffer_storage +bool ValidateBufferStorageEXT(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding targetPacked, + GLsizeiptr size, + const void *data, + GLbitfield flags); + +// GL_EXT_clip_control +bool ValidateClipControlEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum origin, + GLenum depth); + +// GL_EXT_clip_cull_distance + +// GL_EXT_color_buffer_float + +// GL_EXT_color_buffer_half_float + +// GL_EXT_copy_image +bool ValidateCopyImageSubDataEXT(const Context *context, + angle::EntryPoint entryPoint, + GLuint srcName, + GLenum srcTarget, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLuint dstName, + GLenum dstTarget, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth); + +// GL_EXT_debug_label +bool ValidateGetObjectLabelEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + GLuint object, + GLsizei bufSize, + const GLsizei *length, + const GLchar *label); +bool ValidateLabelObjectEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + GLuint object, + GLsizei length, + const GLchar *label); + +// GL_EXT_debug_marker +bool ValidateInsertEventMarkerEXT(const Context *context, + angle::EntryPoint entryPoint, + GLsizei length, + const GLchar *marker); +bool ValidatePopGroupMarkerEXT(const Context *context, angle::EntryPoint entryPoint); +bool ValidatePushGroupMarkerEXT(const Context *context, + angle::EntryPoint entryPoint, + GLsizei length, + const GLchar *marker); + +// GL_EXT_discard_framebuffer +bool ValidateDiscardFramebufferEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLsizei numAttachments, + const GLenum *attachments); + +// GL_EXT_disjoint_timer_query +bool ValidateBeginQueryEXT(const Context *context, + angle::EntryPoint entryPoint, + QueryType targetPacked, + QueryID idPacked); +bool ValidateDeleteQueriesEXT(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const QueryID *idsPacked); +bool ValidateEndQueryEXT(const Context *context, + angle::EntryPoint entryPoint, + QueryType targetPacked); +bool ValidateGenQueriesEXT(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const QueryID *idsPacked); +bool ValidateGetInteger64vEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + const GLint64 *data); +bool ValidateGetQueryObjecti64vEXT(const Context *context, + angle::EntryPoint entryPoint, + QueryID idPacked, + GLenum pname, + const GLint64 *params); +bool ValidateGetQueryObjectivEXT(const Context *context, + angle::EntryPoint entryPoint, + QueryID idPacked, + GLenum pname, + const GLint *params); +bool ValidateGetQueryObjectui64vEXT(const Context *context, + angle::EntryPoint entryPoint, + QueryID idPacked, + GLenum pname, + const GLuint64 *params); +bool ValidateGetQueryObjectuivEXT(const Context *context, + angle::EntryPoint entryPoint, + QueryID idPacked, + GLenum pname, + const GLuint *params); +bool ValidateGetQueryivEXT(const Context *context, + angle::EntryPoint entryPoint, + QueryType targetPacked, + GLenum pname, + const GLint *params); +bool ValidateIsQueryEXT(const Context *context, angle::EntryPoint entryPoint, QueryID idPacked); +bool ValidateQueryCounterEXT(const Context *context, + angle::EntryPoint entryPoint, + QueryID idPacked, + QueryType targetPacked); + +// GL_EXT_draw_buffers +bool ValidateDrawBuffersEXT(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const GLenum *bufs); + +// GL_EXT_draw_buffers_indexed +bool ValidateBlendEquationSeparateiEXT(const Context *context, + angle::EntryPoint entryPoint, + GLuint buf, + GLenum modeRGB, + GLenum modeAlpha); +bool ValidateBlendEquationiEXT(const Context *context, + angle::EntryPoint entryPoint, + GLuint buf, + GLenum mode); +bool ValidateBlendFuncSeparateiEXT(const Context *context, + angle::EntryPoint entryPoint, + GLuint buf, + GLenum srcRGB, + GLenum dstRGB, + GLenum srcAlpha, + GLenum dstAlpha); +bool ValidateBlendFunciEXT(const Context *context, + angle::EntryPoint entryPoint, + GLuint buf, + GLenum src, + GLenum dst); +bool ValidateColorMaskiEXT(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLboolean r, + GLboolean g, + GLboolean b, + GLboolean a); +bool ValidateDisableiEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index); +bool ValidateEnableiEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index); +bool ValidateIsEnablediEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index); + +// GL_EXT_draw_elements_base_vertex +bool ValidateDrawElementsBaseVertexEXT(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLint basevertex); +bool ValidateDrawElementsInstancedBaseVertexEXT(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLsizei instancecount, + GLint basevertex); +bool ValidateDrawRangeElementsBaseVertexEXT(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + GLuint start, + GLuint end, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLint basevertex); +bool ValidateMultiDrawElementsBaseVertexEXT(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + const GLsizei *count, + DrawElementsType typePacked, + const void *const *indices, + GLsizei drawcount, + const GLint *basevertex); + +// GL_EXT_external_buffer +bool ValidateBufferStorageExternalEXT(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding targetPacked, + GLintptr offset, + GLsizeiptr size, + GLeglClientBufferEXT clientBuffer, + GLbitfield flags); +bool ValidateNamedBufferStorageExternalEXT(const Context *context, + angle::EntryPoint entryPoint, + GLuint buffer, + GLintptr offset, + GLsizeiptr size, + GLeglClientBufferEXT clientBuffer, + GLbitfield flags); + +// GL_EXT_float_blend + +// GL_EXT_geometry_shader +bool ValidateFramebufferTextureEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + TextureID texturePacked, + GLint level); + +// GL_EXT_gpu_shader5 + +// GL_EXT_instanced_arrays +bool ValidateDrawArraysInstancedEXT(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + GLint start, + GLsizei count, + GLsizei primcount); +bool ValidateDrawElementsInstancedEXT(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLsizei primcount); +bool ValidateVertexAttribDivisorEXT(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLuint divisor); + +// GL_EXT_map_buffer_range +bool ValidateFlushMappedBufferRangeEXT(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding targetPacked, + GLintptr offset, + GLsizeiptr length); +bool ValidateMapBufferRangeEXT(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding targetPacked, + GLintptr offset, + GLsizeiptr length, + GLbitfield access); + +// GL_EXT_memory_object +bool ValidateBufferStorageMemEXT(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLsizeiptr size, + MemoryObjectID memoryPacked, + GLuint64 offset); +bool ValidateCreateMemoryObjectsEXT(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const MemoryObjectID *memoryObjectsPacked); +bool ValidateDeleteMemoryObjectsEXT(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const MemoryObjectID *memoryObjectsPacked); +bool ValidateGetMemoryObjectParameterivEXT(const Context *context, + angle::EntryPoint entryPoint, + MemoryObjectID memoryObjectPacked, + GLenum pname, + const GLint *params); +bool ValidateGetUnsignedBytevEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + const GLubyte *data); +bool ValidateGetUnsignedBytei_vEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index, + const GLubyte *data); +bool ValidateIsMemoryObjectEXT(const Context *context, + angle::EntryPoint entryPoint, + MemoryObjectID memoryObjectPacked); +bool ValidateMemoryObjectParameterivEXT(const Context *context, + angle::EntryPoint entryPoint, + MemoryObjectID memoryObjectPacked, + GLenum pname, + const GLint *params); +bool ValidateTexStorageMem2DEXT(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height, + MemoryObjectID memoryPacked, + GLuint64 offset); +bool ValidateTexStorageMem2DMultisampleEXT(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLsizei samples, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLboolean fixedSampleLocations, + MemoryObjectID memoryPacked, + GLuint64 offset); +bool ValidateTexStorageMem3DEXT(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth, + MemoryObjectID memoryPacked, + GLuint64 offset); +bool ValidateTexStorageMem3DMultisampleEXT(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLsizei samples, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedSampleLocations, + MemoryObjectID memoryPacked, + GLuint64 offset); + +// GL_EXT_memory_object_fd +bool ValidateImportMemoryFdEXT(const Context *context, + angle::EntryPoint entryPoint, + MemoryObjectID memoryPacked, + GLuint64 size, + HandleType handleTypePacked, + GLint fd); + +// GL_EXT_multi_draw_indirect +bool ValidateMultiDrawArraysIndirectEXT(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + const void *indirect, + GLsizei drawcount, + GLsizei stride); +bool ValidateMultiDrawElementsIndirectEXT(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + DrawElementsType typePacked, + const void *indirect, + GLsizei drawcount, + GLsizei stride); + +// GL_EXT_multisampled_render_to_texture +bool ValidateFramebufferTexture2DMultisampleEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + TextureTarget textargetPacked, + TextureID texturePacked, + GLint level, + GLsizei samples); +bool ValidateRenderbufferStorageMultisampleEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height); + +// GL_EXT_multisampled_render_to_texture2 + +// GL_EXT_occlusion_query_boolean + +// GL_EXT_primitive_bounding_box +bool ValidatePrimitiveBoundingBoxEXT(const Context *context, + angle::EntryPoint entryPoint, + GLfloat minX, + GLfloat minY, + GLfloat minZ, + GLfloat minW, + GLfloat maxX, + GLfloat maxY, + GLfloat maxZ, + GLfloat maxW); + +// GL_EXT_protected_textures + +// GL_EXT_pvrtc_sRGB + +// GL_EXT_read_format_bgra + +// GL_EXT_robustness +bool ValidateGetGraphicsResetStatusEXT(const Context *context, angle::EntryPoint entryPoint); +bool ValidateGetnUniformfvEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + const GLfloat *params); +bool ValidateGetnUniformivEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + const GLint *params); +bool ValidateReadnPixelsEXT(const Context *context, + angle::EntryPoint entryPoint, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *data); + +// GL_EXT_sRGB + +// GL_EXT_sRGB_write_control + +// GL_EXT_semaphore +bool ValidateDeleteSemaphoresEXT(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const SemaphoreID *semaphoresPacked); +bool ValidateGenSemaphoresEXT(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const SemaphoreID *semaphoresPacked); +bool ValidateGetSemaphoreParameterui64vEXT(const Context *context, + angle::EntryPoint entryPoint, + SemaphoreID semaphorePacked, + GLenum pname, + const GLuint64 *params); +bool ValidateIsSemaphoreEXT(const Context *context, + angle::EntryPoint entryPoint, + SemaphoreID semaphorePacked); +bool ValidateSemaphoreParameterui64vEXT(const Context *context, + angle::EntryPoint entryPoint, + SemaphoreID semaphorePacked, + GLenum pname, + const GLuint64 *params); +bool ValidateSignalSemaphoreEXT(const Context *context, + angle::EntryPoint entryPoint, + SemaphoreID semaphorePacked, + GLuint numBufferBarriers, + const BufferID *buffersPacked, + GLuint numTextureBarriers, + const TextureID *texturesPacked, + const GLenum *dstLayouts); +bool ValidateWaitSemaphoreEXT(const Context *context, + angle::EntryPoint entryPoint, + SemaphoreID semaphorePacked, + GLuint numBufferBarriers, + const BufferID *buffersPacked, + GLuint numTextureBarriers, + const TextureID *texturesPacked, + const GLenum *srcLayouts); + +// GL_EXT_semaphore_fd +bool ValidateImportSemaphoreFdEXT(const Context *context, + angle::EntryPoint entryPoint, + SemaphoreID semaphorePacked, + HandleType handleTypePacked, + GLint fd); + +// GL_EXT_separate_shader_objects +bool ValidateActiveShaderProgramEXT(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked, + ShaderProgramID programPacked); +bool ValidateBindProgramPipelineEXT(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked); +bool ValidateCreateShaderProgramvEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderType typePacked, + GLsizei count, + const GLchar **strings); +bool ValidateDeleteProgramPipelinesEXT(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const ProgramPipelineID *pipelinesPacked); +bool ValidateGenProgramPipelinesEXT(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const ProgramPipelineID *pipelinesPacked); +bool ValidateGetProgramPipelineInfoLogEXT(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked, + GLsizei bufSize, + const GLsizei *length, + const GLchar *infoLog); +bool ValidateGetProgramPipelineivEXT(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked, + GLenum pname, + const GLint *params); +bool ValidateIsProgramPipelineEXT(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked); +bool ValidateProgramParameteriEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLenum pname, + GLint value); +bool ValidateProgramUniform1fEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLfloat v0); +bool ValidateProgramUniform1fvEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value); +bool ValidateProgramUniform1iEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLint v0); +bool ValidateProgramUniform1ivEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value); +bool ValidateProgramUniform1uiEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLuint v0); +bool ValidateProgramUniform1uivEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value); +bool ValidateProgramUniform2fEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLfloat v0, + GLfloat v1); +bool ValidateProgramUniform2fvEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value); +bool ValidateProgramUniform2iEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLint v0, + GLint v1); +bool ValidateProgramUniform2ivEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value); +bool ValidateProgramUniform2uiEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLuint v0, + GLuint v1); +bool ValidateProgramUniform2uivEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value); +bool ValidateProgramUniform3fEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLfloat v0, + GLfloat v1, + GLfloat v2); +bool ValidateProgramUniform3fvEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value); +bool ValidateProgramUniform3iEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLint v0, + GLint v1, + GLint v2); +bool ValidateProgramUniform3ivEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value); +bool ValidateProgramUniform3uiEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLuint v0, + GLuint v1, + GLuint v2); +bool ValidateProgramUniform3uivEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value); +bool ValidateProgramUniform4fEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLfloat v0, + GLfloat v1, + GLfloat v2, + GLfloat v3); +bool ValidateProgramUniform4fvEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLfloat *value); +bool ValidateProgramUniform4iEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLint v0, + GLint v1, + GLint v2, + GLint v3); +bool ValidateProgramUniform4ivEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLint *value); +bool ValidateProgramUniform4uiEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3); +bool ValidateProgramUniform4uivEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLuint *value); +bool ValidateProgramUniformMatrix2fvEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix2x3fvEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix2x4fvEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix3fvEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix3x2fvEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix3x4fvEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix4fvEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix4x2fvEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix4x3fvEXT(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateUseProgramStagesEXT(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked, + GLbitfield stages, + ShaderProgramID programPacked); +bool ValidateValidateProgramPipelineEXT(const Context *context, + angle::EntryPoint entryPoint, + ProgramPipelineID pipelinePacked); + +// GL_EXT_shader_framebuffer_fetch + +// GL_EXT_shader_framebuffer_fetch_non_coherent +bool ValidateFramebufferFetchBarrierEXT(const Context *context, angle::EntryPoint entryPoint); + +// GL_EXT_shader_io_blocks + +// GL_EXT_shader_non_constant_global_initializers + +// GL_EXT_shader_texture_lod + +// GL_EXT_shadow_samplers + +// GL_EXT_tessellation_shader +bool ValidatePatchParameteriEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLint value); + +// GL_EXT_texture_border_clamp +bool ValidateGetSamplerParameterIivEXT(const Context *context, + angle::EntryPoint entryPoint, + SamplerID samplerPacked, + GLenum pname, + const GLint *params); +bool ValidateGetSamplerParameterIuivEXT(const Context *context, + angle::EntryPoint entryPoint, + SamplerID samplerPacked, + GLenum pname, + const GLuint *params); +bool ValidateGetTexParameterIivEXT(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + const GLint *params); +bool ValidateGetTexParameterIuivEXT(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + const GLuint *params); +bool ValidateSamplerParameterIivEXT(const Context *context, + angle::EntryPoint entryPoint, + SamplerID samplerPacked, + GLenum pname, + const GLint *param); +bool ValidateSamplerParameterIuivEXT(const Context *context, + angle::EntryPoint entryPoint, + SamplerID samplerPacked, + GLenum pname, + const GLuint *param); +bool ValidateTexParameterIivEXT(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + const GLint *params); +bool ValidateTexParameterIuivEXT(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + const GLuint *params); + +// GL_EXT_texture_buffer +bool ValidateTexBufferEXT(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum internalformat, + BufferID bufferPacked); +bool ValidateTexBufferRangeEXT(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum internalformat, + BufferID bufferPacked, + GLintptr offset, + GLsizeiptr size); + +// GL_EXT_texture_compression_bptc + +// GL_EXT_texture_compression_dxt1 + +// GL_EXT_texture_compression_rgtc + +// GL_EXT_texture_compression_s3tc + +// GL_EXT_texture_compression_s3tc_srgb + +// GL_EXT_texture_cube_map_array + +// GL_EXT_texture_filter_anisotropic + +// GL_EXT_texture_format_BGRA8888 + +// GL_EXT_texture_format_sRGB_override + +// GL_EXT_texture_norm16 + +// GL_EXT_texture_rg + +// GL_EXT_texture_sRGB_R8 + +// GL_EXT_texture_sRGB_RG8 + +// GL_EXT_texture_sRGB_decode + +// GL_EXT_texture_storage +bool ValidateTexStorage1DEXT(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width); +bool ValidateTexStorage2DEXT(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height); +bool ValidateTexStorage3DEXT(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth); + +// GL_EXT_texture_type_2_10_10_10_REV + +// GL_EXT_unpack_subimage + +// GL_IMG_texture_compression_pvrtc + +// GL_IMG_texture_compression_pvrtc2 + +// GL_KHR_blend_equation_advanced +bool ValidateBlendBarrierKHR(const Context *context, angle::EntryPoint entryPoint); + +// GL_KHR_debug +bool ValidateDebugMessageCallbackKHR(const Context *context, + angle::EntryPoint entryPoint, + GLDEBUGPROCKHR callback, + const void *userParam); +bool ValidateDebugMessageControlKHR(const Context *context, + angle::EntryPoint entryPoint, + GLenum source, + GLenum type, + GLenum severity, + GLsizei count, + const GLuint *ids, + GLboolean enabled); +bool ValidateDebugMessageInsertKHR(const Context *context, + angle::EntryPoint entryPoint, + GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar *buf); +bool ValidateGetDebugMessageLogKHR(const Context *context, + angle::EntryPoint entryPoint, + GLuint count, + GLsizei bufSize, + const GLenum *sources, + const GLenum *types, + const GLuint *ids, + const GLenum *severities, + const GLsizei *lengths, + const GLchar *messageLog); +bool ValidateGetObjectLabelKHR(const Context *context, + angle::EntryPoint entryPoint, + GLenum identifier, + GLuint name, + GLsizei bufSize, + const GLsizei *length, + const GLchar *label); +bool ValidateGetObjectPtrLabelKHR(const Context *context, + angle::EntryPoint entryPoint, + const void *ptr, + GLsizei bufSize, + const GLsizei *length, + const GLchar *label); +bool ValidateGetPointervKHR(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + void *const *params); +bool ValidateObjectLabelKHR(const Context *context, + angle::EntryPoint entryPoint, + GLenum identifier, + GLuint name, + GLsizei length, + const GLchar *label); +bool ValidateObjectPtrLabelKHR(const Context *context, + angle::EntryPoint entryPoint, + const void *ptr, + GLsizei length, + const GLchar *label); +bool ValidatePopDebugGroupKHR(const Context *context, angle::EntryPoint entryPoint); +bool ValidatePushDebugGroupKHR(const Context *context, + angle::EntryPoint entryPoint, + GLenum source, + GLuint id, + GLsizei length, + const GLchar *message); + +// GL_KHR_no_error + +// GL_KHR_parallel_shader_compile +bool ValidateMaxShaderCompilerThreadsKHR(const Context *context, + angle::EntryPoint entryPoint, + GLuint count); + +// GL_KHR_robust_buffer_access_behavior + +// GL_KHR_texture_compression_astc_hdr + +// GL_KHR_texture_compression_astc_ldr + +// GL_KHR_texture_compression_astc_sliced_3d + +// GL_MESA_framebuffer_flip_y +bool ValidateFramebufferParameteriMESA(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum pname, + GLint param); +bool ValidateGetFramebufferParameterivMESA(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum pname, + const GLint *params); + +// GL_NV_fence +bool ValidateDeleteFencesNV(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const FenceNVID *fencesPacked); +bool ValidateFinishFenceNV(const Context *context, + angle::EntryPoint entryPoint, + FenceNVID fencePacked); +bool ValidateGenFencesNV(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const FenceNVID *fencesPacked); +bool ValidateGetFenceivNV(const Context *context, + angle::EntryPoint entryPoint, + FenceNVID fencePacked, + GLenum pname, + const GLint *params); +bool ValidateIsFenceNV(const Context *context, angle::EntryPoint entryPoint, FenceNVID fencePacked); +bool ValidateSetFenceNV(const Context *context, + angle::EntryPoint entryPoint, + FenceNVID fencePacked, + GLenum condition); +bool ValidateTestFenceNV(const Context *context, + angle::EntryPoint entryPoint, + FenceNVID fencePacked); + +// GL_NV_framebuffer_blit +bool ValidateBlitFramebufferNV(const Context *context, + angle::EntryPoint entryPoint, + GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter); + +// GL_NV_pixel_buffer_object + +// GL_NV_read_depth + +// GL_NV_read_depth_stencil + +// GL_NV_read_stencil + +// GL_NV_robustness_video_memory_purge + +// GL_NV_shader_noperspective_interpolation + +// GL_OES_EGL_image +bool ValidateEGLImageTargetRenderbufferStorageOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLeglImageOES image); +bool ValidateEGLImageTargetTexture2DOES(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLeglImageOES image); + +// GL_OES_EGL_image_external + +// GL_OES_EGL_image_external_essl3 + +// GL_OES_compressed_ETC1_RGB8_texture + +// GL_OES_compressed_paletted_texture + +// GL_OES_copy_image +bool ValidateCopyImageSubDataOES(const Context *context, + angle::EntryPoint entryPoint, + GLuint srcName, + GLenum srcTarget, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLuint dstName, + GLenum dstTarget, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth); + +// GL_OES_depth24 + +// GL_OES_depth32 + +// GL_OES_depth_texture + +// GL_OES_draw_buffers_indexed +bool ValidateBlendEquationSeparateiOES(const Context *context, + angle::EntryPoint entryPoint, + GLuint buf, + GLenum modeRGB, + GLenum modeAlpha); +bool ValidateBlendEquationiOES(const Context *context, + angle::EntryPoint entryPoint, + GLuint buf, + GLenum mode); +bool ValidateBlendFuncSeparateiOES(const Context *context, + angle::EntryPoint entryPoint, + GLuint buf, + GLenum srcRGB, + GLenum dstRGB, + GLenum srcAlpha, + GLenum dstAlpha); +bool ValidateBlendFunciOES(const Context *context, + angle::EntryPoint entryPoint, + GLuint buf, + GLenum src, + GLenum dst); +bool ValidateColorMaskiOES(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLboolean r, + GLboolean g, + GLboolean b, + GLboolean a); +bool ValidateDisableiOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index); +bool ValidateEnableiOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index); +bool ValidateIsEnablediOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index); + +// GL_OES_draw_elements_base_vertex +bool ValidateDrawElementsBaseVertexOES(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLint basevertex); +bool ValidateDrawElementsInstancedBaseVertexOES(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLsizei instancecount, + GLint basevertex); +bool ValidateDrawRangeElementsBaseVertexOES(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + GLuint start, + GLuint end, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLint basevertex); + +// GL_OES_draw_texture +bool ValidateDrawTexfOES(const Context *context, + angle::EntryPoint entryPoint, + GLfloat x, + GLfloat y, + GLfloat z, + GLfloat width, + GLfloat height); +bool ValidateDrawTexfvOES(const Context *context, + angle::EntryPoint entryPoint, + const GLfloat *coords); +bool ValidateDrawTexiOES(const Context *context, + angle::EntryPoint entryPoint, + GLint x, + GLint y, + GLint z, + GLint width, + GLint height); +bool ValidateDrawTexivOES(const Context *context, + angle::EntryPoint entryPoint, + const GLint *coords); +bool ValidateDrawTexsOES(const Context *context, + angle::EntryPoint entryPoint, + GLshort x, + GLshort y, + GLshort z, + GLshort width, + GLshort height); +bool ValidateDrawTexsvOES(const Context *context, + angle::EntryPoint entryPoint, + const GLshort *coords); +bool ValidateDrawTexxOES(const Context *context, + angle::EntryPoint entryPoint, + GLfixed x, + GLfixed y, + GLfixed z, + GLfixed width, + GLfixed height); +bool ValidateDrawTexxvOES(const Context *context, + angle::EntryPoint entryPoint, + const GLfixed *coords); + +// GL_OES_element_index_uint + +// GL_OES_fbo_render_mipmap + +// GL_OES_framebuffer_object +bool ValidateBindFramebufferOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + FramebufferID framebufferPacked); +bool ValidateBindRenderbufferOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + RenderbufferID renderbufferPacked); +bool ValidateCheckFramebufferStatusOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum target); +bool ValidateDeleteFramebuffersOES(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const FramebufferID *framebuffersPacked); +bool ValidateDeleteRenderbuffersOES(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const RenderbufferID *renderbuffersPacked); +bool ValidateFramebufferRenderbufferOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + GLenum renderbuffertarget, + RenderbufferID renderbufferPacked); +bool ValidateFramebufferTexture2DOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + TextureTarget textargetPacked, + TextureID texturePacked, + GLint level); +bool ValidateGenFramebuffersOES(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const FramebufferID *framebuffersPacked); +bool ValidateGenRenderbuffersOES(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const RenderbufferID *renderbuffersPacked); +bool ValidateGenerateMipmapOES(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked); +bool ValidateGetFramebufferAttachmentParameterivOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + GLenum pname, + const GLint *params); +bool ValidateGetRenderbufferParameterivOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum pname, + const GLint *params); +bool ValidateIsFramebufferOES(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebufferPacked); +bool ValidateIsRenderbufferOES(const Context *context, + angle::EntryPoint entryPoint, + RenderbufferID renderbufferPacked); +bool ValidateRenderbufferStorageOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum internalformat, + GLsizei width, + GLsizei height); + +// GL_OES_geometry_shader +bool ValidateFramebufferTextureOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + TextureID texturePacked, + GLint level); + +// GL_OES_get_program_binary +bool ValidateGetProgramBinaryOES(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLsizei bufSize, + const GLsizei *length, + const GLenum *binaryFormat, + const void *binary); +bool ValidateProgramBinaryOES(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLenum binaryFormat, + const void *binary, + GLint length); + +// GL_OES_mapbuffer +bool ValidateGetBufferPointervOES(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding targetPacked, + GLenum pname, + void *const *params); +bool ValidateMapBufferOES(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding targetPacked, + GLenum access); +bool ValidateUnmapBufferOES(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding targetPacked); + +// GL_OES_matrix_palette +bool ValidateCurrentPaletteMatrixOES(const Context *context, + angle::EntryPoint entryPoint, + GLuint matrixpaletteindex); +bool ValidateLoadPaletteFromModelViewMatrixOES(const Context *context, + angle::EntryPoint entryPoint); +bool ValidateMatrixIndexPointerOES(const Context *context, + angle::EntryPoint entryPoint, + GLint size, + GLenum type, + GLsizei stride, + const void *pointer); +bool ValidateWeightPointerOES(const Context *context, + angle::EntryPoint entryPoint, + GLint size, + GLenum type, + GLsizei stride, + const void *pointer); + +// GL_OES_packed_depth_stencil + +// GL_OES_point_size_array +bool ValidatePointSizePointerOES(const Context *context, + angle::EntryPoint entryPoint, + VertexAttribType typePacked, + GLsizei stride, + const void *pointer); + +// GL_OES_point_sprite + +// GL_OES_primitive_bounding_box +bool ValidatePrimitiveBoundingBoxOES(const Context *context, + angle::EntryPoint entryPoint, + GLfloat minX, + GLfloat minY, + GLfloat minZ, + GLfloat minW, + GLfloat maxX, + GLfloat maxY, + GLfloat maxZ, + GLfloat maxW); + +// GL_OES_query_matrix +bool ValidateQueryMatrixxOES(const Context *context, + angle::EntryPoint entryPoint, + const GLfixed *mantissa, + const GLint *exponent); + +// GL_OES_rgb8_rgba8 + +// GL_OES_sample_shading +bool ValidateMinSampleShadingOES(const Context *context, + angle::EntryPoint entryPoint, + GLfloat value); + +// GL_OES_sample_variables + +// GL_OES_shader_image_atomic + +// GL_OES_shader_io_blocks + +// GL_OES_shader_multisample_interpolation + +// GL_OES_standard_derivatives + +// GL_OES_surfaceless_context + +// GL_OES_texture_3D +bool ValidateCompressedTexImage3DOES(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + const void *data); +bool ValidateCompressedTexSubImage3DOES(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const void *data); +bool ValidateCopyTexSubImage3DOES(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height); +bool ValidateFramebufferTexture3DOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + TextureTarget textargetPacked, + TextureID texturePacked, + GLint level, + GLint zoffset); +bool ValidateTexImage3DOES(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const void *pixels); +bool ValidateTexSubImage3DOES(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *pixels); + +// GL_OES_texture_border_clamp +bool ValidateGetSamplerParameterIivOES(const Context *context, + angle::EntryPoint entryPoint, + SamplerID samplerPacked, + GLenum pname, + const GLint *params); +bool ValidateGetSamplerParameterIuivOES(const Context *context, + angle::EntryPoint entryPoint, + SamplerID samplerPacked, + GLenum pname, + const GLuint *params); +bool ValidateGetTexParameterIivOES(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + const GLint *params); +bool ValidateGetTexParameterIuivOES(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + const GLuint *params); +bool ValidateSamplerParameterIivOES(const Context *context, + angle::EntryPoint entryPoint, + SamplerID samplerPacked, + GLenum pname, + const GLint *param); +bool ValidateSamplerParameterIuivOES(const Context *context, + angle::EntryPoint entryPoint, + SamplerID samplerPacked, + GLenum pname, + const GLuint *param); +bool ValidateTexParameterIivOES(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + const GLint *params); +bool ValidateTexParameterIuivOES(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum pname, + const GLuint *params); + +// GL_OES_texture_buffer +bool ValidateTexBufferOES(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum internalformat, + BufferID bufferPacked); +bool ValidateTexBufferRangeOES(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLenum internalformat, + BufferID bufferPacked, + GLintptr offset, + GLsizeiptr size); + +// GL_OES_texture_compression_astc + +// GL_OES_texture_cube_map +bool ValidateGetTexGenfvOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + const GLfloat *params); +bool ValidateGetTexGenivOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + const GLint *params); +bool ValidateGetTexGenxvOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + const GLfixed *params); +bool ValidateTexGenfOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + GLfloat param); +bool ValidateTexGenfvOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + const GLfloat *params); +bool ValidateTexGeniOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + GLint param); +bool ValidateTexGenivOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + const GLint *params); +bool ValidateTexGenxOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + GLfixed param); +bool ValidateTexGenxvOES(const Context *context, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + const GLfixed *params); + +// GL_OES_texture_cube_map_array + +// GL_OES_texture_float + +// GL_OES_texture_float_linear + +// GL_OES_texture_half_float + +// GL_OES_texture_half_float_linear + +// GL_OES_texture_npot + +// GL_OES_texture_stencil8 + +// GL_OES_texture_storage_multisample_2d_array +bool ValidateTexStorage3DMultisampleOES(const Context *context, + angle::EntryPoint entryPoint, + TextureType targetPacked, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedsamplelocations); + +// GL_OES_vertex_array_object +bool ValidateBindVertexArrayOES(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID arrayPacked); +bool ValidateDeleteVertexArraysOES(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const VertexArrayID *arraysPacked); +bool ValidateGenVertexArraysOES(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const VertexArrayID *arraysPacked); +bool ValidateIsVertexArrayOES(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID arrayPacked); + +// GL_OES_vertex_half_float + +// GL_OES_vertex_type_10_10_10_2 + +// GL_OVR_multiview +bool ValidateFramebufferTextureMultiviewOVR(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + TextureID texturePacked, + GLint level, + GLint baseViewIndex, + GLsizei numViews); + +// GL_OVR_multiview2 + +// GL_QCOM_shading_rate +bool ValidateShadingRateQCOM(const Context *context, angle::EntryPoint entryPoint, GLenum rate); +} // namespace gl + +#endif // LIBANGLE_VALIDATION_ESEXT_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/validationGL1.cpp b/gfx/angle/checkout/src/libANGLE/validationGL1.cpp new file mode 100644 index 0000000000..3e884d4014 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationGL1.cpp @@ -0,0 +1,2421 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// validationGL1.cpp: Validation functions for OpenGL 1.0 entry point parameters + +#include "libANGLE/validationGL1_autogen.h" + +namespace gl +{ + +bool ValidateAccum(const Context *, angle::EntryPoint entryPoint, GLenum op, GLfloat value) +{ + return true; +} + +bool ValidateBegin(const Context *, angle::EntryPoint entryPoint, GLenum mode) +{ + return true; +} + +bool ValidateBitmap(const Context *, + angle::EntryPoint entryPoint, + GLsizei width, + GLsizei height, + GLfloat xorig, + GLfloat yorig, + GLfloat xmove, + GLfloat ymove, + const GLubyte *bitmap) +{ + return true; +} + +bool ValidateCallList(const Context *, angle::EntryPoint entryPoint, GLuint list) +{ + return true; +} + +bool ValidateCallLists(const Context *, + angle::EntryPoint entryPoint, + GLsizei n, + GLenum type, + const void *lists) +{ + return true; +} + +bool ValidateClearAccum(const Context *, + angle::EntryPoint entryPoint, + GLfloat red, + GLfloat green, + GLfloat blue, + GLfloat alpha) +{ + return true; +} + +bool ValidateClearDepth(const Context *, angle::EntryPoint entryPoint, GLdouble depth) +{ + return true; +} + +bool ValidateClearIndex(const Context *, angle::EntryPoint entryPoint, GLfloat c) +{ + return true; +} + +bool ValidateClipPlane(const Context *, + angle::EntryPoint entryPoint, + GLenum plane, + const GLdouble *equation) +{ + return true; +} + +bool ValidateColor3b(const Context *, + angle::EntryPoint entryPoint, + GLbyte red, + GLbyte green, + GLbyte blue) +{ + return true; +} + +bool ValidateColor3bv(const Context *, angle::EntryPoint entryPoint, const GLbyte *v) +{ + return true; +} + +bool ValidateColor3d(const Context *, + angle::EntryPoint entryPoint, + GLdouble red, + GLdouble green, + GLdouble blue) +{ + return true; +} + +bool ValidateColor3dv(const Context *, angle::EntryPoint entryPoint, const GLdouble *v) +{ + return true; +} + +bool ValidateColor3f(const Context *, + angle::EntryPoint entryPoint, + GLfloat red, + GLfloat green, + GLfloat blue) +{ + return true; +} + +bool ValidateColor3fv(const Context *, angle::EntryPoint entryPoint, const GLfloat *v) +{ + return true; +} + +bool ValidateColor3i(const Context *, + angle::EntryPoint entryPoint, + GLint red, + GLint green, + GLint blue) +{ + return true; +} + +bool ValidateColor3iv(const Context *, angle::EntryPoint entryPoint, const GLint *v) +{ + return true; +} + +bool ValidateColor3s(const Context *, + angle::EntryPoint entryPoint, + GLshort red, + GLshort green, + GLshort blue) +{ + return true; +} + +bool ValidateColor3sv(const Context *, angle::EntryPoint entryPoint, const GLshort *v) +{ + return true; +} + +bool ValidateColor3ub(const Context *, + angle::EntryPoint entryPoint, + GLubyte red, + GLubyte green, + GLubyte blue) +{ + return true; +} + +bool ValidateColor3ubv(const Context *, angle::EntryPoint entryPoint, const GLubyte *v) +{ + return true; +} + +bool ValidateColor3ui(const Context *, + angle::EntryPoint entryPoint, + GLuint red, + GLuint green, + GLuint blue) +{ + return true; +} + +bool ValidateColor3uiv(const Context *, angle::EntryPoint entryPoint, const GLuint *v) +{ + return true; +} + +bool ValidateColor3us(const Context *, + angle::EntryPoint entryPoint, + GLushort red, + GLushort green, + GLushort blue) +{ + return true; +} + +bool ValidateColor3usv(const Context *, angle::EntryPoint entryPoint, const GLushort *v) +{ + return true; +} + +bool ValidateColor4b(const Context *, + angle::EntryPoint entryPoint, + GLbyte red, + GLbyte green, + GLbyte blue, + GLbyte alpha) +{ + return true; +} + +bool ValidateColor4bv(const Context *, angle::EntryPoint entryPoint, const GLbyte *v) +{ + return true; +} + +bool ValidateColor4d(const Context *, + angle::EntryPoint entryPoint, + GLdouble red, + GLdouble green, + GLdouble blue, + GLdouble alpha) +{ + return true; +} + +bool ValidateColor4dv(const Context *, angle::EntryPoint entryPoint, const GLdouble *v) +{ + return true; +} + +bool ValidateColor4fv(const Context *, angle::EntryPoint entryPoint, const GLfloat *v) +{ + return true; +} + +bool ValidateColor4i(const Context *, + angle::EntryPoint entryPoint, + GLint red, + GLint green, + GLint blue, + GLint alpha) +{ + return true; +} + +bool ValidateColor4iv(const Context *, angle::EntryPoint entryPoint, const GLint *v) +{ + return true; +} + +bool ValidateColor4s(const Context *, + angle::EntryPoint entryPoint, + GLshort red, + GLshort green, + GLshort blue, + GLshort alpha) +{ + return true; +} + +bool ValidateColor4sv(const Context *, angle::EntryPoint entryPoint, const GLshort *v) +{ + return true; +} + +bool ValidateColor4ubv(const Context *, angle::EntryPoint entryPoint, const GLubyte *v) +{ + return true; +} + +bool ValidateColor4ui(const Context *, + angle::EntryPoint entryPoint, + GLuint red, + GLuint green, + GLuint blue, + GLuint alpha) +{ + return true; +} + +bool ValidateColor4uiv(const Context *, angle::EntryPoint entryPoint, const GLuint *v) +{ + return true; +} + +bool ValidateColor4us(const Context *, + angle::EntryPoint entryPoint, + GLushort red, + GLushort green, + GLushort blue, + GLushort alpha) +{ + return true; +} + +bool ValidateColor4usv(const Context *, angle::EntryPoint entryPoint, const GLushort *v) +{ + return true; +} + +bool ValidateColorMaterial(const Context *, angle::EntryPoint entryPoint, GLenum face, GLenum mode) +{ + return true; +} + +bool ValidateCopyPixels(const Context *, + angle::EntryPoint entryPoint, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum type) +{ + return true; +} + +bool ValidateDeleteLists(const Context *, angle::EntryPoint entryPoint, GLuint list, GLsizei range) +{ + return true; +} + +bool ValidateDepthRange(const Context *, angle::EntryPoint entryPoint, GLdouble n, GLdouble f) +{ + return true; +} + +bool ValidateDrawBuffer(const Context *, angle::EntryPoint entryPoint, GLenum buf) +{ + return true; +} + +bool ValidateDrawPixels(const Context *, + angle::EntryPoint entryPoint, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void *pixels) +{ + return true; +} + +bool ValidateEdgeFlag(const Context *, angle::EntryPoint entryPoint, GLboolean flag) +{ + return true; +} + +bool ValidateEdgeFlagv(const Context *, angle::EntryPoint entryPoint, const GLboolean *flag) +{ + return true; +} + +bool ValidateEnd(const Context *, angle::EntryPoint entryPoint) +{ + return true; +} + +bool ValidateEndList(const Context *, angle::EntryPoint entryPoint) +{ + return true; +} + +bool ValidateEvalCoord1d(const Context *, angle::EntryPoint entryPoint, GLdouble u) +{ + return true; +} + +bool ValidateEvalCoord1dv(const Context *, angle::EntryPoint entryPoint, const GLdouble *u) +{ + return true; +} + +bool ValidateEvalCoord1f(const Context *, angle::EntryPoint entryPoint, GLfloat u) +{ + return true; +} + +bool ValidateEvalCoord1fv(const Context *, angle::EntryPoint entryPoint, const GLfloat *u) +{ + return true; +} + +bool ValidateEvalCoord2d(const Context *, angle::EntryPoint entryPoint, GLdouble u, GLdouble v) +{ + return true; +} + +bool ValidateEvalCoord2dv(const Context *, angle::EntryPoint entryPoint, const GLdouble *u) +{ + return true; +} + +bool ValidateEvalCoord2f(const Context *, angle::EntryPoint entryPoint, GLfloat u, GLfloat v) +{ + return true; +} + +bool ValidateEvalCoord2fv(const Context *, angle::EntryPoint entryPoint, const GLfloat *u) +{ + return true; +} + +bool ValidateEvalMesh1(const Context *, + angle::EntryPoint entryPoint, + GLenum mode, + GLint i1, + GLint i2) +{ + return true; +} + +bool ValidateEvalMesh2(const Context *, + angle::EntryPoint entryPoint, + GLenum mode, + GLint i1, + GLint i2, + GLint j1, + GLint j2) +{ + return true; +} + +bool ValidateEvalPoint1(const Context *, angle::EntryPoint entryPoint, GLint i) +{ + return true; +} + +bool ValidateEvalPoint2(const Context *, angle::EntryPoint entryPoint, GLint i, GLint j) +{ + return true; +} + +bool ValidateFeedbackBuffer(const Context *, + angle::EntryPoint entryPoint, + GLsizei size, + GLenum type, + const GLfloat *buffer) +{ + return true; +} + +bool ValidateFogi(const Context *, angle::EntryPoint entryPoint, GLenum pname, GLint param) +{ + return true; +} + +bool ValidateFogiv(const Context *, angle::EntryPoint entryPoint, GLenum pname, const GLint *params) +{ + return true; +} + +bool ValidateFrustum(const Context *, + angle::EntryPoint entryPoint, + GLdouble left, + GLdouble right, + GLdouble bottom, + GLdouble top, + GLdouble zNear, + GLdouble zFar) +{ + return true; +} + +bool ValidateGenLists(const Context *, angle::EntryPoint entryPoint, GLsizei range) +{ + return true; +} + +bool ValidateGetClipPlane(const Context *, + angle::EntryPoint entryPoint, + GLenum plane, + const GLdouble *equation) +{ + return true; +} + +bool ValidateGetDoublev(const Context *, + angle::EntryPoint entryPoint, + GLenum pname, + const GLdouble *data) +{ + return true; +} + +bool ValidateGetLightiv(const Context *, + angle::EntryPoint entryPoint, + GLenum light, + GLenum pname, + const GLint *params) +{ + return true; +} + +bool ValidateGetMapdv(const Context *, + angle::EntryPoint entryPoint, + GLenum target, + GLenum query, + const GLdouble *v) +{ + return true; +} + +bool ValidateGetMapfv(const Context *, + angle::EntryPoint entryPoint, + GLenum target, + GLenum query, + const GLfloat *v) +{ + return true; +} + +bool ValidateGetMapiv(const Context *, + angle::EntryPoint entryPoint, + GLenum target, + GLenum query, + const GLint *v) +{ + return true; +} + +bool ValidateGetMaterialiv(const Context *, + angle::EntryPoint entryPoint, + GLenum face, + GLenum pname, + const GLint *params) +{ + return true; +} + +bool ValidateGetPixelMapfv(const Context *, + angle::EntryPoint entryPoint, + GLenum map, + const GLfloat *values) +{ + return true; +} + +bool ValidateGetPixelMapuiv(const Context *, + angle::EntryPoint entryPoint, + GLenum map, + const GLuint *values) +{ + return true; +} + +bool ValidateGetPixelMapusv(const Context *, + angle::EntryPoint entryPoint, + GLenum map, + const GLushort *values) +{ + return true; +} + +bool ValidateGetPolygonStipple(const Context *, angle::EntryPoint entryPoint, const GLubyte *mask) +{ + return true; +} + +bool ValidateGetTexGendv(const Context *, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + const GLdouble *params) +{ + return true; +} + +bool ValidateGetTexGenfv(const Context *, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + const GLfloat *params) +{ + return true; +} + +bool ValidateGetTexGeniv(const Context *, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + const GLint *params) +{ + return true; +} + +bool ValidateGetTexImage(const Context *, + angle::EntryPoint entryPoint, + TextureTarget target, + GLint level, + GLenum format, + GLenum type, + const void *pixels) +{ + return true; +} + +bool ValidateIndexMask(const Context *, angle::EntryPoint entryPoint, GLuint mask) +{ + return true; +} + +bool ValidateIndexd(const Context *, angle::EntryPoint entryPoint, GLdouble c) +{ + return true; +} + +bool ValidateIndexdv(const Context *, angle::EntryPoint entryPoint, const GLdouble *c) +{ + return true; +} + +bool ValidateIndexf(const Context *, angle::EntryPoint entryPoint, GLfloat c) +{ + return true; +} + +bool ValidateIndexfv(const Context *, angle::EntryPoint entryPoint, const GLfloat *c) +{ + return true; +} + +bool ValidateIndexi(const Context *, angle::EntryPoint entryPoint, GLint c) +{ + return true; +} + +bool ValidateIndexiv(const Context *, angle::EntryPoint entryPoint, const GLint *c) +{ + return true; +} + +bool ValidateIndexs(const Context *, angle::EntryPoint entryPoint, GLshort c) +{ + return true; +} + +bool ValidateIndexsv(const Context *, angle::EntryPoint entryPoint, const GLshort *c) +{ + return true; +} + +bool ValidateInitNames(const Context *, angle::EntryPoint entryPoint) +{ + return true; +} + +bool ValidateIsList(const Context *, angle::EntryPoint entryPoint, GLuint list) +{ + return true; +} + +bool ValidateLightModeli(const Context *, angle::EntryPoint entryPoint, GLenum pname, GLint param) +{ + return true; +} + +bool ValidateLightModeliv(const Context *, + angle::EntryPoint entryPoint, + GLenum pname, + const GLint *params) +{ + return true; +} + +bool ValidateLighti(const Context *, + angle::EntryPoint entryPoint, + GLenum light, + GLenum pname, + GLint param) +{ + return true; +} + +bool ValidateLightiv(const Context *, + angle::EntryPoint entryPoint, + GLenum light, + GLenum pname, + const GLint *params) +{ + return true; +} + +bool ValidateLineStipple(const Context *, + angle::EntryPoint entryPoint, + GLint factor, + GLushort pattern) +{ + return true; +} + +bool ValidateListBase(const Context *, angle::EntryPoint entryPoint, GLuint base) +{ + return true; +} + +bool ValidateLoadMatrixd(const Context *, angle::EntryPoint entryPoint, const GLdouble *m) +{ + return true; +} + +bool ValidateLoadName(const Context *, angle::EntryPoint entryPoint, GLuint name) +{ + return true; +} + +bool ValidateMap1d(const Context *, + angle::EntryPoint entryPoint, + GLenum target, + GLdouble u1, + GLdouble u2, + GLint stride, + GLint order, + const GLdouble *points) +{ + return true; +} + +bool ValidateMap1f(const Context *, + angle::EntryPoint entryPoint, + GLenum target, + GLfloat u1, + GLfloat u2, + GLint stride, + GLint order, + const GLfloat *points) +{ + return true; +} + +bool ValidateMap2d(const Context *, + angle::EntryPoint entryPoint, + GLenum target, + GLdouble u1, + GLdouble u2, + GLint ustride, + GLint uorder, + GLdouble v1, + GLdouble v2, + GLint vstride, + GLint vorder, + const GLdouble *points) +{ + return true; +} + +bool ValidateMap2f(const Context *, + angle::EntryPoint entryPoint, + GLenum target, + GLfloat u1, + GLfloat u2, + GLint ustride, + GLint uorder, + GLfloat v1, + GLfloat v2, + GLint vstride, + GLint vorder, + const GLfloat *points) +{ + return true; +} + +bool ValidateMapGrid1d(const Context *, + angle::EntryPoint entryPoint, + GLint un, + GLdouble u1, + GLdouble u2) +{ + return true; +} + +bool ValidateMapGrid1f(const Context *, + angle::EntryPoint entryPoint, + GLint un, + GLfloat u1, + GLfloat u2) +{ + return true; +} + +bool ValidateMapGrid2d(const Context *, + angle::EntryPoint entryPoint, + GLint un, + GLdouble u1, + GLdouble u2, + GLint vn, + GLdouble v1, + GLdouble v2) +{ + return true; +} + +bool ValidateMapGrid2f(const Context *, + angle::EntryPoint entryPoint, + GLint un, + GLfloat u1, + GLfloat u2, + GLint vn, + GLfloat v1, + GLfloat v2) +{ + return true; +} + +bool ValidateMateriali(const Context *, + angle::EntryPoint entryPoint, + GLenum face, + GLenum pname, + GLint param) +{ + return true; +} + +bool ValidateMaterialiv(const Context *, + angle::EntryPoint entryPoint, + GLenum face, + GLenum pname, + const GLint *params) +{ + return true; +} + +bool ValidateMultMatrixd(const Context *, angle::EntryPoint entryPoint, const GLdouble *m) +{ + return true; +} + +bool ValidateNewList(const Context *, angle::EntryPoint entryPoint, GLuint list, GLenum mode) +{ + return true; +} + +bool ValidateNormal3b(const Context *, + angle::EntryPoint entryPoint, + GLbyte nx, + GLbyte ny, + GLbyte nz) +{ + return true; +} + +bool ValidateNormal3bv(const Context *, angle::EntryPoint entryPoint, const GLbyte *v) +{ + return true; +} + +bool ValidateNormal3d(const Context *, + angle::EntryPoint entryPoint, + GLdouble nx, + GLdouble ny, + GLdouble nz) +{ + return true; +} + +bool ValidateNormal3dv(const Context *, angle::EntryPoint entryPoint, const GLdouble *v) +{ + return true; +} + +bool ValidateNormal3fv(const Context *, angle::EntryPoint entryPoint, const GLfloat *v) +{ + return true; +} + +bool ValidateNormal3i(const Context *, angle::EntryPoint entryPoint, GLint nx, GLint ny, GLint nz) +{ + return true; +} + +bool ValidateNormal3iv(const Context *, angle::EntryPoint entryPoint, const GLint *v) +{ + return true; +} + +bool ValidateNormal3s(const Context *, + angle::EntryPoint entryPoint, + GLshort nx, + GLshort ny, + GLshort nz) +{ + return true; +} + +bool ValidateNormal3sv(const Context *, angle::EntryPoint entryPoint, const GLshort *v) +{ + return true; +} + +bool ValidateOrtho(const Context *, + angle::EntryPoint entryPoint, + GLdouble left, + GLdouble right, + GLdouble bottom, + GLdouble top, + GLdouble zNear, + GLdouble zFar) +{ + return true; +} + +bool ValidatePassThrough(const Context *, angle::EntryPoint entryPoint, GLfloat token) +{ + return true; +} + +bool ValidatePixelMapfv(const Context *, + angle::EntryPoint entryPoint, + GLenum map, + GLsizei mapsize, + const GLfloat *values) +{ + return true; +} + +bool ValidatePixelMapuiv(const Context *, + angle::EntryPoint entryPoint, + GLenum map, + GLsizei mapsize, + const GLuint *values) +{ + return true; +} + +bool ValidatePixelMapusv(const Context *, + angle::EntryPoint entryPoint, + GLenum map, + GLsizei mapsize, + const GLushort *values) +{ + return true; +} + +bool ValidatePixelStoref(const Context *, angle::EntryPoint entryPoint, GLenum pname, GLfloat param) +{ + return true; +} + +bool ValidatePixelTransferf(const Context *, + angle::EntryPoint entryPoint, + GLenum pname, + GLfloat param) +{ + return true; +} + +bool ValidatePixelTransferi(const Context *, + angle::EntryPoint entryPoint, + GLenum pname, + GLint param) +{ + return true; +} + +bool ValidatePixelZoom(const Context *, + angle::EntryPoint entryPoint, + GLfloat xfactor, + GLfloat yfactor) +{ + return true; +} + +bool ValidatePolygonMode(const Context *, angle::EntryPoint entryPoint, GLenum face, GLenum mode) +{ + return true; +} + +bool ValidatePolygonStipple(const Context *, angle::EntryPoint entryPoint, const GLubyte *mask) +{ + return true; +} + +bool ValidatePopAttrib(const Context *, angle::EntryPoint entryPoint) +{ + return true; +} + +bool ValidatePopName(const Context *, angle::EntryPoint entryPoint) +{ + return true; +} + +bool ValidatePushAttrib(const Context *, angle::EntryPoint entryPoint, GLbitfield mask) +{ + return true; +} + +bool ValidatePushName(const Context *, angle::EntryPoint entryPoint, GLuint name) +{ + return true; +} + +bool ValidateRasterPos2d(const Context *, angle::EntryPoint entryPoint, GLdouble x, GLdouble y) +{ + return true; +} + +bool ValidateRasterPos2dv(const Context *, angle::EntryPoint entryPoint, const GLdouble *v) +{ + return true; +} + +bool ValidateRasterPos2f(const Context *, angle::EntryPoint entryPoint, GLfloat x, GLfloat y) +{ + return true; +} + +bool ValidateRasterPos2fv(const Context *, angle::EntryPoint entryPoint, const GLfloat *v) +{ + return true; +} + +bool ValidateRasterPos2i(const Context *, angle::EntryPoint entryPoint, GLint x, GLint y) +{ + return true; +} + +bool ValidateRasterPos2iv(const Context *, angle::EntryPoint entryPoint, const GLint *v) +{ + return true; +} + +bool ValidateRasterPos2s(const Context *, angle::EntryPoint entryPoint, GLshort x, GLshort y) +{ + return true; +} + +bool ValidateRasterPos2sv(const Context *, angle::EntryPoint entryPoint, const GLshort *v) +{ + return true; +} + +bool ValidateRasterPos3d(const Context *, + angle::EntryPoint entryPoint, + GLdouble x, + GLdouble y, + GLdouble z) +{ + return true; +} + +bool ValidateRasterPos3dv(const Context *, angle::EntryPoint entryPoint, const GLdouble *v) +{ + return true; +} + +bool ValidateRasterPos3f(const Context *, + angle::EntryPoint entryPoint, + GLfloat x, + GLfloat y, + GLfloat z) +{ + return true; +} + +bool ValidateRasterPos3fv(const Context *, angle::EntryPoint entryPoint, const GLfloat *v) +{ + return true; +} + +bool ValidateRasterPos3i(const Context *, angle::EntryPoint entryPoint, GLint x, GLint y, GLint z) +{ + return true; +} + +bool ValidateRasterPos3iv(const Context *, angle::EntryPoint entryPoint, const GLint *v) +{ + return true; +} + +bool ValidateRasterPos3s(const Context *, + angle::EntryPoint entryPoint, + GLshort x, + GLshort y, + GLshort z) +{ + return true; +} + +bool ValidateRasterPos3sv(const Context *, angle::EntryPoint entryPoint, const GLshort *v) +{ + return true; +} + +bool ValidateRasterPos4d(const Context *, + angle::EntryPoint entryPoint, + GLdouble x, + GLdouble y, + GLdouble z, + GLdouble w) +{ + return true; +} + +bool ValidateRasterPos4dv(const Context *, angle::EntryPoint entryPoint, const GLdouble *v) +{ + return true; +} + +bool ValidateRasterPos4f(const Context *, + angle::EntryPoint entryPoint, + GLfloat x, + GLfloat y, + GLfloat z, + GLfloat w) +{ + return true; +} + +bool ValidateRasterPos4fv(const Context *, angle::EntryPoint entryPoint, const GLfloat *v) +{ + return true; +} + +bool ValidateRasterPos4i(const Context *, + angle::EntryPoint entryPoint, + GLint x, + GLint y, + GLint z, + GLint w) +{ + return true; +} + +bool ValidateRasterPos4iv(const Context *, angle::EntryPoint entryPoint, const GLint *v) +{ + return true; +} + +bool ValidateRasterPos4s(const Context *, + angle::EntryPoint entryPoint, + GLshort x, + GLshort y, + GLshort z, + GLshort w) +{ + return true; +} + +bool ValidateRasterPos4sv(const Context *, angle::EntryPoint entryPoint, const GLshort *v) +{ + return true; +} + +bool ValidateRectd(const Context *, + angle::EntryPoint entryPoint, + GLdouble x1, + GLdouble y1, + GLdouble x2, + GLdouble y2) +{ + return true; +} + +bool ValidateRectdv(const Context *, + angle::EntryPoint entryPoint, + const GLdouble *v1, + const GLdouble *v2) +{ + return true; +} + +bool ValidateRectf(const Context *, + angle::EntryPoint entryPoint, + GLfloat x1, + GLfloat y1, + GLfloat x2, + GLfloat y2) +{ + return true; +} + +bool ValidateRectfv(const Context *, + angle::EntryPoint entryPoint, + const GLfloat *v1, + const GLfloat *v2) +{ + return true; +} + +bool ValidateRecti(const Context *, + angle::EntryPoint entryPoint, + GLint x1, + GLint y1, + GLint x2, + GLint y2) +{ + return true; +} + +bool ValidateRectiv(const Context *, angle::EntryPoint entryPoint, const GLint *v1, const GLint *v2) +{ + return true; +} + +bool ValidateRects(const Context *, + angle::EntryPoint entryPoint, + GLshort x1, + GLshort y1, + GLshort x2, + GLshort y2) +{ + return true; +} + +bool ValidateRectsv(const Context *, + angle::EntryPoint entryPoint, + const GLshort *v1, + const GLshort *v2) +{ + return true; +} + +bool ValidateRenderMode(const Context *, angle::EntryPoint entryPoint, GLenum mode) +{ + return true; +} + +bool ValidateRotated(const Context *, + angle::EntryPoint entryPoint, + GLdouble angle, + GLdouble x, + GLdouble y, + GLdouble z) +{ + return true; +} + +bool ValidateScaled(const Context *, + angle::EntryPoint entryPoint, + GLdouble x, + GLdouble y, + GLdouble z) +{ + return true; +} + +bool ValidateSelectBuffer(const Context *, + angle::EntryPoint entryPoint, + GLsizei size, + const GLuint *buffer) +{ + return true; +} + +bool ValidateTexCoord1d(const Context *, angle::EntryPoint entryPoint, GLdouble s) +{ + return true; +} + +bool ValidateTexCoord1dv(const Context *, angle::EntryPoint entryPoint, const GLdouble *v) +{ + return true; +} + +bool ValidateTexCoord1f(const Context *, angle::EntryPoint entryPoint, GLfloat s) +{ + return true; +} + +bool ValidateTexCoord1fv(const Context *, angle::EntryPoint entryPoint, const GLfloat *v) +{ + return true; +} + +bool ValidateTexCoord1i(const Context *, angle::EntryPoint entryPoint, GLint s) +{ + return true; +} + +bool ValidateTexCoord1iv(const Context *, angle::EntryPoint entryPoint, const GLint *v) +{ + return true; +} + +bool ValidateTexCoord1s(const Context *, angle::EntryPoint entryPoint, GLshort s) +{ + return true; +} + +bool ValidateTexCoord1sv(const Context *, angle::EntryPoint entryPoint, const GLshort *v) +{ + return true; +} + +bool ValidateTexCoord2d(const Context *, angle::EntryPoint entryPoint, GLdouble s, GLdouble t) +{ + return true; +} + +bool ValidateTexCoord2dv(const Context *, angle::EntryPoint entryPoint, const GLdouble *v) +{ + return true; +} + +bool ValidateTexCoord2f(const Context *, angle::EntryPoint entryPoint, GLfloat s, GLfloat t) +{ + return true; +} + +bool ValidateTexCoord2fv(const Context *, angle::EntryPoint entryPoint, const GLfloat *v) +{ + return true; +} + +bool ValidateTexCoord2i(const Context *, angle::EntryPoint entryPoint, GLint s, GLint t) +{ + return true; +} + +bool ValidateTexCoord2iv(const Context *, angle::EntryPoint entryPoint, const GLint *v) +{ + return true; +} + +bool ValidateTexCoord2s(const Context *, angle::EntryPoint entryPoint, GLshort s, GLshort t) +{ + return true; +} + +bool ValidateTexCoord2sv(const Context *, angle::EntryPoint entryPoint, const GLshort *v) +{ + return true; +} + +bool ValidateTexCoord3d(const Context *, + angle::EntryPoint entryPoint, + GLdouble s, + GLdouble t, + GLdouble r) +{ + return true; +} + +bool ValidateTexCoord3dv(const Context *, angle::EntryPoint entryPoint, const GLdouble *v) +{ + return true; +} + +bool ValidateTexCoord3f(const Context *, + angle::EntryPoint entryPoint, + GLfloat s, + GLfloat t, + GLfloat r) +{ + return true; +} + +bool ValidateTexCoord3fv(const Context *, angle::EntryPoint entryPoint, const GLfloat *v) +{ + return true; +} + +bool ValidateTexCoord3i(const Context *, angle::EntryPoint entryPoint, GLint s, GLint t, GLint r) +{ + return true; +} + +bool ValidateTexCoord3iv(const Context *, angle::EntryPoint entryPoint, const GLint *v) +{ + return true; +} + +bool ValidateTexCoord3s(const Context *, + angle::EntryPoint entryPoint, + GLshort s, + GLshort t, + GLshort r) +{ + return true; +} + +bool ValidateTexCoord3sv(const Context *, angle::EntryPoint entryPoint, const GLshort *v) +{ + return true; +} + +bool ValidateTexCoord4d(const Context *, + angle::EntryPoint entryPoint, + GLdouble s, + GLdouble t, + GLdouble r, + GLdouble q) +{ + return true; +} + +bool ValidateTexCoord4dv(const Context *, angle::EntryPoint entryPoint, const GLdouble *v) +{ + return true; +} + +bool ValidateTexCoord4f(const Context *, + angle::EntryPoint entryPoint, + GLfloat s, + GLfloat t, + GLfloat r, + GLfloat q) +{ + return true; +} + +bool ValidateTexCoord4fv(const Context *, angle::EntryPoint entryPoint, const GLfloat *v) +{ + return true; +} + +bool ValidateTexCoord4i(const Context *, + angle::EntryPoint entryPoint, + GLint s, + GLint t, + GLint r, + GLint q) +{ + return true; +} + +bool ValidateTexCoord4iv(const Context *, angle::EntryPoint entryPoint, const GLint *v) +{ + return true; +} + +bool ValidateTexCoord4s(const Context *, + angle::EntryPoint entryPoint, + GLshort s, + GLshort t, + GLshort r, + GLshort q) +{ + return true; +} + +bool ValidateTexCoord4sv(const Context *, angle::EntryPoint entryPoint, const GLshort *v) +{ + return true; +} + +bool ValidateTexGend(const Context *, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + GLdouble param) +{ + return true; +} + +bool ValidateTexGendv(const Context *, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + const GLdouble *params) +{ + return true; +} + +bool ValidateTexGenf(const Context *, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + GLfloat param) +{ + return true; +} +bool ValidateTexGenfv(const Context *, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + const GLfloat *params) +{ + return true; +} + +bool ValidateTexGeni(const Context *, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + GLint param) +{ + return true; +} + +bool ValidateTexGeniv(const Context *, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + const GLint *params) +{ + return true; +} + +bool ValidateTexImage1D(const Context *, + angle::EntryPoint entryPoint, + GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLint border, + GLenum format, + GLenum type, + const void *pixels) +{ + return true; +} + +bool ValidateTranslated(const Context *, + angle::EntryPoint entryPoint, + GLdouble x, + GLdouble y, + GLdouble z) +{ + return true; +} + +bool ValidateVertex2d(const Context *, angle::EntryPoint entryPoint, GLdouble x, GLdouble y) +{ + return true; +} + +bool ValidateVertex2dv(const Context *, angle::EntryPoint entryPoint, const GLdouble *v) +{ + return true; +} + +bool ValidateVertex2f(const Context *, angle::EntryPoint entryPoint, GLfloat x, GLfloat y) +{ + return true; +} + +bool ValidateVertex2fv(const Context *, angle::EntryPoint entryPoint, const GLfloat *v) +{ + return true; +} + +bool ValidateVertex2i(const Context *, angle::EntryPoint entryPoint, GLint x, GLint y) +{ + return true; +} + +bool ValidateVertex2iv(const Context *, angle::EntryPoint entryPoint, const GLint *v) +{ + return true; +} + +bool ValidateVertex2s(const Context *, angle::EntryPoint entryPoint, GLshort x, GLshort y) +{ + return true; +} + +bool ValidateVertex2sv(const Context *, angle::EntryPoint entryPoint, const GLshort *v) +{ + return true; +} + +bool ValidateVertex3d(const Context *, + angle::EntryPoint entryPoint, + GLdouble x, + GLdouble y, + GLdouble z) +{ + return true; +} + +bool ValidateVertex3dv(const Context *, angle::EntryPoint entryPoint, const GLdouble *v) +{ + return true; +} + +bool ValidateVertex3f(const Context *, + angle::EntryPoint entryPoint, + GLfloat x, + GLfloat y, + GLfloat z) +{ + return true; +} + +bool ValidateVertex3fv(const Context *, angle::EntryPoint entryPoint, const GLfloat *v) +{ + return true; +} + +bool ValidateVertex3i(const Context *, angle::EntryPoint entryPoint, GLint x, GLint y, GLint z) +{ + return true; +} + +bool ValidateVertex3iv(const Context *, angle::EntryPoint entryPoint, const GLint *v) +{ + return true; +} + +bool ValidateVertex3s(const Context *, + angle::EntryPoint entryPoint, + GLshort x, + GLshort y, + GLshort z) +{ + return true; +} + +bool ValidateVertex3sv(const Context *, angle::EntryPoint entryPoint, const GLshort *v) +{ + return true; +} + +bool ValidateVertex4d(const Context *, + angle::EntryPoint entryPoint, + GLdouble x, + GLdouble y, + GLdouble z, + GLdouble w) +{ + return true; +} + +bool ValidateVertex4dv(const Context *, angle::EntryPoint entryPoint, const GLdouble *v) +{ + return true; +} + +bool ValidateVertex4f(const Context *, + angle::EntryPoint entryPoint, + GLfloat x, + GLfloat y, + GLfloat z, + GLfloat w) +{ + return true; +} + +bool ValidateVertex4fv(const Context *, angle::EntryPoint entryPoint, const GLfloat *v) +{ + return true; +} + +bool ValidateVertex4i(const Context *, + angle::EntryPoint entryPoint, + GLint x, + GLint y, + GLint z, + GLint w) +{ + return true; +} + +bool ValidateVertex4iv(const Context *, angle::EntryPoint entryPoint, const GLint *v) +{ + return true; +} + +bool ValidateVertex4s(const Context *, + angle::EntryPoint entryPoint, + GLshort x, + GLshort y, + GLshort z, + GLshort w) +{ + return true; +} + +bool ValidateVertex4sv(const Context *, angle::EntryPoint entryPoint, const GLshort *v) +{ + return true; +} + +bool ValidateAreTexturesResident(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const GLuint *textures, + const GLboolean *residences) +{ + return true; +} + +bool ValidateArrayElement(const Context *context, angle::EntryPoint entryPoint, GLint i) +{ + return true; +} + +bool ValidateCopyTexImage1D(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLint level, + GLenum internalformat, + GLint x, + GLint y, + GLsizei width, + GLint border) +{ + return true; +} + +bool ValidateCopyTexSubImage1D(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLint level, + GLint xoffset, + GLint x, + GLint y, + GLsizei width) +{ + return true; +} + +bool ValidateEdgeFlagPointer(const Context *context, + angle::EntryPoint entryPoint, + GLsizei stride, + const void *pointer) +{ + return true; +} + +bool ValidateIndexPointer(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + GLsizei stride, + const void *pointer) +{ + return true; +} + +bool ValidateIndexub(const Context *context, angle::EntryPoint entryPoint, GLubyte c) +{ + return true; +} + +bool ValidateIndexubv(const Context *context, angle::EntryPoint entryPoint, const GLubyte *c) +{ + return true; +} + +bool ValidateInterleavedArrays(const Context *context, + angle::EntryPoint entryPoint, + GLenum format, + GLsizei stride, + const void *pointer) +{ + return true; +} + +bool ValidatePopClientAttrib(const Context *context, angle::EntryPoint entryPoint) +{ + return true; +} + +bool ValidatePrioritizeTextures(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const GLuint *textures, + const GLfloat *priorities) +{ + return true; +} + +bool ValidatePushClientAttrib(const Context *context, angle::EntryPoint entryPoint, GLbitfield mask) +{ + return true; +} + +bool ValidateTexSubImage1D(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, + GLenum type, + const void *pixels) +{ + return true; +} + +bool ValidateCompressedTexImage1D(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLint border, + GLsizei imageSize, + const void *data) +{ + return true; +} + +bool ValidateCompressedTexSubImage1D(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, + GLsizei imageSize, + const void *data) +{ + return true; +} + +bool ValidateGetCompressedTexImage(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + const void *img) +{ + return true; +} + +bool ValidateLoadTransposeMatrixd(const Context *context, + angle::EntryPoint entryPoint, + const GLdouble *m) +{ + return true; +} + +bool ValidateLoadTransposeMatrixf(const Context *context, + angle::EntryPoint entryPoint, + const GLfloat *m) +{ + return true; +} + +bool ValidateMultTransposeMatrixd(const Context *context, + angle::EntryPoint entryPoint, + const GLdouble *m) +{ + return true; +} + +bool ValidateMultTransposeMatrixf(const Context *context, + angle::EntryPoint entryPoint, + const GLfloat *m) +{ + return true; +} + +bool ValidateMultiTexCoord1d(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLdouble s) +{ + return true; +} + +bool ValidateMultiTexCoord1dv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLdouble *v) +{ + return true; +} + +bool ValidateMultiTexCoord1f(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLfloat s) +{ + return true; +} + +bool ValidateMultiTexCoord1fv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLfloat *v) +{ + return true; +} + +bool ValidateMultiTexCoord1i(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLint s) +{ + return true; +} + +bool ValidateMultiTexCoord1iv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLint *v) +{ + return true; +} + +bool ValidateMultiTexCoord1s(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLshort s) +{ + return true; +} + +bool ValidateMultiTexCoord1sv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLshort *v) +{ + return true; +} + +bool ValidateMultiTexCoord2d(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLdouble s, + GLdouble t) +{ + return true; +} + +bool ValidateMultiTexCoord2dv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLdouble *v) +{ + return true; +} + +bool ValidateMultiTexCoord2f(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLfloat s, + GLfloat t) +{ + return true; +} + +bool ValidateMultiTexCoord2fv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLfloat *v) +{ + return true; +} + +bool ValidateMultiTexCoord2i(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLint s, + GLint t) +{ + return true; +} + +bool ValidateMultiTexCoord2iv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLint *v) +{ + return true; +} + +bool ValidateMultiTexCoord2s(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLshort s, + GLshort t) +{ + return true; +} + +bool ValidateMultiTexCoord2sv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLshort *v) +{ + return true; +} + +bool ValidateMultiTexCoord3d(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLdouble s, + GLdouble t, + GLdouble r) +{ + return true; +} + +bool ValidateMultiTexCoord3dv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLdouble *v) +{ + return true; +} + +bool ValidateMultiTexCoord3f(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLfloat s, + GLfloat t, + GLfloat r) +{ + return true; +} + +bool ValidateMultiTexCoord3fv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLfloat *v) +{ + return true; +} + +bool ValidateMultiTexCoord3i(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLint s, + GLint t, + GLint r) +{ + return true; +} + +bool ValidateMultiTexCoord3iv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLint *v) +{ + return true; +} + +bool ValidateMultiTexCoord3s(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLshort s, + GLshort t, + GLshort r) +{ + return true; +} + +bool ValidateMultiTexCoord3sv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLshort *v) +{ + return true; +} + +bool ValidateMultiTexCoord4d(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLdouble s, + GLdouble t, + GLdouble r, + GLdouble q) +{ + return true; +} + +bool ValidateMultiTexCoord4dv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLdouble *v) +{ + return true; +} + +bool ValidateMultiTexCoord4fv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLfloat *v) +{ + return true; +} + +bool ValidateMultiTexCoord4i(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLint s, + GLint t, + GLint r, + GLint q) +{ + return true; +} + +bool ValidateMultiTexCoord4iv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLint *v) +{ + return true; +} + +bool ValidateMultiTexCoord4s(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLshort s, + GLshort t, + GLshort r, + GLshort q) +{ + return true; +} + +bool ValidateMultiTexCoord4sv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLshort *v) +{ + return true; +} + +bool ValidateFogCoordPointer(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + GLsizei stride, + const void *pointer) +{ + return true; +} + +bool ValidateFogCoordd(const Context *context, angle::EntryPoint entryPoint, GLdouble coord) +{ + return true; +} + +bool ValidateFogCoorddv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *coord) +{ + return true; +} + +bool ValidateFogCoordf(const Context *context, angle::EntryPoint entryPoint, GLfloat coord) +{ + return true; +} + +bool ValidateFogCoordfv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *coord) +{ + return true; +} + +bool ValidateMultiDrawArrays(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + const GLint *first, + const GLsizei *count, + GLsizei drawcount) +{ + return true; +} + +bool ValidateMultiDrawElements(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + const GLsizei *count, + DrawElementsType typePacked, + const void *const *indices, + GLsizei drawcount) +{ + return true; +} + +bool ValidatePointParameteri(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLint param) +{ + return true; +} + +bool ValidatePointParameteriv(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + const GLint *params) +{ + return true; +} + +bool ValidateSecondaryColor3b(const Context *context, + angle::EntryPoint entryPoint, + GLbyte red, + GLbyte green, + GLbyte blue) +{ + return true; +} + +bool ValidateSecondaryColor3bv(const Context *context, + angle::EntryPoint entryPoint, + const GLbyte *v) +{ + return true; +} + +bool ValidateSecondaryColor3d(const Context *context, + angle::EntryPoint entryPoint, + GLdouble red, + GLdouble green, + GLdouble blue) +{ + return true; +} + +bool ValidateSecondaryColor3dv(const Context *context, + angle::EntryPoint entryPoint, + const GLdouble *v) +{ + return true; +} + +bool ValidateSecondaryColor3f(const Context *context, + angle::EntryPoint entryPoint, + GLfloat red, + GLfloat green, + GLfloat blue) +{ + return true; +} + +bool ValidateSecondaryColor3fv(const Context *context, + angle::EntryPoint entryPoint, + const GLfloat *v) +{ + return true; +} + +bool ValidateSecondaryColor3i(const Context *context, + angle::EntryPoint entryPoint, + GLint red, + GLint green, + GLint blue) +{ + return true; +} + +bool ValidateSecondaryColor3iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v) +{ + return true; +} + +bool ValidateSecondaryColor3s(const Context *context, + angle::EntryPoint entryPoint, + GLshort red, + GLshort green, + GLshort blue) +{ + return true; +} + +bool ValidateSecondaryColor3sv(const Context *context, + angle::EntryPoint entryPoint, + const GLshort *v) +{ + return true; +} + +bool ValidateSecondaryColor3ub(const Context *context, + angle::EntryPoint entryPoint, + GLubyte red, + GLubyte green, + GLubyte blue) +{ + return true; +} + +bool ValidateSecondaryColor3ubv(const Context *context, + angle::EntryPoint entryPoint, + const GLubyte *v) +{ + return true; +} + +bool ValidateSecondaryColor3ui(const Context *context, + angle::EntryPoint entryPoint, + GLuint red, + GLuint green, + GLuint blue) +{ + return true; +} + +bool ValidateSecondaryColor3uiv(const Context *context, + angle::EntryPoint entryPoint, + const GLuint *v) +{ + return true; +} + +bool ValidateSecondaryColor3us(const Context *context, + angle::EntryPoint entryPoint, + GLushort red, + GLushort green, + GLushort blue) +{ + return true; +} + +bool ValidateSecondaryColor3usv(const Context *context, + angle::EntryPoint entryPoint, + const GLushort *v) +{ + return true; +} + +bool ValidateSecondaryColorPointer(const Context *context, + angle::EntryPoint entryPoint, + GLint size, + GLenum type, + GLsizei stride, + const void *pointer) +{ + return true; +} + +bool ValidateWindowPos2d(const Context *context, + angle::EntryPoint entryPoint, + GLdouble x, + GLdouble y) +{ + return true; +} + +bool ValidateWindowPos2dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v) +{ + return true; +} + +bool ValidateWindowPos2f(const Context *context, angle::EntryPoint entryPoint, GLfloat x, GLfloat y) +{ + return true; +} + +bool ValidateWindowPos2fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v) +{ + return true; +} + +bool ValidateWindowPos2i(const Context *context, angle::EntryPoint entryPoint, GLint x, GLint y) +{ + return true; +} + +bool ValidateWindowPos2iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v) +{ + return true; +} + +bool ValidateWindowPos2s(const Context *context, angle::EntryPoint entryPoint, GLshort x, GLshort y) +{ + return true; +} + +bool ValidateWindowPos2sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v) +{ + return true; +} + +bool ValidateWindowPos3d(const Context *context, + angle::EntryPoint entryPoint, + GLdouble x, + GLdouble y, + GLdouble z) +{ + return true; +} + +bool ValidateWindowPos3dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v) +{ + return true; +} + +bool ValidateWindowPos3f(const Context *context, + angle::EntryPoint entryPoint, + GLfloat x, + GLfloat y, + GLfloat z) +{ + return true; +} + +bool ValidateWindowPos3fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v) +{ + return true; +} + +bool ValidateWindowPos3i(const Context *context, + angle::EntryPoint entryPoint, + GLint x, + GLint y, + GLint z) +{ + return true; +} + +bool ValidateWindowPos3iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v) +{ + return true; +} + +bool ValidateWindowPos3s(const Context *context, + angle::EntryPoint entryPoint, + GLshort x, + GLshort y, + GLshort z) +{ + return true; +} + +bool ValidateWindowPos3sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v) +{ + return true; +} + +bool ValidateGetBufferSubData(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLintptr offset, + GLsizeiptr size, + const void *data) +{ + return true; +} + +bool ValidateGetQueryObjectiv(const Context *context, + angle::EntryPoint entryPoint, + QueryID id, + GLenum pname, + const GLint *params) +{ + return true; +} + +bool ValidateMapBuffer(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding targetPacked, + GLenum access) +{ + return true; +} +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/validationGL1_autogen.h b/gfx/angle/checkout/src/libANGLE/validationGL1_autogen.h new file mode 100644 index 0000000000..3e04829ea7 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationGL1_autogen.h @@ -0,0 +1,1192 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// validationGL1_autogen.h: +// Validation functions for the OpenGL Desktop GL 1.x entry points. + +#ifndef LIBANGLE_VALIDATION_GL1_AUTOGEN_H_ +#define LIBANGLE_VALIDATION_GL1_AUTOGEN_H_ + +#include "common/PackedEnums.h" +#include "common/entry_points_enum_autogen.h" + +namespace gl +{ +class Context; + +// GL 1.0 +bool ValidateAccum(const Context *context, angle::EntryPoint entryPoint, GLenum op, GLfloat value); +bool ValidateBegin(const Context *context, angle::EntryPoint entryPoint, GLenum mode); +bool ValidateBitmap(const Context *context, + angle::EntryPoint entryPoint, + GLsizei width, + GLsizei height, + GLfloat xorig, + GLfloat yorig, + GLfloat xmove, + GLfloat ymove, + const GLubyte *bitmap); +bool ValidateCallList(const Context *context, angle::EntryPoint entryPoint, GLuint list); +bool ValidateCallLists(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + GLenum type, + const void *lists); +bool ValidateClearAccum(const Context *context, + angle::EntryPoint entryPoint, + GLfloat red, + GLfloat green, + GLfloat blue, + GLfloat alpha); +bool ValidateClearDepth(const Context *context, angle::EntryPoint entryPoint, GLdouble depth); +bool ValidateClearIndex(const Context *context, angle::EntryPoint entryPoint, GLfloat c); +bool ValidateClipPlane(const Context *context, + angle::EntryPoint entryPoint, + GLenum plane, + const GLdouble *equation); +bool ValidateColor3b(const Context *context, + angle::EntryPoint entryPoint, + GLbyte red, + GLbyte green, + GLbyte blue); +bool ValidateColor3bv(const Context *context, angle::EntryPoint entryPoint, const GLbyte *v); +bool ValidateColor3d(const Context *context, + angle::EntryPoint entryPoint, + GLdouble red, + GLdouble green, + GLdouble blue); +bool ValidateColor3dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v); +bool ValidateColor3f(const Context *context, + angle::EntryPoint entryPoint, + GLfloat red, + GLfloat green, + GLfloat blue); +bool ValidateColor3fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v); +bool ValidateColor3i(const Context *context, + angle::EntryPoint entryPoint, + GLint red, + GLint green, + GLint blue); +bool ValidateColor3iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v); +bool ValidateColor3s(const Context *context, + angle::EntryPoint entryPoint, + GLshort red, + GLshort green, + GLshort blue); +bool ValidateColor3sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v); +bool ValidateColor3ub(const Context *context, + angle::EntryPoint entryPoint, + GLubyte red, + GLubyte green, + GLubyte blue); +bool ValidateColor3ubv(const Context *context, angle::EntryPoint entryPoint, const GLubyte *v); +bool ValidateColor3ui(const Context *context, + angle::EntryPoint entryPoint, + GLuint red, + GLuint green, + GLuint blue); +bool ValidateColor3uiv(const Context *context, angle::EntryPoint entryPoint, const GLuint *v); +bool ValidateColor3us(const Context *context, + angle::EntryPoint entryPoint, + GLushort red, + GLushort green, + GLushort blue); +bool ValidateColor3usv(const Context *context, angle::EntryPoint entryPoint, const GLushort *v); +bool ValidateColor4b(const Context *context, + angle::EntryPoint entryPoint, + GLbyte red, + GLbyte green, + GLbyte blue, + GLbyte alpha); +bool ValidateColor4bv(const Context *context, angle::EntryPoint entryPoint, const GLbyte *v); +bool ValidateColor4d(const Context *context, + angle::EntryPoint entryPoint, + GLdouble red, + GLdouble green, + GLdouble blue, + GLdouble alpha); +bool ValidateColor4dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v); +bool ValidateColor4fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v); +bool ValidateColor4i(const Context *context, + angle::EntryPoint entryPoint, + GLint red, + GLint green, + GLint blue, + GLint alpha); +bool ValidateColor4iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v); +bool ValidateColor4s(const Context *context, + angle::EntryPoint entryPoint, + GLshort red, + GLshort green, + GLshort blue, + GLshort alpha); +bool ValidateColor4sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v); +bool ValidateColor4ubv(const Context *context, angle::EntryPoint entryPoint, const GLubyte *v); +bool ValidateColor4ui(const Context *context, + angle::EntryPoint entryPoint, + GLuint red, + GLuint green, + GLuint blue, + GLuint alpha); +bool ValidateColor4uiv(const Context *context, angle::EntryPoint entryPoint, const GLuint *v); +bool ValidateColor4us(const Context *context, + angle::EntryPoint entryPoint, + GLushort red, + GLushort green, + GLushort blue, + GLushort alpha); +bool ValidateColor4usv(const Context *context, angle::EntryPoint entryPoint, const GLushort *v); +bool ValidateColorMaterial(const Context *context, + angle::EntryPoint entryPoint, + GLenum face, + GLenum mode); +bool ValidateCopyPixels(const Context *context, + angle::EntryPoint entryPoint, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum type); +bool ValidateDeleteLists(const Context *context, + angle::EntryPoint entryPoint, + GLuint list, + GLsizei range); +bool ValidateDepthRange(const Context *context, + angle::EntryPoint entryPoint, + GLdouble n, + GLdouble f); +bool ValidateDrawBuffer(const Context *context, angle::EntryPoint entryPoint, GLenum buf); +bool ValidateDrawPixels(const Context *context, + angle::EntryPoint entryPoint, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void *pixels); +bool ValidateEdgeFlag(const Context *context, angle::EntryPoint entryPoint, GLboolean flag); +bool ValidateEdgeFlagv(const Context *context, angle::EntryPoint entryPoint, const GLboolean *flag); +bool ValidateEnd(const Context *context, angle::EntryPoint entryPoint); +bool ValidateEndList(const Context *context, angle::EntryPoint entryPoint); +bool ValidateEvalCoord1d(const Context *context, angle::EntryPoint entryPoint, GLdouble u); +bool ValidateEvalCoord1dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *u); +bool ValidateEvalCoord1f(const Context *context, angle::EntryPoint entryPoint, GLfloat u); +bool ValidateEvalCoord1fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *u); +bool ValidateEvalCoord2d(const Context *context, + angle::EntryPoint entryPoint, + GLdouble u, + GLdouble v); +bool ValidateEvalCoord2dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *u); +bool ValidateEvalCoord2f(const Context *context, + angle::EntryPoint entryPoint, + GLfloat u, + GLfloat v); +bool ValidateEvalCoord2fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *u); +bool ValidateEvalMesh1(const Context *context, + angle::EntryPoint entryPoint, + GLenum mode, + GLint i1, + GLint i2); +bool ValidateEvalMesh2(const Context *context, + angle::EntryPoint entryPoint, + GLenum mode, + GLint i1, + GLint i2, + GLint j1, + GLint j2); +bool ValidateEvalPoint1(const Context *context, angle::EntryPoint entryPoint, GLint i); +bool ValidateEvalPoint2(const Context *context, angle::EntryPoint entryPoint, GLint i, GLint j); +bool ValidateFeedbackBuffer(const Context *context, + angle::EntryPoint entryPoint, + GLsizei size, + GLenum type, + const GLfloat *buffer); +bool ValidateFogi(const Context *context, angle::EntryPoint entryPoint, GLenum pname, GLint param); +bool ValidateFogiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + const GLint *params); +bool ValidateFrustum(const Context *context, + angle::EntryPoint entryPoint, + GLdouble left, + GLdouble right, + GLdouble bottom, + GLdouble top, + GLdouble zNear, + GLdouble zFar); +bool ValidateGenLists(const Context *context, angle::EntryPoint entryPoint, GLsizei range); +bool ValidateGetClipPlane(const Context *context, + angle::EntryPoint entryPoint, + GLenum plane, + const GLdouble *equation); +bool ValidateGetDoublev(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + const GLdouble *data); +bool ValidateGetLightiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum light, + GLenum pname, + const GLint *params); +bool ValidateGetMapdv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum query, + const GLdouble *v); +bool ValidateGetMapfv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum query, + const GLfloat *v); +bool ValidateGetMapiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum query, + const GLint *v); +bool ValidateGetMaterialiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum face, + GLenum pname, + const GLint *params); +bool ValidateGetPixelMapfv(const Context *context, + angle::EntryPoint entryPoint, + GLenum map, + const GLfloat *values); +bool ValidateGetPixelMapuiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum map, + const GLuint *values); +bool ValidateGetPixelMapusv(const Context *context, + angle::EntryPoint entryPoint, + GLenum map, + const GLushort *values); +bool ValidateGetPolygonStipple(const Context *context, + angle::EntryPoint entryPoint, + const GLubyte *mask); +bool ValidateGetTexGendv(const Context *context, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + const GLdouble *params); +bool ValidateGetTexGenfv(const Context *context, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + const GLfloat *params); +bool ValidateGetTexGeniv(const Context *context, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + const GLint *params); +bool ValidateGetTexImage(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + GLenum format, + GLenum type, + const void *pixels); +bool ValidateIndexMask(const Context *context, angle::EntryPoint entryPoint, GLuint mask); +bool ValidateIndexd(const Context *context, angle::EntryPoint entryPoint, GLdouble c); +bool ValidateIndexdv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *c); +bool ValidateIndexf(const Context *context, angle::EntryPoint entryPoint, GLfloat c); +bool ValidateIndexfv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *c); +bool ValidateIndexi(const Context *context, angle::EntryPoint entryPoint, GLint c); +bool ValidateIndexiv(const Context *context, angle::EntryPoint entryPoint, const GLint *c); +bool ValidateIndexs(const Context *context, angle::EntryPoint entryPoint, GLshort c); +bool ValidateIndexsv(const Context *context, angle::EntryPoint entryPoint, const GLshort *c); +bool ValidateInitNames(const Context *context, angle::EntryPoint entryPoint); +bool ValidateIsList(const Context *context, angle::EntryPoint entryPoint, GLuint list); +bool ValidateLightModeli(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLint param); +bool ValidateLightModeliv(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + const GLint *params); +bool ValidateLighti(const Context *context, + angle::EntryPoint entryPoint, + GLenum light, + GLenum pname, + GLint param); +bool ValidateLightiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum light, + GLenum pname, + const GLint *params); +bool ValidateLineStipple(const Context *context, + angle::EntryPoint entryPoint, + GLint factor, + GLushort pattern); +bool ValidateListBase(const Context *context, angle::EntryPoint entryPoint, GLuint base); +bool ValidateLoadMatrixd(const Context *context, angle::EntryPoint entryPoint, const GLdouble *m); +bool ValidateLoadName(const Context *context, angle::EntryPoint entryPoint, GLuint name); +bool ValidateMap1d(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLdouble u1, + GLdouble u2, + GLint stride, + GLint order, + const GLdouble *points); +bool ValidateMap1f(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLfloat u1, + GLfloat u2, + GLint stride, + GLint order, + const GLfloat *points); +bool ValidateMap2d(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLdouble u1, + GLdouble u2, + GLint ustride, + GLint uorder, + GLdouble v1, + GLdouble v2, + GLint vstride, + GLint vorder, + const GLdouble *points); +bool ValidateMap2f(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLfloat u1, + GLfloat u2, + GLint ustride, + GLint uorder, + GLfloat v1, + GLfloat v2, + GLint vstride, + GLint vorder, + const GLfloat *points); +bool ValidateMapGrid1d(const Context *context, + angle::EntryPoint entryPoint, + GLint un, + GLdouble u1, + GLdouble u2); +bool ValidateMapGrid1f(const Context *context, + angle::EntryPoint entryPoint, + GLint un, + GLfloat u1, + GLfloat u2); +bool ValidateMapGrid2d(const Context *context, + angle::EntryPoint entryPoint, + GLint un, + GLdouble u1, + GLdouble u2, + GLint vn, + GLdouble v1, + GLdouble v2); +bool ValidateMapGrid2f(const Context *context, + angle::EntryPoint entryPoint, + GLint un, + GLfloat u1, + GLfloat u2, + GLint vn, + GLfloat v1, + GLfloat v2); +bool ValidateMateriali(const Context *context, + angle::EntryPoint entryPoint, + GLenum face, + GLenum pname, + GLint param); +bool ValidateMaterialiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum face, + GLenum pname, + const GLint *params); +bool ValidateMultMatrixd(const Context *context, angle::EntryPoint entryPoint, const GLdouble *m); +bool ValidateNewList(const Context *context, + angle::EntryPoint entryPoint, + GLuint list, + GLenum mode); +bool ValidateNormal3b(const Context *context, + angle::EntryPoint entryPoint, + GLbyte nx, + GLbyte ny, + GLbyte nz); +bool ValidateNormal3bv(const Context *context, angle::EntryPoint entryPoint, const GLbyte *v); +bool ValidateNormal3d(const Context *context, + angle::EntryPoint entryPoint, + GLdouble nx, + GLdouble ny, + GLdouble nz); +bool ValidateNormal3dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v); +bool ValidateNormal3fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v); +bool ValidateNormal3i(const Context *context, + angle::EntryPoint entryPoint, + GLint nx, + GLint ny, + GLint nz); +bool ValidateNormal3iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v); +bool ValidateNormal3s(const Context *context, + angle::EntryPoint entryPoint, + GLshort nx, + GLshort ny, + GLshort nz); +bool ValidateNormal3sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v); +bool ValidateOrtho(const Context *context, + angle::EntryPoint entryPoint, + GLdouble left, + GLdouble right, + GLdouble bottom, + GLdouble top, + GLdouble zNear, + GLdouble zFar); +bool ValidatePassThrough(const Context *context, angle::EntryPoint entryPoint, GLfloat token); +bool ValidatePixelMapfv(const Context *context, + angle::EntryPoint entryPoint, + GLenum map, + GLsizei mapsize, + const GLfloat *values); +bool ValidatePixelMapuiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum map, + GLsizei mapsize, + const GLuint *values); +bool ValidatePixelMapusv(const Context *context, + angle::EntryPoint entryPoint, + GLenum map, + GLsizei mapsize, + const GLushort *values); +bool ValidatePixelStoref(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLfloat param); +bool ValidatePixelTransferf(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLfloat param); +bool ValidatePixelTransferi(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLint param); +bool ValidatePixelZoom(const Context *context, + angle::EntryPoint entryPoint, + GLfloat xfactor, + GLfloat yfactor); +bool ValidatePolygonMode(const Context *context, + angle::EntryPoint entryPoint, + GLenum face, + GLenum mode); +bool ValidatePolygonStipple(const Context *context, + angle::EntryPoint entryPoint, + const GLubyte *mask); +bool ValidatePopAttrib(const Context *context, angle::EntryPoint entryPoint); +bool ValidatePopName(const Context *context, angle::EntryPoint entryPoint); +bool ValidatePushAttrib(const Context *context, angle::EntryPoint entryPoint, GLbitfield mask); +bool ValidatePushName(const Context *context, angle::EntryPoint entryPoint, GLuint name); +bool ValidateRasterPos2d(const Context *context, + angle::EntryPoint entryPoint, + GLdouble x, + GLdouble y); +bool ValidateRasterPos2dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v); +bool ValidateRasterPos2f(const Context *context, + angle::EntryPoint entryPoint, + GLfloat x, + GLfloat y); +bool ValidateRasterPos2fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v); +bool ValidateRasterPos2i(const Context *context, angle::EntryPoint entryPoint, GLint x, GLint y); +bool ValidateRasterPos2iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v); +bool ValidateRasterPos2s(const Context *context, + angle::EntryPoint entryPoint, + GLshort x, + GLshort y); +bool ValidateRasterPos2sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v); +bool ValidateRasterPos3d(const Context *context, + angle::EntryPoint entryPoint, + GLdouble x, + GLdouble y, + GLdouble z); +bool ValidateRasterPos3dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v); +bool ValidateRasterPos3f(const Context *context, + angle::EntryPoint entryPoint, + GLfloat x, + GLfloat y, + GLfloat z); +bool ValidateRasterPos3fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v); +bool ValidateRasterPos3i(const Context *context, + angle::EntryPoint entryPoint, + GLint x, + GLint y, + GLint z); +bool ValidateRasterPos3iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v); +bool ValidateRasterPos3s(const Context *context, + angle::EntryPoint entryPoint, + GLshort x, + GLshort y, + GLshort z); +bool ValidateRasterPos3sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v); +bool ValidateRasterPos4d(const Context *context, + angle::EntryPoint entryPoint, + GLdouble x, + GLdouble y, + GLdouble z, + GLdouble w); +bool ValidateRasterPos4dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v); +bool ValidateRasterPos4f(const Context *context, + angle::EntryPoint entryPoint, + GLfloat x, + GLfloat y, + GLfloat z, + GLfloat w); +bool ValidateRasterPos4fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v); +bool ValidateRasterPos4i(const Context *context, + angle::EntryPoint entryPoint, + GLint x, + GLint y, + GLint z, + GLint w); +bool ValidateRasterPos4iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v); +bool ValidateRasterPos4s(const Context *context, + angle::EntryPoint entryPoint, + GLshort x, + GLshort y, + GLshort z, + GLshort w); +bool ValidateRasterPos4sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v); +bool ValidateRectd(const Context *context, + angle::EntryPoint entryPoint, + GLdouble x1, + GLdouble y1, + GLdouble x2, + GLdouble y2); +bool ValidateRectdv(const Context *context, + angle::EntryPoint entryPoint, + const GLdouble *v1, + const GLdouble *v2); +bool ValidateRectf(const Context *context, + angle::EntryPoint entryPoint, + GLfloat x1, + GLfloat y1, + GLfloat x2, + GLfloat y2); +bool ValidateRectfv(const Context *context, + angle::EntryPoint entryPoint, + const GLfloat *v1, + const GLfloat *v2); +bool ValidateRecti(const Context *context, + angle::EntryPoint entryPoint, + GLint x1, + GLint y1, + GLint x2, + GLint y2); +bool ValidateRectiv(const Context *context, + angle::EntryPoint entryPoint, + const GLint *v1, + const GLint *v2); +bool ValidateRects(const Context *context, + angle::EntryPoint entryPoint, + GLshort x1, + GLshort y1, + GLshort x2, + GLshort y2); +bool ValidateRectsv(const Context *context, + angle::EntryPoint entryPoint, + const GLshort *v1, + const GLshort *v2); +bool ValidateRenderMode(const Context *context, angle::EntryPoint entryPoint, GLenum mode); +bool ValidateRotated(const Context *context, + angle::EntryPoint entryPoint, + GLdouble angle, + GLdouble x, + GLdouble y, + GLdouble z); +bool ValidateScaled(const Context *context, + angle::EntryPoint entryPoint, + GLdouble x, + GLdouble y, + GLdouble z); +bool ValidateSelectBuffer(const Context *context, + angle::EntryPoint entryPoint, + GLsizei size, + const GLuint *buffer); +bool ValidateTexCoord1d(const Context *context, angle::EntryPoint entryPoint, GLdouble s); +bool ValidateTexCoord1dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v); +bool ValidateTexCoord1f(const Context *context, angle::EntryPoint entryPoint, GLfloat s); +bool ValidateTexCoord1fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v); +bool ValidateTexCoord1i(const Context *context, angle::EntryPoint entryPoint, GLint s); +bool ValidateTexCoord1iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v); +bool ValidateTexCoord1s(const Context *context, angle::EntryPoint entryPoint, GLshort s); +bool ValidateTexCoord1sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v); +bool ValidateTexCoord2d(const Context *context, + angle::EntryPoint entryPoint, + GLdouble s, + GLdouble t); +bool ValidateTexCoord2dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v); +bool ValidateTexCoord2f(const Context *context, angle::EntryPoint entryPoint, GLfloat s, GLfloat t); +bool ValidateTexCoord2fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v); +bool ValidateTexCoord2i(const Context *context, angle::EntryPoint entryPoint, GLint s, GLint t); +bool ValidateTexCoord2iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v); +bool ValidateTexCoord2s(const Context *context, angle::EntryPoint entryPoint, GLshort s, GLshort t); +bool ValidateTexCoord2sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v); +bool ValidateTexCoord3d(const Context *context, + angle::EntryPoint entryPoint, + GLdouble s, + GLdouble t, + GLdouble r); +bool ValidateTexCoord3dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v); +bool ValidateTexCoord3f(const Context *context, + angle::EntryPoint entryPoint, + GLfloat s, + GLfloat t, + GLfloat r); +bool ValidateTexCoord3fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v); +bool ValidateTexCoord3i(const Context *context, + angle::EntryPoint entryPoint, + GLint s, + GLint t, + GLint r); +bool ValidateTexCoord3iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v); +bool ValidateTexCoord3s(const Context *context, + angle::EntryPoint entryPoint, + GLshort s, + GLshort t, + GLshort r); +bool ValidateTexCoord3sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v); +bool ValidateTexCoord4d(const Context *context, + angle::EntryPoint entryPoint, + GLdouble s, + GLdouble t, + GLdouble r, + GLdouble q); +bool ValidateTexCoord4dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v); +bool ValidateTexCoord4f(const Context *context, + angle::EntryPoint entryPoint, + GLfloat s, + GLfloat t, + GLfloat r, + GLfloat q); +bool ValidateTexCoord4fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v); +bool ValidateTexCoord4i(const Context *context, + angle::EntryPoint entryPoint, + GLint s, + GLint t, + GLint r, + GLint q); +bool ValidateTexCoord4iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v); +bool ValidateTexCoord4s(const Context *context, + angle::EntryPoint entryPoint, + GLshort s, + GLshort t, + GLshort r, + GLshort q); +bool ValidateTexCoord4sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v); +bool ValidateTexGend(const Context *context, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + GLdouble param); +bool ValidateTexGendv(const Context *context, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + const GLdouble *params); +bool ValidateTexGenf(const Context *context, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + GLfloat param); +bool ValidateTexGenfv(const Context *context, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + const GLfloat *params); +bool ValidateTexGeni(const Context *context, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + GLint param); +bool ValidateTexGeniv(const Context *context, + angle::EntryPoint entryPoint, + GLenum coord, + GLenum pname, + const GLint *params); +bool ValidateTexImage1D(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLint border, + GLenum format, + GLenum type, + const void *pixels); +bool ValidateTranslated(const Context *context, + angle::EntryPoint entryPoint, + GLdouble x, + GLdouble y, + GLdouble z); +bool ValidateVertex2d(const Context *context, angle::EntryPoint entryPoint, GLdouble x, GLdouble y); +bool ValidateVertex2dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v); +bool ValidateVertex2f(const Context *context, angle::EntryPoint entryPoint, GLfloat x, GLfloat y); +bool ValidateVertex2fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v); +bool ValidateVertex2i(const Context *context, angle::EntryPoint entryPoint, GLint x, GLint y); +bool ValidateVertex2iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v); +bool ValidateVertex2s(const Context *context, angle::EntryPoint entryPoint, GLshort x, GLshort y); +bool ValidateVertex2sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v); +bool ValidateVertex3d(const Context *context, + angle::EntryPoint entryPoint, + GLdouble x, + GLdouble y, + GLdouble z); +bool ValidateVertex3dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v); +bool ValidateVertex3f(const Context *context, + angle::EntryPoint entryPoint, + GLfloat x, + GLfloat y, + GLfloat z); +bool ValidateVertex3fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v); +bool ValidateVertex3i(const Context *context, + angle::EntryPoint entryPoint, + GLint x, + GLint y, + GLint z); +bool ValidateVertex3iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v); +bool ValidateVertex3s(const Context *context, + angle::EntryPoint entryPoint, + GLshort x, + GLshort y, + GLshort z); +bool ValidateVertex3sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v); +bool ValidateVertex4d(const Context *context, + angle::EntryPoint entryPoint, + GLdouble x, + GLdouble y, + GLdouble z, + GLdouble w); +bool ValidateVertex4dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v); +bool ValidateVertex4f(const Context *context, + angle::EntryPoint entryPoint, + GLfloat x, + GLfloat y, + GLfloat z, + GLfloat w); +bool ValidateVertex4fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v); +bool ValidateVertex4i(const Context *context, + angle::EntryPoint entryPoint, + GLint x, + GLint y, + GLint z, + GLint w); +bool ValidateVertex4iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v); +bool ValidateVertex4s(const Context *context, + angle::EntryPoint entryPoint, + GLshort x, + GLshort y, + GLshort z, + GLshort w); +bool ValidateVertex4sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v); + +// GL 1.1 +bool ValidateAreTexturesResident(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const GLuint *textures, + const GLboolean *residences); +bool ValidateArrayElement(const Context *context, angle::EntryPoint entryPoint, GLint i); +bool ValidateCopyTexImage1D(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLint level, + GLenum internalformat, + GLint x, + GLint y, + GLsizei width, + GLint border); +bool ValidateCopyTexSubImage1D(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLint level, + GLint xoffset, + GLint x, + GLint y, + GLsizei width); +bool ValidateEdgeFlagPointer(const Context *context, + angle::EntryPoint entryPoint, + GLsizei stride, + const void *pointer); +bool ValidateIndexPointer(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + GLsizei stride, + const void *pointer); +bool ValidateIndexub(const Context *context, angle::EntryPoint entryPoint, GLubyte c); +bool ValidateIndexubv(const Context *context, angle::EntryPoint entryPoint, const GLubyte *c); +bool ValidateInterleavedArrays(const Context *context, + angle::EntryPoint entryPoint, + GLenum format, + GLsizei stride, + const void *pointer); +bool ValidatePopClientAttrib(const Context *context, angle::EntryPoint entryPoint); +bool ValidatePrioritizeTextures(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const GLuint *textures, + const GLfloat *priorities); +bool ValidatePushClientAttrib(const Context *context, + angle::EntryPoint entryPoint, + GLbitfield mask); +bool ValidateTexSubImage1D(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, + GLenum type, + const void *pixels); + +// GL 1.2 + +// GL 1.3 +bool ValidateCompressedTexImage1D(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLint border, + GLsizei imageSize, + const void *data); +bool ValidateCompressedTexSubImage1D(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, + GLsizei imageSize, + const void *data); +bool ValidateGetCompressedTexImage(const Context *context, + angle::EntryPoint entryPoint, + TextureTarget targetPacked, + GLint level, + const void *img); +bool ValidateLoadTransposeMatrixd(const Context *context, + angle::EntryPoint entryPoint, + const GLdouble *m); +bool ValidateLoadTransposeMatrixf(const Context *context, + angle::EntryPoint entryPoint, + const GLfloat *m); +bool ValidateMultTransposeMatrixd(const Context *context, + angle::EntryPoint entryPoint, + const GLdouble *m); +bool ValidateMultTransposeMatrixf(const Context *context, + angle::EntryPoint entryPoint, + const GLfloat *m); +bool ValidateMultiTexCoord1d(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLdouble s); +bool ValidateMultiTexCoord1dv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLdouble *v); +bool ValidateMultiTexCoord1f(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLfloat s); +bool ValidateMultiTexCoord1fv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLfloat *v); +bool ValidateMultiTexCoord1i(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLint s); +bool ValidateMultiTexCoord1iv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLint *v); +bool ValidateMultiTexCoord1s(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLshort s); +bool ValidateMultiTexCoord1sv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLshort *v); +bool ValidateMultiTexCoord2d(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLdouble s, + GLdouble t); +bool ValidateMultiTexCoord2dv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLdouble *v); +bool ValidateMultiTexCoord2f(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLfloat s, + GLfloat t); +bool ValidateMultiTexCoord2fv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLfloat *v); +bool ValidateMultiTexCoord2i(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLint s, + GLint t); +bool ValidateMultiTexCoord2iv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLint *v); +bool ValidateMultiTexCoord2s(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLshort s, + GLshort t); +bool ValidateMultiTexCoord2sv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLshort *v); +bool ValidateMultiTexCoord3d(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLdouble s, + GLdouble t, + GLdouble r); +bool ValidateMultiTexCoord3dv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLdouble *v); +bool ValidateMultiTexCoord3f(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLfloat s, + GLfloat t, + GLfloat r); +bool ValidateMultiTexCoord3fv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLfloat *v); +bool ValidateMultiTexCoord3i(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLint s, + GLint t, + GLint r); +bool ValidateMultiTexCoord3iv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLint *v); +bool ValidateMultiTexCoord3s(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLshort s, + GLshort t, + GLshort r); +bool ValidateMultiTexCoord3sv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLshort *v); +bool ValidateMultiTexCoord4d(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLdouble s, + GLdouble t, + GLdouble r, + GLdouble q); +bool ValidateMultiTexCoord4dv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLdouble *v); +bool ValidateMultiTexCoord4fv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLfloat *v); +bool ValidateMultiTexCoord4i(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLint s, + GLint t, + GLint r, + GLint q); +bool ValidateMultiTexCoord4iv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLint *v); +bool ValidateMultiTexCoord4s(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLshort s, + GLshort t, + GLshort r, + GLshort q); +bool ValidateMultiTexCoord4sv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + const GLshort *v); + +// GL 1.4 +bool ValidateFogCoordPointer(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + GLsizei stride, + const void *pointer); +bool ValidateFogCoordd(const Context *context, angle::EntryPoint entryPoint, GLdouble coord); +bool ValidateFogCoorddv(const Context *context, + angle::EntryPoint entryPoint, + const GLdouble *coord); +bool ValidateFogCoordf(const Context *context, angle::EntryPoint entryPoint, GLfloat coord); +bool ValidateFogCoordfv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *coord); +bool ValidateMultiDrawArrays(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + const GLint *first, + const GLsizei *count, + GLsizei drawcount); +bool ValidateMultiDrawElements(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + const GLsizei *count, + DrawElementsType typePacked, + const void *const *indices, + GLsizei drawcount); +bool ValidatePointParameteri(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + GLint param); +bool ValidatePointParameteriv(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + const GLint *params); +bool ValidateSecondaryColor3b(const Context *context, + angle::EntryPoint entryPoint, + GLbyte red, + GLbyte green, + GLbyte blue); +bool ValidateSecondaryColor3bv(const Context *context, + angle::EntryPoint entryPoint, + const GLbyte *v); +bool ValidateSecondaryColor3d(const Context *context, + angle::EntryPoint entryPoint, + GLdouble red, + GLdouble green, + GLdouble blue); +bool ValidateSecondaryColor3dv(const Context *context, + angle::EntryPoint entryPoint, + const GLdouble *v); +bool ValidateSecondaryColor3f(const Context *context, + angle::EntryPoint entryPoint, + GLfloat red, + GLfloat green, + GLfloat blue); +bool ValidateSecondaryColor3fv(const Context *context, + angle::EntryPoint entryPoint, + const GLfloat *v); +bool ValidateSecondaryColor3i(const Context *context, + angle::EntryPoint entryPoint, + GLint red, + GLint green, + GLint blue); +bool ValidateSecondaryColor3iv(const Context *context, + angle::EntryPoint entryPoint, + const GLint *v); +bool ValidateSecondaryColor3s(const Context *context, + angle::EntryPoint entryPoint, + GLshort red, + GLshort green, + GLshort blue); +bool ValidateSecondaryColor3sv(const Context *context, + angle::EntryPoint entryPoint, + const GLshort *v); +bool ValidateSecondaryColor3ub(const Context *context, + angle::EntryPoint entryPoint, + GLubyte red, + GLubyte green, + GLubyte blue); +bool ValidateSecondaryColor3ubv(const Context *context, + angle::EntryPoint entryPoint, + const GLubyte *v); +bool ValidateSecondaryColor3ui(const Context *context, + angle::EntryPoint entryPoint, + GLuint red, + GLuint green, + GLuint blue); +bool ValidateSecondaryColor3uiv(const Context *context, + angle::EntryPoint entryPoint, + const GLuint *v); +bool ValidateSecondaryColor3us(const Context *context, + angle::EntryPoint entryPoint, + GLushort red, + GLushort green, + GLushort blue); +bool ValidateSecondaryColor3usv(const Context *context, + angle::EntryPoint entryPoint, + const GLushort *v); +bool ValidateSecondaryColorPointer(const Context *context, + angle::EntryPoint entryPoint, + GLint size, + GLenum type, + GLsizei stride, + const void *pointer); +bool ValidateWindowPos2d(const Context *context, + angle::EntryPoint entryPoint, + GLdouble x, + GLdouble y); +bool ValidateWindowPos2dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v); +bool ValidateWindowPos2f(const Context *context, + angle::EntryPoint entryPoint, + GLfloat x, + GLfloat y); +bool ValidateWindowPos2fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v); +bool ValidateWindowPos2i(const Context *context, angle::EntryPoint entryPoint, GLint x, GLint y); +bool ValidateWindowPos2iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v); +bool ValidateWindowPos2s(const Context *context, + angle::EntryPoint entryPoint, + GLshort x, + GLshort y); +bool ValidateWindowPos2sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v); +bool ValidateWindowPos3d(const Context *context, + angle::EntryPoint entryPoint, + GLdouble x, + GLdouble y, + GLdouble z); +bool ValidateWindowPos3dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v); +bool ValidateWindowPos3f(const Context *context, + angle::EntryPoint entryPoint, + GLfloat x, + GLfloat y, + GLfloat z); +bool ValidateWindowPos3fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v); +bool ValidateWindowPos3i(const Context *context, + angle::EntryPoint entryPoint, + GLint x, + GLint y, + GLint z); +bool ValidateWindowPos3iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v); +bool ValidateWindowPos3s(const Context *context, + angle::EntryPoint entryPoint, + GLshort x, + GLshort y, + GLshort z); +bool ValidateWindowPos3sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v); + +// GL 1.5 +bool ValidateGetBufferSubData(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLintptr offset, + GLsizeiptr size, + const void *data); +bool ValidateGetQueryObjectiv(const Context *context, + angle::EntryPoint entryPoint, + QueryID idPacked, + GLenum pname, + const GLint *params); +bool ValidateMapBuffer(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding targetPacked, + GLenum access); +} // namespace gl + +#endif // LIBANGLE_VALIDATION_GL1_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/validationGL2.cpp b/gfx/angle/checkout/src/libANGLE/validationGL2.cpp new file mode 100644 index 0000000000..9eb97b2f94 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationGL2.cpp @@ -0,0 +1,262 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// validationGL2.cpp: Validation functions for OpenGL 2.0 entry point parameters + +#include "libANGLE/validationGL2_autogen.h" + +namespace gl +{ + +bool ValidateGetVertexAttribdv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum pname, + const GLdouble *params) +{ + return true; +} + +bool ValidateVertexAttrib1d(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLdouble x) +{ + return true; +} + +bool ValidateVertexAttrib1dv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLdouble *v) +{ + return true; +} + +bool ValidateVertexAttrib1s(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLshort x) +{ + return true; +} + +bool ValidateVertexAttrib1sv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLshort *v) +{ + return true; +} + +bool ValidateVertexAttrib2d(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLdouble x, + GLdouble y) +{ + return true; +} + +bool ValidateVertexAttrib2dv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLdouble *v) +{ + return true; +} + +bool ValidateVertexAttrib2s(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLshort x, + GLshort y) +{ + return true; +} + +bool ValidateVertexAttrib2sv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLshort *v) +{ + return true; +} + +bool ValidateVertexAttrib3d(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLdouble x, + GLdouble y, + GLdouble z) +{ + return true; +} + +bool ValidateVertexAttrib3dv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLdouble *v) +{ + return true; +} + +bool ValidateVertexAttrib3s(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLshort x, + GLshort y, + GLshort z) +{ + return true; +} + +bool ValidateVertexAttrib3sv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLshort *v) +{ + return true; +} + +bool ValidateVertexAttrib4Nbv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLbyte *v) +{ + return true; +} + +bool ValidateVertexAttrib4Niv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLint *v) +{ + return true; +} + +bool ValidateVertexAttrib4Nsv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLshort *v) +{ + return true; +} + +bool ValidateVertexAttrib4Nub(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLubyte x, + GLubyte y, + GLubyte z, + GLubyte w) +{ + return true; +} + +bool ValidateVertexAttrib4Nubv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLubyte *v) +{ + return true; +} + +bool ValidateVertexAttrib4Nuiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLuint *v) +{ + return true; +} + +bool ValidateVertexAttrib4Nusv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLushort *v) +{ + return true; +} + +bool ValidateVertexAttrib4bv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLbyte *v) +{ + return true; +} + +bool ValidateVertexAttrib4d(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLdouble x, + GLdouble y, + GLdouble z, + GLdouble w) +{ + return true; +} + +bool ValidateVertexAttrib4dv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLdouble *v) +{ + return true; +} + +bool ValidateVertexAttrib4iv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLint *v) +{ + return true; +} + +bool ValidateVertexAttrib4s(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLshort x, + GLshort y, + GLshort z, + GLshort w) +{ + return true; +} + +bool ValidateVertexAttrib4sv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLshort *v) +{ + return true; +} + +bool ValidateVertexAttrib4ubv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLubyte *v) +{ + return true; +} + +bool ValidateVertexAttrib4uiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLuint *v) +{ + return true; +} + +bool ValidateVertexAttrib4usv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLushort *v) +{ + return true; +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/validationGL2_autogen.h b/gfx/angle/checkout/src/libANGLE/validationGL2_autogen.h new file mode 100644 index 0000000000..5a6e0b375f --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationGL2_autogen.h @@ -0,0 +1,158 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// validationGL2_autogen.h: +// Validation functions for the OpenGL Desktop GL 2.x entry points. + +#ifndef LIBANGLE_VALIDATION_GL2_AUTOGEN_H_ +#define LIBANGLE_VALIDATION_GL2_AUTOGEN_H_ + +#include "common/PackedEnums.h" +#include "common/entry_points_enum_autogen.h" + +namespace gl +{ +class Context; + +// GL 2.0 +bool ValidateGetVertexAttribdv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum pname, + const GLdouble *params); +bool ValidateVertexAttrib1d(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLdouble x); +bool ValidateVertexAttrib1dv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLdouble *v); +bool ValidateVertexAttrib1s(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLshort x); +bool ValidateVertexAttrib1sv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLshort *v); +bool ValidateVertexAttrib2d(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLdouble x, + GLdouble y); +bool ValidateVertexAttrib2dv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLdouble *v); +bool ValidateVertexAttrib2s(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLshort x, + GLshort y); +bool ValidateVertexAttrib2sv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLshort *v); +bool ValidateVertexAttrib3d(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLdouble x, + GLdouble y, + GLdouble z); +bool ValidateVertexAttrib3dv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLdouble *v); +bool ValidateVertexAttrib3s(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLshort x, + GLshort y, + GLshort z); +bool ValidateVertexAttrib3sv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLshort *v); +bool ValidateVertexAttrib4Nbv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLbyte *v); +bool ValidateVertexAttrib4Niv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLint *v); +bool ValidateVertexAttrib4Nsv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLshort *v); +bool ValidateVertexAttrib4Nub(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLubyte x, + GLubyte y, + GLubyte z, + GLubyte w); +bool ValidateVertexAttrib4Nubv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLubyte *v); +bool ValidateVertexAttrib4Nuiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLuint *v); +bool ValidateVertexAttrib4Nusv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLushort *v); +bool ValidateVertexAttrib4bv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLbyte *v); +bool ValidateVertexAttrib4d(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLdouble x, + GLdouble y, + GLdouble z, + GLdouble w); +bool ValidateVertexAttrib4dv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLdouble *v); +bool ValidateVertexAttrib4iv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLint *v); +bool ValidateVertexAttrib4s(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLshort x, + GLshort y, + GLshort z, + GLshort w); +bool ValidateVertexAttrib4sv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLshort *v); +bool ValidateVertexAttrib4ubv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLubyte *v); +bool ValidateVertexAttrib4uiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLuint *v); +bool ValidateVertexAttrib4usv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLushort *v); + +// GL 2.1 +} // namespace gl + +#endif // LIBANGLE_VALIDATION_GL2_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/validationGL3.cpp b/gfx/angle/checkout/src/libANGLE/validationGL3.cpp new file mode 100644 index 0000000000..1e452bd0f4 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationGL3.cpp @@ -0,0 +1,634 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// validationGL3.cpp: Validation functions for OpenGL 3.0 entry point parameters + +#include "libANGLE/validationGL3_autogen.h" + +namespace gl +{ + +bool ValidateBeginConditionalRender(const Context *context, + angle::EntryPoint entryPoint, + GLuint id, + GLenum mode) +{ + return true; +} + +bool ValidateBindFragDataLocation(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLuint color, + const GLchar *name) +{ + return true; +} + +bool ValidateClampColor(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum clamp) +{ + return true; +} + +bool ValidateEndConditionalRender(const Context *context, angle::EntryPoint entryPoint) +{ + return true; +} + +bool ValidateFramebufferTexture1D(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + TextureTarget textargetPacked, + TextureID texture, + GLint level) +{ + return true; +} + +bool ValidateFramebufferTexture3D(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + TextureTarget textargetPacked, + TextureID texture, + GLint level, + GLint zoffset) +{ + return true; +} + +bool ValidateVertexAttribI1i(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLint x) +{ + return true; +} + +bool ValidateVertexAttribI1iv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLint *v) +{ + return true; +} + +bool ValidateVertexAttribI1ui(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLuint x) +{ + return true; +} + +bool ValidateVertexAttribI1uiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLuint *v) +{ + return true; +} + +bool ValidateVertexAttribI2i(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLint x, + GLint y) +{ + return true; +} + +bool ValidateVertexAttribI2iv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLint *v) +{ + return true; +} + +bool ValidateVertexAttribI2ui(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLuint x, + GLuint y) +{ + return true; +} + +bool ValidateVertexAttribI2uiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLuint *v) +{ + return true; +} + +bool ValidateVertexAttribI3i(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLint x, + GLint y, + GLint z) +{ + return true; +} + +bool ValidateVertexAttribI3iv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLint *v) +{ + return true; +} + +bool ValidateVertexAttribI3ui(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLuint x, + GLuint y, + GLuint z) +{ + return true; +} + +bool ValidateVertexAttribI3uiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLuint *v) +{ + return true; +} + +bool ValidateVertexAttribI4bv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLbyte *v) +{ + return true; +} + +bool ValidateVertexAttribI4sv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLshort *v) +{ + return true; +} + +bool ValidateVertexAttribI4ubv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLubyte *v) +{ + return true; +} + +bool ValidateVertexAttribI4usv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLushort *v) +{ + return true; +} + +bool ValidateGetActiveUniformName(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLuint uniformIndex, + GLsizei bufSize, + const GLsizei *length, + const GLchar *uniformName) +{ + return true; +} + +bool ValidatePrimitiveRestartIndex(const Context *context, + angle::EntryPoint entryPoint, + GLuint index) +{ + return true; +} + +bool ValidateMultiDrawElementsBaseVertex(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + const GLsizei *count, + DrawElementsType type, + const void *const *indices, + GLsizei drawcount, + const GLint *basevertex) +{ + return true; +} + +bool ValidateProvokingVertex(const Context *context, + angle::EntryPoint entryPoint, + ProvokingVertexConvention modePacked) +{ + return true; +} + +bool ValidateTexImage2DMultisample(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations) +{ + return true; +} + +bool ValidateTexImage3DMultisample(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedsamplelocations) +{ + return true; +} + +bool ValidateBindFragDataLocationIndexed(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLuint colorNumber, + GLuint index, + const GLchar *name) +{ + return true; +} + +bool ValidateColorP3ui(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + GLuint color) +{ + return true; +} + +bool ValidateColorP3uiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + const GLuint *color) +{ + return true; +} + +bool ValidateColorP4ui(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + GLuint color) +{ + return true; +} + +bool ValidateColorP4uiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + const GLuint *color) +{ + return true; +} + +bool ValidateGetFragDataIndex(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + const GLchar *name) +{ + return true; +} + +bool ValidateGetQueryObjecti64v(const Context *context, + angle::EntryPoint entryPoint, + QueryID id, + GLenum pname, + const GLint64 *params) +{ + return true; +} + +bool ValidateGetQueryObjectui64v(const Context *context, + angle::EntryPoint entryPoint, + QueryID id, + GLenum pname, + const GLuint64 *params) +{ + return true; +} + +bool ValidateMultiTexCoordP1ui(const Context *context, + angle::EntryPoint entryPoint, + GLenum texture, + GLenum type, + GLuint coords) +{ + return true; +} + +bool ValidateMultiTexCoordP1uiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum texture, + GLenum type, + const GLuint *coords) +{ + return true; +} + +bool ValidateMultiTexCoordP2ui(const Context *context, + angle::EntryPoint entryPoint, + GLenum texture, + GLenum type, + GLuint coords) +{ + return true; +} + +bool ValidateMultiTexCoordP2uiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum texture, + GLenum type, + const GLuint *coords) +{ + return true; +} + +bool ValidateMultiTexCoordP3ui(const Context *context, + angle::EntryPoint entryPoint, + GLenum texture, + GLenum type, + GLuint coords) +{ + return true; +} + +bool ValidateMultiTexCoordP3uiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum texture, + GLenum type, + const GLuint *coords) +{ + return true; +} + +bool ValidateMultiTexCoordP4ui(const Context *context, + angle::EntryPoint entryPoint, + GLenum texture, + GLenum type, + GLuint coords) +{ + return true; +} + +bool ValidateMultiTexCoordP4uiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum texture, + GLenum type, + const GLuint *coords) +{ + return true; +} + +bool ValidateNormalP3ui(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + GLuint coords) +{ + return true; +} + +bool ValidateNormalP3uiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + const GLuint *coords) +{ + return true; +} + +bool ValidateQueryCounter(const Context *context, + angle::EntryPoint entryPoint, + QueryID id, + QueryType targetPacked) +{ + return true; +} + +bool ValidateSecondaryColorP3ui(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + GLuint color) +{ + return true; +} + +bool ValidateSecondaryColorP3uiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + const GLuint *color) +{ + return true; +} + +bool ValidateTexCoordP1ui(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + GLuint coords) +{ + return true; +} + +bool ValidateTexCoordP1uiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + const GLuint *coords) +{ + return true; +} + +bool ValidateTexCoordP2ui(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + GLuint coords) +{ + return true; +} + +bool ValidateTexCoordP2uiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + const GLuint *coords) +{ + return true; +} + +bool ValidateTexCoordP3ui(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + GLuint coords) +{ + return true; +} + +bool ValidateTexCoordP3uiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + const GLuint *coords) +{ + return true; +} + +bool ValidateTexCoordP4ui(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + GLuint coords) +{ + return true; +} + +bool ValidateTexCoordP4uiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + const GLuint *coords) +{ + return true; +} + +bool ValidateVertexAttribP1ui(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum type, + GLboolean normalized, + GLuint value) +{ + return true; +} + +bool ValidateVertexAttribP1uiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum type, + GLboolean normalized, + const GLuint *value) +{ + return true; +} + +bool ValidateVertexAttribP2ui(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum type, + GLboolean normalized, + GLuint value) +{ + return true; +} + +bool ValidateVertexAttribP2uiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum type, + GLboolean normalized, + const GLuint *value) +{ + return true; +} + +bool ValidateVertexAttribP3ui(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum type, + GLboolean normalized, + GLuint value) +{ + return true; +} + +bool ValidateVertexAttribP3uiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum type, + GLboolean normalized, + const GLuint *value) +{ + return true; +} + +bool ValidateVertexAttribP4ui(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum type, + GLboolean normalized, + GLuint value) +{ + return true; +} + +bool ValidateVertexAttribP4uiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum type, + GLboolean normalized, + const GLuint *value) +{ + return true; +} + +bool ValidateVertexP2ui(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + GLuint value) +{ + return true; +} + +bool ValidateVertexP2uiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + const GLuint *value) +{ + return true; +} + +bool ValidateVertexP3ui(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + GLuint value) +{ + return true; +} + +bool ValidateVertexP3uiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + const GLuint *value) +{ + return true; +} + +bool ValidateVertexP4ui(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + GLuint value) +{ + return true; +} + +bool ValidateVertexP4uiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + const GLuint *value) +{ + return true; +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/validationGL3_autogen.h b/gfx/angle/checkout/src/libANGLE/validationGL3_autogen.h new file mode 100644 index 0000000000..1f71153cb1 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationGL3_autogen.h @@ -0,0 +1,367 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// validationGL3_autogen.h: +// Validation functions for the OpenGL Desktop GL 3.x entry points. + +#ifndef LIBANGLE_VALIDATION_GL3_AUTOGEN_H_ +#define LIBANGLE_VALIDATION_GL3_AUTOGEN_H_ + +#include "common/PackedEnums.h" +#include "common/entry_points_enum_autogen.h" + +namespace gl +{ +class Context; + +// GL 3.0 +bool ValidateBeginConditionalRender(const Context *context, + angle::EntryPoint entryPoint, + GLuint id, + GLenum mode); +bool ValidateBindFragDataLocation(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLuint color, + const GLchar *name); +bool ValidateClampColor(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum clamp); +bool ValidateEndConditionalRender(const Context *context, angle::EntryPoint entryPoint); +bool ValidateFramebufferTexture1D(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + TextureTarget textargetPacked, + TextureID texturePacked, + GLint level); +bool ValidateFramebufferTexture3D(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum attachment, + TextureTarget textargetPacked, + TextureID texturePacked, + GLint level, + GLint zoffset); +bool ValidateVertexAttribI1i(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLint x); +bool ValidateVertexAttribI1iv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLint *v); +bool ValidateVertexAttribI1ui(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLuint x); +bool ValidateVertexAttribI1uiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLuint *v); +bool ValidateVertexAttribI2i(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLint x, + GLint y); +bool ValidateVertexAttribI2iv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLint *v); +bool ValidateVertexAttribI2ui(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLuint x, + GLuint y); +bool ValidateVertexAttribI2uiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLuint *v); +bool ValidateVertexAttribI3i(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLint x, + GLint y, + GLint z); +bool ValidateVertexAttribI3iv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLint *v); +bool ValidateVertexAttribI3ui(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLuint x, + GLuint y, + GLuint z); +bool ValidateVertexAttribI3uiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLuint *v); +bool ValidateVertexAttribI4bv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLbyte *v); +bool ValidateVertexAttribI4sv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLshort *v); +bool ValidateVertexAttribI4ubv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLubyte *v); +bool ValidateVertexAttribI4usv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLushort *v); + +// GL 3.1 +bool ValidateGetActiveUniformName(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLuint uniformIndex, + GLsizei bufSize, + const GLsizei *length, + const GLchar *uniformName); +bool ValidatePrimitiveRestartIndex(const Context *context, + angle::EntryPoint entryPoint, + GLuint index); + +// GL 3.2 +bool ValidateMultiDrawElementsBaseVertex(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + const GLsizei *count, + DrawElementsType typePacked, + const void *const *indices, + GLsizei drawcount, + const GLint *basevertex); +bool ValidateProvokingVertex(const Context *context, + angle::EntryPoint entryPoint, + ProvokingVertexConvention modePacked); +bool ValidateTexImage2DMultisample(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations); +bool ValidateTexImage3DMultisample(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedsamplelocations); + +// GL 3.3 +bool ValidateBindFragDataLocationIndexed(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLuint colorNumber, + GLuint index, + const GLchar *name); +bool ValidateColorP3ui(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + GLuint color); +bool ValidateColorP3uiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + const GLuint *color); +bool ValidateColorP4ui(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + GLuint color); +bool ValidateColorP4uiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + const GLuint *color); +bool ValidateGetFragDataIndex(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + const GLchar *name); +bool ValidateGetQueryObjecti64v(const Context *context, + angle::EntryPoint entryPoint, + QueryID idPacked, + GLenum pname, + const GLint64 *params); +bool ValidateGetQueryObjectui64v(const Context *context, + angle::EntryPoint entryPoint, + QueryID idPacked, + GLenum pname, + const GLuint64 *params); +bool ValidateMultiTexCoordP1ui(const Context *context, + angle::EntryPoint entryPoint, + GLenum texture, + GLenum type, + GLuint coords); +bool ValidateMultiTexCoordP1uiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum texture, + GLenum type, + const GLuint *coords); +bool ValidateMultiTexCoordP2ui(const Context *context, + angle::EntryPoint entryPoint, + GLenum texture, + GLenum type, + GLuint coords); +bool ValidateMultiTexCoordP2uiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum texture, + GLenum type, + const GLuint *coords); +bool ValidateMultiTexCoordP3ui(const Context *context, + angle::EntryPoint entryPoint, + GLenum texture, + GLenum type, + GLuint coords); +bool ValidateMultiTexCoordP3uiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum texture, + GLenum type, + const GLuint *coords); +bool ValidateMultiTexCoordP4ui(const Context *context, + angle::EntryPoint entryPoint, + GLenum texture, + GLenum type, + GLuint coords); +bool ValidateMultiTexCoordP4uiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum texture, + GLenum type, + const GLuint *coords); +bool ValidateNormalP3ui(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + GLuint coords); +bool ValidateNormalP3uiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + const GLuint *coords); +bool ValidateQueryCounter(const Context *context, + angle::EntryPoint entryPoint, + QueryID idPacked, + QueryType targetPacked); +bool ValidateSecondaryColorP3ui(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + GLuint color); +bool ValidateSecondaryColorP3uiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + const GLuint *color); +bool ValidateTexCoordP1ui(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + GLuint coords); +bool ValidateTexCoordP1uiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + const GLuint *coords); +bool ValidateTexCoordP2ui(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + GLuint coords); +bool ValidateTexCoordP2uiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + const GLuint *coords); +bool ValidateTexCoordP3ui(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + GLuint coords); +bool ValidateTexCoordP3uiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + const GLuint *coords); +bool ValidateTexCoordP4ui(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + GLuint coords); +bool ValidateTexCoordP4uiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + const GLuint *coords); +bool ValidateVertexAttribP1ui(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum type, + GLboolean normalized, + GLuint value); +bool ValidateVertexAttribP1uiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum type, + GLboolean normalized, + const GLuint *value); +bool ValidateVertexAttribP2ui(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum type, + GLboolean normalized, + GLuint value); +bool ValidateVertexAttribP2uiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum type, + GLboolean normalized, + const GLuint *value); +bool ValidateVertexAttribP3ui(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum type, + GLboolean normalized, + GLuint value); +bool ValidateVertexAttribP3uiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum type, + GLboolean normalized, + const GLuint *value); +bool ValidateVertexAttribP4ui(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum type, + GLboolean normalized, + GLuint value); +bool ValidateVertexAttribP4uiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum type, + GLboolean normalized, + const GLuint *value); +bool ValidateVertexP2ui(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + GLuint value); +bool ValidateVertexP2uiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + const GLuint *value); +bool ValidateVertexP3ui(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + GLuint value); +bool ValidateVertexP3uiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + const GLuint *value); +bool ValidateVertexP4ui(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + GLuint value); +bool ValidateVertexP4uiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum type, + const GLuint *value); +} // namespace gl + +#endif // LIBANGLE_VALIDATION_GL3_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/libANGLE/validationGL4.cpp b/gfx/angle/checkout/src/libANGLE/validationGL4.cpp new file mode 100644 index 0000000000..066391d1d9 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationGL4.cpp @@ -0,0 +1,2223 @@ +// +// Copyright 2019 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// validationGL4.cpp: Validation functions for OpenGL 4.0 entry point parameters + +#include "libANGLE/validationGL4_autogen.h" + +namespace gl +{ + +bool ValidateBeginQueryIndexed(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index, + QueryID id) +{ + return true; +} + +bool ValidateDrawTransformFeedback(const Context *context, + angle::EntryPoint entryPoint, + GLenum mode, + TransformFeedbackID id) +{ + return true; +} + +bool ValidateDrawTransformFeedbackStream(const Context *context, + angle::EntryPoint entryPoint, + GLenum mode, + TransformFeedbackID id, + GLuint stream) +{ + return true; +} + +bool ValidateEndQueryIndexed(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index) +{ + return true; +} + +bool ValidateGetActiveSubroutineName(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLenum shadertype, + GLuint index, + GLsizei bufsize, + const GLsizei *length, + const GLchar *name) +{ + return true; +} + +bool ValidateGetActiveSubroutineUniformName(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLenum shadertype, + GLuint index, + GLsizei bufsize, + const GLsizei *length, + const GLchar *name) +{ + return true; +} + +bool ValidateGetActiveSubroutineUniformiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLenum shadertype, + GLuint index, + GLenum pname, + const GLint *values) +{ + return true; +} + +bool ValidateGetProgramStageiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLenum shadertype, + GLenum pname, + const GLint *values) +{ + return true; +} + +bool ValidateGetQueryIndexediv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index, + GLenum pname, + const GLint *params) +{ + return true; +} + +bool ValidateGetSubroutineIndex(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLenum shadertype, + const GLchar *name) +{ + return true; +} + +bool ValidateGetSubroutineUniformLocation(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLenum shadertype, + const GLchar *name) +{ + return true; +} + +bool ValidateGetUniformSubroutineuiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum shadertype, + GLint location, + const GLuint *params) +{ + return true; +} + +bool ValidateGetUniformdv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + const GLdouble *params) +{ + return true; +} + +bool ValidatePatchParameterfv(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + const GLfloat *values) +{ + return true; +} + +bool ValidateUniform1d(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLdouble x) +{ + return true; +} + +bool ValidateUniform1dv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + const GLdouble *value) +{ + return true; +} + +bool ValidateUniform2d(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLdouble x, + GLdouble y) +{ + return true; +} + +bool ValidateUniform2dv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + const GLdouble *value) +{ + return true; +} + +bool ValidateUniform3d(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLdouble x, + GLdouble y, + GLdouble z) +{ + return true; +} + +bool ValidateUniform3dv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + const GLdouble *value) +{ + return true; +} + +bool ValidateUniform4d(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLdouble x, + GLdouble y, + GLdouble z, + GLdouble w) +{ + return true; +} + +bool ValidateUniform4dv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + const GLdouble *value) +{ + return true; +} + +bool ValidateUniformMatrix2dv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + return true; +} + +bool ValidateUniformMatrix2x3dv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + return true; +} + +bool ValidateUniformMatrix2x4dv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + return true; +} + +bool ValidateUniformMatrix3dv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + return true; +} + +bool ValidateUniformMatrix3x2dv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + return true; +} + +bool ValidateUniformMatrix3x4dv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + return true; +} + +bool ValidateUniformMatrix4dv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + return true; +} + +bool ValidateUniformMatrix4x2dv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + return true; +} + +bool ValidateUniformMatrix4x3dv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + return true; +} + +bool ValidateUniformSubroutinesuiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum shadertype, + GLsizei count, + const GLuint *indices) +{ + return true; +} + +bool ValidateDepthRangeArrayv(const Context *context, + angle::EntryPoint entryPoint, + GLuint first, + GLsizei count, + const GLdouble *v) +{ + return true; +} + +bool ValidateDepthRangeIndexed(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLdouble n, + GLdouble f) +{ + return true; +} + +bool ValidateGetDoublei_v(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index, + const GLdouble *data) +{ + return true; +} + +bool ValidateGetFloati_v(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index, + const GLfloat *data) +{ + return true; +} + +bool ValidateGetVertexAttribLdv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum pname, + const GLdouble *params) +{ + return true; +} + +bool ValidateProgramUniform1d(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLdouble v0) +{ + return true; +} + +bool ValidateProgramUniform1dv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLdouble *value) +{ + return true; +} + +bool ValidateProgramUniform2d(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLdouble v0, + GLdouble v1) +{ + return true; +} + +bool ValidateProgramUniform2dv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLdouble *value) +{ + return true; +} + +bool ValidateProgramUniform3d(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLdouble v0, + GLdouble v1, + GLdouble v2) +{ + return true; +} + +bool ValidateProgramUniform3dv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLdouble *value) +{ + return true; +} + +bool ValidateProgramUniform4d(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLdouble v0, + GLdouble v1, + GLdouble v2, + GLdouble v3) +{ + return true; +} + +bool ValidateProgramUniform4dv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + const GLdouble *value) +{ + return true; +} + +bool ValidateProgramUniformMatrix2dv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + return true; +} + +bool ValidateProgramUniformMatrix2x3dv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + return true; +} + +bool ValidateProgramUniformMatrix2x4dv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + return true; +} + +bool ValidateProgramUniformMatrix3dv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + return true; +} + +bool ValidateProgramUniformMatrix3x2dv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + return true; +} + +bool ValidateProgramUniformMatrix3x4dv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + return true; +} + +bool ValidateProgramUniformMatrix4dv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + return true; +} + +bool ValidateProgramUniformMatrix4x2dv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + return true; +} + +bool ValidateProgramUniformMatrix4x3dv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei count, + GLboolean transpose, + const GLdouble *value) +{ + return true; +} + +bool ValidateScissorArrayv(const Context *context, + angle::EntryPoint entryPoint, + GLuint first, + GLsizei count, + const GLint *v) +{ + return true; +} + +bool ValidateScissorIndexed(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLint left, + GLint bottom, + GLsizei width, + GLsizei height) +{ + return true; +} + +bool ValidateScissorIndexedv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLint *v) +{ + return true; +} + +bool ValidateVertexAttribL1d(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLdouble x) +{ + return true; +} + +bool ValidateVertexAttribL1dv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLdouble *v) +{ + return true; +} + +bool ValidateVertexAttribL2d(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLdouble x, + GLdouble y) +{ + return true; +} + +bool ValidateVertexAttribL2dv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLdouble *v) +{ + return true; +} + +bool ValidateVertexAttribL3d(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLdouble x, + GLdouble y, + GLdouble z) +{ + return true; +} + +bool ValidateVertexAttribL3dv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLdouble *v) +{ + return true; +} + +bool ValidateVertexAttribL4d(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLdouble x, + GLdouble y, + GLdouble z, + GLdouble w) +{ + return true; +} + +bool ValidateVertexAttribL4dv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLdouble *v) +{ + return true; +} + +bool ValidateVertexAttribLPointer(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLint size, + GLenum type, + GLsizei stride, + const void *pointer) +{ + return true; +} + +bool ValidateViewportArrayv(const Context *context, + angle::EntryPoint entryPoint, + GLuint first, + GLsizei count, + const GLfloat *v) +{ + return true; +} + +bool ValidateViewportIndexedf(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLfloat x, + GLfloat y, + GLfloat w, + GLfloat h) +{ + return true; +} + +bool ValidateViewportIndexedfv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLfloat *v) +{ + return true; +} + +bool ValidateDrawArraysInstancedBaseInstance(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLint first, + GLsizei count, + GLsizei instancecount, + GLuint baseinstance) +{ + return true; +} + +bool ValidateDrawElementsInstancedBaseInstance(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLsizei count, + DrawElementsType type, + const void *indices, + GLsizei instancecount, + GLuint baseinstance) +{ + return true; +} + +bool ValidateDrawElementsInstancedBaseVertexBaseInstance(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode mode, + GLsizei count, + DrawElementsType type, + const void *indices, + GLsizei instancecount, + GLint basevertex, + GLuint baseinstance) +{ + return true; +} + +bool ValidateDrawTransformFeedbackInstanced(const Context *context, + angle::EntryPoint entryPoint, + GLenum mode, + TransformFeedbackID id, + GLsizei instancecount) +{ + return true; +} + +bool ValidateDrawTransformFeedbackStreamInstanced(const Context *context, + angle::EntryPoint entryPoint, + GLenum mode, + TransformFeedbackID id, + GLuint stream, + GLsizei instancecount) +{ + return true; +} + +bool ValidateGetActiveAtomicCounterBufferiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLuint bufferIndex, + GLenum pname, + const GLint *params) +{ + return true; +} + +bool ValidateTexStorage1D(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width) +{ + return true; +} + +bool ValidateClearBufferData(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum internalformat, + GLenum format, + GLenum type, + const void *data) +{ + return true; +} + +bool ValidateClearBufferSubData(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum internalformat, + GLintptr offset, + GLsizeiptr size, + GLenum format, + GLenum type, + const void *data) +{ + return true; +} + +bool ValidateGetInternalformati64v(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei bufSize, + const GLint64 *params) +{ + return true; +} + +bool ValidateGetProgramResourceLocationIndex(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLenum programInterface, + const GLchar *name) +{ + return true; +} + +bool ValidateInvalidateBufferData(const Context *context, + angle::EntryPoint entryPoint, + BufferID buffer) +{ + return true; +} + +bool ValidateInvalidateBufferSubData(const Context *context, + angle::EntryPoint entryPoint, + BufferID buffer, + GLintptr offset, + GLsizeiptr length) +{ + return true; +} + +bool ValidateInvalidateTexImage(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLint level) +{ + return true; +} + +bool ValidateInvalidateTexSubImage(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth) +{ + return true; +} + +bool ValidateMultiDrawArraysIndirect(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + const void *indirect, + GLsizei drawcount, + GLsizei stride) +{ + return true; +} + +bool ValidateMultiDrawElementsIndirect(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + DrawElementsType typePacked, + const void *indirect, + GLsizei drawcount, + GLsizei stride) +{ + return true; +} + +bool ValidateShaderStorageBlockBinding(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + GLuint storageBlockIndex, + GLuint storageBlockBinding) +{ + return true; +} + +bool ValidateTextureView(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLenum target, + GLuint origtexture, + GLenum internalformat, + GLuint minlevel, + GLuint numlevels, + GLuint minlayer, + GLuint numlayers) +{ + return true; +} + +bool ValidateVertexAttribLFormat(const Context *context, + angle::EntryPoint entryPoint, + GLuint attribindex, + GLint size, + GLenum type, + GLuint relativeoffset) +{ + return true; +} + +bool ValidateBindBuffersBase(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint first, + GLsizei count, + const BufferID *buffers) +{ + return true; +} + +bool ValidateBindBuffersRange(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint first, + GLsizei count, + const BufferID *buffers, + const GLintptr *offsets, + const GLsizeiptr *sizes) +{ + return true; +} + +bool ValidateBindImageTextures(const Context *context, + angle::EntryPoint entryPoint, + GLuint first, + GLsizei count, + const GLuint *textures) +{ + return true; +} + +bool ValidateBindSamplers(const Context *context, + angle::EntryPoint entryPoint, + GLuint first, + GLsizei count, + const GLuint *samplers) +{ + return true; +} + +bool ValidateBindTextures(const Context *context, + angle::EntryPoint entryPoint, + GLuint first, + GLsizei count, + const GLuint *textures) +{ + return true; +} + +bool ValidateBindVertexBuffers(const Context *context, + angle::EntryPoint entryPoint, + GLuint first, + GLsizei count, + const BufferID *buffers, + const GLintptr *offsets, + const GLsizei *strides) +{ + return true; +} + +bool ValidateBufferStorage(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding targetPacked, + GLsizeiptr size, + const void *data, + GLbitfield flags) +{ + return true; +} + +bool ValidateClearTexImage(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLint level, + GLenum format, + GLenum type, + const void *data) +{ + return true; +} + +bool ValidateClearTexSubImage(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *data) +{ + return true; +} + +bool ValidateBindTextureUnit(const Context *context, + angle::EntryPoint entryPoint, + GLuint unit, + TextureID texture) +{ + return true; +} + +bool ValidateBlitNamedFramebuffer(const Context *context, + angle::EntryPoint entryPoint, + GLuint readFramebuffer, + GLuint drawFramebuffer, + GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter) +{ + return true; +} + +bool ValidateCheckNamedFramebufferStatus(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebuffer, + GLenum target) +{ + return true; +} + +bool ValidateClearNamedBufferData(const Context *context, + angle::EntryPoint entryPoint, + BufferID buffer, + GLenum internalformat, + GLenum format, + GLenum type, + const void *data) +{ + return true; +} + +bool ValidateClearNamedBufferSubData(const Context *context, + angle::EntryPoint entryPoint, + BufferID buffer, + GLenum internalformat, + GLintptr offset, + GLsizeiptr size, + GLenum format, + GLenum type, + const void *data) +{ + return true; +} + +bool ValidateClearNamedFramebufferfi(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebuffer, + GLenum buffer, + GLint drawbuffer, + GLfloat depth, + GLint stencil) +{ + return true; +} + +bool ValidateClearNamedFramebufferfv(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebuffer, + GLenum buffer, + GLint drawbuffer, + const GLfloat *value) +{ + return true; +} + +bool ValidateClearNamedFramebufferiv(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebuffer, + GLenum buffer, + GLint drawbuffer, + const GLint *value) +{ + return true; +} + +bool ValidateClearNamedFramebufferuiv(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebuffer, + GLenum buffer, + GLint drawbuffer, + const GLuint *value) +{ + return true; +} + +bool ValidateClipControl(const Context *context, + angle::EntryPoint entryPoint, + GLenum origin, + GLenum depth) +{ + return true; +} + +bool ValidateCompressedTextureSubImage1D(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, + GLsizei imageSize, + const void *data) +{ + return true; +} + +bool ValidateCompressedTextureSubImage2D(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + const void *data) +{ + return true; +} + +bool ValidateCompressedTextureSubImage3D(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const void *data) +{ + return true; +} + +bool ValidateCopyNamedBufferSubData(const Context *context, + angle::EntryPoint entryPoint, + GLuint readBuffer, + GLuint writeBuffer, + GLintptr readOffset, + GLintptr writeOffset, + GLsizeiptr size) +{ + return true; +} + +bool ValidateCopyTextureSubImage1D(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLint level, + GLint xoffset, + GLint x, + GLint y, + GLsizei width) +{ + return true; +} + +bool ValidateCopyTextureSubImage2D(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLint level, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) +{ + return true; +} + +bool ValidateCopyTextureSubImage3D(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) +{ + return true; +} + +bool ValidateCreateBuffers(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const BufferID *buffers) +{ + return true; +} + +bool ValidateCreateFramebuffers(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const GLuint *framebuffers) +{ + return true; +} + +bool ValidateCreateProgramPipelines(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const GLuint *pipelines) +{ + return true; +} + +bool ValidateCreateQueries(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLsizei n, + const GLuint *ids) +{ + return true; +} + +bool ValidateCreateRenderbuffers(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const RenderbufferID *renderbuffers) +{ + return true; +} + +bool ValidateCreateSamplers(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const GLuint *samplers) +{ + return true; +} + +bool ValidateCreateTextures(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLsizei n, + const GLuint *textures) +{ + return true; +} + +bool ValidateCreateTransformFeedbacks(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const GLuint *ids) +{ + return true; +} + +bool ValidateCreateVertexArrays(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const VertexArrayID *arrays) +{ + return true; +} + +bool ValidateDisableVertexArrayAttrib(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID vaobj, + GLuint index) +{ + return true; +} + +bool ValidateEnableVertexArrayAttrib(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID vaobj, + GLuint index) +{ + return true; +} + +bool ValidateFlushMappedNamedBufferRange(const Context *context, + angle::EntryPoint entryPoint, + BufferID buffer, + GLintptr offset, + GLsizeiptr length) +{ + return true; +} + +bool ValidateGenerateTextureMipmap(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture) +{ + return true; +} + +bool ValidateGetCompressedTextureImage(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLint level, + GLsizei bufSize, + const void *pixels) +{ + return true; +} + +bool ValidateGetCompressedTextureSubImage(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLsizei bufSize, + const void *pixels) +{ + return true; +} + +bool ValidateGetNamedBufferParameteri64v(const Context *context, + angle::EntryPoint entryPoint, + BufferID buffer, + GLenum pname, + const GLint64 *params) +{ + return true; +} + +bool ValidateGetNamedBufferParameteriv(const Context *context, + angle::EntryPoint entryPoint, + BufferID buffer, + GLenum pname, + const GLint *params) +{ + return true; +} + +bool ValidateGetNamedBufferPointerv(const Context *context, + angle::EntryPoint entryPoint, + BufferID buffer, + GLenum pname, + void *const *params) +{ + return true; +} + +bool ValidateGetNamedBufferSubData(const Context *context, + angle::EntryPoint entryPoint, + BufferID buffer, + GLintptr offset, + GLsizeiptr size, + const void *data) +{ + return true; +} + +bool ValidateGetNamedFramebufferAttachmentParameteriv(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebuffer, + GLenum attachment, + GLenum pname, + const GLint *params) +{ + return true; +} + +bool ValidateGetNamedFramebufferParameteriv(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebuffer, + GLenum pname, + const GLint *param) +{ + return true; +} + +bool ValidateGetNamedRenderbufferParameteriv(const Context *context, + angle::EntryPoint entryPoint, + RenderbufferID renderbuffer, + GLenum pname, + const GLint *params) +{ + return true; +} + +bool ValidateGetQueryBufferObjecti64v(const Context *context, + angle::EntryPoint entryPoint, + GLuint id, + BufferID buffer, + GLenum pname, + GLintptr offset) +{ + return true; +} + +bool ValidateGetQueryBufferObjectiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint id, + BufferID buffer, + GLenum pname, + GLintptr offset) +{ + return true; +} + +bool ValidateGetQueryBufferObjectui64v(const Context *context, + angle::EntryPoint entryPoint, + GLuint id, + BufferID buffer, + GLenum pname, + GLintptr offset) +{ + return true; +} + +bool ValidateGetQueryBufferObjectuiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint id, + BufferID buffer, + GLenum pname, + GLintptr offset) +{ + return true; +} + +bool ValidateGetTextureImage(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLint level, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels) +{ + return true; +} + +bool ValidateGetTextureLevelParameterfv(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLint level, + GLenum pname, + const GLfloat *params) +{ + return true; +} + +bool ValidateGetTextureLevelParameteriv(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLint level, + GLenum pname, + const GLint *params) +{ + return true; +} + +bool ValidateGetTextureParameterIiv(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLenum pname, + const GLint *params) +{ + return true; +} + +bool ValidateGetTextureParameterIuiv(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLenum pname, + const GLuint *params) +{ + return true; +} + +bool ValidateGetTextureParameterfv(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLenum pname, + const GLfloat *params) +{ + return true; +} + +bool ValidateGetTextureParameteriv(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLenum pname, + const GLint *params) +{ + return true; +} + +bool ValidateGetTextureSubImage(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels) +{ + return true; +} + +bool ValidateGetTransformFeedbacki64_v(const Context *context, + angle::EntryPoint entryPoint, + GLuint xfb, + GLenum pname, + GLuint index, + const GLint64 *param) +{ + return true; +} + +bool ValidateGetTransformFeedbacki_v(const Context *context, + angle::EntryPoint entryPoint, + GLuint xfb, + GLenum pname, + GLuint index, + const GLint *param) +{ + return true; +} + +bool ValidateGetTransformFeedbackiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint xfb, + GLenum pname, + const GLint *param) +{ + return true; +} + +bool ValidateGetVertexArrayIndexed64iv(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID vaobj, + GLuint index, + GLenum pname, + const GLint64 *param) +{ + return true; +} + +bool ValidateGetVertexArrayIndexediv(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID vaobj, + GLuint index, + GLenum pname, + const GLint *param) +{ + return true; +} + +bool ValidateGetVertexArrayiv(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID vaobj, + GLenum pname, + const GLint *param) +{ + return true; +} + +bool ValidateGetnColorTable(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *table) +{ + return true; +} + +bool ValidateGetnCompressedTexImage(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLint lod, + GLsizei bufSize, + const void *pixels) +{ + return true; +} + +bool ValidateGetnConvolutionFilter(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *image) +{ + return true; +} + +bool ValidateGetnHistogram(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLboolean reset, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *values) +{ + return true; +} + +bool ValidateGetnMapdv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum query, + GLsizei bufSize, + const GLdouble *v) +{ + return true; +} + +bool ValidateGetnMapfv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum query, + GLsizei bufSize, + const GLfloat *v) +{ + return true; +} + +bool ValidateGetnMapiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum query, + GLsizei bufSize, + const GLint *v) +{ + return true; +} + +bool ValidateGetnMinmax(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLboolean reset, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *values) +{ + return true; +} + +bool ValidateGetnPixelMapfv(const Context *context, + angle::EntryPoint entryPoint, + GLenum map, + GLsizei bufSize, + const GLfloat *values) +{ + return true; +} + +bool ValidateGetnPixelMapuiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum map, + GLsizei bufSize, + const GLuint *values) +{ + return true; +} + +bool ValidateGetnPixelMapusv(const Context *context, + angle::EntryPoint entryPoint, + GLenum map, + GLsizei bufSize, + const GLushort *values) +{ + return true; +} + +bool ValidateGetnPolygonStipple(const Context *context, + angle::EntryPoint entryPoint, + GLsizei bufSize, + const GLubyte *pattern) +{ + return true; +} + +bool ValidateGetnSeparableFilter(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum format, + GLenum type, + GLsizei rowBufSize, + const void *row, + GLsizei columnBufSize, + const void *column, + const void *span) +{ + return true; +} + +bool ValidateGetnTexImage(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLint level, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels) +{ + return true; +} + +bool ValidateGetnUniformdv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID program, + UniformLocation location, + GLsizei bufSize, + const GLdouble *params) +{ + return true; +} + +bool ValidateInvalidateNamedFramebufferData(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebuffer, + GLsizei numAttachments, + const GLenum *attachments) +{ + return true; +} + +bool ValidateInvalidateNamedFramebufferSubData(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebuffer, + GLsizei numAttachments, + const GLenum *attachments, + GLint x, + GLint y, + GLsizei width, + GLsizei height) +{ + return true; +} + +bool ValidateMapNamedBuffer(const Context *context, + angle::EntryPoint entryPoint, + BufferID buffer, + GLenum access) +{ + return true; +} + +bool ValidateMapNamedBufferRange(const Context *context, + angle::EntryPoint entryPoint, + BufferID buffer, + GLintptr offset, + GLsizeiptr length, + GLbitfield access) +{ + return true; +} + +bool ValidateNamedBufferData(const Context *context, + angle::EntryPoint entryPoint, + BufferID buffer, + GLsizeiptr size, + const void *data, + GLenum usage) +{ + return true; +} + +bool ValidateNamedBufferStorage(const Context *context, + angle::EntryPoint entryPoint, + BufferID buffer, + GLsizeiptr size, + const void *data, + GLbitfield flags) +{ + return true; +} + +bool ValidateNamedBufferSubData(const Context *context, + angle::EntryPoint entryPoint, + BufferID buffer, + GLintptr offset, + GLsizeiptr size, + const void *data) +{ + return true; +} + +bool ValidateNamedFramebufferDrawBuffer(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebuffer, + GLenum buf) +{ + return true; +} + +bool ValidateNamedFramebufferDrawBuffers(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebuffer, + GLsizei n, + const GLenum *bufs) +{ + return true; +} + +bool ValidateNamedFramebufferParameteri(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebuffer, + GLenum pname, + GLint param) +{ + return true; +} + +bool ValidateNamedFramebufferReadBuffer(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebuffer, + GLenum src) +{ + return true; +} + +bool ValidateNamedFramebufferRenderbuffer(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebuffer, + GLenum attachment, + GLenum renderbuffertarget, + RenderbufferID renderbuffer) +{ + return true; +} + +bool ValidateNamedFramebufferTexture(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebuffer, + GLenum attachment, + TextureID texture, + GLint level) +{ + return true; +} + +bool ValidateNamedFramebufferTextureLayer(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebuffer, + GLenum attachment, + TextureID texture, + GLint level, + GLint layer) +{ + return true; +} + +bool ValidateNamedRenderbufferStorage(const Context *context, + angle::EntryPoint entryPoint, + RenderbufferID renderbuffer, + GLenum internalformat, + GLsizei width, + GLsizei height) +{ + return true; +} + +bool ValidateNamedRenderbufferStorageMultisample(const Context *context, + angle::EntryPoint entryPoint, + RenderbufferID renderbuffer, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height) +{ + return true; +} + +bool ValidateTextureBarrier(const Context *context, angle::EntryPoint entryPoint) +{ + return true; +} + +bool ValidateTextureBuffer(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLenum internalformat, + BufferID buffer) +{ + return true; +} + +bool ValidateTextureBufferRange(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLenum internalformat, + BufferID buffer, + GLintptr offset, + GLsizeiptr size) +{ + return true; +} + +bool ValidateTextureParameterIiv(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLenum pname, + const GLint *params) +{ + return true; +} + +bool ValidateTextureParameterIuiv(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLenum pname, + const GLuint *params) +{ + return true; +} + +bool ValidateTextureParameterf(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLenum pname, + GLfloat param) +{ + return true; +} + +bool ValidateTextureParameterfv(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLenum pname, + const GLfloat *param) +{ + return true; +} + +bool ValidateTextureParameteri(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLenum pname, + GLint param) +{ + return true; +} + +bool ValidateTextureParameteriv(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLenum pname, + const GLint *param) +{ + return true; +} + +bool ValidateTextureStorage1D(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLsizei levels, + GLenum internalformat, + GLsizei width) +{ + return true; +} + +bool ValidateTextureStorage2D(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height) +{ + return true; +} + +bool ValidateTextureStorage2DMultisample(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations) +{ + return true; +} + +bool ValidateTextureStorage3D(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth) +{ + return true; +} + +bool ValidateTextureStorage3DMultisample(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedsamplelocations) +{ + return true; +} + +bool ValidateTextureSubImage1D(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, + GLenum type, + const void *pixels) +{ + return true; +} + +bool ValidateTextureSubImage2D(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void *pixels) +{ + return true; +} + +bool ValidateTextureSubImage3D(const Context *context, + angle::EntryPoint entryPoint, + TextureID texture, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *pixels) +{ + return true; +} + +bool ValidateTransformFeedbackBufferBase(const Context *context, + angle::EntryPoint entryPoint, + GLuint xfb, + GLuint index, + BufferID buffer) +{ + return true; +} + +bool ValidateTransformFeedbackBufferRange(const Context *context, + angle::EntryPoint entryPoint, + GLuint xfb, + GLuint index, + BufferID buffer, + GLintptr offset, + GLsizeiptr size) +{ + return true; +} + +bool ValidateUnmapNamedBuffer(const Context *context, angle::EntryPoint entryPoint, BufferID buffer) +{ + return true; +} + +bool ValidateVertexArrayAttribBinding(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID vaobj, + GLuint attribindex, + GLuint bindingindex) +{ + return true; +} + +bool ValidateVertexArrayAttribFormat(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID vaobj, + GLuint attribindex, + GLint size, + GLenum type, + GLboolean normalized, + GLuint relativeoffset) +{ + return true; +} + +bool ValidateVertexArrayAttribIFormat(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID vaobj, + GLuint attribindex, + GLint size, + GLenum type, + GLuint relativeoffset) +{ + return true; +} + +bool ValidateVertexArrayAttribLFormat(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID vaobj, + GLuint attribindex, + GLint size, + GLenum type, + GLuint relativeoffset) +{ + return true; +} + +bool ValidateVertexArrayBindingDivisor(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID vaobj, + GLuint bindingindex, + GLuint divisor) +{ + return true; +} + +bool ValidateVertexArrayElementBuffer(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID vaobj, + BufferID buffer) +{ + return true; +} + +bool ValidateVertexArrayVertexBuffer(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID vaobj, + GLuint bindingindex, + BufferID buffer, + GLintptr offset, + GLsizei stride) +{ + return true; +} + +bool ValidateVertexArrayVertexBuffers(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID vaobj, + GLuint first, + GLsizei count, + const BufferID *buffers, + const GLintptr *offsets, + const GLsizei *strides) +{ + return true; +} + +bool ValidateMultiDrawArraysIndirectCount(const Context *context, + angle::EntryPoint entryPoint, + GLenum mode, + const void *indirect, + GLintptr drawcount, + GLsizei maxdrawcount, + GLsizei stride) +{ + return true; +} + +bool ValidateMultiDrawElementsIndirectCount(const Context *context, + angle::EntryPoint entryPoint, + GLenum mode, + GLenum type, + const void *indirect, + GLintptr drawcount, + GLsizei maxdrawcount, + GLsizei stride) +{ + return true; +} + +bool ValidatePolygonOffsetClamp(const Context *context, + angle::EntryPoint entryPoint, + GLfloat factor, + GLfloat units, + GLfloat clamp) +{ + return true; +} + +bool ValidateSpecializeShader(const Context *context, + angle::EntryPoint entryPoint, + GLuint shader, + const GLchar *pEntryPoint, + GLuint numSpecializationConstants, + const GLuint *pConstantIndex, + const GLuint *pConstantValue) +{ + return true; +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/libANGLE/validationGL4_autogen.h b/gfx/angle/checkout/src/libANGLE/validationGL4_autogen.h new file mode 100644 index 0000000000..a69a1f2092 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationGL4_autogen.h @@ -0,0 +1,1375 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml. +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// validationGL4_autogen.h: +// Validation functions for the OpenGL Desktop GL 4.x entry points. + +#ifndef LIBANGLE_VALIDATION_GL4_AUTOGEN_H_ +#define LIBANGLE_VALIDATION_GL4_AUTOGEN_H_ + +#include "common/PackedEnums.h" +#include "common/entry_points_enum_autogen.h" + +namespace gl +{ +class Context; + +// GL 4.0 +bool ValidateBeginQueryIndexed(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index, + QueryID idPacked); +bool ValidateDrawTransformFeedback(const Context *context, + angle::EntryPoint entryPoint, + GLenum mode, + TransformFeedbackID idPacked); +bool ValidateDrawTransformFeedbackStream(const Context *context, + angle::EntryPoint entryPoint, + GLenum mode, + TransformFeedbackID idPacked, + GLuint stream); +bool ValidateEndQueryIndexed(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index); +bool ValidateGetActiveSubroutineName(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLenum shadertype, + GLuint index, + GLsizei bufSize, + const GLsizei *length, + const GLchar *name); +bool ValidateGetActiveSubroutineUniformName(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLenum shadertype, + GLuint index, + GLsizei bufSize, + const GLsizei *length, + const GLchar *name); +bool ValidateGetActiveSubroutineUniformiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLenum shadertype, + GLuint index, + GLenum pname, + const GLint *values); +bool ValidateGetProgramStageiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLenum shadertype, + GLenum pname, + const GLint *values); +bool ValidateGetQueryIndexediv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index, + GLenum pname, + const GLint *params); +bool ValidateGetSubroutineIndex(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLenum shadertype, + const GLchar *name); +bool ValidateGetSubroutineUniformLocation(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLenum shadertype, + const GLchar *name); +bool ValidateGetUniformSubroutineuiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum shadertype, + GLint location, + const GLuint *params); +bool ValidateGetUniformdv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + const GLdouble *params); +bool ValidatePatchParameterfv(const Context *context, + angle::EntryPoint entryPoint, + GLenum pname, + const GLfloat *values); +bool ValidateUniform1d(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLdouble x); +bool ValidateUniform1dv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + const GLdouble *value); +bool ValidateUniform2d(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLdouble x, + GLdouble y); +bool ValidateUniform2dv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + const GLdouble *value); +bool ValidateUniform3d(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLdouble x, + GLdouble y, + GLdouble z); +bool ValidateUniform3dv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + const GLdouble *value); +bool ValidateUniform4d(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLdouble x, + GLdouble y, + GLdouble z, + GLdouble w); +bool ValidateUniform4dv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + const GLdouble *value); +bool ValidateUniformMatrix2dv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +bool ValidateUniformMatrix2x3dv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +bool ValidateUniformMatrix2x4dv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +bool ValidateUniformMatrix3dv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +bool ValidateUniformMatrix3x2dv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +bool ValidateUniformMatrix3x4dv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +bool ValidateUniformMatrix4dv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +bool ValidateUniformMatrix4x2dv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +bool ValidateUniformMatrix4x3dv(const Context *context, + angle::EntryPoint entryPoint, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +bool ValidateUniformSubroutinesuiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum shadertype, + GLsizei count, + const GLuint *indices); + +// GL 4.1 +bool ValidateDepthRangeArrayv(const Context *context, + angle::EntryPoint entryPoint, + GLuint first, + GLsizei count, + const GLdouble *v); +bool ValidateDepthRangeIndexed(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLdouble n, + GLdouble f); +bool ValidateGetDoublei_v(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index, + const GLdouble *data); +bool ValidateGetFloati_v(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint index, + const GLfloat *data); +bool ValidateGetVertexAttribLdv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLenum pname, + const GLdouble *params); +bool ValidateProgramUniform1d(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLdouble v0); +bool ValidateProgramUniform1dv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLdouble *value); +bool ValidateProgramUniform2d(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLdouble v0, + GLdouble v1); +bool ValidateProgramUniform2dv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLdouble *value); +bool ValidateProgramUniform3d(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLdouble v0, + GLdouble v1, + GLdouble v2); +bool ValidateProgramUniform3dv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLdouble *value); +bool ValidateProgramUniform4d(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLdouble v0, + GLdouble v1, + GLdouble v2, + GLdouble v3); +bool ValidateProgramUniform4dv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + const GLdouble *value); +bool ValidateProgramUniformMatrix2dv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +bool ValidateProgramUniformMatrix2x3dv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +bool ValidateProgramUniformMatrix2x4dv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +bool ValidateProgramUniformMatrix3dv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +bool ValidateProgramUniformMatrix3x2dv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +bool ValidateProgramUniformMatrix3x4dv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +bool ValidateProgramUniformMatrix4dv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +bool ValidateProgramUniformMatrix4x2dv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +bool ValidateProgramUniformMatrix4x3dv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +bool ValidateScissorArrayv(const Context *context, + angle::EntryPoint entryPoint, + GLuint first, + GLsizei count, + const GLint *v); +bool ValidateScissorIndexed(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLint left, + GLint bottom, + GLsizei width, + GLsizei height); +bool ValidateScissorIndexedv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLint *v); +bool ValidateVertexAttribL1d(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLdouble x); +bool ValidateVertexAttribL1dv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLdouble *v); +bool ValidateVertexAttribL2d(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLdouble x, + GLdouble y); +bool ValidateVertexAttribL2dv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLdouble *v); +bool ValidateVertexAttribL3d(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLdouble x, + GLdouble y, + GLdouble z); +bool ValidateVertexAttribL3dv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLdouble *v); +bool ValidateVertexAttribL4d(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLdouble x, + GLdouble y, + GLdouble z, + GLdouble w); +bool ValidateVertexAttribL4dv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLdouble *v); +bool ValidateVertexAttribLPointer(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLint size, + GLenum type, + GLsizei stride, + const void *pointer); +bool ValidateViewportArrayv(const Context *context, + angle::EntryPoint entryPoint, + GLuint first, + GLsizei count, + const GLfloat *v); +bool ValidateViewportIndexedf(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + GLfloat x, + GLfloat y, + GLfloat w, + GLfloat h); +bool ValidateViewportIndexedfv(const Context *context, + angle::EntryPoint entryPoint, + GLuint index, + const GLfloat *v); + +// GL 4.2 +bool ValidateDrawArraysInstancedBaseInstance(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + GLint first, + GLsizei count, + GLsizei instancecount, + GLuint baseinstance); +bool ValidateDrawElementsInstancedBaseInstance(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLsizei instancecount, + GLuint baseinstance); +bool ValidateDrawElementsInstancedBaseVertexBaseInstance(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + GLsizei count, + DrawElementsType typePacked, + const void *indices, + GLsizei instancecount, + GLint basevertex, + GLuint baseinstance); +bool ValidateDrawTransformFeedbackInstanced(const Context *context, + angle::EntryPoint entryPoint, + GLenum mode, + TransformFeedbackID idPacked, + GLsizei instancecount); +bool ValidateDrawTransformFeedbackStreamInstanced(const Context *context, + angle::EntryPoint entryPoint, + GLenum mode, + TransformFeedbackID idPacked, + GLuint stream, + GLsizei instancecount); +bool ValidateGetActiveAtomicCounterBufferiv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLuint bufferIndex, + GLenum pname, + const GLint *params); +bool ValidateTexStorage1D(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width); + +// GL 4.3 +bool ValidateClearBufferData(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum internalformat, + GLenum format, + GLenum type, + const void *data); +bool ValidateClearBufferSubData(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum internalformat, + GLintptr offset, + GLsizeiptr size, + GLenum format, + GLenum type, + const void *data); +bool ValidateGetInternalformati64v(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei count, + const GLint64 *params); +bool ValidateGetProgramResourceLocationIndex(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLenum programInterface, + const GLchar *name); +bool ValidateInvalidateBufferData(const Context *context, + angle::EntryPoint entryPoint, + BufferID bufferPacked); +bool ValidateInvalidateBufferSubData(const Context *context, + angle::EntryPoint entryPoint, + BufferID bufferPacked, + GLintptr offset, + GLsizeiptr length); +bool ValidateInvalidateTexImage(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLint level); +bool ValidateInvalidateTexSubImage(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth); +bool ValidateMultiDrawArraysIndirect(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + const void *indirect, + GLsizei drawcount, + GLsizei stride); +bool ValidateMultiDrawElementsIndirect(const Context *context, + angle::EntryPoint entryPoint, + PrimitiveMode modePacked, + DrawElementsType typePacked, + const void *indirect, + GLsizei drawcount, + GLsizei stride); +bool ValidateShaderStorageBlockBinding(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + GLuint storageBlockIndex, + GLuint storageBlockBinding); +bool ValidateTextureView(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLenum target, + GLuint origtexture, + GLenum internalformat, + GLuint minlevel, + GLuint numlevels, + GLuint minlayer, + GLuint numlayers); +bool ValidateVertexAttribLFormat(const Context *context, + angle::EntryPoint entryPoint, + GLuint attribindex, + GLint size, + GLenum type, + GLuint relativeoffset); + +// GL 4.4 +bool ValidateBindBuffersBase(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint first, + GLsizei count, + const BufferID *buffersPacked); +bool ValidateBindBuffersRange(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLuint first, + GLsizei count, + const BufferID *buffersPacked, + const GLintptr *offsets, + const GLsizeiptr *sizes); +bool ValidateBindImageTextures(const Context *context, + angle::EntryPoint entryPoint, + GLuint first, + GLsizei count, + const GLuint *textures); +bool ValidateBindSamplers(const Context *context, + angle::EntryPoint entryPoint, + GLuint first, + GLsizei count, + const GLuint *samplers); +bool ValidateBindTextures(const Context *context, + angle::EntryPoint entryPoint, + GLuint first, + GLsizei count, + const GLuint *textures); +bool ValidateBindVertexBuffers(const Context *context, + angle::EntryPoint entryPoint, + GLuint first, + GLsizei count, + const BufferID *buffersPacked, + const GLintptr *offsets, + const GLsizei *strides); +bool ValidateBufferStorage(const Context *context, + angle::EntryPoint entryPoint, + BufferBinding targetPacked, + GLsizeiptr size, + const void *data, + GLbitfield flags); +bool ValidateClearTexImage(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLint level, + GLenum format, + GLenum type, + const void *data); +bool ValidateClearTexSubImage(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *data); + +// GL 4.5 +bool ValidateBindTextureUnit(const Context *context, + angle::EntryPoint entryPoint, + GLuint unit, + TextureID texturePacked); +bool ValidateBlitNamedFramebuffer(const Context *context, + angle::EntryPoint entryPoint, + GLuint readFramebuffer, + GLuint drawFramebuffer, + GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter); +bool ValidateCheckNamedFramebufferStatus(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebufferPacked, + GLenum target); +bool ValidateClearNamedBufferData(const Context *context, + angle::EntryPoint entryPoint, + BufferID bufferPacked, + GLenum internalformat, + GLenum format, + GLenum type, + const void *data); +bool ValidateClearNamedBufferSubData(const Context *context, + angle::EntryPoint entryPoint, + BufferID bufferPacked, + GLenum internalformat, + GLintptr offset, + GLsizeiptr size, + GLenum format, + GLenum type, + const void *data); +bool ValidateClearNamedFramebufferfi(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebufferPacked, + GLenum buffer, + GLint drawbuffer, + GLfloat depth, + GLint stencil); +bool ValidateClearNamedFramebufferfv(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebufferPacked, + GLenum buffer, + GLint drawbuffer, + const GLfloat *value); +bool ValidateClearNamedFramebufferiv(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebufferPacked, + GLenum buffer, + GLint drawbuffer, + const GLint *value); +bool ValidateClearNamedFramebufferuiv(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebufferPacked, + GLenum buffer, + GLint drawbuffer, + const GLuint *value); +bool ValidateClipControl(const Context *context, + angle::EntryPoint entryPoint, + GLenum origin, + GLenum depth); +bool ValidateCompressedTextureSubImage1D(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, + GLsizei imageSize, + const void *data); +bool ValidateCompressedTextureSubImage2D(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + const void *data); +bool ValidateCompressedTextureSubImage3D(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const void *data); +bool ValidateCopyNamedBufferSubData(const Context *context, + angle::EntryPoint entryPoint, + GLuint readBuffer, + GLuint writeBuffer, + GLintptr readOffset, + GLintptr writeOffset, + GLsizeiptr size); +bool ValidateCopyTextureSubImage1D(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLint x, + GLint y, + GLsizei width); +bool ValidateCopyTextureSubImage2D(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height); +bool ValidateCopyTextureSubImage3D(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height); +bool ValidateCreateBuffers(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const BufferID *buffersPacked); +bool ValidateCreateFramebuffers(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const GLuint *framebuffers); +bool ValidateCreateProgramPipelines(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const GLuint *pipelines); +bool ValidateCreateQueries(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLsizei n, + const GLuint *ids); +bool ValidateCreateRenderbuffers(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const RenderbufferID *renderbuffersPacked); +bool ValidateCreateSamplers(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const GLuint *samplers); +bool ValidateCreateTextures(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLsizei n, + const GLuint *textures); +bool ValidateCreateTransformFeedbacks(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const GLuint *ids); +bool ValidateCreateVertexArrays(const Context *context, + angle::EntryPoint entryPoint, + GLsizei n, + const VertexArrayID *arraysPacked); +bool ValidateDisableVertexArrayAttrib(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID vaobjPacked, + GLuint index); +bool ValidateEnableVertexArrayAttrib(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID vaobjPacked, + GLuint index); +bool ValidateFlushMappedNamedBufferRange(const Context *context, + angle::EntryPoint entryPoint, + BufferID bufferPacked, + GLintptr offset, + GLsizeiptr length); +bool ValidateGenerateTextureMipmap(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked); +bool ValidateGetCompressedTextureImage(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLint level, + GLsizei bufSize, + const void *pixels); +bool ValidateGetCompressedTextureSubImage(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLsizei bufSize, + const void *pixels); +bool ValidateGetNamedBufferParameteri64v(const Context *context, + angle::EntryPoint entryPoint, + BufferID bufferPacked, + GLenum pname, + const GLint64 *params); +bool ValidateGetNamedBufferParameteriv(const Context *context, + angle::EntryPoint entryPoint, + BufferID bufferPacked, + GLenum pname, + const GLint *params); +bool ValidateGetNamedBufferPointerv(const Context *context, + angle::EntryPoint entryPoint, + BufferID bufferPacked, + GLenum pname, + void *const *params); +bool ValidateGetNamedBufferSubData(const Context *context, + angle::EntryPoint entryPoint, + BufferID bufferPacked, + GLintptr offset, + GLsizeiptr size, + const void *data); +bool ValidateGetNamedFramebufferAttachmentParameteriv(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebufferPacked, + GLenum attachment, + GLenum pname, + const GLint *params); +bool ValidateGetNamedFramebufferParameteriv(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebufferPacked, + GLenum pname, + const GLint *param); +bool ValidateGetNamedRenderbufferParameteriv(const Context *context, + angle::EntryPoint entryPoint, + RenderbufferID renderbufferPacked, + GLenum pname, + const GLint *params); +bool ValidateGetQueryBufferObjecti64v(const Context *context, + angle::EntryPoint entryPoint, + GLuint id, + BufferID bufferPacked, + GLenum pname, + GLintptr offset); +bool ValidateGetQueryBufferObjectiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint id, + BufferID bufferPacked, + GLenum pname, + GLintptr offset); +bool ValidateGetQueryBufferObjectui64v(const Context *context, + angle::EntryPoint entryPoint, + GLuint id, + BufferID bufferPacked, + GLenum pname, + GLintptr offset); +bool ValidateGetQueryBufferObjectuiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint id, + BufferID bufferPacked, + GLenum pname, + GLintptr offset); +bool ValidateGetTextureImage(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLint level, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels); +bool ValidateGetTextureLevelParameterfv(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLint level, + GLenum pname, + const GLfloat *params); +bool ValidateGetTextureLevelParameteriv(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLint level, + GLenum pname, + const GLint *params); +bool ValidateGetTextureParameterIiv(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLenum pname, + const GLint *params); +bool ValidateGetTextureParameterIuiv(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLenum pname, + const GLuint *params); +bool ValidateGetTextureParameterfv(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLenum pname, + const GLfloat *params); +bool ValidateGetTextureParameteriv(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLenum pname, + const GLint *params); +bool ValidateGetTextureSubImage(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels); +bool ValidateGetTransformFeedbacki64_v(const Context *context, + angle::EntryPoint entryPoint, + GLuint xfb, + GLenum pname, + GLuint index, + const GLint64 *param); +bool ValidateGetTransformFeedbacki_v(const Context *context, + angle::EntryPoint entryPoint, + GLuint xfb, + GLenum pname, + GLuint index, + const GLint *param); +bool ValidateGetTransformFeedbackiv(const Context *context, + angle::EntryPoint entryPoint, + GLuint xfb, + GLenum pname, + const GLint *param); +bool ValidateGetVertexArrayIndexed64iv(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID vaobjPacked, + GLuint index, + GLenum pname, + const GLint64 *param); +bool ValidateGetVertexArrayIndexediv(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID vaobjPacked, + GLuint index, + GLenum pname, + const GLint *param); +bool ValidateGetVertexArrayiv(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID vaobjPacked, + GLenum pname, + const GLint *param); +bool ValidateGetnColorTable(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *table); +bool ValidateGetnCompressedTexImage(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLint lod, + GLsizei bufSize, + const void *pixels); +bool ValidateGetnConvolutionFilter(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *image); +bool ValidateGetnHistogram(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLboolean reset, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *values); +bool ValidateGetnMapdv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum query, + GLsizei bufSize, + const GLdouble *v); +bool ValidateGetnMapfv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum query, + GLsizei bufSize, + const GLfloat *v); +bool ValidateGetnMapiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum query, + GLsizei bufSize, + const GLint *v); +bool ValidateGetnMinmax(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLboolean reset, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *values); +bool ValidateGetnPixelMapfv(const Context *context, + angle::EntryPoint entryPoint, + GLenum map, + GLsizei bufSize, + const GLfloat *values); +bool ValidateGetnPixelMapuiv(const Context *context, + angle::EntryPoint entryPoint, + GLenum map, + GLsizei bufSize, + const GLuint *values); +bool ValidateGetnPixelMapusv(const Context *context, + angle::EntryPoint entryPoint, + GLenum map, + GLsizei bufSize, + const GLushort *values); +bool ValidateGetnPolygonStipple(const Context *context, + angle::EntryPoint entryPoint, + GLsizei bufSize, + const GLubyte *pattern); +bool ValidateGetnSeparableFilter(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLenum format, + GLenum type, + GLsizei rowBufSize, + const void *row, + GLsizei columnBufSize, + const void *column, + const void *span); +bool ValidateGetnTexImage(const Context *context, + angle::EntryPoint entryPoint, + GLenum target, + GLint level, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels); +bool ValidateGetnUniformdv(const Context *context, + angle::EntryPoint entryPoint, + ShaderProgramID programPacked, + UniformLocation locationPacked, + GLsizei bufSize, + const GLdouble *params); +bool ValidateInvalidateNamedFramebufferData(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebufferPacked, + GLsizei numAttachments, + const GLenum *attachments); +bool ValidateInvalidateNamedFramebufferSubData(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebufferPacked, + GLsizei numAttachments, + const GLenum *attachments, + GLint x, + GLint y, + GLsizei width, + GLsizei height); +bool ValidateMapNamedBuffer(const Context *context, + angle::EntryPoint entryPoint, + BufferID bufferPacked, + GLenum access); +bool ValidateMapNamedBufferRange(const Context *context, + angle::EntryPoint entryPoint, + BufferID bufferPacked, + GLintptr offset, + GLsizeiptr length, + GLbitfield access); +bool ValidateNamedBufferData(const Context *context, + angle::EntryPoint entryPoint, + BufferID bufferPacked, + GLsizeiptr size, + const void *data, + GLenum usage); +bool ValidateNamedBufferStorage(const Context *context, + angle::EntryPoint entryPoint, + BufferID bufferPacked, + GLsizeiptr size, + const void *data, + GLbitfield flags); +bool ValidateNamedBufferSubData(const Context *context, + angle::EntryPoint entryPoint, + BufferID bufferPacked, + GLintptr offset, + GLsizeiptr size, + const void *data); +bool ValidateNamedFramebufferDrawBuffer(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebufferPacked, + GLenum buf); +bool ValidateNamedFramebufferDrawBuffers(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebufferPacked, + GLsizei n, + const GLenum *bufs); +bool ValidateNamedFramebufferParameteri(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebufferPacked, + GLenum pname, + GLint param); +bool ValidateNamedFramebufferReadBuffer(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebufferPacked, + GLenum src); +bool ValidateNamedFramebufferRenderbuffer(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebufferPacked, + GLenum attachment, + GLenum renderbuffertarget, + RenderbufferID renderbufferPacked); +bool ValidateNamedFramebufferTexture(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebufferPacked, + GLenum attachment, + TextureID texturePacked, + GLint level); +bool ValidateNamedFramebufferTextureLayer(const Context *context, + angle::EntryPoint entryPoint, + FramebufferID framebufferPacked, + GLenum attachment, + TextureID texturePacked, + GLint level, + GLint layer); +bool ValidateNamedRenderbufferStorage(const Context *context, + angle::EntryPoint entryPoint, + RenderbufferID renderbufferPacked, + GLenum internalformat, + GLsizei width, + GLsizei height); +bool ValidateNamedRenderbufferStorageMultisample(const Context *context, + angle::EntryPoint entryPoint, + RenderbufferID renderbufferPacked, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height); +bool ValidateTextureBarrier(const Context *context, angle::EntryPoint entryPoint); +bool ValidateTextureBuffer(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLenum internalformat, + BufferID bufferPacked); +bool ValidateTextureBufferRange(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLenum internalformat, + BufferID bufferPacked, + GLintptr offset, + GLsizeiptr size); +bool ValidateTextureParameterIiv(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLenum pname, + const GLint *params); +bool ValidateTextureParameterIuiv(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLenum pname, + const GLuint *params); +bool ValidateTextureParameterf(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLenum pname, + GLfloat param); +bool ValidateTextureParameterfv(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLenum pname, + const GLfloat *param); +bool ValidateTextureParameteri(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLenum pname, + GLint param); +bool ValidateTextureParameteriv(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLenum pname, + const GLint *param); +bool ValidateTextureStorage1D(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLsizei levels, + GLenum internalformat, + GLsizei width); +bool ValidateTextureStorage2D(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height); +bool ValidateTextureStorage2DMultisample(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations); +bool ValidateTextureStorage3D(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth); +bool ValidateTextureStorage3DMultisample(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedsamplelocations); +bool ValidateTextureSubImage1D(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, + GLenum type, + const void *pixels); +bool ValidateTextureSubImage2D(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void *pixels); +bool ValidateTextureSubImage3D(const Context *context, + angle::EntryPoint entryPoint, + TextureID texturePacked, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *pixels); +bool ValidateTransformFeedbackBufferBase(const Context *context, + angle::EntryPoint entryPoint, + GLuint xfb, + GLuint index, + BufferID bufferPacked); +bool ValidateTransformFeedbackBufferRange(const Context *context, + angle::EntryPoint entryPoint, + GLuint xfb, + GLuint index, + BufferID bufferPacked, + GLintptr offset, + GLsizeiptr size); +bool ValidateUnmapNamedBuffer(const Context *context, + angle::EntryPoint entryPoint, + BufferID bufferPacked); +bool ValidateVertexArrayAttribBinding(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID vaobjPacked, + GLuint attribindex, + GLuint bindingindex); +bool ValidateVertexArrayAttribFormat(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID vaobjPacked, + GLuint attribindex, + GLint size, + GLenum type, + GLboolean normalized, + GLuint relativeoffset); +bool ValidateVertexArrayAttribIFormat(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID vaobjPacked, + GLuint attribindex, + GLint size, + GLenum type, + GLuint relativeoffset); +bool ValidateVertexArrayAttribLFormat(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID vaobjPacked, + GLuint attribindex, + GLint size, + GLenum type, + GLuint relativeoffset); +bool ValidateVertexArrayBindingDivisor(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID vaobjPacked, + GLuint bindingindex, + GLuint divisor); +bool ValidateVertexArrayElementBuffer(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID vaobjPacked, + BufferID bufferPacked); +bool ValidateVertexArrayVertexBuffer(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID vaobjPacked, + GLuint bindingindex, + BufferID bufferPacked, + GLintptr offset, + GLsizei stride); +bool ValidateVertexArrayVertexBuffers(const Context *context, + angle::EntryPoint entryPoint, + VertexArrayID vaobjPacked, + GLuint first, + GLsizei count, + const BufferID *buffersPacked, + const GLintptr *offsets, + const GLsizei *strides); + +// GL 4.6 +bool ValidateMultiDrawArraysIndirectCount(const Context *context, + angle::EntryPoint entryPoint, + GLenum mode, + const void *indirect, + GLintptr drawcount, + GLsizei maxdrawcount, + GLsizei stride); +bool ValidateMultiDrawElementsIndirectCount(const Context *context, + angle::EntryPoint entryPoint, + GLenum mode, + GLenum type, + const void *indirect, + GLintptr drawcount, + GLsizei maxdrawcount, + GLsizei stride); +bool ValidatePolygonOffsetClamp(const Context *context, + angle::EntryPoint entryPoint, + GLfloat factor, + GLfloat units, + GLfloat clamp); +bool ValidateSpecializeShader(const Context *context, + angle::EntryPoint entryPoint, + GLuint shader, + const GLchar *pEntryPoint, + GLuint numSpecializationConstants, + const GLuint *pConstantIndex, + const GLuint *pConstantValue); +} // namespace gl + +#endif // LIBANGLE_VALIDATION_GL4_AUTOGEN_H_ -- cgit v1.2.3